18e32b400SDavid du Colombier/* 28e32b400SDavid du Colombier * omap3530 reboot code 38e32b400SDavid du Colombier * 48e32b400SDavid du Colombier * must fit in 11K to avoid stepping on PTEs; see mem.h. 58e32b400SDavid du Colombier * 68e32b400SDavid du Colombier * R11 is used by the loader as a temporary, so avoid it. 78e32b400SDavid du Colombier */ 88e32b400SDavid du Colombier#include "arm.s" 98e32b400SDavid du Colombier 108e32b400SDavid du Colombier/* 118e32b400SDavid du Colombier * Turn off MMU, then copy the new kernel to its correct location 128e32b400SDavid du Colombier * in physical memory. Then jump to the start of the kernel. 138e32b400SDavid du Colombier */ 148e32b400SDavid du Colombier 158e32b400SDavid du Colombier/* main(PADDR(entry), PADDR(code), size); */ 168e32b400SDavid du ColombierTEXT main(SB), 1, $-4 178e32b400SDavid du Colombier MOVW $setR12(SB), R12 188e32b400SDavid du Colombier 198e32b400SDavid du Colombier MOVW R0, p1+0(FP) /* destination, passed in R0 */ 208e32b400SDavid du Colombier 218e32b400SDavid du Colombier MOVW CPSR, R0 228e32b400SDavid du Colombier ORR $(PsrDirq|PsrDfiq), R0 238e32b400SDavid du Colombier MOVW R0, CPSR /* splhi */ 248e32b400SDavid du Colombier BARRIERS 258e32b400SDavid du Colombier 26*bb9c7457SDavid du ColombierPUTC('R') 278e32b400SDavid du Colombier MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl 288e32b400SDavid du Colombier BIC $CpACasa, R1 /* no speculative I access forwarding to mem */ 298e32b400SDavid du Colombier /* slow down */ 308e32b400SDavid du Colombier ORR $(CpACcachenopipe|CpACcp15serial|CpACcp15waitidle|CpACcp15pipeflush), R1 318e32b400SDavid du Colombier MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl 328e32b400SDavid du Colombier BARRIERS 338e32b400SDavid du Colombier 348e32b400SDavid du Colombier BL cachesoff(SB) 358e32b400SDavid du Colombier /* now back in 29- or 26-bit addressing, mainly for SB */ 368e32b400SDavid du Colombier /* double mapping of PHYSDRAM & KZERO now in effect */ 378e32b400SDavid du Colombier 388e32b400SDavid du Colombier /* 398e32b400SDavid du Colombier * turn the MMU off 408e32b400SDavid du Colombier */ 418e32b400SDavid du Colombier 42*bb9c7457SDavid du ColombierPUTC('e') 438e32b400SDavid du Colombier /* first switch to PHYSDRAM-based addresses */ 448e32b400SDavid du Colombier DMB 458e32b400SDavid du Colombier 468e32b400SDavid du Colombier MOVW $KSEGM, R7 /* clear segment bits */ 478e32b400SDavid du Colombier MOVW $PHYSDRAM, R0 /* set dram base bits */ 488e32b400SDavid du Colombier BIC R7, R12 /* adjust SB */ 498e32b400SDavid du Colombier ORR R0, R12 508e32b400SDavid du Colombier 518e32b400SDavid du Colombier BL _r15warp(SB) 528e32b400SDavid du Colombier /* don't care about saving R14; we're not returning */ 538e32b400SDavid du Colombier 548e32b400SDavid du Colombier /* 558e32b400SDavid du Colombier * now running in PHYSDRAM segment, not KZERO. 568e32b400SDavid du Colombier */ 578e32b400SDavid du Colombier 58*bb9c7457SDavid du ColombierPUTC('b') 598e32b400SDavid du Colombier SUB $12, SP /* paranoia */ 608e32b400SDavid du Colombier BL cacheuwbinv(SB) 618e32b400SDavid du Colombier ADD $12, SP /* paranoia */ 628e32b400SDavid du Colombier 638e32b400SDavid du Colombier /* invalidate mmu mappings */ 648e32b400SDavid du Colombier MOVW $KZERO, R0 /* some valid virtual address */ 658e32b400SDavid du Colombier MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv 668e32b400SDavid du Colombier BARRIERS 678e32b400SDavid du Colombier 68*bb9c7457SDavid du ColombierPUTC('o') 698e32b400SDavid du Colombier MRC CpSC, 0, R0, C(CpCONTROL), C(0) 708e32b400SDavid du Colombier BIC $(CpCmmu|CpCdcache|CpCicache), R0 718e32b400SDavid du Colombier MCR CpSC, 0, R0, C(CpCONTROL), C(0) /* mmu off */ 728e32b400SDavid du Colombier BARRIERS 738e32b400SDavid du Colombier 74*bb9c7457SDavid du ColombierPUTC('o') 758e32b400SDavid du Colombier /* copy in arguments from stack frame before moving stack */ 768e32b400SDavid du Colombier MOVW p2+4(FP), R4 /* phys source */ 778e32b400SDavid du Colombier MOVW n+8(FP), R5 /* byte count */ 788e32b400SDavid du Colombier MOVW p1+0(FP), R6 /* phys destination */ 798e32b400SDavid du Colombier 808e32b400SDavid du Colombier /* set up a new stack for local vars and memmove args */ 818e32b400SDavid du Colombier MOVW R6, SP /* tiny trampoline stack */ 828e32b400SDavid du Colombier SUB $(0x20 + 4), SP /* back up before a.out header */ 838e32b400SDavid du Colombier 848e32b400SDavid du Colombier// MOVW R14, -48(SP) /* store return addr */ 858e32b400SDavid du Colombier SUB $48, SP /* allocate stack frame */ 868e32b400SDavid du Colombier 878e32b400SDavid du Colombier MOVW R5, 40(SP) /* save count */ 888e32b400SDavid du Colombier MOVW R6, 44(SP) /* save dest/entry */ 898e32b400SDavid du Colombier 908e32b400SDavid du Colombier DELAY(printloop2, 2) 91*bb9c7457SDavid du ColombierPUTC('t') 928e32b400SDavid du Colombier 938e32b400SDavid du Colombier MOVW 40(SP), R5 /* restore count */ 948e32b400SDavid du Colombier MOVW 44(SP), R6 /* restore dest/entry */ 958e32b400SDavid du Colombier MOVW R6, 0(SP) /* normally saved LR goes here */ 968e32b400SDavid du Colombier MOVW R6, 4(SP) /* push dest */ 978e32b400SDavid du Colombier MOVW R6, R0 988e32b400SDavid du Colombier MOVW R4, 8(SP) /* push src */ 998e32b400SDavid du Colombier MOVW R5, 12(SP) /* push size */ 1008e32b400SDavid du Colombier BL memmove(SB) 1018e32b400SDavid du Colombier 102*bb9c7457SDavid du ColombierPUTC('-') 1038e32b400SDavid du Colombier /* 1048e32b400SDavid du Colombier * flush caches 1058e32b400SDavid du Colombier */ 1068e32b400SDavid du Colombier BL cacheuwbinv(SB) 1078e32b400SDavid du Colombier 108*bb9c7457SDavid du ColombierPUTC('>') 1098e32b400SDavid du Colombier DELAY(printloopret, 1) 110*bb9c7457SDavid du ColombierPUTC('\r') 1118e32b400SDavid du Colombier DELAY(printloopnl, 1) 112*bb9c7457SDavid du ColombierPUTC('\n') 1138e32b400SDavid du Colombier/* 1148e32b400SDavid du Colombier * jump to kernel entry point. Note the true kernel entry point is 1158e32b400SDavid du Colombier * the virtual address KZERO|R6, but this must wait until 1168e32b400SDavid du Colombier * the MMU is enabled by the kernel in l.s 1178e32b400SDavid du Colombier */ 1188e32b400SDavid du Colombier MOVW 44(SP), R6 /* restore R6 (dest/entry) */ 1198e32b400SDavid du Colombier ORR R6, R6 /* NOP: avoid link bug */ 1208e32b400SDavid du Colombier B (R6) 121*bb9c7457SDavid du ColombierPUTC('?') 1228e32b400SDavid du Colombier B 0(PC) 1238e32b400SDavid du Colombier 1248e32b400SDavid du Colombier/* 1258e32b400SDavid du Colombier * turn the caches off, double map PHYSDRAM & KZERO, invalidate TLBs, revert 1268e32b400SDavid du Colombier * to tiny addresses. upon return, it will be safe to turn off the mmu. 1278e32b400SDavid du Colombier */ 1288e32b400SDavid du ColombierTEXT cachesoff(SB), 1, $-4 1298e32b400SDavid du Colombier MOVM.DB.W [R14,R1-R10], (R13) /* save regs on stack */ 1308e32b400SDavid du Colombier MOVW CPSR, R0 1318e32b400SDavid du Colombier ORR $(PsrDirq|PsrDfiq), R0 1328e32b400SDavid du Colombier MOVW R0, CPSR 1338e32b400SDavid du Colombier BARRIERS 1348e32b400SDavid du Colombier 1358e32b400SDavid du Colombier SUB $12, SP /* paranoia */ 1368e32b400SDavid du Colombier BL cacheuwbinv(SB) 1378e32b400SDavid du Colombier ADD $12, SP /* paranoia */ 1388e32b400SDavid du Colombier 1398e32b400SDavid du Colombier MRC CpSC, 0, R0, C(CpCONTROL), C(0) 1408e32b400SDavid du Colombier BIC $(CpCicache|CpCdcache), R0 1418e32b400SDavid du Colombier MCR CpSC, 0, R0, C(CpCONTROL), C(0) /* caches off */ 1428e32b400SDavid du Colombier BARRIERS 1438e32b400SDavid du Colombier 1448e32b400SDavid du Colombier /* 1458e32b400SDavid du Colombier * caches are off 1468e32b400SDavid du Colombier */ 1478e32b400SDavid du Colombier 1488e32b400SDavid du Colombier /* invalidate stale TLBs before changing them */ 1498e32b400SDavid du Colombier MOVW $KZERO, R0 /* some valid virtual address */ 1508e32b400SDavid du Colombier MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv 1518e32b400SDavid du Colombier BARRIERS 1528e32b400SDavid du Colombier 1538e32b400SDavid du Colombier /* redo double map of PHYSDRAM, KZERO */ 1548e32b400SDavid du Colombier MOVW $PHYSDRAM, R3 1558e32b400SDavid du Colombier CMP $KZERO, R3 1568e32b400SDavid du Colombier BEQ noun2map 1578e32b400SDavid du Colombier MOVW $(L1+L1X(PHYSDRAM)), R4 /* address of PHYSDRAM's PTE */ 1588e32b400SDavid du Colombier MOVW $PTEDRAM, R2 /* PTE bits */ 1598e32b400SDavid du Colombier MOVW $DOUBLEMAPMBS, R5 1608e32b400SDavid du Colombier_ptrdbl: 1618e32b400SDavid du Colombier ORR R3, R2, R1 /* first identity-map 0 to 0, etc. */ 1628e32b400SDavid du Colombier MOVW R1, (R4) 1638e32b400SDavid du Colombier ADD $4, R4 /* bump PTE address */ 1648e32b400SDavid du Colombier ADD $MiB, R3 /* bump pa */ 1658e32b400SDavid du Colombier SUB.S $1, R5 1668e32b400SDavid du Colombier BNE _ptrdbl 1678e32b400SDavid du Colombiernoun2map: 1688e32b400SDavid du Colombier 1698e32b400SDavid du Colombier /* 1708e32b400SDavid du Colombier * flush stale TLB entries 1718e32b400SDavid du Colombier */ 1728e32b400SDavid du Colombier 1738e32b400SDavid du Colombier BARRIERS 1748e32b400SDavid du Colombier MOVW $KZERO, R0 /* some valid virtual address */ 1758e32b400SDavid du Colombier MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv 1768e32b400SDavid du Colombier BARRIERS 1778e32b400SDavid du Colombier 1788e32b400SDavid du Colombier /* switch back to PHYSDRAM addressing, mainly for SB */ 1798e32b400SDavid du Colombier MOVW $KSEGM, R7 /* clear segment bits */ 1808e32b400SDavid du Colombier MOVW $PHYSDRAM, R0 /* set dram base bits */ 1818e32b400SDavid du Colombier BIC R7, R12 /* adjust SB */ 1828e32b400SDavid du Colombier ORR R0, R12 1838e32b400SDavid du Colombier BIC R7, SP 1848e32b400SDavid du Colombier ORR R0, SP 1858e32b400SDavid du Colombier 1868e32b400SDavid du Colombier MOVM.IA.W (R13), [R14,R1-R10] /* restore regs from stack */ 1878e32b400SDavid du Colombier 1888e32b400SDavid du Colombier MOVW $KSEGM, R0 /* clear segment bits */ 1898e32b400SDavid du Colombier BIC R0, R14 /* adjust link */ 1908e32b400SDavid du Colombier MOVW $PHYSDRAM, R0 /* set dram base bits */ 1918e32b400SDavid du Colombier ORR R0, R14 1928e32b400SDavid du Colombier 1938e32b400SDavid du Colombier RET 1948e32b400SDavid du Colombier 1958e32b400SDavid du ColombierTEXT _r15warp(SB), 1, $-4 1968e32b400SDavid du Colombier BIC R7, R14 /* link */ 1978e32b400SDavid du Colombier ORR R0, R14 1988e32b400SDavid du Colombier 1998e32b400SDavid du Colombier BIC R7, R13 /* SP */ 2008e32b400SDavid du Colombier ORR R0, R13 2018e32b400SDavid du Colombier RET 2028e32b400SDavid du Colombier 2038e32b400SDavid du ColombierTEXT panic(SB), 1, $-4 /* stub */ 204*bb9c7457SDavid du ColombierPUTC('?') 2058e32b400SDavid du Colombier RET 2068e32b400SDavid du ColombierTEXT pczeroseg(SB), 1, $-4 /* stub */ 2078e32b400SDavid du Colombier RET 2088e32b400SDavid du Colombier 2098e32b400SDavid du Colombier#include "cache.v7.s" 210