* [9fans] bitsy suspend fix
@ 2002-05-17 11:25 Fco.J.Ballesteros
0 siblings, 0 replies; only message in thread
From: Fco.J.Ballesteros @ 2002-05-17 11:25 UTC (permalink / raw)
To: 9fans
[-- Attachment #1: Type: text/plain, Size: 379 bytes --]
I found that the code as distributed caused permanent hangs (i.e.
not resuming) some times and it looks like it was causing a panic some times.
(Perhaps that's why it was doing a reset at resume time?).
I think this version works; at least I'm using it and did not make
weird things (yet).
The files are attached.
Let me know if this code fails for any of you.
hth
[-- Attachment #2.1: Type: text/plain, Size: 303 bytes --]
The following attachment had content that we can't
prove to be harmless. To avoid possible automatic
execution, we changed the content headers.
The original header was:
Content-Disposition: attachment; filename=l.s
Content-Type: text/plain; charset="US-ASCII"
Content-Transfer-Encoding: 7bit
[-- Attachment #2.2: l.s.suspect --]
[-- Type: application/octet-stream, Size: 18237 bytes --]
#include "mem.h"
/*
* Entered here from Compaq's bootldr with MMU disabled.
*/
TEXT _start(SB), $-4
MOVW $setR12(SB), R12 /* load the SB */
_main:
/* SVC mode, interrupts disabled */
MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1
MOVW R1, CPSR
/* disable the MMU */
MOVW $0x130, R1
MCR CpMMU, 0, R1, C(CpControl), C(0x0)
/* 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
MOVW $(MACHADDR+4*BY2PG), R13 /* stack */
SUB $4, R13 /* link */
BL main(SB)
BL exit(SB)
/* we shouldn't get here */
_mainloop:
B _mainloop
BL _div(SB) /* hack to get _div etc loaded */
/* flush tlb's */
TEXT mmuinvalidate(SB), $-4
MCR CpMMU, 0, R0, C(CpTLBFlush), C(0x7)
RET
/* flush tlb's */
TEXT mmuinvalidateaddr(SB), $-4
MCR CpMMU, 0, R0, C(CpTLBFlush), C(0x6), 1
RET
/* write back and invalidate i and d caches */
TEXT cacheflush(SB), $-4
/* splhi */
MOVW CPSR, R3
ORR $(PsrDirq), R3, R1
MOVW R1, CPSR
/* write back any dirty data */
MOVW $0xe0000000,R0
ADD $(8*1024),R0,R1
_cfloop:
MOVW.P 32(R0),R2
CMP.S R0,R1
BGE _cfloop
/* drain write buffer and invalidate i cache contents */
MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4
MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x5), 0
/* drain prefetch */
MOVW R0,R0
MOVW R0,R0
MOVW R0,R0
MOVW R0,R0
/* splx */
MOVW R3, CPSR
RET
/* write back d cache */
TEXT cachewb(SB), $-4
/* write back any dirty data */
_cachewb:
MOVW $0xe0000000,R0
ADD $(8*1024),R0,R1
_cwbloop:
MOVW.P 32(R0),R2
CMP.S R0,R1
BGE _cwbloop
/* drain write buffer */
MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4
RET
/* write back a single cache line */
TEXT cachewbaddr(SB), $-4
BIC $31,R0
MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 1
B _wbflush
/* write back a region of cache lines */
TEXT cachewbregion(SB), $-4
MOVW 4(FP),R1
CMP.S $(4*1024),R1
BGT _cachewb
ADD R0,R1
BIC $31,R0
_cwbrloop:
MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 1
ADD $32,R0
CMP.S R0,R1
BGT _cwbrloop
B _wbflush
/* invalidate the dcache */
TEXT dcacheinvalidate(SB), $-4
MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x6)
RET
/* invalidate the icache */
TEXT icacheinvalidate(SB), $-4
MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x9)
RET
/* drain write buffer */
TEXT wbflush(SB), $-4
_wbflush:
MCR CpMMU, 0, R0, C(CpCacheFlush), C(0xa), 4
RET
/* return cpu id */
TEXT getcpuid(SB), $-4
MRC CpMMU, 0, R0, C(CpCPUID), C(0x0)
RET
/* return fault status */
TEXT getfsr(SB), $-4
MRC CpMMU, 0, R0, C(CpFSR), C(0x0)
RET
/* return mmu control register */
TEXT getcontrol(SB), $-4
SUB R0, R0
MRC CpMMU, 0, R0, C(CpControl), C(0x0)
RET
/* return mmu dac register */
TEXT getdac(SB), $-4
SUB R0, R0
MRC CpMMU, 0, R0, C(CpDAC), C(0x0)
RET
/* return mmu ttb register */
TEXT getttb(SB), $-4
SUB R0, R0
MRC CpMMU, 0, R0, C(CpTTB), C(0x0)
RET
/* return fault address */
TEXT getfar(SB), $-4
MRC CpMMU, 0, R0, C(CpFAR), C(0x0)
RET
/* set the translation table base */
TEXT putttb(SB), $-4
MCR CpMMU, 0, R0, C(CpTTB), C(0x0)
RET
/*
* enable mmu, i and d caches
*/
TEXT mmuenable(SB), $-4
MRC CpMMU, 0, R0, C(CpControl), C(0x0)
ORR $(CpCmmuena|CpCdcache|CpCicache|CpCwb), R0
MCR CpMMU, 0, R0, C(CpControl), C(0x0)
MOVW R0, R0
MOVW R0, R0
MOVW R0, R0
MOVW R0, R0
RET
TEXT mmudisable(SB), $-4
MRC CpMMU, 0, R0, C(CpControl), C(0x0)
BIC $(CpCmmuena|CpCdcache|CpCicache|CpCwb|CpCvivec), R0
MCR CpMMU, 0, R0, C(CpControl), C(0x0)
RET
/*
* use exception vectors at 0xffff0000
*/
TEXT mappedIvecEnable(SB), $-4
MRC CpMMU, 0, R0, C(CpControl), C(0x0)
ORR $(CpCvivec), R0
MCR CpMMU, 0, R0, C(CpControl), C(0x0)
RET
TEXT mappedIvecDisable(SB), $-4
MRC CpMMU, 0, R0, C(CpControl), C(0x0)
BIC $(CpCvivec), R0
MCR CpMMU, 0, R0, C(CpControl), C(0x0)
RET
/* set the translation table base */
TEXT putdac(SB), $-4
MCR CpMMU, 0, R0, C(CpDAC), C(0x0)
RET
/* set address translation pid */
TEXT putpid(SB), $-4
MCR CpMMU, 0, R0, C(CpPID), C(0x0)
RET
/*
* set the stack value for the mode passed in R0
*/
TEXT setr13(SB), $-4
MOVW 4(FP), R1
MOVW CPSR, R2
BIC $PsrMask, R2, R3
ORR R0, R3
MOVW R3, CPSR
MOVW R13, R0
MOVW R1, R13
MOVW R2, CPSR
RET
/*
* exception vectors, copied by trapinit() to somewhere useful
*/
TEXT vectors(SB), $-4
MOVW 0x18(R15), R15 /* reset */
MOVW 0x18(R15), R15 /* undefined */
MOVW 0x18(R15), R15 /* SWI */
MOVW 0x18(R15), R15 /* prefetch abort */
MOVW 0x18(R15), R15 /* data abort */
MOVW 0x18(R15), R15 /* reserved */
MOVW 0x18(R15), R15 /* IRQ */
MOVW 0x18(R15), R15 /* FIQ */
TEXT vtable(SB), $-4
WORD $_vsvc(SB) /* reset, in svc mode already */
WORD $_vund(SB) /* undefined, switch to svc mode */
WORD $_vsvc(SB) /* swi, in svc mode already */
WORD $_vpabt(SB) /* prefetch abort, switch to svc mode */
WORD $_vdabt(SB) /* data abort, switch to svc mode */
WORD $_vsvc(SB) /* reserved */
WORD $_virq(SB) /* IRQ, switch to svc mode */
WORD $_vfiq(SB) /* FIQ, switch to svc mode */
TEXT _vrst(SB), $-4
BL resettrap(SB)
TEXT _vsvc(SB), $-4 /* SWI */
MOVW.W R14, -4(R13) /* ureg->pc = interupted PC */
MOVW SPSR, R14 /* ureg->psr = SPSR */
MOVW.W R14, -4(R13) /* ... */
MOVW $PsrMsvc, R14 /* ureg->type = PsrMsvc */
MOVW.W R14, -4(R13) /* ... */
MOVM.DB.W.S [R0-R14], (R13) /* save user level registers, at end r13 points to ureg */
MOVW $setR12(SB), R12 /* Make sure we've got the kernel's SB loaded */
MOVW R13, R0 /* first arg is pointer to ureg */
SUB $8, R13 /* space for argument+link */
BL syscall(SB)
ADD $(8+4*15), R13 /* make r13 point to ureg->type */
MOVW 8(R13), R14 /* restore link */
MOVW 4(R13), R0 /* restore SPSR */
MOVW R0, SPSR /* ... */
MOVM.DB.S (R13), [R0-R14] /* restore registers */
ADD $8, R13 /* pop past ureg->{type+psr} */
RFE /* MOVM.IA.S.W (R13), [R15] */
TEXT _vund(SB), $-4 /* undefined */
MOVM.IA [R0-R4], (R13) /* free some working space */
MOVW $PsrMund, R0
B _vswitch
TEXT _vpabt(SB), $-4 /* prefetch abort */
MOVM.IA [R0-R4], (R13) /* free some working space */
MOVW $PsrMabt, R0 /* r0 = type */
B _vswitch
TEXT _vdabt(SB), $-4 /* prefetch abort */
MOVM.IA [R0-R4], (R13) /* free some working space */
MOVW $(PsrMabt+1), R0 /* r0 = type */
B _vswitch
TEXT _virq(SB), $-4 /* IRQ */
MOVM.IA [R0-R4], (R13) /* free some working space */
MOVW $PsrMirq, R0 /* r0 = type */
B _vswitch
/*
* come here with type in R0 and R13 pointing above saved [r0-r4]
* and type in r0. we'll switch to SVC mode and then call trap.
*/
_vswitch:
MOVW SPSR, R1 /* save SPSR for ureg */
MOVW R14, R2 /* save interrupted pc for ureg */
MOVW R13, R3 /* save pointer to where the original [R0-R3] are */
/* switch to svc mode */
MOVW CPSR, R14
BIC $PsrMask, R14
ORR $(PsrDirq|PsrDfiq|PsrMsvc), R14
MOVW R14, CPSR
/* interupted code kernel or user? */
AND.S $0xf, R1, R4
BEQ _userexcep
/* here for trap from SVC mode */
MOVM.DB.W [R0-R2], (R13) /* set ureg->{type, psr, pc}; r13 points to ureg->type */
MOVM.IA (R3), [R0-R4] /* restore [R0-R4] from previous mode's stack */
MOVM.DB.W [R0-R14], (R13) /* save kernel level registers, at end r13 points to ureg */
MOVW $setR12(SB), R12 /* Make sure we've got the kernel's SB loaded */
MOVW R13, R0 /* first arg is pointer to ureg */
SUB $8, R13 /* space for argument+link (for debugger) */
MOVW $0xdeaddead,R11 /* marker */
BL trap(SB)
ADD $(8+4*15), R13 /* make r13 point to ureg->type */
MOVW 8(R13), R14 /* restore link */
MOVW 4(R13), R0 /* restore SPSR */
MOVW R0, SPSR /* ... */
MOVM.DB (R13), [R0-R14] /* restore registers */
ADD $8, R13 /* pop past ureg->{type+psr} */
RFE /* MOVM.IA.S.W (R13), [R15] */
/* here for trap from USER mode */
_userexcep:
MOVM.DB.W [R0-R2], (R13) /* set ureg->{type, psr, pc}; r13 points to ureg->type */
MOVM.IA (R3), [R0-R4] /* restore [R0-R4] from previous mode's stack */
MOVM.DB.W.S [R0-R14], (R13) /* save kernel level registers, at end r13 points to ureg */
MOVW $setR12(SB), R12 /* Make sure we've got the kernel's SB loaded */
MOVW R13, R0 /* first arg is pointer to ureg */
SUB $8, R13 /* space for argument+link (for debugger) */
BL trap(SB)
ADD $(8+4*15), R13 /* make r13 point to ureg->type */
MOVW 8(R13), R14 /* restore link */
MOVW 4(R13), R0 /* restore SPSR */
MOVW R0, SPSR /* ... */
MOVM.DB.S (R13), [R0-R14] /* restore registers */
ADD $8, R13 /* pop past ureg->{type+psr} */
RFE /* MOVM.IA.S.W (R13), [R15] */
TEXT _vfiq(SB), $-4 /* FIQ */
RFE /* FIQ is special, ignore it for now */
/*
* This is the first jump from kernel to user mode.
* Fake a return from interrupt.
*
* Enter with R0 containing the user stack pointer.
* UTZERO + 0x20 is always the entry point.
*
*/
TEXT touser(SB),$-4
/* store the user stack pointer into the USR_r13 */
MOVM.DB.W [R0], (R13)
MOVM.S.IA.W (R13),[R13]
/* set up a PSR for user level */
MOVW $(PsrMusr), R0
MOVW R0,SPSR
/* save the PC on the stack */
MOVW $(UTZERO+0x20), R0
MOVM.DB.W [R0],(R13)
/* return from interrupt */
RFE /* MOVM.IA.S.W (R13), [R15] */
/*
* here to jump to a newly forked process
*/
TEXT forkret(SB),$-4
ADD $(4*15), R13 /* make r13 point to ureg->type */
MOVW 8(R13), R14 /* restore link */
MOVW 4(R13), R0 /* restore SPSR */
MOVW R0, SPSR /* ... */
MOVM.DB.S (R13), [R0-R14] /* restore registers */
ADD $8, R13 /* pop past ureg->{type+psr} */
RFE /* MOVM.IA.S.W (R13), [R15] */
TEXT splhi(SB), $-4
/* save caller pc in Mach */
MOVW $(MACHADDR+0x04),R2
MOVW R14,0(R2)
/* turn off interrupts */
MOVW CPSR, R0
ORR $(PsrDirq), R0, R1
MOVW R1, CPSR
RET
TEXT spllo(SB), $-4
MOVW CPSR, R0
BIC $(PsrDirq), R0, R1
MOVW R1, CPSR
RET
TEXT splx(SB), $-4
/* save caller pc in Mach */
MOVW $(MACHADDR+0x04),R2
MOVW R14,0(R2)
/* reset interrupt level */
MOVW R0, R1
MOVW CPSR, R0
MOVW R1, CPSR
RET
TEXT splxpc(SB), $-4 /* for iunlock */
MOVW R0, R1
MOVW CPSR, R0
MOVW R1, CPSR
RET
TEXT spldone(SB), $0
RET
TEXT islo(SB), $-4
MOVW CPSR, R0
AND $(PsrDirq), R0
EOR $(PsrDirq), R0
RET
TEXT cpsrr(SB), $-4
MOVW CPSR, R0
RET
TEXT spsrr(SB), $-4
MOVW SPSR, R0
RET
TEXT getsp(SB), $-4
MOVW R13, R0
RET
TEXT getlink(SB), $-4
MOVW R14, R0
RET
TEXT getcallerpc(SB), $-4
MOVW 0(R13), R0
RET
TEXT tas(SB), $-4
MOVW R0, R1
MOVW $0xDEADDEAD, R0
MOVW R0, R3
SWPW R0, (R1)
CMP.S R0, R3
BEQ _tasout
EOR R3, R3
CMP.S R0, R3
BEQ _tasout
MOVW $1,R15
_tasout:
RET
TEXT setlabel(SB), $-4
MOVW R13, 0(R0) /* sp */
MOVW R14, 4(R0) /* pc */
MOVW $0, R0
RET
TEXT gotolabel(SB), $-4
MOVW 0(R0), R13 /* sp */
MOVW 4(R0), R14 /* pc */
MOVW $1, R0
RET
/* save the state machine in power_state[] for an upcoming suspend
*/
TEXT setpowerlabel(SB), $-4
MOVW $power_state+0(SB), R0
/* svc */ /* power_state[]: 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)
/* usr */
BIC $(PsrMask), R2, R3
ORR $(0xdf), R3
MOVW R3, CPSR
MOVW SPSR, R11
MOVW R11, 168(R0)
MOVW R12, 172(R0)
MOVW R13, 176(R0)
MOVW R14, 180(R0)
/* irq */
BIC $(PsrMask), R2, R3
ORR $(0xd2), 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 $(0xdb), 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 $(0xd7), 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 $(0xd1), 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 power_resume(SB), $-4
MOVW $setR12(SB), R12 /* load the SB */
/* SVC mode, interrupts disabled */
MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1
MOVW R1, CPSR
/* gotopowerlabel() */
/* svc */
MOVW $power_state+0(SB), R0
MOVW 56(R0), R1 /* R1: SPSR, R2: CPSR */
MOVW 60(R0), R2
MOVW R1, SPSR
MOVW R2, CPSR
/* copro */
/* 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
MCR CpMMU, 0, R0, C(CpTLBFlush), C(0x7)
MOVW 144(R0), R3
MCR CpMMU, 0, R3, C(CpDAC), C(0x0)
MOVW 148(R0), R3
MCR CpMMU, 0, R3, C(CpTTB), 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)
MOVW 152(R0), R3
MCR CpMMU, 0, R3, C(CpControl), C(0x0) /* Enable cache */
MOVW R0,R0
MOVW R0,R0
MOVW R0,R0
MOVW R0,R0
/* flush i&d caches */
MCR CpMMU, 0, R0, C(CpCacheFlush), C(0x7), 0
/* flush tlb */
MCR CpMMU, 0, R0, C(CpTLBFlush), C(0x7), 0
/* drain prefetch */
MOVW R0,R0
MOVW R0,R0
MOVW R0,R0
MOVW R0,R0
/* usr */
BIC $(PsrMask), R2, R3
ORR $(0xdf), R3
MOVW 168(R0), R11
MOVW 172(R0), R12
MOVW 176(R0), R13
MOVW 180(R0), R14
MOVW R11, SPSR
/* irq */
BIC $(PsrMask), R2, R3
ORR $(0xd2), 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 $(0xdb), 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 $(0xd7), 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 $(0xd1), 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
TEXT power_down(SB), $-4
TEXT sa1100_power_off<>+0(SB),$8
MOVW resetregs+0(SB),R7
MOVW gpioregs+0(SB),R6
MOVW memconfregs+0(SB),R5
MOVW powerregs+0(SB),R3
/* wakeup on power | rtc */
MOVW $(PWR_rtc|PWR_gpio0),R2
MOVW R2,0xc(R3)
/* clear reset status */
MOVW $(RCSR_all), R2
MOVW R2, 0x4(R7)
/* float */
MOVW $(PCFR_opde|PCFR_fp|PCFR_fs), R2
MOVW R2,0x10(R3)
/* sleep state */
MOVW $0,R2
MOVW R2,0x18(R3)
/* set resume address (pspr)*/
MOVW $resumeaddr+0(SB),R1
MOVW 0x0(R1), R2
MOVW R2,0x8(R3)
BL cacheflush(SB)
/* disable clock switching */
MCR CpPWR, 0, R1, C(CpTest), C(0x2), 2
/* adjust mem timing */
MOVW memconfregs+0(SB),R5
MOVW 0x1c(R5), R2
ORR $(MDREFR_k1db2), R2
MOVW R2, 0x1c(R5)
/* set PLL to lower speed w/ delay (ppcr = 0)*/
MOVW powerregs+0(SB),R3
MOVW $(120*206),R0
l11: SUB $1,R0
BGT l11
MOVW $0, R2
MOVW R2, 0x14(R3)
MOVW $(120*206),R0
l12: SUB $1,R0
BGT l12
/* setup registers for suspend procedure:
* 1. clear RT in mscx (R1, R7, R8)
* 2. clear DRI in mdrefr (R4)
* 3. set slfrsh in mdrefr (R6)
* 4. clear DE in mdcnfg (R9)
* 5. clear dram refresh (R10)
* 6. force sleep (R2)
*/
/* 1 */
MOVW 0x10(R5), R2
BIC $(MSC_rt), R2
MOVW R2, R1
MOVW 0x14(R5), R2
BIC $(MSC_rt), R2
MOVW R2, R7
MOVW 0x2c(R5), R2
BIC $(MSC_rt), R2
MOVW R2, R8
/* 2 */
MOVW 0x1c(R5), R2
BIC $(0xff00), R2
BIC $(0x00f0), R2
MOVW R2, R4
/* 3 */
ORR $(MDREFR_slfrsh), R2, R6
/* 4 */
MOVW 0x0(R5), R9
BIC $(MDCFNG_de), R9, R9
/* 5 */
MOVW R4, R2
BIC $(MDREFR_slfrsh), R2, R2
BIC $(MDREFR_e1pin), R2, R2
MOVW R2, R10
/* 6 */
MOVW $1,R2
/* Follow the procedure */
/* 1 */
MOVW R1, 0x10(R5)
MOVW R7, 0x14(R5)
MOVW R8, 0x2c(R5)
/* 2 */
MOVW R4, 0x1c(R5)
/* 3 */
MOVW R6, 0x1c(R5)
/* 4 */
MOVW R9, 0x0(R5)
/* 5 */
MOVW R10, 0x1c(R5)
/* 6 */
MOVW R2, 0x0(R3)
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).
*
* 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
MOVW $UCDRAMZERO, R1
MOVW R0,R0
MOVW R0,R0
MOVW R0,R0
MOVW R0,R0
MOVW R0,R0
MOVW R0,R0
MOVW R0,R0
MCR CpPWR, 0, R0, C(CpTest), C(0x2), 2
MOVW (R1), R0
MCR CpPWR, 0, R0, C(CpTest), C(0x8), 2
RET
[-- Attachment #3: power.c --]
[-- Type: text/plain, Size: 6831 bytes --]
#include "u.h"
#include "../port/lib.h"
#include "mem.h"
#include "dat.h"
#include "fns.h"
#include "io.h"
#include "ureg.h"
#include "pool.h"
/* Power management for the bitsy */
/* saved state during power down.
* it's only used up to 164/4.
* it's only used by routines in l.s
*/
ulong power_state[200/4];
ulong resumeaddr[1];
Rendez powerr;
ulong powerflag = 0; /* set to start power-off sequence */
extern void power_resume(void);
extern int setpowerlabel(void);
extern void _start(void);
extern Uart sa1110uart[];
GPIOregs savedgpioregs;
Intrregs savedintrregs;
#define R(p) ((Uartregs*)((p)->regs))
uchar *savedtext;
static void
checkflash(void)
{
ulong *p;
ulong s;
s = 0;
for (p = (ulong*)FLASHZERO; p < (ulong*)(FLASHZERO+8*1024*1024); p++)
s += *p;
iprint("flash checksum is 0x%lux\n", s);
}
static void
checkktext(void)
{
ulong *p;
ulong s;
s = 0;
for (p = (ulong*)_start; p < (ulong*)etext; p++){
if(*p == 0)
iprint("0x%lux->0\n", p);
if (((ulong)p & 0x1fff) == 0){
iprint("page 0x%lux checksum 0x%lux\n",
(ulong)(p-1)&~0x1fff, s);
s = 0;
}
s += *p;
}
iprint("page 0x%lux checksum 0x%lux\n", (ulong)(p-1)&~0x1fff, s);
}
static void
checkpagetab(void)
{
extern ulong l1table;
ulong *p;
ulong s;
s = 0;
for (p = (ulong*)l1table; p < (ulong*)(l1table+16*1024); p++)
s += *p;
iprint("page table checksum is 0x%lux\n", s);
}
static void
dumpitall(void)
{
extern ulong l1table;
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",
R(&sa1110uart[0])->ctl[0], R(&sa1110uart[0])->status[0], R(&sa1110uart[0])->status[1],
R(&sa1110uart[1])->ctl[0], R(&sa1110uart[1])->status[0], R(&sa1110uart[1])->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);
iprint("mmu: CpControl %lux CpTTB %lux CpDAC %lux l1table 0x%lux\n",
getcontrol(), getttb(), getdac(), l1table);
iprint("powerregs: pmcr %lux pssr %lux pcfr %lux ppcr %lux pwer %lux pspr %lux pgsr %lux posr %lux\n",
powerregs->pmcr, powerregs->pssr, powerregs->pcfr, powerregs->ppcr,
powerregs->pwer, powerregs->pspr, powerregs->pgsr, powerregs->posr);
checkpagetab();
checkflash();
checkktext();
iprint("\n\n");
}
static void
intrcpy(Intrregs *to, Intrregs *from)
{
to->iclr = from->iclr;
to->iccr = from->iccr;
to->icmr = from->icmr; // interrupts enabled
}
static void
gpiosave(GPIOregs *to, GPIOregs *from)
{
to->level = from->level;
to->rising = from->rising; // gpio intrs enabled
to->falling= from->falling; // gpio intrs enabled
to->altfunc = from->altfunc;
to->direction = from->direction;
}
static void
gpiorestore(GPIOregs *to, GPIOregs *from)
{
to->direction = from->direction;
to->altfunc = from->altfunc;
to->set = from->level & 0x0fffffff;
to->clear = ~from->level & 0x0fffffff;
to->rising = from->rising; // gpio intrs enabled
to->falling= from->falling; // gpio intrs enabled
}
void (*restart)(void) = nil;
static int
bitno(ulong x)
{
int i;
for(i = 0; i < 8*sizeof(x); i++)
if((1<<i) & x)
break;
return i;
}
int
powerdown(void *)
{
return powerflag;
}
void
deepsleep(void) {
static int power_pl;
ulong xsp, xlink, mecr;
extern void power_resume(void);
power_pl = splhi();
xlink = getcallerpc(&xlink);
// *resumeaddr = (ulong) power_resume;
// *resumeaddr = nil;
/* Power down */
irpower(0);
audiopower(0);
screenpower(0);
µcpower(0);
iprint("entering suspend mode, sp = 0x%lux, pc = 0x%lux, psw = 0x%ux\n", &xsp, xlink, power_pl);
// dumpitall();
delay(1000);
uartpower(0);
rs232power(0);
clockpower(0);
gpiosave(&savedgpioregs, gpioregs);
intrcpy(&savedintrregs, intrregs);
cacheflush();
delay(50);
mecr = memconfregs->mecr;
if(setpowerlabel()){
/* return here with mmu back on */
trapresume();
/* Turn off memory auto power */
// memconfregs->mdrefr &= ~0x30000000;
// memconfregs->mecr = mecr;
gpiorestore(gpioregs, &savedgpioregs);
delay(50);
intrcpy(intrregs, &savedintrregs);
if(intrregs->icip & (1<<IRQgpio0)){
// don't want to sleep now. clear on/off irq.
gpioregs->edgestatus = (1<<IRQgpio0);
intrregs->icip = (1<<IRQgpio0);
}
clockpower(1);
gpclkregs->r0 = 1<<0;
rs232power(1);
uartpower(1);
delay(100);
xlink = getcallerpc(&xlink);
iprint("\nresuming execution, sp = 0x%lux, pc = 0x%lux, psw = 0x%ux\n", &xsp, xlink, splhi());
// dumpitall();
delay(1000);
// irpower(1);
// audiopower(1);
µcpower(1);
screenpower(1);
splx(power_pl);
return;
}
cacheflush();
delay(100);
power_down();
/* no return */
}
void
powerkproc(void*)
{
ulong xlink, xlink1;
for(;;){
while(powerflag == 0)
sleep(&powerr, powerdown, 0);
xlink = getcallerpc(&xlink);
// iprint("call deepsleep, pc = 0x%lux, sp = 0x%lux\n", xlink, &xlink);
deepsleep();
xlink1 = getcallerpc(&xlink1);
delay(2000);
// iprint("deepsleep returned, pc = 0x%lux, sp = 0x%lux\n", xlink1, &xlink);
powerflag = 0;
}
}
void
onoffintr(Ureg* , void*)
{
int i;
/* Power down interrupt comes on power button release.
* Act only after button has been released a full 100 ms
*/
if (powerflag)
return;
for (i = 0; i < 100; i++) {
delay(1);
if ((gpioregs->level & GPIO_PWR_ON_i) == 0)
return; /* bounced */
}
powerflag = 1;
wakeup(&powerr);
}
static void
blanktimer(void)
{
drawactive(0);
}
void
powerinit(void)
{
addclock0link(blanktimer);
intrenable(GPIOrising, bitno(GPIO_PWR_ON_i), onoffintr, nil, "on/off");
}
void
idlehands(void)
{
char *msgb = "idlehands called with splhi\n";
char *msga = "doze returns with splhi\n";
if(!islo()){
uartputs(msga, strlen(msga));
spllo();
}
doze();
if(!islo()){
uartputs(msgb, strlen(msgb));
spllo();
}
}
[-- Attachment #4: mem.h --]
[-- Type: text/plain, Size: 8281 bytes --]
/*
* Memory and machine-specific definitions. Used in C and assembler.
*/
/*
* Sizes
*/
#define BI2BY 8 /* bits per byte */
#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 BLOCKALIGN 8
#define MAXMACH 1 /* max # cpus system can run */
/*
* Time
*/
#define HZ (20) /* clock frequency */
#define MS2HZ (1000/HZ) /* millisec per clock tick */
#define TK2SEC(t) ((t)/HZ) /* ticks to seconds */
/*
* Virtual addresses:
*
* We direct map all discovered DRAM and the area twixt 0xe0000000 and
* 0xe8000000 used to provide zeros for cache flushing.
*
* Flash is mapped to 0xb0000000 and special registers are mapped
* on demand to areas starting at 0xa0000000.
*
* The direct mapping is convenient but not necessary. It means
* that we don't have to turn on the MMU till well into the
* 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 KZERO 0xC0000000 /* base of kernel address space */
#define KTZERO 0xC0008000 /* first address in kernel text */
#define EMEMZERO 0x90000000 /* 256 meg for add on memory */
#define EMEMTOP 0xA0000000 /* ... */
#define REGZERO 0xA0000000 /* 128 meg for mapspecial regs */
#define REGTOP 0xA8000000 /* ... */
#define FLASHZERO 0xB0000000 /* 128 meg for flash */
#define FLASHTOP 0xB8000000 /* ... */
#define DRAMZERO 0xC0000000 /* 128 meg for dram */
#define DRAMTOP 0xC8000000 /* ... */
#define UCDRAMZERO 0xC8000000 /* 128 meg for dram (uncached/unbuffered) */
#define UCDRAMTOP 0xD0000000 /* ... */
#define NULLZERO 0xE0000000 /* 128 meg for cache flush zeroes */
#define NULLTOP 0xE8000000 /* ... */
#define USTKTOP 0x2000000 /* byte just beyond 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 EVECTORS 0xFFFF0000 /* virt base of exception vectors */
#define KSTACK (16*1024) /* Size of kernel stack */
/*
* Offsets into flash
*/
#define Flash_bootldr (FLASHZERO+0x0) /* boot loader */
#define Flash_kernel (FLASHZERO+0x10000) /* boot kernel */
#define Flash_tar (FLASHZERO+0x200000) /* fs.sac (tar file) */
/*
* virtual MMU
*/
#define PTEMAPMEM (1024*1024)
#define PTEPERTAB (PTEMAPMEM/BY2PG)
#define SEGMAPSIZE 1984
#define SSEGMAPSIZE 16
#define PPN(x) ((x)&~(BY2PG-1))
/*
* SA1110 definitions
*/
/*
* memory physical addresses
*/
#define PHYSFLASH0 0x00000000
#define PHYSDRAM0 0xC0000000
#define PHYSNULL0 0xE0000000
/*
* 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 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 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 */
/*
* PCMCIA addresses
*/
#define PHYSPCM0REGS 0x20000000
#define PYHSPCM0ATTR 0x28000000
#define PYHSPCM0MEM 0x2C000000
#define PHYSPCM1REGS 0x30000000
#define PYHSPCM1ATTR 0x38000000
#define PYHSPCM1MEM 0x3C000000
/*
* Program Status Registers
*/
#define PsrMusr 0x00000010 /* mode */
#define PsrMfiq 0x00000011
#define PsrMirq 0x00000012
#define PsrMsvc 0x00000013
#define PsrMabt 0x00000017
#define PsrMund 0x0000001B
#define PsrMask 0x0000001F
#define PsrDfiq 0x00000040 /* disable FIQ interrupts */
#define PsrDirq 0x00000080 /* disable IRQ interrupts */
#define PsrV 0x10000000 /* overflow */
#define PsrC 0x20000000 /* carry/borrow/extend */
#define PsrZ 0x40000000 /* zero */
#define PsrN 0x80000000 /* negative/less than */
/*
* Coprocessors
*/
#define CpMMU 15
#define CpPWR 15
/*
* Internal MMU coprocessor registers
*/
#define CpCPUID 0 /* R: */
#define CpControl 1 /* R: */
#define CpTTB 2 /* RW: translation table base */
#define CpDAC 3 /* RW: domain access control */
#define CpFSR 5 /* RW: fault status */
#define CpFAR 6 /* RW: fault address */
#define CpCacheFlush 7 /* W: cache flushing, wb draining*/
#define CpTLBFlush 8 /* W: TLB flushing */
#define CpRBFlush 9 /* W: Read Buffer ops */
#define CpPID 13 /* RW: PID for virtual mapping */
#define CpBpt 14 /* W: Breakpoint register */
#define CpTest 15 /* W: Test, Clock and Idle Control */
/*
* CpControl
*/
#define CpCmmuena 0x00000001 /* M: MMU enable */
#define CpCalign 0x00000002 /* A: alignment fault enable */
#define CpCdcache 0x00000004 /* C: data cache on */
#define CpCwb 0x00000008 /* W: write buffer turned on */
#define CpCi32 0x00000010 /* P: 32-bit program space */
#define CpCd32 0x00000020 /* D: 32-bit data space */
#define CpCbe 0x00000080 /* B: big-endian operation */
#define CpCsystem 0x00000100 /* S: system permission */
#define CpCrom 0x00000200 /* R: ROM permission */
#define CpCicache 0x00001000 /* I: instruction cache on */
#define CpCvivec 0x00002000 /* X: virtual interrupt vector adjust */
/*
* fault codes
*/
#define FCterm 0x2 /* terminal */
#define FCvec 0x0 /* vector */
#define FCalignf 0x1 /* unaligned full word data access */
#define FCalignh 0x3 /* unaligned half word data access */
#define FCl1abort 0xc /* level 1 external abort on translation */
#define FCl2abort 0xe /* level 2 external abort on translation */
#define FCtransSec 0x5 /* section translation */
#define FCtransPage 0x7 /* page translation */
#define FCdomainSec 0x9 /* section domain */
#define FCdomainPage 0x11 /* page domain */
#define FCpermSec 0x9 /* section permissions */
#define FCpermPage 0x11 /* page permissions */
#define FCabortLFSec 0x4 /* external abort on linefetch for section */
#define FCabortLFPage 0x6 /* external abort on linefetch for page */
#define FCabortNLFSec 0x8 /* external abort on non-linefetch for section */
#define FCabortNLFPage 0xa /* external abort on non-linefetch for page */
/*
* PTE bits used by fault.h. mmu.c translates them to real values.
*/
#define PTEVALID (1<<0)
#define PTERONLY 0 /* this is implied by the absence of PTEWRITE */
#define PTEWRITE (1<<1)
#define PTEUNCACHED (1<<2)
#define PTEKERNEL (1<<3) /* no user access */
/*
* H3650 specific definitions
*/
#define EGPIOREGS 0x49000000 /* Additional GPIO register */
/* Power management */
#define PWR_rtc 0x80000000 /* resume on RTC */
#define PWR_gpio0 0x00000001 /* resume on power button */
#define RCSR_all 0x0000000f
#define PCFR_opde 0x00000001 /* oscillator power-down enable */
#define PCFR_suspend 0x00000001
#define PCFR_fp 0x00000002 /* float pcmcia */
#define PCFR_fs 0x00000004 /* float static memory */
#define PCFR_fo 0x00000008
#define MDREFR_k1db2 (1 << 22)
#define MDREFR_slfrsh 0x80000000 /* self refresh */
#define MDREFR_e1pin (1 << 20)
#define MSC_rt 0x00030003
#define MDCNFG_de0 0x00000001 /* dram enable */
#define MDCNFG_de1 0x00000002
#define MDCNFG_de2 0x00000004
#define MDCNFG_de3 0x00000008
#define MDCFNG_de 0x0000000f
#define PMCR_sf 1
[-- Attachment #5: io.h --]
[-- Type: text/plain, Size: 8087 bytes --]
/*
* Definitions for IO devices. Used only in C.
*/
enum
{
/* hardware counter frequency */
ClockFreq= 3686400,
};
/*
* IRQ's defined by SA1100
*/
enum
{
IRQgpio0= 0,
IRQgpio1= 1,
IRQgpio2= 2,
IRQgpio3= 3,
IRQgpio4= 4,
IRQgpio5= 5,
IRQgpio6= 6,
IRQgpio7= 7,
IRQgpio8= 8,
IRQgpio9= 9,
IRQgpio10= 10,
IRQgpiohi= 11,
IRQlcd= 12,
IRQudc= 13,
IRQuart1b= 15,
IRQuart2= 16,
IRQuart3= 17,
IRQmcp= 18,
IRQssp= 19,
IRQdma0= 20,
IRQdma1= 21,
IRQdma2= 22,
IRQdma3= 23,
IRQdma4= 24,
IRQdma5= 25,
IRQtimer0= 26,
IRQtimer1= 27,
IRQtimer2= 28,
IRQtimer3= 29,
IRQsecond= 30,
IRQrtc= 31,
};
/*
* GPIO lines (signal names from compaq document). _i indicates input
* and _o output.
*/
enum
{
GPIO_PWR_ON_i= 1<<0, /* power button */
GPIO_UP_IRQ_i= 1<<1, /* microcontroller interrupts */
GPIO_LDD8_o= 1<<2, /* LCD data 8-15 */
GPIO_LDD9_o= 1<<3,
GPIO_LDD10_o= 1<<4,
GPIO_LDD11_o= 1<<5,
GPIO_LDD12_o= 1<<6,
GPIO_LDD13_o= 1<<7,
GPIO_LDD14_o= 1<<8,
GPIO_LDD15_o= 1<<9,
GPIO_CARD_IND1_i= 1<<10, /* card inserted in PCMCIA socket 1 */
GPIO_CARD_IRQ1_i= 1<<11, /* PCMCIA socket 1 interrupt */
GPIO_CLK_SET0_o= 1<<12, /* clock selects for audio codec */
GPIO_CLK_SET1_o= 1<<13,
GPIO_L3_SDA_io= 1<<14, /* UDA1341 interface */
GPIO_L3_MODE_o= 1<<15,
GPIO_L3_SCLK_o= 1<<16,
GPIO_CARD_IND0_i= 1<<17, /* card inserted in PCMCIA socket 0 */
GPIO_KEY_ACT_i= 1<<18, /* hot key from cradle */
GPIO_SYS_CLK_i= 1<<19, /* clock from codec */
GPIO_BAT_FAULT_i= 1<<20, /* battery fault */
GPIO_CARD_IRQ0_i= 1<<21, /* PCMCIA socket 0 interrupt */
GPIO_LOCK_i= 1<<22, /* expansion pack lock/unlock */
GPIO_COM_DCD_i= 1<<23, /* DCD from UART3 */
GPIO_OPT_IRQ_i= 1<<24, /* expansion pack IRQ */
GPIO_COM_CTS_i= 1<<25, /* CTS from UART3 */
GPIO_COM_RTS_o= 1<<26, /* RTS to UART3 */
GPIO_OPT_IND_i= 1<<27, /* expansion pack inserted */
/* Peripheral Unit GPIO pin assignments: alternate functions */
GPIO_SSP_TXD_o= 1<<10, /* SSP Transmit Data */
GPIO_SSP_RXD_i= 1<<11, /* SSP Receive Data */
GPIO_SSP_SCLK_o= 1<<12, /* SSP Sample CLocK */
GPIO_SSP_SFRM_o= 1<<13, /* SSP Sample FRaMe */
/* ser. port 1: */
GPIO_UART_TXD_o= 1<<14, /* UART Transmit Data */
GPIO_UART_RXD_i= 1<<15, /* UART Receive Data */
GPIO_SDLC_SCLK_io= 1<<16, /* SDLC Sample CLocK (I/O) */
GPIO_SDLC_AAF_o= 1<<17, /* SDLC Abort After Frame */
GPIO_UART_SCLK1_i= 1<<18, /* UART Sample CLocK 1 */
/* ser. port 4: */
GPIO_SSP_CLK_i= 1<<19, /* SSP external CLocK */
/* ser. port 3: */
GPIO_UART_SCLK3_i= 1<<20, /* UART Sample CLocK 3 */
/* ser. port 4: */
GPIO_MCP_CLK_i= 1<<21, /* MCP CLocK */
/* test controller: */
GPIO_TIC_ACK_o= 1<<21, /* TIC ACKnowledge */
GPIO_MBGNT_o= 1<<21, /* Memory Bus GraNT */
GPIO_TREQA_i= 1<<22, /* TIC REQuest A */
GPIO_MBREQ_i= 1<<22, /* Memory Bus REQuest */
GPIO_TREQB_i= 1<<23, /* TIC REQuest B */
GPIO_1Hz_o= 1<<25, /* 1 Hz clock */
GPIO_RCLK_o= 1<<26, /* internal (R) CLocK (O, fcpu/2) */
GPIO_32_768kHz_o= 1<<27, /* 32.768 kHz clock (O, RTC) */
};
/*
* types of interrupts
*/
enum
{
GPIOrising,
GPIOfalling,
GPIOboth,
IRQ,
};
/* hardware registers */
typedef struct Uartregs Uartregs;
struct Uartregs
{
ulong ctl[4];
ulong dummya;
ulong data;
ulong dummyb;
ulong status[2];
};
extern Uartregs *uart3regs;
extern Uartregs *uart1regs;
/* general purpose I/O lines control registers */
typedef struct GPIOregs GPIOregs;
struct GPIOregs
{
ulong level; /* 1 == high */
ulong direction; /* 1 == output */
ulong set; /* a 1 sets the bit, 0 leaves it alone */
ulong clear; /* a 1 clears the bit, 0 leaves it alone */
ulong rising; /* rising edge detect enable */
ulong falling; /* falling edge detect enable */
ulong edgestatus; /* writing a 1 bit clears */
ulong altfunc; /* turn on alternate function for any set bits */
};
extern GPIOregs *gpioregs;
/* extra general purpose I/O bits, output only */
enum
{
EGPIO_prog_flash= 1<<0,
EGPIO_pcmcia_reset= 1<<1,
EGPIO_exppack_reset= 1<<2,
EGPIO_codec_reset= 1<<3,
EGPIO_exp_nvram_power= 1<<4,
EGPIO_exp_full_power= 1<<5,
EGPIO_lcd_3v= 1<<6,
EGPIO_rs232_power= 1<<7,
EGPIO_lcd_ic_power= 1<<8,
EGPIO_ir_power= 1<<9,
EGPIO_audio_power= 1<<10,
EGPIO_audio_ic_power= 1<<11,
EGPIO_audio_mute= 1<<12,
EGPIO_fir= 1<<13, /* not set is sir */
EGPIO_lcd_5v= 1<<14,
EGPIO_lcd_9v= 1<<15,
};
extern ulong *egpioreg;
/* Peripheral pin controller registers */
typedef struct PPCregs PPCregs;
struct PPCregs {
ulong direction;
ulong state;
ulong assignment;
ulong sleepdir;
ulong flags;
};
extern PPCregs *ppcregs;
/* Synchronous Serial Port controller registers */
typedef struct SSPregs SSPregs;
struct SSPregs {
ulong control0;
ulong control1;
ulong dummy0;
ulong data;
ulong dummy1;
ulong status;
};
extern SSPregs *sspregs;
/* Multimedia Communications Port controller registers */
typedef struct MCPregs MCPregs;
struct MCPregs {
ulong control0;
ulong reserved0;
ulong data0;
ulong data1;
ulong data2;
ulong reserved1;
ulong status;
ulong reserved[11];
ulong control1;
};
extern MCPregs *mcpregs;
/*
* memory configuration
*/
enum
{
/* bit shifts for pcmcia access time counters */
MECR_io0= 0,
MECR_attr0= 5,
MECR_mem0= 10,
MECR_fast0= 11,
MECR_io1= MECR_io0+16,
MECR_attr1= MECR_attr0+16,
MECR_mem1= MECR_mem0+16,
MECR_fast1= MECR_fast0+16,
REFR_kapd= 29,
REFR_eapd= 28,
REFR_k1db2= 22,
REFR_slfrsh= 31,
};
typedef struct MemConfRegs MemConfRegs;
struct MemConfRegs
{
ulong mdcnfg; /* 0x00 dram */
ulong mdcas00; /* 0x04 dram banks 0/1 */
ulong mdcas01; /* 0x08 */
ulong mdcas02; /* 0x0c */
ulong msc0; /* 0x10 static */
ulong msc1; /* 0x14 */
ulong mecr; /* 0x18 pcmcia */
ulong mdrefr; /* 0x1c dram refresh */
ulong mdcas20; /* 0x20 dram banks 2/3 */
ulong mdcas21; /* 0x24 */
ulong mdcas22; /* 0x28 */
ulong msc2; /* 0x2c static */
ulong smcnfg; /* 0x30 SMROM config */
};
extern MemConfRegs *memconfregs;
/*
* power management
*/
/* Power management ops */
typedef struct PowerRegs PowerRegs;
struct PowerRegs
{
ulong pmcr; /* 0x0 Power manager control register */
ulong pssr; /* 0x4 Power manager sleep status register */
ulong pspr; /* 0x8 Power manager scratch pad register */
ulong pwer; /* 0xc Power manager wakeup enable register */
ulong pcfr; /* 0x10 Power manager general configuration register */
ulong ppcr; /* 0x14 Power manager PPL configuration register */
ulong pgsr; /* 0x18 Power manager GPIO sleep state register */
ulong posr; /* 0x1c 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 */
};
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;
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2002-05-17 11:25 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2002-05-17 11:25 [9fans] bitsy suspend fix Fco.J.Ballesteros
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).