1 /* $NetBSD: entry.S,v 1.6 2012/01/14 20:03:12 phx Exp $ */ 2 3 #include <powerpc/psl.h> 4 #include <powerpc/spr.h> 5 #include <powerpc/oea/spr.h> 6 #include <powerpc/oea/bat.h> 7 #include <powerpc/oea/hid.h> 8 9 .text 10 .globl _start 11 _start: 12 /* 13 * Save possible argc and argv values from the firmware, usually 14 * passed in r3 and r4. 15 * When started with "bootm", as a Linux kernel module, r6 and r7 16 * point to the start and end address of the bootargs. 17 */ 18 mr 30,3 19 mr 31,4 20 mr 28,6 21 mr 29,7 22 23 /* Disable interrupts and everything except the MMU. */ 24 mfmsr 3 25 andi. 3,3,PSL_DR|PSL_IR 26 mtmsr 3 27 isync 28 29 /* 30 * U-Boot/PPCBoot forgets to flush the cache when using the "bootm" 31 * command, so we have to do that now. 32 */ 33 lis 11,_start@ha 34 addi 11,11,_start@l 35 li 10,-32 36 and 11,11,10 37 lis 12,(_edata+31)@ha 38 addi 12,12,(_edata+31)@l 39 bl syncicache 40 41 mfspr 11,SPR_HID0 42 andi. 0,11,HID0_DCE 43 ori 11,11,HID0_ICE 44 ori 8,11,HID0_ICFI 45 bne 1f /* don't invalidate the D-cache */ 46 ori 8,8,HID0_DCFI /* unless it wasn't enabled */ 47 1: 48 mfmsr 0 49 andi. 0,0,PSL_DR 50 beq 2f 51 lis 5,0xfec00000@ha /* CONFIG_ADDR of PCI */ 52 lis 6,0xfee00000@ha /* CONFIG_DATA of PCI */ 53 mfspr 3,SPR_DBAT0U 54 mfspr 4,SPR_DBAT0L 55 bl dbat_sanity_check 56 beq 3f 57 mfspr 3,SPR_DBAT1U 58 mfspr 4,SPR_DBAT1L 59 bl dbat_sanity_check 60 beq 3f 61 mfspr 3,SPR_DBAT2U 62 mfspr 4,SPR_DBAT2L 63 bl dbat_sanity_check 64 beq 3f 65 mfspr 3,SPR_DBAT3U 66 mfspr 4,SPR_DBAT3L 67 bl dbat_sanity_check 68 beq 3f 69 70 2: /* Disable D-cache */ 71 li 0,HID0_DCE 72 andc 11,11,0 73 b 4f 74 75 3: /* Enable D-cache */ 76 ori 11,11,HID0_DCE 77 78 4: 79 lis 1,BAT123@ha 80 addi 1,1,BAT123@l 81 lwz 3,0(1) 82 lwz 4,4(1) 83 mtdbatl 1,3 84 mtdbatu 1,4 85 lwz 3,8(1) 86 lwz 4,12(1) 87 mtdbatl 2,3 88 mtdbatu 2,4 89 lwz 3,16(1) 90 lwz 4,20(1) 91 mtdbatl 3,3 92 mtdbatu 3,4 93 94 sync 95 mtspr SPR_HID0,8 /* enable and invalidate caches */ 96 sync 97 mtspr SPR_HID0,11 /* enable caches */ 98 sync 99 isync 100 101 /* make sure .bss gets zeroed. */ 102 li 0,0 103 lis 8,edata@ha 104 addi 8,8,edata@l 105 lis 9,end@ha 106 addi 9,9,end@l 107 5: cmpw 0,8,9 /* edata & end are >= word aligned */ 108 bge 6f 109 stw 0,0(8) 110 addi 8,8,4 111 b 5b 112 113 6: 114 /* prepare stack at +1MB from _start, 16-byte aligned */ 115 lis 1,_start@ha 116 addi 1,1,_start@l 117 addis 1,1,0x100000@ha 118 li 10,-16 119 and 1,1,10 120 stw 0,0(1) 121 122 bl brdsetup 123 #ifdef DEBUG 124 bl init_vectors 125 #endif 126 mr 3,30 127 mr 4,31 128 mr 5,28 129 mr 6,29 130 bl main 131 132 hang: b hang 133 /* NOTREACHED */ 134 135 dbat_sanity_check: 136 andi. 0,3,BAT_Vs 137 beq 2f 138 andi. 0,4,BAT_I|BAT_PP_RW 139 cmpwi 0,0,BAT_I|BAT_PP_RW 140 bnelr 141 rlwinm 0,3,15,4,14 142 andis. 3,3,0xfffe0000@ha /* BAT_EPI */ 143 andis. 4,4,BAT_RPN@ha 144 cmplw 0,3,4 145 bnelr 146 add 4,4,0 147 oris 4,4,0x0001ffff@ha 148 ori 4,4,0x0001ffff@l 149 cmplw 0,3,5 150 bgt 1f 151 cmplw 0,5,4 152 bgt 1f 153 li 5,0 154 1: cmplw 0,3,6 155 bgt 2f 156 cmplw 0,6,4 157 bgt 2f 158 li 6,0 159 2: cmplw 0,5,6 160 blr 161 162 /* 163 * run(startsym, endsym, howto, bootinfo, entry) 164 */ 165 .globl run 166 run: 167 mtctr 7 /* hat trick jump to entry point */ 168 bctr 169 170 /* 171 * newaltboot(argc, argv, altboot_base, altboot_len) 172 * To be executed in a safe memory region. Copies the new altboot from 173 * altboot_base to 0x1000000 and starts it there. 174 */ 175 .globl newaltboot 176 newaltboot: 177 lis 7,0x1000000@h 178 mr 11,7 179 subi 7,7,4 180 subi 5,5,4 181 add 12,11,6 182 addi 6,6,3 183 srawi 6,6,2 184 mtctr 6 185 1: lwzu 8,4(5) 186 stwu 8,4(7) 187 bdnz+ 1b 188 mtctr 11 189 addi 12,12,31 190 bl syncicache 191 bctr 192 syncicache: 193 /* r11=start, r12=end, r10=scratch */ 194 mr 10,11 195 2: dcbst 0,10 196 addi 10,10,32 197 cmplw 10,12 198 ble 2b 199 sync 200 3: icbi 0,11 201 addi 11,11,32 202 cmplw 11,12 203 ble 3b 204 sync 205 isync 206 blr 207 .globl newaltboot_end 208 newaltboot_end: 209 210 211 /* 8-bit i/o access */ 212 .globl out8 213 out8: 214 stb 4,0(3) 215 eieio 216 blr 217 218 .globl in8 219 in8: 220 lbz 3,0(3) 221 eieio 222 blr 223 224 /* 225 * reverse endian access to mimic outw/outl/inw/inl 226 */ 227 .globl out16rb 228 .globl iohtole16 229 out16rb: 230 iohtole16: 231 sthbrx 4,0,3 232 eieio 233 blr 234 235 .globl out32rb 236 .globl iohtole32 237 out32rb: 238 iohtole32: 239 stwbrx 4,0,3 240 eieio 241 blr 242 243 .globl in16rb 244 .globl iole16toh 245 in16rb: 246 iole16toh: 247 lhbrx 3,0,3 248 eieio 249 blr 250 251 .globl in32rb 252 .globl iole32toh 253 in32rb: 254 iole32toh: 255 lwbrx 3,0,3 256 eieio 257 blr 258 259 #ifdef DEBUG 260 /* 261 * Call an exception handler, which prints out all information 262 * about the type of exception, cpu registers, stack frame 263 * backtrace, etc. 264 * Use a new stack at 0x2000 and make room for 32 GPRs, and 15 265 * special registers. The layout will be: 266 * 0x00: link area 267 * 0x10: R0 268 * ... 269 * 0x8c: R31 270 * 0x90: CR, XER, LR, CTR 271 * 0xa0: SRR0, SRR1, DAR, DSISR 272 * 0xb0: DMISS, DCMP, HASH1, HASH2 273 * 0xc0: IMISS, ICMP, RPA 274 * 275 */ 276 .globl trap 277 trap: 278 mtsprg1 1 279 mfmsr 1 280 andis. 1,1,PSL_TGPR@h 281 beq 1f 282 andi. 1,1,0xffff /* make sure TGPR is disabled */ 283 mtmsr 1 284 isync 285 mtsprg1 1 /* and save the real r1 again */ 286 1: li 1,0x2000-16-(32*4+15*4) 287 stmw 2,24(1) /* save r2..r31 */ 288 stw 0,16(1) /* save r0 */ 289 mfsprg1 3 290 stw 3,20(1) /* and finally r1 */ 291 mfcr 3 292 stw 3,0x90(1) 293 mfxer 3 294 stw 3,0x94(1) 295 mflr 3 296 stw 3,0x98(1) 297 mfctr 3 298 stw 3,0x9c(1) 299 mfsrr0 3 300 stw 3,0xa0(1) 301 mfsrr1 3 302 stw 3,0xa4(1) 303 mfdar 3 304 stw 3,0xa8(1) 305 mfdsisr 3 306 stw 3,0xac(1) 307 mfspr 3,976 308 stw 3,0xb0(1) 309 mfspr 3,977 310 stw 3,0xb4(1) 311 mfspr 3,978 312 stw 3,0xb8(1) 313 mfspr 3,979 314 stw 3,0xbc(1) 315 mfspr 3,980 316 stw 3,0xc0(1) 317 mfspr 3,981 318 stw 3,0xc4(1) 319 mfspr 3,982 320 stw 3,0xc8(1) 321 bl call_handler 322 call_handler: 323 lis 11,exception_handler@ha 324 addi 11,11,exception_handler@l 325 mtsrr0 11 326 li 0,PSL_DR|PSL_IR 327 mtsrr1 0 328 mflr 3 329 subi 3,3,call_handler-trap 330 addi 4,1,16 331 rfi 332 .globl trap_end 333 trap_end: 334 #endif 335 336 .data 337 #define xBATL(pa, wimg, pp) \ 338 ((pa) | (wimg) | (pp)) 339 #define xBATU(va, len, v) \ 340 ((va) | ((len) & BAT_BL) | ((v) & BAT_V)) 341 BAT123: 342 .long xBATL(0x80000000, BAT_I|BAT_G, BAT_PP_RW) 343 .long xBATU(0x80000000, BAT_BL_256M, BAT_Vs) 344 .long xBATL(0xfc000000, BAT_I|BAT_G, BAT_PP_RW) 345 .long xBATU(0xfc000000, BAT_BL_64M, BAT_Vs) 346 .long xBATL(0x70000000, BAT_I|BAT_G, BAT_PP_RW) 347 .long xBATU(0x70000000, BAT_BL_128K, BAT_Vs) 348