Hazard3/test/sim/sw_testcases/irq_set_all_with_pri.c

92 lines
2.3 KiB
C

#include "tb_cxxrtl_io.h"
#include "hazard3_irq.h"
// Similar to the irq_preempt_set_in_irq test, but there are two IRQs at each
// priority level, and rather than posting the high-priority IRQs from within
// lower priority IRQs, we post every single IRQ at once. Check that:
//
// - The IRQS run from highest to lowest priority order (which happens to be
// opposite to the default tiebreak order for these IRQs)
//
// - Within each priority level, the IRQs are tiebroken lowest-first
//
// - Each IRQ enters and exits before any lower IRQ enters
//
// - The EIRQ vector was entered exactly once (save/restore was shared between
// all the IRQs at their different priority levels)
/*EXPECTED-OUTPUT***************************************************************
Posting IRQs
Entered IRQ 15
Exiting IRQ 15
Entered IRQ 14
Exiting IRQ 14
Entered IRQ 13
Exiting IRQ 13
Entered IRQ 12
Exiting IRQ 12
Entered IRQ 11
Exiting IRQ 11
Entered IRQ 10
Exiting IRQ 10
Entered IRQ 9
Exiting IRQ 9
Entered IRQ 8
Exiting IRQ 8
Entered IRQ 7
Exiting IRQ 7
Entered IRQ 6
Exiting IRQ 6
Entered IRQ 5
Exiting IRQ 5
Entered IRQ 4
Exiting IRQ 4
Entered IRQ 3
Exiting IRQ 3
Entered IRQ 2
Exiting IRQ 2
Entered IRQ 1
Exiting IRQ 1
Entered IRQ 0
Exiting IRQ 0
EIRQ vector was entered 1 times
gstat
*******************************************************************************/
#define PRIORITY_LEVELS 16
#define NUM_IRQS 32
extern uintptr_t _external_irq_table[NUM_IRQS];
extern uint32_t _external_irq_entry_count;
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 < PRIORITY_LEVELS * 2; ++i) {
h3irq_enable(i, true);
h3irq_set_priority(i, i / 2);
_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 IRQs\n");
tb_set_irq_masked(0xffffffffu);
asm ("wfi");
tb_printf("EIRQ vector was entered %d times\n", _external_irq_entry_count);
return 0;
}
void handler(void) {
int irqnum = h3irq_get_current_irq();
tb_printf("Entered IRQ %d\n", irqnum);
tb_clr_irq_masked(1u << irqnum);
tb_printf("Exiting IRQ %d\n", irqnum);
}