repair ppc port Reference: /n/atom/patch/applied/ppcrepair Date: Tue Apr 15 22:21:42 CES 2014 Signed-off-by: quanstro@quanstro.net --- /sys/src/9/ppc/blast Tue Apr 15 22:21:42 2014 +++ /sys/src/9/ppc/blast Tue Apr 15 22:21:42 2014 @@ -24,6 +24,11 @@ loopbackmedium misc + alloc + physalloc + noswap + xalloc + uartsmc m8260 @@ -54,8 +59,9 @@ /power/bin/echo /power/bin/mount /power/bin/sleep - /power/bin/ip/ipconfig /power/bin/auth/factotum + /power/bin/ip/ipconfig /power/bin/ls + /power/bin/ps /power/bin/auth/wrkey - /sys/lib/sysconfig/blast/boot + /sys/lib/sysconfig/ppc/boot --- /sys/src/9/ppc/blast.h Tue Apr 15 22:21:42 2014 +++ /sys/src/9/ppc/blast.h Tue Apr 15 22:21:42 2014 @@ -27,6 +27,8 @@ * * CS2, CS3, CS4, (and CS5) are covered by DBAT 0, CS0 and CS1 by DBAT 3, CS6 by DBAT 2 */ +#define IMMR 0xf0000000 + #define FLASHMEM 0xfe000000 #define FLASHSIZE 0x01000000 #define DSP1BASE 0xfc000000 --- /sys/src/9/ppc/dat.h Tue Apr 15 22:21:42 2014 +++ /sys/src/9/ppc/dat.h Tue Apr 15 22:21:42 2014 @@ -13,13 +13,14 @@ typedef struct Pcidev Pcidev; typedef struct Proc Proc; typedef struct Sys Sys; +typedef vlong Tval; typedef struct Ureg Ureg; typedef struct Vctl Vctl; -typedef ulong Tval; typedef ulong uintmem; #pragma incomplete Ureg #pragma incomplete Imap +#pragma incomplete Mach #define MAXSYSARG 5 /* for mount(fd, mpt, flag, arg, srv) */ @@ -38,6 +39,7 @@ ulong sr; ulong pc; Proc *p; + Mach *m; ulong pid; ushort isilock; }; @@ -136,6 +138,9 @@ #define kmap(p) (KMap*)((p)->pa|KZERO) #define kunmap(k) +struct IMM; +typedef struct IMM IMM; + struct Mach { /* OFFSETS OF THE FOLLOWING KNOWN BY l.s */ @@ -150,6 +155,10 @@ /* ordering from here on irrelevant */ Imap* imap; + +#ifndef ucuconf + IMM* immr; +#endif ulong ticks; /* of the clock since boot time */ Label sched; /* scheduler wakeup */ --- /sys/src/9/ppc/devce.c Thu Jan 1 00:00:00 1970 +++ /sys/src/9/ppc/devce.c Tue Apr 15 22:21:42 2014 @@ -0,0 +1,191 @@ +// +// channel element driver +// +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "../port/error.h" +#include "msaturn.h" + +enum{ + Ucuunknown = 0, + Ucu64, + + Ndsp = 16, + + Cedead = 0, + Cereset, + Celoaded, + Cerunning, + + Qdir = 0, + Qctl, + Qce, + + Cpldbase = Saturn + 0x6000000, + Cplducuversion_ucu = 0x1c, + Cebase = Saturn + 0x3000000, + Cesize = 0x100000, +}; + +typedef struct Cpld Cpld; +struct Cpld{ + uchar led; + uchar fpga1; + uchar slotid; + uchar version; + uchar watchdog; + uchar spi; + uchar asicreset; + uchar dspreset; + uchar generalreset; + uchar ucuversion; + uchar fpga2; +}; + +typedef struct Circbuf Circbuf; +struct Circbuf{ + uchar *nextin; + uchar *nextout; + uchar *start; + uchar *end; +}; + +typedef struct Dsp Dsp; +struct Dsp{ + Ref; + int state; + Circbuf *cb; +}; + +typedef struct Ce Ce; +struct Ce{ + int ucutype; + Ce *ces[Ndsp]; +}; + +static Cpld*cpld = (Cpld*)Cpldbase; +static Ce ce; + +static void +ceinit(void) +{ + if(cpld->ucuversion & Cplducuversion_ucu) + ce.ucutype = Ucu64; + else{ + print("ceinit: unsuppoerted UCU\n"); + return; + } + +} + +static Chan* +ceattach(char*spec) +{ + return devattach('C', spec); +} + +#define DEV(q) ((int)(((q).path >> 8) & 0xff)) +#define TYPE(q) ((int)((q).path & 0xff)) +#define QID(d, t) ((((d) & 0xff) << 8) | (t)) + +static int +cegen(Chan*c, char*, Dirtab*, int, int i, Dir*dp) +{ + Qid qid; + + switch(TYPE(c->qid)){ + case Qdir: + if(i == DEVDOTDOT){ + mkqid(&qid, QID(0, Qdir), 0, QTDIR); + devdir(c, qid, "#C", 0, eve, 0555, dp); + return 1; + } + + if(i == 0){ + mkqid(&qid, QID(-1, Qctl), 0, QTFILE); + devdir(c, qid, "cectl", 0, eve, 0644, dp); + return 1; + } + + if (--i >= Ndsp) + return -1; + + mkqid(&qid, QID(Qce, i), 0, QTFILE); + snprint(up->genbuf, sizeof(up->genbuf), "ce%d", i); + devdir(c, qid, up->genbuf, 0, eve, 0644, dp); + return 1; + + default: + return -1; + } +} + +static Walkqid * +cewalk(Chan*c, Chan*nc, char**name, int nname) +{ + return devwalk(c, nc, name, nname, 0, 0, cegen); +} + +static int +cestat(Chan*c, uchar*db, int n) +{ + return devstat(c, db, n, 0, 0, cegen); +} + +static Chan* +ceopen(Chan*c, int omode) +{ + c->mode = openmode(omode); + c->flag |= COPEN; + c->offset = 0; + return c; +} + +static void +ceclose(Chan*) +{} + +static long +ceread(Chan*c, void*a, long n, vlong) +{ + switch(TYPE(c->qid)){ + case Qdir: + return devdirread(c, a, n, 0, 0, cegen); + + default: + error("unsupported operation"); + } + return 0; +} + +static long +cewrite(Chan*, void*, long, vlong) +{ + return 0; +} + +Dev cedevtab = { + 'C', + "channel element", + + devreset, + ceinit, + devshutdown, + ceattach, + cewalk, + cestat, + ceopen, + devcreate, + ceclose, + ceread, + devbread, + cewrite, + devbwrite, + devremove, + devwstat, + devpower, +}; --- /sys/src/9/ppc/devether.c Tue Apr 15 22:21:42 2014 +++ /sys/src/9/ppc/devether.c Tue Apr 15 22:21:42 2014 @@ -16,23 +16,28 @@ Chan* etherattach(char* spec) { - ulong ctlrno; + uint ctlrno; char *p; Chan *chan; ctlrno = 0; if(spec && *spec){ ctlrno = strtoul(spec, &p, 0); - if((ctlrno == 0 && p == spec) || *p || (ctlrno >= MaxEther)) + if(*p != 0 || ctlrno >= MaxEther) error(Ebadarg); } if(etherxx[ctlrno] == 0) error(Enodev); chan = devattach('l', spec); + if(waserror()){ + chanfree(chan); + nexterror(); + } chan->dev = ctlrno; if(etherxx[ctlrno]->attach) etherxx[ctlrno]->attach(etherxx[ctlrno]); + poperror(); return chan; } @@ -117,7 +122,7 @@ multi = pkt->d[0] & 1; /* check for valid multicast addresses */ - if(multi && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) && ether->prom == 0){ + if(multi && memcmp(pkt->d, ether->bcast, sizeof(pkt->d)) != 0 && ether->prom == 0){ if(!activemulti(ether, pkt->d, sizeof(pkt->d))){ if(fromwire){ freeb(bp); @@ -197,7 +202,8 @@ if(!loopback){ qbwrite(ether->oq, bp); - ether->transmit(ether); + if(ether->transmit != nil) + ether->transmit(ether); } else freeb(bp); @@ -209,20 +215,28 @@ { Ether *ether; Block *bp; - int nn; + int nn, onoff; + Cmdbuf *cb; ether = etherxx[chan->dev]; if(NETTYPE(chan->qid.path) != Ndataqid) { nn = netifwrite(ether, chan, buf, n); if(nn >= 0) return nn; - if(n == sizeof("nonblocking")-1 && strncmp((char*)buf, "nonblocking", n) == 0){ - qnoblock(ether->oq, 1); + cb = parsecmd(buf, n); + if(cb->f[0] && strcmp(cb->f[0], "nonblocking") == 0){ + if(cb->nf <= 1) + onoff = 1; + else + onoff = atoi(cb->f[1]); + qnoblock(ether->oq, onoff); + free(cb); return n; } - if(ether->ctl!=nil) - return ether->ctl(ether,buf,n); - + free(cb); + if(ether->ctl != nil) + return ether->ctl(ether, buf, n); + error(Ebadctl); } @@ -301,7 +315,7 @@ int i; p = from; - for(i = 0; i < 6; i++){ + for(i = 0; i < Eaddrlen; i++){ if(*p == 0) return -1; nip[0] = *p++; @@ -397,26 +411,6 @@ } if(ether) free(ether); -} - -#define POLY 0xedb88320 - -/* really slow 32 bit crc for ethers */ -ulong -ethercrc(uchar *p, int len) -{ - int i, j; - ulong crc, b; - - crc = 0xffffffff; - for(i = 0; i < len; i++){ - b = *p++; - for(j = 0; j < 8; j++){ - crc = (crc>>1) ^ (((crc^b) & 1) ? POLY : 0); - b >>= 1; - } - } - return crc; } Dev etherdevtab = { --- /sys/src/9/ppc/devirq.c Tue Apr 15 22:21:42 2014 +++ /sys/src/9/ppc/devirq.c Tue Apr 15 22:21:42 2014 @@ -302,7 +302,7 @@ iomem->simr_h, iomem->simr_l, iomem->sipnr_h, iomem->sipnr_l, iomem->siexr, iomem->siprr); - dumpvno(); +// dumpvno(); } poperror(); free(cb); --- /sys/src/9/ppc/etherfcc.c Tue Apr 15 22:21:42 2014 +++ /sys/src/9/ppc/etherfcc.c Tue Apr 15 22:21:42 2014 @@ -466,40 +466,42 @@ ctlr = ether->ctlr; - p = malloc(2*READSTR); - len = snprint(p, 2*READSTR, "interrupts: %lud\n", ctlr->interrupts); - len += snprint(p+len, 2*READSTR-len, "carrierlost: %lud\n", ctlr->carrierlost); - len += snprint(p+len, 2*READSTR-len, "heartbeat: %lud\n", ctlr->heartbeat); - len += snprint(p+len, 2*READSTR-len, "retrylimit: %lud\n", ctlr->retrylim); - len += snprint(p+len, 2*READSTR-len, "retrycount: %lud\n", ctlr->retrycount); - len += snprint(p+len, 2*READSTR-len, "latecollisions: %lud\n", ctlr->latecoll); - len += snprint(p+len, 2*READSTR-len, "rxoverruns: %lud\n", ctlr->overrun); - len += snprint(p+len, 2*READSTR-len, "txunderruns: %lud\n", ctlr->underrun); - len += snprint(p+len, 2*READSTR-len, "framesdeferred: %lud\n", ctlr->deferred); + p = malloc(READSTR); + len = snprint(p, READSTR, "interrupts: %lud\n", ctlr->interrupts); + len += snprint(p+len, READSTR-len, "carrierlost: %lud\n", ctlr->carrierlost); + len += snprint(p+len, READSTR-len, "heartbeat: %lud\n", ctlr->heartbeat); + len += snprint(p+len, READSTR-len, "retrylimit: %lud\n", ctlr->retrylim); + len += snprint(p+len, READSTR-len, "retrycount: %lud\n", ctlr->retrycount); + len += snprint(p+len, READSTR-len, "latecollisions: %lud\n", ctlr->latecoll); + len += snprint(p+len, READSTR-len, "rxoverruns: %lud\n", ctlr->overrun); + len += snprint(p+len, READSTR-len, "txunderruns: %lud\n", ctlr->underrun); + len += snprint(p+len, READSTR-len, "framesdeferred: %lud\n", ctlr->deferred); miistatus(ctlr->mii); phy = ctlr->mii->curphy; - len += snprint(p+len, 2*READSTR-len, "phy: link=%d, tfc=%d, rfc=%d, speed=%d, fd=%d\n", + len += snprint(p+len, READSTR-len, "phy: link=%d, tfc=%d, rfc=%d, speed=%d, fd=%d\n", phy->link, phy->tfc, phy->rfc, phy->speed, phy->fd); #ifdef DBG if(ctlr->mii != nil && ctlr->mii->curphy != nil){ - len += snprint(p+len, 2*READSTR, "phy: "); + len += snprint(p+len, READSTR, "phy: "); for(i = 0; i < NMiiPhyr; i++){ if(i && ((i & 0x07) == 0)) - len += snprint(p+len, 2*READSTR-len, "\n "); + len += snprint(p+len, READSTR-len, "\n "); r = miimir(ctlr->mii, i); - len += snprint(p+len, 2*READSTR-len, " %4.4uX", r); + len += snprint(p+len, READSTR-len, " %4.4uX", r); } - snprint(p+len, 2*READSTR-len, "\n"); + snprint(p+len, READSTR-len, "\n"); } #endif - snprint(p+len, 2*READSTR-len, "\n"); + snprint(p+len, READSTR-len, "\n"); n = readstr(offset, a, n, p); free(p); return n; } + +IMM* imm; /* * This follows the MPC8260 user guide: section28.9's initialisation sequence. --- /sys/src/9/ppc/ethermii.c Thu Jan 1 00:00:00 1970 +++ /sys/src/9/ppc/ethermii.c Tue Apr 15 22:21:42 2014 @@ -0,0 +1,233 @@ +#include "u.h" +#include "../port/lib.h" +#include "mem.h" +#include "dat.h" +#include "fns.h" +#include "io.h" +#include "../port/error.h" +#include "../port/netif.h" + +#include "etherif.h" +#include "../ppc/ethermii.h" + +int +mii(Mii* mii, int mask) +{ + MiiPhy *miiphy; + int bit, oui, phyno, r, rmask; + + /* + * Probe through mii for PHYs in mask; + * return the mask of those found in the current probe. + * If the PHY has not already been probed, update + * the Mii information. + */ + rmask = 0; + for(phyno = 0; phyno < NMiiPhy; phyno++){ + bit = 1<mask & bit){ + rmask |= bit; + continue; + } + if(mii->mir(mii, phyno, Bmsr) == -1) + continue; + r = mii->mir(mii, phyno, Phyidr1); + oui = (r & 0x3FFF)<<6; + r = mii->mir(mii, phyno, Phyidr2); + oui |= r>>10; + if(oui == 0xFFFFF || oui == 0) + continue; + + if((miiphy = malloc(sizeof(MiiPhy))) == nil) + continue; + + miiphy->mii = mii; + miiphy->oui = oui; + miiphy->phyno = phyno; + + miiphy->anar = ~0; + miiphy->fc = ~0; + miiphy->mscr = ~0; + + mii->phy[phyno] = miiphy; + if(mii->curphy == nil) + mii->curphy = miiphy; + mii->mask |= bit; + mii->nphy++; + + rmask |= bit; + } + return rmask; +} + +int +miimir(Mii* mii, int r) +{ + if(mii == nil || mii->ctlr == nil || mii->curphy == nil) + return -1; + return mii->mir(mii, mii->curphy->phyno, r); +} + +int +miimiw(Mii* mii, int r, int data) +{ + if(mii == nil || mii->ctlr == nil || mii->curphy == nil) + return -1; + return mii->miw(mii, mii->curphy->phyno, r, data); +} + +int +miireset(Mii* mii) +{ + int bmcr; + + if(mii == nil || mii->ctlr == nil || mii->curphy == nil) + return -1; + bmcr = mii->mir(mii, mii->curphy->phyno, Bmcr); + bmcr |= BmcrR; + mii->miw(mii, mii->curphy->phyno, Bmcr, bmcr); + microdelay(1); + + return 0; +} + +int +miiane(Mii* mii, int a, int p, int e) +{ + int anar, bmsr, mscr, r, phyno; + + if(mii == nil || mii->ctlr == nil || mii->curphy == nil) + return -1; + phyno = mii->curphy->phyno; + + bmsr = mii->mir(mii, phyno, Bmsr); + if(!(bmsr & BmsrAna)) + return -1; + + anar = mii->mir(mii, phyno, Anar); + anar &= ~(AnaAP|AnaP|AnaT4|AnaTXFD|AnaTXHD|Ana10FD|Ana10HD); + + if(a != ~0) + anar |= (AnaT4|AnaTXFD|AnaTXHD|Ana10FD|Ana10HD) & a; + else if(mii->curphy->anar != ~0) + anar = mii->curphy->anar; + else{ + if(bmsr & Bmsr10THD) + anar |= Ana10HD; + if(bmsr & Bmsr10TFD) + anar |= Ana10FD; + if(bmsr & Bmsr100TXHD) + anar |= AnaTXHD; + if(bmsr & Bmsr100TXFD) + anar |= AnaTXFD; + } + mii->curphy->anar = anar; + + if(p != ~0) + anar |= (AnaAP|AnaP) & p; + else if(mii->curphy->fc != ~0) + anar |= mii->curphy->fc; + mii->curphy->fc = (AnaAP|AnaP) & anar; + + mii->miw(mii, phyno, Anar, anar); + + mscr = 0; + if(bmsr & BmsrEs){ + mscr = mii->mir(mii, phyno, Mscr); + mscr &= ~(Mscr1000TFD|Mscr1000THD); + if(e != ~0) + mscr |= (Mscr1000TFD|Mscr1000THD) & e; + else if(mii->curphy->mscr != ~0) + mscr = mii->curphy->mscr; + else{ + r = mii->mir(mii, phyno, Esr); + if(r & Esr1000THD) + mscr |= Mscr1000THD; + if(r & Esr1000TFD) + mscr |= Mscr1000TFD; + } + mii->miw(mii, phyno, Mscr, mscr); + } + mii->curphy->mscr = mscr; + + r = mii->mir(mii, phyno, Bmcr); + if(!(r & BmcrR)){ + r |= BmcrAne|BmcrRan; + mii->miw(mii, phyno, Bmcr, r); + } + + return 0; +} + +int +miistatus(Mii* mii) +{ + MiiPhy *phy; + int anlpar, bmsr, p, r, phyno; + + if(mii == nil || mii->ctlr == nil || mii->curphy == nil) + return -1; + phy = mii->curphy; + phyno = phy->phyno; + + /* + * Check Auto-Negotiation is complete and link is up. + * (Read status twice as the Ls bit is sticky). + */ + phy->bmsr = bmsr = mii->mir(mii, phyno, Bmsr); + if(!(bmsr & (BmsrAnc|BmsrAna))) + return -1; + + phy->bmsr = bmsr = mii->mir(mii, phyno, Bmsr); + if(!(bmsr & BmsrLs)){ + phy->link = 0; + return 0; + } + + phy->speed = phy->fd = phy->rfc = phy->tfc = 0; + if(phy->mscr & (Mscr1000TFD|Mscr1000THD)){ + r = mii->mir(mii, phyno, Mssr); + if((phy->mscr & Mscr1000TFD) && (r & Mssr1000TFD)){ + phy->speed = 1000; + phy->fd = 1; + } + else if((phy->mscr & Mscr1000THD) && (r & Mssr1000THD)) + phy->speed = 1000; + } + + anlpar = mii->mir(mii, phyno, Anlpar); + if(phy->speed == 0){ + r = phy->anar & anlpar; + if(r & AnaTXFD){ + phy->speed = 100; + phy->fd = 1; + } + else if(r & AnaTXHD) + phy->speed = 100; + else if(r & Ana10FD){ + phy->speed = 10; + phy->fd = 1; + } + else if(r & Ana10HD) + phy->speed = 10; + } + if(phy->speed == 0) + return -1; + + if(phy->fd){ + p = phy->fc; + r = anlpar & (AnaAP|AnaP); + if(p == AnaAP && r == (AnaAP|AnaP)) + phy->tfc = 1; + else if(p == (AnaAP|AnaP) && r == AnaAP) + phy->rfc = 1; + else if((p & AnaP) && (r & AnaP)) + phy->rfc = phy->tfc = 1; + } + + phy->link = 1; + + return 0; +} --- /sys/src/9/ppc/ethermii.h Thu Jan 1 00:00:00 1970 +++ /sys/src/9/ppc/ethermii.h Tue Apr 15 22:21:42 2014 @@ -0,0 +1,117 @@ +typedef struct Mii Mii; +typedef struct MiiPhy MiiPhy; + +enum { /* registers */ + Bmcr = 0x00, /* Basic Mode Control */ + Bmsr = 0x01, /* Basic Mode Status */ + Phyidr1 = 0x02, /* PHY Identifier #1 */ + Phyidr2 = 0x03, /* PHY Identifier #2 */ + Anar = 0x04, /* Auto-Negotiation Advertisement */ + Anlpar = 0x05, /* AN Link Partner Ability */ + Aner = 0x06, /* AN Expansion */ + Annptr = 0x07, /* AN Next Page TX */ + Annprr = 0x08, /* AN Next Page RX */ + Mscr = 0x09, /* MASTER-SLAVE Control */ + Mssr = 0x0A, /* MASTER-SLAVE Status */ + Esr = 0x0F, /* Extended Status */ + + NMiiPhyr = 32, + NMiiPhy = 32, +}; + +enum { /* Bmcr */ + BmcrSs1 = 0x0040, /* Speed Select[1] */ + BmcrCte = 0x0080, /* Collision Test Enable */ + BmcrDm = 0x0100, /* Duplex Mode */ + BmcrRan = 0x0200, /* Restart Auto-Negotiation */ + BmcrI = 0x0400, /* Isolate */ + BmcrPd = 0x0800, /* Power Down */ + BmcrAne = 0x1000, /* Auto-Negotiation Enable */ + BmcrSs0 = 0x2000, /* Speed Select[0] */ + BmcrLe = 0x4000, /* Loopback Enable */ + BmcrR = 0x8000, /* Reset */ +}; + +enum { /* Bmsr */ + BmsrEc = 0x0001, /* Extended Capability */ + BmsrJd = 0x0002, /* Jabber Detect */ + BmsrLs = 0x0004, /* Link Status */ + BmsrAna = 0x0008, /* Auto-Negotiation Ability */ + BmsrRf = 0x0010, /* Remote Fault */ + BmsrAnc = 0x0020, /* Auto-Negotiation Complete */ + BmsrPs = 0x0040, /* Preamble Suppression Capable */ + BmsrEs = 0x0100, /* Extended Status */ + Bmsr100T2HD = 0x0200, /* 100BASE-T2 HD Capable */ + Bmsr100T2FD = 0x0400, /* 100BASE-T2 FD Capable */ + Bmsr10THD = 0x0800, /* 10BASE-T HD Capable */ + Bmsr10TFD = 0x1000, /* 10BASE-T FD Capable */ + Bmsr100TXHD = 0x2000, /* 100BASE-TX HD Capable */ + Bmsr100TXFD = 0x4000, /* 100BASE-TX FD Capable */ + Bmsr100T4 = 0x8000, /* 100BASE-T4 Capable */ +}; + +enum { /* Anar/Anlpar */ + Ana10HD = 0x0020, /* Advertise 10BASE-T */ + Ana10FD = 0x0040, /* Advertise 10BASE-T FD */ + AnaTXHD = 0x0080, /* Advertise 100BASE-TX */ + AnaTXFD = 0x0100, /* Advertise 100BASE-TX FD */ + AnaT4 = 0x0200, /* Advertise 100BASE-T4 */ + AnaP = 0x0400, /* Pause */ + AnaAP = 0x0800, /* Asymmetrical Pause */ + AnaRf = 0x2000, /* Remote Fault */ + AnaAck = 0x4000, /* Acknowledge */ + AnaNp = 0x8000, /* Next Page Indication */ +}; + +enum { /* Mscr */ + Mscr1000THD = 0x0100, /* Advertise 1000BASE-T HD */ + Mscr1000TFD = 0x0200, /* Advertise 1000BASE-T FD */ +}; + +enum { /* Mssr */ + Mssr1000THD = 0x0400, /* Link Partner 1000BASE-T HD able */ + Mssr1000TFD = 0x0800, /* Link Partner 1000BASE-T FD able */ +}; + +enum { /* Esr */ + Esr1000THD = 0x1000, /* 1000BASE-T HD Capable */ + Esr1000TFD = 0x2000, /* 1000BASE-T FD Capable */ + Esr1000XHD = 0x4000, /* 1000BASE-X HD Capable */ + Esr1000XFD = 0x8000, /* 1000BASE-X FD Capable */ +}; + +typedef struct Mii { + Lock; + int nphy; + int mask; + MiiPhy* phy[NMiiPhy]; + MiiPhy* curphy; + + void* ctlr; + int (*mir)(Mii*, int, int); + int (*miw)(Mii*, int, int, int); +} Mii; + +typedef struct MiiPhy { + Mii* mii; + int oui; + int phyno; + + int bmsr; + int anar; + int fc; + int mscr; + + int link; + int speed; + int fd; + int rfc; + int tfc; +}; + +extern int mii(Mii*, int); +extern int miiane(Mii*, int, int, int); +extern int miimir(Mii*, int); +extern int miimiw(Mii*, int, int); +extern int miireset(Mii*); +extern int miistatus(Mii*); --- /sys/src/9/ppc/ethersaturn.c Tue Apr 15 22:21:42 2014 +++ /sys/src/9/ppc/ethersaturn.c Tue Apr 15 22:21:42 2014 @@ -65,6 +65,7 @@ ulong overflows; } Ctlr; +uchar etheraddr[6] = { 0x90, 0x85, 0x82, 0x32, 0x83, 0x00}; static ushort*etcr=(ushort*)Etcr; static ushort*etsr=(ushort*)Etsr; static ushort*ercr=(ushort*)Ercr; --- /sys/src/9/ppc/fns.h Tue Apr 15 22:21:42 2014 +++ /sys/src/9/ppc/fns.h Tue Apr 15 22:21:42 2014 @@ -1,9 +1,11 @@ #include "../port/portfns.h" +ulong cankaddr(ulong); int cistrcmp(char*, char*); int cistrncmp(char*, char*, int); void clockinit(void); void clockintr(Ureg*); +int cmpswap(long*, long, long); void cpuidprint(void); void cycles(uvlong*); void dbgputc(int c); @@ -116,6 +118,9 @@ Pcidev* pcimatch(Pcidev*, int, int); Pcidev* pcimatchtbdf(int); void procrestore(Proc*); + +#define PTR2UINT(p) ((uintptr)(p)) +#define UINT2PTR(i) ((void*)(i)) #ifdef ucuconf extern ulong getpll(void); --- /sys/src/9/ppc/imm.h Thu Jan 1 00:00:00 1970 +++ /sys/src/9/ppc/imm.h Tue Apr 15 22:21:42 2014 @@ -0,0 +1,730 @@ +enum{ + Nuart = 1, /* Number of SMC Uarts */ +}; + +enum{ + /* Vectors */ + VecXXX0, + VecI2C, + VecSPI, + VecRisc, + VecSMC1, + VecSMC2, + VecIDMA1, + VecIDMA2, + VecIDMA3, + VecIDMA4, + VecSDMA, + VecXXX11, + VecTimer1, + VecTimer2, + VecTimer3, + VecTimer4, + VecTMCNT, + VecPIT, + VecXXX18, + VecIRQ1, + VecIRQ2, + VecIRQ3, + VecIRQ4, + VecIRQ5, + VecIRQ6, + VecIRQ7, + VecXXX26, + VecXXX27, + VecXXX28, + VecXXX29, + VecXXX30, + VecXXX31, + VecFCC1, + VecFCC2, + VecFCC3, + VecXXX35, + VecMCC1, + VecMCC2, + VecXXX38, + VecXXX39, + VecSCC1, + VecSCC2, + VecSCC3, + VecSCC4, + VecXXX44, + VecXXX45, + VecXXX46, + VecXXX47, + VecPC15, + VecPC14, + VecPC13, + VecPC12, + VecPC11, + VecPC10, + VecPC9, + VecPC8, + VecPC7, + VecPC6, + VecPC5, + VecPC4, + VecPC3, + VecPC2, + VecPC1, + VecPC0, +}; + +typedef struct BD BD; +struct BD { + ushort status; + ushort length; + ulong addr; +}; + +enum{ + BDEmpty= SBIT(0), + BDReady= SBIT(0), + BDWrap= SBIT(2), + BDInt= SBIT(3), + BDLast= SBIT(4), + BDFirst= SBIT(5), +}; + +typedef struct Ring Ring; + +struct Ring { + BD* rdr; /* receive descriptor ring */ + void* rrb; /* receive ring buffers */ + int rdrx; /* index into rdr */ + int nrdre; /* length of rdr */ + + BD* tdr; /* transmit descriptor ring */ + void** txb; /* corresponding transmit ring buffers */ + int tdrh; /* host index into tdr */ + int tdri; /* interface index into tdr */ + int ntdre; /* length of tdr */ + int ntq; /* pending transmit requests */ +}; + +int ioringinit(Ring*, int, int, int); + +/* + * MCC parameters + */ +typedef struct MCCparam MCCparam; +struct MCCparam { +/*0x00*/ ulong mccbase; +/*0x04*/ ushort mccstate; +/*0x06*/ ushort mrblr; +/*0x08*/ ushort grfthr; +/*0x0a*/ ushort grfcnt; +/*0x0c*/ ulong rinttmp; +/*0x10*/ ulong data0; +/*0x14*/ ulong data1; +/*0x18*/ ulong tintbase; +/*0x1c*/ ulong tintptr; +/*0x20*/ ulong tinttmp; +/*0x24*/ ushort sctpbase; +/*0x26*/ ushort Rsvd26; +/*0x28*/ ulong cmask32; +/*0x2c*/ ushort xtrabase; +/*0x2e*/ ushort cmask16; +/*0x30*/ ulong rinttmp[4]; +/*0x40*/ struct { + ulong base; + ulong ptr; + } rint[4]; +/*0x60*/ ulong tstmp; +/*0x64*/ +}; +/* + * IO controller parameters + */ +typedef struct IOCparam IOCparam; +struct IOCparam { +/*0x00*/ ushort rbase; +/*0x02*/ ushort tbase; +/*0x04*/ uchar rfcr; +/*0x05*/ uchar tfcr; +/*0x06*/ ushort mrblr; +/*0x08*/ ulong rstate; +/*0x0c*/ ulong rxidp; +/*0x10*/ ushort rbptr; +/*0x12*/ ushort rxibc; +/*0x14*/ ulong rxtemp; +/*0x18*/ ulong tstate; +/*0x1c*/ ulong txidp; +/*0x20*/ ushort tbptr; +/*0x22*/ ushort txibc; +/*0x24*/ ulong txtemp; +/*0x28*/ +}; + +typedef struct SCCparam SCCparam; +struct SCCparam { + IOCparam; + ulong rcrc; + ulong tcrc; +}; + +typedef struct FCCparam FCCparam; +struct FCCparam { +/*0x00*/ ushort riptr; +/*0x02*/ ushort tiptr; +/*0x04*/ ushort Rsvd04; +/*0x06*/ ushort mrblr; +/*0x08*/ ulong rstate; +/*0x0c*/ ulong rbase; +/*0x10*/ ushort rbdstat; +/*0x12*/ ushort rbdlen; +/*0x14*/ char* rdptr; +/*0x18*/ ulong tstate; +/*0x1c*/ ulong tbase; +/*0x20*/ ushort tbdstat; +/*0x22*/ ushort tbdlen; +/*0x24*/ ulong tdptr; +/*0x28*/ ulong rbptr; +/*0x2c*/ ulong tbptr; +/*0x30*/ ulong rcrc; +/*0x34*/ ulong Rsvd34; +/*0x38*/ ulong tcrc; +/*0x3c*/ +}; + +typedef struct SCC SCC; +struct SCC { + ulong gsmrl; + ulong gsmrh; + ushort psmr; + uchar rsvscc0[2]; + ushort todr; + ushort dsr; + ushort scce; + uchar rsvscc1[2]; + ushort sccm; + uchar rsvscc2; + uchar sccs; + ushort irmode; + ushort irsip; + uchar rsvscc3[4]; /* BUG */ +}; + +typedef struct FCC FCC; +struct FCC { +/*0x00*/ ulong gfmr; /* general mode register 28.2/28-3 */ +/*0x04*/ ulong fpsmr; /* protocol-specific mode reg. 29.13.2(ATM) 30.18.1(Ether) */ +/*0x08*/ ushort ftodr; /* transmit on demand register 28.5/28-7 */ +/*0x0A*/ ushort Rsvd0A; +/*0x0C*/ ushort fdsr; /* data synchronization register 28.4/28-7 */ +/*0x0E*/ ushort Rsvd0E; +/*0x10*/ ushort fcce; /* event register 29.13.3 (ATM), 30.18.2 (Ethernet) */ +/*0x12*/ ushort Rsvd12; +/*0x14*/ ushort fccm; /* mask register */ +/*0x16*/ ushort Rsvd16; +/*0x18*/ uchar fccs; /* status register 8 bits 31.10 (HDLC) */ +/*0x19*/ uchar Rsvd19[3]; +/*0x1C*/ uchar ftirrphy[4]; /* transmit internal rate registers for PHY0DH3 29.13.4/29-88 (ATM) */ +/*0x20*/ +}; + +typedef struct SMC SMC; +struct SMC { +/*0x0*/ ushort pad1; +/*0x2*/ ushort smcmr; +/*0x4*/ ushort pad2; +/*0x6*/ uchar smce; +/*0x7*/ uchar pad3[3]; +/*0xa*/ uchar smcm; +/*0xb*/ uchar pad4[5]; +/*0x10*/ +}; + +typedef struct SPI SPI; +struct SPI { + ushort spmode; + uchar res1[4]; + uchar spie; + uchar res2[3]; + uchar spim; + uchar res3[2]; + uchar spcom; + uchar res4[2]; +}; + +typedef struct Bankmap Bankmap; +struct Bankmap { +/*0*/ ulong br; /* Base register bank 32 bits 10.3.1/10-14 */ +/*4*/ ulong or; /* Option register bank 32 bits 10.3.2/10-16 */ +/*8*/ +}; + +typedef struct Port Port; +struct Port { +/*0x00*/ ulong pdir; /* Port A data direction register 32 bits 35.2.3/35-3 */ +/*0x04*/ ulong ppar; /* Port Apin assignment register 32 bits 35.2.4/35-4 */ +/*0x08*/ ulong psor; /* Port A special options register 32 bits 35.2.5/35-4 */ +/*0x0C*/ ulong podr; /* Port Aopen drain register 32 bits 35.2.1/35-2 */ +/*0x10*/ ulong pdat; /* Port A data register 32 bits 35.2.2/35-2 */ +/*0x14*/ uchar Rsvd14[12]; +/*0x20*/ +}; + +typedef struct IDMA IDMA; +struct IDMA { +/*0x0*/ uchar idsr; /* IDMA event register 8 bits 18.8.4/18-22 */ +/*0x1*/ uchar Rsvd1[3]; +/*0x4*/ uchar idmr; /* IDMA mask register 8 bits 18.8.4/18-22 */ +/*0x5*/ uchar Rsvd5[3]; +/*0x8*/ +}; + +typedef struct PrmSCC PrmSCC; +struct PrmSCC { + uchar sccbytes[0x100]; +}; + +typedef struct PrmFCC PrmFCC; +struct PrmFCC { + uchar fccbytes[0x100]; +}; + +typedef struct Bases Bases; +struct Bases { +/*0x00*/ uchar mcc[0x80]; +/*0x80*/ uchar Rsvd80[0x60]; +/*0xe0*/ uchar risctimers[0x10]; +/*0xf0*/ ushort revnum; +/*0xf2*/ uchar Rsvdf2[6]; +/*0xf8*/ ulong rand; +/*0xfc*/ ushort smcbase; +#define i2cbase smcbase +/*0xfe*/ ushort idmabase; +/*0x100*/ +}; + +typedef struct Uartsmc Uartsmc; +struct Uartsmc { +/*0x00*/ IOCparam; +/*0x28*/ ushort maxidl; +/*0x2a*/ ushort idlc; +/*0x2c*/ ushort brkln; +/*0x2e*/ ushort brkec; +/*0x30*/ ushort brkcr; +/*0x32*/ ushort r_mask; +/*0x34*/ ulong sdminternal; +/*0x38*/ uchar Rsvd38[8]; +/*0x40*/ +}; + +typedef struct SI SI; +struct SI { +/*0x11B20*/ ushort siamr; /* SI TDMA1 mode register 16 bits 14.5.2/14-17 */ +/*0x11B22*/ ushort sibmr; /* SI TDMB1 mode register 16 bits */ +/*0x11B24*/ ushort sicmr; /* SI TDMC1 mode register 16 bits */ +/*0x11B26*/ ushort sidmr; /* SI TDMD1 mode register 16 bits */ +/*0x11B28*/ uchar sigmr; /* SI global mode register 8 bits 14.5.1/14-17 */ +/*0x11B29*/ uchar Rsvd11B29; +/*0x11B2A*/ ushort sicmdr; /* SI command register 8 bits 14.5.4/14-24 */ +/*0x11B2C*/ ushort sistr; /* SI status register 8 bits 14.5.5/14-25 */ +/*0x11B2E*/ ushort sirsr; /* SI RAM shadow address register 16 bits 14.5.3/14-23 */ +}; + +typedef struct RegMap RegMap; +struct RegMap { +/* General SIU */ +/*0x10000*/ ulong siumcr; /* SIU module configuration register 32 bits 4.3.2.6/4-31 */ +/*0x10004*/ ulong sypcr; /* System protection control register 32 bits 4.3.2.8/4-35 */ +/*0x10008*/ uchar Rsvd10008[0xe-0x8]; +/*0x1000E*/ ushort swsr; /* Softwareservice register 16 bits 4.3.2.9/4-36 */ +/*0x10010*/ uchar Rsvd10010[0x14]; +/*0x10024*/ ulong bcr; /* Bus configuration register 32 bits 4.3.2.1/4-25 */ +/*0x10028*/ ulong PPC_ACR; /* 60x bus arbiter configuration register 8 bits 4.3.2.2/4-28 */ +/*0x1002C*/ ulong PPCALRH; /* 60x bus arbitration-level register high (first 8 clients) 32 bits 4.3.2.3/4-28 */ +/*0x10030*/ ulong PPC_ALRL; /* 60x bus arbitration-level register low (next 8 clients) 32 bits 4.3.2.3/4-28 */ +/*0x10034*/ ulong LCL_ACR; /* Local arbiter configuration register 8 bits 4.3.2.4/4-29 */ +/*0x10038*/ ulong LCL_ALRH; /* Local arbitration-level register (first 8 clients) 32 bits 4.3.2.5/4-30 */ + +/*0x1003C*/ ulong LCL_ALRL; /* Local arbitration-level register (next 8 clients) 32 bits 4.3.2.3/4-28 */ +/*0x10040*/ ulong TESCR1; /* 60x bus transfer error status control register1 32 bits 4.3.2.10/4-36 */ +/*0x10044*/ ulong TESCR2; /* 60x bus transfer error status control register2 32 bits 4.3.2.11/4-37 */ +/*0x10048*/ ulong L_TESCR1; /* Local bus transfer error status control register1 32 bits 4.3.2.12/4-38 */ +/*0x1004C*/ ulong L_TESCR2; /* Local bus transfer error status control register2 32 bits 4.3.2.13/4-39 */ +/*0x10050*/ ulong pdtea; /* 60x bus DMAtransfer error address 32 bits 18.2.3/18-4 */ +/*0x10054*/ uchar pdtem; /* 60x bus DMAtransfer error MSNUM 8 bits 18.2.4/18-4 */ +/*0x10055*/ uchar Rsvd10055[3]; +/*0x10058*/ void* ldtea; /* Local bus DMA transfer error address 32 bits 18.2.3/18-4 */ +/*0x1005C*/ uchar ldtem; /* Local bus DMA transfer error MSNUM 8 bits 18.2.4/18-4 */ +/*0x1005D*/ uchar Rsvd1005D[163]; + +/* Memory Controller */ +/*0x10100*/ Bankmap bank[12]; + +/*0x10160*/ uchar Rsvd10160[8]; +/*0x10168*/ void* MAR; /* Memory address register 32 bits 10.3.7/10-29 */ +/*0x1016C*/ ulong Rsvd1016C; +/*0x10170*/ ulong MAMR; /* Machine A mode register 32 bits 10.3.5/10-26 */ +/*0x10174*/ ulong MBMR; /* Machine B mode register 32 bits */ +/*0x10178*/ ulong MCMR; /* Machine C mode register 32 bits */ +/*0x1017C*/ uchar Rsvd1017C[6]; +/*0x10184*/ ulong mptpr; /* Memory periodic timer prescaler 16 bits 10.3.12/10-32 */ +/*0x10188*/ ulong mdr; /* Memorydata register 32 bits 10.3.6/10-28 */ +/*0x1018C*/ ulong Rsvd1018C; +/*0x10190*/ ulong psdmr; /* 60x bus SDRAM mode register 32 bits 10.3.3/10-21 */ +/*0x10194*/ ulong lsdmr; /* Local bus SDRAM mode register 32 bits 10.3.4/10-24 */ +/*0x10198*/ ulong PURT; /* 60x bus-assigned UPM refresh timer 8 bits 10.3.8/10-30 */ +/*0x1019C*/ ulong PSRT; /* 60x bus-assigned SDRAM refresh timer 8 bits 10.3.10/10-31 */ + +/*0x101A0*/ ulong LURT; /* Local bus-assigned UPM refresh timer8 bits 10.3.9/10-30 */ +/*0x101A4*/ ulong LSRT; /* Local bus-assigned SDRAM refresh timer 8 bits 10.3.11/10-32 */ + +/*0x101A8*/ ulong immr; /* Internal memory map register 32 bits 4.3.2.7/4-34 */ +/*0x101AC*/ uchar Rsvd101AC[84]; +/* System Integration Timers */ +/*0x10200*/ uchar Rsvd10200[32]; +/*0x10220*/ ulong TMCNTSC; /* Time counter statusand control register 16 bits 4.3.2.14/4-40 */ + +/*0x10224*/ ulong TMCNT; /* Time counter register 32 bits 4.3.2.15/4-41 */ +/*0x10228*/ ulong Rsvd10228; +/*0x1022C*/ ulong TMCNTAL; /* Time counter alarm register 32 bits 4.3.2.16/4-41 */ +/*0x10230*/ uchar Rsvd10230[0x10]; +/*0x10240*/ ulong PISCR; /* Periodic interrupt statusand control register 16 bits 4.3.3.1/4-42 */ + +/*0x10244*/ ulong PITC; /* Periodic interrupt count register 32 bits 4.3.3.2/4-43 */ +/*0x10248*/ ulong PITR; /* Periodic interrupt timer register 32 bits 4.3.3.3/4-44 */ +/*0x1024C*/ uchar Rsvd1024C[94]; +/*0x102AA*/ uchar Rsvd102AA[2390]; + +/* Interrupt Controller */ +/*0x10C00*/ ushort sicr; /* SIU interrupt configuration register 16 bits 4.3.1.1/4-17 */ +/*0x10C02*/ ushort Rsvd10C02; +/*0x10C04*/ ulong sivec; /* SIU interrupt vector register 32 bits 4.3.1.6/4-23 */ +/*0x10C08*/ ulong sipnr_h; /* SIU interrupt pending register(high) 32 bits 4.3.1.4/4-21 */ +/*0x10C0C*/ ulong sipnr_l; /* SIU interrupt pending register(low) 32 bits 4.3.1.4/4-21 */ +/*0x10C10*/ ulong siprr; /* SIU interrupt priority register 32 bits 4.3.1.2/4-18 */ +/*0x10C14*/ ulong scprr_h; /* CPM interrupt priority register(high) 32 bits 4.3.1.3/4-19 */ +/*0x10C18*/ ulong scprr_l; /* CPM interrupt priority register(low) 32 bits 4.3.1.3/4-19 */ +/*0x10C1C*/ ulong simr_h; /* SIU interrupt mask register(high) 32 bits 4.3.1.5/4-22 */ +/*0x10C20*/ ulong simr_l; /* SIU interrupt mask register(low) 32 bits 4.3.1.5/4-22 */ +/*0x10C24*/ ulong siexr; /* SIUexternal interrupt control register 32 bits 4.3.1.7/4-24 */ +/*0x10C28*/ uchar Rsvd10C28[88]; + +/* Clocks and Reset */ +/*0x10C80*/ ulong sccr; /* System clock control register 32 bits 9.8/9-8 */ +/*0x10C84*/ uchar Rsvd10C84[4]; +/*0x10C88*/ ulong scmr; /* System clock mode register 32 bits 9.9/9-9 */ +/*0x10C8C*/ uchar Rsvd10C8C[4]; +/*0x10C90*/ ulong rsr; /* Reset status register 32 bits 5.2/5-4 */ +/*0x10C94*/ ulong rmr; /* Reset mode register 32 bits 5.3/5-5 */ +/*0x10C98*/ uchar Rsvd10C98[104]; + +/* Part I.Overview Input/Output Port */ +/*0x10D00*/ Port port[4]; + +/* CPMTimers */ +/*0x10D80*/ uchar tgcr1; /* Timer1 and timer2 global configuration register 8 bits 17.2.2/17-4 */ + +/*0x10D81*/ uchar Rsvd10D81[3]; +/*0x10D84*/ uchar tgcr2; /* Timer3 and timer4 global configuration register 8 bits 17.2.2/17-4 */ +/*0x10D85*/ uchar Rsvd10D85[3]; + +/*0x10D88*/ uchar Rsvd10D88[8]; +/*0x10D90*/ ushort tmr1; /* Timer1 mode register 16 bits 17.2.3/17-6 */ +/*0x10D92*/ ushort tmr2; /* Timer2 mode register 16 bits 17.2.3/17-6 */ + union{ + struct { +/*0x10D94*/ ushort trr1; /* Timer1 reference register 16 bits 17.2.4/17-7 */ +/*0x10D96*/ ushort trr2; /* Timer2 reference register 16 bits 17.2.4/17-7 */ + }; +/*0x10D94*/ ulong trrl1; /* Combined Timer 1/2 trr register */ + }; + union{ + struct { +/*0x10D98*/ ushort tcr1; /* Timer1 capture register 16 bits 17.2.5/17-8 */ +/*0x10D9A*/ ushort tcr2; /* Timer2 capture register 16 bits 17.2.5/17-8 */ + }; +/*0x10D98*/ ulong tcrl1; /* Combined timer1/2 capture register */ + }; + union{ + struct { +/*0x10D9C*/ ushort tcn1; /* Timer1 counter 16 bits 17.2.6/17-8 */ +/*0x10D9E*/ ushort tcn2; /* Timer2 counter 16 bits 17.2.6/17-8 */ + }; +/*0x10D9C*/ ulong tcnl1; /* Combined timer1/2 counter */ + }; +/*0x10DA0*/ ushort tmr3; /* Timer3 mode register 16 bits 17.2.3/17-6 */ +/*0x10DA2*/ ushort tmr4; /* Timer4 mode register 16 bits 17.2.3/17-6 */ + union{ + struct { +/*0x10DA4*/ ushort trr3; /* Timer3 reference register 16 bits 17.2.4/17-7 */ +/*0x10DA6*/ ushort trr4; /* Timer4 reference register 16 bits 17.2.4/17-7 */ + }; +/*0x10DA4*/ ulong trrl3; + }; + union{ + struct { +/*0x10DA8*/ ushort tcr3; /* Timer3 capture register 16 bits 17.2.5/17-8 */ +/*0x10DAA*/ ushort tcr4; /* Timer4 capture register 16 bits 17.2.5/17-8 */ + }; +/*0x10DA8*/ ulong tcrl3; + }; + union{ + struct { +/*0x10DAC*/ ushort tcn3; /* Timer3 counter 16 bits 17.2.6/17-8 */ +/*0x10DAE*/ ushort tcn4; /* Timer4 counter 16 bits 17.2.6/17-8 */ + }; +/*0x10DAC*/ ulong tcnl3; + }; +/*0x10DB0*/ ushort ter1; /* Timer1 event register 16 bits 17.2.7/17-8 */ +/*0x10DB2*/ ushort ter2; /* Timer2 event register 16 bits 17.2.7/17-8 */ +/*0x10DB4*/ ushort ter3; /* Timer3 event register 16 bits 17.2.7/17-8 */ +/*0x10DB6*/ ushort ter4; /* Timer4 event register 16 bits 17.2.7/17-8 */ +/*0x10DB8*/ uchar Rsvd10DB8[608]; + +/* SDMADHGeneral */ +/*0x11018*/ uchar sdsr; /* SDMA status register 8 bits 18.2.1/18-3 */ +/*0x11019*/ uchar Rsvd11019[3]; +/*0x1101C*/ uchar sdmr; /* SDMA mask register 8 bits 18.2.2/18-4 */ +/*0x1101D*/ uchar Rsvd1101D[3]; + +/* IDMA */ +/*0x11020*/ IDMA idma[4]; + +/*0x11040*/ uchar Rsvd11040[704]; + +/*0x11300*/ FCC fcc[3]; + +/*0x11360*/ uchar Rsvd11360[0x290]; + +/* BRGs5DH8 */ +/*0x115F0*/ ulong BRGC5; /* BRG5 configuration register 32 bits 16.1/16-2 */ +/*0x115F4*/ ulong BRGC6; /* BRG6configuration register 32 bits */ +/*0x115F8*/ ulong BRGC7; /* BRG7configuration register 32 bits */ +/*0x115FC*/ ulong BRGC8; /* BRG8configuration register 32 bits */ +/*0x11600*/ uchar Rsvd11600[0x260]; +/*0x11860*/ uchar I2MOD; /* I2C mode register 8 bits 34.4.1/34-6 */ +/*0x11861*/ uchar Rsvd11861[3]; +/*0x11864*/ uchar I2ADD; /* I2C address register 8 bits 34.4.2/34-7 */ +/*0x11865*/ uchar Rsvd11865[3]; +/*0x11868*/ uchar I2BRG; /* I2C BRG register 8 bits 34.4.3/34-7 */ +/*0x11869*/ uchar Rsvd11869[3]; +/*0x1186C*/ uchar I2COM; /* I2C command register 8 bits 34.4.5/34-8 */ +/*0x1186D*/ uchar Rsvd1186D[3]; +/*0x11870*/ uchar I2CER; /* I2C event register 8 bits 34.4.4/34-8 */ +/*0x11871*/ uchar Rsvd11871[3]; +/*0x11874*/ uchar I2CMR; /* I2C mask register 8 bits 34.4.4/34-8 */ +/*0x11875*/ uchar Rsvd11875[331]; + +/* Communications Processor */ +/*0x119C0*/ ulong cpcr; /* Communications processor command register 32 bits 13.4.1/13-11 */ + +/*0x119C4*/ ulong rccr; /* CP configuration register 32 bits 13.3.6/13-7 */ +/*0x119C8*/ uchar Rsvd119C8[14]; +/*0x119D6*/ ushort rter; /* CP timers event register 16 bits 13.6.4/13-21 */ +/*0x119D8*/ ushort Rsvd119D8; +/*0x119DA*/ ushort rtmr; /* CP timers mask register 16 bits */ +/*0x119DC*/ ushort rtscr; /* CPtime-stamp timer control register 16 bits 13.3.7/13-9 */ +/*0x119DE*/ ushort Rsvd119DE; +/*0x119E0*/ ulong rtsr; /* CPtime-stamp register 32 bits 13.3.8/13-10 */ +/*0x119E4*/ uchar Rsvd119E4[12]; + +/*0x119F0*/ ulong brgc[4]; /* BRG configuration registers 32 bits 16.1/16-2 */ + +/*0x11A00*/ SCC scc[4]; + +/*0x11A80*/ SMC smc[2]; + + SPI; + +/*0x11AB0*/ uchar Rsvd11AB0[80]; + +/* CPMMux */ +/*0x11B00*/ uchar cmxsi1cr; /* CPM mux SI1clock route register 8 bits 15.4.2/15-10 */ +/*0x11B01*/ uchar Rsvd11B01; +/*0x11B02*/ uchar cmxsi2cr; /* CPM mux SI2clock route register 8 bits 15.4.3/15-11 */ +/*0x11B03*/ uchar Rsvd11B03; +/*0x11B04*/ ulong cmxfcr; /* CPM mux FCC clock route register 32 bits 15.4.4/15-12 */ +/*0x11B08*/ ulong cmxscr; /* CPM mux SCC clock route register 32 bits 15.4.5/15-14 */ +/*0x11B0C*/ uchar cmxsmr; /* CPM mux SMC clock route register 8 bits 15.4.6/15-17 */ +/*0x11B0D*/ uchar Rsvd11B0D; +/*0x11B0E*/ ushort cmxuar; /* CPM mux UTOPIA address register 16 bits 15.4.1/15-7 */ +/*0x11B10*/ uchar Rsvd11B10[16]; + + SI si1; /* SI 1 Registers */ + +/* MCC1Registers */ +/*0x11B30*/ ushort MCCE1; /* MCC1 event register 16 bits 27.10.1/27-18 */ +/*0x11B32*/ ushort Rsvd11B32; +/*0x11B34*/ ushort MCCM1; /* MCC1 mask register 16 bits */ +/*0x11B36*/ ushort Rsvd11B36; +/*0x11B38*/ uchar MCCF1; /* MCC1 configuration register 8 bits 27.8/27-15 */ +/*0x11B39*/ uchar Rsvd11B39[7]; + + SI si2; /* SI 2 Registers */ + +/* MCC2Registers */ +/*0x11B50*/ ushort MCCE2; /* MCC2 event register 16 bits 27.10.1/27-18 */ +/*0x11B52*/ ushort Rsvd11B52; +/*0x11B54*/ ushort MCCM2; /* MCC2 mask register 16 bits */ +/*0x11B56*/ ushort Rsvd11B56; +/*0x11B58*/ uchar MCCF2; /* MCC2 configuration register 8 bits 27.8/27-15 */ +/*0x11B59*/ uchar Rsvd11B59[1191]; + +/* SI1RAM */ +/*0x12000*/ uchar SI1TxRAM[0x200];/* SI1 transmit routing RAM 512 14.4.3/14-10 */ +/*0x12200*/ uchar Rsvd12200[0x200]; +/*0x12400*/ uchar SI1RxRAM[0x200];/* SI1 receive routing RAM 512 14.4.3/14-10 */ +/*0x12600*/ uchar Rsvd12600[0x200]; + +/* SI2RAM */ +/*0x12800*/ uchar SI2TxRAM[0x200];/* SI2 transmit routing RAM 512 14.4.3/14-10 */ +/*0x12A00*/ uchar Rsvd12A00[0x200]; +/*0x12C00*/ uchar SI2RxRAM[0x200];/* SI2 receive routing RAM 512 14.4.3/14-10 */ +/*0x12E00*/ uchar Rsvd12E00[0x200]; +/*0x13000*/ uchar Rsvd13000[0x800]; +/*0x13800*/ uchar Rsvd13800[0x800]; +}; + +typedef struct FCCextra FCCextra; +struct FCCextra { +/*0x00*/ uchar ri[0x20]; +/*0x20*/ uchar ti[0x20]; +/*0x40*/ uchar pad[0x20]; +}; + +typedef struct IMM IMM; +struct IMM { +/* CPMDual-Port RAM */ +/*0x00000*/ uchar dpram1[0x3800]; /* Dual-port RAM 16Kbytes 13.5/13-15 */ +/*0x03800*/ FCCextra fccextra[4]; +/*0x03980*/ Uartsmc uartsmc[2]; +/*0x03a00*/ uchar dsp1p[0x40]; +/*0x03a40*/ uchar dsp2p[0x40]; +/*0x03a80*/ BD bd[(0x04000-0x03a80)/sizeof(BD)]; /* Buffer descriptors */ +/*0x04000*/ uchar Rsvd4000[0x04000]; + +/* Dual port RAM bank 2 -- Parameter Ram, Section 13.5 */ +/*0x08000*/ PrmSCC prmscc[4]; +/*0x08400*/ PrmFCC prmfcc[3]; +/*0x08700*/ Bases param[4]; +/*0x08b00*/ uchar dpram2[0x500]; + +/*0x09000*/ uchar Rsvd9000[0x2000]; + +/* Dual port RAM bank 3 -- Section 13.5 */ +/*0x0B000*/ uchar dpram3[0x1000]; /* Dual-port RAM 4Kbytes 13.5/13-15 */ +/*0x0C000*/ uchar Rsvdc000[0x4000]; + +/*0x10000*/ RegMap; +}; + +enum { +/* CPM Command register. */ + cpm_rst = 0x80000000, + cpm_page = 0x7c000000, + cpm_sblock = 0x03e00000, + cpm_flg = 0x00010000, + cpm_mcn = 0x00003fc0, + cpm_opcode = 0x0000000f, + +/* Device sub-block and page codes. */ + cpm_fcc1_sblock = 0x10, + cpm_fcc2_sblock = 0x11, + cpm_fcc3_sblock = 0x12, + cpm_scc1_sblock = 0x04, + cpm_scc2_sblock = 0x05, + cpm_scc3_sblock = 0x06, + cpm_scc4_sblock = 0x07, + cpm_smc1_sblock = 0x08, + cpm_smc2_sblock = 0x09, + cpm_rand_sblock = 0x0e, + cpm_spi_sblock = 0x0a, + cpm_i2c_sblock = 0x0b, + cpm_timer_sblock = 0x0f, + cpm_mcc1_sblock = 0x1c, + cpm_mcc2_sblock = 0x1d, + cpm_idma1_sblock = 0x14, + cpm_idma2_sblock = 0x15, + cpm_idma3_sblock = 0x16, + cpm_idma4_sblock = 0x17, + + cpm_scc1_page = 0x00, + cpm_scc2_page = 0x01, + cpm_scc3_page = 0x02, + cpm_scc4_page = 0x03, + cpm_smc1_page = 0x07, + cpm_smc2_page = 0x08, + cpm_spi_page = 0x09, + cpm_i2c_page = 0x0a, + cpm_timer_page = 0x0a, + cpm_rand_page = 0x0a, + cpm_fcc1_page = 0x04, + cpm_fcc2_page = 0x05, + cpm_fcc3_page = 0x06, + cpm_idma1_page = 0x07, + cpm_idma2_page = 0x08, + cpm_idma3_page = 0x09, + cpm_idma4_page = 0x0a, + cpm_mcc1_page = 0x07, + cpm_mcc2_page = 0x08, + +}; + +/* + * CPM + */ +enum { + /* commands */ + InitRxTx = 0, + InitRx = 1, + InitTx = 2, + EnterHunt= 3, + StopTx= 4, + GracefulStopTx = 5, + InitIDMA = 5, + RestartTx = 6, + CloseRxBD = 7, + SetGroupAddr = 8, + SetTimer = 8, + GCITimeout = 9, + GCIAbort = 10, + StopIDMA = 11, + StartDSP = 12, + ArmIDMA = 13, + InitDSP = 13, + USBCmd = 15, + + /* channel IDs */ + SCC1ID= cpm_scc1_page << 5 | cpm_scc1_sblock, + SCC2ID= cpm_scc2_page << 5 | cpm_scc2_sblock, + SCC3ID= cpm_scc3_page << 5 | cpm_scc3_sblock, + SMC1ID= cpm_smc1_page << 5 | cpm_smc1_sblock, + SMC2ID= cpm_smc2_page << 5 | cpm_smc2_sblock, + FCC1ID= cpm_fcc1_page << 5 | cpm_fcc1_sblock, + FCC2ID= cpm_fcc2_page << 5 | cpm_fcc2_sblock, + FCC3ID= cpm_fcc3_page << 5 | cpm_fcc3_sblock, +// USBID= 0, These are wrong +// I2CID= 1, +// IDMA1ID= 1, +// SPIID= 5, +// IDMA2ID= 5, +// TIMERID= 5, +// DSP1ID=9, +// SCC4ID= 10, +// DSP2ID= 13, + + /* sicr */ + BRG1 = 0, + BRG2 = 1, + BRG3 = 2, + BRG4 = 4, + CLK1 = 4, + CLK2 = 5, + CLK3 = 6, + CLK4 = 7, + +}; + +extern IMM* imm; +extern int uartsmcoffset[]; + +BD* bdalloc(int); +void cpmop(int, int, int); +void ioplock(void); +void iopunlock(void); +void kreboot(ulong); --- /sys/src/9/ppc/l.s Tue Apr 15 22:21:42 2014 +++ /sys/src/9/ppc/l.s Tue Apr 15 22:21:42 2014 @@ -381,6 +381,22 @@ BNE xdecloop RETURN +TEXT cmpswap(SB),$0 /* int cmpswap(long*, long, long) */ + MOVW R3, R4 /* addr */ + MOVW old+4(FP), R5 + MOVW new+8(FP), R6 + DCBF (R4) /* fix for 603x bug? */ + LWAR (R4), R3 + CMP R3, R5 + BNE fail + STWCCC R6, (R4) + BNE fail + MOVW $1, R3 + RETURN +fail: + MOVW $0, R3 + RETURN + TEXT tlbflushall(SB), $0 MOVW $TLBENTRIES, R3 MOVW R3, CTR --- /sys/src/9/ppc/m8260.c Tue Apr 15 22:21:42 2014 +++ /sys/src/9/ppc/m8260.c Tue Apr 15 22:21:42 2014 @@ -116,6 +116,7 @@ */ IMM* iomem = (IMM*)IOMEM; +uchar etheraddr[6] = { 0x90, 0x85, 0x82, 0x32, 0x83, 0x00}; static Lock cpmlock; @@ -233,7 +234,8 @@ * if PLAN9INI == ~0, it's not stored in flash or there is no flash * if *cp == 0xff, flash memory is not initialized */ - if (PLAN9INI == ~0 || *(plan9inistr = (char*)(FLASHMEM+PLAN9INI)) == 0xff){ + if (PLAN9INI == ~0 || + (uchar)*(plan9inistr = (char*)(FLASHMEM+PLAN9INI)) == 0xff){ /* No plan9.ini in flash */ plan9inistr = "console=0\n" @@ -397,8 +399,23 @@ return ticks.val; } +ulong multiplier; + +ulong +µs(void) +{ + uvlong x; + + if(multiplier == 0){ + multiplier = (uvlong)(1000000LL << 16) / m->cyclefreq; + print("µs: multiplier %ld, cyclefreq %lld, shifter %d\n", multiplier, m->cyclefreq, 16); + } + cycles(&x); + return (x*multiplier) >> 16; +} + void -timerset(uvlong next) +timerset(Tval next) { long offset; uvlong now; --- /sys/src/9/ppc/mkfile Tue Apr 15 22:21:42 2014 +++ /sys/src/9/ppc/mkfile Tue Apr 15 22:21:42 2014 @@ -12,7 +12,6 @@ PORT=\ alarm.$O\ - alloc.$O\ allocb.$O\ auth.$O\ cache.$O\ @@ -33,12 +32,10 @@ qlock.$O\ rdb.$O\ segment.$O\ - noswap.$O\ sysfile.$O\ sysproc.$O\ taslock.$O\ tod.$O\ - xalloc.$O\ OBJ=\ l.$O\ @@ -65,8 +62,10 @@ /$objtype/lib/libmemlayer.a\ /$objtype/lib/libmemdraw.a\ /$objtype/lib/libdraw.a\ - /$objtype/lib/libc.a\ /$objtype/lib/libsec.a\ + /$objtype/lib/libmp.a\ + /$objtype/lib/libip.a\ + /$objtype/lib/libc.a\ ETHER=`{echo devether.c ether*.c | sed 's/\.c/.'$O'/g'} VGA=`{echo devvga.c screen.c vga*.c | sed 's/\.c/.'$O'/g'} @@ -104,6 +103,6 @@ $AS init9.s $LD -l -s -R4 -o init.out init9.$O initcode.$O /power/lib/libc.a {echo 'uchar initcode[]={' - strip < init.out | xd -1x | + strip -o /fd/1 init.out | xd -1x | sed -e 's/^[0-9a-f]+ //' -e 's/ ([0-9a-f][0-9a-f])/0x\1,/g' echo '};'} > init.h --- /sys/src/9/ppc/saturntimer.c Tue Apr 15 22:21:42 2014 +++ /sys/src/9/ppc/saturntimer.c Tue Apr 15 22:21:42 2014 @@ -26,6 +26,21 @@ static Lock tlock; static ushort timer_ctl; +ulong multiplier; + +ulong +µs(void) +{ + uvlong x; + + if(multiplier == 0){ + multiplier = (uvlong)(1000000LL << 16) / m->cyclefreq; + print("µs: multiplier %ld, cyclefreq %lld, shifter %d\n", multiplier, m->cyclefreq, 16); + } + cycles(&x); + return (x*multiplier) >> 16; +} + void saturntimerintr(Ureg *u, void*) { @@ -72,7 +87,7 @@ } void -timerset(uvlong next) +timerset(Tval next) { ulong offset; uvlong now; --- /sys/src/9/ppc/trap.c Tue Apr 15 22:21:42 2014 +++ /sys/src/9/ppc/trap.c Tue Apr 15 22:21:42 2014 @@ -11,6 +11,18 @@ static Lock vctllock; Vctl *vctl[256]; +int intrstack[5]; +uvlong intrtime[5]; +vlong lastoffset; +int inintr; +int nintr[10]; +int nintro; +int dblintr[64]; +ulong thisto[32]; +ulong thistoo; +vlong vnot[64]; +ulong vnon[64]; + void intrenable(int irq, void (*f)(Ureg*, void*), void* a, char *name) { @@ -152,7 +164,6 @@ tos->kcycles += t - up->kentry; tos->pcycles = up->pcycles; tos->pid = up->pid; - tos->machno = m->machno; } void @@ -161,7 +172,6 @@ int ecode, user; char buf[ERRMAX], *s; extern FPsave initfp; - Proc *uprock; ecode = (ureg->cause >> 8) & 0xff; user = (ureg->srr1 & MSR_PR) != 0; @@ -175,10 +185,7 @@ switch(ecode) { case CEI: m->intr++; - uprock = up; - up = nil; intr(ureg); - up = uprock; break; case CDEC: clockintr(ureg); @@ -392,6 +399,63 @@ vp[n] = 0x4e800021; /* BL (LR) */ }else vp[n] = (18<<26)|(pa&0x3FFFFFC)|3; /* bla */ +} + + +void +intr(Ureg *ureg) +{ + int vno, pvno, i; + Vctl *ctl, *v; + void (*pt)(Proc*, int, vlong); + uvlong tt, x; + + cycles(&tt); + pt = proctrace; + pvno = -1; + for(i = 0; i < 64; i++){ + vno = intvec(); + if(vno == 0) + break; + cycles(&x); + vnot[vno] -= x; + if(vno == pvno) + dblintr[vno]++; + pvno = vno; + if(pt && up && up->trace) + pt(up, (vno << 16) | SInts, 0); + + if(vno > nelem(vctl) || (ctl = vctl[vno]) == 0) { + iprint("spurious intr %d\n", vno); + return; + } + + for(v = ctl; v != nil; v = v->next) + if(v->f) + v->f(ureg, v->a); + + intend(vno); /* reenable the interrupt */ + + if(pt && up && up->trace) + pt(up, (vno << 16) | SInte, 0); + cycles(&x); + vnot[vno] += x; + vnon[vno]++; + } + if(i < nelem(nintr)) + nintr[i]++; + else + nintro++; + cycles(&x); + tt = x - tt; + i = tt / 3600; /* 100 microseconds units */ + if(i < nelem(thisto)) + thisto[i]++; + else + thistoo++; + + if(up) + preempted(); } char* --- /sys/src/9/ppc/uartsmc.c Tue Apr 15 22:21:42 2014 +++ /sys/src/9/ppc/uartsmc.c Tue Apr 15 22:21:42 2014 @@ -97,6 +97,57 @@ } void +smcsetup(Uart *uart) +{ + Uartsmc *p; + SMC *smc; + UartData *ud; + + ud = uart->regs; + + /* magic addresses */ + + p = &m->immr->uartsmc[ud->smcno]; + smc = imm->smc + ud->smcno; /* SMC1 */ + ud->smc = smc; + ud->usmc = p; + + /* step 0: disable rx/tx */ + smc->smcmr &= ~3; + + ioplock(); + + /* step 1, Using Port D */ + if (ud->smcno != 0) + panic("Don't know how to set Port D bits"); + imm->port[SMC1PORT].ppar |= SMRXD1|SMTXD1; + imm->port[SMC1PORT].pdir |= SMTXD1; + imm->port[SMC1PORT].pdir &= ~SMRXD1; + imm->port[SMC1PORT].psor &= ~(SMRXD1|SMTXD1); + + /* step 2: set up brgc1 */ + imm->brgc[ud->smcno] = baudgen(uart->baud) | 0x10000; + + /* step 3: route clock to SMC1 */ + imm->cmxsmr &= (ud->smcno == 0) ? ~0xb0 : ~0xb; /* clear smcx and smcxcs */ + + iopunlock(); + + /* step 4: assign a pointer to the SMCparameter RAM */ + m->immr->param[ud->smcno].smcbase = (ulong)p - IMMR; + + /* step 6: issue command to CP */ + if (ud->smcno == 0) + cpmop(InitRxTx, SMC1ID, 0); + else + cpmop(InitRxTx, SMC2ID, 0); + + /* step 7: protocol parameters */ + p->rfcr = 0x30; + p->tfcr = 0x30; +} + +void smcinit(Uart *uart) { Uartsmc *p; @@ -220,7 +271,7 @@ sp = ((UartData*)uart->regs)->smc; snprint(p, sizeof p, "b%d c%d e%d l%d m0 p%c s%d i1\n" - "dev(%d) type(%d) framing(%d) overruns(%d)\n", + "dev(%d) framing(%d) overruns(%d)\n", uart->baud, uart->hup_dcd, @@ -230,7 +281,6 @@ (sp->smcmr & Sl) ? 2: 1, uart->dev, - uart->type, uart->ferr, uart->oerr ); --- /sys/src/9/ppc/uartsmc.h Thu Jan 1 00:00:00 1970 +++ /sys/src/9/ppc/uartsmc.h Tue Apr 15 22:21:42 2014 @@ -0,0 +1,17 @@ + +typedef struct UartData UartData; +struct UartData +{ + int smcno; /* smc number: 0 or 1 */ + SMC *smc; + Uartsmc *usmc; + char *rxbuf; + char *txbuf; + BD* rxb; + BD* txb; + int initialized; + int enabled; +} uartdata[Nuart]; + +int baudgen(int); +void smcsetup(Uart *uart); --- /sys/src/9/ppc/ucu Tue Apr 15 22:21:42 2014 +++ /sys/src/9/ppc/ucu Tue Apr 15 22:21:42 2014 @@ -22,6 +22,11 @@ netdevmedium misc + alloc + physalloc + noswap + xalloc + uartsaturn saturntimer msaturn @@ -58,4 +63,4 @@ /power/bin/ls /power/bin/ps /power/bin/auth/wrkey - /sys/lib/sysconfig/blast/boot + /sys/lib/sysconfig/ppc/boot