7 * Turn off MMU, then copy the new kernel to its correct location
8 * in physical memory. Then jump to the start of the kernel.
11 /* main(PADDR(entry), PADDR(code), size); */
15 /* copy in arguments before stack gets unmapped */
16 MOVW R0, R8 /* entry point */
17 MOVW p2+4(FP), R9 /* source */
18 MOVW n+8(FP), R10 /* byte count */
20 /* SVC mode, interrupts disabled */
21 MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R1
24 /* prepare to turn off mmu */
28 MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
30 MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
32 /* set up a tiny stack for local vars and memmove args */
33 MOVW R8, SP /* stack top just before kernel dest */
34 SUB $20, SP /* allocate stack frame */
36 /* copy the kernel to final destination */
37 MOVW R8, 16(SP) /* save dest (entry point) */
38 MOVW R8, R0 /* first arg is dest */
39 MOVW R9, 8(SP) /* push src */
40 MOVW R10, 12(SP) /* push size */
42 MOVW 16(SP), R8 /* restore entry point */
44 /* jump to kernel physical entry point */
49 * turn the caches off, double map PHYSDRAM & KZERO, invalidate TLBs, revert
50 * to tiny addresses. upon return, it will be safe to turn off the mmu.
51 * clobbers R0-R2, and returns with SP invalid.
53 TEXT cachesoff(SB), 1, $-4
55 /* write back and invalidate caches */
58 MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEwbi), CpCACHEall
59 MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall
62 MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
63 BIC $(CpCdcache|CpCicache|CpCpredict), R1
64 MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl
66 /* invalidate stale TLBs before changing them */
68 MOVW $KZERO, R0 /* some valid virtual address */
69 MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
72 /* from here on, R0 is base of physical memory */
75 /* redo double map of first MiB PHYSDRAM = KZERO */
76 MOVW $(L1+L1X(PHYSDRAM)), R2 /* address of PHYSDRAM's PTE */
77 MOVW $PTEDRAM, R1 /* PTE bits */
78 ORR R0, R1 /* dram base */
81 /* invalidate stale TLBs again */
83 MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv
86 /* relocate SB and return address to PHYSDRAM addressing */
87 MOVW $KSEGM, R1 /* clear segment bits */
88 BIC R1, R12 /* adjust SB */
90 BIC R1, R14 /* adjust return address */