1use std::sync::{Arc, Mutex};
2
3use machina_core::address::GPA;
4
5use crate::ram::RamBlock;
6
7pub trait MmioOps: Send {
15 fn read(&self, offset: u64, size: u32) -> u64;
16
17 fn write(&self, offset: u64, size: u32, val: u64);
18}
19
20pub enum RegionType {
23 Ram {
24 block: Arc<RamBlock>,
25 },
26 Rom {
27 block: Arc<RamBlock>,
28 },
29 Io {
30 ops: Arc<Mutex<Box<dyn MmioOps>>>,
31 },
32 Alias {
33 target: Box<MemoryRegion>,
34 offset: u64,
35 },
36 Container,
37}
38
39pub struct SubRegion {
42 pub region: MemoryRegion,
43 pub offset: GPA,
44}
45
46pub struct MemoryRegion {
49 pub name: String,
50 pub size: u64,
51 pub region_type: RegionType,
52 pub priority: i32,
53 pub subregions: Vec<SubRegion>,
54 pub enabled: bool,
55}
56
57impl MemoryRegion {
58 pub fn container(name: &str, size: u64) -> Self {
60 Self {
61 name: name.to_string(),
62 size,
63 region_type: RegionType::Container,
64 priority: 0,
65 subregions: Vec::new(),
66 enabled: true,
67 }
68 }
69
70 pub fn ram(name: &str, size: u64) -> (Self, Arc<RamBlock>) {
73 let block = Arc::new(RamBlock::new(size));
74 let region = Self {
75 name: name.to_string(),
76 size,
77 region_type: RegionType::Ram {
78 block: Arc::clone(&block),
79 },
80 priority: 0,
81 subregions: Vec::new(),
82 enabled: true,
83 };
84 (region, block)
85 }
86
87 pub fn rom(name: &str, size: u64) -> (Self, Arc<RamBlock>) {
91 let block = Arc::new(RamBlock::new(size));
92 let region = Self {
93 name: name.to_string(),
94 size,
95 region_type: RegionType::Rom {
96 block: Arc::clone(&block),
97 },
98 priority: 0,
99 subregions: Vec::new(),
100 enabled: true,
101 };
102 (region, block)
103 }
104
105 pub fn io(name: &str, size: u64, ops: Box<dyn MmioOps>) -> Self {
107 Self {
108 name: name.to_string(),
109 size,
110 region_type: RegionType::Io {
111 ops: Arc::new(Mutex::new(ops)),
112 },
113 priority: 0,
114 subregions: Vec::new(),
115 enabled: true,
116 }
117 }
118
119 pub fn alias(
122 name: &str,
123 target: MemoryRegion,
124 offset: u64,
125 size: u64,
126 ) -> Self {
127 Self {
128 name: name.to_string(),
129 size,
130 region_type: RegionType::Alias {
131 target: Box::new(target),
132 offset,
133 },
134 priority: 0,
135 subregions: Vec::new(),
136 enabled: true,
137 }
138 }
139
140 pub fn add_subregion(&mut self, region: MemoryRegion, offset: GPA) {
143 self.subregions.push(SubRegion { region, offset });
144 }
145
146 pub fn add_subregion_with_priority(
148 &mut self,
149 mut region: MemoryRegion,
150 offset: GPA,
151 priority: i32,
152 ) {
153 region.priority = priority;
154 self.subregions.push(SubRegion { region, offset });
155 }
156}