15d9de2d3SDavid du Colombier/* 2*5c47fe09SDavid du Colombier * armv6/armv7 reboot code 35d9de2d3SDavid du Colombier */ 45d9de2d3SDavid du Colombier#include "arm.s" 55d9de2d3SDavid du Colombier 6*5c47fe09SDavid du Colombier#define PTEDRAM (Dom0|L1AP(Krw)|Section) 7*5c47fe09SDavid du Colombier 8*5c47fe09SDavid du Colombier#define WFI WORD $0xe320f003 /* wait for interrupt */ 9*5c47fe09SDavid du Colombier#define WFE WORD $0xe320f002 /* wait for event */ 10*5c47fe09SDavid du Colombier 115d9de2d3SDavid du Colombier/* 12*5c47fe09SDavid du Colombier * CPU0: 13*5c47fe09SDavid du Colombier * main(PADDR(entry), PADDR(code), size); 14*5c47fe09SDavid du Colombier * Copy the new kernel to its correct location in virtual memory. 15*5c47fe09SDavid du Colombier * Then turn off the mmu and jump to the start of the kernel. 16*5c47fe09SDavid du Colombier * 17*5c47fe09SDavid du Colombier * Other CPUs: 18*5c47fe09SDavid du Colombier * main(0, soc.armlocal, 0); 19*5c47fe09SDavid du Colombier * Turn off the mmu, wait for a restart address from CPU0, and jump to it. 205d9de2d3SDavid du Colombier */ 215d9de2d3SDavid du Colombier 22*5c47fe09SDavid du Colombier/* */ 235d9de2d3SDavid du ColombierTEXT main(SB), 1, $-4 245d9de2d3SDavid du Colombier MOVW $setR12(SB), R12 255d9de2d3SDavid du Colombier 265d9de2d3SDavid du Colombier /* copy in arguments before stack gets unmapped */ 275d9de2d3SDavid du Colombier MOVW R0, R8 /* entry point */ 28*5c47fe09SDavid du Colombier MOVW p2+4(FP), R7 /* source */ 29*5c47fe09SDavid du Colombier MOVW n+8(FP), R6 /* byte count */ 305d9de2d3SDavid du Colombier 31*5c47fe09SDavid du Colombier /* redo double map of first MiB PHYSDRAM = KZERO */ 32*5c47fe09SDavid du Colombier MOVW 12(R(MACH)), R2 /* m->mmul1 (virtual addr) */ 33*5c47fe09SDavid du Colombier MOVW $PTEDRAM, R1 /* PTE bits */ 34*5c47fe09SDavid du Colombier MOVW R1, (R2) 35*5c47fe09SDavid du Colombier DSB 36*5c47fe09SDavid du Colombier MCR CpSC, 0, R2, C(CpCACHE), C(CpCACHEwb), CpCACHEse 375d9de2d3SDavid du Colombier 38*5c47fe09SDavid du Colombier /* invalidate stale TLBs */ 39*5c47fe09SDavid du Colombier BARRIERS 40*5c47fe09SDavid du Colombier MOVW $0, R0 41*5c47fe09SDavid du Colombier MCR CpSC, 0, R0, C(CpTLB), C(CpTLBinvu), CpTLBinv 42*5c47fe09SDavid du Colombier BARRIERS 435d9de2d3SDavid du Colombier 44*5c47fe09SDavid du Colombier /* relocate PC to physical addressing */ 45*5c47fe09SDavid du Colombier MOVW $_reloc(SB), R15 46*5c47fe09SDavid du Colombier 47*5c47fe09SDavid du ColombierTEXT _reloc(SB), $-4 48*5c47fe09SDavid du Colombier 49*5c47fe09SDavid du Colombier /* continue with reboot only on cpu0 */ 50*5c47fe09SDavid du Colombier CPUID(R2) 51*5c47fe09SDavid du Colombier BEQ bootcpu 52*5c47fe09SDavid du Colombier 53*5c47fe09SDavid du Colombier /* other cpus wait for inter processor interrupt from cpu0 */ 54*5c47fe09SDavid du Colombier 55*5c47fe09SDavid du Colombier /* turn caches off, invalidate icache */ 56*5c47fe09SDavid du Colombier MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl 57*5c47fe09SDavid du Colombier BIC $(CpCdcache|CpCicache), R1 58*5c47fe09SDavid du Colombier MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl 59*5c47fe09SDavid du Colombier MOVW $0, R0 60*5c47fe09SDavid du Colombier MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall 615d9de2d3SDavid du Colombier /* turn off mmu */ 625d9de2d3SDavid du Colombier MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl 635d9de2d3SDavid du Colombier BIC $CpCmmu, R1 645d9de2d3SDavid du Colombier MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl 65*5c47fe09SDavid du Colombier /* turn off SMP cache snooping */ 66*5c47fe09SDavid du Colombier MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl 67*5c47fe09SDavid du Colombier BIC $CpACsmp, R1 68*5c47fe09SDavid du Colombier MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl 69*5c47fe09SDavid du Colombier ISB 70*5c47fe09SDavid du Colombier DSB 71*5c47fe09SDavid du Colombier /* turn icache back on */ 72*5c47fe09SDavid du Colombier MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl 73*5c47fe09SDavid du Colombier ORR $(CpCicache), R1 74*5c47fe09SDavid du Colombier MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl 75*5c47fe09SDavid du Colombier BARRIERS 765d9de2d3SDavid du Colombier 77*5c47fe09SDavid du Colombierdowfi: 78*5c47fe09SDavid du Colombier WFE /* wait for event signal */ 79*5c47fe09SDavid du Colombier MOVW $0xCC(R7), R1 /* inter-core .startcpu mailboxes */ 80*5c47fe09SDavid du Colombier ADD R2<<4, R1 /* mailbox for this core */ 81*5c47fe09SDavid du Colombier MOVW 0(R1), R8 /* content of mailbox */ 82*5c47fe09SDavid du Colombier CMP $0, R8 83*5c47fe09SDavid du Colombier BEQ dowfi /* if zero, wait again */ 84*5c47fe09SDavid du Colombier BL (R8) /* call received address */ 85*5c47fe09SDavid du Colombier B dowfi /* shouldn't return */ 86*5c47fe09SDavid du Colombier 87*5c47fe09SDavid du Colombierbootcpu: 88*5c47fe09SDavid du Colombier MOVW $PADDR(MACHADDR+MACHSIZE-4), SP 895d9de2d3SDavid du Colombier 905d9de2d3SDavid du Colombier /* copy the kernel to final destination */ 91*5c47fe09SDavid du Colombier MOVW R8, R9 /* save physical entry point */ 92*5c47fe09SDavid du Colombier ADD $KZERO, R8 /* relocate dest to virtual */ 93*5c47fe09SDavid du Colombier ADD $KZERO, R7 /* relocate src to virtual */ 94*5c47fe09SDavid du Colombier ADD $3, R6 /* round length to words */ 95*5c47fe09SDavid du Colombier BIC $3, R6 96*5c47fe09SDavid du Colombiermemloop: 97*5c47fe09SDavid du Colombier MOVM.IA.W (R7), [R1] 98*5c47fe09SDavid du Colombier MOVM.IA.W [R1], (R8) 99*5c47fe09SDavid du Colombier SUB.S $4, R6 100*5c47fe09SDavid du Colombier BNE memloop 1015d9de2d3SDavid du Colombier 102*5c47fe09SDavid du Colombier /* clean dcache using appropriate code for armv6 or armv7 */ 103*5c47fe09SDavid du Colombier MRC CpSC, 0, R1, C(CpID), C(CpIDfeat), 7 /* Memory Model Feature Register 3 */ 104*5c47fe09SDavid du Colombier TST $0xF, R1 /* hierarchical cache maintenance? */ 105*5c47fe09SDavid du Colombier BNE l2wb 106*5c47fe09SDavid du Colombier DSB 1075d9de2d3SDavid du Colombier MOVW $0, R0 108*5c47fe09SDavid du Colombier MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEwb), CpCACHEall 109*5c47fe09SDavid du Colombier B l2wbx 110*5c47fe09SDavid du Colombierl2wb: 111*5c47fe09SDavid du Colombier BL cachedwb(SB) 112*5c47fe09SDavid du Colombier BL l2cacheuwb(SB) 113*5c47fe09SDavid du Colombierl2wbx: 1145d9de2d3SDavid du Colombier 115*5c47fe09SDavid du Colombier /* turn caches off, invalidate icache */ 1165d9de2d3SDavid du Colombier MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl 1175d9de2d3SDavid du Colombier BIC $(CpCdcache|CpCicache|CpCpredict), R1 1185d9de2d3SDavid du Colombier MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl 119*5c47fe09SDavid du Colombier DSB 120*5c47fe09SDavid du Colombier MOVW $0, R0 121*5c47fe09SDavid du Colombier MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvi), CpCACHEall 122*5c47fe09SDavid du Colombier DSB 123*5c47fe09SDavid du Colombier /* turn off mmu */ 124*5c47fe09SDavid du Colombier MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl 125*5c47fe09SDavid du Colombier BIC $CpCmmu, R1 126*5c47fe09SDavid du Colombier MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpMainctl 1275d9de2d3SDavid du Colombier BARRIERS 128*5c47fe09SDavid du Colombier /* turn off SMP cache snooping */ 129*5c47fe09SDavid du Colombier MRC CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl 130*5c47fe09SDavid du Colombier BIC $CpACsmp, R1 131*5c47fe09SDavid du Colombier MCR CpSC, 0, R1, C(CpCONTROL), C(0), CpAuxctl 1325d9de2d3SDavid du Colombier 133*5c47fe09SDavid du Colombier /* invalidate dcache using appropriate code for armv6 or armv7 */ 134*5c47fe09SDavid du Colombier MRC CpSC, 0, R1, C(CpID), C(CpIDfeat), 7 /* Memory Model Feature Register 3 */ 135*5c47fe09SDavid du Colombier TST $0xF, R1 /* hierarchical cache maintenance */ 136*5c47fe09SDavid du Colombier BNE l2inv 137*5c47fe09SDavid du Colombier DSB 138*5c47fe09SDavid du Colombier MOVW $0, R0 139*5c47fe09SDavid du Colombier MCR CpSC, 0, R0, C(CpCACHE), C(CpCACHEinvd), CpCACHEall 140*5c47fe09SDavid du Colombier B l2invx 141*5c47fe09SDavid du Colombierl2inv: 142*5c47fe09SDavid du Colombier BL cachedinv(SB) 143*5c47fe09SDavid du Colombier BL l2cacheuinv(SB) 144*5c47fe09SDavid du Colombierl2invx: 1455d9de2d3SDavid du Colombier 146*5c47fe09SDavid du Colombier /* jump to restart entry point */ 147*5c47fe09SDavid du Colombier MOVW R9, R8 148*5c47fe09SDavid du Colombier MOVW $0, R9 149*5c47fe09SDavid du Colombier B (R8) 1505d9de2d3SDavid du Colombier 151*5c47fe09SDavid du Colombier#define ICACHELINESZ 32 152*5c47fe09SDavid du Colombier#include "cache.v7.s" 153