Created
December 4, 2021 00:52
-
-
Save Wren6991/158db32537f643d315afe14820231d29 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Custom CSRs | |
#define meie0 0xbe0 // External interrupt enable | |
#define meip0 0xfe0 // External interrupt pending | |
#define mlei 0xfe4 // Lowest external interrupt, left shifted by 2. | |
_external_irq_vector: | |
// Begin critical section | |
addi sp, sp, -16 | |
sw a0, 0(sp) | |
sw a1, 4(sp) | |
// Save exception return state. No need to save mstatus because we know we | |
// got here from M mode, and we know interrupts were enabled at the point | |
// the interrupt fired. | |
csrr a0, mepc | |
sw a0, 8(sp) | |
csrr a0, meie0 | |
sw a0, 12(sp) | |
// Disable this and lower-priority interrupts. mlei returns the index of | |
// the lowest-numbered pending & enabled external IRQ, left-shifted by 2. | |
csrr a0, mlei | |
la a1, irq_primask_table | |
add a1, a1, a0 | |
lw a1, (a1) | |
csrw meie0, a1 | |
// End of critical section. Enable preemption. | |
csrsi mstatus, 0x8 | |
// Save caller saves. ISR may be an undecorated function. | |
addi sp, sp, -64 | |
sw ra, 0 (sp) | |
sw t0, 4 (sp) | |
sw t1, 8 (sp) | |
sw t2, 12(sp) | |
sw a2, 16(sp) | |
sw a3, 20(sp) | |
sw a4, 24(sp) | |
sw a5, 28(sp) | |
sw a6, 32(sp) | |
sw a7, 36(sp) | |
sw t3, 40(sp) | |
sw t4, 44(sp) | |
sw t5, 48(sp) | |
sw t6, 52(sp) | |
// Let's go! | |
la a1, irq_vector_table | |
add a1, a1, a0 | |
jalr a1 | |
// Restore caller saves | |
lw ra, 0 (sp) | |
lw t0, 4 (sp) | |
lw t1, 8 (sp) | |
lw t2, 12(sp) | |
lw a2, 16(sp) | |
lw a3, 20(sp) | |
lw a4, 24(sp) | |
lw a5, 28(sp) | |
lw a6, 32(sp) | |
lw a7, 36(sp) | |
lw t3, 40(sp) | |
lw t4, 44(sp) | |
lw t5, 48(sp) | |
lw t6, 52(sp) | |
addi sp, sp, 64 | |
// Begin critical section | |
csrci mstatus, 0x8 | |
lw a0, 8(sp) | |
csrw mepc, a0 | |
lw a0, 12(sp) | |
csrw meie0, a0 | |
lw a0, 0(sp) | |
lw a1, 4(sp) | |
addi sp, sp, 16 | |
// Exception state restored, return to whence we came | |
mret | |
.section .data, "aw" | |
// RAM-resident ISR function pointer table | |
.p2align 2 | |
_external_irq_vector_table: | |
.rept 32 | |
.word 0 | |
.endr | |
// For each IRQ number, a mask where that bit and the bit corresponding to any | |
// IRQ of lower or equal priority is clear. The IRQs are grouped into | |
// relatively few priority levels (say 4 of them) to avoid blowing out the | |
// stack. When an IRQ's priority is adjusted, we disable IRQs and update the | |
// mask table. | |
_external_irq_primask_table: | |
.rept 32 | |
.word 0 | |
.endr |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment