diff options
Diffstat (limited to 'firmware/target/arm')
-rw-r--r-- | firmware/target/arm/imx31/avic-imx31.c | 2 | ||||
-rw-r--r-- | firmware/target/arm/imx31/avic-imx31.h | 48 | ||||
-rw-r--r-- | firmware/target/arm/imx31/crt0.S | 35 | ||||
-rw-r--r-- | firmware/target/arm/imx31/dvfs_dptc-imx31.c | 4 |
4 files changed, 40 insertions, 49 deletions
diff --git a/firmware/target/arm/imx31/avic-imx31.c b/firmware/target/arm/imx31/avic-imx31.c index b2b62755e1..5b0aad434c 100644 --- a/firmware/target/arm/imx31/avic-imx31.c +++ b/firmware/target/arm/imx31/avic-imx31.c | |||
@@ -103,6 +103,7 @@ void __attribute__((interrupt("IRQ"))) irq_handler(void) | |||
103 | } | 103 | } |
104 | #endif /* 0 */ | 104 | #endif /* 0 */ |
105 | 105 | ||
106 | #if 0 | ||
106 | /* Accoring to section 9.3.5 of the UM, the AVIC doesn't accelerate | 107 | /* Accoring to section 9.3.5 of the UM, the AVIC doesn't accelerate |
107 | * fast interrupts and they must be dispatched */ | 108 | * fast interrupts and they must be dispatched */ |
108 | void __attribute__((naked)) fiq_handler(void) | 109 | void __attribute__((naked)) fiq_handler(void) |
@@ -115,6 +116,7 @@ void __attribute__((naked)) fiq_handler(void) | |||
115 | "bx r8 \n" /* jump to FIQ service routine */ | 116 | "bx r8 \n" /* jump to FIQ service routine */ |
116 | ); | 117 | ); |
117 | } | 118 | } |
119 | #endif /* 0 */ | ||
118 | 120 | ||
119 | void INIT_ATTR avic_init(void) | 121 | void INIT_ATTR avic_init(void) |
120 | { | 122 | { |
diff --git a/firmware/target/arm/imx31/avic-imx31.h b/firmware/target/arm/imx31/avic-imx31.h index ca48f85ba5..a01a6cd795 100644 --- a/firmware/target/arm/imx31/avic-imx31.h +++ b/firmware/target/arm/imx31/avic-imx31.h | |||
@@ -77,34 +77,24 @@ static inline void avic_unmask_int(enum IMX31_INT_LIST ints) | |||
77 | * priority. Avoid using any app or other SVC stack by doing it with a mini | 77 | * priority. Avoid using any app or other SVC stack by doing it with a mini |
78 | * "stack on irq stack". Avoid actually enabling IRQ until the routine | 78 | * "stack on irq stack". Avoid actually enabling IRQ until the routine |
79 | * decides to do so; epilogue code will always disable them again. */ | 79 | * decides to do so; epilogue code will always disable them again. */ |
80 | #define AVIC_NESTED_NI_CALL_PROLOGUE(prio, stacksize) \ | 80 | #define AVIC_NESTED_NI_CALL(fn, prio) \ |
81 | ({ asm volatile ( \ | 81 | ({ asm volatile ( \ |
82 | "sub lr, lr, #4 \n" /* prepare return address */ \ | 82 | "sub lr, lr, #4 \n" /* prepare return address */ \ |
83 | "srsdb #0x12! \n" /* save LR_irq and SPSR_irq */ \ | 83 | "srsdb #0x12! \n" /* save LR_irq and SPSR_irq */ \ |
84 | "stmfd sp!, { r0-r3, r12 } \n" /* preserve context */ \ | 84 | "stmfd sp!, { r0-r3, r12 } \n" /* preserve context */ \ |
85 | "mov r0, #0x68000000 \n" /* AVIC_BASE_ADDR */ \ | 85 | "mov r0, #0x68000000 \n" /* AVIC_BASE_ADDR */ \ |
86 | "mov r1, %0 \n" /* load interrupt level */ \ | 86 | "mov r1, %0 \n" /* load interrupt level */ \ |
87 | "ldr r2, [r0, #0x04] \n" /* save NIMASK */ \ | 87 | "ldr r2, [r0, #0x04] \n" /* save NIMASK */ \ |
88 | "str r1, [r0, #0x04] \n" /* set interrupt level */ \ | 88 | "str r1, [r0, #0x04] \n" /* set interrupt level */ \ |
89 | "mov r0, sp \n" /* grab IRQ stack */ \ | 89 | "cps #0x13 \n" /* change to SVC mode */ \ |
90 | "sub sp, sp, %1 \n" /* allocate space for routine to SP_irq */ \ | 90 | "stmfd sp!, { r2, lr } \n" /* push NIMASK and LR_svc */ \ |
91 | "cps #0x13 \n" /* change to SVC mode */ \ | 91 | "bl " #fn " \n" /* Call SVC routine */ \ |
92 | "mov r1, sp \n" /* save SP_svc */ \ | 92 | "cpsid i \n" /* disable IRQ */ \ |
93 | "mov sp, r0 \n" /* switch to SP_irq *copy* */ \ | 93 | "ldmfd sp!, { r1, lr } \n" /* pop NIMASK and LR_svc */ \ |
94 | "stmfd sp!, { r1, r2, lr } \n" /* push SP_svc, NIMASK and LR_svc */ \ | 94 | "cps #0x12 \n" /* return to IRQ mode */ \ |
95 | : : "i"(prio), "i"(stacksize)); }) | 95 | "mov r0, #0x68000000 \n" /* AVIC BASE ADDR */ \ |
96 | 96 | "str r1, [r0, #0x04] \n" /* restore NIMASK */ \ | |
97 | #define AVIC_NESTED_NI_CALL_EPILOGUE(stacksize) \ | 97 | "ldmfd sp!, { r0-r3, r12 } \n" /* reload context */ \ |
98 | ({ asm volatile ( \ | 98 | "rfefd sp! \n" /* move stacked SPSR to CPSR, return */ \ |
99 | "cpsid i \n" /* disable IRQ */ \ | 99 | : : "i"(prio)); }) |
100 | "ldmfd sp!, { r1, r2, lr } \n" /* pop SP_svc, NIMASK and LR_svc */ \ | ||
101 | "mov sp, r1 \n" /* restore SP_svc */ \ | ||
102 | "cps #0x12 \n" /* return to IRQ mode */ \ | ||
103 | "add sp, sp, %0 \n" /* deallocate routine space */ \ | ||
104 | "mov r0, #0x68000000 \n" /* AVIC BASE ADDR */ \ | ||
105 | "str r2, [r0, #0x04] \n" /* restore NIMASK */ \ | ||
106 | "ldmfd sp!, { r0-r3, r12 } \n" /* reload context */ \ | ||
107 | "rfefd sp! \n" /* move stacked SPSR to CPSR, return */ \ | ||
108 | : : "i"(stacksize)); }) | ||
109 | |||
110 | #endif /* AVIC_IMX31_H */ | 100 | #endif /* AVIC_IMX31_H */ |
diff --git a/firmware/target/arm/imx31/crt0.S b/firmware/target/arm/imx31/crt0.S index 69577e4d3d..b6a49266ef 100644 --- a/firmware/target/arm/imx31/crt0.S +++ b/firmware/target/arm/imx31/crt0.S | |||
@@ -32,8 +32,9 @@ start: | |||
32 | b prefetch_abort_handler | 32 | b prefetch_abort_handler |
33 | b data_abort_handler | 33 | b data_abort_handler |
34 | b reserved_handler | 34 | b reserved_handler |
35 | /* These vectors are unused */ | ||
35 | subs pc, lr, #4 @ b irq_handler | 36 | subs pc, lr, #4 @ b irq_handler |
36 | b fiq_handler | 37 | subs pc, lr, #4 @ b fiq_handler |
37 | .balign 0x40, 0x6B | 38 | .balign 0x40, 0x6B |
38 | 39 | ||
39 | /* Arm bootloader and startup code based on startup.s from the iPodLinux loader | 40 | /* Arm bootloader and startup code based on startup.s from the iPodLinux loader |
@@ -80,7 +81,7 @@ remap_start: | |||
80 | mcrne p15, 0, r0, c7, c7, 0 /* invalidate I cache and D cache */ | 81 | mcrne p15, 0, r0, c7, c7, 0 /* invalidate I cache and D cache */ |
81 | mcr p15, 0, r0, c8, c7, 0 /* invalidate TLBs */ | 82 | mcr p15, 0, r0, c8, c7, 0 /* invalidate TLBs */ |
82 | mcr p15, 0, r0, c7, c10, 4 /* Drain the write buffer */ | 83 | mcr p15, 0, r0, c7, c10, 4 /* Drain the write buffer */ |
83 | 84 | ||
84 | mcr p15, 0, r0, c13, c0, 0 | 85 | mcr p15, 0, r0, c13, c0, 0 |
85 | mcr p15, 0, r0, c13, c0, 1 | 86 | mcr p15, 0, r0, c13, c0, 1 |
86 | 87 | ||
@@ -100,7 +101,7 @@ remap_start: | |||
100 | bic r3, r3, #((1 << 2) | /* L1 D-cache disabled */ \ | 101 | bic r3, r3, #((1 << 2) | /* L1 D-cache disabled */ \ |
101 | (1 << 0)) /* MMU disabled */ | 102 | (1 << 0)) /* MMU disabled */ |
102 | mcr p15, 0, r3, c1, c0, 0 | 103 | mcr p15, 0, r3, c1, c0, 0 |
103 | 104 | ||
104 | /* | 105 | /* |
105 | * Configure L2 Cache: | 106 | * Configure L2 Cache: |
106 | * - 128k size(16k way) | 107 | * - 128k size(16k way) |
@@ -175,7 +176,7 @@ remap_start: | |||
175 | mov r0, #0 | 176 | mov r0, #0 |
176 | mcr p15, 0, r0, c8, c7, 0 /* Invalidate TLB */ | 177 | mcr p15, 0, r0, c8, c7, 0 /* Invalidate TLB */ |
177 | mcr p15, 0, r0, c7, c7, 0 /* Invalidate icache and dcache */ | 178 | mcr p15, 0, r0, c7, c7, 0 /* Invalidate icache and dcache */ |
178 | 179 | ||
179 | /* Auxilliary control register */ | 180 | /* Auxilliary control register */ |
180 | mrc p15, 0, r0, c1, c0, 1 | 181 | mrc p15, 0, r0, c1, c0, 1 |
181 | bic r0, r0, #((1 << 6) | /* Restrict cache size OFF */ \ | 182 | bic r0, r0, #((1 << 6) | /* Restrict cache size OFF */ \ |
@@ -252,18 +253,18 @@ remap_end: | |||
252 | cmp r3, r2 | 253 | cmp r3, r2 |
253 | strhi r4, [r2], #4 | 254 | strhi r4, [r2], #4 |
254 | bhi 1b | 255 | bhi 1b |
255 | 256 | ||
256 | /* Set up stack for IRQ mode */ | 257 | /* Set up stack for IRQ mode */ |
257 | msr cpsr_c, #0xd2 | 258 | msr cpsr_c, #0xd2 |
258 | ldr sp, =irq_stack | 259 | ldr sp, =irq_stack |
259 | 260 | ||
260 | /* Set up stack for FIQ mode */ | 261 | /* FIQ mode is unused, thus sp_FIQ is irrelevant for it */ |
261 | msr cpsr_c, #0xd1 | ||
262 | ldr sp, =fiq_stack | ||
263 | 262 | ||
264 | /* Let svc, abort and undefined modes use irq stack */ | 263 | /* Set up stack for SVC mode */ |
265 | msr cpsr_c, #0xd3 | 264 | msr cpsr_c, #0xd3 |
266 | ldr sp, =irq_stack | 265 | ldr sp, =svc_stack |
266 | |||
267 | /* Let abort and undefined modes use irq stack */ | ||
267 | msr cpsr_c, #0xd7 | 268 | msr cpsr_c, #0xd7 |
268 | ldr sp, =irq_stack | 269 | ldr sp, =irq_stack |
269 | msr cpsr_c, #0xdb | 270 | msr cpsr_c, #0xdb |
@@ -286,7 +287,7 @@ remap_end: | |||
286 | mrc p15, 0, r3, c1, c0, 2 | 287 | mrc p15, 0, r3, c1, c0, 2 |
287 | orr r3, r3, #0xf00000 | 288 | orr r3, r3, #0xf00000 |
288 | mcr p15, 0, r3, c1, c0, 2 | 289 | mcr p15, 0, r3, c1, c0, 2 |
289 | 290 | ||
290 | /* Enable VFP */ | 291 | /* Enable VFP */ |
291 | mrc p10, 7, r3, c8, c0, 0 | 292 | mrc p10, 7, r3, c8, c0, 0 |
292 | orr r3, r3, #1<<30 | 293 | orr r3, r3, #1<<30 |
@@ -314,7 +315,7 @@ remap_end: | |||
314 | ldr pc, [pc, #24] | 315 | ldr pc, [pc, #24] |
315 | ldr pc, [pc, #24] | 316 | ldr pc, [pc, #24] |
316 | subs pc, lr, #4 @ ldr pc, [pc, #24] | 317 | subs pc, lr, #4 @ ldr pc, [pc, #24] |
317 | ldr pc, [pc, #24] | 318 | subs pc, lr, #4 @ ldr pc, [pc, #24] |
318 | .word newstart | 319 | .word newstart |
319 | .word undef_instr_handler | 320 | .word undef_instr_handler |
320 | .word software_int_handler | 321 | .word software_int_handler |
@@ -322,7 +323,7 @@ remap_end: | |||
322 | .word data_abort_handler | 323 | .word data_abort_handler |
323 | .word reserved_handler | 324 | .word reserved_handler |
324 | .word 0 @ irq_handler | 325 | .word 0 @ irq_handler |
325 | .word fiq_handler | 326 | .word 0 @ fiq_handler |
326 | #endif /* BOOTLOADER */ | 327 | #endif /* BOOTLOADER */ |
327 | 328 | ||
328 | .text | 329 | .text |
@@ -350,7 +351,7 @@ prefetch_abort_handler: | |||
350 | b UIE | 351 | b UIE |
351 | 352 | ||
352 | data_abort_handler: | 353 | data_abort_handler: |
353 | sub r0, lr, #8 | 354 | sub r0, lr, #8 |
354 | mov r1, #2 | 355 | mov r1, #2 |
355 | b UIE | 356 | b UIE |
356 | 357 | ||
@@ -360,8 +361,8 @@ data_abort_handler: | |||
360 | .space 256*4 | 361 | .space 256*4 |
361 | irq_stack: | 362 | irq_stack: |
362 | 363 | ||
363 | /* 256 words of FIQ stack */ | 364 | /* 256 words of SVC stack */ |
364 | .section .bss | 365 | .section .bss |
365 | .balign 32 | 366 | .balign 32 |
366 | .space 256*4 | 367 | .space 256*4 |
367 | fiq_stack: | 368 | svc_stack: |
diff --git a/firmware/target/arm/imx31/dvfs_dptc-imx31.c b/firmware/target/arm/imx31/dvfs_dptc-imx31.c index 1c5ad863ce..e8dee17416 100644 --- a/firmware/target/arm/imx31/dvfs_dptc-imx31.c +++ b/firmware/target/arm/imx31/dvfs_dptc-imx31.c | |||
@@ -241,9 +241,7 @@ static void __attribute__((used)) dvfs_int(void) | |||
241 | static __attribute__((naked, interrupt("IRQ"))) void CCM_DVFS_HANDLER(void) | 241 | static __attribute__((naked, interrupt("IRQ"))) void CCM_DVFS_HANDLER(void) |
242 | { | 242 | { |
243 | /* Audio can glitch with the long udelay if nested IRQ isn't allowed. */ | 243 | /* Audio can glitch with the long udelay if nested IRQ isn't allowed. */ |
244 | AVIC_NESTED_NI_CALL_PROLOGUE(INT_PRIO_DVFS, 32*4); | 244 | AVIC_NESTED_NI_CALL(dvfs_int, INT_PRIO_DVFS); |
245 | asm volatile ("bl dvfs_int"); | ||
246 | AVIC_NESTED_NI_CALL_EPILOGUE(32*4); | ||
247 | } | 245 | } |
248 | 246 | ||
249 | /* Initialize the DVFS hardware */ | 247 | /* Initialize the DVFS hardware */ |