82 lines
1.7 KiB
C
82 lines
1.7 KiB
C
#include "tb_cxxrtl_io.h"
|
|
#include "hazard3_irq.h"
|
|
|
|
/*EXPECTED-OUTPUT***************************************************************
|
|
|
|
Posting first IRQ
|
|
Entered IRQ 0
|
|
Entered IRQ 1
|
|
Entered IRQ 2
|
|
Entered IRQ 3
|
|
Entered IRQ 4
|
|
Entered IRQ 5
|
|
Entered IRQ 6
|
|
Entered IRQ 7
|
|
Entered IRQ 8
|
|
Entered IRQ 9
|
|
Entered IRQ 10
|
|
Entered IRQ 11
|
|
Entered IRQ 12
|
|
Entered IRQ 13
|
|
Entered IRQ 14
|
|
Entered IRQ 15
|
|
Exiting IRQ 15
|
|
Exiting IRQ 14
|
|
Exiting IRQ 13
|
|
Exiting IRQ 12
|
|
Exiting IRQ 11
|
|
Exiting IRQ 10
|
|
Exiting IRQ 9
|
|
Exiting IRQ 8
|
|
Exiting IRQ 7
|
|
Exiting IRQ 6
|
|
Exiting IRQ 5
|
|
Exiting IRQ 4
|
|
Exiting IRQ 3
|
|
Exiting IRQ 2
|
|
Exiting IRQ 1
|
|
Exiting IRQ 0
|
|
Done.
|
|
|
|
*******************************************************************************/
|
|
|
|
#define MAX_PRIORITY 15
|
|
#define NUM_IRQS 64
|
|
|
|
extern uintptr_t _external_irq_table[NUM_IRQS];
|
|
|
|
void handler(void);
|
|
|
|
int main() {
|
|
// Enable external IRQs globally
|
|
set_csr(mstatus, 0x8);
|
|
set_csr(mie, 0x800);
|
|
// Enable one external IRQ at each priority level
|
|
for (int i = 0; i <= MAX_PRIORITY; ++i) {
|
|
h3irq_enable(i, true);
|
|
h3irq_set_priority(i, i);
|
|
_external_irq_table[i] = (uintptr_t)handler;
|
|
}
|
|
// Set off the lowest-priority IRQ. The IRQ handler will then set the
|
|
// next-lowest, which will preempt it. So on, up to the highest level,
|
|
// then return all the way back down through the nested frames.
|
|
tb_puts("Posting first IRQ\n");
|
|
tb_set_irq_masked(0x1);
|
|
asm ("wfi");
|
|
|
|
tb_puts("Done.\n");
|
|
return 0;
|
|
}
|
|
|
|
void handler(void) {
|
|
int irqnum = h3irq_get_current_irq();
|
|
tb_printf("Entered IRQ %d\n", irqnum);
|
|
if (irqnum < MAX_PRIORITY)
|
|
tb_set_irq_masked(1u << (irqnum + 1));
|
|
// !!! Get preempted here
|
|
tb_clr_irq_masked(1u << irqnum);
|
|
// Make sure context save/restore tracks as expected:
|
|
irqnum = h3irq_get_current_irq();
|
|
tb_printf("Exiting IRQ %d\n", irqnum);
|
|
}
|