diff --git a/bsp/qemu-riscv-virt64/driver/Kconfig b/bsp/qemu-riscv-virt64/driver/Kconfig index d6fca695ef422f2f45481ff9fcf86ae0f57bca5c..3b5b6671f492cc89b0171f95be98056a6acd5568 100644 --- a/bsp/qemu-riscv-virt64/driver/Kconfig +++ b/bsp/qemu-riscv-virt64/driver/Kconfig @@ -1,21 +1,7 @@ - - -menu "RISCV qemu virt64 configs" - -menuconfig BSP_USING_UART1 - bool "Enable UART1" - default n - if BSP_USING_UART1 - config BSP_UART1_TXD_PIN - int "uart1 TXD pin number" - default 20 - config BSP_UART1_RXD_PIN - int "uart1 RXD pin number" - default 21 - endif +menu "RISC-V QEMU virt64 configs" config RISCV_S_MODE - bool "RT-Thread run in riscv smode" + bool "RT-Thread run in RISC-V S-Mode(supervisor mode)" default y endmenu diff --git a/bsp/qemu-riscv-virt64/driver/board.c b/bsp/qemu-riscv-virt64/driver/board.c index 91e8f25982bb7b1a88bb0437026cbd56d198c23c..c1e68090c687b3defcc6895f73264527539a03d3 100644 --- a/bsp/qemu-riscv-virt64/driver/board.c +++ b/bsp/qemu-riscv-virt64/driver/board.c @@ -67,4 +67,3 @@ void rt_hw_cpu_reset(void) while(1); } MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reset machine); - diff --git a/bsp/qemu-riscv-virt64/driver/plic.c b/bsp/qemu-riscv-virt64/driver/plic.c index 6e2ec5e84e7729c414389fa0d25ef9967713d757..6e1d1d750447f32547ef9d7673a8f6aeed55cbbf 100644 --- a/bsp/qemu-riscv-virt64/driver/plic.c +++ b/bsp/qemu-riscv-virt64/driver/plic.c @@ -35,7 +35,7 @@ void plic_set_priority(int irq, int priority) */ void plic_irq_enable(int irq) { - int hart = r_mhartid(); + int hart = __raw_hartid(); *(uint32_t*)PLIC_ENABLE(hart) = ((*(uint32_t*)PLIC_ENABLE(hart)) | (1 << irq)); #ifdef RISCV_S_MODE set_csr(sie, read_csr(sie) | MIP_SEIP); @@ -46,7 +46,7 @@ void plic_irq_enable(int irq) void plic_irq_disable(int irq) { - int hart = r_mhartid(); + int hart = __raw_hartid(); *(uint32_t*)PLIC_ENABLE(hart) = (((*(uint32_t*)PLIC_ENABLE(hart)) & (~(1 << irq)))); } @@ -59,7 +59,7 @@ void plic_irq_disable(int irq) */ void plic_set_threshold(int threshold) { - int hart = r_mhartid(); + int hart = __raw_hartid(); *(uint32_t*)PLIC_THRESHOLD(hart) = threshold; } @@ -77,7 +77,7 @@ void plic_set_threshold(int threshold) */ int plic_claim(void) { - int hart = r_mhartid(); + int hart = __raw_hartid(); int irq = *(uint32_t*)PLIC_CLAIM(hart); return irq; } @@ -94,6 +94,6 @@ int plic_claim(void) */ void plic_complete(int irq) { - int hart = r_mhartid(); + int hart = __raw_hartid(); *(uint32_t*)PLIC_COMPLETE(hart) = irq; } diff --git a/bsp/qemu-riscv-virt64/driver/plic.h b/bsp/qemu-riscv-virt64/driver/plic.h index 5d0fea6eb22956c296ee499f7b74195d6c0ad4ff..3557079c10f9ffca170130e268a41727d820ca21 100644 --- a/bsp/qemu-riscv-virt64/driver/plic.h +++ b/bsp/qemu-riscv-virt64/driver/plic.h @@ -6,48 +6,53 @@ * Change Logs: * Date Author Notes * 2021-05-20 bigmagic first version + * 2021-10-20 bernard fix s-mode issue */ #ifndef PLIC_H #define PLIC_H #include + /* * This machine puts platform-level interrupt controller (PLIC) here. * Here only list PLIC registers in Machine mode. * */ -#define VIRT_PLIC_BASE 0x0c000000L +#define VIRT_PLIC_BASE 0x0c000000L + +#define PLIC_PRIORITY_OFFSET (0x0) +#define PLIC_PENDING_OFFSET (0x1000) -#define PLIC_PRIORITY_OFFSET (0x0) -#define PLIC_PENDING_OFFSET (0x1000) +#define PLIC_ENABLE_STRIDE 0x80 +#define PLIC_CONTEXT_STRIDE 0x1000 #ifndef RISCV_S_MODE -#define PLIC_MENABLE_OFFSET (0x2000) -#define PLIC_MTHRESHOLD_OFFSET (0x200000) -#define PLIC_MCLAIM_OFFSET (0x200004) -#define PLIC_MCOMPLETE_OFFSET (0x200004) +#define PLIC_MENABLE_OFFSET (0x2000) +#define PLIC_MTHRESHOLD_OFFSET (0x200000) +#define PLIC_MCLAIM_OFFSET (0x200004) +#define PLIC_MCOMPLETE_OFFSET (0x200004) -#define PLIC_ENABLE(hart) (VIRT_PLIC_BASE + PLIC_MENABLE_OFFSET + (hart) * 0x80) -#define PLIC_THRESHOLD(hart) (VIRT_PLIC_BASE + PLIC_MTHRESHOLD_OFFSET + (hart) * 0x1000) -#define PLIC_CLAIM(hart) (VIRT_PLIC_BASE + PLIC_MCLAIM_OFFSET + (hart) * 0x1000) -#define PLIC_COMPLETE(hart) (VIRT_PLIC_BASE + PLIC_MCOMPLETE_OFFSET + (hart) * 0x1000) +#define PLIC_ENABLE(hart) (VIRT_PLIC_BASE + PLIC_MENABLE_OFFSET + (hart * 2) * PLIC_ENABLE_STRIDE) +#define PLIC_THRESHOLD(hart) (VIRT_PLIC_BASE + PLIC_MTHRESHOLD_OFFSET + (hart * 2) * PLIC_CONTEXT_STRIDE) +#define PLIC_CLAIM(hart) (VIRT_PLIC_BASE + PLIC_MCLAIM_OFFSET + (hart * 2) * PLIC_CONTEXT_STRIDE) +#define PLIC_COMPLETE(hart) (VIRT_PLIC_BASE + PLIC_MCOMPLETE_OFFSET + (hart * 2) * PLIC_CONTEXT_STRIDE) #else -#define PLIC_SENABLE_OFFSET (0x2080) -#define PLIC_STHRESHOLD_OFFSET (0x201000) -#define PLIC_SCLAIM_OFFSET (0x201004) -#define PLIC_SCOMPLETE_OFFSET (0x201004) - -#define PLIC_ENABLE(hart) (VIRT_PLIC_BASE + PLIC_SENABLE_OFFSET + (hart) * 0x80) -#define PLIC_THRESHOLD(hart) (VIRT_PLIC_BASE + PLIC_STHRESHOLD_OFFSET + (hart) * 0x1000) -#define PLIC_CLAIM(hart) (VIRT_PLIC_BASE + PLIC_SCLAIM_OFFSET + (hart) * 0x1000) -#define PLIC_COMPLETE(hart) (VIRT_PLIC_BASE + PLIC_SCOMPLETE_OFFSET + (hart) * 0x1000) +#define PLIC_SENABLE_OFFSET (0x2000 + PLIC_ENABLE_STRIDE) +#define PLIC_STHRESHOLD_OFFSET (0x200000 + PLIC_CONTEXT_STRIDE) +#define PLIC_SCLAIM_OFFSET (0x200004 + PLIC_CONTEXT_STRIDE) +#define PLIC_SCOMPLETE_OFFSET (0x200004 + PLIC_CONTEXT_STRIDE) + +#define PLIC_ENABLE(hart) (VIRT_PLIC_BASE + PLIC_SENABLE_OFFSET + (hart * 2) * PLIC_ENABLE_STRIDE) +#define PLIC_THRESHOLD(hart) (VIRT_PLIC_BASE + PLIC_STHRESHOLD_OFFSET + (hart * 2) * PLIC_CONTEXT_STRIDE) +#define PLIC_CLAIM(hart) (VIRT_PLIC_BASE + PLIC_SCLAIM_OFFSET + (hart * 2) * PLIC_CONTEXT_STRIDE) +#define PLIC_COMPLETE(hart) (VIRT_PLIC_BASE + PLIC_SCOMPLETE_OFFSET + (hart * 2) * PLIC_CONTEXT_STRIDE) #endif -#define PLIC_PRIORITY(id) (VIRT_PLIC_BASE + PLIC_PRIORITY_OFFSET + (id) * 4) -#define PLIC_PENDING(id) (VIRT_PLIC_BASE + PLIC_PENDING_OFFSET + ((id) / 32)) +#define PLIC_PRIORITY(id) (VIRT_PLIC_BASE + PLIC_PRIORITY_OFFSET + (id) * 4) +#define PLIC_PENDING(id) (VIRT_PLIC_BASE + PLIC_PENDING_OFFSET + ((id) / 32)) void plic_set_priority(int irq, int priority); void plic_irq_enable(int irq); diff --git a/libcpu/risc-v/virt64/interrupt.c b/libcpu/risc-v/virt64/interrupt.c index eae0a55c966d311f0a757dd3cb6c213e63d3604d..f2869fc441a18af8428de1da93477a9d13080bc1 100644 --- a/libcpu/risc-v/virt64/interrupt.c +++ b/libcpu/risc-v/virt64/interrupt.c @@ -14,7 +14,6 @@ #include "riscv.h" #include "interrupt.h" -#define CPU_NUM 2 #define MAX_HANDLERS 128 static struct rt_irq_desc irq_desc[MAX_HANDLERS]; @@ -60,7 +59,6 @@ void rt_hw_interrupt_init(void) /* init exceptions table */ for (idx = 0; idx < MAX_HANDLERS; idx++) { - //rt_hw_interrupt_mask(idx); irq_desc[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle; irq_desc[idx].param = RT_NULL; #ifdef RT_USING_INTERRUPT_INFO @@ -68,6 +66,8 @@ void rt_hw_interrupt_init(void) irq_desc[idx].counter = 0; #endif } + + plic_set_threshold(0); } /** @@ -86,7 +86,7 @@ void rt_hw_interrupt_mask(int vector) void rt_hw_interrupt_umask(int vector) { plic_set_priority(vector, 1); - plic_set_threshold(0); + rt_hw_plic_irq_enable(vector); } @@ -182,6 +182,7 @@ void handle_trap(rt_size_t xcause,rt_size_t xtval,rt_size_t xepc,struct rt_hw_st { int cause = (xcause & 0xFFFFFFFF); int plic_irq = 0; + if (xcause & (1UL << 63)) { switch (cause) @@ -197,11 +198,13 @@ void handle_trap(rt_size_t xcause,rt_size_t xtval,rt_size_t xepc,struct rt_hw_st case IRQ_S_TIMER: tick_isr(); break; + case IRQ_S_EXT: plic_irq = plic_claim(); plic_complete(plic_irq); irq_desc[plic_irq].handler(plic_irq, irq_desc[plic_irq].param); break; + case IRQ_M_EXT: plic_irq = plic_claim(); plic_complete(plic_irq); diff --git a/libcpu/risc-v/virt64/riscv_io.h b/libcpu/risc-v/virt64/riscv_io.h index 391d7f5a41d50fa4dfde4788c77269a8243660d8..7dcc98f70a66d9e3f1c03a614bb9d996a045f7eb 100644 --- a/libcpu/risc-v/virt64/riscv_io.h +++ b/libcpu/risc-v/virt64/riscv_io.h @@ -10,15 +10,15 @@ #ifndef __RISCV_IO_H__ #define __RISCV_IO_H__ -// which hart (core) is this? -static inline uint32_t r_mhartid() +static inline uint32_t __raw_hartid(void) { -#ifndef RISCV_S_MODE +#ifdef RISCV_S_MODE + extern int boot_hartid; + return boot_hartid; +#else uint32_t x; asm volatile("csrr %0, mhartid" : "=r" (x) ); return x; -#else - return 0; #endif } diff --git a/libcpu/risc-v/virt64/startup_gcc.S b/libcpu/risc-v/virt64/startup_gcc.S index ac980f6ed22df59ade9a0c15e35737abd67584e8..98fdc1d15b7827ba13b436a1e5c1cef12aae8813 100644 --- a/libcpu/risc-v/virt64/startup_gcc.S +++ b/libcpu/risc-v/virt64/startup_gcc.S @@ -14,10 +14,18 @@ #define XSTATUS_PUM (1 << 18) #include +boot_hartid: .int + .global boot_hartid + .global _start .section ".start", "ax" _start: -#ifndef RISCV_S_MODE +#ifdef RISCV_S_MODE + # save hartid + la t0, boot_hartid # global varible rt_boot_hartid + mv t1, a0 # get hartid in S-mode frome a0 register + sw t1, (t0) # store t1 register low 4 bits in memory address which is stored in t0 +#else # setup stacks per hart csrr t0, mhartid # read current hart id slli t0, t0, 10 # shift left the hart id by 1024 @@ -54,4 +62,4 @@ _start: park: wfi - j park \ No newline at end of file + j park diff --git a/libcpu/risc-v/virt64/tick.c b/libcpu/risc-v/virt64/tick.c index d6970ec41765bd4bd8b12dad4b8545b81e794fe0..53f555da9dfad5684362f830d2832164b86bf6f0 100644 --- a/libcpu/risc-v/virt64/tick.c +++ b/libcpu/risc-v/virt64/tick.c @@ -36,7 +36,7 @@ int tick_isr(void) #ifdef RISCV_S_MODE sbi_set_timer(get_ticks() + tick_cycles); #else - *(uint64_t*)CLINT_MTIMECMP(r_mhartid()) = *(uint64_t*)CLINT_MTIME + tick_cycles; + *(uint64_t*)CLINT_MTIMECMP(__raw_hartid()) = *(uint64_t*)CLINT_MTIME + tick_cycles; #endif return 0; @@ -62,7 +62,7 @@ int rt_hw_tick_init(void) #else clear_csr(mie, MIP_MTIP); clear_csr(mip, MIP_MTIP); - *(uint64_t*)CLINT_MTIMECMP(r_mhartid()) = *(uint64_t*)CLINT_MTIME + interval; + *(uint64_t*)CLINT_MTIMECMP(__raw_hartid()) = *(uint64_t*)CLINT_MTIME + interval; set_csr(mie, MIP_MTIP); #endif return 0;