NEMU ISA相关的API说明文档
为了提高性能, 这些API也可以通过宏定义实现, 但本文档还是以C变量或函数的方式列出, 以给出变量或函数的类型.
全局类型
word_t;
表示与ISA字长等长的无符号类型, 在32位的ISA中为uint32_t
, 在64位的ISA中为uint64_t
.
sword_t;
表示与ISA字长等长的有符号类型, 在32位的ISA中为int32_t
, 在64位的ISA中为int64_t
.
char *FMT_WORD;
word_t
类型对应的十六进制格式化说明符, 在32位的ISA中为"0x%08x"
, 在64位的ISA中为"0x%016lx"
.
Monitor相关
char isa_logo[];
用于在未实现指令的报错信息中提示开发者阅读相关的手册.
word_t RESET_VECTOR;
表示PC的初始值.
void init_isa();
在monitor初始化时调用, 进行至少如下ISA相关的初始化工作:
- 设置必要的寄存器初值, 如
PC
等 - 加载内置客户程序
寄存器相关
struct {
// ...
word_t pc;
} CPU_state;
寄存器结构的类型定义, 其中必须包含一个名为pc
, 类型为word_t
的成员.
CPU_state cpu;
寄存器结构的全局定义.
void isa_reg_display();
用于打印寄存器当前的值.
word_t isa_reg_str2val(const char *name, bool *success);
若存在名称为name
的寄存器, 则返回其当前值, 并设置success
为true
;
否则设置success
为false
.
指令执行相关
struct {
// ...
} ISADecodeInfo;
用于存放ISA相关的译码信息, 会嵌入在译码信息结构体Decode
的定义中.
vaddr_t isa_fetch_decode(Decode *s);
取出s->pc
指向的指令并译码, 同时更新s->snpc
, 最后返回一个用于标识指令执行辅助函数的ID.
虚拟内存相关
int isa_mmu_check(vaddr_t vaddr, int len, int type);
检查当前系统状态下对内存区间为[vaddr, vaddr + len)
, 类型为type
的访问是否需要经过地址转换.
其中type
可能为:
MEM_TYPE_IFETCH
: 取指令MEM_TYPE_READ
: 读数据MEM_TYPE_WRITE
: 写数据
函数返回值可能为:
MMU_DIRECT
: 该内存访问可以在物理内存上直接进行MMU_TRANSLATE
: 该内存访问需要经过地址转换MMU_FAIL
: 该内存访问失败, 需要抛出异常(如RISC架构不支持非对齐的内存访问)
paddr_t isa_mmu_translate(vaddr_t vaddr, int len, int type);
对内存区间为[vaddr, vaddr + len)
, 类型为type
的内存访问进行地址转换.
函数返回值可能为:
pg_paddr
|MEM_RET_OK
: 地址转换成功, 其中pg_paddr
为物理页面的地址(而不是vaddr
翻译后的物理地址)MEM_RET_FAIL
: 地址转换失败, 原因包括权限检查失败等不可恢复的原因, 一般需要抛出异常MEM_RET_CROSS_PAGE
: 地址转换失败, 原因为访存请求跨越了页面的边界
中断异常相关
vaddr_t isa_raise_intr(word_t NO, vaddr_t epc);
抛出一个号码为NO
的异常, 其中epc
为触发异常的指令PC, 返回异常处理的出口地址.
word_t isa_query_intr();
查询当前是否有未处理的中断, 若有则返回中断号码, 否则返回INTR_EMPTY
.
DiffTest相关
NEMU作为DUT时使用
bool isa_difftest_checkregs(CPU_state *ref_r, vaddr_t pc);
检查当前的寄存器状态是否与ref_r
相同, 其中pc
为cpu.pc
的上一条动态指令的PC, 即cpu.pc
的旧值.
如果状态相同, 则返回true
, 否则返回false
.
void isa_difftest_attach();
将当前的所有状态同步到REF, 并在之后的执行中开启DiffTest.
NEMU作为REF时使用
void isa_difftest_regcpy(void *dut, bool direction);
direction
为DIFFTEST_TO_DUT
时, 获取REF的寄存器状态到dut
;
direction
为DIFFTEST_TO_REF
时, 设置REF的寄存器状态为dut
.
void isa_difftest_raise_intr(word_t NO);
触发一个编号为NO
的异常.