mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-11-09 20:45:41 +08:00
Improve c906 smart qemu support
This commit is contained in:
1 parent
8dc000e5b3
commit
c9c1b9c8d0
35 files changed
+4491
No files matched your search
@@ -479,6 +479,13 @@
|
||||
"xuantie/xiaohui/r910",
|
||||
"xuantie/xiaohui/r920"
|
||||
]
|
||||
},
|
||||
{
|
||||
"RTT_BSP": "xuantie-smart",
|
||||
"RTT_TOOL_CHAIN": "sourcery-Xuantie-900-gcc-linux-musl",
|
||||
"SUB_RTT_BSP": [
|
||||
"xuantie/virt64/c906"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
@@ -159,6 +159,15 @@ jobs:
|
||||
/opt/Xuantie-900-gcc-elf-newlib-x86_64-V3.0.2/bin/riscv64-unknown-elf-gcc --version
|
||||
echo "RTT_EXEC_PATH=/opt/Xuantie-900-gcc-elf-newlib-x86_64-V3.0.2/bin" >> $GITHUB_ENV
|
||||
|
||||
- name: Install Xuantie-900-gcc-linux-musl Tools
|
||||
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'sourcery-Xuantie-900-gcc-linux-musl' && success() }}
|
||||
run: |
|
||||
wget -q https://github.com/RT-Thread/toolchains-ci/releases/download/v1.9/Xuantie-900-gcc-linux-6.6.0-musl64-x86_64-V3.0.2.tar.gz
|
||||
sudo tar -zxvf Xuantie-900-gcc-linux-6.6.0-musl64-x86_64-V3.0.2.tar.gz -C /opt
|
||||
/opt/Xuantie-900-gcc-linux-6.6.0-musl64-x86_64-V3.0.2/bin/riscv64-unknown-linux-musl-gcc --version
|
||||
echo "RTT_EXEC_PATH=/opt/Xuantie-900-gcc-linux-6.6.0-musl64-x86_64-V3.0.2/bin" >> $GITHUB_ENV
|
||||
echo "RTT_CC_PREFIX=riscv64-unknown-linux-musl-" >> $GITHUB_ENV
|
||||
|
||||
- name: Install k230 MUSL ToolChains
|
||||
if: ${{ matrix.legs.RTT_TOOL_CHAIN == 'riscv64-unknown-linux-musl-' && matrix.legs.RTT_BSP == 'K230' && success() }}
|
||||
run: |
|
||||
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,28 @@
|
||||
mainmenu "RT-Thread Project Configuration"
|
||||
|
||||
RTT_DIR := ../../../..
|
||||
PKGS_DIR := packages
|
||||
|
||||
source "$(RTT_DIR)/Kconfig"
|
||||
osource "$PKGS_DIR/Kconfig"
|
||||
rsource "board/Kconfig"
|
||||
|
||||
config BOARD_QEMU_VIRT_RV64
|
||||
bool
|
||||
select ARCH_RISCV64
|
||||
select ARCH_USING_RISCV_COMMON64
|
||||
select RT_USING_COMPONENTS_INIT
|
||||
select RT_USING_USER_MAIN
|
||||
select RT_USING_CACHE
|
||||
select ARCH_MM_MMU
|
||||
select ARCH_REMAP_KERNEL
|
||||
default y
|
||||
|
||||
config ENABLE_FPU
|
||||
bool "Enable FPU"
|
||||
select ARCH_RISCV_FPU
|
||||
default y
|
||||
|
||||
config __STACKSIZE__
|
||||
int "stack size for interrupt"
|
||||
default 8192
|
||||
File diff suppressed because it is too large.
Load diff
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,15 @@
|
||||
# for module compiling
|
||||
import os
|
||||
Import('RTT_ROOT')
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
objs = []
|
||||
list = os.listdir(cwd)
|
||||
|
||||
for d in list:
|
||||
path = os.path.join(cwd, d)
|
||||
if os.path.isfile(os.path.join(path, 'SConscript')):
|
||||
objs = objs + SConscript(os.path.join(d, 'SConscript'))
|
||||
|
||||
Return('objs')
|
||||
@@ -0,0 +1,51 @@
|
||||
import os
|
||||
import sys
|
||||
import rtconfig
|
||||
from SCons.Script import *
|
||||
|
||||
if os.getenv('RTT_ROOT'):
|
||||
RTT_ROOT = os.getenv('RTT_ROOT')
|
||||
else:
|
||||
RTT_ROOT = os.path.normpath(os.getcwd() + '/../../../..')
|
||||
|
||||
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
|
||||
|
||||
try:
|
||||
from building import *
|
||||
except:
|
||||
print('Cannot found RT-Thread root directory, please check RTT_ROOT')
|
||||
print(RTT_ROOT)
|
||||
exit(-1)
|
||||
|
||||
TARGET = 'rtthread.' + rtconfig.TARGET_EXT
|
||||
|
||||
DefaultEnvironment(tools=[])
|
||||
env = Environment(tools = ['mingw'],
|
||||
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
|
||||
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
|
||||
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
|
||||
AR = rtconfig.AR, ARFLAGS = '-rc',
|
||||
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
|
||||
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
|
||||
env['ASCOM'] = env['ASPPCOM']
|
||||
|
||||
Export('RTT_ROOT')
|
||||
Export('rtconfig')
|
||||
|
||||
|
||||
# prepare building environment
|
||||
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False)
|
||||
|
||||
stack_size = 4096
|
||||
|
||||
if GetDepend('RT_USING_SMART'):
|
||||
# use smart link.lds
|
||||
env['LINKFLAGS'] = env['LINKFLAGS'].replace('link.lds', 'link_smart.lds')
|
||||
|
||||
stack_lds = open('link_stacksize.lds', 'w')
|
||||
if GetDepend('__STACKSIZE__'): stack_size = GetDepend('__STACKSIZE__')
|
||||
stack_lds.write('__STACKSIZE__ = %d;\n' % stack_size)
|
||||
stack_lds.close()
|
||||
|
||||
# make a building
|
||||
DoBuilding(TARGET, objs)
|
||||
@@ -0,0 +1,11 @@
|
||||
from building import *
|
||||
import os
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
CPPPATH = [cwd]
|
||||
src = ['main.c']
|
||||
src += ['mnt.c']
|
||||
|
||||
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2018, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
#include <string.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
rt_kprintf("Hello RISC-V\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021/08/19 bernard the first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
|
||||
#ifdef RT_USING_DFS
|
||||
#include <dfs_fs.h>
|
||||
#include <rtdbg.h>
|
||||
|
||||
int mnt_init(void)
|
||||
{
|
||||
if (rt_device_find("virtio-blk0"))
|
||||
{
|
||||
/* mount virtio-blk as root directory */
|
||||
if (dfs_mount("virtio-blk0", "/", "elm", 0, RT_NULL) == 0)
|
||||
{
|
||||
rt_kprintf("file system initialization done!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
if (dfs_mount("virtio-blk0", "/", "ext", 0, RT_NULL) == 0)
|
||||
{
|
||||
rt_kprintf("file system initialization done!\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_kprintf("file system initialization fail!\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_ENV_EXPORT(mnt_init);
|
||||
#endif
|
||||
@@ -0,0 +1,15 @@
|
||||
menu "RISC-V QEMU virt64 configs"
|
||||
|
||||
config BSP_USING_VIRTIO
|
||||
bool "Using VirtIO"
|
||||
default y
|
||||
depends on RT_USING_DEVICE_OPS
|
||||
|
||||
config BSP_USING_VIRTIO_BLK
|
||||
bool "Using VirtIO BLK"
|
||||
select RT_USING_VIRTIO
|
||||
select RT_USING_VIRTIO_BLK
|
||||
default y
|
||||
depends on BSP_USING_VIRTIO
|
||||
|
||||
endmenu
|
||||
@@ -0,0 +1,15 @@
|
||||
import os
|
||||
import rtconfig
|
||||
from building import *
|
||||
|
||||
cwd = GetCurrentDir()
|
||||
|
||||
# add general drivers
|
||||
src = ['board.c']
|
||||
src += ['drv_uart.c']
|
||||
src += ['drv_virtio.c']
|
||||
|
||||
path = [cwd]
|
||||
|
||||
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
|
||||
Return('group')
|
||||
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2025, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2025-04-23 Wangshun first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <rtdevice.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "mm_aspace.h"
|
||||
#include "tick.h"
|
||||
|
||||
#include "drv_uart.h"
|
||||
#include "encoding.h"
|
||||
#include "stack.h"
|
||||
#include "sbi.h"
|
||||
#include "riscv.h"
|
||||
#include "plic.h"
|
||||
#include "stack.h"
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
#include "riscv_mmu.h"
|
||||
#include "mmu.h"
|
||||
#include "page.h"
|
||||
#include "lwp_arch.h"
|
||||
|
||||
rt_region_t init_page_region = {(rt_size_t)RT_HW_PAGE_START, (rt_size_t)RT_HW_PAGE_END};
|
||||
|
||||
extern size_t MMUTable[];
|
||||
|
||||
struct mem_desc platform_mem_desc[] = {
|
||||
{KERNEL_VADDR_START, (rt_size_t)RT_HW_PAGE_END - 1, (rt_size_t)ARCH_MAP_FAILED, NORMAL_MEM},
|
||||
};
|
||||
|
||||
#define NUM_MEM_DESC (sizeof(platform_mem_desc) / sizeof(platform_mem_desc[0]))
|
||||
|
||||
#endif
|
||||
|
||||
void primary_cpu_entry(void)
|
||||
{
|
||||
/* disable global interrupt */
|
||||
rt_hw_interrupt_disable();
|
||||
|
||||
entry();
|
||||
}
|
||||
|
||||
#define IOREMAP_SIZE (1ul << 30)
|
||||
|
||||
#ifndef ARCH_REMAP_KERNEL
|
||||
#define IOREMAP_VEND USER_VADDR_START
|
||||
#else
|
||||
#define IOREMAP_VEND 0ul
|
||||
#endif /* ARCH_REMAP_KERNEL */
|
||||
|
||||
void rt_hw_board_init(void)
|
||||
{
|
||||
#ifdef RT_USING_SMART
|
||||
/* init data structure */
|
||||
rt_hw_mmu_map_init(&rt_kernel_space, (void *)(IOREMAP_VEND - IOREMAP_SIZE), IOREMAP_SIZE, (rt_size_t *)MMUTable, PV_OFFSET);
|
||||
|
||||
/* init page allocator */
|
||||
rt_page_init(init_page_region);
|
||||
|
||||
/* setup region, and enable MMU */
|
||||
rt_hw_mmu_setup(&rt_kernel_space, platform_mem_desc, NUM_MEM_DESC);
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_HEAP
|
||||
/* initialize memory system */
|
||||
rt_system_heap_init(RT_HW_HEAP_BEGIN, RT_HW_HEAP_END);
|
||||
#endif
|
||||
|
||||
plic_init();
|
||||
|
||||
rt_hw_interrupt_init();
|
||||
|
||||
rt_hw_uart_init();
|
||||
|
||||
#ifdef RT_USING_CONSOLE
|
||||
/* set console device */
|
||||
rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
|
||||
#endif /* RT_USING_CONSOLE */
|
||||
|
||||
rt_hw_tick_init();
|
||||
|
||||
#ifdef RT_USING_COMPONENTS_INIT
|
||||
rt_components_board_init();
|
||||
#endif
|
||||
|
||||
#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);
|
||||
#endif /* RT_USING_HEAP */
|
||||
}
|
||||
|
||||
void rt_hw_cpu_reset(void)
|
||||
{
|
||||
sbi_shutdown();
|
||||
|
||||
while (1)
|
||||
;
|
||||
}
|
||||
MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reset machine);
|
||||
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-01-30 lizhirui first version
|
||||
*/
|
||||
|
||||
#ifndef BOARD_H__
|
||||
#define BOARD_H__
|
||||
|
||||
#include <rtconfig.h>
|
||||
|
||||
extern unsigned int __bss_start;
|
||||
extern unsigned int __bss_end;
|
||||
|
||||
#ifndef RT_USING_SMART
|
||||
#define KERNEL_VADDR_START 0x0
|
||||
#endif
|
||||
|
||||
#define VIRT64_SBI_MEMSZ (0x200000)
|
||||
|
||||
#define RT_HW_HEAP_BEGIN ((void *)&__bss_end)
|
||||
#define RT_HW_HEAP_END ((void *)(RT_HW_HEAP_BEGIN + 64 * 1024 * 1024))
|
||||
#define RT_HW_PAGE_START RT_HW_HEAP_END
|
||||
#define RT_HW_PAGE_END ((void *)(KERNEL_VADDR_START + (256 * 1024 * 1024 - VIRT64_SBI_MEMSZ)))
|
||||
|
||||
void rt_hw_board_init(void);
|
||||
void rt_init_user_mem(struct rt_thread *thread, const char *name,
|
||||
unsigned long *entry);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,165 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtdevice.h>
|
||||
#include <rtthread.h>
|
||||
|
||||
#include "board.h"
|
||||
#include "drv_uart.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#ifdef RT_USING_SMART
|
||||
#include <ioremap.h>
|
||||
#endif
|
||||
#include "sbi.h"
|
||||
|
||||
struct device_uart
|
||||
{
|
||||
rt_ubase_t hw_base;
|
||||
rt_uint32_t irqno;
|
||||
};
|
||||
|
||||
void *uart0_base = (void*)0x10000000;
|
||||
struct rt_serial_device serial0;
|
||||
struct device_uart uart0;
|
||||
|
||||
void uart_init(void)
|
||||
{
|
||||
rt_uint32_t div = UART_REFERENCE_CLOCK / (UART_DEFAULT_BAUDRATE * 16);
|
||||
|
||||
write8_uart0(UART_IER, 0x00);
|
||||
write8_uart0(UART_LCR, UART_LCR_BAUD_LATCH);
|
||||
|
||||
// LSB
|
||||
write8_uart0(0, div & 0xff);
|
||||
// MSB
|
||||
write8_uart0(1, (div >> 8) & 0xff);
|
||||
|
||||
// set word length to 8 bits, no parity
|
||||
write8_uart0(UART_LCR, UART_LCR_EIGHT_BITS);
|
||||
|
||||
write8_uart0(UART_FCR, UART_FCR_FIFO_ENABLE | UART_FCR_FIFO_CLEAR);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static rt_err_t _uart_configure(struct rt_serial_device *serial, struct serial_configure *cfg)
|
||||
{
|
||||
return (RT_EOK);
|
||||
}
|
||||
|
||||
static rt_err_t _uart_control(struct rt_serial_device *serial, int cmd, void *arg)
|
||||
{
|
||||
struct device_uart *uart = (struct device_uart*)serial->parent.user_data;
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case RT_DEVICE_CTRL_CLR_INT:
|
||||
if ((size_t)arg == RT_DEVICE_FLAG_INT_RX)
|
||||
{
|
||||
rt_uint8_t value = read8_uart0(UART_IER);
|
||||
write8_uart0(UART_IER, value & ~UART_IER_RX_ENABLE);
|
||||
}
|
||||
break;
|
||||
|
||||
case RT_DEVICE_CTRL_SET_INT:
|
||||
if ((size_t)arg == RT_DEVICE_FLAG_INT_RX)
|
||||
{
|
||||
rt_uint8_t value = read8_uart0(UART_IER);
|
||||
write8_uart0(UART_IER, value | UART_IER_RX_ENABLE);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return (RT_EOK);
|
||||
}
|
||||
|
||||
static int _uart_putc(struct rt_serial_device *serial, char c)
|
||||
{
|
||||
struct device_uart *uart;
|
||||
uart = (struct device_uart*)serial->parent.user_data;
|
||||
|
||||
// wait for Transmit Holding Empty to be set in LSR.
|
||||
while((read8_uart0(UART_LSR) & UART_LSR_TX_IDLE) == 0)
|
||||
;
|
||||
write8_uart0(UART_THR, c);
|
||||
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int _uart_getc(struct rt_serial_device *serial)
|
||||
{
|
||||
struct device_uart *uart;
|
||||
volatile rt_uint32_t lsr;
|
||||
int ch = -1;
|
||||
|
||||
uart = (struct device_uart*)serial->parent.user_data;
|
||||
lsr = read8_uart0(UART_LSR);
|
||||
|
||||
if (lsr & UART_LSR_RX_READY)
|
||||
{
|
||||
ch = read8_uart0(UART_RHR);
|
||||
}
|
||||
return ch;
|
||||
}
|
||||
|
||||
const struct rt_uart_ops _uart_ops = {
|
||||
_uart_configure,
|
||||
_uart_control,
|
||||
_uart_putc,
|
||||
_uart_getc,
|
||||
// TODO: add DMA support
|
||||
RT_NULL};
|
||||
|
||||
static void rt_hw_uart_isr(int irqno, void *param)
|
||||
{
|
||||
rt_ubase_t level = rt_hw_interrupt_disable();
|
||||
|
||||
struct rt_serial_device *serial = (struct rt_serial_device *)param;
|
||||
|
||||
rt_hw_serial_isr(serial, RT_SERIAL_EVENT_RX_IND);
|
||||
|
||||
rt_hw_interrupt_enable(level);
|
||||
}
|
||||
|
||||
/*
|
||||
* UART Initiation
|
||||
*/
|
||||
int rt_hw_uart_init(void)
|
||||
{
|
||||
struct rt_serial_device *serial;
|
||||
struct device_uart *uart;
|
||||
struct serial_configure config = RT_SERIAL_CONFIG_DEFAULT;
|
||||
#ifdef RT_USING_SMART
|
||||
uart0_base = rt_ioremap(uart0_base, 4096);
|
||||
#endif
|
||||
// register device
|
||||
serial = &serial0;
|
||||
uart = &uart0;
|
||||
|
||||
serial->ops = &_uart_ops;
|
||||
serial->config = config;
|
||||
serial->config.baud_rate = UART_DEFAULT_BAUDRATE;
|
||||
uart->hw_base = (rt_ubase_t)uart0_base;
|
||||
uart->irqno = 0x0a;
|
||||
|
||||
rt_hw_serial_register(serial,
|
||||
RT_CONSOLE_DEVICE_NAME,
|
||||
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, RT_CONSOLE_DEVICE_NAME);
|
||||
rt_hw_interrupt_umask(uart->irqno);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* WEAK for SDK 0.5.6 */
|
||||
rt_weak void uart_debug_init(int uart_channel)
|
||||
{
|
||||
}
|
||||
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2020, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
*/
|
||||
|
||||
#ifndef __DRV_UART_H__
|
||||
#define __DRV_UART_H__
|
||||
|
||||
#include "riscv_io.h"
|
||||
|
||||
/**
|
||||
* uart ns16550a
|
||||
* http://byterunner.com/16550.html
|
||||
*/
|
||||
|
||||
/* TRANSMIT AND RECEIVE HOLDING REGISTER */
|
||||
#define UART_RHR 0
|
||||
#define UART_THR 0
|
||||
|
||||
/* INTERRUPT ENABLE REGISTER */
|
||||
#define UART_IER 1
|
||||
#define UART_IER_RX_ENABLE (1 << 0)
|
||||
#define UART_IER_TX_ENABLE (1 << 1)
|
||||
|
||||
/* FIFO CONTROL REGISTER */
|
||||
#define UART_FCR 2
|
||||
#define UART_FCR_FIFO_ENABLE (1 << 0)
|
||||
#define UART_FCR_FIFO_CLEAR (3 << 1)
|
||||
|
||||
/* INTERRUPT STATUS REGISTER */
|
||||
#define UART_ISR 2
|
||||
|
||||
/* LINE CONTROL REGISTER */
|
||||
#define UART_LCR 3
|
||||
#define UART_LCR_EIGHT_BITS (3 << 0)
|
||||
// special mode to set baud rate
|
||||
#define UART_LCR_BAUD_LATCH (1 << 7)
|
||||
|
||||
/* LINE STATUS REGISTER */
|
||||
#define UART_LSR 5
|
||||
// input is waiting to be read from RHR
|
||||
#define UART_LSR_RX_READY (1 << 0)
|
||||
// THR can accept another character to send
|
||||
#define UART_LSR_TX_IDLE (1 << 5)
|
||||
|
||||
#define UART_REFERENCE_CLOCK 1843200
|
||||
#define UART_DEFAULT_BAUDRATE 115200
|
||||
|
||||
extern void *uart0_base;
|
||||
|
||||
#define write8_uart0(idx, value) __raw_writeb(((rt_uint8_t)value), (void*)((size_t)uart0_base + (idx)))
|
||||
#define read8_uart0(idx) __raw_readb((void*)((size_t)uart0_base + (idx)))
|
||||
|
||||
void rt_hw_uart_start_rx_thread();
|
||||
int rt_hw_uart_init(void);
|
||||
void drv_uart_puts(char *str); // for syscall
|
||||
|
||||
#endif /* __DRV_UART_H__ */
|
||||
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-11-11 GuEe-GUI the first version
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <virt.h>
|
||||
|
||||
#ifdef BSP_USING_VIRTIO
|
||||
|
||||
#include <virtio.h>
|
||||
#ifdef BSP_USING_VIRTIO_BLK
|
||||
#include <virtio_blk.h>
|
||||
#endif
|
||||
|
||||
|
||||
#include <board.h>
|
||||
|
||||
static virtio_device_init_handler virtio_device_init_handlers[] =
|
||||
{
|
||||
#ifdef BSP_USING_VIRTIO_BLK
|
||||
[VIRTIO_DEVICE_ID_BLOCK] = rt_virtio_blk_init,
|
||||
#endif
|
||||
[VIRTIO_DEVICE_TYPE_SIZE] = RT_NULL
|
||||
};
|
||||
|
||||
int rt_virtio_devices_init(void)
|
||||
{
|
||||
int i;
|
||||
rt_uint32_t irq = VIRTIO_IRQ_BASE;
|
||||
rt_ubase_t mmio_base = VIRTIO_MMIO_BASE;
|
||||
struct virtio_mmio_config *mmio_config;
|
||||
virtio_device_init_handler init_handler;
|
||||
|
||||
if (sizeof(virtio_device_init_handlers) == 0)
|
||||
{
|
||||
/* The compiler will optimize the codes after here. */
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
mmio_base = (rt_ubase_t)rt_ioremap((void *)mmio_base, VIRTIO_MMIO_SIZE * VIRTIO_MAX_NR);
|
||||
|
||||
if (mmio_base == RT_NULL)
|
||||
{
|
||||
return -RT_ERROR;
|
||||
}
|
||||
#endif
|
||||
|
||||
for (i = 0; i < VIRTIO_MAX_NR; ++i, ++irq, mmio_base += VIRTIO_MMIO_SIZE)
|
||||
{
|
||||
mmio_config = (struct virtio_mmio_config *)mmio_base;
|
||||
|
||||
if (mmio_config->magic != VIRTIO_MAGIC_VALUE ||
|
||||
mmio_config->version != RT_USING_VIRTIO_VERSION ||
|
||||
mmio_config->vendor_id != VIRTIO_VENDOR_ID)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
init_handler = virtio_device_init_handlers[mmio_config->device_id];
|
||||
|
||||
if (init_handler != RT_NULL)
|
||||
{
|
||||
init_handler((rt_ubase_t *)mmio_base, irq);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
INIT_DEVICE_EXPORT(rt_virtio_devices_init);
|
||||
#endif /* BSP_USING_VIRTIO */
|
||||
@@ -0,0 +1,16 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-11-11 GuEe-GUI the first version
|
||||
*/
|
||||
|
||||
#ifndef __DRV_VIRTIO_H__
|
||||
#define __DRV_VIRTIO_H__
|
||||
|
||||
int rt_virtio_devices_init(void);
|
||||
|
||||
#endif /* __DRV_VIRTIO_H__ */
|
||||
@@ -0,0 +1,30 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-02-17 GuEe-GUI the first version
|
||||
*/
|
||||
|
||||
#ifndef VIRT_H__
|
||||
#define VIRT_H__
|
||||
|
||||
#include <rtdef.h>
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
#include <mmu.h>
|
||||
#include <ioremap.h>
|
||||
|
||||
#endif
|
||||
|
||||
/* VirtIO */
|
||||
#define VIRTIO_MMIO_BASE 0x10001000
|
||||
#define VIRTIO_MMIO_SIZE 0x00001000
|
||||
#define VIRTIO_MAX_NR 8
|
||||
#define VIRTIO_IRQ_BASE 1
|
||||
#define VIRTIO_VENDOR_ID 0x554d4551 /* "QEMU" */
|
||||
|
||||
#define MAX_HANDLERS 128
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
# RT-Thread building script for component
|
||||
|
||||
from building import *
|
||||
cwd = GetCurrentDir()
|
||||
src = Glob('*.c') + Glob('*.cpp') + Glob('*_gcc.S')
|
||||
CPPPATH = [cwd]
|
||||
|
||||
group = DefineGroup('libcpu', src, depend = [''], CPPPATH = CPPPATH)
|
||||
|
||||
Return('group')
|
||||
@@ -0,0 +1,42 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-01-29 lizhirui first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtdef.h>
|
||||
#include <board.h>
|
||||
#include <riscv.h>
|
||||
#include <cache.h>
|
||||
|
||||
void rt_hw_cpu_icache_ops(int ops, void *addr, int size)
|
||||
{
|
||||
if (ops == RT_HW_CACHE_INVALIDATE)
|
||||
{
|
||||
rt_hw_cpu_icache_invalidate(addr, size);
|
||||
}
|
||||
}
|
||||
|
||||
void rt_hw_cpu_dcache_ops(int ops, void *addr, int size)
|
||||
{
|
||||
if (ops == RT_HW_CACHE_FLUSH)
|
||||
{
|
||||
rt_hw_cpu_dcache_clean(addr, size);
|
||||
}
|
||||
else
|
||||
{
|
||||
rt_hw_cpu_dcache_invalidate(addr, size);
|
||||
}
|
||||
}
|
||||
|
||||
void rt_hw_sync_cache_local(void *addr, int size)
|
||||
{
|
||||
rt_hw_cpu_dcache_clean_local(addr, size);
|
||||
rt_hw_cpu_icache_invalidate_local(addr, size);
|
||||
return;
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2025 RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-11-09 RT-Thread The first version
|
||||
*/
|
||||
#ifndef __CACHE_H__
|
||||
#define __CACHE_H__
|
||||
|
||||
#include <rtdef.h>
|
||||
|
||||
/**
|
||||
* @brief These APIs may not be supported by a specified architecture
|
||||
* But we have to include to all the cases to be 'general purpose'
|
||||
*/
|
||||
|
||||
rt_always_inline void rt_hw_cpu_dcache_clean_local(void *addr, int size)
|
||||
{
|
||||
RT_UNUSED(addr);
|
||||
RT_UNUSED(size);
|
||||
}
|
||||
|
||||
rt_always_inline void rt_hw_cpu_dcache_invalidate_local(void *addr, int size)
|
||||
{
|
||||
RT_UNUSED(addr);
|
||||
RT_UNUSED(size);
|
||||
}
|
||||
|
||||
rt_always_inline void rt_hw_cpu_dcache_clean_and_invalidate_local(void *addr, int size)
|
||||
{
|
||||
RT_UNUSED(addr);
|
||||
RT_UNUSED(size);
|
||||
}
|
||||
|
||||
rt_always_inline void rt_hw_cpu_dcache_clean_all_local(void)
|
||||
{
|
||||
}
|
||||
|
||||
rt_always_inline void rt_hw_cpu_dcache_invalidate_all_local(void)
|
||||
{
|
||||
}
|
||||
|
||||
rt_always_inline void rt_hw_cpu_dcache_clean_and_invalidate_all_local(void)
|
||||
{
|
||||
}
|
||||
|
||||
/*use fence.i to invalidate all icache*/
|
||||
rt_always_inline void rt_hw_cpu_icache_invalidate_local(void *addr, int size)
|
||||
{
|
||||
|
||||
}
|
||||
/*use fence.i to invalidate all icache*/
|
||||
rt_always_inline void rt_hw_cpu_icache_invalidate_all_local(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Multi-core
|
||||
*/
|
||||
|
||||
#define rt_hw_cpu_dcache_clean rt_hw_cpu_dcache_clean_local
|
||||
#define rt_hw_cpu_dcache_invalidate rt_hw_cpu_dcache_invalidate_local
|
||||
#define rt_hw_cpu_dcache_clean_and_invalidate rt_hw_cpu_dcache_clean_and_invalidate_local
|
||||
|
||||
#define rt_hw_cpu_dcache_clean_all rt_hw_cpu_dcache_clean_all_local
|
||||
#define rt_hw_cpu_dcache_invalidate_all rt_hw_cpu_dcache_invalidate_all_local
|
||||
#define rt_hw_cpu_dcache_clean_and_invalidate_all rt_hw_cpu_dcache_clean_and_invalidate_all_local
|
||||
|
||||
#define rt_hw_cpu_icache_invalidate rt_hw_cpu_icache_invalidate_local
|
||||
#define rt_hw_cpu_icache_invalidate_all rt_hw_cpu_icache_invalidate_all_local
|
||||
|
||||
#define rt_hw_icache_invalidate_all rt_hw_cpu_icache_invalidate_all
|
||||
|
||||
/** instruction barrier */
|
||||
static inline void rt_hw_cpu_sync(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief local cpu icahce & dcache synchronization
|
||||
*
|
||||
* @param addr
|
||||
* @param size
|
||||
*/
|
||||
void rt_hw_sync_cache_local(void *addr, int size);
|
||||
|
||||
#endif /* __CACHE_H__ */
|
||||
@@ -0,0 +1,94 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2018/10/01 Bernard The first version
|
||||
* 2018/12/27 Jesven Change irq enable/disable to cpu0
|
||||
*/
|
||||
#include <plic.h>
|
||||
#include <mmu.h>
|
||||
#include "tick.h"
|
||||
#include "encoding.h"
|
||||
#include "riscv.h"
|
||||
#include "interrupt.h"
|
||||
|
||||
struct rt_irq_desc irq_desc[MAX_HANDLERS];
|
||||
|
||||
static rt_isr_handler_t rt_hw_interrupt_handle(rt_uint32_t vector, void *param)
|
||||
{
|
||||
rt_kprintf("UN-handled interrupt %d occurred!!!\n", vector);
|
||||
return RT_NULL;
|
||||
}
|
||||
|
||||
int rt_hw_plic_irq_enable(int irq_number)
|
||||
{
|
||||
plic_irq_enable(irq_number);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int rt_hw_plic_irq_disable(int irq_number)
|
||||
{
|
||||
plic_irq_disable(irq_number);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will un-mask a interrupt.
|
||||
* @param vector the interrupt number
|
||||
*/
|
||||
void rt_hw_interrupt_umask(int vector)
|
||||
{
|
||||
plic_set_priority(vector, 1);
|
||||
|
||||
rt_hw_plic_irq_enable(vector);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function will install a interrupt service routine to a interrupt.
|
||||
* @param vector the interrupt number
|
||||
* @param new_handler the interrupt service routine to be installed
|
||||
* @param old_handler the old interrupt service routine
|
||||
*/
|
||||
rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler,
|
||||
void *param, const char *name)
|
||||
{
|
||||
rt_isr_handler_t old_handler = RT_NULL;
|
||||
|
||||
if(vector < MAX_HANDLERS)
|
||||
{
|
||||
old_handler = irq_desc[vector].handler;
|
||||
if (handler != RT_NULL)
|
||||
{
|
||||
irq_desc[vector].handler = (rt_isr_handler_t)handler;
|
||||
irq_desc[vector].param = param;
|
||||
#ifdef RT_USING_INTERRUPT_INFO
|
||||
rt_snprintf(irq_desc[vector].name, RT_NAME_MAX - 1, "%s", name);
|
||||
irq_desc[vector].counter = 0;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
return old_handler;
|
||||
}
|
||||
|
||||
void rt_hw_interrupt_init()
|
||||
{
|
||||
/* Enable machine external interrupts. */
|
||||
// set_csr(sie, SIP_SEIP);
|
||||
int idx = 0;
|
||||
/* init exceptions table */
|
||||
for (idx = 0; idx < MAX_HANDLERS; idx++)
|
||||
{
|
||||
irq_desc[idx].handler = (rt_isr_handler_t)rt_hw_interrupt_handle;
|
||||
irq_desc[idx].param = RT_NULL;
|
||||
#ifdef RT_USING_INTERRUPT_INFO
|
||||
rt_snprintf(irq_desc[idx].name, RT_NAME_MAX - 1, "default");
|
||||
irq_desc[idx].counter = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
plic_set_threshold(0);
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-05-20 bigmagic The first version
|
||||
*/
|
||||
|
||||
#ifndef INTERRUPT_H__
|
||||
#define INTERRUPT_H__
|
||||
|
||||
#define MAX_HANDLERS 128
|
||||
|
||||
#include <rthw.h>
|
||||
#include "stack.h"
|
||||
|
||||
enum
|
||||
{
|
||||
EP_INSTRUCTION_ADDRESS_MISALIGNED = 0,
|
||||
EP_INSTRUCTION_ACCESS_FAULT,
|
||||
EP_ILLEGAL_INSTRUCTION,
|
||||
EP_BREAKPOINT,
|
||||
EP_LOAD_ADDRESS_MISALIGNED,
|
||||
EP_LOAD_ACCESS_FAULT,
|
||||
EP_STORE_ADDRESS_MISALIGNED,
|
||||
EP_STORE_ACCESS_FAULT,
|
||||
EP_ENVIRONMENT_CALL_U_MODE,
|
||||
EP_ENVIRONMENT_CALL_S_MODE,
|
||||
EP_RESERVED10,
|
||||
EP_ENVIRONMENT_CALL_M_MODE,
|
||||
EP_INSTRUCTION_PAGE_FAULT, /* page attr */
|
||||
EP_LOAD_PAGE_FAULT, /* read data */
|
||||
EP_RESERVED14,
|
||||
EP_STORE_PAGE_FAULT, /* write data */
|
||||
};
|
||||
|
||||
int rt_hw_plic_irq_enable(int irq_number);
|
||||
int rt_hw_plic_irq_disable(int irq_number);
|
||||
void rt_hw_interrupt_init(void);
|
||||
void rt_hw_interrupt_mask(int vector);
|
||||
rt_isr_handler_t rt_hw_interrupt_install(int vector, rt_isr_handler_t handler, void *param, const char *name);
|
||||
void handle_trap(rt_ubase_t xcause, rt_ubase_t xtval, rt_ubase_t xepc, struct rt_hw_stack_frame *sp);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2021, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-11-09 Shell Add portable asm support
|
||||
*/
|
||||
#ifndef __OPCODE_H__
|
||||
#define __OPCODE_H__
|
||||
|
||||
/**
|
||||
* @brief binary opcode pseudo operations
|
||||
* Used to bypass toolchain restriction on extension ISA
|
||||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* @brief RISC-V instruction formats
|
||||
*/
|
||||
|
||||
/**
|
||||
* R type: .insn r opcode6, func3, func7, rd, rs1, rs2
|
||||
*
|
||||
* +-------+-----+-----+-------+----+---------+
|
||||
* | func7 | rs2 | rs1 | func3 | rd | opcode6 |
|
||||
* +-------+-----+-----+-------+----+---------+
|
||||
* 31 25 20 15 12 7 0
|
||||
*/
|
||||
#define __OPC_INSN_FORMAT_R(opcode, func3, func7, rd, rs1, rs2) \
|
||||
".insn r "RT_STRINGIFY(opcode)","RT_STRINGIFY(func3)","RT_STRINGIFY(func7)","RT_STRINGIFY(rd)","RT_STRINGIFY(rs1)","RT_STRINGIFY(rs2)
|
||||
|
||||
#ifdef _TOOLCHAIN_SUPP_ZIFENCEI_ISA_
|
||||
#define OPC_FENCE_I "fence.i"
|
||||
#else /* !_TOOLCHAIN_SUPP_ZIFENCEI_ISA_ */
|
||||
#define OPC_FENCE_I ".long 0x0000100F"
|
||||
#endif /* _TOOLCHAIN_SUPP_ZIFENCEI_ISA_ */
|
||||
|
||||
#endif /* __OPCODE_H__ */
|
||||
@@ -0,0 +1,156 @@
|
||||
/*
|
||||
* 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
|
||||
* 2022-09-16 WangXiaoyao Porting to rv64
|
||||
*/
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include <stdint.h>
|
||||
#include "plic.h"
|
||||
#include <riscv_io.h>
|
||||
#include "encoding.h"
|
||||
#include <interrupt.h>
|
||||
|
||||
#include <riscv.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef RT_USING_SMART
|
||||
#include <ioremap.h>
|
||||
#else
|
||||
#define rt_ioremap(addr, ...) (addr)
|
||||
#endif
|
||||
|
||||
size_t plic_base = 0x0c000000L;
|
||||
|
||||
/*
|
||||
* 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 = __raw_hartid();
|
||||
*(uint32_t *)PLIC_ENABLE(hart) = ((*(uint32_t *)PLIC_ENABLE(hart)) | (1 << irq));
|
||||
#ifdef RISCV_VIRT64_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 = __raw_hartid();
|
||||
*(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 = __raw_hartid();
|
||||
*(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 = __raw_hartid();
|
||||
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 = __raw_hartid();
|
||||
*(uint32_t *)PLIC_COMPLETE(hart) = irq;
|
||||
}
|
||||
|
||||
void plic_set_ie(rt_uint32_t word_index, rt_uint32_t val)
|
||||
{
|
||||
volatile void *plic_ie = (void *)(rt_ubase_t)(plic_base + PLIC_ENABLE_BASE + 0x80 + word_index * 4);
|
||||
writel(val, plic_ie);
|
||||
}
|
||||
|
||||
static void _set_sie(int hartid)
|
||||
{
|
||||
for (size_t i = hartid * WORD_CNT_BYTE; i < 32; i++)
|
||||
plic_set_ie(i, 0xffffffff);
|
||||
}
|
||||
|
||||
void plic_init()
|
||||
{
|
||||
// PLIC takes up 64 MB space
|
||||
plic_base = (size_t)rt_ioremap((void *)plic_base, 64 * 1024 * 1024);
|
||||
|
||||
plic_set_threshold(0);
|
||||
|
||||
for (int i = 0; i < CONFIG_IRQ_NR; i++)
|
||||
{
|
||||
plic_set_priority(i, 1);
|
||||
}
|
||||
|
||||
// in a single core system, only current context was set
|
||||
_set_sie(__raw_hartid());
|
||||
}
|
||||
|
||||
extern struct rt_irq_desc irq_desc[MAX_HANDLERS];
|
||||
/*
|
||||
* Handling an interrupt is a two-step process: first you claim the interrupt
|
||||
* by reading the claim register, then you complete the interrupt by writing
|
||||
* that source ID back to the same claim register. This automatically enables
|
||||
* and disables the interrupt, so there's nothing else to do.
|
||||
*/
|
||||
void plic_handle_irq(void)
|
||||
{
|
||||
int plic_irq = plic_claim();
|
||||
plic_complete(plic_irq);
|
||||
irq_desc[plic_irq].handler(plic_irq, irq_desc[plic_irq].param);
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/*
|
||||
* 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
|
||||
* 2021-10-20 bernard fix s-mode issue
|
||||
*/
|
||||
|
||||
#ifndef __PLIC_H__
|
||||
#define __PLIC_H__
|
||||
|
||||
#include <rtconfig.h>
|
||||
#include <rthw.h>
|
||||
|
||||
#define PLIC_PRIORITY_BASE 0x0
|
||||
#define PLIC_PENDING_BASE 0x1000
|
||||
#define PLIC_ENABLE_BASE 0x2000
|
||||
#define PLIC_CONTEXT_BASE 0x200000
|
||||
|
||||
extern size_t plic_base;
|
||||
|
||||
#define VIRT_PLIC_BASE (plic_base)
|
||||
|
||||
#define PLIC_PRIORITY_OFFSET (0x0)
|
||||
#define PLIC_PENDING_OFFSET (0x1000)
|
||||
|
||||
#define PLIC_ENABLE_STRIDE 0x80
|
||||
#define PLIC_CONTEXT_STRIDE 0x1000
|
||||
|
||||
/* RT-Thread runs in S-mode on virt64 by default */
|
||||
#define RISCV_VIRT64_S_MODE
|
||||
|
||||
#ifndef RISCV_VIRT64_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 * 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 (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 WORD_CNT_BYTE (1024 / 8)
|
||||
|
||||
/* IRQ config in system, max 1024 (from 0 to 1023) */
|
||||
#define CONFIG_IRQ_NR (128)
|
||||
#define CONFIG_IRQ_WORD (CONFIG_IRQ_NR / 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);
|
||||
|
||||
void plic_set_thresh(rt_uint32_t val);
|
||||
void plic_set_ie(rt_uint32_t word_index,rt_uint32_t val);
|
||||
void plic_init();
|
||||
void plic_handle_irq(void);
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,189 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2024, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2021-01-30 lizhirui first version
|
||||
* 2023-10-12 Shell Add permission control API
|
||||
*/
|
||||
|
||||
#ifndef __RISCV_MMU_H__
|
||||
#define __RISCV_MMU_H__
|
||||
|
||||
#include <rtthread.h>
|
||||
#include <rthw.h>
|
||||
#include "riscv.h"
|
||||
|
||||
#undef PAGE_SIZE
|
||||
|
||||
#define PAGE_OFFSET_SHIFT 0
|
||||
#define PAGE_OFFSET_BIT 12
|
||||
#define PAGE_SIZE __SIZE(PAGE_OFFSET_BIT)
|
||||
#define PAGE_OFFSET_MASK __MASK(PAGE_OFFSET_BIT)
|
||||
#define VPN0_SHIFT (PAGE_OFFSET_SHIFT + PAGE_OFFSET_BIT)
|
||||
#define VPN0_BIT 9
|
||||
#define VPN1_SHIFT (VPN0_SHIFT + VPN0_BIT)
|
||||
#define VPN1_BIT 9
|
||||
#define VPN2_SHIFT (VPN1_SHIFT + VPN1_BIT)
|
||||
#define VPN2_BIT 9
|
||||
|
||||
#define PPN0_SHIFT (PAGE_OFFSET_SHIFT + PAGE_OFFSET_BIT)
|
||||
#define PPN0_BIT 9
|
||||
#define PPN1_SHIFT (PPN0_SHIFT + PPN0_BIT)
|
||||
#define PPN1_BIT 9
|
||||
#define PPN2_SHIFT (PPN1_SHIFT + PPN1_BIT)
|
||||
#define PPN2_BIT 10
|
||||
#define PPN_BITS (PPN0_BIT + PPN1_BIT + PPN2_BIT)
|
||||
|
||||
#define L1_PAGE_SIZE __SIZE(PAGE_OFFSET_BIT + VPN0_BIT + VPN1_BIT)
|
||||
#define L2_PAGE_SIZE __SIZE(PAGE_OFFSET_BIT + VPN0_BIT)
|
||||
#define L3_PAGE_SIZE __SIZE(PAGE_OFFSET_BIT)
|
||||
|
||||
#define ARCH_ADDRESS_WIDTH_BITS 64
|
||||
|
||||
#define PHYSICAL_ADDRESS_WIDTH_BITS 56
|
||||
|
||||
#define PAGE_ATTR_NEXT_LEVEL (0)
|
||||
#define PAGE_ATTR_RWX (PTE_X | PTE_W | PTE_R)
|
||||
#define PAGE_ATTR_READONLY (PTE_R)
|
||||
#define PAGE_ATTR_READEXECUTE (PTE_X | PTE_R)
|
||||
|
||||
#define PAGE_ATTR_USER (PTE_U)
|
||||
#define PAGE_ATTR_SYSTEM (0)
|
||||
|
||||
#define PAGE_DEFAULT_ATTR_LEAF (PAGE_ATTR_RWX | PAGE_ATTR_USER | PTE_V | PTE_G)
|
||||
#define PAGE_DEFAULT_ATTR_NEXT (PAGE_ATTR_NEXT_LEVEL | PTE_V | PTE_G)
|
||||
|
||||
#define PAGE_IS_LEAF(pte) __MASKVALUE(pte, PAGE_ATTR_RWX)
|
||||
|
||||
#define PTE_USED(pte) __MASKVALUE(pte, PTE_V)
|
||||
|
||||
/**
|
||||
* encoding of SATP (Supervisor Address Translation and Protection register)
|
||||
*/
|
||||
#define SATP_MODE_OFFSET 60
|
||||
#define SATP_MODE_BARE 0
|
||||
#define SATP_MODE_SV39 8
|
||||
#define SATP_MODE_SV48 9
|
||||
#define SATP_MODE_SV57 10
|
||||
#define SATP_MODE_SV64 11
|
||||
|
||||
#define ARCH_VADDR_WIDTH 39
|
||||
#define SATP_MODE SATP_MODE_SV39
|
||||
|
||||
#define MMU_MAP_K_DEVICE (PTE_G | PTE_W | PTE_R | PTE_V)
|
||||
#define MMU_MAP_K_RWCB (PTE_G | PTE_X | PTE_W | PTE_R | PTE_V)
|
||||
#define MMU_MAP_K_RW (PTE_G | PTE_X | PTE_W | PTE_R | PTE_V)
|
||||
#define MMU_MAP_U_RWCB (PTE_U | PTE_X | PTE_W | PTE_R | PTE_V)
|
||||
#define MMU_MAP_U_RWCB_XN (PTE_U | PTE_W | PTE_R | PTE_V)
|
||||
#define MMU_MAP_U_RW (PTE_U | PTE_X | PTE_W | PTE_R | PTE_V)
|
||||
#define MMU_MAP_EARLY (PAGE_ATTR_RWX | PTE_G | PTE_V)
|
||||
|
||||
#define PTE_XWR_MASK 0xe
|
||||
|
||||
#define ARCH_PAGE_SIZE PAGE_SIZE
|
||||
#define ARCH_PAGE_MASK (ARCH_PAGE_SIZE - 1)
|
||||
#define ARCH_PAGE_SHIFT PAGE_OFFSET_BIT
|
||||
#define ARCH_INDEX_WIDTH 9
|
||||
#define ARCH_INDEX_SIZE (1ul << ARCH_INDEX_WIDTH)
|
||||
#define ARCH_INDEX_MASK (ARCH_INDEX_SIZE - 1)
|
||||
|
||||
#define ARCH_MAP_FAILED ((void *)-1)
|
||||
|
||||
void mmu_set_pagetable(rt_ubase_t addr);
|
||||
void mmu_enable_user_page_access(void);
|
||||
void mmu_disable_user_page_access(void);
|
||||
|
||||
#define RT_HW_MMU_PROT_READ 1
|
||||
#define RT_HW_MMU_PROT_WRITE 2
|
||||
#define RT_HW_MMU_PROT_EXECUTE 4
|
||||
#define RT_HW_MMU_PROT_KERNEL 8
|
||||
#define RT_HW_MMU_PROT_USER 16
|
||||
#define RT_HW_MMU_PROT_CACHE 32
|
||||
|
||||
void rt_hw_asid_init(void);
|
||||
struct rt_aspace;
|
||||
void rt_hw_asid_switch_pgtbl(struct rt_aspace *aspace, rt_ubase_t pgtbl);
|
||||
|
||||
/**
|
||||
* @brief Remove permission from attribution
|
||||
*
|
||||
* @param attr architecture specified mmu attribution
|
||||
* @param prot protect that will be removed
|
||||
* @return size_t returned attribution
|
||||
*/
|
||||
rt_inline size_t rt_hw_mmu_attr_rm_perm(size_t attr, rt_base_t prot)
|
||||
{
|
||||
switch (prot)
|
||||
{
|
||||
/* remove write permission for user */
|
||||
case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER:
|
||||
attr &= ~PTE_W;
|
||||
break;
|
||||
/* remove write permission for kernel */
|
||||
case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_KERNEL:
|
||||
attr &= ~PTE_W;
|
||||
break;
|
||||
default:
|
||||
RT_ASSERT(0);
|
||||
}
|
||||
return attr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Add permission from attribution
|
||||
*
|
||||
* @param attr architecture specified mmu attribution
|
||||
* @param prot protect that will be added
|
||||
* @return size_t returned attribution
|
||||
*/
|
||||
rt_inline size_t rt_hw_mmu_attr_add_perm(size_t attr, rt_base_t prot)
|
||||
{
|
||||
switch (prot)
|
||||
{
|
||||
/* add write permission for user */
|
||||
case RT_HW_MMU_PROT_WRITE | RT_HW_MMU_PROT_USER:
|
||||
attr |= (PTE_R | PTE_W | PTE_U);
|
||||
break;
|
||||
default:
|
||||
RT_ASSERT(0);
|
||||
}
|
||||
return attr;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test permission from attribution
|
||||
*
|
||||
* @param attr architecture specified mmu attribution
|
||||
* @param prot protect that will be test
|
||||
* @return rt_bool_t RT_TRUE if the prot is allowed, otherwise RT_FALSE
|
||||
*/
|
||||
rt_inline rt_bool_t rt_hw_mmu_attr_test_perm(size_t attr, rt_base_t prot)
|
||||
{
|
||||
rt_bool_t rc = 0;
|
||||
switch (prot & ~RT_HW_MMU_PROT_USER)
|
||||
{
|
||||
/* test write permission for user */
|
||||
case RT_HW_MMU_PROT_WRITE:
|
||||
rc = ((attr & PTE_W) && (attr & PTE_R));
|
||||
break;
|
||||
case RT_HW_MMU_PROT_READ:
|
||||
rc = !!(attr & PTE_R);
|
||||
break;
|
||||
case RT_HW_MMU_PROT_EXECUTE:
|
||||
rc = !!(attr & PTE_X);
|
||||
break;
|
||||
default:
|
||||
RT_ASSERT(0);
|
||||
}
|
||||
|
||||
if (rc && (prot & RT_HW_MMU_PROT_USER))
|
||||
{
|
||||
rc = !!(attr & PTE_U);
|
||||
}
|
||||
return rc;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright (c) 2006-2022, RT-Thread Development Team
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2022-12-07 RT-Thread the first version
|
||||
*/
|
||||
|
||||
#include <rthw.h>
|
||||
#include <rtthread.h>
|
||||
#include "board.h"
|
||||
|
||||
void init_bss(void)
|
||||
{
|
||||
unsigned int *dst;
|
||||
|
||||
dst = &__bss_start;
|
||||
while (dst < &__bss_end)
|
||||
{
|
||||
*dst++ = 0;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (C) 2017-2024 Alibaba Group Holding Limited
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
INCLUDE "link_stacksize.lds"
|
||||
|
||||
MEMORY
|
||||
{
|
||||
DRAM : ORIGIN = 0xFFFFFFC000200000, LENGTH = 0x1000000 - 0x200000
|
||||
}
|
||||
|
||||
ENTRY(_start)
|
||||
SECTIONS
|
||||
{
|
||||
/* . = 0x80200000 ; */
|
||||
. = 0xFFFFFFC000200000;
|
||||
|
||||
/* __STACKSIZE__ = 4096; */
|
||||
__text_start = .;
|
||||
.start :
|
||||
{
|
||||
*(.start);
|
||||
} > DRAM
|
||||
. = ALIGN(8);
|
||||
.text :
|
||||
{
|
||||
*(.text)
|
||||
*(.text.*)
|
||||
*(.rodata)
|
||||
*(.rodata*)
|
||||
*(.glue_7)
|
||||
*(.glue_7t)
|
||||
*(.gnu.linkonce.t*)
|
||||
. = ALIGN(8);
|
||||
__fsymtab_start = .;
|
||||
KEEP(*(FSymTab))
|
||||
__fsymtab_end = .;
|
||||
. = ALIGN(8);
|
||||
__vsymtab_start = .;
|
||||
KEEP(*(VSymTab))
|
||||
__vsymtab_end = .;
|
||||
. = ALIGN(8);
|
||||
. = ALIGN(8);
|
||||
__rt_init_start = .;
|
||||
KEEP(*(SORT(.rti_fn*)))
|
||||
__rt_init_end = .;
|
||||
. = ALIGN(8);
|
||||
__rt_utest_tc_tab_start = .;
|
||||
KEEP(*(UtestTcTab))
|
||||
__rt_utest_tc_tab_end = .;
|
||||
. = ALIGN(8);
|
||||
__usbh_class_info_start__ = .;
|
||||
KEEP(*(.usbh_class_info))
|
||||
__usbh_class_info_end__ = .;
|
||||
. = ALIGN(8);
|
||||
_etext = .;
|
||||
} > DRAM
|
||||
.eh_frame_hdr :
|
||||
{
|
||||
*(.eh_frame_hdr)
|
||||
*(.eh_frame_entry)
|
||||
} > DRAM
|
||||
.eh_frame : ONLY_IF_RO { KEEP (*(.eh_frame)) } > DRAM
|
||||
. = ALIGN(8);
|
||||
__text_end = .;
|
||||
__text_size = __text_end - __text_start;
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data.*)
|
||||
*(.data1)
|
||||
*(.data1.*)
|
||||
. = ALIGN(8);
|
||||
PROVIDE( __global_pointer$ = . + 0x800 );
|
||||
*(.sdata)
|
||||
*(.sdata.*)
|
||||
} > DRAM
|
||||
.stack :
|
||||
{
|
||||
. = ALIGN(64);
|
||||
__stack_start__ = .;
|
||||
. += 65536;
|
||||
__stack_cpu0 = .;
|
||||
. += 65536;
|
||||
__stack_cpu1 = .;
|
||||
} > DRAM
|
||||
. = ALIGN(8);
|
||||
.osdebug :
|
||||
{
|
||||
_osdebug_start = .;
|
||||
. += 87K;
|
||||
_osdebug_end = .;
|
||||
} > DRAM
|
||||
. = ALIGN(8);
|
||||
.sbss :
|
||||
{
|
||||
__bss_start = .;
|
||||
*(.sbss)
|
||||
*(.sbss.*)
|
||||
*(.dynsbss)
|
||||
*(.scommon)
|
||||
} > DRAM
|
||||
.bss :
|
||||
{
|
||||
*(.bss)
|
||||
*(.bss.*)
|
||||
*(.dynbss)
|
||||
*(COMMON)
|
||||
. = ALIGN(64);
|
||||
__bss_end = .;
|
||||
} > DRAM
|
||||
_end = .;
|
||||
.stab 0 : { *(.stab) }
|
||||
.stabstr 0 : { *(.stabstr) }
|
||||
.stab.excl 0 : { *(.stab.excl) }
|
||||
.stab.exclstr 0 : { *(.stab.exclstr) }
|
||||
.stab.index 0 : { *(.stab.index) }
|
||||
.stab.indexstr 0 : { *(.stab.indexstr) }
|
||||
.comment 0 : { *(.comment) }
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
__STACKSIZE__ = 16384;
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,51 @@
|
||||
import os
|
||||
|
||||
# toolchains options
|
||||
ARCH ='risc-v'
|
||||
CPU ='c906'
|
||||
CROSS_TOOL ='gcc'
|
||||
|
||||
RTT_ROOT = os.getenv('RTT_ROOT') or os.path.join(os.getcwd(), '..', '..')
|
||||
|
||||
if os.getenv('RTT_CC'):
|
||||
CROSS_TOOL = os.getenv('RTT_CC')
|
||||
|
||||
if CROSS_TOOL == 'gcc':
|
||||
PLATFORM = 'gcc'
|
||||
EXEC_PATH = os.getenv('RTT_EXEC_PATH') or '/usr/bin'
|
||||
else:
|
||||
print('Please make sure your toolchains is GNU GCC!')
|
||||
exit(0)
|
||||
|
||||
BUILD = 'debug'
|
||||
|
||||
if PLATFORM == 'gcc':
|
||||
# toolchains
|
||||
PREFIX = os.getenv('RTT_CC_PREFIX') or 'riscv64-unknown-elf-'
|
||||
CC = PREFIX + 'gcc'
|
||||
CXX = PREFIX + 'g++'
|
||||
AS = PREFIX + 'gcc'
|
||||
AR = PREFIX + 'ar'
|
||||
LINK = PREFIX + 'gcc'
|
||||
TARGET_EXT = 'elf'
|
||||
SIZE = PREFIX + 'size'
|
||||
OBJDUMP = PREFIX + 'objdump'
|
||||
OBJCPY = PREFIX + 'objcopy'
|
||||
|
||||
DEVICE = ' -mcmodel=medany -march=rv64imafdc -mabi=lp64d '
|
||||
CFLAGS = DEVICE + '-ffreestanding -flax-vector-conversions -Wno-cpp -fno-common -ffunction-sections -fdata-sections -fstrict-volatile-bitfields -fdiagnostics-color=always'
|
||||
AFLAGS = ' -c' + DEVICE + ' -x assembler-with-cpp -D__ASSEMBLY__ '
|
||||
LFLAGS = DEVICE + ' -nostartfiles -Wl,--gc-sections,-Map=rtthread.map,-cref,-u,_start -T link.lds' + ' -lsupc++ -lgcc -static'
|
||||
CPATH = ''
|
||||
LPATH = ''
|
||||
|
||||
if BUILD == 'debug':
|
||||
CFLAGS += ' -O0 -ggdb -fvar-tracking '
|
||||
AFLAGS += ' -ggdb'
|
||||
else:
|
||||
CFLAGS += ' -O2 -Os'
|
||||
|
||||
CXXFLAGS = CFLAGS
|
||||
|
||||
DUMP_ACTION = OBJDUMP + ' -D -S $TARGET > rtthread.asm\n'
|
||||
POST_ACTION = OBJCPY + ' -O binary $TARGET rtthread.bin\n' + SIZE + ' $TARGET \n'
|
||||
Executable
+30
@@ -0,0 +1,30 @@
|
||||
#!/bin/bash
|
||||
|
||||
usage ()
|
||||
{
|
||||
echo "Usage:"
|
||||
echo "./run.sh [<path_to_image>]"
|
||||
echo "Note: if <path_to_image> is not provided, will create a 'sd.bin'"
|
||||
echo "in the current directory and load it by default."
|
||||
}
|
||||
|
||||
path_image=${1}
|
||||
|
||||
if [ -z $path_image ]; then
|
||||
path_image="./sd.bin"
|
||||
if [ ! -f $path_image ]; then
|
||||
dd if=/dev/zero of=$path_image bs=1024 count=65536
|
||||
mkfs.fat $path_image
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ! -f $path_image ]; then
|
||||
echo "ERROR: $path_image does not exist!"
|
||||
usage
|
||||
exit
|
||||
fi
|
||||
|
||||
qemu-system-riscv64 -cpu c906fd -machine virt -m 256M -nographic -kernel rtthread.bin \
|
||||
-drive if=none,file=$path_image,format=raw,id=blk0 -device virtio-blk-device,drive=blk0,bus=virtio-mmio-bus.0 \
|
||||
-device virtio-serial-device -chardev socket,host=127.0.0.1,port=4321,server=on,wait=off,telnet=on,id=console0 -device virtserialport,chardev=console0
|
||||
|
||||
Reference in new issue
Block a user