Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 1 | /*************************************************************************** |
| 2 | * __________ __ ___. |
| 3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ |
| 4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / |
| 5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < |
| 6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ |
| 7 | * \/ \/ \/ \/ \/ |
| 8 | * $Id$ |
| 9 | * |
| 10 | * Copyright (C) 2002 by Linus Nielsen Feltzing |
| 11 | * |
Daniel Stenberg | 2acc0ac | 2008-06-28 18:10:04 +0000 | [diff] [blame^] | 12 | * This program is free software; you can redistribute it and/or |
| 13 | * modify it under the terms of the GNU General Public License |
| 14 | * as published by the Free Software Foundation; either version 2 |
| 15 | * of the License, or (at your option) any later version. |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 16 | * |
| 17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY |
| 18 | * KIND, either express or implied. |
| 19 | * |
| 20 | ****************************************************************************/ |
| 21 | #include "config.h" |
| 22 | #include "cpu.h" |
| 23 | |
| 24 | .section .init.text,"ax",%progbits |
| 25 | |
| 26 | .global start |
| 27 | start: |
| 28 | |
| 29 | /* PortalPlayer bootloader and startup code based on startup.s from the iPodLinux |
| 30 | * loader |
| 31 | * |
| 32 | * Copyright (c) 2003, Daniel Palffy (dpalffy (at) rainstorm.org) |
| 33 | * Copyright (c) 2005, Bernard Leach <leachbj@bouncycastle.org> |
| 34 | * |
| 35 | */ |
| 36 | #if CONFIG_CPU == PP5002 |
Michael Sevakis | a8b388f | 2007-11-27 01:20:26 +0000 | [diff] [blame] | 37 | .equ PROC_ID, 0xc4000000 |
| 38 | .equ CPU_ICLR, 0xcf001028 |
| 39 | .equ CPU_CTRL, 0xcf004054 |
| 40 | .equ COP_ICLR, 0xcf001038 |
| 41 | .equ COP_CTRL, 0xcf004058 |
| 42 | .equ CPU_STATUS, 0xcf004050 |
| 43 | .equ COP_STATUS, 0xcf004050 |
| 44 | .equ IIS_CONFIG, 0xc0002500 |
| 45 | .equ SLEEP, 0x000000ca |
| 46 | .equ WAKE, 0x000000ce |
| 47 | .equ CPUSLEEPING, 0x00008000 |
| 48 | .equ COPSLEEPING, 0x00004000 |
| 49 | .equ CACHE_CTRL, 0xcf004024 |
| 50 | .equ MMAP_LOG, 0xf000f000 /* MMAP0 */ |
| 51 | .equ MMAP_PHYS, 0xf000f004 |
Michael Sevakis | 940e899 | 2007-10-04 04:53:01 +0000 | [diff] [blame] | 52 | #if MEM > 32 |
Michael Sevakis | a8b388f | 2007-11-27 01:20:26 +0000 | [diff] [blame] | 53 | .equ MMAP_MASK, 0x00003c00 |
Michael Sevakis | 940e899 | 2007-10-04 04:53:01 +0000 | [diff] [blame] | 54 | #else |
Michael Sevakis | a8b388f | 2007-11-27 01:20:26 +0000 | [diff] [blame] | 55 | .equ MMAP_MASK, 0x00003e00 |
Michael Sevakis | 940e899 | 2007-10-04 04:53:01 +0000 | [diff] [blame] | 56 | #endif |
Michael Sevakis | a8b388f | 2007-11-27 01:20:26 +0000 | [diff] [blame] | 57 | .equ MMAP_FLAGS, 0x00003f84 |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 58 | #else |
Michael Sevakis | a8b388f | 2007-11-27 01:20:26 +0000 | [diff] [blame] | 59 | .equ PROC_ID, 0x60000000 |
| 60 | .equ CPU_ICLR, 0x60004028 |
| 61 | .equ CPU_CTRL, 0x60007000 |
| 62 | .equ CPU_STATUS, 0x60007000 |
| 63 | .equ COP_ICLR, 0x60004038 |
| 64 | .equ COP_CTRL, 0x60007004 |
| 65 | .equ COP_STATUS, 0x60007004 |
| 66 | .equ IIS_CONFIG, 0x70002800 |
| 67 | .equ SLEEP, 0x80000000 |
| 68 | .equ WAKE, 0x00000000 |
| 69 | .equ CPUSLEEPING, 0x80000000 |
| 70 | .equ COPSLEEPING, 0x80000000 |
| 71 | .equ CACHE_CTRL, 0x6000c000 |
| 72 | .equ MMAP_LOG, 0xf000f000 /* MMAP0 */ |
| 73 | .equ MMAP_PHYS, 0xf000f004 |
Michael Sevakis | 940e899 | 2007-10-04 04:53:01 +0000 | [diff] [blame] | 74 | #if MEM > 32 |
Michael Sevakis | a8b388f | 2007-11-27 01:20:26 +0000 | [diff] [blame] | 75 | .equ MMAP_MASK, 0x00003c00 |
Michael Sevakis | 940e899 | 2007-10-04 04:53:01 +0000 | [diff] [blame] | 76 | #else |
Michael Sevakis | a8b388f | 2007-11-27 01:20:26 +0000 | [diff] [blame] | 77 | .equ MMAP_MASK, 0x00003e00 |
Michael Sevakis | 940e899 | 2007-10-04 04:53:01 +0000 | [diff] [blame] | 78 | #endif |
Michael Sevakis | a8b388f | 2007-11-27 01:20:26 +0000 | [diff] [blame] | 79 | .equ MMAP_FLAGS, 0x00000f84 |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 80 | #endif |
| 81 | |
Michael Sevakis | e1c52e7 | 2007-08-01 20:26:04 +0000 | [diff] [blame] | 82 | msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 83 | b pad_skip |
Daniel Ankers | 43e2c01 | 2006-11-22 00:49:16 +0000 | [diff] [blame] | 84 | |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 85 | .space 64*4 /* (more than enough) space for exception vectors and mi4 magic */ |
Daniel Ankers | 43e2c01 | 2006-11-22 00:49:16 +0000 | [diff] [blame] | 86 | |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 87 | pad_skip: |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 88 | /* Find out which processor we are - r0 should be preserved for the |
| 89 | * duration of the init to avoid constant reloading of the processor ID. |
| 90 | * For each stage, CPU proceeds first, then COP. |
| 91 | */ |
| 92 | ldr r0, =PROC_ID |
| 93 | ldrb r0, [r0] |
| 94 | |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 95 | /* We need to remap memory from wherever SDRAM is mapped natively, to |
| 96 | base address 0, so we can put our exception vectors there. We don't |
| 97 | want to do this remapping while executing from SDRAM, so we copy the |
| 98 | remapping code to IRAM, then execute from there. Hence, the following |
| 99 | code is compiled for address 0, but is currently executing at either |
| 100 | 0x28000000 or 0x10000000, depending on chipset version. Do not use any |
| 101 | absolute addresses until remapping has been done. */ |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 102 | |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 103 | /* Cores are stepped though the init in turn: CPU then COP. The the remap |
| 104 | stage is completed by each core in turn and then the COP waits for the |
| 105 | CPU to finish initializing its kernel where the CPU will wake the COP |
| 106 | and wait for the COP to finish. This ensures no threading activity |
| 107 | starts until it is safe. */ |
| 108 | cmp r0, #0x55 |
| 109 | |
| 110 | /* mask all interrupt sources before setting anything up */ |
| 111 | ldreq r2, =CPU_ICLR |
| 112 | ldrne r2, =COP_ICLR |
| 113 | mvn r1, #0 |
| 114 | str r1, [r2] |
| 115 | |
| 116 | /* put us (co-processor) to sleep and wait for CPU to remap */ |
| 117 | ldrne r2, =COP_CTRL |
| 118 | movne r1, #SLEEP |
| 119 | strne r1, [r2] |
Michael Sevakis | a8b388f | 2007-11-27 01:20:26 +0000 | [diff] [blame] | 120 | nop |
| 121 | nop |
| 122 | nop |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 123 | |
| 124 | /* wait for co-processor to sleep then CPU can begin its remapping */ |
| 125 | ldreq r2, =COP_STATUS |
| 126 | 1: |
| 127 | ldreq r1, [r2] |
Michael Sevakis | a8b388f | 2007-11-27 01:20:26 +0000 | [diff] [blame] | 128 | tsteq r1, #COPSLEEPING |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 129 | beq 1b |
| 130 | |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 131 | /* disable cache and local interrupt vectors - it is really not desireable |
| 132 | to have them enabled here */ |
| 133 | ldr r2, =CACHE_CTRL |
| 134 | mov r1, #0 |
| 135 | str r1, [r2] |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 136 | |
| 137 | mov r2, #0x40000000 |
| 138 | ldr r3, =remap_start |
| 139 | ldr r4, =remap_end |
| 140 | |
| 141 | and r6, pc, #0xff000000 /* adjust for execute address */ |
| 142 | orr r3, r3, r6 |
| 143 | orr r4, r4, r6 |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 144 | |
| 145 | /* copy the code to 0x40000000 */ |
| 146 | 1: |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 147 | ldr r5, [r3], #4 |
| 148 | str r5, [r2], #4 |
| 149 | cmp r3, r4 |
| 150 | blo 1b |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 151 | |
Michael Sevakis | 940e899 | 2007-10-04 04:53:01 +0000 | [diff] [blame] | 152 | ldr r4, =MMAP_FLAGS |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 153 | orr r4, r4, r6 /* adjust for execute address */ |
Michael Sevakis | 940e899 | 2007-10-04 04:53:01 +0000 | [diff] [blame] | 154 | ldr r3, =MMAP_PHYS |
| 155 | ldr r2, =MMAP_MASK /* ldr is more flexible */ |
| 156 | ldr r1, =MMAP_LOG |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 157 | mov pc, #0x40000000 |
| 158 | |
| 159 | remap_start: |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 160 | str r2, [r1] |
| 161 | str r4, [r3] |
| 162 | ldr r1, L_post_remap |
| 163 | mov pc, r1 |
| 164 | L_post_remap: |
| 165 | .word remap_end |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 166 | remap_end: |
| 167 | |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 168 | cmp r0, #0x55 |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 169 | ldr r4, =COP_CTRL |
| 170 | /* Wakeup co-processor to let it do remappings */ |
| 171 | moveq r3, #WAKE |
| 172 | /* Sleep us (co-processor) and wait for CPU to do kernel initialization */ |
Michael Sevakis | e1c52e7 | 2007-08-01 20:26:04 +0000 | [diff] [blame] | 173 | movne r3, #SLEEP |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 174 | str r3, [r4] |
Michael Sevakis | a8b388f | 2007-11-27 01:20:26 +0000 | [diff] [blame] | 175 | nop |
| 176 | nop |
| 177 | nop |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 178 | |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 179 | /* Jump to co-processor init */ |
Michael Sevakis | e1c52e7 | 2007-08-01 20:26:04 +0000 | [diff] [blame] | 180 | ldrne pc, =cop_init |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 181 | |
Barry Wardell | 2f16d4f | 2006-12-19 11:33:53 +0000 | [diff] [blame] | 182 | cpu_init: |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 183 | /* Wait for COP to go to sleep before proceeding */ |
Barry Wardell | 2f16d4f | 2006-12-19 11:33:53 +0000 | [diff] [blame] | 184 | ldr r4, =COP_STATUS |
| 185 | 1: |
| 186 | ldr r3, [r4] |
Michael Sevakis | a8b388f | 2007-11-27 01:20:26 +0000 | [diff] [blame] | 187 | tst r3, #COPSLEEPING |
Barry Wardell | 2f16d4f | 2006-12-19 11:33:53 +0000 | [diff] [blame] | 188 | beq 1b |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 189 | |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 190 | /* Copy exception handler code to address 0 */ |
| 191 | ldr r2, =_vectorsstart |
| 192 | ldr r3, =_vectorsend |
| 193 | ldr r4, =_vectorscopy |
| 194 | 1: |
| 195 | cmp r3, r2 |
| 196 | ldrhi r5, [r4], #4 |
| 197 | strhi r5, [r2], #4 |
| 198 | bhi 1b |
Daniel Ankers | 43e2c01 | 2006-11-22 00:49:16 +0000 | [diff] [blame] | 199 | |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 200 | /* Zero out IBSS */ |
| 201 | ldr r2, =_iedata |
| 202 | ldr r3, =_iend |
| 203 | mov r4, #0 |
| 204 | 1: |
| 205 | cmp r3, r2 |
| 206 | strhi r4, [r2], #4 |
| 207 | bhi 1b |
| 208 | |
| 209 | /* Copy the IRAM */ |
| 210 | ldr r2, =_iramcopy |
| 211 | ldr r3, =_iramstart |
| 212 | ldr r4, =_iramend |
| 213 | 1: |
| 214 | cmp r4, r3 |
| 215 | ldrhi r5, [r2], #4 |
| 216 | strhi r5, [r3], #4 |
| 217 | bhi 1b |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 218 | |
| 219 | /* Initialise bss section to zero */ |
| 220 | ldr r2, =_edata |
| 221 | ldr r3, =_end |
| 222 | mov r4, #0 |
| 223 | 1: |
| 224 | cmp r3, r2 |
| 225 | strhi r4, [r2], #4 |
| 226 | bhi 1b |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 227 | |
| 228 | /* Load stack munge value */ |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 229 | ldr r4, =0xdeadbeef |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 230 | |
| 231 | /* Set up some stack and munge it with 0xdeadbeef */ |
| 232 | ldr r2, =stackbegin |
| 233 | ldr sp, =stackend |
| 234 | 1: |
| 235 | cmp sp, r2 |
| 236 | strhi r4, [r2], #4 |
| 237 | bhi 1b |
| 238 | |
| 239 | #if NUM_CORES > 1 |
| 240 | /* Set up idle stack and munge it with 0xdeadbeef */ |
| 241 | ldr r2, =cpu_idlestackbegin |
| 242 | ldr r3, =cpu_idlestackend |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 243 | 1: |
| 244 | cmp r3, r2 |
| 245 | strhi r4, [r2], #4 |
| 246 | bhi 1b |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 247 | #endif |
| 248 | |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 249 | /* Set up stack for IRQ mode */ |
Michael Sevakis | e1c52e7 | 2007-08-01 20:26:04 +0000 | [diff] [blame] | 250 | msr cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */ |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 251 | ldr sp, =irq_stack |
| 252 | /* Set up stack for FIQ mode */ |
Michael Sevakis | e1c52e7 | 2007-08-01 20:26:04 +0000 | [diff] [blame] | 253 | msr cpsr_c, #0xd1 /* IRQ/FIQ disabled */ |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 254 | ldr sp, =fiq_stack |
| 255 | /* We'll load the banked FIQ mode registers with useful values here. |
Michael Sevakis | 6077e5b | 2007-10-06 22:27:27 +0000 | [diff] [blame] | 256 | These values will be used in the FIQ handler in pcm-pp.c */ |
| 257 | ldr r10, =IIS_CONFIG |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 258 | |
Michael Sevakis | 6077e5b | 2007-10-06 22:27:27 +0000 | [diff] [blame] | 259 | ldr r11, =dma_play_data |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 260 | |
| 261 | /* Let abort and undefined modes use IRQ stack */ |
Michael Sevakis | e1c52e7 | 2007-08-01 20:26:04 +0000 | [diff] [blame] | 262 | msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */ |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 263 | ldr sp, =irq_stack |
Michael Sevakis | e1c52e7 | 2007-08-01 20:26:04 +0000 | [diff] [blame] | 264 | msr cpsr_c, #0xdb /* IRQ/FIQ disabled */ |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 265 | ldr sp, =irq_stack |
Michael Sevakis | 4aaded5 | 2007-08-01 20:59:27 +0000 | [diff] [blame] | 266 | |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 267 | /* Switch back to supervisor mode */ |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 268 | msr cpsr_c, #0xd3 |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 269 | |
| 270 | /* Delay waking the COP until thread initialization is complete unless dual-core |
| 271 | support is not enabled in which case the cop_main function does not perform |
| 272 | any kernel or thread initialization. It's just a trivial sleep loop. */ |
| 273 | #if NUM_CORES == 1 |
| 274 | ldr r4, =COP_CTRL |
| 275 | mov r3, #WAKE |
| 276 | str r3, [r4] |
| 277 | #endif |
| 278 | |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 279 | bl main |
| 280 | /* main() should never return */ |
| 281 | |
| 282 | cop_init: |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 283 | #if NUM_CORES > 1 |
| 284 | /* Wait for CPU to go to sleep at the end of its kernel init */ |
| 285 | ldr r4, =CPU_STATUS |
Barry Wardell | 2f16d4f | 2006-12-19 11:33:53 +0000 | [diff] [blame] | 286 | 1: |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 287 | ldr r3, [r4] |
Michael Sevakis | a8b388f | 2007-11-27 01:20:26 +0000 | [diff] [blame] | 288 | tst r3, #CPUSLEEPING |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 289 | beq 1b |
Michael Sevakis | da55251 | 2007-09-29 06:17:33 +0000 | [diff] [blame] | 290 | #endif |
Barry Wardell | 2f16d4f | 2006-12-19 11:33:53 +0000 | [diff] [blame] | 291 | |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 292 | /* Set up idle stack for COP and munge it with 0xdeadbeef */ |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 293 | ldr sp, =cop_idlestackend |
Michael Sevakis | da55251 | 2007-09-29 06:17:33 +0000 | [diff] [blame] | 294 | ldr r2, =cop_idlestackbegin |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 295 | ldr r4, =0xdeadbeef |
| 296 | 2: |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 297 | cmp sp, r2 |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 298 | strhi r4, [r2], #4 |
| 299 | bhi 2b |
| 300 | |
Daniel Ankers | 82f9056 | 2007-03-04 20:06:41 +0000 | [diff] [blame] | 301 | /* Set up stack for IRQ mode */ |
Michael Sevakis | e1c52e7 | 2007-08-01 20:26:04 +0000 | [diff] [blame] | 302 | msr cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */ |
Daniel Ankers | 82f9056 | 2007-03-04 20:06:41 +0000 | [diff] [blame] | 303 | ldr sp, =cop_irq_stack |
| 304 | /* Set up stack for FIQ mode */ |
Michael Sevakis | e1c52e7 | 2007-08-01 20:26:04 +0000 | [diff] [blame] | 305 | msr cpsr_c, #0xd1 /* IRQ/FIQ disabled */ |
| 306 | ldr sp, =cop_fiq_stack |
Daniel Ankers | 82f9056 | 2007-03-04 20:06:41 +0000 | [diff] [blame] | 307 | |
| 308 | /* Let abort and undefined modes use IRQ stack */ |
Michael Sevakis | e1c52e7 | 2007-08-01 20:26:04 +0000 | [diff] [blame] | 309 | msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */ |
Daniel Ankers | 82f9056 | 2007-03-04 20:06:41 +0000 | [diff] [blame] | 310 | ldr sp, =cop_irq_stack |
Michael Sevakis | e1c52e7 | 2007-08-01 20:26:04 +0000 | [diff] [blame] | 311 | msr cpsr_c, #0xdb /* IRQ/FIQ disabled */ |
Daniel Ankers | 82f9056 | 2007-03-04 20:06:41 +0000 | [diff] [blame] | 312 | ldr sp, =cop_irq_stack |
| 313 | |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 314 | /* Switch back to supervisor mode */ |
Michael Sevakis | 4aaded5 | 2007-08-01 20:59:27 +0000 | [diff] [blame] | 315 | msr cpsr_c, #0xd3 |
Barry Wardell | 2f16d4f | 2006-12-19 11:33:53 +0000 | [diff] [blame] | 316 | |
| 317 | /* Run cop_main() in apps/main.c */ |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 318 | bl cop_main |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 319 | |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 320 | /* Exception handlers. Will be copied to address 0 after memory remapping */ |
| 321 | .section .vectors,"aw" |
| 322 | ldr pc, [pc, #24] |
| 323 | ldr pc, [pc, #24] |
| 324 | ldr pc, [pc, #24] |
| 325 | ldr pc, [pc, #24] |
| 326 | ldr pc, [pc, #24] |
| 327 | ldr pc, [pc, #24] |
| 328 | ldr pc, [pc, #24] |
| 329 | ldr pc, [pc, #24] |
| 330 | |
| 331 | /* Exception vectors */ |
| 332 | .global vectors |
| 333 | vectors: |
| 334 | .word start |
| 335 | .word undef_instr_handler |
| 336 | .word software_int_handler |
| 337 | .word prefetch_abort_handler |
| 338 | .word data_abort_handler |
| 339 | .word reserved_handler |
| 340 | .word irq_handler |
Michael Sevakis | 6077e5b | 2007-10-06 22:27:27 +0000 | [diff] [blame] | 341 | .word fiq_handler |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 342 | |
| 343 | .text |
| 344 | |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 345 | /* All illegal exceptions call into UIE with exception address as first |
| 346 | parameter. This is calculated differently depending on which exception |
| 347 | we're in. Second parameter is exception number, used for a string lookup |
| 348 | in UIE. |
| 349 | */ |
| 350 | undef_instr_handler: |
| 351 | mov r0, lr |
| 352 | mov r1, #0 |
| 353 | b UIE |
| 354 | |
| 355 | /* We run supervisor mode most of the time, and should never see a software |
| 356 | exception being thrown. Perhaps make it illegal and call UIE? |
| 357 | */ |
| 358 | software_int_handler: |
| 359 | reserved_handler: |
| 360 | movs pc, lr |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 361 | prefetch_abort_handler: |
| 362 | sub r0, lr, #4 |
| 363 | mov r1, #1 |
| 364 | b UIE |
| 365 | |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 366 | data_abort_handler: |
| 367 | sub r0, lr, #8 |
| 368 | mov r1, #2 |
| 369 | b UIE |
| 370 | |
| 371 | irq_handler: |
| 372 | #ifndef STUB |
| 373 | stmfd sp!, {r0-r3, r12, lr} |
| 374 | bl irq |
| 375 | ldmfd sp!, {r0-r3, r12, lr} |
| 376 | #endif |
| 377 | subs pc, lr, #4 |
| 378 | |
| 379 | #ifdef STUB |
| 380 | UIE: |
| 381 | b UIE |
| 382 | #endif |
| 383 | |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 384 | /* Align stacks to cache line boundary */ |
Michael Sevakis | a8b388f | 2007-11-27 01:20:26 +0000 | [diff] [blame] | 385 | .balign 32 |
Michael Sevakis | 7914e90 | 2007-09-28 10:20:02 +0000 | [diff] [blame] | 386 | |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 387 | /* 256 words of IRQ stack */ |
| 388 | .space 256*4 |
| 389 | irq_stack: |
| 390 | |
Daniel Ankers | 82f9056 | 2007-03-04 20:06:41 +0000 | [diff] [blame] | 391 | /* 256 words of COP IRQ stack */ |
| 392 | .space 256*4 |
| 393 | cop_irq_stack: |
| 394 | |
Daniel Ankers | 41997d3 | 2006-08-31 19:45:05 +0000 | [diff] [blame] | 395 | /* 256 words of FIQ stack */ |
| 396 | .space 256*4 |
| 397 | fiq_stack: |
Michael Sevakis | e1c52e7 | 2007-08-01 20:26:04 +0000 | [diff] [blame] | 398 | |
| 399 | /* We'll need this soon - just reserve the symbol */ |
| 400 | #if 0 |
| 401 | /* 256 words of COP FIQ stack */ |
| 402 | .space 256*4 |
| 403 | #endif |
| 404 | cop_fiq_stack: |