123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175 |
- /*
- * sheevaplug reboot code
- *
- * R11 is used by the loader as a temporary, so avoid it.
- */
- #include "arm.s"
- /*
- * Turn off MMU, then copy the new kernel to its correct location
- * in physical memory. Then jump to the start of the kernel.
- */
- /* main(PADDR(entry), PADDR(code), size); */
- TEXT main(SB), 1, $-4
- MOVW $setR12(SB), R12
- MOVW R0, p1+0(FP) /* destination, passed in R0 */
- /* copy in arguments from frame */
- MOVW R0, R8 /* entry point */
- MOVW p2+4(FP), R9 /* source */
- MOVW n+8(FP), R10 /* byte count */
- WAVE('R')
- BL cachesoff(SB)
- /* now back in 29- or 26-bit addressing, mainly for SB */
- /* turn the MMU off */
- WAVE('e')
- MOVW $KSEGM, R7
- MOVW $PHYSDRAM, R0
- BL _r15warp(SB)
- BIC R7, R12 /* SB */
- BIC R7, R13 /* SP */
- /* don't care about R14 */
- WAVE('b')
- BL mmuinvalidate(SB)
- WAVE('o')
- BL mmudisable(SB)
- WAVE('o')
- MOVW R9, R4 /* restore regs across function calls */
- MOVW R10, R5
- MOVW R8, R6
- /* set up a new stack for local vars and memmove args */
- MOVW R6, SP /* tiny trampoline stack */
- SUB $(0x20 + 4), SP /* back up before a.out header */
- MOVW R14, -48(SP) /* store return addr */
- SUB $48, SP /* allocate stack frame */
- MOVW R6, 44(SP) /* save dest/entry */
- MOVW R5, 40(SP) /* save count */
- WAVE('t')
- MOVW R6, 0(SP)
- MOVW R6, 4(SP) /* push dest */
- MOVW R6, R0
- MOVW R4, 8(SP) /* push src */
- MOVW R5, 12(SP) /* push size */
- BL memmove(SB)
- MOVW 44(SP), R6 /* restore R6 (dest/entry) */
- MOVW 40(SP), R5 /* restore R5 (count) */
- WAVE('-')
- /*
- * flush caches
- */
- BL cacheuwbinv(SB)
- WAVE('>')
- WAVE('\r');
- WAVE('\n');
- /*
- * jump to kernel entry point. Note the true kernel entry point is
- * the virtual address KZERO|R6, but this must wait until
- * the MMU is enabled by the kernel in l.s
- */
- ORR R6, R6 /* NOP: avoid link bug */
- B (R6)
- /*
- * turn the caches off, double map 0 & KZERO, invalidate TLBs, revert to
- * tiny addresses. upon return, it will be safe to turn off the mmu.
- */
- TEXT cachesoff(SB), 1, $-4
- MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R0
- MOVW R0, CPSR
- MOVW $KADDR(0x100-4), R7 /* just before this code */
- MOVW R14, (R7) /* save link */
- BL cacheuwbinv(SB)
- MRC CpSC, 0, R0, C(CpCONTROL), C(0)
- BIC $(CpCwb|CpCicache|CpCdcache|CpCalign), R0
- MCR CpSC, 0, R0, C(CpCONTROL), C(0)
- BARRIERS
- /* redo double map of 0, KZERO */
- MOVW $(L1+L1X(PHYSDRAM)), R4 /* address of PTE for 0 */
- MOVW $PTEDRAM, R2 /* PTE bits */
- // MOVW $PTEIO, R2 /* PTE bits */
- MOVW $PHYSDRAM, R3
- MOVW $512, R5
- _ptrdbl:
- ORR R3, R2, R1 /* first identity-map 0 to 0, etc. */
- MOVW R1, (R4)
- ADD $4, R4 /* bump PTE address */
- ADD $MiB, R3 /* bump pa */
- SUB.S $1, R5
- BNE _ptrdbl
- BARRIERS
- MOVW $0, R0
- MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvd), CpTLBinv
- MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
- BARRIERS
- /* back to 29- or 26-bit addressing, mainly for SB */
- MRC CpSC, 0, R0, C(CpCONTROL), C(0)
- BIC $(CpCd32|CpCi32), R0
- MCR CpSC, 0, R0, C(CpCONTROL), C(0)
- BARRIERS
- MOVW $KADDR(0x100-4), R7 /* just before this code */
- MOVW (R7), R14 /* restore link */
- RET
- TEXT _r15warp(SB), 1, $-4
- BIC $0xf0000000, R14
- ORR R0, R14
- RET
- TEXT mmudisable(SB), 1, $-4
- MRC CpSC, 0, R0, C(CpCONTROL), C(0)
- BIC $(CpChv|CpCmmu|CpCdcache|CpCicache|CpCwb), R0
- MCR CpSC, 0, R0, C(CpCONTROL), C(0)
- BARRIERS
- RET
- TEXT mmuinvalidate(SB), 1, $-4 /* invalidate all */
- MOVW $0, R0
- MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
- BARRIERS
- RET
- TEXT cacheuwbinv(SB), 1, $-4 /* D+I writeback+invalidate */
- BARRIERS
- MOVW CPSR, R3 /* splhi */
- ORR $(PsrDirq), R3, R1
- MOVW R1, CPSR
- _uwbinv: /* D writeback+invalidate */
- MRC CpSC, 0, PC, C(CpCACHE), C(CpCACHEwbi), CpCACHEtest
- BNE _uwbinv
- MCR CpSC, CpL2, PC, C(CpTESTCFG), C(CpTCl2flush), CpTCl2all
- BARRIERS
- MCR CpSC, CpL2, PC, C(CpTESTCFG), C(CpTCl2inv), CpTCl2all
- BARRIERS
- MOVW $0, R0 /* I invalidate */
- MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
- BARRIERS
- MOVW $0, R0 /* drain write buffer */
- MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEwait
- BARRIERS
- MOVW R3, CPSR /* splx */
- RET
|