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相关

unsigned 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的寄存器, 则返回其当前值, 并设置successtrue; 否则设置successfalse.

指令执行相关

struct {
  // ...
} ISADecodeInfo;

用于存放ISA相关的译码信息, 会嵌入在译码信息结构体Decode的定义中.


int isa_exec_once(Decode *s);

取出s->pc指向的指令并译码执行, 同时更新s->snpc.

虚拟内存相关

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相关

bool isa_difftest_checkregs(CPU_state *ref_r, vaddr_t pc);

检查当前的寄存器状态是否与ref_r相同, 其中pccpu.pc的上一条动态指令的PC, 即cpu.pc的旧值. 如果状态相同, 则返回true, 否则返回false.


void isa_difftest_attach();

将当前的所有状态同步到REF, 并在之后的执行中开启DiffTest.