diff options
Diffstat (limited to 'firmware/target/arm/imx31/avic-imx31.h')
-rw-r--r-- | firmware/target/arm/imx31/avic-imx31.h | 48 |
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 */ |