From 1fa8857738caefec81086e270ccb4161e03d5891 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Tue, 4 Jun 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-06-04 --- "bitsy/dev\302\265c.c" | 20 +++--- bitsy/etherwavelan.c | 134 ++++++++++++++++++++++------------------- bitsy/fns.h | 4 +- bitsy/l.s | 52 ++++++++++++++-- bitsy/power.c | 24 ++++++-- bitsy/trap.c | 15 ----- 6 files changed, 154 insertions(+), 95 deletions(-) diff --git "a/bitsy/dev\302\265c.c" "b/bitsy/dev\302\265c.c" index 88aa62f0c9e31b8398be2bf1adfdfabd96819419..d6fa239b0597c9daefe6bd07338a065edb4cbb13 100644 --- "a/bitsy/dev\302\265c.c" +++ "b/bitsy/dev\302\265c.c" @@ -15,7 +15,7 @@ enum{ Qkbdin, Qled, Qversion, - Qsuspend, + Qpower, /* command types */ BLversion= 0, @@ -58,7 +58,7 @@ Dirtab µcdir[]={ "kbdin", { Qkbdin, 0 }, 0, 0664, "led", { Qled, 0 }, 0, 0664, "version", { Qversion, 0 }, 0, 0664, - "suspend", { Qsuspend, 0 }, 0, 0222, + "power", { Qpower, 0 }, 0, 0600, }; static struct µcontroller @@ -353,8 +353,8 @@ static long char str[64]; int i, j; Rune r; - extern Rendez powerr; - extern ulong powerflag; + extern ulong resumeaddr[]; + extern void power_resume(void); if(c->qid.path == Qkbdin){ if(n >= sizeof(str)) @@ -367,13 +367,17 @@ static long } return n; } - if(c->qid.path == Qsuspend){ + if(c->qid.path == Qpower){ if(!iseve()) error(Eperm); - if(strncmp(a, "suspend", 7) != 0) + if(strncmp(a, "suspend", 7) == 0) + *resumeaddr = (ulong)power_resume; + else if(strncmp(a, "halt", 4) == 0) + *resumeaddr = 0; + else error(Ebadarg); - powerflag = 1; - wakeup(&powerr); + deepsleep(); + return n; } cmd = parsecmd(a, n); diff --git a/bitsy/etherwavelan.c b/bitsy/etherwavelan.c index af7c7b57d4f8b625ab9cc0c7d4b3f9804f9aa0d4..16c93dc70337f1175987ca7e9ac0cd5598033f68 100644 --- a/bitsy/etherwavelan.c +++ b/bitsy/etherwavelan.c @@ -27,67 +27,10 @@ #include "../port/netif.h" #include "etherif.h" -#define DEBUG if(1)print +#define DEBUG if(1){}else print #define SEEKEYS 0 -typedef struct Ctlr Ctlr; -typedef struct Wltv Wltv; -typedef struct WFrame WFrame; -typedef struct Stats Stats; -typedef struct WStats WStats; -typedef struct WKey WKey; - -struct WStats -{ - ulong ntxuframes; // unicast frames - ulong ntxmframes; // multicast frames - ulong ntxfrags; // fragments - ulong ntxubytes; // unicast bytes - ulong ntxmbytes; // multicast bytes - ulong ntxdeferred; // deferred transmits - ulong ntxsretries; // single retries - ulong ntxmultiretries; // multiple retries - ulong ntxretrylimit; - ulong ntxdiscards; - ulong nrxuframes; // unicast frames - ulong nrxmframes; // multicast frames - ulong nrxfrags; // fragments - ulong nrxubytes; // unicast bytes - ulong nrxmbytes; // multicast bytes - ulong nrxfcserr; - ulong nrxdropnobuf; - ulong nrxdropnosa; - ulong nrxcantdecrypt; - ulong nrxmsgfrag; - ulong nrxmsgbadfrag; - ulong end; -}; - -struct WFrame -{ - ushort sts; - ushort rsvd0; - ushort rsvd1; - ushort qinfo; - ushort rsvd2; - ushort rsvd3; - ushort txctl; - ushort framectl; - ushort id; - uchar addr1[Eaddrlen]; - uchar addr2[Eaddrlen]; - uchar addr3[Eaddrlen]; - ushort seqctl; - uchar addr4[Eaddrlen]; - ushort dlen; - uchar dstaddr[Eaddrlen]; - uchar srcaddr[Eaddrlen]; - ushort len; - ushort dat[3]; - ushort type; -}; - // Lucent's Length-Type-Value records to talk to the wavelan. // most operational parameters are read/set using this. enum @@ -191,6 +134,9 @@ enum WR_Data0 = 0x36, WR_Data1 = 0x38, + WR_PciCor = 0x26, + WR_PciHcr = 0x2E, + // Frame stuff WF_Err = 0x0003, @@ -212,9 +158,62 @@ enum }; -#define csr_outs(ctlr,r,arg) outs((ctlr)->iob+(r),(arg)) -#define csr_ins(ctlr,r) ins((ctlr)->iob+(r)) -#define csr_ack(ctlr,ev) outs((ctlr)->iob+WR_EvAck,(ev)) +typedef struct Ctlr Ctlr; +typedef struct Wltv Wltv; +typedef struct WFrame WFrame; +typedef struct Stats Stats; +typedef struct WStats WStats; +typedef struct WKey WKey; + +struct WStats +{ + ulong ntxuframes; // unicast frames + ulong ntxmframes; // multicast frames + ulong ntxfrags; // fragments + ulong ntxubytes; // unicast bytes + ulong ntxmbytes; // multicast bytes + ulong ntxdeferred; // deferred transmits + ulong ntxsretries; // single retries + ulong ntxmultiretries; // multiple retries + ulong ntxretrylimit; + ulong ntxdiscards; + ulong nrxuframes; // unicast frames + ulong nrxmframes; // multicast frames + ulong nrxfrags; // fragments + ulong nrxubytes; // unicast bytes + ulong nrxmbytes; // multicast bytes + ulong nrxfcserr; + ulong nrxdropnobuf; + ulong nrxdropnosa; + ulong nrxcantdecrypt; + ulong nrxmsgfrag; + ulong nrxmsgbadfrag; + ulong end; +}; + +struct WFrame +{ + ushort sts; + ushort rsvd0; + ushort rsvd1; + ushort qinfo; + ushort rsvd2; + ushort rsvd3; + ushort txctl; + ushort framectl; + ushort id; + uchar addr1[Eaddrlen]; + uchar addr2[Eaddrlen]; + uchar addr3[Eaddrlen]; + ushort seqctl; + uchar addr4[Eaddrlen]; + ushort dlen; + uchar dstaddr[Eaddrlen]; + uchar srcaddr[Eaddrlen]; + ushort len; + ushort dat[3]; + ushort type; +}; struct WKey { @@ -252,6 +251,7 @@ struct Wltv struct Stats { ulong nints; + ulong ndoubleint; ulong nrx; ulong ntx; ulong ntxrq; @@ -301,10 +301,22 @@ struct Ctlr Wltv keys; // default keys int xclear; // exclude clear packets off/on + int ctlrno; + + /* for PCI-based devices */ + Ctlr *next; + ushort *mmb; + int active; + Pcidev *pcidev; + Stats; WStats; }; +#define csr_outs(ctlr,r,arg) outs((ctlr)->iob+(r),(arg)) +#define csr_ins(ctlr,r) ins((ctlr)->iob+(r)) +#define csr_ack(ctlr,ev) outs((ctlr)->iob+WR_EvAck,(ev)) + // w_... routines do not ilock the Ctlr and should // be called locked. diff --git a/bitsy/fns.h b/bitsy/fns.h index 6fe8dd2f5668fe5bf9c0fb9a4f47a073f0c41e4a..f03b38d87d20900f28be5e3ca64c88cf163fde76 100644 --- a/bitsy/fns.h +++ b/bitsy/fns.h @@ -20,9 +20,9 @@ void clockpower(int); void delay(int); void µdelay(ulong); void µcpower(int); +void deepsleep(void); void dmainit(void); -void _doze(void); -void (*doze)(void); +void doze(void); void egpiobits(ulong, int); void evenaddr(ulong); void exppackpower(int); diff --git a/bitsy/l.s b/bitsy/l.s index 53e82b6f7c90598f4c15d894c45ad2d26445f65c..89f12f41224f28283b8104e616653e13096e3b9e 100644 --- a/bitsy/l.s +++ b/bitsy/l.s @@ -772,7 +772,31 @@ l12: SUB $1,R0 /* 6 */ MOVW $1,R2 - /* Follow the procedure */ +TEXT power_magic(SB), $-4 + /* power_code gets copied into the area of no-ops below, + * at a cache-line boundary (8 instructions) + */ + MOVW R0, R0 + MOVW R0, R0 + MOVW R0, R0 + MOVW R0, R0 + MOVW R0, R0 + MOVW R0, R0 + MOVW R0, R0 + MOVW R0, R0 + MOVW R0, R0 + MOVW R0, R0 + MOVW R0, R0 + MOVW R0, R0 + MOVW R0, R0 + MOVW R0, R0 + MOVW R0, R0 + MOVW R0, R0 + +TEXT power_code(SB), $-4 + /* Follow the procedure; this code gets copied to the no-op + * area preceding this code + */ /* 1 */ MOVW R1, 0x10(R5) MOVW R7, 0x14(R5) @@ -791,12 +815,13 @@ slloop: B slloop /* loop waiting for sleep */ /* The first MCR instruction of this function needs to be on a cache-line - * boundary; to make this happen, it will be copied (in trap.c). + * boundary; to make this happen, it will be copied to the first cache-line + * boundary 8 words from the start of doze. * * Doze puts the machine into idle mode. Any interrupt will get it out * at the next instruction (the RET, to be precise). */ -TEXT _doze(SB), $-4 +TEXT doze(SB), $-4 MOVW $UCDRAMZERO, R1 MOVW R0,R0 MOVW R0,R0 @@ -805,7 +830,26 @@ TEXT _doze(SB), $-4 MOVW R0,R0 MOVW R0,R0 MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + RET + +TEXT doze_code(SB), $-4 MCR CpPWR, 0, R0, C(CpTest), C(0x2), 2 MOVW (R1), R0 MCR CpPWR, 0, R0, C(CpTest), C(0x8), 2 - RET diff --git a/bitsy/power.c b/bitsy/power.c index 4e75b03dc2f671235ffd6141a1ef1ea42e1f7e88..96899359db6006b0510f39be5bf5b352099d05d3 100644 --- a/bitsy/power.c +++ b/bitsy/power.c @@ -30,7 +30,6 @@ Intrregs savedintrregs; uchar *savedtext; - static void checkflash(void) { @@ -165,14 +164,13 @@ powerdown(void *) void deepsleep(void) { static int power_pl; - ulong xsp, xlink, mecr; + ulong xsp, xlink; +// ulong mecr; extern void power_resume(void); power_pl = splhi(); xlink = getcallerpc(&xlink); - *resumeaddr = (ulong) power_resume; -// *resumeaddr = nil; /* Power down */ irpower(0); audiopower(0); @@ -188,7 +186,7 @@ deepsleep(void) { intrcpy(&savedintrregs, intrregs); cacheflush(); delay(50); - mecr = memconfregs->mecr; +// mecr = memconfregs->mecr; if(setpowerlabel()){ /* return here with mmu back on */ trapresume(); @@ -281,6 +279,22 @@ blanktimer(void) void powerinit(void) { + extern ulong power_magic; + extern ulong power_code; + extern ulong doze_code; + ulong *p, *q, i; + + p = (ulong*)(((ulong)&power_magic + 0x1f) & ~0x1f); + q = &power_code; + for (i = 0; i < 8; i++) + *p++ = *q++; + p = (ulong*)(((ulong)doze + 0x3f) & ~0x1f); + q = &doze_code; + for (i = 0; i < 3; i++) + *p++ = *q++; + + + *resumeaddr = (ulong) power_resume; addclock0link(blanktimer); intrenable(GPIOrising, bitno(GPIO_PWR_ON_i), onoffintr, nil, "on/off"); } diff --git a/bitsy/trap.c b/bitsy/trap.c index d2f1e4c58e4662c5e7ee2020ced25cd36476c3ad..dd423a471f57ed66e16973c7b25b07dcdcac40be 100644 --- a/bitsy/trap.c +++ b/bitsy/trap.c @@ -30,12 +30,6 @@ typedef struct Vpage0 { } Vpage0; Vpage0 *vpage0; -/* - * A cached line for the doze and hibernate code - */ -void (*doze)(void); -void (*hibernate)(void); - static void irq(Ureg*); static void gpiointr(Ureg*, void*); @@ -66,15 +60,6 @@ trapinit(void) memmove(vpage0->vectors, vectors, sizeof(vpage0->vectors)); memmove(vpage0->vtable, vtable, sizeof(vpage0->vtable)); - /* relocate the doze and hibernate routines - * to a cache line boundary in cached mem - */ - doze = xspanalloc(12*sizeof(long), 16, 0); - memmove(doze, _doze, 12*sizeof(long)); -#ifdef notdef - hibernate = xspanalloc(8*sizeof(long), 16, 0); - memmove(hibernate, _hibernate, 8*sizeof(long)); -#endif wbflush(); /* use exception vectors at 0xFFFF0000 */