Skip to content

Commit 09ce096

Browse files
committed
Improve c906 qemu support
1 parent 7568ec9 commit 09ce096

31 files changed

+4055
-0
lines changed

bsp/xuantie/virt64/c906/.config

Lines changed: 1652 additions & 0 deletions
Large diffs are not rendered by default.

bsp/xuantie/virt64/c906/Kconfig

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
mainmenu "RT-Thread Project Configuration"
2+
3+
RTT_DIR := ../../../..
4+
PKGS_DIR := packages
5+
6+
source "$(RTT_DIR)/Kconfig"
7+
osource "$PKGS_DIR/Kconfig"
8+
rsource "board/Kconfig"
9+
10+
config BOARD_QEMU_VIRT_RV64
11+
bool
12+
select ARCH_RISCV64
13+
select ARCH_USING_RISCV_COMMON64
14+
select RT_USING_COMPONENTS_INIT
15+
select RT_USING_USER_MAIN
16+
select RT_USING_CACHE
17+
select ARCH_MM_MMU
18+
select ARCH_REMAP_KERNEL
19+
default y
20+
21+
config ENABLE_FPU
22+
bool "Enable FPU"
23+
select ARCH_RISCV_FPU
24+
default y
25+
26+
config __STACKSIZE__
27+
int "stack size for interrupt"
28+
default 8192

bsp/xuantie/virt64/c906/README.md

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
# XuanTie - C906 Series
2+
3+
## 一 简介
4+
5+
### 1. 内核
6+
7+
C906 是基于 RISC-V 指令架构的 64 位超高能效处理器,主要面向安防监控、智能音箱、扫码/刷脸支付等领域。
8+
9+
### 2.特点
10+
11+
• RV64IMA[FD]C[V] 指令架构;
12+
13+
• 5 级单发按序执行流水线;
14+
15+
• 一级哈佛结构的指令和数据缓存,大小为 8KB/16KB/32KB/64KB 可配置,缓存行为 64B;
16+
17+
• Sv39 内存管理单元,实现虚实地址转换与内存管理;
18+
19+
• 支持 AXI4.0 128 比特 Master 接口;
20+
21+
• 支持核内中断 CLINT 和中断控制器 PLIC;
22+
23+
• 支持 RISC-V Debug 标准。
24+
25+
• 遵循 RISC-V V 矢量扩展标准(revision 0.7.1);
26+
27+
• 算力可达 4G Flops(@1GHz);
28+
29+
• 支持矢量执行单元运算宽度 64 位和 128 位硬件可配置;
30+
31+
• 支持 INT8/INT16/INT32/INT64/FP16/FP32/BFP16 矢量运算;
32+
33+
### 3.BSP支持情况
34+
35+
- 当前BSP支持下述内核:
36+
37+
```asciiarmor
38+
c906 c906fd c906fdv
39+
```
40+
41+
- 当前BSP默认设置的内核是c906,该架构支持[F] [D]扩展,可以通过menuconfig工具使能[F]扩展或者[F] [D] 扩展。
42+
43+
- 当使用其他内核架构时需要修改,rtconfig.py文件中的`MCPU`字段。
44+
45+
### 4.运行QEMU
46+
47+
- BSP根目录下存在`qemu.bat`脚本,生成可执行文件后可点击该脚本直接启动QEMU.
48+
49+
## 二 工具
50+
51+
- 编译器: https://www.xrvm.cn/community/download?id=4433353576298909696
52+
- 模拟器: https://www.xrvm.cn/community/download?id=4397435198627713024
53+
54+
注:若上述链接中的编译器与模拟器不能使用,可以使用下述CDK中的编译器与模拟器
55+
56+
- SDK:https://www.xrvm.cn/community/download?id=4397799570420076544
57+
58+
## 三 调试方法
59+
60+
**下述调试方法以E906举例,本BSP操作方式一致**,搭建完成RT-Thread开发环境,在BSP根目录使用env工具在当前目录打开env。
61+
62+
![](figures/1.env.png)
63+
64+
使用前执行一次**menuconfig**命令,更新rtconfig.h配置,然后在当前目录执行**scons -j12**命令编译生成可可执行文件。
65+
66+
<img src="figures/2.scons.png" alt="env" style="zoom: 95%;" />
67+
68+
生成可执行文件,可以直接在命令行启动qemu或者配置vscode脚本借助vscode强大的插件进行图形化调试,qemu的相关命令可以查看玄铁qemu的[用户手册](https://www.xrvm.cn/community/download?id=4397435198627713024),下述是启动qemu的命令,在powershell或命令行可直接执行下述命令,注意qemu需要导出至环境变量或者使用绝对路径。
69+
70+
```shell
71+
qemu-system-riscv64 -machine smartl -nographic -kernel rtthread.elf -cpu e906
72+
```
73+
74+
下述是使用vscode调试的展示。
75+
76+
<img src="figures/3.vscode.png" alt="env" style="zoom: 63%;" />
77+
78+
一起为RISC-V加油!

bsp/xuantie/virt64/c906/SConscript

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
# for module compiling
2+
import os
3+
Import('RTT_ROOT')
4+
from building import *
5+
6+
cwd = GetCurrentDir()
7+
objs = []
8+
list = os.listdir(cwd)
9+
10+
for d in list:
11+
path = os.path.join(cwd, d)
12+
if os.path.isfile(os.path.join(path, 'SConscript')):
13+
objs = objs + SConscript(os.path.join(d, 'SConscript'))
14+
15+
Return('objs')

bsp/xuantie/virt64/c906/SConstruct

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
import os
2+
import sys
3+
import rtconfig
4+
from SCons.Script import *
5+
from termcolor import colored
6+
7+
if os.getenv('RTT_ROOT'):
8+
RTT_ROOT = os.getenv('RTT_ROOT')
9+
else:
10+
RTT_ROOT = os.path.normpath(os.getcwd() + '/../../../..')
11+
12+
sys.path = sys.path + [os.path.join(RTT_ROOT, 'tools')]
13+
14+
try:
15+
from building import *
16+
except:
17+
print('Cannot found RT-Thread root directory, please check RTT_ROOT')
18+
print(RTT_ROOT)
19+
exit(-1)
20+
21+
TARGET = 'rtthread.' + rtconfig.TARGET_EXT
22+
23+
print(colored('RT-Thread root directory: %s' % RTT_ROOT, 'green'))
24+
print(colored('Building path: %s' % os.path.abspath('.'), 'green'))
25+
print(colored('Building target: %s' % TARGET, 'green'))
26+
27+
DefaultEnvironment(tools=[])
28+
env = Environment(tools = ['mingw'],
29+
AS = rtconfig.AS, ASFLAGS = rtconfig.AFLAGS,
30+
CC = rtconfig.CC, CCFLAGS = rtconfig.CFLAGS,
31+
CXX = rtconfig.CXX, CXXFLAGS = rtconfig.CXXFLAGS,
32+
AR = rtconfig.AR, ARFLAGS = '-rc',
33+
LINK = rtconfig.LINK, LINKFLAGS = rtconfig.LFLAGS)
34+
env.PrependENVPath('PATH', rtconfig.EXEC_PATH)
35+
env['ASCOM'] = env['ASPPCOM']
36+
37+
Export('RTT_ROOT')
38+
Export('rtconfig')
39+
40+
41+
# prepare building environment
42+
objs = PrepareBuilding(env, RTT_ROOT, has_libcpu = False)
43+
44+
stack_size = 4096
45+
46+
if GetDepend('RT_USING_SMART'):
47+
# use smart link.lds
48+
env['LINKFLAGS'] = env['LINKFLAGS'].replace('link.lds', 'link_smart.lds')
49+
50+
stack_lds = open('link_stacksize.lds', 'w')
51+
if GetDepend('__STACKSIZE__'): stack_size = GetDepend('__STACKSIZE__')
52+
stack_lds.write('__STACKSIZE__ = %d;\n' % stack_size)
53+
stack_lds.close()
54+
55+
# make a building
56+
DoBuilding(TARGET, objs)
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
from building import *
2+
import os
3+
4+
cwd = GetCurrentDir()
5+
CPPPATH = [cwd]
6+
src = ['main.c']
7+
8+
group = DefineGroup('Applications', src, depend = [''], CPPPATH = CPPPATH)
9+
10+
Return('group')
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
#include <rtthread.h>
2+
3+
#define THREAD_PRIORITY 25
4+
#define THREAD_STACK_SIZE 2048
5+
#define THREAD_TIMESLICE 5
6+
7+
static rt_thread_t tid1 = RT_NULL;
8+
9+
/* 线程 1 的入口函数 */
10+
static void thread1_entry(void *parameter)
11+
{
12+
rt_uint32_t count = 0;
13+
14+
for (count = 0; count < 10 ; count++)
15+
{
16+
/* 线程 1 采用低优先级运行 */
17+
rt_kprintf("thread1 count: %d\n", count);
18+
rt_thread_mdelay(500);
19+
}
20+
rt_kprintf("thread1 exit\n");
21+
/* 线程 1 运行结束后也将自动被系统脱离 */
22+
}
23+
24+
#if defined(RT_VERSION_CHECK) && (RTTHREAD_VERSION >= RT_VERSION_CHECK(5, 0, 1))
25+
rt_align(RT_ALIGN_SIZE)
26+
#else
27+
ALIGN(RT_ALIGN_SIZE)
28+
#endif
29+
static char thread2_stack[1024];
30+
static struct rt_thread thread2;
31+
/* 线程 2 入口 */
32+
static void thread2_entry(void *param)
33+
{
34+
rt_uint32_t count = 0;
35+
36+
/* 线程 2 拥有较高的优先级,以抢占线程 1 而获得执行 */
37+
for (count = 0; count < 10 ; count++)
38+
{
39+
/* 线程 2 打印计数值 */
40+
rt_kprintf("thread2 count: %d\n", count);
41+
}
42+
rt_kprintf("thread2 exit\n");
43+
/* 线程 2 运行结束后也将自动被系统脱离 */
44+
}
45+
46+
/* 线程示例 */
47+
int main(void)
48+
{
49+
/* 创建线程 1,名称是 thread1,入口是 thread1_entry*/
50+
tid1 = rt_thread_create("thread1",
51+
thread1_entry, RT_NULL,
52+
THREAD_STACK_SIZE,
53+
THREAD_PRIORITY, THREAD_TIMESLICE);
54+
55+
/* 如果获得线程控制块,启动这个线程 */
56+
if (tid1 != RT_NULL)
57+
rt_thread_startup(tid1);
58+
59+
/* 初始化线程 2,名称是 thread2,入口是 thread2_entry */
60+
rt_thread_init(&thread2,
61+
"thread2",
62+
thread2_entry,
63+
RT_NULL,
64+
&thread2_stack[0],
65+
sizeof(thread2_stack),
66+
THREAD_PRIORITY - 1, THREAD_TIMESLICE);
67+
rt_thread_startup(&thread2);
68+
69+
return 0;
70+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/*
2+
* Copyright (c) 2006-2021, RT-Thread Development Team
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*
6+
* Change Logs:
7+
* Date Author Notes
8+
* 2021/08/19 bernard the first version
9+
*/
10+
11+
#include <rtthread.h>
12+
13+
#ifdef RT_USING_DFS
14+
#include <dfs_fs.h>
15+
#include <rtdbg.h>
16+
17+
int mnt_init(void)
18+
{
19+
if (rt_device_find("virtio-blk0"))
20+
{
21+
/* mount virtio-blk as root directory */
22+
if (dfs_mount("virtio-blk0", "/", "elm", 0, RT_NULL) == 0)
23+
{
24+
rt_kprintf("file system initialization done!\n");
25+
}
26+
else
27+
{
28+
if (dfs_mount("virtio-blk0", "/", "ext", 0, RT_NULL) == 0)
29+
{
30+
rt_kprintf("file system initialization done!\n");
31+
}
32+
else
33+
{
34+
rt_kprintf("file system initialization fail!\n");
35+
}
36+
}
37+
}
38+
39+
return 0;
40+
}
41+
INIT_ENV_EXPORT(mnt_init);
42+
#endif
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
menu "RISC-V QEMU virt64 configs"
2+
3+
config BSP_USING_VIRTIO
4+
bool "Using VirtIO"
5+
default y
6+
depends on RT_USING_DEVICE_OPS
7+
8+
config BSP_USING_VIRTIO_BLK
9+
bool "Using VirtIO BLK"
10+
select RT_USING_VIRTIO
11+
select RT_USING_VIRTIO_BLK
12+
default y
13+
depends on BSP_USING_VIRTIO
14+
15+
endmenu
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
import os
2+
import rtconfig
3+
from building import *
4+
5+
cwd = GetCurrentDir()
6+
7+
# add general drivers
8+
src = ['board.c']
9+
src += ['drv_uart.c']
10+
src += ['drv_virtio.c']
11+
12+
path = [cwd]
13+
14+
group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)
15+
Return('group')

0 commit comments

Comments
 (0)