进到了系统指令的环节,
一样先参考 RISC-V-TLM 和 exactstep 的做法,
恩...一言难尽。
先从指令介绍开始吧!
指令格式如下:
|31 20|19 15|14 12|11 7|6 0|
+-------------------------------------------+
| imm | rs1 | funct3 | rd | opcode |
+-------------------------------------------+
用来执行需要更高权限才能执行的功能,
例如作业系统的 system call,
在目前参考的指令及版本有提到原先是叫 SCALL,
但因为需要支援更多的使用情境,改成 ECALL。
|31 20|19 15|14 12|11 7|6 0|
+-------------------------------------------+
| 0 | 00000 | 000 | 00000 | 1110011 |
+-------------------------------------------+
用来中断程序的运作,
让系统可以把使用权转交给 Debugger。
其实 Debugger 的 Break Point 就是用这个指令实现的,
只是偷偷把指定位置的指令换掉了不跟使用者讲而已!
和 ECALL 一样,
在目前参考的指令及版本有提到原先是叫 SBREAK,
但因为需要支援更多的使用情境,改成 EBREAK。
|31 20|19 15|14 12|11 7|6 0|
+-------------------------------------------+
| 1 | 00000 | 000 | 00000 | 1110011 |
+-------------------------------------------+
github 页面 Tag: ITDay21
ECALL 在 RISC-V-TLM 的做法就是直接结束模拟。
exactstep 实作上把 ECALL 接起来自己做掉,
并没有跳到某个位置执行软件注册的 Handler 再跳回来的过程。
根据规格书对 Bare metal hardware platforms 的描述:
The hardware platform defines an execution environment
that begins at power-on reset.",
exactstep 的做法应该是符合规范的。
但还是比较喜欢让 Software 有弹性的做法,
目前先依照 RISC-V-TLM 的行为实作,
日後再扩充。
EBREAK 则是会发生 Trap,目前没有实作相关机制来处理,
等之後把 Interrupt 和 CSR 的部分做出来再回来拯救这个指令吧!
//instructionDecoderInterface.h
...
SYSTEM_OP = 0b1110011,
...
enum Func12 {
ECALL_FN12 = 0b0,
EBREAK_FN12 = 0b1,
};
...
//executor.cpp
...
case INSTRUCTION_DECODER_INTERFACE::SYSTEM_OP:
system_dispatch();
break;
...
void EXECUTOR::system_dispatch()
{
switch (instruction_decoder->get_func12()) {
case INSTRUCTION_DECODER_INTERFACE::ECALL_FN12:
ECALL_E();
break;
case INSTRUCTION_DECODER_INTERFACE::EBREAK_FN12:
EBREAK_E();
break;
default:
std::cout << "INVALID: Func3 in MISC_MEM_OP :" << instruction_decoder->get_func3() << std::endl;
break;
}
}
...
void EXECUTOR::ECALL_E()
{
sc_core::sc_stop();
}
void EXECUTOR::EBREAK_E()
{
sc_core::sc_stop();
}
新增了一个 system 专用的 get_func12
//instructionDecoder.cpp
...
uint32_t INSTRUCTION_DECODER::get_func12()
{
return instruction_value.range(31, 20);
}
...
加了一段测试程序,让最後一道指令 ECALL 结束 Simulator 的运作。
也因为这样,Cpu 里面的 Cycle Limit 可以移除了,
之後等做出 Exception 系列功能,
就可以用 Illegal Instruction Exceptions 取代。
//memory.cpp
...
0b000000000000'00000'000'00000'1110011, //ECALL
...
//cpu.cpp
...
void CPU::cpu_thread(void)
{
while(true) {
step();
wait(delay);
}
}
...
<<: [第二十只羊] 迷雾森林舞会XIV 进房间聊天 hotwire + stimulus 起步走
>>: [Day20] 第二十章 - 修改登入画面 (使用bootstrap 4.6的范例)
kafka是一套与昨天的NATS类似的分布式MQ系统,会用这两套也不是想要做差异比较,单纯只是有多一...
「泛型(Generics)」是 TypeScript 中很常会使用到的功能,泛型的概念简单来说,就是...
今天我们来看到~物件导向的三大特性~ 什麽是物件呢~ 物件是指类别的实例。 例如,有一个类别是Car...
这一天原本想贴一贴学员心得,所以完全没有准备什麽内容。 学员毕业心得,没有强制要每个离开的学员写。...
更新 我把从第一天到现在每天的 Home 目录都放上 GitHub 了,README.md 里面有...