Files
DSA/dsa-emu/src/memory/mod.rs
T
2026-03-03 17:19:07 +00:00

91 lines
2.0 KiB
Rust

use serde::{Deserialize, Serialize};
use crate::{
memory::{mainstore::RandomAccessMemory, mmu::MMU},
processor::processor::Emulator,
};
mod cache;
pub mod mainstore;
pub mod mmu;
mod tlb;
pub type VirtAddr = u32;
pub type PhysAddr = u32;
pub enum FaultInfo {
PageFault,
}
#[repr(u32)]
#[derive(Serialize, Deserialize, Clone, Copy, Debug)]
enum RegionType {
Reserved,
Bootloader,
Kernel,
KernelTables,
Usable,
MMIO,
}
#[derive(Serialize, Deserialize, Debug, Clone, Copy)]
pub struct Region {
base: PhysAddr,
size: u32,
region_type: RegionType,
// flags for the emulator
#[serde(default)]
identity_map_on_boot: bool,
}
#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct MemoryMap {
table_addr: PhysAddr,
pub regions: Vec<Region>,
}
impl MemoryMap {
pub const DEFAULT_MEMORY_MAP_ADDR: PhysAddr = 0x1000;
pub fn new() -> Self {
MemoryMap {
table_addr: Self::DEFAULT_MEMORY_MAP_ADDR,
regions: Vec::new(),
}
}
pub fn apply(&self, cpu: &mut Emulator<impl RandomAccessMemory>) {
for reg in &self.regions {
if reg.identity_map_on_boot {
Self::identity_map(cpu.mmu_mut(), reg);
}
}
let mem = cpu.memory_mut();
let mut offset = self.table_addr;
for region in &self.regions {
println!("Wrote entry: {region:?} to page table");
mem.write_word(offset, region.base);
mem.write_word(offset + 4, region.size);
mem.write_word(offset + 8, region.region_type as u32);
offset += 12;
}
}
pub fn identity_map(mmu: &mut MMU, region: &Region) {
let first_page = region.base >> 12;
let page_count = (region.size >> 12);
for page in (first_page..first_page + page_count).map(|p| p << 12) {
mmu.create_mapping(page, page);
}
}
}
impl Default for MemoryMap {
fn default() -> Self {
ron::from_str(include_str!("../config/dsa.mmap.default.ron")).unwrap()
}
}