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