diff options
author | Amaury Pouly <amaury.pouly@gmail.com> | 2014-02-16 20:51:01 +0100 |
---|---|---|
committer | Amaury Pouly <amaury.pouly@gmail.com> | 2014-02-16 20:53:08 +0100 |
commit | db392245e2524085bbfb67b09fa1e6634752c529 (patch) | |
tree | 8f0041043a3a154f4ac9df4c2179aab3d1416a46 /firmware/target | |
parent | 556fa2c4cddf125b91b47009229dd65832e6e102 (diff) | |
download | rockbox-db392245e2524085bbfb67b09fa1e6634752c529.tar.gz rockbox-db392245e2524085bbfb67b09fa1e6634752c529.zip |
imx233: rework interrupt nesting, disabled for now
Rework the irq code, to put more code in the C part. When interrupt
nesting is enable, Rockbox gets pretty unstable so disable it for now.
Change-Id: Iee18b539c80ea408273f6082975faaa87d3ee1b6
Diffstat (limited to 'firmware/target')
-rw-r--r-- | firmware/target/arm/imx233/icoll-imx233.c | 50 |
1 files changed, 30 insertions, 20 deletions
diff --git a/firmware/target/arm/imx233/icoll-imx233.c b/firmware/target/arm/imx233/icoll-imx233.c index e23af602db..4e3c6fe864 100644 --- a/firmware/target/arm/imx233/icoll-imx233.c +++ b/firmware/target/arm/imx233/icoll-imx233.c | |||
@@ -127,6 +127,15 @@ static isr_t isr_table[INT_SRC_COUNT] = | |||
127 | static uint32_t irq_count_old[INT_SRC_COUNT]; | 127 | static uint32_t irq_count_old[INT_SRC_COUNT]; |
128 | static uint32_t irq_count[INT_SRC_COUNT]; | 128 | static uint32_t irq_count[INT_SRC_COUNT]; |
129 | 129 | ||
130 | unsigned imx233_icoll_get_priority(int src) | ||
131 | { | ||
132 | #if IMX233_SUBTARGET < 3780 | ||
133 | return BF_RDn(ICOLL_PRIORITYn, src / 4, PRIORITYx(src % 4)); | ||
134 | #else | ||
135 | return BF_RDn(ICOLL_INTERRUPTn, src, PRIORITY); | ||
136 | #endif | ||
137 | } | ||
138 | |||
130 | struct imx233_icoll_irq_info_t imx233_icoll_get_irq_info(int src) | 139 | struct imx233_icoll_irq_info_t imx233_icoll_get_irq_info(int src) |
131 | { | 140 | { |
132 | struct imx233_icoll_irq_info_t info; | 141 | struct imx233_icoll_irq_info_t info; |
@@ -135,11 +144,7 @@ struct imx233_icoll_irq_info_t imx233_icoll_get_irq_info(int src) | |||
135 | #else | 144 | #else |
136 | info.enabled = BF_RDn(ICOLL_INTERRUPTn, src, ENABLE); | 145 | info.enabled = BF_RDn(ICOLL_INTERRUPTn, src, ENABLE); |
137 | #endif | 146 | #endif |
138 | #if IMX233_SUBTARGET < 3780 | 147 | info.priority = imx233_icoll_get_priority(src); |
139 | info.priority = BF_RDn(ICOLL_PRIORITYn, src / 4, PRIORITYx(src % 4)); | ||
140 | #else | ||
141 | info.priority = BF_RDn(ICOLL_INTERRUPTn, src, PRIORITY); | ||
142 | #endif | ||
143 | info.freq = irq_count_old[src]; | 148 | info.freq = irq_count_old[src]; |
144 | return info; | 149 | return info; |
145 | } | 150 | } |
@@ -163,16 +168,23 @@ static void UIRQ(void) | |||
163 | } | 168 | } |
164 | 169 | ||
165 | /* return the priority level */ | 170 | /* return the priority level */ |
166 | int _irq_handler(uint32_t vec) | 171 | void _irq_handler(void) |
167 | { | 172 | { |
173 | /* read vector and notify as side effect */ | ||
174 | uint32_t vec = HW_ICOLL_VECTOR; | ||
168 | int irq_nr = (vec - HW_ICOLL_VBASE) / 4; | 175 | int irq_nr = (vec - HW_ICOLL_VBASE) / 4; |
176 | /* check for IRQ storm */ | ||
169 | if(irq_count[irq_nr]++ > IRQ_STORM_THRESHOLD) | 177 | if(irq_count[irq_nr]++ > IRQ_STORM_THRESHOLD) |
170 | panicf("IRQ %d: storm detected", irq_nr); | 178 | panicf("IRQ %d: storm detected", irq_nr); |
179 | /* do some regular stat */ | ||
171 | if(irq_nr == INT_SRC_TIMER(TIMER_TICK)) | 180 | if(irq_nr == INT_SRC_TIMER(TIMER_TICK)) |
172 | do_irq_stat(); | 181 | do_irq_stat(); |
182 | /* enable interrupts again */ | ||
183 | //enable_irq(); | ||
184 | /* process interrupt */ | ||
173 | (*(isr_t *)vec)(); | 185 | (*(isr_t *)vec)(); |
174 | /* acknowledge completion of IRQ */ | 186 | /* acknowledge completion of IRQ */ |
175 | return imx233_icoll_get_irq_info(irq_nr).priority; | 187 | HW_ICOLL_LEVELACK = 1 << imx233_icoll_get_priority(irq_nr); |
176 | } | 188 | } |
177 | 189 | ||
178 | void irq_handler(void) | 190 | void irq_handler(void) |
@@ -181,22 +193,20 @@ void irq_handler(void) | |||
181 | asm volatile( | 193 | asm volatile( |
182 | "sub lr, lr, #4 \n" /* Create return address */ | 194 | "sub lr, lr, #4 \n" /* Create return address */ |
183 | "stmfd sp!, { r0-r5, r12, lr } \n" /* Save what gets clobbered */ | 195 | "stmfd sp!, { r0-r5, r12, lr } \n" /* Save what gets clobbered */ |
184 | "ldr r5, =0x8001c290 \n" /* Save pointer to instruction */ | 196 | "ldr r1, =0x8001c290 \n" /* Save pointer to instruction */ |
185 | "str lr, [r5] \n" /* in HW_DIGCTL_SCRATCH0 */ | 197 | "str lr, [r1] \n" /* in HW_DIGCTL_SCRATCH0 */ |
186 | "ldr r4, =0x80000000 \n" /* Read HW_ICOLL_VECTOR */ | ||
187 | "ldr r0, [r4] \n" /* and notify as side-effect */ | ||
188 | "mrs lr, spsr \n" /* Save SPSR_irq */ | 198 | "mrs lr, spsr \n" /* Save SPSR_irq */ |
189 | "stmfd sp!, { lr } \n" /* Push it on the IRQ stack */ | 199 | "stmfd sp!, { r1, lr } \n" /* Push it on the stack */ |
190 | "msr cpsr_c, #0x13 \n" /* Switch to SVC mode, enable IRQ */ | 200 | "msr cpsr_c, #0x93 \n" /* Switch to SVC mode, IRQ disabled */ |
191 | "stmfd sp!, { lr } \n" /* Save lr_SVC */ | 201 | "mov r4, lr \n" /* Save lr_SVC */ |
192 | "blx _irq_handler \n" /* Process IRQ, returns ack level */ | 202 | "and r5, sp, #4 \n" /* Align SVC stack */ |
193 | "ldmfd sp!, { lr } \n" /* Restore lr_SVC */ | 203 | "sub sp, sp, r5 \n" /* on 8-byte boundary */ |
204 | "blx _irq_handler \n" /* Process IRQ */ | ||
205 | "add sp, sp, r5 \n" /* Undo alignement */ | ||
206 | "mov lr, r4 \n" /* Restore lr_SVC */ | ||
194 | "msr cpsr_c, #0x92 \n" /* Mask IRQ, return to IRQ mode */ | 207 | "msr cpsr_c, #0x92 \n" /* Mask IRQ, return to IRQ mode */ |
195 | "ldmfd sp!, { lr } \n" /* Pop back SPSR */ | 208 | "ldmfd sp!, { r1, lr } \n" /* Reload saved value */ |
196 | "msr spsr_cxsf, lr \n" /* Restore SPSR_irq */ | 209 | "msr spsr_cxsf, lr \n" /* Restore SPSR_irq */ |
197 | "mov r3, #1 \n" /* Compute ack level value */ | ||
198 | "lsl r0, r3, r0 \n" /* (1 << ack_lvl) */ | ||
199 | "str r0, [r4, #0x10] \n" /* and write it to HW_ICOLL_LEVELACK */ | ||
200 | "ldmfd sp!, { r0-r5, r12, pc }^ \n" /* Restore regs, and RFE */); | 210 | "ldmfd sp!, { r0-r5, r12, pc }^ \n" /* Restore regs, and RFE */); |
201 | } | 211 | } |
202 | 212 | ||