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