summaryrefslogtreecommitdiff
path: root/firmware/target/arm/imx31/avic-imx31.h
diff options
context:
space:
mode:
Diffstat (limited to 'firmware/target/arm/imx31/avic-imx31.h')
-rw-r--r--firmware/target/arm/imx31/avic-imx31.h48
1 files changed, 19 insertions, 29 deletions
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 */