diff options
Diffstat (limited to 'tests/tcg/xtensa/test_interrupt.S')
-rw-r--r-- | tests/tcg/xtensa/test_interrupt.S | 259 |
1 files changed, 259 insertions, 0 deletions
diff --git a/tests/tcg/xtensa/test_interrupt.S b/tests/tcg/xtensa/test_interrupt.S new file mode 100644 index 000000000..efedc43f6 --- /dev/null +++ b/tests/tcg/xtensa/test_interrupt.S @@ -0,0 +1,259 @@ +#include "macros.inc" + +#define LSBIT(v) ((v) & -(v)) + +#define LEVEL_MASK(x) glue3(XCHAL_INTLEVEL, x, _MASK) +#define LEVEL_SOFT_MASK(x) (LEVEL_MASK(x) & XCHAL_INTTYPE_MASK_SOFTWARE) + +#define L1_SOFT_MASK LEVEL_SOFT_MASK(1) +#define L1_SOFT LSBIT(L1_SOFT_MASK) + +#if LEVEL_SOFT_MASK(2) +#define HIGH_LEVEL_SOFT_MASK LEVEL_SOFT_MASK(2) +#elif LEVEL_SOFT_MASK(3) +#define HIGH_LEVEL_SOFT_MASK LEVEL_SOFT_MASK(3) +#elif LEVEL_SOFT_MASK(4) +#define HIGH_LEVEL_SOFT_MASK LEVEL_SOFT_MASK(4) +#elif LEVEL_SOFT_MASK(5) +#define HIGH_LEVEL_SOFT_MASK LEVEL_SOFT_MASK(5) +#elif LEVEL_SOFT_MASK(6) +#define HIGH_LEVEL_SOFT_MASK LEVEL_SOFT_MASK(6) +#else +#define HIGH_LEVEL_SOFT_MASK 0 +#endif + +#define HIGH_LEVEL_SOFT LSBIT(HIGH_LEVEL_SOFT_MASK) + +#if LEVEL_SOFT_MASK(2) +#define HIGH_LEVEL_SOFT_LEVEL 2 +#elif LEVEL_SOFT_MASK(3) +#define HIGH_LEVEL_SOFT_LEVEL 3 +#elif LEVEL_SOFT_MASK(4) +#define HIGH_LEVEL_SOFT_LEVEL 4 +#elif LEVEL_SOFT_MASK(5) +#define HIGH_LEVEL_SOFT_LEVEL 5 +#elif LEVEL_SOFT_MASK(6) +#define HIGH_LEVEL_SOFT_LEVEL 6 +#else +#define HIGH_LEVEL_SOFT_LEVEL 0 +#endif + +test_suite interrupt + +#if XCHAL_HAVE_INTERRUPTS + +.macro clear_interrupts + movi a2, 0 + wsr a2, intenable +#if XCHAL_NUM_TIMERS + wsr a2, ccompare0 +#endif +#if XCHAL_NUM_TIMERS > 1 + wsr a2, ccompare1 +#endif +#if XCHAL_NUM_TIMERS > 2 + wsr a2, ccompare2 +#endif + esync + rsr a2, interrupt + wsr a2, intclear + + esync + rsr a2, interrupt + assert eqi, a2, 0 +.endm + +.macro check_l1 + rsr a2, ps + movi a3, 0x1f /* EXCM | INTMASK */ + and a2, a2, a3 + assert eqi, a2, 0x10 /* only EXCM is set for level-1 interrupt */ + rsr a2, exccause + assert eqi, a2, 4 +.endm + +test rsil + clear_interrupts + + rsr a2, ps + rsil a3, 7 + rsr a4, ps + assert eq, a2, a3 + movi a2, 0xf + and a2, a4, a2 + assert eqi, a2, 7 + xor a3, a3, a4 + movi a2, 0xfffffff0 + and a2, a3, a2 + assert eqi, a2, 0 +test_end + +#if L1_SOFT +test soft_disabled + set_vector kernel, 1f + clear_interrupts + + movi a2, L1_SOFT + wsr a2, intset + esync + rsr a3, interrupt + movi a4, ~XCHAL_INTTYPE_MASK_TIMER + and a3, a3, a4 + assert eq, a2, a3 + wsr a2, intclear + esync + rsr a3, interrupt + and a3, a3, a4 + assert eqi, a3, 0 + j 2f +1: + test_fail +2: +test_end + +test soft_intenable + set_vector kernel, 1f + clear_interrupts + + movi a2, L1_SOFT + wsr a2, intset + esync + rsr a3, interrupt + movi a4, ~XCHAL_INTTYPE_MASK_TIMER + and a3, a3, a4 + assert eq, a2, a3 + rsil a3, 0 + wsr a2, intenable + esync + test_fail +1: + check_l1 +test_end + +test soft_rsil + set_vector kernel, 1f + clear_interrupts + + movi a2, L1_SOFT + wsr a2, intset + esync + rsr a3, interrupt + movi a4, ~XCHAL_INTTYPE_MASK_TIMER + and a3, a3, a4 + assert eq, a2, a3 + wsr a2, intenable + rsil a3, 0 + esync + test_fail +1: + check_l1 +test_end + +test soft_waiti + set_vector kernel, 1f + clear_interrupts + + movi a2, L1_SOFT + wsr a2, intset + esync + rsr a3, interrupt + movi a4, ~XCHAL_INTTYPE_MASK_TIMER + and a3, a3, a4 + assert eq, a2, a3 + wsr a2, intenable + waiti 0 + test_fail +1: + check_l1 +test_end + +test soft_user + set_vector kernel, 1f + set_vector user, 2f + clear_interrupts + + movi a2, L1_SOFT + wsr a2, intset + esync + rsr a3, interrupt + movi a4, ~XCHAL_INTTYPE_MASK_TIMER + and a3, a3, a4 + assert eq, a2, a3 + wsr a2, intenable + + rsr a2, ps + movi a3, 0x20 + or a2, a2, a3 + wsr a2, ps + waiti 0 +1: + test_fail +2: + check_l1 +test_end + +#if HIGH_LEVEL_SOFT +test soft_priority + set_vector kernel, 1f + set_vector glue(level, HIGH_LEVEL_SOFT_LEVEL), 2f + clear_interrupts + + movi a2, L1_SOFT | HIGH_LEVEL_SOFT + wsr a2, intenable + rsil a3, 0 + esync + wsr a2, intset + esync +1: + test_fail +2: + rsr a2, ps + movi a3, 0x1f /* EXCM | INTMASK */ + and a2, a2, a3 + movi a3, 0x10 | HIGH_LEVEL_SOFT_LEVEL + assert eq, a2, a3 /* EXCM and INTMASK are set + for high-priority interrupt */ +test_end +#endif +#endif + +#if HIGH_LEVEL_SOFT +test eps_epc_rfi + set_vector glue(level, HIGH_LEVEL_SOFT_LEVEL), 3f + clear_interrupts + reset_ps + + movi a2, L1_SOFT_MASK | HIGH_LEVEL_SOFT_MASK + wsr a2, intenable + rsil a3, 0 + rsr a3, ps + esync + wsr a2, intset +1: + esync +2: + test_fail +3: + rsr a2, glue(eps, HIGH_LEVEL_SOFT_LEVEL) + assert eq, a2, a3 + rsr a2, glue(epc, HIGH_LEVEL_SOFT_LEVEL) + movi a3, 1b + assert ge, a2, a3 + movi a3, 2b + assert ge, a3, a2 + movi a2, 4f + wsr a2, glue(epc, HIGH_LEVEL_SOFT_LEVEL) + movi a2, 0x40000 | HIGH_LEVEL_SOFT_LEVEL + wsr a2, glue(eps, HIGH_LEVEL_SOFT_LEVEL) + rfi HIGH_LEVEL_SOFT_LEVEL + test_fail +4: + rsr a2, ps + movi a3, 0x40000 | HIGH_LEVEL_SOFT_LEVEL + assert eq, a2, a3 +test_end +#endif + +#endif + +test_suite_end |