1 use fdt::{ 2 node::{FdtNode, NodeProperty}, 3 Fdt, 4 }; 5 use system_error::SystemError; 6 7 use crate::{ 8 arch::MMArch, 9 init::boot_params, 10 libs::{align::page_align_down, rwlock::RwLock}, 11 mm::{ 12 memblock::{mem_block_manager, MemBlockManager}, 13 MemoryManagementArch, PhysAddr, 14 }, 15 }; 16 17 #[inline(always)] 18 pub fn open_firmware_fdt_driver() -> &'static OpenFirmwareFdtDriver { 19 &OpenFirmwareFdtDriver 20 } 21 22 static FDT_GLOBAL_DATA: RwLock<FdtGlobalData> = RwLock::new(FdtGlobalData::new()); 23 24 #[derive(Debug)] 25 struct FdtGlobalData { 26 /// FDT根节点下的`size-cells`属性值 27 root_size_cells: u32, 28 29 /// FDT根节点下的`address-cells`属性值 30 root_addr_cells: u32, 31 32 chosen_node_name: Option<&'static str>, 33 } 34 35 impl FdtGlobalData { 36 pub const fn new() -> Self { 37 Self { 38 root_size_cells: 1, 39 root_addr_cells: 1, 40 chosen_node_name: None, 41 } 42 } 43 } 44 45 pub struct OpenFirmwareFdtDriver; 46 47 impl OpenFirmwareFdtDriver { 48 pub fn early_scan_device_tree(&self) -> Result<(), SystemError> { 49 let fdt_vaddr = boot_params().read().fdt().unwrap(); 50 let fdt = unsafe { 51 fdt::Fdt::from_ptr(fdt_vaddr.as_ptr()).map_err(|e| { 52 kerror!("failed to parse fdt, err={:?}", e); 53 SystemError::EINVAL 54 }) 55 }?; 56 57 self.early_init_scan_nodes(&fdt); 58 59 return Ok(()); 60 } 61 62 fn early_init_scan_nodes(&self, fdt: &Fdt) { 63 self.early_init_scan_root(fdt) 64 .expect("Failed to scan fdt root node."); 65 66 self.early_init_scan_chosen(fdt).unwrap_or_else(|_| { 67 kwarn!("No `chosen` node found"); 68 }); 69 70 self.early_init_scan_memory(fdt); 71 } 72 73 /// 扫描根节点 74 fn early_init_scan_root(&self, fdt: &Fdt) -> Result<(), SystemError> { 75 let node = fdt.find_node("/").ok_or(SystemError::ENODEV)?; 76 77 let mut guard = FDT_GLOBAL_DATA.write(); 78 79 if let Some(prop) = node.property("#size-cells") { 80 guard.root_size_cells = prop.as_usize().unwrap() as u32; 81 82 kdebug!("fdt_root_size_cells={}", guard.root_size_cells); 83 } 84 85 if let Some(prop) = node.property("#address-cells") { 86 guard.root_addr_cells = prop.as_usize().unwrap() as u32; 87 88 kdebug!("fdt_root_addr_cells={}", guard.root_addr_cells); 89 } 90 91 return Ok(()); 92 } 93 94 /// 扫描 `/chosen` 节点 95 fn early_init_scan_chosen(&self, fdt: &Fdt) -> Result<(), SystemError> { 96 const CHOSEN_NAME1: &'static str = "/chosen"; 97 let mut node = fdt.find_node(CHOSEN_NAME1); 98 if node.is_none() { 99 const CHOSEN_NAME2: &'static str = "/chosen@0"; 100 node = fdt.find_node(CHOSEN_NAME2); 101 if node.is_some() { 102 FDT_GLOBAL_DATA.write().chosen_node_name = Some(CHOSEN_NAME2); 103 } 104 } else { 105 FDT_GLOBAL_DATA.write().chosen_node_name = Some(CHOSEN_NAME1); 106 } 107 108 if let Some(node) = node { 109 if let Some(prop) = node.property("bootargs") { 110 let bootargs = prop.as_str().unwrap(); 111 112 boot_params() 113 .write() 114 .boot_cmdline_append(bootargs.as_bytes()); 115 } 116 } 117 118 // TODO: 拼接内核自定义的command line参数 119 120 kdebug!("Command line: {}", boot_params().read().boot_cmdline_str()); 121 return Ok(()); 122 } 123 124 /// 扫描 `/memory` 节点 125 /// 126 /// ## 参数 127 /// 128 /// - `fdt`:FDT 129 /// 130 /// ## 返回值 131 /// 132 /// 如果扫描成功,找到可用内存,则返回`true`,否则返回`false`。 133 fn early_init_scan_memory(&self, fdt: &Fdt) -> bool { 134 let mut found_memory = false; 135 for node in fdt.all_nodes() { 136 let device_type: Option<NodeProperty<'_>> = node.property("device_type"); 137 if device_type.is_none() { 138 continue; 139 } 140 let device_type = device_type.unwrap().as_str(); 141 if device_type.is_none() || device_type.unwrap() != "memory" { 142 continue; 143 } 144 145 if !self.is_device_avaliable(&node) { 146 continue; 147 } 148 149 let reg = node.property("reg"); 150 if reg.is_none() { 151 continue; 152 } 153 let reg = reg.unwrap(); 154 // 每个cell是4字节 155 let addr_cells = FDT_GLOBAL_DATA.read().root_addr_cells as usize; 156 let size_cells = FDT_GLOBAL_DATA.read().root_size_cells as usize; 157 158 let total_elements_in_reg = reg.value.len() / ((addr_cells + size_cells) * 4); 159 160 for i in 0..total_elements_in_reg { 161 let mut base_index = i * (addr_cells + size_cells); 162 let base: u64; 163 let size: u64; 164 match addr_cells { 165 1 => { 166 base = u32::from_be_bytes( 167 reg.value[base_index..base_index + 4].try_into().unwrap(), 168 ) as u64; 169 } 170 2 => { 171 base = u64::from_be_bytes( 172 reg.value[base_index..base_index + 8].try_into().unwrap(), 173 ); 174 } 175 _ => { 176 panic!("addr_cells must be 1 or 2"); 177 } 178 } 179 base_index += addr_cells * 4; 180 181 match size_cells { 182 1 => { 183 size = u32::from_be_bytes( 184 reg.value[base_index..base_index + 4].try_into().unwrap(), 185 ) as u64; 186 } 187 2 => { 188 size = u64::from_be_bytes( 189 reg.value[base_index..base_index + 8].try_into().unwrap(), 190 ); 191 } 192 _ => { 193 panic!("size_cells must be 1 or 2"); 194 } 195 } 196 197 if size == 0 { 198 continue; 199 } 200 201 kdebug!("Found memory: base={:#x}, size={:#x}", base, size); 202 self.early_init_dt_add_memory(base, size); 203 found_memory = true; 204 } 205 } 206 207 return found_memory; 208 } 209 210 fn early_init_dt_add_memory(&self, base: u64, size: u64) { 211 let mut base = base as usize; 212 let mut size = size as usize; 213 214 if size < (MMArch::PAGE_SIZE - (base & (!MMArch::PAGE_MASK))) { 215 kwarn!("Ignoring memory block {:#x}-{:#x}", base, base + size); 216 } 217 218 if PhysAddr::new(base).check_aligned(MMArch::PAGE_SIZE) == false { 219 size -= MMArch::PAGE_SIZE - (base & (!MMArch::PAGE_MASK)); 220 base = page_align_down(base); 221 } 222 223 size = page_align_down(size); 224 225 if base > MemBlockManager::MAX_MEMBLOCK_ADDR.data() { 226 kwarn!("Ignoring memory block {:#x}-{:#x}", base, base + size); 227 } 228 229 if base + size - 1 > MemBlockManager::MAX_MEMBLOCK_ADDR.data() { 230 kwarn!( 231 "Ignoring memory range {:#x}-{:#x}", 232 MemBlockManager::MAX_MEMBLOCK_ADDR.data() + 1, 233 base + size 234 ); 235 size = MemBlockManager::MAX_MEMBLOCK_ADDR.data() - base + 1; 236 } 237 238 if base + size < MemBlockManager::MIN_MEMBLOCK_ADDR.data() { 239 kwarn!("Ignoring memory range {:#x}-{:#x}", base, base + size); 240 return; 241 } 242 243 if base < MemBlockManager::MIN_MEMBLOCK_ADDR.data() { 244 { 245 kwarn!( 246 "Ignoring memory range {:#x}-{:#x}", 247 base, 248 MemBlockManager::MIN_MEMBLOCK_ADDR.data() 249 ); 250 size -= MemBlockManager::MIN_MEMBLOCK_ADDR.data() - base; 251 base = MemBlockManager::MIN_MEMBLOCK_ADDR.data(); 252 } 253 254 mem_block_manager() 255 .add_block(PhysAddr::new(base), size) 256 .unwrap_or_else(|e| { 257 panic!( 258 "Failed to add memory block '{:#x}-{:#x}', err={:?}", 259 base, 260 base + size, 261 e 262 ); 263 }); 264 } 265 } 266 267 fn is_device_avaliable(&self, node: &FdtNode) -> bool { 268 let status = node.property("status"); 269 if status.is_none() { 270 return true; 271 } 272 273 let status = status.unwrap().as_str(); 274 if let Some(status) = status { 275 if status == "okay" || status == "ok" { 276 return true; 277 } 278 } 279 280 return false; 281 } 282 } 283