Compare commits

..

2 Commits

7 changed files with 65 additions and 79 deletions

2
.rust-analyzer.toml Normal file
View File

@@ -0,0 +1,2 @@
[diagnostics]
disabled = ["inactive-code"]

View File

@@ -13,7 +13,7 @@ use std::time::Duration;
use nix::fcntl::fcntl; use nix::fcntl::fcntl;
use nix::fcntl::{FcntlArg, OFlag}; use nix::fcntl::{FcntlArg, OFlag};
use trve::exceptions::{MemoryException, MemoryExceptionType}; use trve::exceptions::MemoryExceptionType;
use trve::mem::MemDeviceInterface; use trve::mem::MemDeviceInterface;
/// byte 0: rx/tx /// byte 0: rx/tx
@@ -77,26 +77,20 @@ impl BasicUart {
} }
impl MemDeviceInterface for BasicUart { impl MemDeviceInterface for BasicUart {
fn write_byte(&self, addr: u64, value: u8) -> Result<(), MemoryException> { fn write_byte(&self, addr: u64, value: u8) -> Result<(), MemoryExceptionType> {
match addr { match addr {
0 => { 0 => {
self.write(value); self.write(value);
Ok(()) Ok(())
} }
_ => Err(MemoryException { _ => Err(MemoryExceptionType::AccessFault),
type_: MemoryExceptionType::AccessFault,
addr,
}),
} }
} }
fn read_byte(&self, addr: u64) -> Result<u8, MemoryException> { fn read_byte(&self, addr: u64) -> Result<u8, MemoryExceptionType> {
match addr { match addr {
0 => Ok(self.read()), 0 => Ok(self.read()),
1 => Ok(1 | (self.can_read() as u8) << 1), 1 => Ok(1 | (self.can_read() as u8) << 1),
_ => Err(MemoryException { _ => Err(MemoryExceptionType::AccessFault),
type_: MemoryExceptionType::AccessFault,
addr,
}),
} }
} }
} }

View File

@@ -58,7 +58,7 @@ impl Core {
let instr = match self.mem.read_word(self.pc) { let instr = match self.mem.read_word(self.pc) {
Ok(i) => i, Ok(i) => i,
Err(e) => { Err(e) => {
return Err(e.to_exception_instr()); return Err(e.into_exception_instr());
} }
}; };

View File

@@ -51,6 +51,12 @@ pub enum MemoryExceptionType {
PageFault, PageFault,
} }
impl MemoryExceptionType {
pub(crate) fn with_addr(self, addr: u64) -> MemoryException {
MemoryException { type_: self, addr }
}
}
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub struct MemoryException { pub struct MemoryException {
pub type_: MemoryExceptionType, pub type_: MemoryExceptionType,
@@ -58,7 +64,7 @@ pub struct MemoryException {
} }
impl MemoryException { impl MemoryException {
pub(crate) fn to_exception_store(&self) -> Exception { pub(crate) fn into_exception_store(self) -> Exception {
Exception { Exception {
type_: match self.type_ { type_: match self.type_ {
MemoryExceptionType::AddressMisaligned => ExceptionType::StoreAmoAddressMisaligned, MemoryExceptionType::AddressMisaligned => ExceptionType::StoreAmoAddressMisaligned,
@@ -69,7 +75,7 @@ impl MemoryException {
} }
} }
pub(crate) fn to_exception_instr(&self) -> Exception { pub(crate) fn into_exception_instr(self) -> Exception {
Exception { Exception {
type_: match self.type_ { type_: match self.type_ {
MemoryExceptionType::AddressMisaligned => ExceptionType::InstructionAccessFault, MemoryExceptionType::AddressMisaligned => ExceptionType::InstructionAccessFault,
@@ -80,7 +86,7 @@ impl MemoryException {
} }
} }
pub(crate) fn to_exception_load(&self) -> Exception { pub(crate) fn into_exception_load(self) -> Exception {
Exception { Exception {
type_: match self.type_ { type_: match self.type_ {
MemoryExceptionType::AddressMisaligned => ExceptionType::LoadAddressMisaligned, MemoryExceptionType::AddressMisaligned => ExceptionType::LoadAddressMisaligned,

View File

@@ -11,7 +11,7 @@ pub fn sd(core: &mut Core, instr: Instruction) -> Result<(), Exception> {
let value = core.reg_read(instr.rs2()); let value = core.reg_read(instr.rs2());
core.mem core.mem
.write_dword(addr, value) .write_dword(addr, value)
.map_err(|e| e.to_exception_store())?; .map_err(|e| e.into_exception_store())?;
core.advance_pc(); core.advance_pc();
Ok(()) Ok(())
} }
@@ -22,7 +22,7 @@ pub fn ld(core: &mut Core, instr: Instruction) -> Result<(), Exception> {
instr.rd(), instr.rd(),
core.mem core.mem
.read_dword(addr) .read_dword(addr)
.map_err(|e| e.to_exception_load())?, .map_err(|e| e.into_exception_load())?,
); );
core.advance_pc(); core.advance_pc();
Ok(()) Ok(())
@@ -33,7 +33,7 @@ pub fn sw(core: &mut Core, instr: Instruction) -> Result<(), Exception> {
let value = core.reg_read(instr.rs2()) as u32; let value = core.reg_read(instr.rs2()) as u32;
core.mem core.mem
.write_word(addr, value) .write_word(addr, value)
.map_err(|e| e.to_exception_store())?; .map_err(|e| e.into_exception_store())?;
core.advance_pc(); core.advance_pc();
Ok(()) Ok(())
} }
@@ -44,7 +44,7 @@ pub fn lw(core: &mut Core, instr: Instruction) -> Result<(), Exception> {
instr.rd(), instr.rd(),
core.mem core.mem
.read_word(addr) .read_word(addr)
.map_err(|e| e.to_exception_load())? as i32 as i64 as u64, .map_err(|e| e.into_exception_load())? as i32 as i64 as u64,
); );
core.advance_pc(); core.advance_pc();
Ok(()) Ok(())
@@ -56,7 +56,7 @@ pub fn lwu(core: &mut Core, instr: Instruction) -> Result<(), Exception> {
instr.rd(), instr.rd(),
core.mem core.mem
.read_word(addr) .read_word(addr)
.map_err(|e| e.to_exception_load())? as u64, .map_err(|e| e.into_exception_load())? as u64,
); );
core.advance_pc(); core.advance_pc();
Ok(()) Ok(())
@@ -67,7 +67,7 @@ pub fn sh(core: &mut Core, instr: Instruction) -> Result<(), Exception> {
let value = core.reg_read(instr.rs2()) as u16; let value = core.reg_read(instr.rs2()) as u16;
core.mem core.mem
.write_hword(addr, value) .write_hword(addr, value)
.map_err(|e| e.to_exception_store())?; .map_err(|e| e.into_exception_store())?;
core.advance_pc(); core.advance_pc();
Ok(()) Ok(())
} }
@@ -78,7 +78,7 @@ pub fn lh(core: &mut Core, instr: Instruction) -> Result<(), Exception> {
instr.rd(), instr.rd(),
core.mem core.mem
.read_hword(addr) .read_hword(addr)
.map_err(|e| e.to_exception_load())? as i16 as i64 as u64, .map_err(|e| e.into_exception_load())? as i16 as i64 as u64,
); );
core.advance_pc(); core.advance_pc();
Ok(()) Ok(())
@@ -90,7 +90,7 @@ pub fn lhu(core: &mut Core, instr: Instruction) -> Result<(), Exception> {
instr.rd(), instr.rd(),
core.mem core.mem
.read_hword(addr) .read_hword(addr)
.map_err(|e| e.to_exception_load())? as u64, .map_err(|e| e.into_exception_load())? as u64,
); );
core.advance_pc(); core.advance_pc();
Ok(()) Ok(())
@@ -101,7 +101,7 @@ pub fn sb(core: &mut Core, instr: Instruction) -> Result<(), Exception> {
let value = core.reg_read(instr.rs2()) as u8; let value = core.reg_read(instr.rs2()) as u8;
core.mem core.mem
.write_byte(addr, value) .write_byte(addr, value)
.map_err(|e| e.to_exception_store())?; .map_err(|e| e.into_exception_store())?;
core.advance_pc(); core.advance_pc();
Ok(()) Ok(())
} }
@@ -112,7 +112,7 @@ pub fn lb(core: &mut Core, instr: Instruction) -> Result<(), Exception> {
instr.rd(), instr.rd(),
core.mem core.mem
.read_byte(addr) .read_byte(addr)
.map_err(|e| e.to_exception_load())? as i8 as i64 as u64, .map_err(|e| e.into_exception_load())? as i8 as i64 as u64,
); );
core.advance_pc(); core.advance_pc();
Ok(()) Ok(())
@@ -124,7 +124,7 @@ pub fn lbu(core: &mut Core, instr: Instruction) -> Result<(), Exception> {
instr.rd(), instr.rd(),
core.mem core.mem
.read_byte(addr) .read_byte(addr)
.map_err(|e| e.to_exception_load())? as u64, .map_err(|e| e.into_exception_load())? as u64,
); );
core.advance_pc(); core.advance_pc();
Ok(()) Ok(())

View File

@@ -10,7 +10,7 @@ use clap::Parser;
use trve::{ use trve::{
core::Core, core::Core,
exceptions::MemoryException, exceptions::MemoryExceptionType,
gdb, gdb,
mem::{MemConfig, MemDeviceInterface, MmioRoot, Ram}, mem::{MemConfig, MemDeviceInterface, MmioRoot, Ram},
}; };
@@ -69,22 +69,22 @@ mod basic_uart;
struct DbgOut; struct DbgOut;
impl MemDeviceInterface for DbgOut { impl MemDeviceInterface for DbgOut {
fn write_dword(&self, addr: u64, value: u64) -> Result<(), MemoryException> { fn write_dword(&self, addr: u64, value: u64) -> Result<(), MemoryExceptionType> {
eprintln!("Wrote DWord {value:016x} to Debug-Out address {addr:x}"); eprintln!("Wrote DWord {value:016x} to Debug-Out address {addr:x}");
Ok(()) Ok(())
} }
fn write_word(&self, addr: u64, value: u32) -> Result<(), MemoryException> { fn write_word(&self, addr: u64, value: u32) -> Result<(), MemoryExceptionType> {
eprintln!("Wrote Word {value:08x} to Debug-Out address {addr:x}"); eprintln!("Wrote Word {value:08x} to Debug-Out address {addr:x}");
Ok(()) Ok(())
} }
fn write_hword(&self, addr: u64, value: u16) -> Result<(), MemoryException> { fn write_hword(&self, addr: u64, value: u16) -> Result<(), MemoryExceptionType> {
eprintln!("Wrote HWord {value:04x} to Debug-Out address {addr:x}"); eprintln!("Wrote HWord {value:04x} to Debug-Out address {addr:x}");
Ok(()) Ok(())
} }
fn write_byte(&self, addr: u64, value: u8) -> Result<(), MemoryException> { fn write_byte(&self, addr: u64, value: u8) -> Result<(), MemoryExceptionType> {
eprintln!("Wrote Byte {value:02x} to Debug-Out address {addr:x}"); eprintln!("Wrote Byte {value:02x} to Debug-Out address {addr:x}");
Ok(()) Ok(())
} }

View File

@@ -49,7 +49,7 @@ impl MemConfig {
addr, addr,
})?; })?;
interface.read_dword(addr) interface.read_dword(addr).map_err(|e| e.with_addr(addr))
} }
} }
pub fn read_word(&self, addr: u64) -> Result<u32, MemoryException> { pub fn read_word(&self, addr: u64) -> Result<u32, MemoryException> {
@@ -67,7 +67,7 @@ impl MemConfig {
addr, addr,
})?; })?;
interface.read_word(addr) interface.read_word(addr).map_err(|e| e.with_addr(addr))
} }
} }
pub fn read_hword(&self, addr: u64) -> Result<u16, MemoryException> { pub fn read_hword(&self, addr: u64) -> Result<u16, MemoryException> {
@@ -84,7 +84,7 @@ impl MemConfig {
type_: MemoryExceptionType::AccessFault, type_: MemoryExceptionType::AccessFault,
addr, addr,
})?; })?;
interface.read_hword(addr) interface.read_hword(addr).map_err(|e| e.with_addr(addr))
} }
} }
pub fn read_byte(&self, addr: u64) -> Result<u8, MemoryException> { pub fn read_byte(&self, addr: u64) -> Result<u8, MemoryException> {
@@ -95,7 +95,7 @@ impl MemConfig {
type_: MemoryExceptionType::AccessFault, type_: MemoryExceptionType::AccessFault,
addr, addr,
})?; })?;
interface.read_byte(addr) interface.read_byte(addr).map_err(|e| e.with_addr(addr))
} }
} }
@@ -113,7 +113,9 @@ impl MemConfig {
type_: MemoryExceptionType::AccessFault, type_: MemoryExceptionType::AccessFault,
addr, addr,
})?; })?;
interface.write_dword(addr, value) interface
.write_dword(addr, value)
.map_err(|e| e.with_addr(addr))
} }
} }
pub fn write_word(&self, addr: u64, value: u32) -> Result<(), MemoryException> { pub fn write_word(&self, addr: u64, value: u32) -> Result<(), MemoryException> {
@@ -130,7 +132,9 @@ impl MemConfig {
type_: MemoryExceptionType::AccessFault, type_: MemoryExceptionType::AccessFault,
addr, addr,
})?; })?;
interface.write_word(addr, value) interface
.write_word(addr, value)
.map_err(|e| e.with_addr(addr))
} }
} }
pub fn write_hword(&self, addr: u64, value: u16) -> Result<(), MemoryException> { pub fn write_hword(&self, addr: u64, value: u16) -> Result<(), MemoryException> {
@@ -147,7 +151,9 @@ impl MemConfig {
type_: MemoryExceptionType::AccessFault, type_: MemoryExceptionType::AccessFault,
addr, addr,
})?; })?;
interface.write_hword(addr, value) interface
.write_hword(addr, value)
.map_err(|e| e.with_addr(addr))
} }
} }
pub fn write_byte(&self, addr: u64, value: u8) -> Result<(), MemoryException> { pub fn write_byte(&self, addr: u64, value: u8) -> Result<(), MemoryException> {
@@ -158,7 +164,9 @@ impl MemConfig {
type_: MemoryExceptionType::AccessFault, type_: MemoryExceptionType::AccessFault,
addr, addr,
})?; })?;
interface.write_byte(addr, value) interface
.write_byte(addr, value)
.map_err(|e| e.with_addr(addr))
} }
} }
@@ -531,53 +539,29 @@ impl Default for MmioSecondLevel {
#[allow(unused_variables)] #[allow(unused_variables)]
pub trait MemDeviceInterface { pub trait MemDeviceInterface {
fn write_dword(&self, addr: u64, value: u64) -> Result<(), MemoryException> { fn write_dword(&self, addr: u64, value: u64) -> Result<(), MemoryExceptionType> {
Err(MemoryException { Err(MemoryExceptionType::AccessFault)
type_: MemoryExceptionType::AccessFault,
addr,
})
} }
fn write_word(&self, addr: u64, value: u32) -> Result<(), MemoryException> { fn write_word(&self, addr: u64, value: u32) -> Result<(), MemoryExceptionType> {
Err(MemoryException { Err(MemoryExceptionType::AccessFault)
type_: MemoryExceptionType::AccessFault,
addr,
})
} }
fn write_hword(&self, addr: u64, value: u16) -> Result<(), MemoryException> { fn write_hword(&self, addr: u64, value: u16) -> Result<(), MemoryExceptionType> {
Err(MemoryException { Err(MemoryExceptionType::AccessFault)
type_: MemoryExceptionType::AccessFault,
addr,
})
} }
fn write_byte(&self, addr: u64, value: u8) -> Result<(), MemoryException> { fn write_byte(&self, addr: u64, value: u8) -> Result<(), MemoryExceptionType> {
Err(MemoryException { Err(MemoryExceptionType::AccessFault)
type_: MemoryExceptionType::AccessFault,
addr,
})
} }
fn read_dword(&self, addr: u64) -> Result<u64, MemoryException> { fn read_dword(&self, addr: u64) -> Result<u64, MemoryExceptionType> {
Err(MemoryException { Err(MemoryExceptionType::AccessFault)
type_: MemoryExceptionType::AccessFault,
addr,
})
} }
fn read_word(&self, addr: u64) -> Result<u32, MemoryException> { fn read_word(&self, addr: u64) -> Result<u32, MemoryExceptionType> {
Err(MemoryException { Err(MemoryExceptionType::AccessFault)
type_: MemoryExceptionType::AccessFault,
addr,
})
} }
fn read_hword(&self, addr: u64) -> Result<u16, MemoryException> { fn read_hword(&self, addr: u64) -> Result<u16, MemoryExceptionType> {
Err(MemoryException { Err(MemoryExceptionType::AccessFault)
type_: MemoryExceptionType::AccessFault,
addr,
})
} }
fn read_byte(&self, addr: u64) -> Result<u8, MemoryException> { fn read_byte(&self, addr: u64) -> Result<u8, MemoryExceptionType> {
Err(MemoryException { Err(MemoryExceptionType::AccessFault)
type_: MemoryExceptionType::AccessFault,
addr,
})
} }
} }