1154abd99SDavid du Colombier/* 2154abd99SDavid du Colombier * sheevaplug reboot code 3154abd99SDavid du Colombier * 4154abd99SDavid du Colombier * R11 is used by the loader as a temporary, so avoid it. 5154abd99SDavid du Colombier */ 6154abd99SDavid du Colombier#include "arm.s" 7154abd99SDavid du Colombier 8154abd99SDavid du Colombier/* 9154abd99SDavid du Colombier * Turn off MMU, then copy the new kernel to its correct location 10154abd99SDavid du Colombier * in physical memory. Then jump to the start of the kernel. 11154abd99SDavid du Colombier */ 12154abd99SDavid du Colombier 13154abd99SDavid du Colombier/* main(PADDR(entry), PADDR(code), size); */ 14154abd99SDavid du ColombierTEXT main(SB), 1, $-4 15154abd99SDavid du Colombier MOVW $setR12(SB), R12 16154abd99SDavid du Colombier 17154abd99SDavid du Colombier MOVW R0, p1+0(FP) /* destination, passed in R0 */ 18154abd99SDavid du Colombier 19154abd99SDavid du Colombier /* copy in arguments from frame */ 20154abd99SDavid du Colombier MOVW R0, R8 /* entry point */ 21154abd99SDavid du Colombier MOVW p2+4(FP), R9 /* source */ 22154abd99SDavid du Colombier MOVW n+8(FP), R10 /* byte count */ 23154abd99SDavid du Colombier 24*bb9c7457SDavid du ColombierPUTC('R') 25154abd99SDavid du Colombier BL cachesoff(SB) 26154abd99SDavid du Colombier /* now back in 29- or 26-bit addressing, mainly for SB */ 27154abd99SDavid du Colombier 28154abd99SDavid du Colombier /* turn the MMU off */ 29*bb9c7457SDavid du ColombierPUTC('e') 30154abd99SDavid du Colombier MOVW $KSEGM, R7 31154abd99SDavid du Colombier MOVW $PHYSDRAM, R0 32154abd99SDavid du Colombier BL _r15warp(SB) 33154abd99SDavid du Colombier 34154abd99SDavid du Colombier BIC R7, R12 /* SB */ 35154abd99SDavid du Colombier BIC R7, R13 /* SP */ 36154abd99SDavid du Colombier /* don't care about R14 */ 37154abd99SDavid du Colombier 38*bb9c7457SDavid du ColombierPUTC('b') 39154abd99SDavid du Colombier BL mmuinvalidate(SB) 40*bb9c7457SDavid du ColombierPUTC('o') 41154abd99SDavid du Colombier BL mmudisable(SB) 42154abd99SDavid du Colombier 43*bb9c7457SDavid du ColombierPUTC('o') 44154abd99SDavid du Colombier MOVW R9, R4 /* restore regs across function calls */ 45154abd99SDavid du Colombier MOVW R10, R5 46154abd99SDavid du Colombier MOVW R8, R6 47154abd99SDavid du Colombier 48154abd99SDavid du Colombier /* set up a new stack for local vars and memmove args */ 49154abd99SDavid du Colombier MOVW R6, SP /* tiny trampoline stack */ 50154abd99SDavid du Colombier SUB $(0x20 + 4), SP /* back up before a.out header */ 51154abd99SDavid du Colombier 52154abd99SDavid du Colombier MOVW R14, -48(SP) /* store return addr */ 53154abd99SDavid du Colombier SUB $48, SP /* allocate stack frame */ 54154abd99SDavid du Colombier 55154abd99SDavid du Colombier MOVW R6, 44(SP) /* save dest/entry */ 56154abd99SDavid du Colombier MOVW R5, 40(SP) /* save count */ 57154abd99SDavid du Colombier 58*bb9c7457SDavid du ColombierPUTC('t') 59154abd99SDavid du Colombier 60154abd99SDavid du Colombier MOVW R6, 0(SP) 61154abd99SDavid du Colombier MOVW R6, 4(SP) /* push dest */ 62154abd99SDavid du Colombier MOVW R6, R0 63154abd99SDavid du Colombier MOVW R4, 8(SP) /* push src */ 64154abd99SDavid du Colombier MOVW R5, 12(SP) /* push size */ 65154abd99SDavid du Colombier BL memmove(SB) 66154abd99SDavid du Colombier 67154abd99SDavid du Colombier MOVW 44(SP), R6 /* restore R6 (dest/entry) */ 68154abd99SDavid du Colombier MOVW 40(SP), R5 /* restore R5 (count) */ 69*bb9c7457SDavid du ColombierPUTC('-') 70154abd99SDavid du Colombier /* 71154abd99SDavid du Colombier * flush caches 72154abd99SDavid du Colombier */ 73154abd99SDavid du Colombier BL cacheuwbinv(SB) 74154abd99SDavid du Colombier 75*bb9c7457SDavid du ColombierPUTC('>') 76*bb9c7457SDavid du ColombierPUTC('\r'); 77*bb9c7457SDavid du ColombierPUTC('\n'); 78154abd99SDavid du Colombier/* 79154abd99SDavid du Colombier * jump to kernel entry point. Note the true kernel entry point is 80154abd99SDavid du Colombier * the virtual address KZERO|R6, but this must wait until 81154abd99SDavid du Colombier * the MMU is enabled by the kernel in l.s 82154abd99SDavid du Colombier */ 83154abd99SDavid du Colombier ORR R6, R6 /* NOP: avoid link bug */ 84154abd99SDavid du Colombier B (R6) 85154abd99SDavid du Colombier 86154abd99SDavid du Colombier/* 87154abd99SDavid du Colombier * turn the caches off, double map 0 & KZERO, invalidate TLBs, revert to 88154abd99SDavid du Colombier * tiny addresses. upon return, it will be safe to turn off the mmu. 89154abd99SDavid du Colombier */ 90154abd99SDavid du ColombierTEXT cachesoff(SB), 1, $-4 91154abd99SDavid du Colombier MOVW $(PsrDirq|PsrDfiq|PsrMsvc), R0 92154abd99SDavid du Colombier MOVW R0, CPSR 93154abd99SDavid du Colombier MOVW $KADDR(0x100-4), R7 /* just before this code */ 94154abd99SDavid du Colombier MOVW R14, (R7) /* save link */ 95154abd99SDavid du Colombier 96154abd99SDavid du Colombier BL cacheuwbinv(SB) 97154abd99SDavid du Colombier 98154abd99SDavid du Colombier MRC CpSC, 0, R0, C(CpCONTROL), C(0) 99154abd99SDavid du Colombier BIC $(CpCwb|CpCicache|CpCdcache|CpCalign), R0 100154abd99SDavid du Colombier MCR CpSC, 0, R0, C(CpCONTROL), C(0) 101154abd99SDavid du Colombier BARRIERS 102154abd99SDavid du Colombier 103154abd99SDavid du Colombier /* redo double map of 0, KZERO */ 104154abd99SDavid du Colombier MOVW $(L1+L1X(PHYSDRAM)), R4 /* address of PTE for 0 */ 105154abd99SDavid du Colombier MOVW $PTEDRAM, R2 /* PTE bits */ 106154abd99SDavid du Colombier// MOVW $PTEIO, R2 /* PTE bits */ 107154abd99SDavid du Colombier MOVW $PHYSDRAM, R3 108154abd99SDavid du Colombier MOVW $512, R5 109154abd99SDavid du Colombier_ptrdbl: 110154abd99SDavid du Colombier ORR R3, R2, R1 /* first identity-map 0 to 0, etc. */ 111154abd99SDavid du Colombier MOVW R1, (R4) 112154abd99SDavid du Colombier ADD $4, R4 /* bump PTE address */ 113154abd99SDavid du Colombier ADD $MiB, R3 /* bump pa */ 114154abd99SDavid du Colombier SUB.S $1, R5 115154abd99SDavid du Colombier BNE _ptrdbl 116154abd99SDavid du Colombier 117154abd99SDavid du Colombier BARRIERS 118154abd99SDavid du Colombier MOVW $0, R0 119154abd99SDavid du Colombier MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvd), CpTLBinv 120154abd99SDavid du Colombier MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv 121154abd99SDavid du Colombier BARRIERS 122154abd99SDavid du Colombier 123154abd99SDavid du Colombier /* back to 29- or 26-bit addressing, mainly for SB */ 124154abd99SDavid du Colombier MRC CpSC, 0, R0, C(CpCONTROL), C(0) 125154abd99SDavid du Colombier BIC $(CpCd32|CpCi32), R0 126154abd99SDavid du Colombier MCR CpSC, 0, R0, C(CpCONTROL), C(0) 127154abd99SDavid du Colombier BARRIERS 128154abd99SDavid du Colombier 129154abd99SDavid du Colombier MOVW $KADDR(0x100-4), R7 /* just before this code */ 130154abd99SDavid du Colombier MOVW (R7), R14 /* restore link */ 131154abd99SDavid du Colombier RET 132154abd99SDavid du Colombier 133154abd99SDavid du ColombierTEXT _r15warp(SB), 1, $-4 13433cde4a6SDavid du Colombier BIC $KSEGM, R14 135154abd99SDavid du Colombier ORR R0, R14 136154abd99SDavid du Colombier RET 137154abd99SDavid du Colombier 138154abd99SDavid du ColombierTEXT mmudisable(SB), 1, $-4 139154abd99SDavid du Colombier MRC CpSC, 0, R0, C(CpCONTROL), C(0) 140154abd99SDavid du Colombier BIC $(CpChv|CpCmmu|CpCdcache|CpCicache|CpCwb), R0 141154abd99SDavid du Colombier MCR CpSC, 0, R0, C(CpCONTROL), C(0) 142154abd99SDavid du Colombier BARRIERS 143154abd99SDavid du Colombier RET 144154abd99SDavid du Colombier 145154abd99SDavid du ColombierTEXT mmuinvalidate(SB), 1, $-4 /* invalidate all */ 146154abd99SDavid du Colombier MOVW $0, R0 147154abd99SDavid du Colombier MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv 148154abd99SDavid du Colombier BARRIERS 149154abd99SDavid du Colombier RET 150154abd99SDavid du Colombier 151154abd99SDavid du ColombierTEXT cacheuwbinv(SB), 1, $-4 /* D+I writeback+invalidate */ 152154abd99SDavid du Colombier BARRIERS 153154abd99SDavid du Colombier MOVW CPSR, R3 /* splhi */ 154154abd99SDavid du Colombier ORR $(PsrDirq), R3, R1 155154abd99SDavid du Colombier MOVW R1, CPSR 156154abd99SDavid du Colombier 157154abd99SDavid du Colombier_uwbinv: /* D writeback+invalidate */ 158154abd99SDavid du Colombier MRC CpSC, 0, PC, C(CpCACHE), C(CpCACHEwbi), CpCACHEtest 159154abd99SDavid du Colombier BNE _uwbinv 160154abd99SDavid du Colombier 16133cde4a6SDavid du Colombier MOVW $0, R0 /* I invalidate */ 16233cde4a6SDavid du Colombier MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall 163b72bcbbfSDavid du Colombier /* drain L1 write buffer, also drains L2 eviction buffer on sheeva */ 16433cde4a6SDavid du Colombier BARRIERS 16533cde4a6SDavid du Colombier 166b72bcbbfSDavid du Colombier MCR CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2flush), CpTCl2all 16733cde4a6SDavid du Colombier BARRIERS 168b72bcbbfSDavid du Colombier MCR CpSC, CpL2, R0, C(CpTESTCFG), C(CpTCl2inv), CpTCl2all 169154abd99SDavid du Colombier BARRIERS 170154abd99SDavid du Colombier 171154abd99SDavid du Colombier MOVW R3, CPSR /* splx */ 172154abd99SDavid du Colombier RET 173