summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/basic_uart.rs47
-rw-r--r--src/core.rs50
-rw-r--r--src/exceptions.rs30
-rw-r--r--src/instructions.rs88
-rw-r--r--src/instructions/rvi.rs77
-rw-r--r--src/instructions/rvi/mem.rs140
-rw-r--r--src/lib.rs1
-rw-r--r--src/main.rs55
-rw-r--r--src/mem.rs154
9 files changed, 308 insertions, 334 deletions
diff --git a/src/basic_uart.rs b/src/basic_uart.rs
index 3380515..ec687e3 100644
--- a/src/basic_uart.rs
+++ b/src/basic_uart.rs
@@ -14,7 +14,8 @@ use std::time::Duration;
use nix::fcntl::fcntl;
use nix::fcntl::{FcntlArg, OFlag};
use trve::consts::{Byte, DWord, HWord, Word};
-use trve::mem::{MemAccessFault, MemDeviceInterface, PageNum};
+use trve::exceptions::ExceptionType;
+use trve::mem::{MemDeviceInterface, PageNum};
/// byte 0: rx/tx
/// byte 1: status (------rt, r=rxready, t=txready)/none
@@ -82,12 +83,12 @@ impl MemDeviceInterface for BasicUart {
_page: PageNum,
_offset: u16,
_value: DWord,
- ) -> Result<(), MemAccessFault> {
- Err(MemAccessFault)
+ ) -> Result<(), ExceptionType> {
+ Err(ExceptionType::StoreAmoAccessFault)
}
- fn write_word(&self, _page: PageNum, _offset: u16, _value: Word) -> Result<(), MemAccessFault> {
- Err(MemAccessFault)
+ fn write_word(&self, _page: PageNum, _offset: u16, _value: Word) -> Result<(), ExceptionType> {
+ Err(ExceptionType::StoreAmoAccessFault)
}
fn write_hword(
@@ -95,13 +96,13 @@ impl MemDeviceInterface for BasicUart {
_page: PageNum,
_offset: u16,
_value: HWord,
- ) -> Result<(), MemAccessFault> {
- Err(MemAccessFault)
+ ) -> Result<(), ExceptionType> {
+ Err(ExceptionType::StoreAmoAccessFault)
}
- fn write_byte(&self, page: PageNum, offset: u16, value: Byte) -> Result<(), MemAccessFault> {
+ fn write_byte(&self, page: PageNum, offset: u16, value: Byte) -> Result<(), ExceptionType> {
if page > 0 {
- return Err(MemAccessFault);
+ return Err(ExceptionType::StoreAmoAccessFault);
}
match offset {
@@ -109,31 +110,31 @@ impl MemDeviceInterface for BasicUart {
self.write(value);
Ok(())
}
- _ => Err(MemAccessFault),
+ _ => Err(ExceptionType::StoreAmoAccessFault),
}
}
- fn read_dword(&self, _page: PageNum, _offset: u16) -> Result<DWord, MemAccessFault> {
- Err(MemAccessFault)
+ fn read_dword(&self, _page: PageNum, _offset: u16) -> Result<DWord, ExceptionType> {
+ Err(ExceptionType::LoadAccessFault)
}
- fn read_word(&self, _page: PageNum, _offset: u16) -> Result<Word, MemAccessFault> {
- Err(MemAccessFault)
+ fn read_word(&self, _page: PageNum, _offset: u16) -> Result<Word, ExceptionType> {
+ Err(ExceptionType::LoadAccessFault)
}
- fn read_hword(&self, _page: PageNum, _offset: u16) -> Result<HWord, MemAccessFault> {
- Err(MemAccessFault)
+ fn read_hword(&self, _page: PageNum, _offset: u16) -> Result<HWord, ExceptionType> {
+ Err(ExceptionType::LoadAccessFault)
}
- fn read_byte(&self, page: PageNum, offset: u16) -> Result<Byte, MemAccessFault> {
+ fn read_byte(&self, page: PageNum, offset: u16) -> Result<Byte, ExceptionType> {
if page > 0 {
- return Err(MemAccessFault);
+ return Err(ExceptionType::LoadAccessFault);
}
match offset {
0 => Ok(self.read()),
1 => Ok(1 | (self.can_read() as u8) << 1),
- _ => Err(MemAccessFault),
+ _ => Err(ExceptionType::LoadAccessFault),
}
}
@@ -141,15 +142,15 @@ impl MemDeviceInterface for BasicUart {
&self,
_page: PageNum,
_offset: u16,
- ) -> Result<&std::sync::atomic::AtomicU32, MemAccessFault> {
- Err(MemAccessFault)
+ ) -> Result<&std::sync::atomic::AtomicU32, ExceptionType> {
+ Err(ExceptionType::StoreAmoAccessFault)
}
fn get_atomic_dword(
&self,
_page: PageNum,
_offset: u16,
- ) -> Result<&std::sync::atomic::AtomicU64, MemAccessFault> {
- Err(MemAccessFault)
+ ) -> Result<&std::sync::atomic::AtomicU64, ExceptionType> {
+ Err(ExceptionType::StoreAmoAccessFault)
}
}
diff --git a/src/core.rs b/src/core.rs
index 8fe5520..7e477c1 100644
--- a/src/core.rs
+++ b/src/core.rs
@@ -7,19 +7,11 @@
use crate::{
consts::{Addr, RegId, RegValue},
decode::Instruction,
+ exceptions::ExceptionType,
instructions::find_and_exec,
mem::MemConfig,
};
-// placeholder - change when exception system is in place
-pub(crate) type Exception = ();
-
-pub(crate) enum InstructionResult {
- Normal,
- Exception(Exception),
- // Pause,
-}
-
pub struct Core {
pub(crate) x_regs: [RegValue; 32],
pub(crate) pc: Addr,
@@ -40,50 +32,46 @@ impl Core {
let page = (self.pc / 4096) as usize;
let offset = (self.pc % 4096 / 4) as u16;
if !self.pc.is_multiple_of(4) {
- //replace eprint with logging, replace break with exception
- eprintln!("PC not aligned");
+ self.throw_exception(ExceptionType::InstructionAccessMisaligned);
break;
}
let instr = match self.mem.read_word(page, offset) {
Ok(i) => i,
Err(_) => {
- eprintln!("Memory access fault while fetching instruction");
- eprintln!("PC: {:x}", self.pc);
+ self.throw_exception(ExceptionType::InstructionAccessFault);
break;
}
};
if instr == 0 {
- eprintln!("Executing 0 instruction at {:x}", self.pc);
+ self.throw_exception(ExceptionType::IllegalInstruction);
break;
}
- assert_eq!(instr & 3, 3, "Compressed instructions not supported");
+ if instr & 3 != 3 {
+ self.throw_exception(ExceptionType::IllegalInstruction);
+ break;
+ }
let instr = Instruction(instr);
- let res = find_and_exec(instr, self);
-
- if let Some(res) = res {
- match res {
- InstructionResult::Normal => {}
- InstructionResult::Exception(_e) => {
- eprintln!("Exception from instruction");
- eprintln!("PC: {:016x}, instr: {:08x}", self.pc, instr.0);
- break;
- } // InstructionResult::Pause => {
- // eprintln!("Instruction asked for pause");
- // break;
- // }
+ match find_and_exec(instr, self) {
+ Ok(()) => {}
+ Err(e) => {
+ self.throw_exception(e);
+ eprintln!("instr: {:08x}", instr.0);
+ break;
}
- } else {
- eprintln!("Invalid Instruction {:08x} at PC: {:x}", instr.0, self.pc);
- break;
}
}
}
+ fn throw_exception(&mut self, exception_type: ExceptionType) {
+ eprintln!("Exception: {exception_type:?}");
+ dbg!(self.pc, self.x_regs);
+ }
+
pub fn reset(&mut self, pc: Addr) {
self.pc = pc;
}
diff --git a/src/exceptions.rs b/src/exceptions.rs
new file mode 100644
index 0000000..2929d65
--- /dev/null
+++ b/src/exceptions.rs
@@ -0,0 +1,30 @@
+// Copyright (c) 2025 taitep
+// SPDX-License-Identifier: MIT
+//
+// This file is part of TRVE (https://gitea.taitep.se/taitep/trve)
+// See LICENSE file in the project root for full license text.
+
+use int_enum::IntEnum;
+
+#[repr(u8)]
+#[allow(dead_code)]
+#[derive(Debug, Clone, Copy, PartialEq, Eq, IntEnum)]
+pub enum ExceptionType {
+ InstructionAccessMisaligned = 0,
+ InstructionAccessFault = 1,
+ IllegalInstruction = 2,
+ Breakpoint = 3,
+ LoadAddressMisaligned = 4,
+ LoadAccessFault = 5,
+ StoreAmoAddressMisaligned = 6,
+ StoreAmoAccessFault = 7,
+ EnvironmentCallFromUMode = 8,
+ EnvironmentCallFromSMode = 9,
+ EnvironmentCallFromMMode = 11,
+ InstructionPageFault = 12,
+ LoadPageFault = 13,
+ StoreAmoPageFault = 15,
+ DoubleTrap = 16,
+ SoftwareCheck = 18,
+ HardwareError = 19,
+}
diff --git a/src/instructions.rs b/src/instructions.rs
index e4d5b03..482ea5d 100644
--- a/src/instructions.rs
+++ b/src/instructions.rs
@@ -7,67 +7,81 @@
mod rvi;
use crate::{
- core::{Core, InstructionResult},
+ core::Core,
decode::Instruction,
+ exceptions::ExceptionType::{self, IllegalInstruction},
};
-pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Option<InstructionResult> {
+pub(crate) fn find_and_exec(instr: Instruction, core: &mut Core) -> Result<(), ExceptionType> {
match instr.opcode_noncompressed() {
0b01100 => match (instr.funct7(), instr.funct3()) {
// OP
- (0b0000000, 0b000) => Some(rvi::add(core, instr)),
- (0b0100000, 0b000) => Some(rvi::sub(core, instr)),
- (0b0000000, 0b111) => Some(rvi::and(core, instr)),
- (0b0000000, 0b110) => Some(rvi::or(core, instr)),
- _ => None,
+ (0b0000000, 0b000) => rvi::add(core, instr),
+ (0b0100000, 0b000) => rvi::sub(core, instr),
+ (0b0000000, 0b111) => rvi::and(core, instr),
+ (0b0000000, 0b110) => rvi::or(core, instr),
+ _ => Err(IllegalInstruction),
},
0b00100 => match instr.funct3() {
// OP_IMM
- 0b000 => Some(rvi::addi(core, instr)),
- 0b001 => (instr.funct6() == 0).then(|| rvi::slli(core, instr)),
+ 0b000 => rvi::addi(core, instr),
+ 0b001 => {
+ if instr.funct6() == 0 {
+ rvi::slli(core, instr)
+ } else {
+ Err(IllegalInstruction)
+ }
+ }
0b101 => match instr.funct6() {
// immediate right-shift
- 0b000000 => Some(rvi::srli(core, instr)),
- _ => None,
+ 0b000000 => rvi::srli(core, instr),
+ _ => Err(IllegalInstruction),
},
- 0b111 => Some(rvi::andi(core, instr)),
- _ => None,
+ 0b111 => rvi::andi(core, instr),
+ _ => Err(IllegalInstruction),
},
0b00110 => match instr.funct3() {
// OP_IMM_32
- 0b000 => Some(rvi::addiw(core, instr)),
- _ => None,
+ 0b000 => rvi::addiw(core, instr),
+ _ => Err(IllegalInstruction),
},
0b01000 => match instr.funct3() {
// STORE
- 0b000 => Some(rvi::sb(core, instr)),
- 0b001 => Some(rvi::sh(core, instr)),
- 0b010 => Some(rvi::sw(core, instr)),
- 0b011 => Some(rvi::sd(core, instr)),
- _ => None,
+ 0b000 => rvi::sb(core, instr),
+ 0b001 => rvi::sh(core, instr),
+ 0b010 => rvi::sw(core, instr),
+ 0b011 => rvi::sd(core, instr),
+ _ => Err(IllegalInstruction),
},
0b00000 => match instr.funct3() {
// LOAD
- 0b000 => Some(rvi::lb(core, instr)),
- 0b100 => Some(rvi::lbu(core, instr)),
- 0b001 => Some(rvi::lh(core, instr)),
- 0b010 => Some(rvi::lw(core, instr)),
- 0b011 => Some(rvi::ld(core, instr)),
- _ => None,
+ 0b000 => rvi::lb(core, instr),
+ 0b100 => rvi::lbu(core, instr),
+ 0b001 => rvi::lh(core, instr),
+ 0b010 => rvi::lw(core, instr),
+ 0b011 => rvi::ld(core, instr),
+ _ => Err(IllegalInstruction),
},
0b11000 => match instr.funct3() {
// BRANCH
- 0b000 => Some(rvi::beq(core, instr)),
- 0b001 => Some(rvi::bne(core, instr)),
- 0b100 => Some(rvi::blt(core, instr)),
- 0b110 => Some(rvi::bltu(core, instr)),
- 0b111 => Some(rvi::bgeu(core, instr)),
- _ => None,
+ 0b000 => rvi::beq(core, instr),
+ 0b001 => rvi::bne(core, instr),
+ 0b100 => rvi::blt(core, instr),
+ 0b110 => rvi::bltu(core, instr),
+ 0b111 => rvi::bgeu(core, instr),
+ _ => Err(IllegalInstruction),
},
- 0b01101 => Some(rvi::lui(core, instr)),
- 0b00101 => Some(rvi::auipc(core, instr)),
- 0b11011 => Some(rvi::jal(core, instr)),
- 0b11001 => (instr.funct3() == 0).then(|| rvi::jalr(core, instr)),
- _ => None,
+ 0b01101 => rvi::lui(core, instr),
+ 0b00101 => rvi::auipc(core, instr),
+ 0b11011 => rvi::jal(core, instr),
+ // 0b11001 => (instr.funct3() == 0).then(|| rvi::jalr(core, instr)),
+ 0b11001 => {
+ if instr.funct3() == 0 {
+ rvi::jalr(core, instr)
+ } else {
+ Err(IllegalInstruction)
+ }
+ }
+ _ => Err(IllegalInstruction),
}
}
diff --git a/src/instructions/rvi.rs b/src/instructions/rvi.rs
index 6766fdf..d8439fa 100644
--- a/src/instructions/rvi.rs
+++ b/src/instructions/rvi.rs
@@ -4,157 +4,154 @@
// This file is part of TRVE (https://gitea.taitep.se/taitep/trve)
// See LICENSE file in the project root for full license text.
-use crate::{
- core::{Core, InstructionResult},
- decode::Instruction,
-};
+use crate::{core::Core, decode::Instruction, exceptions::ExceptionType};
mod mem;
pub use mem::*;
-pub fn add(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn add(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
core.reg_write(
instr.rd(),
core.reg_read(instr.rs1())
.wrapping_add(core.reg_read(instr.rs2())),
);
core.advance_pc();
- InstructionResult::Normal
+ Ok(())
}
-pub fn sub(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn sub(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
core.reg_write(
instr.rd(),
core.reg_read(instr.rs1())
.wrapping_sub(core.reg_read(instr.rs2())),
);
core.advance_pc();
- InstructionResult::Normal
+ Ok(())
}
-pub fn addi(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn addi(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
core.reg_write(
instr.rd(),
core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()),
);
core.advance_pc();
- InstructionResult::Normal
+ Ok(())
}
-pub fn addiw(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn addiw(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
let res = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i()) as i32;
core.reg_write(instr.rd(), res as i64 as u64);
core.advance_pc();
- InstructionResult::Normal
+ Ok(())
}
-pub fn and(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn and(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
core.reg_write(
instr.rd(),
core.reg_read(instr.rs1()) & core.reg_read(instr.rs2()),
);
core.advance_pc();
- InstructionResult::Normal
+ Ok(())
}
-pub fn andi(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn andi(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
core.reg_write(instr.rd(), core.reg_read(instr.rs1()) & instr.imm_i());
core.advance_pc();
- InstructionResult::Normal
+ Ok(())
}
-pub fn or(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn or(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
core.reg_write(
instr.rd(),
core.reg_read(instr.rs1()) | core.reg_read(instr.rs2()),
);
core.advance_pc();
- InstructionResult::Normal
+ Ok(())
}
-pub fn slli(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn slli(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
core.reg_write(instr.rd(), core.reg_read(instr.rs1()) << instr.imm_shamt());
core.advance_pc();
- InstructionResult::Normal
+ Ok(())
}
-pub fn srli(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn srli(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
core.reg_write(instr.rd(), core.reg_read(instr.rs1()) >> instr.imm_shamt());
core.advance_pc();
- InstructionResult::Normal
+ Ok(())
}
-pub fn lui(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn lui(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
core.reg_write(instr.rd(), instr.imm_u());
core.advance_pc();
- InstructionResult::Normal
+ Ok(())
}
-pub fn auipc(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn auipc(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
core.reg_write(instr.rd(), core.pc.wrapping_add(instr.imm_u()));
core.advance_pc();
- InstructionResult::Normal
+ Ok(())
}
-pub fn jal(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn jal(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
core.reg_write(instr.rd(), core.pc.wrapping_add(4));
core.pc = core.pc.wrapping_add(instr.imm_j());
- InstructionResult::Normal
+ Ok(())
}
-pub fn jalr(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn jalr(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
core.reg_write(instr.rd(), core.pc.wrapping_add(4));
core.pc = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i());
- InstructionResult::Normal
+ Ok(())
}
-pub fn beq(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn beq(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
if core.reg_read(instr.rs1()) == core.reg_read(instr.rs2()) {
core.pc = core.pc.wrapping_add(instr.imm_b());
} else {
core.advance_pc();
}
- InstructionResult::Normal
+ Ok(())
}
-pub fn bne(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn bne(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
if core.reg_read(instr.rs1()) != core.reg_read(instr.rs2()) {
core.pc = core.pc.wrapping_add(instr.imm_b());
} else {
core.advance_pc();
}
- InstructionResult::Normal
+ Ok(())
}
-pub fn blt(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn blt(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
if (core.reg_read(instr.rs1()) as i64) < (core.reg_read(instr.rs2()) as i64) {
core.pc = core.pc.wrapping_add(instr.imm_b());
} else {
core.advance_pc();
}
- InstructionResult::Normal
+ Ok(())
}
-pub fn bgeu(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn bgeu(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
if core.reg_read(instr.rs1()) >= core.reg_read(instr.rs2()) {
core.pc = core.pc.wrapping_add(instr.imm_b());
} else {
core.advance_pc();
}
- InstructionResult::Normal
+ Ok(())
}
-pub fn bltu(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn bltu(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
if core.reg_read(instr.rs1()) < core.reg_read(instr.rs2()) {
core.pc = core.pc.wrapping_add(instr.imm_b());
} else {
core.advance_pc();
}
- InstructionResult::Normal
+ Ok(())
}
diff --git a/src/instructions/rvi/mem.rs b/src/instructions/rvi/mem.rs
index c948519..ad938cb 100644
--- a/src/instructions/rvi/mem.rs
+++ b/src/instructions/rvi/mem.rs
@@ -7,177 +7,145 @@
use crate::{
consts::{Addr, Byte, DWord, HWord, Word},
core::Core,
- instructions::{Instruction, InstructionResult},
+ exceptions::ExceptionType,
+ instructions::Instruction,
mem::PageNum,
};
// TODO: Support misaligned memory access
-pub fn sd(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn sd(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_s());
if !addr.is_multiple_of(std::mem::size_of::<DWord>() as Addr) {
- return InstructionResult::Exception(());
+ return Err(ExceptionType::StoreAmoAddressMisaligned);
}
let page = (addr / 4096) as PageNum;
let offset = (addr / 8 & ((4096 / 8 as Addr) - 1)) as u16;
let value = core.reg_read(instr.rs2());
- match core.mem.write_dword(page, offset, value) {
- Ok(_) => {
- core.advance_pc();
- InstructionResult::Normal
- }
- Err(_) => InstructionResult::Exception(()),
- }
+ core.mem.write_dword(page, offset, value)?;
+ core.advance_pc();
+
+ Ok(())
}
-pub fn ld(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn ld(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i());
if !addr.is_multiple_of(std::mem::size_of::<DWord>() as Addr) {
- return InstructionResult::Exception(());
+ return Err(ExceptionType::LoadAddressMisaligned);
}
let page = (addr / 4096) as PageNum;
let offset = (addr / 8 & ((4096 / 8 as Addr) - 1)) as u16;
- match core.mem.read_dword(page, offset) {
- Ok(x) => {
- core.reg_write(instr.rd(), x);
- core.advance_pc();
- InstructionResult::Normal
- }
- Err(_) => InstructionResult::Exception(()),
- }
+ core.reg_write(instr.rd(), core.mem.read_dword(page, offset)?);
+ core.advance_pc();
+ Ok(())
}
-pub fn sw(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn sw(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_s());
if !addr.is_multiple_of(std::mem::size_of::<Word>() as Addr) {
- return InstructionResult::Exception(());
+ return Err(ExceptionType::StoreAmoAddressMisaligned);
}
let page = (addr / 4096) as PageNum;
let offset = (addr / 4 & ((4096 / 4 as Addr) - 1)) as u16;
let value = core.reg_read(instr.rs2()) as Word;
- match core.mem.write_word(page, offset, value) {
- Ok(_) => {
- core.advance_pc();
- InstructionResult::Normal
- }
- Err(_) => InstructionResult::Exception(()),
- }
+ core.mem.write_word(page, offset, value)?;
+ core.advance_pc();
+ Ok(())
}
-pub fn lw(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn lw(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i());
if !addr.is_multiple_of(std::mem::size_of::<Word>() as Addr) {
- return InstructionResult::Exception(());
+ return Err(ExceptionType::LoadAddressMisaligned);
}
let page = (addr / 4096) as PageNum;
let offset = (addr / 4 & ((4096 / 4 as Addr) - 1)) as u16;
- match core.mem.read_word(page, offset) {
- Ok(x) => {
- core.reg_write(instr.rd(), x as i32 as i64 as DWord);
- core.advance_pc();
- InstructionResult::Normal
- }
- Err(_) => InstructionResult::Exception(()),
- }
+ core.reg_write(
+ instr.rd(),
+ core.mem.read_word(page, offset)? as i32 as i64 as DWord,
+ );
+ core.advance_pc();
+ Ok(())
}
-pub fn sh(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn sh(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_s());
if !addr.is_multiple_of(std::mem::size_of::<HWord>() as Addr) {
- return InstructionResult::Exception(());
+ return Err(ExceptionType::StoreAmoAddressMisaligned);
}
let page = (addr / 4096) as PageNum;
let offset = (addr / 2 & ((4096 / 2 as Addr) - 1)) as u16;
let value = core.reg_read(instr.rs2()) as HWord;
- match core.mem.write_hword(page, offset, value) {
- Ok(_) => {
- core.advance_pc();
- InstructionResult::Normal
- }
- Err(_) => InstructionResult::Exception(()),
- }
+ core.mem.write_hword(page, offset, value)?;
+ core.advance_pc();
+ Ok(())
}
-pub fn lh(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn lh(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i());
if !addr.is_multiple_of(std::mem::size_of::<HWord>() as Addr) {
- return InstructionResult::Exception(());
+ return Err(ExceptionType::LoadAddressMisaligned);
}
let page = (addr / 4096) as PageNum;
let offset = (addr / 2 & ((4096 / 2 as Addr) - 1)) as u16;
- match core.mem.read_hword(page, offset) {
- Ok(x) => {
- core.reg_write(instr.rd(), x as i16 as i64 as DWord);
- core.advance_pc();
- InstructionResult::Normal
- }
- Err(_) => InstructionResult::Exception(()),
- }
+ core.reg_write(
+ instr.rd(),
+ core.mem.read_hword(page, offset)? as i16 as i64 as DWord,
+ );
+ core.advance_pc();
+ Ok(())
}
-pub fn sb(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn sb(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_s());
let page = (addr / 4096) as PageNum;
let offset = (addr & (4096 as Addr - 1)) as u16;
let value = core.reg_read(instr.rs2()) as Byte;
- match core.mem.write_byte(page, offset, value) {
- Ok(_) => {
- core.advance_pc();
- InstructionResult::Normal
- }
- Err(_) => InstructionResult::Exception(()),
- }
+ core.mem.write_byte(page, offset, value)?;
+ core.advance_pc();
+ Ok(())
}
-pub fn lb(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn lb(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i());
let page = (addr / 4096) as PageNum;
let offset = (addr & (4096 as Addr - 1)) as u16;
- match core.mem.read_byte(page, offset) {
- Ok(x) => {
- let x = x as i8 as i64 as DWord;
- core.reg_write(instr.rd(), x);
- core.advance_pc();
- InstructionResult::Normal
- }
- Err(_) => InstructionResult::Exception(()),
- }
+ core.reg_write(
+ instr.rd(),
+ core.mem.read_byte(page, offset)? as i8 as i64 as DWord,
+ );
+ core.advance_pc();
+ Ok(())
}
-pub fn lbu(core: &mut Core, instr: Instruction) -> InstructionResult {
+pub fn lbu(core: &mut Core, instr: Instruction) -> Result<(), ExceptionType> {
let addr = core.reg_read(instr.rs1()).wrapping_add(instr.imm_i());
let page = (addr / 4096) as PageNum;
let offset = (addr & (4096 as Addr - 1)) as u16;
- match core.mem.read_byte(page, offset) {
- Ok(x) => {
- let x = x as DWord;
- core.reg_write(instr.rd(), x);
- core.advance_pc();
- InstructionResult::Normal
- }
- Err(_) => InstructionResult::Exception(()),
- }
+ core.reg_write(instr.rd(), core.mem.read_byte(page, offset)? as DWord);
+ core.advance_pc();
+ Ok(())
}
diff --git a/src/lib.rs b/src/lib.rs
index cf59a4b..7a9ac37 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -1,5 +1,6 @@
pub mod consts;
pub mod core;
mod decode;
+pub mod exceptions;
mod instructions;
pub mod mem;
diff --git a/src/main.rs b/src/main.rs
index 90fffd3..615f3bf 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -9,7 +9,8 @@ use std::{env, sync::Arc, time::Duration};
use trve::{
consts::{Byte, DWord, HWord, Word},
core::Core,
- mem::{DeviceEntry, MemAccessFault, MemConfig, MemDeviceInterface, PageNum, Ram},
+ exceptions::ExceptionType,
+ mem::{DeviceEntry, MemConfig, MemDeviceInterface, PageNum, Ram},
};
use anyhow::{Result, bail};
@@ -63,12 +64,7 @@ mod basic_uart;
struct DbgOut;
impl MemDeviceInterface for DbgOut {
- fn write_dword(
- &self,
- page: PageNum,
- offset: u16,
- value: DWord,
- ) -> Result<(), trve::mem::MemAccessFault> {
+ fn write_dword(&self, page: PageNum, offset: u16, value: DWord) -> Result<(), ExceptionType> {
eprintln!(
"Wrote DWord {value:016x} to Debug-Out page {page}, offset {offset} (byte {})",
offset * 8
@@ -76,12 +72,7 @@ impl MemDeviceInterface for DbgOut {
Ok(())
}
- fn write_word(
- &self,
- page: PageNum,
- offset: u16,
- value: Word,
- ) -> Result<(), trve::mem::MemAccessFault> {
+ fn write_word(&self, page: PageNum, offset: u16, value: Word) -> Result<(), ExceptionType> {
eprintln!(
"Wrote Word {value:08x} to Debug-Out page {page}, offset {offset} (byte {})",
offset * 4
@@ -89,12 +80,7 @@ impl MemDeviceInterface for DbgOut {
Ok(())
}
- fn write_hword(
- &self,
- page: PageNum,
- offset: u16,
- value: HWord,
- ) -> Result<(), trve::mem::MemAccessFault> {
+ fn write_hword(&self, page: PageNum, offset: u16, value: HWord) -> Result<(), ExceptionType> {
eprintln!(
"Wrote HWord {value:04x} to Debug-Out page {page}, offset {offset} (byte {})",
offset * 2
@@ -102,45 +88,40 @@ impl MemDeviceInterface for DbgOut {
Ok(())
}
- fn write_byte(
- &self,
- page: PageNum,
- offset: u16,
- value: Byte,
- ) -> Result<(), trve::mem::MemAccessFault> {
+ fn write_byte(&self, page: PageNum, offset: u16, value: Byte) -> Result<(), ExceptionType> {
eprintln!("Wrote Byte {value:02x} to Debug-Out page {page}, offset {offset}");
Ok(())
}
- fn read_dword(&self, _page: PageNum, _offset: u16) -> Result<DWord, trve::mem::MemAccessFault> {
- Err(MemAccessFault)
+ fn read_dword(&self, _page: PageNum, _offset: u16) -> Result<DWord, ExceptionType> {
+ Err(ExceptionType::LoadAccessFault)
}
- fn read_word(&self, _page: PageNum, _offset: u16) -> Result<Word, trve::mem::MemAccessFault> {
- Err(MemAccessFault)
+ fn read_word(&self, _page: PageNum, _offset: u16) -> Result<Word, ExceptionType> {
+ Err(ExceptionType::LoadAccessFault)
}
- fn read_hword(&self, _page: PageNum, _offset: u16) -> Result<HWord, trve::mem::MemAccessFault> {
- Err(MemAccessFault)
+ fn read_hword(&self, _page: PageNum, _offset: u16) -> Result<HWord, ExceptionType> {
+ Err(ExceptionType::LoadAccessFault)
}
- fn read_byte(&self, _page: PageNum, _offset: u16) -> Result<Byte, trve::mem::MemAccessFault> {
- Err(MemAccessFault)
+ fn read_byte(&self, _page: PageNum, _offset: u16) -> Result<Byte, ExceptionType> {
+ Err(ExceptionType::LoadAccessFault)
}
fn get_atomic_word(
&self,
_page: PageNum,
_offset: u16,
- ) -> Result<&std::sync::atomic::AtomicU32, trve::mem::MemAccessFault> {
- Err(MemAccessFault)
+ ) -> Result<&std::sync::atomic::AtomicU32, ExceptionType> {
+ Err(ExceptionType::StoreAmoAccessFault)
}
fn get_atomic_dword(
&self,
_page: PageNum,
_offset: u16,
- ) -> Result<&std::sync::atomic::AtomicU64, trve::mem::MemAccessFault> {
- Err(MemAccessFault)
+ ) -> Result<&std::sync::atomic::AtomicU64, ExceptionType> {
+ Err(ExceptionType::StoreAmoAccessFault)
}
}
diff --git a/src/mem.rs b/src/mem.rs
index 44e1dc7..21cabec 100644
--- a/src/mem.rs
+++ b/src/mem.rs
@@ -11,7 +11,10 @@ use std::sync::{
use memmap2::MmapMut;
-use crate::consts::{Byte, DWord, HWord, Word};
+use crate::{
+ consts::{Byte, DWord, HWord, Word},
+ exceptions::ExceptionType,
+};
pub type PageNum = usize;
@@ -45,38 +48,46 @@ impl MemConfig {
}
}
- pub fn read_dword(&self, page: PageNum, offset: u16) -> Result<DWord, MemAccessFault> {
+ pub fn read_dword(&self, page: PageNum, offset: u16) -> Result<DWord, ExceptionType> {
if page_in_range(page, self.ram_start, self.ram.pages) {
self.ram.read_dword(page - self.ram_start, offset)
} else {
- let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
+ let entry = self
+ .find_device_by_page(page)
+ .ok_or(ExceptionType::LoadAccessFault)?;
entry.interface.read_dword(page - entry.base, offset)
}
}
- pub fn read_word(&self, page: PageNum, offset: u16) -> Result<Word, MemAccessFault> {
+ pub fn read_word(&self, page: PageNum, offset: u16) -> Result<Word, ExceptionType> {
if page_in_range(page, self.ram_start, self.ram.pages) {
self.ram.read_word(page - self.ram_start, offset)
} else {
- let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
+ let entry = self
+ .find_device_by_page(page)
+ .ok_or(ExceptionType::LoadAccessFault)?;
entry.interface.read_word(page - entry.base, offset)
}
}
- pub fn read_hword(&self, page: PageNum, offset: u16) -> Result<HWord, MemAccessFault> {
+ pub fn read_hword(&self, page: PageNum, offset: u16) -> Result<HWord, ExceptionType> {
if page_in_range(page, self.ram_start, self.ram.pages) {
self.ram.read_hword(page - self.ram_start, offset)
} else {
- let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
+ let entry = self
+ .find_device_by_page(page)
+ .ok_or(ExceptionType::LoadAccessFault)?;
entry.interface.read_hword(page - entry.base, offset)
}
}
- pub fn read_byte(&self, page: PageNum, offset: u16) -> Result<Byte, MemAccessFault> {
+ pub fn read_byte(&self, page: PageNum, offset: u16) -> Result<Byte, ExceptionType> {
if page_in_range(page, self.ram_start, self.ram.pages) {
self.ram.read_byte(page - self.ram_start, offset)
} else {
- let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
+ let entry = self
+ .find_device_by_page(page)
+ .ok_or(ExceptionType::LoadAccessFault)?;
entry.interface.read_byte(page - entry.base, offset)
}
@@ -87,26 +98,25 @@ impl MemConfig {
page: PageNum,
offset: u16,
value: DWord,
- ) -> Result<(), MemAccessFault> {
+ ) -> Result<(), ExceptionType> {
if page_in_range(page, self.ram_start, self.ram.pages) {
self.ram.write_dword(page - self.ram_start, offset, value)
} else {
- let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
+ let entry = self
+ .find_device_by_page(page)
+ .ok_or(ExceptionType::StoreAmoAccessFault)?;
entry
.interface
.write_dword(page - entry.base, offset, value)
}
}
- pub fn write_word(
- &self,
- page: PageNum,
- offset: u16,
- value: Word,
- ) -> Result<(), MemAccessFault> {
+ pub fn write_word(&self, page: PageNum, offset: u16, value: Word) -> Result<(), ExceptionType> {
if page_in_range(page, self.ram_start, self.ram.pages) {
self.ram.write_word(page - self.ram_start, offset, value)
} else {
- let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
+ let entry = self
+ .find_device_by_page(page)
+ .ok_or(ExceptionType::StoreAmoAccessFault)?;
entry.interface.write_word(page - entry.base, offset, value)
}
}
@@ -115,26 +125,25 @@ impl MemConfig {
page: PageNum,
offset: u16,
value: HWord,
- ) -> Result<(), MemAccessFault> {
+ ) -> Result<(), ExceptionType> {
if page_in_range(page, self.ram_start, self.ram.pages) {
self.ram.write_hword(page - self.ram_start, offset, value)
} else {
- let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
+ let entry = self
+ .find_device_by_page(page)
+ .ok_or(ExceptionType::StoreAmoAccessFault)?;
entry
.interface
.write_hword(page - entry.base, offset, value)
}
}
- pub fn write_byte(
- &self,
- page: PageNum,
- offset: u16,
- value: Byte,
- ) -> Result<(), MemAccessFault> {
+ pub fn write_byte(&self, page: PageNum, offset: u16, value: Byte) -> Result<(), ExceptionType> {
if page_in_range(page, self.ram_start, self.ram.pages) {
self.ram.write_byte(page - self.ram_start, offset, value)
} else {
- let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
+ let entry = self
+ .find_device_by_page(page)
+ .ok_or(ExceptionType::StoreAmoAccessFault)?;
entry.interface.write_byte(page - entry.base, offset, value)
}
}
@@ -143,7 +152,7 @@ impl MemConfig {
&self,
page: PageNum,
offset: u16,
- ) -> Result<&AtomicU64, MemAccessFault> {
+ ) -> Result<&AtomicU64, ExceptionType> {
if page_in_range(page, self.ram_start, self.ram.pages) {
debug_assert!(((offset * 8) as usize) < PAGE_SIZE);
let index = page * (PAGE_SIZE / 8) + (offset as usize);
@@ -151,18 +160,16 @@ impl MemConfig {
self.ram
.buf_transmuted::<AtomicU64>()
.get(index)
- .ok_or(MemAccessFault)
+ .ok_or(ExceptionType::HardwareError)
}
} else {
- let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
+ let entry = self
+ .find_device_by_page(page)
+ .ok_or(ExceptionType::StoreAmoAccessFault)?;
entry.interface.get_atomic_dword(page - entry.base, offset)
}
}
- pub fn get_atomic_word(
- &self,
- page: PageNum,
- offset: u16,
- ) -> Result<&AtomicU32, MemAccessFault> {
+ pub fn get_atomic_word(&self, page: PageNum, offset: u16) -> Result<&AtomicU32, ExceptionType> {
if page_in_range(page, self.ram_start, self.ram.pages) {
debug_assert!(((offset * 4) as usize) < PAGE_SIZE);
let index = page * (PAGE_SIZE / 4) + (offset as usize);
@@ -170,10 +177,12 @@ impl MemConfig {
self.ram
.buf_transmuted::<AtomicU32>()
.get(index)
- .ok_or(MemAccessFault)
+ .ok_or(ExceptionType::HardwareError)
}
} else {
- let entry = self.find_device_by_page(page).ok_or(MemAccessFault)?;
+ let entry = self
+ .find_device_by_page(page)
+ .ok_or(ExceptionType::StoreAmoAccessFault)?;
entry.interface.get_atomic_word(page - entry.base, offset)
}
}
@@ -232,46 +241,46 @@ impl Ram {
}
#[inline]
- pub fn read_dword(&self, page: PageNum, offset: u16) -> Result<DWord, MemAccessFault> {
+ pub fn read_dword(&self, page: PageNum, offset: u16) -> Result<DWord, ExceptionType> {
debug_assert!(((offset * 8) as usize) < PAGE_SIZE);
let index = page * (PAGE_SIZE / 8) + (offset as usize);
Ok(unsafe {
self.buf_transmuted::<AtomicU64>()
.get(index)
- .ok_or(MemAccessFault)
+ .ok_or(ExceptionType::LoadAccessFault)
}?
.load(Relaxed))
}
#[inline]
- pub fn read_word(&self, page: PageNum, offset: u16) -> Result<Word, MemAccessFault> {
+ pub fn read_word(&self, page: PageNum, offset: u16) -> Result<Word, ExceptionType> {
debug_assert!(((offset * 4) as usize) < PAGE_SIZE);
let index = page * (PAGE_SIZE / 4) + (offset as usize);
Ok(unsafe {
self.buf_transmuted::<AtomicU32>()
.get(index)
- .ok_or(MemAccessFault)
+ .ok_or(ExceptionType::LoadAccessFault)
}?
.load(Relaxed))
}
#[inline]
- pub fn read_hword(&self, page: PageNum, offset: u16) -> Result<HWord, MemAccessFault> {
+ pub fn read_hword(&self, page: PageNum, offset: u16) -> Result<HWord, ExceptionType> {
debug_assert!(((offset * 2) as usize) < PAGE_SIZE);
let index = page * (PAGE_SIZE / 2) + (offset as usize);
Ok(unsafe {
self.buf_transmuted::<AtomicU16>()
.get(index)
- .ok_or(MemAccessFault)
+ .ok_or(ExceptionType::LoadAccessFault)
}?
.load(Relaxed))
}
#[inline]
- pub fn read_byte(&self, page: PageNum, offset: u16) -> Result<Byte, MemAccessFault> {
+ pub fn read_byte(&self, page: PageNum, offset: u16) -> Result<Byte, ExceptionType> {
debug_assert!((offset as usize) < PAGE_SIZE);
let index = page * PAGE_SIZE + (offset as usize);
Ok(self
.buf_atomic()
.get(index)
- .ok_or(MemAccessFault)?
+ .ok_or(ExceptionType::LoadAccessFault)?
.load(Relaxed))
}
@@ -281,30 +290,25 @@ impl Ram {
page: PageNum,
offset: u16,
value: DWord,
- ) -> Result<(), MemAccessFault> {
+ ) -> Result<(), ExceptionType> {
debug_assert!(((offset * 8) as usize) < PAGE_SIZE);
let index = page * (PAGE_SIZE / 8) + (offset as usize);
unsafe {
self.buf_transmuted::<AtomicU64>()
.get(index)
- .ok_or(MemAccessFault)
+ .ok_or(ExceptionType::StoreAmoAccessFault)
}?
.store(value, Relaxed);
Ok(())
}
#[inline]
- pub fn write_word(
- &self,
- page: PageNum,
- offset: u16,
- value: Word,
- ) -> Result<(), MemAccessFault> {
+ pub fn write_word(&self, page: PageNum, offset: u16, value: Word) -> Result<(), ExceptionType> {
debug_assert!(((offset * 4) as usize) < PAGE_SIZE);
let index = page * (PAGE_SIZE / 4) + (offset as usize);
unsafe {
self.buf_transmuted::<AtomicU32>()
.get(index)
- .ok_or(MemAccessFault)
+ .ok_or(ExceptionType::StoreAmoAccessFault)
}?
.store(value, Relaxed);
Ok(())
@@ -315,29 +319,24 @@ impl Ram {
page: PageNum,
offset: u16,
value: HWord,
- ) -> Result<(), MemAccessFault> {
+ ) -> Result<(), ExceptionType> {
debug_assert!(((offset * 2) as usize) < PAGE_SIZE);
let index = page * (PAGE_SIZE / 2) + (offset as usize);
unsafe {
self.buf_transmuted::<AtomicU16>()
.get(index)
- .ok_or(MemAccessFault)
+ .ok_or(ExceptionType::StoreAmoAccessFault)
}?
.store(value, Relaxed);
Ok(())
}
#[inline]
- pub fn write_byte(
- &self,
- page: PageNum,
- offset: u16,
- value: Byte,
- ) -> Result<(), MemAccessFault> {
+ pub fn write_byte(&self, page: PageNum, offset: u16, value: Byte) -> Result<(), ExceptionType> {
debug_assert!((offset as usize) < PAGE_SIZE);
let index = page * PAGE_SIZE + (offset as usize);
self.buf_atomic()
.get(index)
- .ok_or(MemAccessFault)?
+ .ok_or(ExceptionType::StoreAmoAccessFault)?
.store(value, Relaxed);
Ok(())
}
@@ -351,21 +350,16 @@ pub struct DeviceEntry {
}
pub trait MemDeviceInterface {
- fn write_dword(&self, page: PageNum, offset: u16, value: DWord) -> Result<(), MemAccessFault>;
- fn write_word(&self, page: PageNum, offset: u16, value: Word) -> Result<(), MemAccessFault>;
- fn write_hword(&self, page: PageNum, offset: u16, value: HWord) -> Result<(), MemAccessFault>;
- fn write_byte(&self, page: PageNum, offset: u16, value: Byte) -> Result<(), MemAccessFault>;
-
- fn read_dword(&self, page: PageNum, offset: u16) -> Result<DWord, MemAccessFault>;
- fn read_word(&self, page: PageNum, offset: u16) -> Result<Word, MemAccessFault>;
- fn read_hword(&self, page: PageNum, offset: u16) -> Result<HWord, MemAccessFault>;
- fn read_byte(&self, page: PageNum, offset: u16) -> Result<Byte, MemAccessFault>;
-
- fn get_atomic_word(&self, page: PageNum, offset: u16) -> Result<&AtomicU32, MemAccessFault>;
- fn get_atomic_dword(&self, page: PageNum, offset: u16) -> Result<&AtomicU64, MemAccessFault>;
+ fn write_dword(&self, page: PageNum, offset: u16, value: DWord) -> Result<(), ExceptionType>;
+ fn write_word(&self, page: PageNum, offset: u16, value: Word) -> Result<(), ExceptionType>;
+ fn write_hword(&self, page: PageNum, offset: u16, value: HWord) -> Result<(), ExceptionType>;
+ fn write_byte(&self, page: PageNum, offset: u16, value: Byte) -> Result<(), ExceptionType>;
+
+ fn read_dword(&self, page: PageNum, offset: u16) -> Result<DWord, ExceptionType>;
+ fn read_word(&self, page: PageNum, offset: u16) -> Result<Word, ExceptionType>;
+ fn read_hword(&self, page: PageNum, offset: u16) -> Result<HWord, ExceptionType>;
+ fn read_byte(&self, page: PageNum, offset: u16) -> Result<Byte, ExceptionType>;
+
+ fn get_atomic_word(&self, page: PageNum, offset: u16) -> Result<&AtomicU32, ExceptionType>;
+ fn get_atomic_dword(&self, page: PageNum, offset: u16) -> Result<&AtomicU64, ExceptionType>;
}
-
-/// Error that means something has gone wrong accessing memory
-/// Examples are: Accessing unmapped memory, accessing an MMIO register at the wrong size
-#[derive(Debug)]
-pub struct MemAccessFault;