From 617f6d975acf4b1b6060d389fb60de9a33eefbd6 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Mon, 18 Jun 2001 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2001-06-18 --- bitsy/clock.c | 13 ++- "bitsy/dev\302\265c.c" | 14 +++ bitsy/fns.h | 5 ++ bitsy/io.h | 70 ++++++++++++++- bitsy/l.s | 182 +++++++++++++++++++++++++++++++++++++++ bitsy/main.c | 6 ++ bitsy/mem.h | 45 +++++----- bitsy/power.c | 187 +++++++++++++++++++++++++++++++++-------- bitsy/screen.c | 14 +++ bitsy/trap.c | 35 +++++--- bitsy/uartsa1110.c | 10 --- 11 files changed, 498 insertions(+), 83 deletions(-) diff --git a/bitsy/clock.c b/bitsy/clock.c index cde343e696788230c59524d603236498c79e8394..aa9114c93789d0a1e3309fe8a5b01feebd004039 100644 --- a/bitsy/clock.c +++ b/bitsy/clock.c @@ -16,11 +16,22 @@ typedef struct OSTimer ulong oier; /* timer interrupt enable register */ } OSTimer; -static OSTimer *timerregs = (OSTimer*)OSTIMERREGS; +OSTimer *timerregs = (OSTimer*)OSTIMERREGS; static int clockinited; static void clockintr(Ureg*, void*); +void +clockpower(int on) +{ + + if (on){ + timerregs->ossr |= 1<<0; + timerregs->oier = 1<<0; + timerregs->osmr[0] = timerregs->oscr + ClockFreq/HZ; + } +} + void clockinit(void) { diff --git "a/bitsy/dev\302\265c.c" "b/bitsy/dev\302\265c.c" index 3b197612a0e3768b31cbf4a3867d5e90ec73bed6..a5b0a084efc328cd7078fd1d3756656a3a628334 100644 --- "a/bitsy/dev\302\265c.c" +++ "b/bitsy/dev\302\265c.c" @@ -379,6 +379,20 @@ static long return n; } +void +µcpower(int on) +{ + uchar data[16]; + if (on == 0) + return; + /* maybe dangerous, not holding the lock */ + data[0]= 2; + data[1]= 1; + data[2]= 0x80; + _sendmsg(0xd, data, 3); + wakeup(&ctlr.r); +} + Dev µcdevtab = { 'r', "µc", diff --git a/bitsy/fns.h b/bitsy/fns.h index cc974b6acd06effd3a39fd4d501181165bb28666..1cd2a73f1af58b30cfd1fe7a096eadd9f3af3cf8 100644 --- a/bitsy/fns.h +++ b/bitsy/fns.h @@ -9,10 +9,12 @@ void dcacheinvalidate(void); int cistrcmp(char*, char*); int cistrncmp(char*, char*, int); void clockinit(void); +void clockpower(int); #define coherence() #define dcflush(a, b) void delay(int); void µdelay(ulong); +void µcpower(int); void dmainit(void); void _doze(void); void (*doze)(void); @@ -67,6 +69,7 @@ PCMmap* pcmmap(int, ulong, int, int); void pcmunmap(int, PCMmap*); void penbutton(int, int); void pentrackxy(int x, int y); +void powerinit(void); #define procrestore(p) void procsave(Proc*); void procsetup(Proc*); @@ -78,6 +81,7 @@ void rs232power(int); void uartspecial(Uart*, int, Queue**, Queue**, int (*)(Queue*, int)); void sa1110_uartsetup(int); void screeninit(void); +void screenpower(int); int screenprint(char*, ...); /* debugging */ void serialµcputs(uchar *str, int n); void setr13(int, ulong*); @@ -85,6 +89,7 @@ uchar* tarlookup(uchar*, char*, int*); void touser(void*); void trapdump(char *tag); void trapinit(void); +void trapresume(void); int tas(void*); int uartstageoutput(Uart*); void uartkick(void*); diff --git a/bitsy/io.h b/bitsy/io.h index 6791a662535d5dea396d08019bdd38719638b7b8..bcac6f2767cdee0ada1e40a8070de9e2d79d4ce9 100644 --- a/bitsy/io.h +++ b/bitsy/io.h @@ -130,7 +130,8 @@ struct Uartregs ulong dummyb; ulong status[2]; }; -Uartregs *uart3regs; +extern Uartregs *uart3regs; +extern Uartregs *uart1regs; /* general purpose I/O lines control registers */ typedef struct GPIOregs GPIOregs; @@ -246,6 +247,17 @@ extern MemConfRegs *memconfregs; /* * power management */ + +/* Power management ops */ +enum { + PCFR_suspend = 1, + + PCFR_opde = 1, + PCFR_fp = 2, + PCFR_fs = 4, + PCFR_fo = 8, +}; + typedef struct PowerRegs PowerRegs; struct PowerRegs { @@ -259,3 +271,59 @@ struct PowerRegs ulong posr; /* Power manager oscillator status register */ }; extern PowerRegs *powerregs; + +/* + * reset controller + */ + +enum +{ + RCSR_hwr = 0x00000001, /* hw reset */ + RCSR_swr = 0x00000002, /* sw reset */ + RCSR_wdr = 0x00000004, /* watch dog */ + RCSR_smr = 0x00000008, /* sleep mode reset */ + RCSR_all = 0x0000000f, +}; + +typedef struct ResetRegs ResetRegs; +struct ResetRegs +{ + ulong rsrr; /* reset controller software reset register */ + ulong rcsr; /* reset controller status register */ +}; +extern ResetRegs *resetregs; + +typedef struct OSTimerRegs OSTimerRegs; +struct OSTimerRegs +{ + ulong osmr[4]; /* match registers */ + ulong oscr; /* counter register */ + ulong ossr; /* status register */ + ulong ower; /* watchdog enable register */ + ulong oier; /* timer interrupt enable register */ +}; +extern OSTimerRegs* timerregs; + +typedef struct Intrregs Intrregs; +struct Intrregs +{ + ulong icip; /* pending IRQs */ + ulong icmr; /* IRQ mask */ + ulong iclr; /* IRQ if bit == 0, FRIQ if 1 */ + ulong iccr; /* control register */ + ulong icfp; /* pending FIQs */ + ulong dummy1[3]; + ulong icpr; /* pending interrupts */ +}; +extern Intrregs *intrregs; + +typedef struct Gpclkregs Gpclkregs; +struct Gpclkregs +{ + ulong r0; + ulong r1; + ulong dummya; + ulong r2; + ulong r3; +}; +extern Gpclkregs *gpclkregs; diff --git a/bitsy/l.s b/bitsy/l.s index 2ef3f0f858ba577999bad430651083774efedb03..84174dff66f4ba01671225540d008979869b9643 100644 --- a/bitsy/l.s +++ b/bitsy/l.s @@ -443,6 +443,188 @@ TEXT gotolabel(SB), $-4 MOVW $1, R0 RET +/* save the state machine in power_resume[] for an upcoming suspend + */ +TEXT setpowerlabel(SB), $-4 + MOVW $power_resume+0(SB), R0 + /* svc */ /* power_resume[]: what */ + MOVW R1, 0(R0) + MOVW R2, 4(R0) + MOVW R3, 8(R0) + MOVW R4, 12(R0) + MOVW R5, 16(R0) + MOVW R6, 20(R0) + MOVW R7, 24(R0) + MOVW R8, 28(R0) + MOVW R9, 32(R0) + MOVW R10,36(R0) + MOVW R11,40(R0) + MOVW R12,44(R0) + MOVW R13,48(R0) + MOVW R14,52(R0) + MOVW SPSR, R1 + MOVW R1, 56(R0) + MOVW CPSR, R2 + MOVW R2, 60(R0) + /* copro */ + MRC CpMMU, 0, R3, C(CpDAC), C(0x0) + MOVW R3, 144(R0) + MRC CpMMU, 0, R3, C(CpTTB), C(0x0) + MOVW R3, 148(R0) + MRC CpMMU, 0, R3, C(CpControl), C(0x0) + MOVW R3, 152(R0) + MRC CpMMU, 0, R3, C(CpFSR), C(0x0) + MOVW R3, 156(R0) + MRC CpMMU, 0, R3, C(CpFAR), C(0x0) + MOVW R3, 160(R0) + MRC CpMMU, 0, R3, C(CpPID), C(0x0) + MOVW R3, 164(R0) + /* irq */ + BIC $(PsrMask), R2, R3 + ORR $(PsrDirq|PsrMirq), R3 + MOVW R3, CPSR + MOVW SPSR, R11 + MOVW R11, 64(R0) + MOVW R12, 68(R0) + MOVW R13, 72(R0) + MOVW R14, 76(R0) + /* und */ + BIC $(PsrMask), R2, R3 + ORR $(PsrDirq|PsrMund), R3 + MOVW R3, CPSR + MOVW SPSR, R11 + MOVW R11, 80(R0) + MOVW R12, 84(R0) + MOVW R13, 88(R0) + MOVW R14, 92(R0) + /* abt */ + BIC $(PsrMask), R2, R3 + ORR $(PsrDirq|PsrMabt), R3 + MOVW R3, CPSR + MOVW SPSR, R11 + MOVW R11, 96(R0) + MOVW R12, 100(R0) + MOVW R13, 104(R0) + MOVW R14, 108(R0) + /* fiq */ + BIC $(PsrMask), R2, R3 + ORR $(PsrDirq|PsrMfiq), R3 + MOVW R3, CPSR + MOVW SPSR, R7 + MOVW R7, 112(R0) + MOVW R8, 116(R0) + MOVW R9, 120(R0) + MOVW R10,124(R0) + MOVW R11,128(R0) + MOVW R12,132(R0) + MOVW R13,136(R0) + MOVW R14,140(R0) + /* done */ + MOVW R2, CPSR + MOVW R1, SPSR + MOVW $0, R0 + RET + +/* Entered after a resume from suspend state. + * The bootldr jumps here after a processor reset. + */ +TEXT sa1100_power_resume(SB), $-4 + MOVW $setR12(SB), R12 /* load the SB */ + /* SVC mode, interrupts disabled */ + MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1 + MOVW R1, CPSR + /* flush caches */ + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0 + /* drain prefetch */ + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + MOVW R0,R0 + /* drain write buffer */ + MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4 + /* gotopowerlabel() */ + /* svc */ + MOVW $power_resume+0(SB), R0 + MOVW 56(R0), R1 /* R1: SPSR, R2: CPSR */ + MOVW 60(R0), R2 + /* copro */ + MOVW 148(R0), R3 + MCR CpMMU, 0, R3, C(CpTTB), C(0x0) + MOVW 144(R0), R3 + MCR CpMMU, 0, R3, C(CpDAC), C(0x0) + MOVW 152(R0), R3 + MCR CpMMU, 0, R3, C(CpControl), C(0x0) + MOVW 156(R0), R3 + MCR CpMMU, 0, R3, C(CpFSR), C(0x0) + MOVW 160(R0), R3 + MCR CpMMU, 0, R3, C(CpFAR), C(0x0) + MOVW 164(R0), R3 + MCR CpMMU, 0, R3, C(CpPID), C(0x0) + MCR CpMMU, 0, R0, C(CpTLBFlush), C(0x7) + /* irq */ + BIC $(PsrMask), R2, R3 + ORR $(PsrDirq|PsrMirq), R3 + MOVW R3, CPSR + MOVW 64(R0), R11 + MOVW 68(R0), R12 + MOVW 72(R0), R13 + MOVW 76(R0), R14 + MOVW R11, SPSR + /* und */ + BIC $(PsrMask), R2, R3 + ORR $(PsrDirq|PsrMund), R3 + MOVW R3, CPSR + MOVW 80(R0), R11 + MOVW 84(R0), R12 + MOVW 88(R0), R13 + MOVW 92(R0), R14 + MOVW R11, SPSR + /* abt */ + BIC $(PsrMask), R2, R3 + ORR $(PsrDirq|PsrMabt), R3 + MOVW R3, CPSR + MOVW 96(R0), R11 + MOVW 100(R0), R12 + MOVW 104(R0), R13 + MOVW 108(R0), R14 + MOVW R11, SPSR + /* fiq */ + BIC $(PsrMask), R2, R3 + ORR $(PsrDirq|PsrMfiq), R3 + MOVW R3, CPSR + MOVW 112(R0), R7 + MOVW 116(R0), R8 + MOVW 120(R0), R9 + MOVW 124(R0), R10 + MOVW 128(R0), R11 + MOVW 132(R0), R12 + MOVW 136(R0), R13 + MOVW 140(R0), R14 + MOVW R7, SPSR + /* svc */ + MOVW 56(R0), R1 + MOVW 60(R0), R2 + MOVW R1, SPSR + MOVW R2, CPSR + MOVW 0(R0), R1 + MOVW 4(R0), R2 + MOVW 8(R0), R3 + MOVW 12(R0),R4 + MOVW 16(R0),R5 + MOVW 20(R0),R6 + MOVW 24(R0),R7 + MOVW 28(R0),R8 + MOVW 32(R0),R9 + MOVW 36(R0),R10 + MOVW 40(R0),R11 + MOVW 44(R0),R12 + MOVW 48(R0),R13 + MOVW 52(R0),R14 + RET +loop: + B loop + + /* 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). diff --git a/bitsy/main.c b/bitsy/main.c index c63dd4aeba8d98da1ba42124f42bb7363fdca52f..2d05c000dc3fb7a0bdc102b10f1641ad0ef4ec4e 100644 --- a/bitsy/main.c +++ b/bitsy/main.c @@ -37,6 +37,7 @@ main(void) trapinit(); sa1110_uartsetup(1); rs232power(1); + powerinit(); dmainit(); screeninit(); printinit(); /* from here on, print works, before this we need iprint */ @@ -362,6 +363,8 @@ ulong *egpioreg = (ulong*)EGPIOREGS; PPCregs *ppcregs; MemConfRegs *memconfregs; PowerRegs *powerregs; +ResetRegs *resetregs; +OSTimerRegs *timerregs = (OSTimerRegs*)OSTIMERREGS; /* * configure the machine @@ -395,6 +398,9 @@ machinit(void) /* memory configuraton */ memconfregs = mapspecial(MEMCONFREGS, 32); + + /* reset controller */ + resetregs = mapspecial(RESETREGS, 32); } diff --git a/bitsy/mem.h b/bitsy/mem.h index 49fdba17ec04a0d11bf80dcf3f54700caa8e55fc..cebb68746e8e15b510ebee2bd84de6893b9e311b 100644 --- a/bitsy/mem.h +++ b/bitsy/mem.h @@ -6,23 +6,23 @@ * Sizes */ #define BI2BY 8 /* bits per byte */ -#define BI2WD 32 /* bits per word */ +#define BI2WD 32 /* bits per word */ #define BY2WD 4 /* bytes per word */ #define BY2V 8 /* bytes per double word */ #define BY2PG 4096 /* bytes per page */ #define WD2PG (BY2PG/BY2WD) /* words per page */ #define PGSHIFT 12 /* log(BY2PG) */ -#define ROUND(s, sz) (((s)+(sz-1))&~(sz-1)) -#define PGROUND(s) ROUND(s, BY2PG) +#define ROUND(s, sz) (((s)+(sz-1))&~(sz-1)) +#define PGROUND(s) ROUND(s, BY2PG) #define BLOCKALIGN 8 -#define MAXMACH 1 /* max # cpus system can run */ +#define MAXMACH 1 /* max # cpus system can run */ /* * Time */ #define HZ (20) /* clock frequency */ -#define MS2HZ (1000/HZ) /* millisec per clock tick */ +#define MS2HZ (1000/HZ) /* millisec per clock tick */ #define TK2SEC(t) ((t)/HZ) /* ticks to seconds */ #define TK2MS(t) ((((ulong)(t))*1000)/HZ) /* ticks to milliseconds */ #define MS2TK(t) ((((ulong)(t))*HZ)/1000) /* milliseconds to ticks */ @@ -41,8 +41,8 @@ * kernel. This can be changed by providing a mapping in l.s * before calling main. */ -#define UZERO 0 /* base of user address space */ -#define UTZERO (UZERO+BY2PG) /* first address in user text */ +#define UZERO 0 /* base of user address space */ +#define UTZERO (UZERO+BY2PG) /* first address in user text */ #define KZERO 0xC0000000 /* base of kernel address space */ #define KTZERO 0xC0008000 /* first address in kernel text */ #define EMEMZERO 0x90000000 /* 256 meg for add on memory */ @@ -52,19 +52,19 @@ #define FLASHZERO 0xB0000000 /* 128 meg for flash */ #define FLASHTOP 0xB8000000 /* ... */ #define DRAMZERO 0xC0000000 /* 128 meg for dram */ -#define DRAMTOP 0xC8000000 /* ... */ +#define DRAMTOP 0xC8000000 /* ... */ #define UCDRAMZERO 0xC8000000 /* 128 meg for dram (uncached/unbuffered) */ -#define UCDRAMTOP 0xD0000000 /* ... */ +#define UCDRAMTOP 0xD0000000 /* ... */ #define NULLZERO 0xE0000000 /* 128 meg for cache flush zeroes */ -#define NULLTOP 0xE8000000 /* ... */ +#define NULLTOP 0xE8000000 /* ... */ #define USTKTOP 0x2000000 /* byte just beyond user stack */ -#define USTKSIZE (8*1024*1024) /* size of user stack */ +#define USTKSIZE (8*1024*1024) /* size of user stack */ #define TSTKTOP (USTKTOP-USTKSIZE) /* end of new stack in sysexec */ -#define TSTKSIZ 100 -#define MACHADDR (KZERO+0x00001000) +#define TSTKSIZ 100 +#define MACHADDR (KZERO+0x00001000) #define EVECTORS 0xFFFF0000 /* virt base of exception vectors */ -#define KSTACK (32*1024) /* Size of kernel stack */ +#define KSTACK (16*1024) /* Size of kernel stack */ /* * Offsets into flash @@ -97,17 +97,18 @@ * peripheral control module physical addresses */ #define USBREGS 0x80000000 /* serial port 0 - USB */ -#define UART1REGS 0x80010000 /* serial port 1 - UART */ -#define GPCLKREGS 0x80020060 /* serial port 1 - general purpose clock */ -#define UART2REGS 0x80030000 /* serial port 2 - low speed IR */ -#define HSSPREGS 0x80040060 /* serial port 2 - high speed IR */ -#define UART3REGS 0x80050000 /* serial port 3 - RS232 UART */ +#define UART1REGS 0x80010000 /* serial port 1 - UART */ +#define GPCLKREGS 0x80020060 /* serial port 1 - general purpose clock */ +#define UART2REGS 0x80030000 /* serial port 2 - low speed IR */ +#define HSSPREGS 0x80040060 /* serial port 2 - high speed IR */ +#define UART3REGS 0x80050000 /* serial port 3 - RS232 UART */ #define MCPREGS 0x80060000 /* serial port 4 - multimedia comm port */ #define SSPREGS 0x80070060 /* serial port 4 - synchronous serial port */ #define OSTIMERREGS 0x90000000 /* operating system timer registers */ -#define POWERREGS 0x90020000 /* power management */ -#define GPIOREGS 0x90040000 /* 28 general purpose IO pins */ -#define INTRREGS 0x90050000 /* interrupt registers */ +#define POWERREGS 0x90020000 /* power management */ +#define RESETREGS 0x90030000 /* reset controller */ +#define GPIOREGS 0x90040000 /* 28 general purpose IO pins */ +#define INTRREGS 0x90050000 /* interrupt registers */ #define PPCREGS 0x90060000 /* peripheral pin controller */ #define MEMCONFREGS 0xA0000000 /* memory configuration */ #define LCDREGS 0xB0100000 /* display */ diff --git a/bitsy/power.c b/bitsy/power.c index 67e4b015bfaa397f70d64bc049ef74b4b5d1da83..056f722b834433938a373eac7d3fbbbb768ae9ea 100644 --- a/bitsy/power.c +++ b/bitsy/power.c @@ -9,73 +9,188 @@ /* Power management for the bitsy */ -#ifdef NOTDEF -enum { - pmcr_sf = 0, +/* saved state during power down. + * it's only used up to 164/4. + * it's only used by routines in l.s + */ +ulong power_resume[200/4]; - pcfr_opde = 0, - pcfr_fp = 1, - pcfr_fs = 2, - pcfr_fo = 3, -}; +extern void sa1100_power_resume(void); +extern int setpowerlabel(void); + + +GPIOregs savedgpioregs; +Uartregs saveduart3regs; +Uartregs saveduart1regs; +Intrregs savedintrregs; -jmp_buf power_resume; static void -onoffintr(Ureg*, void *x) +dumpitall(void) { - /* On/off button interrupt */ - int i; + iprint("intr: icip %lux iclr %lux iccr %lux icmr %lux\n", + intrregs->icip, + intrregs->iclr, intrregs->iccr, intrregs->icmr ); + iprint("gpio: lvl %lux dir %lux, re %lux, fe %lux sts %lux alt %lux\n", + gpioregs->level, + gpioregs->direction, gpioregs->rising, gpioregs->falling, + gpioregs->edgestatus, gpioregs->altfunc); + iprint("uart1: %lux %lux %lux \nuart3: %lux %lux %lux\n", + uart1regs->ctl[0], uart1regs->status[0], uart1regs->status[1], + uart3regs->ctl[0], uart3regs->status[0], uart3regs->status[1]); + iprint("tmr: osmr %lux %lux %lux %lux oscr %lux ossr %lux oier %lux\n", + timerregs->osmr[0], timerregs->osmr[1], + timerregs->osmr[2], timerregs->osmr[3], + timerregs->oscr, timerregs->ossr, timerregs->oier); + iprint("dram: mdcnfg %lux mdrefr %lux cas %lux %lux %lux %lux %lux %lux\n", + memconfregs->mdcnfg, memconfregs->mdrefr, + memconfregs->mdcas00, memconfregs->mdcas01,memconfregs->mdcas02, + memconfregs->mdcas20, memconfregs->mdcas21,memconfregs->mdcas22); + iprint("dram: mdcnfg msc %lux %lux %lux mecr %lux\n", + memconfregs->msc0, memconfregs->msc1,memconfregs->msc2, + memconfregs->mecr); + + +} + +static void +intrcpy(Intrregs *to, Intrregs *from) +{ + to->iclr = from->iclr; + to->iccr = from->iccr; + to->icmr = from->icmr; // interrupts enabled +} + +static void +uartcpy(Uartregs *to, Uartregs *from) +{ + to->ctl[0] = from->ctl[0]; +// to->ctl[1] = from->ctl[1]; +// to->ctl[2] = from->ctl[2]; + to->ctl[3] = from->ctl[3]; + +} + +static void +gpiocpy(GPIOregs *to, GPIOregs *from) +{ + to->rising = from->rising; // gpio intrs enabled + to->falling= from->falling; // gpio intrs enabled + to->altfunc = from->altfunc; + to->direction = from->direction; +} + +static void +sa1100_power_off(void) +{ + /* enable wakeup by µcontroller, on/off switch or real-time clock alarm */ + powerregs->pwer = 1 << IRQrtc | 1 << IRQgpio0 | 1 << IRQgpio1; + + /* clear previous reset status */ + resetregs->rcsr = RCSR_all; + + /* disable internal oscillator, float CS lines */ + powerregs->pcfr = PCFR_opde | PCFR_fp | PCFR_fs; + powerregs->pgsr = 0; + /* set resume address. The loader jumps to it */ + powerregs->pspr = (ulong)sa1100_power_resume; + /* set lowest clock; delay to avoid resume hangs on fast sa1110 */ + delay(90); + powerregs->ppcr = 0; + delay(90); + + /* set all GPIOs to input mode */ + gpioregs->direction = 0; + delay(100); + /* enter sleep mode */ + powerregs->pmcr = PCFR_suspend; + for(;;); +} - /* debounce, 50 ms*/ - for (i = 0; i < 50; i++) { +void +onoffintr(Ureg* , void*) +{ + static int power_pl; + int i; + for (i = 0; i < 100; i++) { delay(1); if ((gpioregs->level & GPIO_PWR_ON_i) == 0) return; /* bounced */ } - if (i = setjmp(power_resume)) { - /* power back up */ + power_pl = splhi(); + cachewb(); + delay(500); + if (setpowerlabel()) { + mmuinvalidate(); + mmuenable(); + cacheflush(); + trapresume(); rs232power(1); - lcdpower(1); - audiopower(1); irpower(1); + audiopower(1); + clockpower(1); + gpclkregs->r0 = 1<<0; + gpiocpy(gpioregs, &savedgpioregs); + intrcpy(intrregs, &savedintrregs); + if (intrregs->icip & (1<edgestatus = (1<icip = (1<status[0] = uart3regs->status[0]; + uartcpy(uart1regs,&saveduart1regs); + uart1regs->status[0] = uart1regs->status[0]; + µcpower(1); + screenpower(1); + iprint("\nresuming execution\n"); +// dumpitall(); + delay(800); + splx(power_pl); return; } /* Power down */ + iprint("\nentering suspend mode\n"); + gpiocpy(&savedgpioregs, gpioregs); + intrcpy(&savedintrregs, intrregs); + uartcpy(&saveduart3regs, uart3regs); + uartcpy(&saveduart1regs, uart1regs); + delay(400); + clockpower(0); irpower(0); audiopower(0); - lcdpower(0); + screenpower(0); + µcpower(0); rs232power(0); sa1100_power_off(); /* no return */ } -static void -sa1100_power_off(void) + + +static int +bitno(ulong x) { - delay(100); - splhi(); - /* enable wakeup by µcontroller, on/off switch or real-time clock alarm */ - powerregs->pwer = 0x80000003; - /* disable internal oscillator, float CS lines */ - powerregs->pcfr = 1<ppcr = 0; - /* set all GPIOs to input mode */ - gpioregs->direction = 0; - /* enter sleep mode */ - powerregs->pmcr = 1<lccr0 */ LEN = 0, /* 1 bit */ @@ -207,6 +209,18 @@ lcdtweak(Cmdbuf *cmd) | (atoi(cmd->f[3])<palette, sizeof framebuf->palette); + blankscreen(1); + } else { + memmove(framebuf->palette, savedpalette, sizeof framebuf->palette); + blankscreen(0); + } +} + void screeninit(void) { diff --git a/bitsy/trap.c b/bitsy/trap.c index 8936de5f8a7737b78b8f5ad8fd17f895d35ce3cf..893e9ef45497adf872cc29f2a55f9dbfda1b80f7 100644 --- a/bitsy/trap.c +++ b/bitsy/trap.c @@ -7,18 +7,7 @@ #include "ureg.h" #include "../port/error.h" -struct Intrregs -{ - ulong icip; /* pending IRQs */ - ulong icmr; /* IRQ mask */ - ulong iclr; /* IRQ if bit == 0, FRIQ if 1 */ - ulong iccr; /* control register */ - ulong icfp; /* pending FIQs */ - ulong dummy1[3]; - ulong icpr; /* pending interrupts */ -}; - -struct Intrregs *intrregs; +Intrregs *intrregs; typedef struct Vctl { Vctl* next; /* handlers on this vector */ @@ -49,8 +38,24 @@ void (*doze)(void); static void irq(Ureg*); static void gpiointr(Ureg*, void*); +/* recover state after power suspend + * NB: to help debugging bad suspend code, + * I changed some prints below to iprints, + * to avoid deadlocks when a panic is being + * issued during the suspend/resume handler. + */ +void +trapresume(void) +{ + vpage0 = (Vpage0*)EVECTORS; + memmove(vpage0->vectors, vectors, sizeof(vpage0->vectors)); + memmove(vpage0->vtable, vtable, sizeof(vpage0->vtable)); + wbflush(); + mappedIvecEnable(); +} + /* - * set up for exceptioons + * set up for exceptions */ void trapinit(void) @@ -751,8 +756,10 @@ _dumpstack(Ureg *ureg) ulong *p; extern ulong etext; - if(up == 0) + if(up == 0){ + print("no current proc\n"); return; + } print("ktrace /kernel/path %.8lux %.8lux %.8lux\n", ureg->pc, ureg->sp, ureg->r14); i = 0; diff --git a/bitsy/uartsa1110.c b/bitsy/uartsa1110.c index e57e6eb848a6b9b9ee6f6cc66adb22b388bf803c..f99d50d082079e9390101e3917e5f6b9a26f90ec 100644 --- a/bitsy/uartsa1110.c +++ b/bitsy/uartsa1110.c @@ -436,16 +436,6 @@ serialµcputs(uchar *str, int n) ; } -typedef struct Gpclkregs Gpclkregs; -struct Gpclkregs -{ - ulong r0; - ulong r1; - ulong dummya; - ulong r2; - ulong r3; -}; - enum { /* gpclk register 0 */