From 5ab60422ad8978d760709187695504ea7bd9e89c Mon Sep 17 00:00:00 2001 From: Luke Wren Date: Fri, 17 Dec 2021 01:24:11 +0000 Subject: [PATCH] Add minimal multicore launch code --- test/sim/common/init.S | 24 ++++++++++++++++++++++-- test/sim/common/tb_cxxrtl_io.h | 12 ++++++------ test/sim/hello_multicore/Makefile | 5 +++++ test/sim/hello_multicore/main.c | 23 +++++++++++++++++++++++ test/sim/sw_testcases/soft_irq.c | 20 ++++++++++---------- test/sim/tb_cxxrtl/tb.cpp | 6 +++--- test/sim/tb_cxxrtl/tb.v | 4 ++-- test/sim/tb_cxxrtl/tb_multicore.v | 6 +++--- 8 files changed, 74 insertions(+), 26 deletions(-) create mode 100644 test/sim/hello_multicore/Makefile create mode 100644 test/sim/hello_multicore/main.c diff --git a/test/sim/common/init.S b/test/sim/common/init.S index 3e3b7ec..96418d7 100644 --- a/test/sim/common/init.S +++ b/test/sim/common/init.S @@ -62,8 +62,12 @@ j \name .p2align 2 1: // Set up trap vector table. mtvec LSB enables vectoring - la t0, .vector_table + 1 - csrw mtvec, t0 + la a0, .vector_table + 1 + csrw mtvec, a0 + + // Put spare cores to sleep before setting up core 0 stack + csrr a0, mhartid + bnez a0, .core1_wait // Set up stack pointer before doing anything else la sp, __stack_top @@ -78,6 +82,22 @@ j \name jal _start j .halt +.core1_wait: + // IRQs disabled, but soft IRQ unmasked -> soft IRQ will exit WFI. + csrci mstatus, 0x8 + csrw mie, 0x8 +.core1_wait_loop: + wfi + la a0, core1_entry_vector + lw a0, (a0) + beqz a0, .core1_wait_loop + la sp, __stack_top - 0x10000 + jalr a0 +.p2align 2 +.global core1_entry_vector +core1_entry_vector: + .word 0 + .global _exit _exit: li a1, IO_EXIT diff --git a/test/sim/common/tb_cxxrtl_io.h b/test/sim/common/tb_cxxrtl_io.h index e26c248..2a1eadb 100644 --- a/test/sim/common/tb_cxxrtl_io.h +++ b/test/sim/common/tb_cxxrtl_io.h @@ -71,16 +71,16 @@ static inline void tb_printf(const char *fmt, ...) { #define tb_assert(cond, ...) if (!(cond)) {tb_printf(__VA_ARGS__); tb_exit(-1);} -static inline void tb_set_softirq() { - mm_io->set_softirq = 1; +static inline void tb_set_softirq(int idx) { + mm_io->set_softirq = 1u << idx; } -static inline void tb_clr_softirq() { - mm_io->clr_softirq = 1; +static inline void tb_clr_softirq(int idx) { + mm_io->clr_softirq = 1u << idx; } -static inline bool tb_get_softirq() { - return (bool)mm_io->set_softirq; +static inline bool tb_get_softirq(int idx) { + return (bool)(mm_io->set_softirq & (1u << idx)); } static inline void tb_set_irq_masked(uint32_t mask) { diff --git a/test/sim/hello_multicore/Makefile b/test/sim/hello_multicore/Makefile new file mode 100644 index 0000000..e9440d7 --- /dev/null +++ b/test/sim/hello_multicore/Makefile @@ -0,0 +1,5 @@ +SRCS := ../common/init.S main.c +APP := hello_multicore +CCFLAGS = -march=rv32imc -Os + +include ../common/src_only_app.mk diff --git a/test/sim/hello_multicore/main.c b/test/sim/hello_multicore/main.c new file mode 100644 index 0000000..ccd8ca9 --- /dev/null +++ b/test/sim/hello_multicore/main.c @@ -0,0 +1,23 @@ +#include "tb_cxxrtl_io.h" + +extern volatile uintptr_t core1_entry_vector; + +void launch_core1(void (*entry)(void)) { + core1_entry_vector = (uintptr_t)entry; + tb_set_softirq(1); +} + +void core1_main() { + tb_clr_softirq(1); + tb_puts("Hello world from core 1\n"); + tb_exit(0); +} + +int main() { + tb_puts("Hello world from core 0!\n"); + launch_core1(core1_main); + asm volatile ( + "1: wfi\n" + " j 1b\n" + ); +} diff --git a/test/sim/sw_testcases/soft_irq.c b/test/sim/sw_testcases/soft_irq.c index bd1cd16..cd55dc0 100644 --- a/test/sim/sw_testcases/soft_irq.c +++ b/test/sim/sw_testcases/soft_irq.c @@ -23,12 +23,12 @@ int main() { tb_assert(!(read_csr(mip) & mip_msip), "mip.msip should be clear at start of test\n"); tb_puts("Dry run\n"); - tb_set_softirq(); - tb_assert(tb_get_softirq(), "Failed to set soft_irq through tb\n"); + tb_set_softirq(0); + tb_assert(tb_get_softirq(0), "Failed to set soft_irq through tb\n"); tb_assert(read_csr(mip) & mip_msip, "soft_irq not reflected in mip\n"); - tb_clr_softirq(); - tb_assert(!tb_get_softirq(), "Failed to clear soft_irq through tb\n"); + tb_clr_softirq(0); + tb_assert(!tb_get_softirq(0), "Failed to clear soft_irq through tb\n"); tb_assert(!(read_csr(mip) & mip_msip), "soft_irq clear not reflected in mip\n"); tb_puts("Set mie only\n"); @@ -37,18 +37,18 @@ int main() { // IRQ should not fire yet. tb_puts("Then set IRQ\n"); - tb_set_softirq(); + tb_set_softirq(0); tb_assert(!(read_csr(mip) & mip_msip), "soft_irq should have been cleared by IRQ\n"); tb_puts("Returned from IRQ\n"); tb_puts("Clear mie, do another dry run\n"); write_csr(mie, 0); - tb_set_softirq(); - tb_assert(tb_get_softirq(), "Failed to set soft_irq through tb\n"); + tb_set_softirq(0); + tb_assert(tb_get_softirq(0), "Failed to set soft_irq through tb\n"); tb_assert(read_csr(mip) & mip_msip, "soft_irq not reflected in mip\n"); - tb_clr_softirq(); - tb_assert(!tb_get_softirq(), "Failed to clear soft_irq through tb\n"); + tb_clr_softirq(0); + tb_assert(!tb_get_softirq(0), "Failed to clear soft_irq through tb\n"); tb_assert(!(read_csr(mip) & mip_msip), "soft_irq clear not reflected in mip\n"); return 0; @@ -58,7 +58,7 @@ void __attribute__((interrupt)) isr_machine_softirq() { tb_puts("-> handle_soft_irq\n"); tb_printf("mip = %08x\n", read_csr(mip)); tb_printf("mie = %08x\n", read_csr(mie)); - tb_clr_softirq(); + tb_clr_softirq(0); tb_printf("mcause = %08x\n", read_csr(mcause)); tb_printf("mstatus = %08x\n", read_csr(mstatus)); } diff --git a/test/sim/tb_cxxrtl/tb.cpp b/test/sim/tb_cxxrtl/tb.cpp index bff9819..650dafb 100644 --- a/test/sim/tb_cxxrtl/tb.cpp +++ b/test/sim/tb_cxxrtl/tb.cpp @@ -106,10 +106,10 @@ bus_response mem_access(cxxrtl_design::p_tb &tb, mem_io_state &memio, bus_reques } } else if (req.addr == IO_BASE + IO_SET_SOFTIRQ) { - tb.p_soft__irq.set(true); + tb.p_soft__irq.set(tb.p_soft__irq.get() | req.wdata); } else if (req.addr == IO_BASE + IO_CLR_SOFTIRQ) { - tb.p_soft__irq.set(false); + tb.p_soft__irq.set(tb.p_soft__irq.get() & ~req.wdata); } else if (req.addr == IO_BASE + IO_SET_IRQ) { tb.p_irq.set(tb.p_irq.get() | req.wdata); @@ -143,7 +143,7 @@ bus_response mem_access(cxxrtl_design::p_tb &tb, mem_io_state &memio, bus_reques memio.mem[req.addr + 3] << 24; } else if (req.addr == IO_BASE + IO_SET_SOFTIRQ || req.addr == IO_BASE + IO_CLR_SOFTIRQ) { - resp.rdata = tb.p_soft__irq.get(); + resp.rdata = tb.p_soft__irq.get(); } else if (req.addr == IO_BASE + IO_SET_IRQ || req.addr == IO_BASE + IO_CLR_IRQ) { resp.rdata = tb.p_irq.get(); diff --git a/test/sim/tb_cxxrtl/tb.v b/test/sim/tb_cxxrtl/tb.v index c50af30..39d35d0 100644 --- a/test/sim/tb_cxxrtl/tb.v +++ b/test/sim/tb_cxxrtl/tb.v @@ -49,7 +49,7 @@ module tb #( // Level-sensitive interrupt sources input wire [NUM_IRQ-1:0] irq, // -> mip.meip - input wire soft_irq, // -> mip.msip + input wire [1:0] soft_irq, // -> mip.msip input wire timer_irq // -> mip.mtip ); @@ -231,7 +231,7 @@ hazard3_cpu_2port #( .dbg_instr_caught_ebreak (hart_instr_caught_ebreak), .irq (irq), - .soft_irq (soft_irq), + .soft_irq (soft_irq[0]), .timer_irq (timer_irq) ); diff --git a/test/sim/tb_cxxrtl/tb_multicore.v b/test/sim/tb_cxxrtl/tb_multicore.v index 01ebbd5..a599712 100644 --- a/test/sim/tb_cxxrtl/tb_multicore.v +++ b/test/sim/tb_cxxrtl/tb_multicore.v @@ -49,7 +49,7 @@ module tb #( // Level-sensitive interrupt sources input wire [NUM_IRQ-1:0] irq, // -> mip.meip - input wire soft_irq, // -> mip.msip + input wire [1:0] soft_irq, // -> mip.msip input wire timer_irq // -> mip.mtip ); @@ -249,7 +249,7 @@ hazard3_cpu_1port #( .dbg_instr_caught_ebreak (hart_instr_caught_ebreak [0]), .irq (irq), - .soft_irq (soft_irq), + .soft_irq (soft_irq[0]), .timer_irq (timer_irq) ); @@ -313,7 +313,7 @@ hazard3_cpu_1port #( .dbg_instr_caught_ebreak (hart_instr_caught_ebreak [1]), .irq (irq), - .soft_irq (soft_irq), + .soft_irq (soft_irq[1]), .timer_irq (timer_irq) );