Implement ECALL and EBREAK, the final RV64I instructions!
This commit is contained in:
@@ -4,6 +4,8 @@ taitep's RISC-V Emulator.
|
|||||||
The goal is to support at least RV64GC and be able to run Linux,
|
The goal is to support at least RV64GC and be able to run Linux,
|
||||||
potentially more. No plans for RV32I or RV32/64E.
|
potentially more. No plans for RV32I or RV32/64E.
|
||||||
|
|
||||||
|
Currently implemented RISC-V ISA: `RV64I`
|
||||||
|
|
||||||
## Current Use
|
## Current Use
|
||||||
Currently, the emulator is nowhere near complete,
|
Currently, the emulator is nowhere near complete,
|
||||||
its not even at rv64i, but it does work for a subset of it.
|
its not even at rv64i, but it does work for a subset of it.
|
||||||
|
|||||||
@@ -93,4 +93,9 @@ impl Instruction {
|
|||||||
pub fn funct6(self) -> u8 {
|
pub fn funct6(self) -> u8 {
|
||||||
(self.0 >> 26 & 0x3f) as u8
|
(self.0 >> 26 & 0x3f) as u8
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Mostly/only used for the SYSTEM opcode
|
||||||
|
pub fn funct12(self) -> u16 {
|
||||||
|
(self.0 >> 20) as u16
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,6 +31,15 @@ pub enum ExceptionType {
|
|||||||
HardwareError = 19,
|
HardwareError = 19,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl ExceptionType {
|
||||||
|
pub fn with_no_value(self) -> Exception {
|
||||||
|
Exception {
|
||||||
|
type_: self,
|
||||||
|
value: 0,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Exception {
|
pub struct Exception {
|
||||||
pub type_: ExceptionType,
|
pub type_: ExceptionType,
|
||||||
|
|||||||
@@ -13,7 +13,10 @@ use crate::{
|
|||||||
consts::DWord,
|
consts::DWord,
|
||||||
core::Core,
|
core::Core,
|
||||||
decode::Instruction,
|
decode::Instruction,
|
||||||
exceptions::{Exception, ExceptionType::IllegalInstruction},
|
exceptions::{
|
||||||
|
Exception,
|
||||||
|
ExceptionType::{self, IllegalInstruction},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
fn illegal(instr: Instruction) -> Result<(), Exception> {
|
fn illegal(instr: Instruction) -> Result<(), Exception> {
|
||||||
@@ -130,6 +133,15 @@ pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), E
|
|||||||
}
|
}
|
||||||
_ => illegal(instr),
|
_ => illegal(instr),
|
||||||
},
|
},
|
||||||
|
0b11100 => match (instr.funct3(), instr.funct12(), instr.rs1(), instr.rd()) {
|
||||||
|
(0b000, 0b000000000000, 0, 0) => {
|
||||||
|
// TODO: When privilege modes are added, make the exception raised by ecall
|
||||||
|
// depend on privilege mode
|
||||||
|
Err(ExceptionType::EnvironmentCallFromMMode.with_no_value())
|
||||||
|
}
|
||||||
|
(0b000, 0b000000000001, 0, 0) => Err(ExceptionType::Breakpoint.with_no_value()),
|
||||||
|
_ => illegal(instr),
|
||||||
|
},
|
||||||
_ => illegal(instr),
|
_ => illegal(instr),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user