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 IMAGE_START;

表示镜像在内存中的位置距离内存起始地址的偏移.


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相关的译码信息, 会嵌入在译码状态结构体DecodeExecState的定义中.


vaddr_t isa_exec_once();

执行cpu.pc指向的指令, 并更新cpu.pc, 返回被执行指令的下一条静态指令的PC.

内存相关

word_t PMEM_BASE;

表示物理内存的起始地址.


int isa_vaddr_check(vaddr_t vaddr, int type, int len);

检查当前系统状态是否支持内存区间为[vaddr, vaddr + len), 类型为type的内存访问. 其中type可能为:

  • MEM_TYPE_IFETCH: 取指令
  • MEM_TYPE_READ: 读数据
  • MEM_TYPE_WRITE: 写数据

函数返回值可能为:

  • MEM_RET_OK: 该内存访问可以在物理内存上直接进行
  • MEM_RET_NEED_TRANSLATE: 该内存访问需要经过地址转换
  • MEM_RET_FAIL: 该内存访问失败, 需要抛出异常(如RISC架构不支持非对齐的内存访问)

paddr_t isa_mmu_translate(vaddr_t vaddr, int type, int len);

对内存区间为[vaddr, vaddr + len), 类型为type的内存访问进行地址转换. 函数返回值可能为:

  • pg_paddr | MEM_RET_OK: 地址转换成功, 其中pg_paddr为物理页面的地址(而不是vaddr翻译后的物理地址)
  • MEM_RET_FAIL: 地址转换失败, 原因包括权限检查失败等不可恢复的原因, 一般需要抛出异常
  • MEM_RET_CROSS_PAGE: 地址转换失败, 原因为访存请求跨越了页面的边界

bool isa_has_mem_exception();

查询当前是否有访存请求抛出异常, 如有则返回true, 否则返回false

DiffTest相关

NEMU作为DUT时使用

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.

NEMU作为REF时使用

void isa_difftest_getregs(void *r);

将当前的寄存器状态复制到r中.


void isa_difftest_setregs(const void *r);

r中的寄存器状态复制到当前的寄存器中.


void isa_difftest_raise_intr(word_t NO);

触发一个编号为NO的中断/异常.

results matching ""

    No results matching ""