diff options
author | Michael Sevakis <jethead71@rockbox.org> | 2007-08-01 20:26:04 +0000 |
---|---|---|
committer | Michael Sevakis <jethead71@rockbox.org> | 2007-08-01 20:26:04 +0000 |
commit | e1c52e7fbe95dff284f9007ac279d27b51f61dd0 (patch) | |
tree | bc77e010b74c3183d3fe51acb1fe1a7c896c1f3a /firmware | |
parent | ffb3dfd241a537fb7323507f8ab34a512437c7d2 (diff) | |
download | rockbox-e1c52e7fbe95dff284f9007ac279d27b51f61dd0.tar.gz rockbox-e1c52e7fbe95dff284f9007ac279d27b51f61dd0.zip |
PP50xx: Allow FIQ during IRQ to always be able to service FIFOs. I've got a diff handy for quick revert if there's a problem.
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@14123 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r-- | firmware/target/arm/crt0-pp.S | 81 |
1 files changed, 44 insertions, 37 deletions
diff --git a/firmware/target/arm/crt0-pp.S b/firmware/target/arm/crt0-pp.S index 41a0495861..b2e09fd690 100644 --- a/firmware/target/arm/crt0-pp.S +++ b/firmware/target/arm/crt0-pp.S | |||
@@ -32,26 +32,29 @@ start: | |||
32 | * | 32 | * |
33 | */ | 33 | */ |
34 | #if CONFIG_CPU == PP5002 | 34 | #if CONFIG_CPU == PP5002 |
35 | .equ PROC_ID, 0xc4000000 | 35 | .equ PROC_ID, 0xc4000000 |
36 | .equ COP_CTRL, 0xcf004058 | 36 | .equ CPU_ICLR, 0xcf001028 |
37 | .equ COP_ICLR, 0xcf001038 | ||
38 | .equ COP_CTRL, 0xcf004058 | ||
37 | .equ COP_STATUS, 0xcf004050 | 39 | .equ COP_STATUS, 0xcf004050 |
38 | .equ IIS_CONFIG, 0xc0002500 | 40 | .equ IIS_CONFIG, 0xc0002500 |
39 | .equ SLEEP, 0xca | 41 | .equ SLEEP, 0x000000ca |
40 | .equ WAKE, 0xce | 42 | .equ WAKE, 0x000000ce |
41 | .equ SLEEPING, 0x4000 | 43 | .equ SLEEPING, 0x00004000 |
42 | #else | 44 | #else |
43 | .equ PROC_ID, 0x60000000 | 45 | .equ PROC_ID, 0x60000000 |
44 | .equ COP_CTRL, 0x60007004 | 46 | .equ CPU_ICLR, 0x60004028 |
47 | .equ COP_ICLR, 0x60004038 | ||
48 | .equ COP_CTRL, 0x60007004 | ||
45 | .equ COP_STATUS, 0x60007004 | 49 | .equ COP_STATUS, 0x60007004 |
46 | .equ IIS_CONFIG, 0x70002800 | 50 | .equ IIS_CONFIG, 0x70002800 |
47 | .equ SLEEP, 0x80000000 | 51 | .equ SLEEP, 0x80000000 |
48 | .equ WAKE, 0x0 | 52 | .equ WAKE, 0x00000000 |
49 | .equ SLEEPING, 0x80000000 | 53 | .equ SLEEPING, 0x80000000 |
50 | .equ CACHE_CTRL, 0x6000c000 | 54 | .equ CACHE_CTRL, 0x6000c000 |
51 | #endif | 55 | #endif |
52 | 56 | ||
53 | msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ */ | 57 | msr cpsr_c, #0xd3 /* enter supervisor mode, disable IRQ/FIQ */ |
54 | |||
55 | b pad_skip | 58 | b pad_skip |
56 | 59 | ||
57 | .space 60*4 /* (more than enough) space for exception vectors and mi4 magic */ | 60 | .space 60*4 /* (more than enough) space for exception vectors and mi4 magic */ |
@@ -110,25 +113,28 @@ remap_end: | |||
110 | 113 | ||
111 | /* Find out which processor we are */ | 114 | /* Find out which processor we are */ |
112 | ldr r0, =PROC_ID | 115 | ldr r0, =PROC_ID |
113 | ldr r0, [r0] | 116 | ldrb r0, [r0] |
114 | and r0, r0, #0xff | ||
115 | cmp r0, #0x55 | 117 | cmp r0, #0x55 |
116 | beq cpu_init | 118 | |
119 | /* Mask all interrupt sources before setting up modes */ | ||
120 | ldreq r0, =CPU_ICLR | ||
121 | ldrne r0, =COP_ICLR | ||
122 | mvn r1, #1 | ||
123 | str r1, [r0] | ||
117 | 124 | ||
118 | /* put us (co-processor) to sleep */ | 125 | /* put us (co-processor) to sleep */ |
119 | ldr r4, =COP_CTRL | 126 | ldrne r4, =COP_CTRL |
120 | mov r3, #SLEEP | 127 | movne r3, #SLEEP |
121 | str r3, [r4] | 128 | strne r3, [r4] |
122 | |||
123 | ldr pc, =cop_init | ||
124 | 129 | ||
130 | ldrne pc, =cop_init | ||
125 | 131 | ||
126 | cpu_init: | 132 | cpu_init: |
127 | /* Wait for COP to be sleeping */ | 133 | /* Wait for COP to be sleeping */ |
128 | ldr r4, =COP_STATUS | 134 | ldr r4, =COP_STATUS |
129 | 1: | 135 | 1: |
130 | ldr r3, [r4] | 136 | ldr r3, [r4] |
131 | ands r3, r3, #SLEEPING | 137 | tst r3, #SLEEPING |
132 | beq 1b | 138 | beq 1b |
133 | 139 | ||
134 | /* Copy exception handler code to address 0 */ | 140 | /* Copy exception handler code to address 0 */ |
@@ -180,10 +186,10 @@ cpu_init: | |||
180 | bhi 1b | 186 | bhi 1b |
181 | 187 | ||
182 | /* Set up stack for IRQ mode */ | 188 | /* Set up stack for IRQ mode */ |
183 | msr cpsr_c, #0xd2 | 189 | msr cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */ |
184 | ldr sp, =irq_stack | 190 | ldr sp, =irq_stack |
185 | /* Set up stack for FIQ mode */ | 191 | /* Set up stack for FIQ mode */ |
186 | msr cpsr_c, #0xd1 | 192 | msr cpsr_c, #0xd1 /* IRQ/FIQ disabled */ |
187 | ldr sp, =fiq_stack | 193 | ldr sp, =fiq_stack |
188 | /* We'll load the banked FIQ mode registers with useful values here. | 194 | /* We'll load the banked FIQ mode registers with useful values here. |
189 | These values will be used in the FIQ handler in pcm_playback.c */ | 195 | These values will be used in the FIQ handler in pcm_playback.c */ |
@@ -192,9 +198,9 @@ cpu_init: | |||
192 | ldr r11, =p | 198 | ldr r11, =p |
193 | 199 | ||
194 | /* Let abort and undefined modes use IRQ stack */ | 200 | /* Let abort and undefined modes use IRQ stack */ |
195 | msr cpsr_c, #0xd7 | 201 | msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */ |
196 | ldr sp, =irq_stack | 202 | ldr sp, =irq_stack |
197 | msr cpsr_c, #0xdb | 203 | msr cpsr_c, #0xdb /* IRQ/FIQ disabled */ |
198 | ldr sp, =irq_stack | 204 | ldr sp, =irq_stack |
199 | /* Switch to supervisor mode */ | 205 | /* Switch to supervisor mode */ |
200 | msr cpsr_c, #0xd3 | 206 | msr cpsr_c, #0xd3 |
@@ -228,16 +234,16 @@ cop_init: | |||
228 | bhi 2b | 234 | bhi 2b |
229 | 235 | ||
230 | /* Set up stack for IRQ mode */ | 236 | /* Set up stack for IRQ mode */ |
231 | msr cpsr_c, #0xd2 | 237 | msr cpsr_c, #0x92 /* IRQ disabled, FIQ enabled */ |
232 | ldr sp, =cop_irq_stack | 238 | ldr sp, =cop_irq_stack |
233 | /* Set up stack for FIQ mode */ | 239 | /* Set up stack for FIQ mode */ |
234 | msr cpsr_c, #0xd1 | 240 | msr cpsr_c, #0xd1 /* IRQ/FIQ disabled */ |
235 | ldr sp, =fiq_stack | 241 | ldr sp, =cop_fiq_stack |
236 | 242 | ||
237 | /* Let abort and undefined modes use IRQ stack */ | 243 | /* Let abort and undefined modes use IRQ stack */ |
238 | msr cpsr_c, #0xd7 | 244 | msr cpsr_c, #0xd7 /* IRQ/FIQ disabled */ |
239 | ldr sp, =cop_irq_stack | 245 | ldr sp, =cop_irq_stack |
240 | msr cpsr_c, #0xdb | 246 | msr cpsr_c, #0xdb /* IRQ/FIQ disabled */ |
241 | ldr sp, =cop_irq_stack | 247 | ldr sp, =cop_irq_stack |
242 | 248 | ||
243 | ldr sp, =cop_stackend | 249 | ldr sp, =cop_stackend |
@@ -266,13 +272,12 @@ vectors: | |||
266 | .word data_abort_handler | 272 | .word data_abort_handler |
267 | .word reserved_handler | 273 | .word reserved_handler |
268 | .word irq_handler | 274 | .word irq_handler |
269 | .word fiq_handler | 275 | .word 0 /* fiq handler set in pcm driver */ |
270 | 276 | ||
271 | .text | 277 | .text |
272 | 278 | ||
273 | #ifndef STUB | 279 | #ifndef STUB |
274 | .global irq | 280 | .global irq |
275 | .global fiq | ||
276 | .global UIE | 281 | .global UIE |
277 | #endif | 282 | #endif |
278 | 283 | ||
@@ -298,11 +303,6 @@ prefetch_abort_handler: | |||
298 | mov r1, #1 | 303 | mov r1, #1 |
299 | b UIE | 304 | b UIE |
300 | 305 | ||
301 | fiq_handler: | ||
302 | @ Branch straight to FIQ handler in pcm_playback.c. This also handles the | ||
303 | @ the correct return sequence. | ||
304 | ldr pc, =fiq | ||
305 | |||
306 | data_abort_handler: | 306 | data_abort_handler: |
307 | sub r0, lr, #8 | 307 | sub r0, lr, #8 |
308 | mov r1, #2 | 308 | mov r1, #2 |
@@ -332,3 +332,10 @@ cop_irq_stack: | |||
332 | /* 256 words of FIQ stack */ | 332 | /* 256 words of FIQ stack */ |
333 | .space 256*4 | 333 | .space 256*4 |
334 | fiq_stack: | 334 | fiq_stack: |
335 | |||
336 | /* We'll need this soon - just reserve the symbol */ | ||
337 | #if 0 | ||
338 | /* 256 words of COP FIQ stack */ | ||
339 | .space 256*4 | ||
340 | #endif | ||
341 | cop_fiq_stack: | ||