From 95faab6f2c0cc232c2b1d3886397c466f0d3b078 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Wed, 22 Mar 2023 02:44:03 +0000 Subject: [PATCH] Add zcmp_irq_kill test --- test/sim/sw_testcases/zcmp_irq_kill.c | 128 ++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) create mode 100644 test/sim/sw_testcases/zcmp_irq_kill.c diff --git a/test/sim/sw_testcases/zcmp_irq_kill.c b/test/sim/sw_testcases/zcmp_irq_kill.c new file mode 100644 index 0000000..2ec6909 --- /dev/null +++ b/test/sim/sw_testcases/zcmp_irq_kill.c @@ -0,0 +1,128 @@ +#include "tb_cxxrtl_io.h" + +// Test intent: check that killing and restarting of push/pop instructions +// due to IRQs does not cause stack corruption + +volatile uint32_t results[13]; + +void foreground_task() { + asm volatile ( + // First push is an actual save of the registers + ".hword 0xb8f6\n" // cm.push {ra,s0-s11},-80 + "sw a0, 0(sp)\n" + "sw a1, 4(sp)\n" + "li a1, 13 * 100\n" + "li x1, 0xa5000000 + 1\n" + "li x8, 0xa5000000 + 8\n" + "li x9, 0xa5000000 + 9\n" + "li x18, 0xa5000000 + 18\n" + "li x19, 0xa5000000 + 19\n" + "li x20, 0xa5000000 + 20\n" + "li x21, 0xa5000000 + 21\n" + "li x22, 0xa5000000 + 22\n" + "li x23, 0xa5000000 + 23\n" + "li x24, 0xa5000000 + 24\n" + "li x25, 0xa5000000 + 25\n" + "li x26, 0xa5000000 + 26\n" + "li x27, 0xa5000000 + 27\n" + "1:\n" + ".hword 0xb8f2\n" // cm.push {ra,s0-s11},-64 + // Rotate the contents of the stack frame + "lw s0, 12(sp)\n" + "lw s1, 16(sp)\n" + "lw s2, 20(sp)\n" + "lw s3, 24(sp)\n" + "lw s4, 28(sp)\n" + "lw s5, 32(sp)\n" + "lw s6, 36(sp)\n" + "lw s7, 40(sp)\n" + "lw s8, 44(sp)\n" + "lw s9, 48(sp)\n" + "lw s10, 52(sp)\n" + "lw s11, 56(sp)\n" + "lw a0, 60(sp)\n" + + "lw a0, 12(sp)\n" + "lw s0, 16(sp)\n" + "lw s1, 20(sp)\n" + "lw s2, 24(sp)\n" + "lw s3, 28(sp)\n" + "lw s4, 32(sp)\n" + "lw s5, 36(sp)\n" + "lw s6, 40(sp)\n" + "lw s7, 44(sp)\n" + "lw s8, 48(sp)\n" + "lw s9, 52(sp)\n" + "lw s10, 56(sp)\n" + "lw s11, 60(sp)\n" + // Re-pop. Doing this a multiple of 13 times will restore the original contents. + ".hword 0xbaf2\n" // cm.pop {ra, s0-s11},64 + "addi a1, a1, -1\n" + "bnez a1, 1b\n" + // Write out results + "la a1, results\n" + "sw x1, 4*0(a1)\n" + "sw x8, 4*1(a1)\n" + "sw x9, 4*2(a1)\n" + "sw x18, 4*3(a1)\n" + "sw x19, 4*4(a1)\n" + "sw x20, 4*5(a1)\n" + "sw x21, 4*6(a1)\n" + "sw x22, 4*7(a1)\n" + "sw x23, 4*8(a1)\n" + "sw x24, 4*9(a1)\n" + "sw x25, 4*10(a1)\n" + "sw x26, 4*11(a1)\n" + "sw x27, 4*12(a1)\n" + // Restore original register values + "lw a0, 0(sp)\n" + "lw a1, 4(sp)\n" + ".hword 0xbaf6\n" // cm.pop {ra,s0-s11},80 + ); +} + +// Note not using attribute interrupt due to stack corruption bug in current +// CORE-V toolchain +void __attribute__((naked)) isr_machine_timer() { + asm volatile ( + ".hword 0xb852\n" // cm.push {ra,s0},-16 + "li ra, %0\n" + "lw s0, (ra)\n" + "addi s0, s0, 421\n" // Prime number + "sw s0, (ra)\n" + ".hword 0xba52\n" // cm.pop {ra,s0},16 + "mret\n" + : : "i" ((uintptr_t)&mm_timer->mtimecmp) + ); +} + +int main() { + asm volatile ("csrw mie, %0" : : "r" (0x80)); + mm_timer->mtime = 0; + // Will take first timer interrupt immediately: + asm volatile ("csrsi mstatus, 0x8"); + + foreground_task(); + for (int i = 0; i < 13; ++i) { + tb_put_u32(results[i]); + } + return 0; +} + +/*EXPECTED-OUTPUT*************************************************************** + +a5000001 +a5000008 +a5000009 +a5000012 +a5000013 +a5000014 +a5000015 +a5000016 +a5000017 +a5000018 +a5000019 +a500001a +a500001b + +*******************************************************************************/