move loading into xous

Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
2023-12-30 23:41:50 +08:00
parent 8be17ff6f1
commit ff16f35de5
4 changed files with 595 additions and 347 deletions

View File

@ -1515,7 +1515,15 @@ impl Cpu {
self.mmu.memory_size()
}
pub fn phys_read_u8(&mut self, address: u64) -> u8 {
pub fn phys_read_u32(&self, address: u64) -> u32 {
self.mmu.load_word_raw(address)
}
pub fn phys_write_u32(&mut self, address: u64, value: u32) {
self.mmu.store_word_raw(address, value)
}
pub fn phys_read_u8(&self, address: u64) -> u8 {
self.mmu.load_raw(address)
}
@ -2458,9 +2466,9 @@ const INSTRUCTIONS: [Instruction; INSTRUCTION_NUM] = [
*dest = *src;
}
cpu.handler = Some(handler);
return Ok(())
return Ok(());
}
let exception_type = match cpu.privilege_mode {
PrivilegeMode::User => TrapType::EnvironmentCallFromUMode,
PrivilegeMode::Supervisor => TrapType::EnvironmentCallFromSMode,

View File

@ -173,7 +173,7 @@ impl Mmu {
self.clear_page_cache();
}
fn get_effective_address(&self, address: u64) -> u64 {
fn trim_to_xlen(&self, address: u64) -> u64 {
match self.xlen {
Xlen::Bit32 => address & 0xffffffff,
Xlen::Bit64 => address,
@ -204,7 +204,7 @@ impl Mmu {
if (v_address & 0xfff) <= (0x1000 - width) {
// Fast path. All bytes fetched are in the same page so
// translating an address only once.
let effective_address = self.get_effective_address(v_address);
let effective_address = self.trim_to_xlen(v_address);
self.translate_address(effective_address, &MemoryAccessType::Execute)
.map(|p_address| self.load_word_raw(p_address))
.map_err(|()| Trap {
@ -229,7 +229,7 @@ impl Mmu {
/// # Arguments
/// * `v_address` Virtual address
pub fn load(&mut self, v_address: u64) -> Result<u8, Trap> {
let effective_address = self.get_effective_address(v_address);
let effective_address = self.trim_to_xlen(v_address);
match self.translate_address(effective_address, &MemoryAccessType::Read) {
Ok(p_address) => Ok(self.load_raw(p_address)),
Err(()) => Err(Trap {
@ -403,8 +403,8 @@ impl Mmu {
///
/// # Arguments
/// * `p_address` Physical address
pub(crate) fn load_raw(&mut self, p_address: u64) -> u8 {
self.memory.read_byte(self.get_effective_address(p_address))
pub(crate) fn load_raw(&self, p_address: u64) -> u8 {
self.memory.read_byte(self.trim_to_xlen(p_address))
}
/// Loads two bytes from main memory or peripheral devices depending on
@ -412,9 +412,8 @@ impl Mmu {
///
/// # Arguments
/// * `p_address` Physical address
fn load_halfword_raw(&mut self, p_address: u64) -> u16 {
self.memory
.read_halfword(self.get_effective_address(p_address))
fn load_halfword_raw(&self, p_address: u64) -> u16 {
self.memory.read_halfword(self.trim_to_xlen(p_address))
}
/// Loads four bytes from main memory or peripheral devices depending on
@ -422,10 +421,8 @@ impl Mmu {
///
/// # Arguments
/// * `p_address` Physical address
pub fn load_word_raw(&mut self, p_address: u64) -> u32 {
let val = self.memory.read_word(self.get_effective_address(p_address));
// println!("Read value from {:08x}: {:08x}", p_address, val);
val
pub fn load_word_raw(&self, p_address: u64) -> u32 {
self.memory.read_word(self.trim_to_xlen(p_address))
}
/// Loads eight bytes from main memory or peripheral devices depending on
@ -433,9 +430,8 @@ impl Mmu {
///
/// # Arguments
/// * `p_address` Physical address
fn load_doubleword_raw(&mut self, p_address: u64) -> u64 {
self.memory
.read_doubleword(self.get_effective_address(p_address))
fn load_doubleword_raw(&self, p_address: u64) -> u64 {
self.memory.read_doubleword(self.trim_to_xlen(p_address))
}
/// Stores a byte to main memory or peripheral devices depending on
@ -445,8 +441,7 @@ impl Mmu {
/// * `p_address` Physical address
/// * `value` data written
pub(crate) fn store_raw(&mut self, p_address: u64, value: u8) {
self.memory
.write_byte(self.get_effective_address(p_address), value)
self.memory.write_byte(self.trim_to_xlen(p_address), value)
}
/// Stores two bytes to main memory or peripheral devices depending on
@ -455,9 +450,9 @@ impl Mmu {
/// # Arguments
/// * `p_address` Physical address
/// * `value` data written
fn store_halfword_raw(&mut self, p_address: u64, value: u16) {
pub(crate) fn store_halfword_raw(&mut self, p_address: u64, value: u16) {
self.memory
.write_halfword(self.get_effective_address(p_address), value)
.write_halfword(self.trim_to_xlen(p_address), value)
}
/// Stores four bytes to main memory or peripheral devices depending on
@ -466,9 +461,8 @@ impl Mmu {
/// # Arguments
/// * `p_address` Physical address
/// * `value` data written
fn store_word_raw(&mut self, p_address: u64, value: u32) {
self.memory
.write_word(self.get_effective_address(p_address), value)
pub(crate) fn store_word_raw(&mut self, p_address: u64, value: u32) {
self.memory.write_word(self.trim_to_xlen(p_address), value)
}
/// Stores eight bytes to main memory or peripheral devices depending on
@ -479,7 +473,7 @@ impl Mmu {
/// * `value` data written
fn store_doubleword_raw(&mut self, p_address: u64, value: u64) {
self.memory
.write_doubleword(self.get_effective_address(p_address), value)
.write_doubleword(self.trim_to_xlen(p_address), value)
}
/// Checks if passed virtual address is valid (pointing a certain device) or not.
@ -489,10 +483,7 @@ impl Mmu {
/// * `v_address` Virtual address
pub fn validate_address(&mut self, v_address: u64) -> Option<bool> {
if let Ok(p_address) = self.translate_address(v_address, &MemoryAccessType::DontCare) {
Some(
self.memory
.validate_address(self.get_effective_address(p_address)),
)
Some(self.memory.validate_address(self.trim_to_xlen(p_address)))
} else {
None
}
@ -503,7 +494,7 @@ impl Mmu {
v_address: u64,
access_type: &MemoryAccessType,
) -> Result<u64, ()> {
let address = self.get_effective_address(v_address);
let address = self.trim_to_xlen(v_address);
let v_page = address & !0xfff;
if let Some(p_page) = match self.page_cache_enabled {
true => match access_type {
@ -750,7 +741,7 @@ impl MemoryWrapper {
self.memory.init(capacity);
}
pub fn read_byte(&mut self, p_address: u64) -> u8 {
pub fn read_byte(&self, p_address: u64) -> u8 {
debug_assert!(
p_address >= self.dram_base,
"Memory address must equals to or bigger than self.dram_base. {:X}",
@ -759,7 +750,7 @@ impl MemoryWrapper {
self.memory.read_byte(p_address - self.dram_base)
}
pub fn read_halfword(&mut self, p_address: u64) -> u16 {
pub fn read_halfword(&self, p_address: u64) -> u16 {
debug_assert!(
p_address >= self.dram_base && p_address.wrapping_add(1) >= self.dram_base,
"Memory address must equals to or bigger than self.dram_base. {:X}",
@ -768,7 +759,7 @@ impl MemoryWrapper {
self.memory.read_halfword(p_address - self.dram_base)
}
pub fn read_word(&mut self, p_address: u64) -> u32 {
pub fn read_word(&self, p_address: u64) -> u32 {
debug_assert!(
p_address >= self.dram_base && p_address.wrapping_add(3) >= self.dram_base,
"Memory address must equals to or bigger than self.dram_base. {:X}",
@ -777,7 +768,7 @@ impl MemoryWrapper {
self.memory.read_word(p_address - self.dram_base)
}
pub fn read_doubleword(&mut self, p_address: u64) -> u64 {
pub fn read_doubleword(&self, p_address: u64) -> u64 {
debug_assert!(
p_address >= self.dram_base && p_address.wrapping_add(7) >= self.dram_base,
"Memory address must equals to or bigger than self.dram_base. {:X}",