使用riscv-tests进行指令测试(一)


本文属于《 TinyEMU模拟器基础系列教程》之一,欢迎查看其它文章。

1 riscv-tests简介

riscv-tests,是用于验证RISC-V处理器实现,是否符合其指令集架构规范的一组测试程序。

具体来说,riscv-tests目录包含isa、debug、mt和benchmarks的测试文件、底层相关驱动以及编译的文件,用于测试RISC-V CPU的实现。

  • 其中,benchmark测试,包含一些业内公认的C代码测试集;
  • 而ISA测试,则包含定向指令测试,如机器/用户/监督者模式下I/A/C/D/F/M类型的指令测试。

使用riscv-test套件可以帮助开发人员,验证他们的RISC-V处理器或模拟器实现的正确性和稳定性。

  • 通过将编译生成的测试程序,烧录到RISC-V处理器或模拟器实现的设备上并运行,测试程序会执行一系列的测试用例,检查处理器实现是否正确。
  • 通过这种方式,开发人员可以及时发现并修复处理器或模拟器实现中的BUG,确保其符合RISC-V ISA的规范。

riscv-tests官网:http://riscv.org/riscv-tests/
riscv-tests仓库:https://github.com/riscv/riscv-tests

2 安装riscv交叉编译器

riscv交叉编译器,有两种版本:

  • elf版,只支持静态链接,主要用于嵌入式系统,更通用更简单;
  • glibc版,支持静态链接和动态链接,主要用于Linux操作系统,更复杂。

我们这里使用elf版,编译好的elf版RISC-V交叉编译器:
riscv64-elf-ubuntu-20.04-nightly-2023.01.31-nightly.tar.gz

解压

tar -xvzf riscv64-elf-ubuntu-20.04-nightly-2023.01.31-nightly.tar.gz

编辑.bashrc

vim ~/.bashrc

将编译器bin路径(/home/tools/riscv/bin替换为自己的路径),加入.bashrc文件末尾。

export PATH=/home/tools/riscv/bin:$PATH

使路径生效

source ~/.bashrc

最后,查看编译器版本,以验证安装

riscv64-unknown-elf-gcc -v

会打印出gcc版本,编译器环境搭建好了。

3 编译riscv-tests

下载riscv-tests源码

git clone https://github.com/riscv/riscv-tests

进入源码目录

cd riscv-tests

更新子模块到最新状态

git submodule update --init --recursive

自动默认配置

autoconf

配置前缀

./configure --prefix=$RISCV/target

执行编译,默认会全部编译

make

若想部分编译,也可执行以下命令。

  • 仅编译riscv-tests/isa下,某一种类型用例:
    如rv64ui,则先cd isa,然后再make rv64ui;编译结果在isa目录下。
  • 编译riscv-tests/isa所有用例:
    则在riscv-tests目录下,执行make isa;编译结果在isa目录下。
  • 编译riscv-tests/benchmarks所有用例:
    则在riscv-tests目录下,执行make benchmarks;编译结果在benchmarks目录下。
  • make clean,可以将所有编译结果,全部清除。
  • 用例被编译后,输出有2类文件:
    一类为可执行程序,另一类为dump文件(该可执行程序对应的汇编源码)。
    在这里插入图片描述

安装(可选),会将编译结果,拷贝到/target/share/riscv-tests目录下。

make install

4 在TinyEMU中运行测试用例

我们以rv64ui-p-add为例,其对应的汇编源文件为rv64ui-p-add.dump。

4.1 ELF转RAW格式

TinyEMU只支持原始(RAW)的可执行文件,因此需要格式转换。

ELF格式rv64ui-p-add,转为RAW格式rv64ui-p-add.bin:

riscv64-unknown-elf-objcopy -O binary rv64ui-p-add rv64ui-p-add.bin

4.2 修改TinyEMU配置文件

我们查看rv64ui-p-add.dump文件:

0000000080000000 <_start>:
    80000000:	0500006f          	j	80000050 <reset_vector>

该程序从0x80000000开始执行,这与TinyEMU中Bootloader(如bbl64.bin)的起始地址完全一致。

因此,我们要想在TinyEMU中,运行rv64ui-p-add.bin,那么把TinyEMU配置文件中,bbl64.bin修改为rv64ui-p-add.bin即可。

比如,root-riscv64.cfg中:


/* VM configuration file */
{
    version: 1,
    machine: "riscv64",
    memory_size: 128,
    bios: "rv64ui-p-add.bin",
    kernel: "kernel-riscv64.bin",
    cmdline: "console=hvc0 root=/dev/vda rw",
    drive0: { file: "initramfs.ext2" },
    eth0: { driver: "user" },
}

bios选项,配置为rv64ui-p-add.bin,其他保持不变。
到这里,rv64ui-p-add.bin,已经可以在TinyEMU中运行了。

4.3 修改riscv_cpu.c

对于riscv-tests生成的一个测试用例,我们可以通过如下条件,来判断测试是否通过。

  • 若测试失败
    • a7设为0x5d;
    • gp左移一位加1后传给a0;
    • 随后调用ecall指令。
  • 若测试成功
    • a7设为0x5d;
    • a0设为0;
    • gp设为1;
    • 随后调用ecall指令。

因此,我们可以修改TinyEMU中ecall指令实现,检查a7,gp等寄存器,来判断是否测试成功。

修改riscv_cpu.c中,raise_exception2函数,如下所示:

static void raise_exception2(RISCVCPUState *s, uint32_t cause,
                             target_ulong tval)
{
	...

	if (s->reg[17] == 0x5d) {  //a7 == 0x5d
		if (s->reg[10] == 0) { // a0 == 0
			printf("Test Pass\n");
		} else { // a0 != 0
			printf("Test #%d Failed\n", s->reg[10]/2);
		}
	}

	...
}

增加a7和a0寄存器判断逻辑。

4.4 运行rv64ui-p-add

启动TinyEMU,以执行rv64ui-p-add

./temu -ctrlc root-riscv64.cfg

rv64ui-p-add需要放到,与temu同一目录下

rv64ui-p-add.bin执行完毕,TinyEMU打印出Test Pass,表明rv64ui-p-add.bin中所有指令测试成功。

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

百里杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值