M bitsy/devµc.c => bitsy/devµc.c +12 -8
@@ 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);
M bitsy/etherwavelan.c => bitsy/etherwavelan.c +73 -61
@@ 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.
M bitsy/fns.h => bitsy/fns.h +2 -2
@@ 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);
M bitsy/l.s => bitsy/l.s +48 -4
@@ 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
M bitsy/power.c => bitsy/power.c +19 -5
@@ 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");
}
M bitsy/trap.c => bitsy/trap.c +0 -15
@@ 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 */