diff options
| author | bigmagic <[email protected]> | 2021-05-21 17:03:30 +0800 |
|---|---|---|
| committer | bigmagic <[email protected]> | 2021-05-21 17:10:07 +0800 |
| commit | b7c7c7f4dec7ec3708ff056b3d12c9750c835f38 (patch) | |
| tree | b06cf2b027a180b9d393a1ac69a08ec4b47b4d40 /bsp | |
| parent | 0dc972bee60ed64032071fa482ee99f4e4c4ef57 (diff) | |
Support for running with M-Mode
Diffstat (limited to 'bsp')
| -rw-r--r-- | bsp/qemu-riscv-virt64/.config | 7 | ||||
| -rw-r--r-- | bsp/qemu-riscv-virt64/SConstruct | 6 | ||||
| -rw-r--r-- | bsp/qemu-riscv-virt64/applications/main.c | 7 | ||||
| -rw-r--r-- | bsp/qemu-riscv-virt64/driver/Kconfig | 7 | ||||
| -rw-r--r-- | bsp/qemu-riscv-virt64/driver/board.c | 149 | ||||
| -rw-r--r-- | bsp/qemu-riscv-virt64/driver/drv_uart.c | 112 | ||||
| -rw-r--r-- | bsp/qemu-riscv-virt64/driver/drv_uart.h | 34 | ||||
| -rw-r--r-- | bsp/qemu-riscv-virt64/driver/plic.c | 98 | ||||
| -rw-r--r-- | bsp/qemu-riscv-virt64/driver/plic.h | 61 | ||||
| -rw-r--r-- | bsp/qemu-riscv-virt64/link.lds | 4 | ||||
| -rw-r--r-- | bsp/qemu-riscv-virt64/link_stacksize.lds | 3 | ||||
| -rwxr-xr-x | bsp/qemu-riscv-virt64/qemu-nographic-smode.sh | 1 | ||||
| -rwxr-xr-x[-rw-r--r--] | bsp/qemu-riscv-virt64/qemu-nographic.sh | 2 | ||||
| -rw-r--r-- | bsp/qemu-riscv-virt64/rtconfig.h | 2 |
14 files changed, 271 insertions, 222 deletions
diff --git a/bsp/qemu-riscv-virt64/.config b/bsp/qemu-riscv-virt64/.config index 8a61ab72eb..49c8fff6b0 100644 --- a/bsp/qemu-riscv-virt64/.config +++ b/bsp/qemu-riscv-virt64/.config @@ -213,6 +213,7 @@ CONFIG_RT_LIBC_FIXED_TIMEZONE=8 # CONFIG_RT_USING_RYM is not set # CONFIG_RT_USING_ULOG is not set # CONFIG_RT_USING_UTEST is not set +# CONFIG_RT_USING_RT_LINK is not set # # RT-Thread Utestcases @@ -335,6 +336,7 @@ CONFIG_RT_LIBC_FIXED_TIMEZONE=8 # CONFIG_PKG_USING_HELIX is not set # CONFIG_PKG_USING_AZUREGUIX is not set # CONFIG_PKG_USING_TOUCHGFX2RTT is not set +# CONFIG_PKG_USING_NUEMWIN is not set # # tools packages @@ -492,6 +494,7 @@ CONFIG_RT_LIBC_FIXED_TIMEZONE=8 # CONFIG_PKG_USING_LIBNFC is not set # CONFIG_PKG_USING_MFOC is not set # CONFIG_PKG_USING_TMC51XX is not set +# CONFIG_PKG_USING_TCA9534 is not set # # AI packages @@ -519,6 +522,7 @@ CONFIG_RT_LIBC_FIXED_TIMEZONE=8 # CONFIG_PKG_USING_FLEXIBLE_BUTTON is not set # CONFIG_PKG_USING_CANFESTIVAL is not set # CONFIG_PKG_USING_ZLIB is not set +# CONFIG_PKG_USING_MINIZIP is not set # CONFIG_PKG_USING_DSTR is not set # CONFIG_PKG_USING_TINYFRAME is not set # CONFIG_PKG_USING_KENDRYTE_DEMO is not set @@ -558,7 +562,8 @@ CONFIG_BOARD_virt=y CONFIG_RT_USING_USERSPACE=y # -# General Purpose UARTs +# RISCV qemu virt64 configs # # CONFIG_BSP_USING_UART1 is not set +# CONFIG_RISCV_S_MODE is not set CONFIG___STACKSIZE__=16384 diff --git a/bsp/qemu-riscv-virt64/SConstruct b/bsp/qemu-riscv-virt64/SConstruct index 422e592ccd..770a62ccc2 100644 --- a/bsp/qemu-riscv-virt64/SConstruct +++ b/bsp/qemu-riscv-virt64/SConstruct @@ -31,7 +31,11 @@ stack_size = 4096 stack_lds = open('link_stacksize.lds', 'w') if GetDepend('__STACKSIZE__'): stack_size = GetDepend('__STACKSIZE__') -stack_lds.write('__STACKSIZE__ = %d;' % stack_size) +stack_lds.write('__STACKSIZE__ = %d;\r\n' % stack_size) +if GetDepend('RISCV_S_MODE'): start_addr = int(0x80200000) +else: start_addr = int(0x80000000) +stack_lds.write('__START_ADDR__ = 0x%x;' % start_addr) + stack_lds.close() # make a building diff --git a/bsp/qemu-riscv-virt64/applications/main.c b/bsp/qemu-riscv-virt64/applications/main.c index 288d4f08ba..50d2de7a22 100644 --- a/bsp/qemu-riscv-virt64/applications/main.c +++ b/bsp/qemu-riscv-virt64/applications/main.c @@ -1,10 +1,11 @@ /* - * Copyright (c) 2006-2018, RT-Thread Development Team + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * * Change Logs: * Date Author Notes + * 2021-05-20 bigmagic first version */ #include <rtthread.h> @@ -14,9 +15,7 @@ int main(void) { - void rt_hw_uart_start_rx_thread(); - rt_hw_uart_start_rx_thread(); - printf("Hello RISC-V\n"); + printf("Hello RISC-V!\n"); return 0; } diff --git a/bsp/qemu-riscv-virt64/driver/Kconfig b/bsp/qemu-riscv-virt64/driver/Kconfig index 5744c89702..d6fca695ef 100644 --- a/bsp/qemu-riscv-virt64/driver/Kconfig +++ b/bsp/qemu-riscv-virt64/driver/Kconfig @@ -1,6 +1,6 @@ -menu "General Purpose UARTs" +menu "RISCV qemu virt64 configs" menuconfig BSP_USING_UART1 bool "Enable UART1" @@ -14,5 +14,8 @@ menuconfig BSP_USING_UART1 default 21 endif -endmenu +config RISCV_S_MODE + bool "RT-Thread run in riscv smode" + default y +endmenu diff --git a/bsp/qemu-riscv-virt64/driver/board.c b/bsp/qemu-riscv-virt64/driver/board.c index e723f49aca..1e567ea151 100644 --- a/bsp/qemu-riscv-virt64/driver/board.c +++ b/bsp/qemu-riscv-virt64/driver/board.c @@ -21,6 +21,9 @@ #include "sbi.h" #include "riscv.h" #include "stack.h" +#include "riscv_io.h" +#include "plic.h" +#include "interrupt.h" void primary_cpu_entry(void) { @@ -33,11 +36,6 @@ void primary_cpu_entry(void) entry(); } -void rt_hw_interrupt_init() -{ - /* Enable machine external interrupts. */ - set_csr(sie, SIP_SEIP); -} void rt_hw_board_init(void) { @@ -46,10 +44,7 @@ void rt_hw_board_init(void) /* initialize hardware interrupt */ rt_hw_uart_init(); - rt_hw_tick_init(); - #ifdef RT_USING_HEAP - rt_kprintf("heap: [0x%08x - 0x%08x]\n", (rt_ubase_t) RT_HW_HEAP_BEGIN, (rt_ubase_t) RT_HW_HEAP_END); /* initialize memory system */ rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END); #endif @@ -58,7 +53,9 @@ void rt_hw_board_init(void) /* set console device */ rt_console_set_device("uart"); #endif /* RT_USING_CONSOLE */ - + rt_hw_tick_init(); + rt_kprintf("heap: [0x%08x - 0x%08x]\n", (rt_ubase_t) RT_HW_HEAP_BEGIN, (rt_ubase_t) RT_HW_HEAP_END); + #ifdef RT_USING_COMPONENTS_INIT rt_components_board_init(); #endif @@ -71,137 +68,3 @@ void rt_hw_cpu_reset(void) } MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reset machine); -void dump_regs(struct rt_hw_stack_frame *regs) -{ - rt_kprintf("--------------Dump Registers-----------------\n"); - - rt_kprintf("Function Registers:\n"); - rt_kprintf("\tra(x1) = 0x%p\tuser_sp = 0x%p\n",regs -> ra,regs -> user_sp_exc_stack); - rt_kprintf("\tgp(x3) = 0x%p\ttp(x4) = 0x%p\n",regs -> gp,regs -> tp); - rt_kprintf("Temporary Registers:\n"); - rt_kprintf("\tt0(x5) = 0x%p\tt1(x6) = 0x%p\n",regs -> t0,regs -> t1); - rt_kprintf("\tt2(x7) = 0x%p\n",regs -> t2); - rt_kprintf("\tt3(x28) = 0x%p\tt4(x29) = 0x%p\n",regs -> t3,regs -> t4); - rt_kprintf("\tt5(x30) = 0x%p\tt6(x31) = 0x%p\n",regs -> t5,regs -> t6); - rt_kprintf("Saved Registers:\n"); - rt_kprintf("\ts0/fp(x8) = 0x%p\ts1(x9) = 0x%p\n",regs -> s0_fp,regs -> s1); - rt_kprintf("\ts2(x18) = 0x%p\ts3(x19) = 0x%p\n",regs -> s2,regs -> s3); - rt_kprintf("\ts4(x20) = 0x%p\ts5(x21) = 0x%p\n",regs -> s4,regs -> s5); - rt_kprintf("\ts6(x22) = 0x%p\ts7(x23) = 0x%p\n",regs -> s6,regs -> s7); - rt_kprintf("\ts8(x24) = 0x%p\ts9(x25) = 0x%p\n",regs -> s8,regs -> s9); - rt_kprintf("\ts10(x26) = 0x%p\ts11(x27) = 0x%p\n",regs -> s10,regs -> s11); - rt_kprintf("Function Arguments Registers:\n"); - rt_kprintf("\ta0(x10) = 0x%p\ta1(x11) = 0x%p\n",regs -> a0,regs -> a1); - rt_kprintf("\ta2(x12) = 0x%p\ta3(x13) = 0x%p\n",regs -> a2,regs -> a3); - rt_kprintf("\ta4(x14) = 0x%p\ta5(x15) = 0x%p\n",regs -> a4,regs -> a5); - rt_kprintf("\ta6(x16) = 0x%p\ta7(x17) = 0x%p\n",regs -> a6,regs -> a7); - rt_kprintf("sstatus = 0x%p\n",regs -> sstatus); - rt_kprintf("\t%s\n",(regs -> sstatus & SSTATUS_SIE) ? "Supervisor Interrupt Enabled" : "Supervisor Interrupt Disabled"); - rt_kprintf("\t%s\n",(regs -> sstatus & SSTATUS_SPIE) ? "Last Time Supervisor Interrupt Enabled" : "Last Time Supervisor Interrupt Disabled"); - rt_kprintf("\t%s\n",(regs -> sstatus & SSTATUS_SPP) ? "Last Privilege is Supervisor Mode" : "Last Privilege is User Mode"); - rt_kprintf("\t%s\n",(regs -> sstatus & SSTATUS_PUM) ? "Permit to Access User Page" : "Not Permit to Access User Page"); - rt_kprintf("\t%s\n",(regs -> sstatus & (1 << 19)) ? "Permit to Read Executable-only Page" : "Not Permit to Read Executable-only Page"); - rt_size_t satp_v = read_csr(satp); - rt_kprintf("satp = 0x%p\n",satp_v); - const char *mode_str = "Unknown Address Translation/Protection Mode"; - - switch(__MASKVALUE(satp_v >> 60,__MASK(4))) - { - case 0: - mode_str = "No Address Translation/Protection Mode"; - break; - - case 8: - mode_str = "Page-based 39-bit Virtual Addressing Mode"; - break; - - case 9: - mode_str = "Page-based 48-bit Virtual Addressing Mode"; - break; - } - - rt_kprintf("\tMode = %s\n",mode_str); - rt_kprintf("-----------------Dump OK---------------------\n"); -} - -static const char *Exception_Name[] = - { - "Instruction Address Misaligned", - "Instruction Access Fault", - "Illegal Instruction", - "Breakpoint", - "Load Address Misaligned", - "Load Access Fault", - "Store/AMO Address Misaligned", - "Store/AMO Access Fault", - "Environment call from U-mode", - "Environment call from S-mode", - "Reserved-10", - "Reserved-11", - "Instruction Page Fault", - "Load Page Fault", - "Reserved-14", - "Store/AMO Page Fault" - }; - -static const char *Interrupt_Name[] = - { - "User Software Interrupt", - "Supervisor Software Interrupt", - "Reversed-2", - "Reversed-3", - "User Timer Interrupt", - "Supervisor Timer Interrupt", - "Reversed-6", - "Reversed-7", - "User External Interrupt", - "Supervisor External Interrupt", - "Reserved-10", - "Reserved-11", - }; - -void handle_trap(rt_size_t scause,rt_size_t stval,rt_size_t sepc,struct rt_hw_stack_frame *sp) -{ - if(scause == (uint64_t)(0x8000000000000005)) - { - rt_interrupt_enter(); - tick_isr(); - rt_interrupt_leave(); - } - else - { - rt_size_t id = __MASKVALUE(scause,__MASK(63UL)); - const char *msg; - - if(scause >> 63) - { - if(id < sizeof(Interrupt_Name) / sizeof(const char *)) - { - msg = Interrupt_Name[id]; - } - else - { - msg = "Unknown Interrupt"; - } - - rt_kprintf("Unhandled Interrupt %ld:%s\n",id,msg); - } - else - { - if(id < sizeof(Exception_Name) / sizeof(const char *)) - { - msg = Exception_Name[id]; - } - else - { - msg = "Unknown Exception"; - } - - rt_kprintf("Unhandled Exception %ld:%s\n",id,msg); - } - - rt_kprintf("scause:0x%p,stval:0x%p,sepc:0x%p\n",scause,stval,sepc); - dump_regs(sp); - while(1); - } -} diff --git a/bsp/qemu-riscv-virt64/driver/drv_uart.c b/bsp/qemu-riscv-virt64/driver/drv_uart.c index 754a1fbfd1..f6ee2e1c7f 100644 --- a/bsp/qemu-riscv-virt64/driver/drv_uart.c +++ b/bsp/qemu-riscv-virt64/driver/drv_uart.c @@ -1,10 +1,12 @@ /* - * Copyright (c) 2019-2020, Xim + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * + * Change Logs: + * Date Author Notes + * 2021-05-20 bigmagic first version */ - #include <rthw.h> #include <rtdevice.h> @@ -13,8 +15,7 @@ #include <stdio.h> #include "sbi.h" - -#define UART_DEFAULT_BAUDRATE 115200 +#include "interrupt.h" struct device_uart { @@ -27,23 +28,25 @@ static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg static int drv_uart_putc(struct rt_serial_device *serial, char c); static int drv_uart_getc(struct rt_serial_device *serial); -const struct rt_uart_ops _uart_ops = +void virt_uart_init(void) { - rt_uart_configure, - uart_control, - drv_uart_putc, - drv_uart_getc, - //TODO: add DMA support - RT_NULL -}; + //http://byterunner.com/16550.html + uart_write_reg(IER, 0x00); -void uart_init(void) -{ - return ; -} + uint8_t lcr = uart_read_reg(LCR); + uart_write_reg(LCR, lcr | (1 << 7)); + uart_write_reg(DLL, 0x03); + uart_write_reg(DLM, 0x00); -struct rt_serial_device serial1; -struct device_uart uart1; + lcr = 0; + uart_write_reg(LCR, lcr | (3 << 0)); + + /* + * enable receive interrupts. + */ + uint8_t ier = uart_read_reg(IER); + uart_write_reg(IER, ier | (1 << 0)); +} /* * UART interface @@ -58,22 +61,6 @@ static rt_err_t rt_uart_configure(struct rt_serial_device *serial, struct serial return (RT_EOK); } -#define UART_LSR_DR 0x01 /* Data ready */ -#define UART_LSR_THRE 0x20 /* Xmit holding register empty */ - -#define UART_RBR(hw) HWREG32(hw + 0x00) -#define UART_IER(hw) HWREG32(hw + 0x04) -#define UART_LSR(hw) HWREG32(hw + 0x14) - -static volatile uint64_t uart_hwbase = 0x10000000; - -void uart_putc(char c) -{ - while ((UART_LSR(uart_hwbase) & UART_LSR_THRE) == 0); - - UART_RBR(uart_hwbase) = c; -} - static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg) { struct device_uart *uart; @@ -97,38 +84,38 @@ static rt_err_t uart_control(struct rt_serial_device *serial, int cmd, void *arg } static int drv_uart_putc(struct rt_serial_device *serial, char c) -{ - sbi_console_putchar(c); - return (1); +{ + while ((uart_read_reg(LSR) & LSR_TX_IDLE) == 0); + return uart_write_reg(THR, c); } static int drv_uart_getc(struct rt_serial_device *serial) { - return sbi_console_getchar(); + if (uart_read_reg(LSR) & LSR_RX_READY){ + return uart_read_reg(RHR); + } else { + return -1; + } + //return sbi_console_getchar(); } -char rt_hw_console_getchar(void) +static void rt_hw_uart_isr(int irqno, void *param) { - return sbi_console_getchar(); + struct rt_serial_device *serial = (struct rt_serial_device*)param; + rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND); } -static void uart_rx(void *param) -{ - struct rt_serial_device *serial = (struct rt_serial_device *)param; - - while(1) - { - rt_hw_serial_isr((struct rt_serial_device *)serial,RT_SERIAL_EVENT_RX_IND); - rt_thread_mdelay(10); - } -} +struct rt_serial_device serial1; +struct device_uart uart1; -void rt_hw_uart_start_rx_thread() +const struct rt_uart_ops _uart_ops = { - rt_thread_t th; - RT_ASSERT((th = rt_thread_create("uartrx",uart_rx,(void *)&serial1,8192,8,20)) != RT_NULL); - RT_ASSERT(rt_thread_startup(th) == RT_EOK); -} + rt_uart_configure, + uart_control, + drv_uart_putc, + drv_uart_getc, + RT_NULL +}; /* * UART Initiation @@ -138,7 +125,6 @@ int rt_hw_uart_init(void) struct rt_serial_device *serial; struct device_uart *uart; struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT; - { serial = &serial1; uart = &uart1; @@ -147,19 +133,19 @@ int rt_hw_uart_init(void) serial->config = config; serial->config.baud_rate = UART_DEFAULT_BAUDRATE; - uart->hw_base = 0x10000000; - uart->irqno = 0xa; + uart->hw_base = UART_BASE; + uart->irqno = UART0_IRQ; + + virt_uart_init(); rt_hw_serial_register(serial, "uart", RT_DEVICE_FLAG_STREAM | RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_INT_RX, uart); + rt_hw_interrupt_install(uart->irqno, rt_hw_uart_isr, serial, "uart"); + + rt_hw_interrupt_umask(uart->irqno); } return 0; } - -/* WEAK for SDK 0.5.6 */ -RT_WEAK void uart_debug_init(int uart_channel) -{ -} diff --git a/bsp/qemu-riscv-virt64/driver/drv_uart.h b/bsp/qemu-riscv-virt64/driver/drv_uart.h index a7a18d0dde..1a590b83df 100644 --- a/bsp/qemu-riscv-virt64/driver/drv_uart.h +++ b/bsp/qemu-riscv-virt64/driver/drv_uart.h @@ -1,15 +1,43 @@ /* - * Copyright (c) 2019-2020, Xim + * Copyright (c) 2006-2021, RT-Thread Development Team * * SPDX-License-Identifier: Apache-2.0 * + * Change Logs: + * Date Author Notes + * 2021-05-20 bigmagic first version */ #ifndef __DRV_UART_H__ #define __DRV_UART_H__ -void rt_hw_uart_start_rx_thread(); +#define UART0_IRQ (10) + +#define UART_DEFAULT_BAUDRATE 115200 + +#define UART_BASE (0x10000000L) + +#define RHR 0 // Receive Holding Register (read mode) +#define THR 0 // Transmit Holding Register (write mode) +#define DLL 0 // LSB of Divisor Latch (write mode) +#define IER 1 // Interrupt Enable Register (write mode) +#define DLM 1 // MSB of Divisor Latch (write mode) +#define FCR 2 // FIFO Control Register (write mode) +#define ISR 2 // Interrupt Status Register (read mode) +#define LCR 3 // Line Control Register +#define MCR 4 // Modem Control Register +#define LSR 5 // Line Status Register +#define MSR 6 // Modem Status Register +#define SPR 7 // ScratchPad Register + +#define UART_REG(reg) ((volatile uint8_t *)(UART_BASE + reg)) + +#define LSR_RX_READY (1 << 0) +#define LSR_TX_IDLE (1 << 5) + +#define uart_read_reg(reg) (*(UART_REG(reg))) +#define uart_write_reg(reg, v) (*(UART_REG(reg)) = (v)) + int rt_hw_uart_init(void); -void drv_uart_puts(char *str); // for syscall #endif /* __DRV_UART_H__ */ diff --git a/bsp/qemu-riscv-virt64/driver/plic.c b/bsp/qemu-riscv-virt64/driver/plic.c new file mode 100644 index 0000000000..afd186933d --- /dev/null +++ b/bsp/qemu-riscv-virt64/driver/plic.c @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-20 bigmagic first version + */ +#include "rtthread.h" +#include "plic.h" +#include <riscv_io.h> +#include "encoding.h" + +/* +* Each PLIC interrupt source can be assigned a priority by writing +* to its 32-bit memory-mapped priority register. +* The QEMU-virt (the same as FU540-C000) supports 7 levels of priority. +* A priority value of 0 is reserved to mean "never interrupt" and +* effectively disables the interrupt. +* Priority 1 is the lowest active priority, and priority 7 is the highest. +* Ties between global interrupts of the same priority are broken by +* the Interrupt ID; interrupts with the lowest ID have the highest +* effective priority. +*/ +void plic_set_priority(int irq, int priority) +{ + *(uint32_t*)PLIC_PRIORITY(irq) = priority; +} + +/* +* Each global interrupt can be enabled by setting the corresponding +* bit in the enables registers. +*/ +void plic_irq_enable(int irq) +{ + int hart = r_mhartid(); + *(uint32_t*)PLIC_ENABLE(hart) = ((*(uint32_t*)PLIC_ENABLE(hart)) | (1 << irq)); +#ifdef RISCV_S_MODE + set_csr(sie, read_csr(sie) | MIP_SEIP); +#else + set_csr(mie, read_csr(mie) | MIP_MEIP); +#endif +} + +void plic_irq_disable(int irq) +{ + int hart = r_mhartid(); + *(uint32_t*)PLIC_ENABLE(hart) = (((*(uint32_t*)PLIC_ENABLE(hart)) & (~(1 << irq)))); +} + +/* +* PLIC will mask all interrupts of a priority less than or equal to threshold. +* Maximum threshold is 7. +* For example, a threshold value of zero permits all interrupts with +* non-zero priority, whereas a value of 7 masks all interrupts. +* Notice, the threshold is global for PLIC, not for each interrupt source. +*/ +void plic_set_threshold(int threshold) +{ + int hart = r_mhartid(); + *(uint32_t*)PLIC_THRESHOLD(hart) = threshold; +} + +/* + * DESCRIPTION: + * Query the PLIC what interrupt we should serve. + * Perform an interrupt claim by reading the claim register, which + * returns the ID of the highest-priority pending interrupt or zero if there + * is no pending interrupt. + * A successful claim also atomically clears the corresponding pending bit + * on the interrupt source. + * RETURN VALUE: + * the ID of the highest-priority pending interrupt or zero if there + * is no pending interrupt. + */ +int plic_claim(void) +{ + int hart = r_mhartid(); + int irq = *(uint32_t*)PLIC_CLAIM(hart); + return irq; +} + +/* + * DESCRIPTION: + * Writing the interrupt ID it received from the claim (irq) to the + * complete register would signal the PLIC we've served this IRQ. + * The PLIC does not check whether the completion ID is the same as the + * last claim ID for that target. If the completion ID does not match an + * interrupt source that is currently enabled for the target, the completion + * is silently ignored. + * RETURN VALUE: none + */ +void plic_complete(int irq) +{ + int hart = r_mhartid(); + *(uint32_t*)PLIC_COMPLETE(hart) = irq; +} diff --git a/bsp/qemu-riscv-virt64/driver/plic.h b/bsp/qemu-riscv-virt64/driver/plic.h new file mode 100644 index 0000000000..79af90cbfb --- /dev/null +++ b/bsp/qemu-riscv-virt64/driver/plic.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2006-2021, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2021-05-20 bigmagic first version + */ + +#ifndef PLIC_H +#define PLIC_H + +#include <rtconfig.h> +/* + * This machine puts platform-level interrupt controller (PLIC) here. + * Here only list PLIC registers in Machine mode. + * + */ + +#define VIRT_PLIC_BASE 0x0c000000L + +#define PLIC_PRIORITY_OFFSET (0x0) +#define PLIC_PENDING_OFFSET (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_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) + +#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) +#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)) + + + +void plic_set_priority(int irq, int priority); +void plic_irq_enable(int irq); +void plic_irq_disable(int irq); +void plic_set_threshold(int mthreshold); +int plic_claim(void); +void plic_complete(int irq); + +#endif diff --git a/bsp/qemu-riscv-virt64/link.lds b/bsp/qemu-riscv-virt64/link.lds index e8c0db9c24..2614e0eb36 100644 --- a/bsp/qemu-riscv-virt64/link.lds +++ b/bsp/qemu-riscv-virt64/link.lds @@ -21,13 +21,13 @@ OUTPUT_ARCH( "riscv" ) MEMORY { - SRAM : ORIGIN = 0x80200000, LENGTH = 0x7FF000 + SRAM : ORIGIN = __START_ADDR__, LENGTH = 0x7FF000 } ENTRY(_start) SECTIONS { - . = 0x80200000 ; + . = __START_ADDR__ ; /* __STACKSIZE__ = 4096; */ diff --git a/bsp/qemu-riscv-virt64/link_stacksize.lds b/bsp/qemu-riscv-virt64/link_stacksize.lds index 8685bc0f1c..4a0d736ae8 100644 --- a/bsp/qemu-riscv-virt64/link_stacksize.lds +++ b/bsp/qemu-riscv-virt64/link_stacksize.lds @@ -1 +1,2 @@ -__STACKSIZE__ = 16384;
\ No newline at end of file +__STACKSIZE__ = 16384; +__START_ADDR__ = 0x80000000;
\ No newline at end of file diff --git a/bsp/qemu-riscv-virt64/qemu-nographic-smode.sh b/bsp/qemu-riscv-virt64/qemu-nographic-smode.sh new file mode 100755 index 0000000000..750f6f0fcd --- /dev/null +++ b/bsp/qemu-riscv-virt64/qemu-nographic-smode.sh @@ -0,0 +1 @@ +qemu-system-riscv64 -nographic -machine virt -m 256M -kernel rtthread.bin
\ No newline at end of file diff --git a/bsp/qemu-riscv-virt64/qemu-nographic.sh b/bsp/qemu-riscv-virt64/qemu-nographic.sh index 934c4f935b..546e7a3d87 100644..100755 --- a/bsp/qemu-riscv-virt64/qemu-nographic.sh +++ b/bsp/qemu-riscv-virt64/qemu-nographic.sh @@ -1 +1 @@ -qemu-system-riscv64 -nographic -machine virt -m 256M -kernel rtthread.bin +qemu-system-riscv64 -nographic -machine virt -m 256M -bios rtthread.bin diff --git a/bsp/qemu-riscv-virt64/rtconfig.h b/bsp/qemu-riscv-virt64/rtconfig.h index 38d19a2265..fab069701e 100644 --- a/bsp/qemu-riscv-virt64/rtconfig.h +++ b/bsp/qemu-riscv-virt64/rtconfig.h @@ -177,7 +177,7 @@ #define BOARD_virt #define RT_USING_USERSPACE -/* General Purpose UARTs */ +/* RISCV qemu virt64 configs */ #define __STACKSIZE__ 16384 |
