/* $NetBSD: entry.S,v 1.6 2012/01/14 20:03:12 phx Exp $ */ #include #include #include #include #include .text .globl _start _start: /* * Save possible argc and argv values from the firmware, usually * passed in r3 and r4. * When started with "bootm", as a Linux kernel module, r6 and r7 * point to the start and end address of the bootargs. */ mr 30,3 mr 31,4 mr 28,6 mr 29,7 /* Disable interrupts and everything except the MMU. */ mfmsr 3 andi. 3,3,PSL_DR|PSL_IR mtmsr 3 isync /* * U-Boot/PPCBoot forgets to flush the cache when using the "bootm" * command, so we have to do that now. */ lis 11,_start@ha addi 11,11,_start@l li 10,-32 and 11,11,10 lis 12,(_edata+31)@ha addi 12,12,(_edata+31)@l bl syncicache mfspr 11,SPR_HID0 andi. 0,11,HID0_DCE ori 11,11,HID0_ICE ori 8,11,HID0_ICFI bne 1f /* don't invalidate the D-cache */ ori 8,8,HID0_DCFI /* unless it wasn't enabled */ 1: mfmsr 0 andi. 0,0,PSL_DR beq 2f lis 5,0xfec00000@ha /* CONFIG_ADDR of PCI */ lis 6,0xfee00000@ha /* CONFIG_DATA of PCI */ mfspr 3,SPR_DBAT0U mfspr 4,SPR_DBAT0L bl dbat_sanity_check beq 3f mfspr 3,SPR_DBAT1U mfspr 4,SPR_DBAT1L bl dbat_sanity_check beq 3f mfspr 3,SPR_DBAT2U mfspr 4,SPR_DBAT2L bl dbat_sanity_check beq 3f mfspr 3,SPR_DBAT3U mfspr 4,SPR_DBAT3L bl dbat_sanity_check beq 3f 2: /* Disable D-cache */ li 0,HID0_DCE andc 11,11,0 b 4f 3: /* Enable D-cache */ ori 11,11,HID0_DCE 4: lis 1,BAT123@ha addi 1,1,BAT123@l lwz 3,0(1) lwz 4,4(1) mtdbatl 1,3 mtdbatu 1,4 lwz 3,8(1) lwz 4,12(1) mtdbatl 2,3 mtdbatu 2,4 lwz 3,16(1) lwz 4,20(1) mtdbatl 3,3 mtdbatu 3,4 sync mtspr SPR_HID0,8 /* enable and invalidate caches */ sync mtspr SPR_HID0,11 /* enable caches */ sync isync /* make sure .bss gets zeroed. */ li 0,0 lis 8,edata@ha addi 8,8,edata@l lis 9,end@ha addi 9,9,end@l 5: cmpw 0,8,9 /* edata & end are >= word aligned */ bge 6f stw 0,0(8) addi 8,8,4 b 5b 6: /* prepare stack at +1MB from _start, 16-byte aligned */ lis 1,_start@ha addi 1,1,_start@l addis 1,1,0x100000@ha li 10,-16 and 1,1,10 stw 0,0(1) bl brdsetup #ifdef DEBUG bl init_vectors #endif mr 3,30 mr 4,31 mr 5,28 mr 6,29 bl main hang: b hang /* NOTREACHED */ dbat_sanity_check: andi. 0,3,BAT_Vs beq 2f andi. 0,4,BAT_I|BAT_PP_RW cmpwi 0,0,BAT_I|BAT_PP_RW bnelr rlwinm 0,3,15,4,14 andis. 3,3,0xfffe0000@ha /* BAT_EPI */ andis. 4,4,BAT_RPN@ha cmplw 0,3,4 bnelr add 4,4,0 oris 4,4,0x0001ffff@ha ori 4,4,0x0001ffff@l cmplw 0,3,5 bgt 1f cmplw 0,5,4 bgt 1f li 5,0 1: cmplw 0,3,6 bgt 2f cmplw 0,6,4 bgt 2f li 6,0 2: cmplw 0,5,6 blr /* * run(startsym, endsym, howto, bootinfo, entry) */ .globl run run: mtctr 7 /* hat trick jump to entry point */ bctr /* * newaltboot(argc, argv, altboot_base, altboot_len) * To be executed in a safe memory region. Copies the new altboot from * altboot_base to 0x1000000 and starts it there. */ .globl newaltboot newaltboot: lis 7,0x1000000@h mr 11,7 subi 7,7,4 subi 5,5,4 add 12,11,6 addi 6,6,3 srawi 6,6,2 mtctr 6 1: lwzu 8,4(5) stwu 8,4(7) bdnz+ 1b mtctr 11 addi 12,12,31 bl syncicache bctr syncicache: /* r11=start, r12=end, r10=scratch */ mr 10,11 2: dcbst 0,10 addi 10,10,32 cmplw 10,12 ble 2b sync 3: icbi 0,11 addi 11,11,32 cmplw 11,12 ble 3b sync isync blr .globl newaltboot_end newaltboot_end: /* 8-bit i/o access */ .globl out8 out8: stb 4,0(3) eieio blr .globl in8 in8: lbz 3,0(3) eieio blr /* * reverse endian access to mimic outw/outl/inw/inl */ .globl out16rb .globl iohtole16 out16rb: iohtole16: sthbrx 4,0,3 eieio blr .globl out32rb .globl iohtole32 out32rb: iohtole32: stwbrx 4,0,3 eieio blr .globl in16rb .globl iole16toh in16rb: iole16toh: lhbrx 3,0,3 eieio blr .globl in32rb .globl iole32toh in32rb: iole32toh: lwbrx 3,0,3 eieio blr #ifdef DEBUG /* * Call an exception handler, which prints out all information * about the type of exception, cpu registers, stack frame * backtrace, etc. * Use a new stack at 0x2000 and make room for 32 GPRs, and 15 * special registers. The layout will be: * 0x00: link area * 0x10: R0 * ... * 0x8c: R31 * 0x90: CR, XER, LR, CTR * 0xa0: SRR0, SRR1, DAR, DSISR * 0xb0: DMISS, DCMP, HASH1, HASH2 * 0xc0: IMISS, ICMP, RPA * */ .globl trap trap: mtsprg1 1 mfmsr 1 andis. 1,1,PSL_TGPR@h beq 1f andi. 1,1,0xffff /* make sure TGPR is disabled */ mtmsr 1 isync mtsprg1 1 /* and save the real r1 again */ 1: li 1,0x2000-16-(32*4+15*4) stmw 2,24(1) /* save r2..r31 */ stw 0,16(1) /* save r0 */ mfsprg1 3 stw 3,20(1) /* and finally r1 */ mfcr 3 stw 3,0x90(1) mfxer 3 stw 3,0x94(1) mflr 3 stw 3,0x98(1) mfctr 3 stw 3,0x9c(1) mfsrr0 3 stw 3,0xa0(1) mfsrr1 3 stw 3,0xa4(1) mfdar 3 stw 3,0xa8(1) mfdsisr 3 stw 3,0xac(1) mfspr 3,976 stw 3,0xb0(1) mfspr 3,977 stw 3,0xb4(1) mfspr 3,978 stw 3,0xb8(1) mfspr 3,979 stw 3,0xbc(1) mfspr 3,980 stw 3,0xc0(1) mfspr 3,981 stw 3,0xc4(1) mfspr 3,982 stw 3,0xc8(1) bl call_handler call_handler: lis 11,exception_handler@ha addi 11,11,exception_handler@l mtsrr0 11 li 0,PSL_DR|PSL_IR mtsrr1 0 mflr 3 subi 3,3,call_handler-trap addi 4,1,16 rfi .globl trap_end trap_end: #endif .data #define xBATL(pa, wimg, pp) \ ((pa) | (wimg) | (pp)) #define xBATU(va, len, v) \ ((va) | ((len) & BAT_BL) | ((v) & BAT_V)) BAT123: .long xBATL(0x80000000, BAT_I|BAT_G, BAT_PP_RW) .long xBATU(0x80000000, BAT_BL_256M, BAT_Vs) .long xBATL(0xfc000000, BAT_I|BAT_G, BAT_PP_RW) .long xBATU(0xfc000000, BAT_BL_64M, BAT_Vs) .long xBATL(0x70000000, BAT_I|BAT_G, BAT_PP_RW) .long xBATU(0x70000000, BAT_BL_128K, BAT_Vs)