Spurious interrupts support

This commit is contained in:
giomba 2019-01-07 16:22:46 +01:00
parent 92e1e261e7
commit 0ef7b9e353
2 changed files with 13 additions and 3 deletions

View File

@ -2,6 +2,10 @@
#include <interrupt.h>
#include <stdint.h>
extern "C" void spurious_irq_handler(const uint8_t cpuID, const uint16_t interruptID) {
printkl("Spurious interrupt caught");
}
extern "C" uint32_t c_irq_handler(uint32_t iar) {
uint8_t cpuID = (iar >> 10) & 0x7;
uint16_t interruptID = iar & 0x3ff;
@ -19,6 +23,9 @@ extern "C" uint32_t c_irq_handler(uint32_t iar) {
case 54: case 55: case 56: case 57: case 99: case 100:
handler = interrupt::handler[interruptID];
break;
case 1023:
handler = spurious_irq_handler;
break;
}
/* Call interrupt handler */
@ -35,3 +42,4 @@ extern "C" uint32_t c_irq_handler(uint32_t iar) {
return iar;
}

View File

@ -91,13 +91,15 @@ irq_handler:
ldr r0, [r10]
push {r0}
// C complex handler
// Complex handlers in C++
bl c_irq_handler
// Send End of Interrupt
pop {r0}
ldr r10, =0x01c82010 // EOIR
str r0, [r10]
ldr r10, =0x01c82010 // EOIR address
mov r1, #1023 // check for spurious interrupt
cmp r0, r1
strne r0, [r10] // ack interrupt only if not spurious (see GICC_EOIR)
// Reload context from stack
// and also restore CPSR from SPSR (that caret)