91 lines
2.0 KiB
Rust
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()
|
|
}
|
|
}
|