summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--firmware/target/arm/imx31/avic-imx31.c2
-rw-r--r--firmware/target/arm/imx31/avic-imx31.h48
-rw-r--r--firmware/target/arm/imx31/crt0.S35
-rw-r--r--firmware/target/arm/imx31/dvfs_dptc-imx31.c4
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 */
108void __attribute__((naked)) fiq_handler(void) 109void __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
119void INIT_ATTR avic_init(void) 121void 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
352data_abort_handler: 353data_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
361irq_stack: 362irq_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
367fiq_stack: 368svc_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)
241static __attribute__((naked, interrupt("IRQ"))) void CCM_DVFS_HANDLER(void) 241static __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 */