Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
| 2 | * __________ __ ___. |
| 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
| 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
| 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
| 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
| 7 | * \/ \/ \/ \/ \/ |
| 8 | * $Id$ |
| 9 | * |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 10 | * Copyright (C) 2008 by Karl Kurbjun |
| 11 | * |
| 12 | * Arm bootloader and startup code based on startup.s from the iPodLinux loader |
| 13 | * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org) |
| 14 | * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org> |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 15 | * |
Daniel Stenberg | 2acc0ac | 2008-06-28 18:10:04 +0000 | [diff] [blame^] | 16 | * This program is free software; you can redistribute it and/or |
| 17 | * modify it under the terms of the GNU General Public License |
| 18 | * as published by the Free Software Foundation; either version 2 |
| 19 | * of the License, or (at your option) any later version. |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 20 | * |
| 21 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
| 22 | * KIND, either express or implied. |
| 23 | * |
| 24 | ****************************************************************************/ |
| 25 | #include "config.h" |
| 26 | #include "cpu.h" |
| 27 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 28 | /* Exception Handlers */ |
| 29 | .section .vectors,"ax",%progbits |
| 30 | .code 32 |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 31 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 32 | .global vectors |
| 33 | vectors: |
| 34 | b start |
| 35 | b undef_instr_handler |
| 36 | b software_int_handler |
| 37 | b prefetch_abort_handler |
| 38 | b data_abort_handler |
| 39 | b reserved_handler |
| 40 | b irq_handler |
| 41 | b fiq_handler |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 42 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 43 | /* |
| 44 | * Function: code_copy |
| 45 | * Variables: |
| 46 | * r0 = from |
| 47 | * r1 = to |
| 48 | * r2 = length |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 49 | */ |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 50 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 51 | .section .init.text, "ax", %progbits |
| 52 | .align 0x04 |
| 53 | .global word_copy |
| 54 | .type word_copy, %function |
| 55 | word_copy: |
| 56 | sub r2, r2, #0x04 |
| 57 | cmp r2, #0 |
| 58 | ldrge r3, [r0], #4 |
| 59 | strge r3, [r1], #4 |
| 60 | bgt word_copy |
| 61 | bx lr |
| 62 | .ltorg |
| 63 | .size word_copy, .-word_copy |
| 64 | |
| 65 | /* |
| 66 | * Entry: start |
| 67 | * Variables: |
| 68 | * none |
| 69 | */ |
| 70 | |
| 71 | .section .init.text,"ax",%progbits |
| 72 | .code 32 |
| 73 | .align 0x04 /* Align */ |
| 74 | .global start |
| 75 | start: |
| 76 | msr cpsr, #0xd3 /* enter supervisor mode, disable IRQ */ |
| 77 | |
| 78 | /* Disable the watchdog */ |
| 79 | ldr r2, =0x00000000 |
| 80 | mov r1, #0x53000000 |
| 81 | str r2, [r1] |
| 82 | |
| 83 | /* Mask all Interupts to be safe */ |
| 84 | ldr r2, =0xFFFFFFFF |
| 85 | mov r1, #0x4A000000 |
| 86 | str r2, [r1] |
| 87 | |
| 88 | /* Submask too */ |
| 89 | ldr r2, =0x00003FFF |
| 90 | str r2, [r1, #0x1C] |
| 91 | |
| 92 | /* Check if loaded by the old bootloader or by the OF |
| 93 | * Be careful with code size above this as well. |
| 94 | */ |
| 95 | |
| 96 | /* Get the execute address (cannot be past 0x100 for this to work */ |
| 97 | ldr r0, =0xffffff00 |
| 98 | and r0, pc, r0 |
| 99 | |
| 100 | /* Calculate the length of the code needed to run/copy */ |
| 101 | ldr r1, = _vectorstart |
Michael Sevakis | 209aa8e | 2008-05-10 22:03:45 +0000 | [diff] [blame] | 102 | ldr r2, = _initdata_end |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 103 | sub r2, r2, r1 |
| 104 | |
| 105 | add r3, r2, #0x30000000 |
| 106 | |
| 107 | /* Is there enough space to copy without overwriting? */ |
| 108 | cmp r0, r3 |
| 109 | |
| 110 | /* There's enough space, skip copying */ |
| 111 | bgt skipreset |
| 112 | |
| 113 | /* Is this code running from 0x0? If so skip copy. */ |
| 114 | cmplt r0, #0 |
| 115 | beq skipreset |
| 116 | |
| 117 | /* There's not enough space to copy without overwriting, copy to safe spot |
| 118 | * and reset |
| 119 | */ |
| 120 | mov r1, #0x31000000 /* copy location */ |
| 121 | bl word_copy |
| 122 | |
| 123 | mov pc, #0x31000000 |
| 124 | |
| 125 | skipreset: |
| 126 | |
| 127 | /* Initial Clock Setup */ |
| 128 | mov r2, #0x7 |
| 129 | mov r1, #0x4C000000 |
| 130 | str r2, [r1, #0x14] |
| 131 | |
| 132 | mov r2, #0x0 |
| 133 | str r2, [r1, #0x18] |
| 134 | |
| 135 | ldr r2, =0xFFFFFFFF |
| 136 | str r2, [r1] |
| 137 | |
| 138 | ldr r2, =0x0003C042 |
| 139 | str r2, [r1, #0x08] |
| 140 | |
| 141 | nop |
| 142 | nop |
| 143 | nop |
| 144 | nop |
| 145 | nop |
| 146 | nop |
| 147 | nop |
| 148 | nop |
| 149 | |
| 150 | ldr r2, =0x000C9042 |
| 151 | str r2, [r1, #0x04] |
| 152 | |
| 153 | nop |
| 154 | nop |
| 155 | nop |
| 156 | nop |
| 157 | nop |
| 158 | nop |
| 159 | nop |
| 160 | nop |
| 161 | |
| 162 | /* If we want to disable extraneous clocks, uncomment, but it can |
| 163 | * freeze the device |
| 164 | */ |
| 165 | #if 0 |
| 166 | ldr r2, =0x6030 |
| 167 | mov r1, #0x4C000000 |
| 168 | str r2, [r1, #0x0C] |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 169 | #endif |
| 170 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 171 | /* set Bus to Asynchronous mode (full speed) */ |
| 172 | mov r0, #0 |
| 173 | mrc p15, 0, r0, c1, c0, 0 |
| 174 | ldr r1, =0xC0000000 |
| 175 | orr r0, r0, r1 |
| 176 | mcr p15, 0, r0, c1, c0, 0 |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 177 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 178 | /* Setup MISCCR */ |
| 179 | ldr r2, =0x00613020 |
| 180 | mov r1, #0x56000000 |
| 181 | str r2, [r1, #0x80] |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 182 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 183 | /* Setup some unknown outputs in GPB and GPH */ |
| 184 | ldr r2, [r1, #0x10] |
| 185 | mov r3, #0x05 |
| 186 | orr r2, r3, r2 |
| 187 | str r2, [r1, #0x10] |
| 188 | |
| 189 | ldr r2, [r1, #0x14] |
| 190 | mov r3, #0x03 |
| 191 | orr r2, r3, r2 |
| 192 | str r2, [r1, #0x14] |
| 193 | |
| 194 | ldr r2, [r1, #0x70] |
| 195 | mov r3, #0x05 |
| 196 | orr r2, r3, r2 |
| 197 | str r2, [r1, #0x70] |
| 198 | |
| 199 | ldr r2, [r1, #0x74] |
| 200 | mov r3, #0x03 |
| 201 | orr r2, r3, r2 |
| 202 | str r2, [r1, #0x74] |
| 203 | |
| 204 | /* Memory setup (taken from 0x5070) */ |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 205 | |
| 206 | /* BWSCON |
| 207 | * Reserved 0 |
| 208 | * Bank 0: |
| 209 | * Bus width 01 (16 bit) |
| 210 | * Bank 1: |
| 211 | * Buswidth 00 (8 bit) |
| 212 | * Disable wait 0 |
| 213 | * Not using UB/LB 0 |
| 214 | * Bank 2: |
| 215 | * Buswidth 10 (32 bit) |
| 216 | * Disable wait 0 |
| 217 | * Not using UB/LB 0 |
| 218 | * Bank 3: |
| 219 | * Buswidth 10 (32 bit) |
| 220 | * Disable wait 0 |
| 221 | * Use UB/LB 1 |
| 222 | * Bank 4: |
| 223 | * Buswidth 10 (32 bit) |
| 224 | * Disable wait 0 |
| 225 | * Use UB/LB 1 |
| 226 | * Bank 5: |
| 227 | * Buswidth 00 (8 bit) |
| 228 | * Disable wait 0 |
| 229 | * Not using UB/LB 0 |
| 230 | * Bank 6: |
| 231 | * Buswidth 10 (32 bit) |
| 232 | * Disable wait 0 |
| 233 | * Not using UB/LB 0 |
| 234 | * Bank 7: |
| 235 | * Buswidth 00 (8 bit) |
| 236 | * Disable wait 0 |
| 237 | * Not using UB/LB 0 |
| 238 | */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 239 | ldr r2, =0x01055102 |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 240 | mov r1, #0x48000000 |
| 241 | str r2, [r1] |
| 242 | |
| 243 | /* BANKCON0 |
| 244 | * Pagemode: normal (1 data) 00 |
| 245 | * Pagemode access cycle: 2 clocks 00 |
| 246 | * Address hold: 2 clocks 10 |
| 247 | * Chip selection hold time: 1 clock 10 |
| 248 | * Access cycle: 8 clocks 101 |
| 249 | * Chip select setup time: 1 clock 01 |
| 250 | * Address setup time: 0 clock 00 |
| 251 | */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 252 | ldr r2, =0x00000D60 |
| 253 | str r2, [r1, #0x04] |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 254 | |
| 255 | |
| 256 | /* BANKCON1 |
| 257 | * Pagemode: normal (1 data) 00 |
| 258 | * Pagemode access cycle: 2 clocks 00 |
| 259 | * Address hold: 0 clocks 00 |
| 260 | * Chip selection hold time: 0 clock 00 |
| 261 | * Access cycle: 1 clocks 000 |
| 262 | * Chip select setup time: 0 clocks 00 |
| 263 | * Address setup time: 0 clocks 00 |
| 264 | */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 265 | ldr r2, =0x00000000 |
| 266 | str r2, [r1, #0x08] |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 267 | |
| 268 | /* BANKCON2 |
| 269 | * Pagemode: normal (1 data) 00 |
| 270 | * Pagemode access cycle: 2 clocks 00 |
| 271 | * Address hold: 2 clocks 10 |
| 272 | * Chip selection hold time: 2 clocks 10 |
| 273 | * Access cycle: 14 clocks 111 |
| 274 | * Chip select setup time: 4 clocks 11 |
| 275 | * Address setup time: 0 clocks 00 |
| 276 | */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 277 | ldr r2, =0x00001FA0 |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 278 | str r2, [r1, #0xC] |
| 279 | |
| 280 | /* BANKCON3 */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 281 | ldr r2, =0x00001D80 |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 282 | str r2, [r1, #0x10] |
| 283 | /* BANKCON4 */ |
| 284 | str r2, [r1, #0x14] |
| 285 | |
| 286 | /* BANKCON5 */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 287 | ldr r2, =0x00000000 |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 288 | str r2, [r1, #0x18] |
| 289 | |
| 290 | /* BANKCON6/7 |
| 291 | * SCAN: 9 bit 01 |
| 292 | * Trcd: 3 clocks 01 |
| 293 | * Tcah: 0 clock 00 |
| 294 | * Tcoh: 0 clock 00 |
| 295 | * Tacc: 1 clock 000 |
| 296 | * Tcos: 0 clock 00 |
| 297 | * Tacs: 0 clock 00 |
| 298 | * MT: Sync DRAM 11 |
| 299 | */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 300 | ldr r2, =0x00018005 |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 301 | str r2, [r1, #0x1C] |
| 302 | /* BANKCON7 */ |
| 303 | str r2, [r1, #0x20] |
| 304 | |
| 305 | /* REFRESH */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 306 | ldr r2, =0x00980501 |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 307 | str r2, [r1, #0x24] |
| 308 | |
| 309 | /* BANKSIZE |
| 310 | * BK76MAP: 32M/32M 000 |
| 311 | * Reserved: 0 0 (was 1) |
| 312 | * SCLK_EN: always 1 (was 0) |
| 313 | * SCKE_EN: disable 0 |
| 314 | * Reserved: 0 0 |
| 315 | * BURST_EN: enabled 1 |
| 316 | */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 317 | ldr r2, =0x00000090 |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 318 | str r2, [r1, #0x28] |
| 319 | |
| 320 | /* MRSRB6 */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 321 | ldr r2, =0x00000030 |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 322 | str r2, [r1, #0x2C] |
| 323 | /* MRSRB7 */ |
| 324 | str r2, [r1, #0x30] |
| 325 | |
| 326 | #if 0 |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 327 | /* GPACON */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 328 | mov r1, #0x56000000 |
| 329 | ldr r2, =0x01FFFCFF /* 0x01FFFCFF */ |
| 330 | str r2, [r1] |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 331 | |
| 332 | /* GPADAT */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 333 | ldr r2, =0x01FFFEFF |
| 334 | str r2, [r1, #0x04] |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 335 | |
| 336 | /* MRSRB6 */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 337 | mov r1, #0x48000000 |
| 338 | mov r2, #0x00000000 |
| 339 | str r2, [r1, #0x2C] |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 340 | |
| 341 | /* GPADAT */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 342 | mov r1, #0x56000000 |
| 343 | ldr r2, =0x01FFFFFF |
| 344 | str r2, [r1, #0x04] |
| 345 | |
| 346 | /* MRSRB6 */ |
| 347 | mov r1, #0x48000000 |
| 348 | mov r2, #0x00000030 |
| 349 | str r2, [r1, #0x2C] |
| 350 | |
| 351 | /* GPACON */ |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 352 | mov r1, #0x56000000 |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 353 | mov r2, #0x01FFFFFF |
| 354 | str r2, [r1] |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 355 | |
| 356 | /* End of the unknown */ |
| 357 | #endif |
| 358 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 359 | /* The builds have two potential load addresses, one being from flash, |
| 360 | * and the other from some "unknown" location right now the assumption |
| 361 | * is that the code is not at 0x3000000. |
| 362 | */ |
| 363 | /* get the high part of our execute address (where am I) */ |
| 364 | ldr r0, =0xfffff000 |
| 365 | and r0, pc, r0 |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 366 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 367 | /* Copy code to 0x30000000 */ |
| 368 | ldr r2, = _vectorstart |
Michael Sevakis | 209aa8e | 2008-05-10 22:03:45 +0000 | [diff] [blame] | 369 | ldr r3, = _initdata_end |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 370 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 371 | sub r2, r3, r2 /* length of loader */ |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 372 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 373 | ldr r1, =0x30000000 /* copy location */ |
| 374 | |
| 375 | bl word_copy |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 376 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 377 | ldr r1, =donecopy |
| 378 | ldr r2, =0x30000000 |
| 379 | add r1, r1, r2 |
| 380 | mov pc, r1 /* The code is located where we want it-jump*/ |
| 381 | |
| 382 | donecopy: |
| 383 | |
| 384 | /* Setup the MMU, start by disabling */ |
| 385 | |
| 386 | mrc p15, 0, r0, c1, c0, 0 |
| 387 | bic r0, r0, #0x41 /* disable mmu and dcache */ |
| 388 | bic r0, r0, #0x1000 /* disable icache */ |
| 389 | mcr p15, 0, r0, c1, c0, 0 |
| 390 | |
| 391 | bl ttb_init |
| 392 | |
| 393 | ldr r0, =0x0 |
| 394 | ldr r1, =0x0 |
| 395 | ldr r2, =0x1000 |
| 396 | mov r3, #0 |
| 397 | bl map_section |
| 398 | |
| 399 | ldr r0, =0x30000000 |
| 400 | ldr r1, =0x0 |
| 401 | mov r2, #32 |
| 402 | mov r3, #12 |
| 403 | bl map_section |
| 404 | |
| 405 | ldr r0, =0x31FD6800 /* FRAME */ |
| 406 | mov r1, r0 |
| 407 | mov r2, #1 |
| 408 | mov r3, #4 |
| 409 | bl map_section |
| 410 | |
| 411 | bl enable_mmu |
| 412 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 413 | /* Initialise bss section to zero */ |
| 414 | ldr r2, =_edata |
| 415 | ldr r3, =_end |
| 416 | mov r4, #0 |
| 417 | bsszero: |
| 418 | cmp r3, r2 |
| 419 | strhi r4, [r2], #4 |
| 420 | bhi bsszero |
| 421 | |
| 422 | /* Set up some stack and munge it with 0xdeadbeef */ |
| 423 | ldr sp, =stackend |
| 424 | mov r3, sp |
| 425 | ldr r2, =stackbegin |
| 426 | ldr r4, =0xdeadbeef |
| 427 | stackmunge: |
| 428 | cmp r3, r2 |
| 429 | strhi r4, [r2], #4 |
| 430 | bhi stackmunge |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 431 | |
| 432 | /* Set up stack for IRQ mode */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 433 | msr cpsr_c, #0xd2 |
| 434 | ldr sp, =irq_stack |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 435 | /* Set up stack for FIQ mode */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 436 | msr cpsr_c, #0xd1 |
| 437 | ldr sp, =fiq_stack |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 438 | |
| 439 | /* Let abort and undefined modes use IRQ stack */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 440 | msr cpsr_c, #0xd7 |
| 441 | ldr sp, =irq_stack |
| 442 | msr cpsr_c, #0xdb |
| 443 | ldr sp, =irq_stack |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 444 | /* Switch to supervisor mode */ |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 445 | msr cpsr_c, #0xd3 |
| 446 | ldr sp, =stackend |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 447 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 448 | /* Start the main function */ |
| 449 | ldr pc, =main |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 450 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 451 | /* Should never get here, but let's restart in case */ |
| 452 | // b vectors |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 453 | |
| 454 | /* All illegal exceptions call into UIE with exception address as first |
| 455 | parameter. This is calculated differently depending on which exception |
| 456 | we're in. Second parameter is exception number, used for a string lookup |
| 457 | in UIE. |
| 458 | */ |
| 459 | undef_instr_handler: |
| 460 | mov r0, lr |
| 461 | mov r1, #0 |
| 462 | b UIE |
| 463 | |
| 464 | /* We run supervisor mode most of the time, and should never see a software |
| 465 | exception being thrown. Perhaps make it illegal and call UIE? |
| 466 | */ |
| 467 | software_int_handler: |
| 468 | reserved_handler: |
| 469 | movs pc, lr |
| 470 | |
| 471 | prefetch_abort_handler: |
| 472 | sub r0, lr, #4 |
| 473 | mov r1, #1 |
| 474 | b UIE |
| 475 | |
| 476 | data_abort_handler: |
| 477 | sub r0, lr, #8 |
| 478 | mov r1, #2 |
| 479 | b UIE |
| 480 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 481 | #if defined(BOOTLOADER) |
| 482 | fiq_handler: |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 483 | b UIE |
| 484 | #endif |
| 485 | |
Karl Kurbjun | 7510335 | 2008-04-22 04:34:25 +0000 | [diff] [blame] | 486 | UIE: |
| 487 | b UIE |
| 488 | |
| 489 | .section .text |
Karl Kurbjun | 31ea780 | 2007-11-11 17:58:13 +0000 | [diff] [blame] | 490 | /* 256 words of IRQ stack */ |
| 491 | .space 256*4 |
| 492 | irq_stack: |
| 493 | |
| 494 | /* 256 words of FIQ stack */ |
| 495 | .space 256*4 |
| 496 | fiq_stack: |
| 497 | |