From c03bc2efb56dc1136fdacd64c1f98fb25e9a86e7 Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Fri, 4 Jun 2021 08:16:54 +0100 Subject: [PATCH] Update init.S for new IRQ functionality --- test/sim/common/hazard3_csr.h | 9 ++ test/sim/common/init.S | 135 ++++++++++++++++-- test/sim/common/tb_cxxrtl_io.h | 15 ++ .../sim/coremark/dist/barebones/hazard3_csr.h | 1 + test/sim/ecall_simple/main.c | 6 +- test/sim/hellow/Makefile | 2 +- 6 files changed, 158 insertions(+), 10 deletions(-) create mode 100644 test/sim/common/hazard3_csr.h create mode 120000 test/sim/coremark/dist/barebones/hazard3_csr.h diff --git a/test/sim/common/hazard3_csr.h b/test/sim/common/hazard3_csr.h new file mode 100644 index 0000000..3d343a4 --- /dev/null +++ b/test/sim/common/hazard3_csr.h @@ -0,0 +1,9 @@ +#ifndef _HAZARD3_CSR_H +#define _HAZARD3_CSR_H + +#define hazard3_csr_midcr 0xbc0 +#define hazard3_csr_meie0 0xbe0 // External interrupt enable IRQ0 -> 31 +#define hazard3_csr_meip0 0xfe0 // External interrupt pending IRQ0 -> 31 +#define hazard3_csr_mlei 0xfe4 // Lowest external interrupt (pending & enabled) + +#endif diff --git a/test/sim/common/init.S b/test/sim/common/init.S index c93d3c6..aaf3986 100644 --- a/test/sim/common/init.S +++ b/test/sim/common/init.S @@ -1,4 +1,4 @@ -#define COLLAPSE_WEAK_HANDLERS +#include "hazard3_csr.h" #define IO_BASE 0x80000000 #define IO_PRINT_CHAR (IO_BASE + 0x0) @@ -11,7 +11,6 @@ .option push .option norelax -.option norvc .section .vectors @@ -44,13 +43,18 @@ j \name VEC .halt VEC .halt VEC .halt - VEC .halt + VEC isr_external_irq VEC .halt VEC .halt VEC .halt VEC .halt -// External interrupts, if vectoring is enabled +// When midcr.eivect is 1, hardware vectors IRQs directly to the +// platform-specific part of the vector table. Otherwise, software indexes +// this table in the prologue of a shared external IRQ handler. + +.p2align 2 +platform_vectors: VEC isr_irq0 VEC isr_irq1 @@ -68,6 +72,22 @@ j \name VEC isr_irq13 VEC isr_irq14 VEC isr_irq15 + VEC isr_irq16 + VEC isr_irq17 + VEC isr_irq18 + VEC isr_irq19 + VEC isr_irq20 + VEC isr_irq21 + VEC isr_irq22 + VEC isr_irq23 + VEC isr_irq24 + VEC isr_irq25 + VEC isr_irq26 + VEC isr_irq27 + VEC isr_irq28 + VEC isr_irq29 + VEC isr_irq30 + VEC isr_irq31 // ---------------------------------------------------------------------------- @@ -76,9 +96,8 @@ j \name .reset_handler: la sp, __stack_top - la t0, .vector_table - // Set mtvec LSB to enable vectoring - ori t0, t0, 1 + // mtvec LSB enables vectoring + la t0, .vector_table + 1 csrw mtvec, t0 // newlib _start expects argc, argv on the stack. Leave stack 16-byte aligned. @@ -115,6 +134,91 @@ heap_ptr: progname: .asciz "hazard5-testbench" +// ---------------------------------------------------------------------------- +// Soft external IRQ dispatch + +// Vector isr_external_irq to the relevant ISR, based on mcause. The ISR can +// be a standard C-ABI function. This method also leaves the possibility of +// using addresses in the IRQ vector table, rather than jump instructions. + +.global isr_external_irq +.weak isr_external_irq +isr_external_irq: + // Save all caller-saves, plus three callee saves for CSR saving + addi sp, sp, -80 + sw ra, 0(sp) + sw t0, 4(sp) + sw t1, 8(sp) + sw t2, 12(sp) + sw t3, 16(sp) + sw t4, 20(sp) + sw t5, 24(sp) + sw t6, 28(sp) + sw a0, 32(sp) + sw a1, 36(sp) + sw a2, 40(sp) + sw a3, 44(sp) + sw a4, 48(sp) + sw a5, 52(sp) + sw a6, 56(sp) + sw a7, 60(sp) + sw s0, 64(sp) + sw s1, 68(sp) + sw s2, 72(sp) + + // Save exception state to callee-saves so we can use it for return + csrr s0, mepc + csrr s1, mstatus + csrr s2, hazard3_csr_meie0 + + // Calculate IRQ entry point + csrr a0, mcause + slli a0, a0, 2 + csrr a1, mtvec + andi a1, a1, -4 + add a1, a1, a0 + + // Mask off higher-numbered IRQs (and this IRQ), then re-enable IRQs so we + // can be preempted. Could have some other priority scheme here. + srli a0, a0, 2 + addi a0, a0, -16 + li a2, -1 + sll a2, a2, a0 + csrc hazard3_csr_meie0, a2 + csrsi mstatus, 8 + + // Enter IRQ + jalr a1 +trap_return: + // No more preemption until we mret. + csrci mstatus, 8 + + csrw mepc, s0 + csrw mstatus, s1 + csrw hazard3_csr_meie0, s2 + lw ra, 0(sp) + lw t0, 4(sp) + lw t1, 8(sp) + lw t2, 12(sp) + lw t3, 16(sp) + lw t4, 20(sp) + lw t5, 24(sp) + lw t6, 28(sp) + lw a0, 32(sp) + lw a1, 36(sp) + lw a2, 40(sp) + lw a3, 44(sp) + lw a4, 48(sp) + lw a5, 52(sp) + lw a6, 56(sp) + lw a7, 60(sp) + lw s0, 64(sp) + lw s1, 68(sp) + lw s2, 72(sp) + addi sp, sp, 80 + mret + + // ---------------------------------------------------------------------------- // Weak handler/ISR symbols @@ -186,7 +290,6 @@ _str_sp: .asciz "sp: " .macro weak_handler name:req .p2align 2 .global \name -.type \name,%function .weak \name \name: la x31, _str_\name @@ -214,6 +317,22 @@ weak_handler isr_irq12 weak_handler isr_irq13 weak_handler isr_irq14 weak_handler isr_irq15 +weak_handler isr_irq16 +weak_handler isr_irq17 +weak_handler isr_irq18 +weak_handler isr_irq19 +weak_handler isr_irq20 +weak_handler isr_irq21 +weak_handler isr_irq22 +weak_handler isr_irq23 +weak_handler isr_irq24 +weak_handler isr_irq25 +weak_handler isr_irq26 +weak_handler isr_irq27 +weak_handler isr_irq28 +weak_handler isr_irq29 +weak_handler isr_irq30 +weak_handler isr_irq31 // You can relax now .option pop diff --git a/test/sim/common/tb_cxxrtl_io.h b/test/sim/common/tb_cxxrtl_io.h index 70f199d..52aec86 100644 --- a/test/sim/common/tb_cxxrtl_io.h +++ b/test/sim/common/tb_cxxrtl_io.h @@ -1,7 +1,9 @@ #ifndef _TB_CXXRTL_IO_H #define _TB_CXXRTL_IO_H +#include #include +#include #define IO_BASE 0x80000000 @@ -30,4 +32,17 @@ static inline void tb_exit(uint32_t ret) { mm_io->exit = ret; } +#ifndef PRINTF_BUF_SIZE +#define PRINTF_BUF_SIZE 256 +#endif + +static inline void tb_printf(const char *fmt, ...) { + char buf[PRINTF_BUF_SIZE]; + va_list args; + va_start(args, fmt); + vsnprintf(buf, PRINTF_BUF_SIZE, fmt, args); + tb_puts(buf); + va_end(args); +} + #endif diff --git a/test/sim/coremark/dist/barebones/hazard3_csr.h b/test/sim/coremark/dist/barebones/hazard3_csr.h new file mode 120000 index 0000000..dcec24c --- /dev/null +++ b/test/sim/coremark/dist/barebones/hazard3_csr.h @@ -0,0 +1 @@ +../../../common/hazard3_csr.h \ No newline at end of file diff --git a/test/sim/ecall_simple/main.c b/test/sim/ecall_simple/main.c index 8a20958..d1ce642 100644 --- a/test/sim/ecall_simple/main.c +++ b/test/sim/ecall_simple/main.c @@ -11,7 +11,7 @@ #define write_csr(csrname, val) __asm__ ("csrw " #csrname ", %0" : : "r" (val)) -void __attribute__((interrupt)) handle_ecall() { +void __attribute__((interrupt)) handle_exception() { uint32_t call_num; asm volatile ("mv %0, a7" : "=r" (call_num)); tb_puts("Handling ecall. Call number:\n"); @@ -30,8 +30,12 @@ const uint32_t call_nums[] = { }; void main() { + tb_puts("mcause initial value:\n"); + tb_put_u32(read_csr(mcause)); for (int i = 0; i < sizeof(call_nums) / sizeof(*call_nums); ++i) make_ecall(call_nums[i]); tb_puts("Finished making calls.\n"); + tb_puts("mcause final value:\n"); + tb_put_u32(read_csr(mcause)); tb_exit(0); } diff --git a/test/sim/hellow/Makefile b/test/sim/hellow/Makefile index 412a6e7..e5b4219 100644 --- a/test/sim/hellow/Makefile +++ b/test/sim/hellow/Makefile @@ -1,5 +1,5 @@ SRCS := ../common/init.S main.c APP := hellow -CCFLAGS = -march=rv32ic +CCFLAGS = -march=rv32imc -Os include ../common/src_only_app.mk