summaryrefslogtreecommitdiff
path: root/bsp
diff options
context:
space:
mode:
authorbigmagic <[email protected]>2021-05-21 17:03:30 +0800
committerbigmagic <[email protected]>2021-05-21 17:10:07 +0800
commitb7c7c7f4dec7ec3708ff056b3d12c9750c835f38 (patch)
treeb06cf2b027a180b9d393a1ac69a08ec4b47b4d40 /bsp
parent0dc972bee60ed64032071fa482ee99f4e4c4ef57 (diff)
Support for running with M-Mode
Diffstat (limited to 'bsp')
-rw-r--r--bsp/qemu-riscv-virt64/.config7
-rw-r--r--bsp/qemu-riscv-virt64/SConstruct6
-rw-r--r--bsp/qemu-riscv-virt64/applications/main.c7
-rw-r--r--bsp/qemu-riscv-virt64/driver/Kconfig7
-rw-r--r--bsp/qemu-riscv-virt64/driver/board.c149
-rw-r--r--bsp/qemu-riscv-virt64/driver/drv_uart.c112
-rw-r--r--bsp/qemu-riscv-virt64/driver/drv_uart.h34
-rw-r--r--bsp/qemu-riscv-virt64/driver/plic.c98
-rw-r--r--bsp/qemu-riscv-virt64/driver/plic.h61
-rw-r--r--bsp/qemu-riscv-virt64/link.lds4
-rw-r--r--bsp/qemu-riscv-virt64/link_stacksize.lds3
-rwxr-xr-xbsp/qemu-riscv-virt64/qemu-nographic-smode.sh1
-rwxr-xr-x[-rw-r--r--]bsp/qemu-riscv-virt64/qemu-nographic.sh2
-rw-r--r--bsp/qemu-riscv-virt64/rtconfig.h2
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