145626c85SLoGin use fdt::{ 245626c85SLoGin node::{FdtNode, NodeProperty}, 345626c85SLoGin Fdt, 445626c85SLoGin }; 545626c85SLoGin use system_error::SystemError; 645626c85SLoGin 7*92849878SLoGin use crate::{init::boot_params, libs::rwlock::RwLock}; 845626c85SLoGin 945626c85SLoGin #[inline(always)] 1045626c85SLoGin pub fn open_firmware_fdt_driver() -> &'static OpenFirmwareFdtDriver { 1145626c85SLoGin &OpenFirmwareFdtDriver 1245626c85SLoGin } 1345626c85SLoGin 1445626c85SLoGin static FDT_GLOBAL_DATA: RwLock<FdtGlobalData> = RwLock::new(FdtGlobalData::new()); 1545626c85SLoGin 1645626c85SLoGin #[derive(Debug)] 1745626c85SLoGin struct FdtGlobalData { 1845626c85SLoGin /// FDT根节点下的`size-cells`属性值 1945626c85SLoGin root_size_cells: u32, 2045626c85SLoGin 2145626c85SLoGin /// FDT根节点下的`address-cells`属性值 2245626c85SLoGin root_addr_cells: u32, 2345626c85SLoGin 2445626c85SLoGin chosen_node_name: Option<&'static str>, 2545626c85SLoGin } 2645626c85SLoGin 2745626c85SLoGin impl FdtGlobalData { 2845626c85SLoGin pub const fn new() -> Self { 2945626c85SLoGin Self { 3045626c85SLoGin root_size_cells: 1, 3145626c85SLoGin root_addr_cells: 1, 3245626c85SLoGin chosen_node_name: None, 3345626c85SLoGin } 3445626c85SLoGin } 3545626c85SLoGin } 3645626c85SLoGin 3745626c85SLoGin pub struct OpenFirmwareFdtDriver; 3845626c85SLoGin 3945626c85SLoGin impl OpenFirmwareFdtDriver { 40*92849878SLoGin #[allow(dead_code)] 4145626c85SLoGin pub fn early_scan_device_tree(&self) -> Result<(), SystemError> { 427a29d4fcSLoGin let fdt_vaddr = boot_params().read().fdt().unwrap(); 4345626c85SLoGin let fdt = unsafe { 4445626c85SLoGin fdt::Fdt::from_ptr(fdt_vaddr.as_ptr()).map_err(|e| { 4545626c85SLoGin kerror!("failed to parse fdt, err={:?}", e); 4645626c85SLoGin SystemError::EINVAL 4745626c85SLoGin }) 4845626c85SLoGin }?; 4945626c85SLoGin 5045626c85SLoGin self.early_init_scan_nodes(&fdt); 5145626c85SLoGin 5245626c85SLoGin return Ok(()); 5345626c85SLoGin } 5445626c85SLoGin 5545626c85SLoGin fn early_init_scan_nodes(&self, fdt: &Fdt) { 5645626c85SLoGin self.early_init_scan_root(fdt) 5745626c85SLoGin .expect("Failed to scan fdt root node."); 5845626c85SLoGin 5945626c85SLoGin self.early_init_scan_chosen(fdt).unwrap_or_else(|_| { 6045626c85SLoGin kwarn!("No `chosen` node found"); 6145626c85SLoGin }); 6245626c85SLoGin 6345626c85SLoGin self.early_init_scan_memory(fdt); 6445626c85SLoGin } 6545626c85SLoGin 6645626c85SLoGin /// 扫描根节点 6745626c85SLoGin fn early_init_scan_root(&self, fdt: &Fdt) -> Result<(), SystemError> { 6845626c85SLoGin let node = fdt.find_node("/").ok_or(SystemError::ENODEV)?; 6945626c85SLoGin 7045626c85SLoGin let mut guard = FDT_GLOBAL_DATA.write(); 7145626c85SLoGin 7245626c85SLoGin if let Some(prop) = node.property("#size-cells") { 7345626c85SLoGin guard.root_size_cells = prop.as_usize().unwrap() as u32; 7445626c85SLoGin 7545626c85SLoGin kdebug!("fdt_root_size_cells={}", guard.root_size_cells); 7645626c85SLoGin } 7745626c85SLoGin 7845626c85SLoGin if let Some(prop) = node.property("#address-cells") { 7945626c85SLoGin guard.root_addr_cells = prop.as_usize().unwrap() as u32; 8045626c85SLoGin 8145626c85SLoGin kdebug!("fdt_root_addr_cells={}", guard.root_addr_cells); 8245626c85SLoGin } 8345626c85SLoGin 8445626c85SLoGin return Ok(()); 8545626c85SLoGin } 8645626c85SLoGin 8745626c85SLoGin /// 扫描 `/chosen` 节点 8845626c85SLoGin fn early_init_scan_chosen(&self, fdt: &Fdt) -> Result<(), SystemError> { 8945626c85SLoGin const CHOSEN_NAME1: &'static str = "/chosen"; 9045626c85SLoGin let mut node = fdt.find_node(CHOSEN_NAME1); 9145626c85SLoGin if node.is_none() { 9245626c85SLoGin const CHOSEN_NAME2: &'static str = "/chosen@0"; 9345626c85SLoGin node = fdt.find_node(CHOSEN_NAME2); 9445626c85SLoGin if node.is_some() { 9545626c85SLoGin FDT_GLOBAL_DATA.write().chosen_node_name = Some(CHOSEN_NAME2); 9645626c85SLoGin } 9745626c85SLoGin } else { 9845626c85SLoGin FDT_GLOBAL_DATA.write().chosen_node_name = Some(CHOSEN_NAME1); 9945626c85SLoGin } 10045626c85SLoGin 10145626c85SLoGin if let Some(node) = node { 10245626c85SLoGin if let Some(prop) = node.property("bootargs") { 10345626c85SLoGin let bootargs = prop.as_str().unwrap(); 10445626c85SLoGin 10545626c85SLoGin boot_params() 10645626c85SLoGin .write() 10745626c85SLoGin .boot_cmdline_append(bootargs.as_bytes()); 10845626c85SLoGin } 10945626c85SLoGin } 11045626c85SLoGin 11145626c85SLoGin // TODO: 拼接内核自定义的command line参数 11245626c85SLoGin 11345626c85SLoGin kdebug!("Command line: {}", boot_params().read().boot_cmdline_str()); 11445626c85SLoGin return Ok(()); 11545626c85SLoGin } 11645626c85SLoGin 11745626c85SLoGin /// 扫描 `/memory` 节点 11845626c85SLoGin /// 11945626c85SLoGin /// ## 参数 12045626c85SLoGin /// 12145626c85SLoGin /// - `fdt`:FDT 12245626c85SLoGin /// 12345626c85SLoGin /// ## 返回值 12445626c85SLoGin /// 12545626c85SLoGin /// 如果扫描成功,找到可用内存,则返回`true`,否则返回`false`。 12645626c85SLoGin fn early_init_scan_memory(&self, fdt: &Fdt) -> bool { 12745626c85SLoGin let mut found_memory = false; 12845626c85SLoGin for node in fdt.all_nodes() { 12945626c85SLoGin let device_type: Option<NodeProperty<'_>> = node.property("device_type"); 13045626c85SLoGin if device_type.is_none() { 13145626c85SLoGin continue; 13245626c85SLoGin } 13345626c85SLoGin let device_type = device_type.unwrap().as_str(); 13445626c85SLoGin if device_type.is_none() || device_type.unwrap() != "memory" { 13545626c85SLoGin continue; 13645626c85SLoGin } 13745626c85SLoGin 13845626c85SLoGin if !self.is_device_avaliable(&node) { 13945626c85SLoGin continue; 14045626c85SLoGin } 14145626c85SLoGin 14245626c85SLoGin let reg = node.property("reg"); 14345626c85SLoGin if reg.is_none() { 14445626c85SLoGin continue; 14545626c85SLoGin } 14645626c85SLoGin let reg = reg.unwrap(); 14745626c85SLoGin // 每个cell是4字节 14845626c85SLoGin let addr_cells = FDT_GLOBAL_DATA.read().root_addr_cells as usize; 14945626c85SLoGin let size_cells = FDT_GLOBAL_DATA.read().root_size_cells as usize; 15045626c85SLoGin 15145626c85SLoGin let total_elements_in_reg = reg.value.len() / ((addr_cells + size_cells) * 4); 15245626c85SLoGin 15345626c85SLoGin for i in 0..total_elements_in_reg { 15445626c85SLoGin let mut base_index = i * (addr_cells + size_cells); 15545626c85SLoGin let base: u64; 15645626c85SLoGin let size: u64; 15745626c85SLoGin match addr_cells { 15845626c85SLoGin 1 => { 15945626c85SLoGin base = u32::from_be_bytes( 16045626c85SLoGin reg.value[base_index..base_index + 4].try_into().unwrap(), 16145626c85SLoGin ) as u64; 16245626c85SLoGin } 16345626c85SLoGin 2 => { 16445626c85SLoGin base = u64::from_be_bytes( 16545626c85SLoGin reg.value[base_index..base_index + 8].try_into().unwrap(), 16645626c85SLoGin ); 16745626c85SLoGin } 16845626c85SLoGin _ => { 16945626c85SLoGin panic!("addr_cells must be 1 or 2"); 17045626c85SLoGin } 17145626c85SLoGin } 17245626c85SLoGin base_index += addr_cells * 4; 17345626c85SLoGin 17445626c85SLoGin match size_cells { 17545626c85SLoGin 1 => { 17645626c85SLoGin size = u32::from_be_bytes( 17745626c85SLoGin reg.value[base_index..base_index + 4].try_into().unwrap(), 17845626c85SLoGin ) as u64; 17945626c85SLoGin } 18045626c85SLoGin 2 => { 18145626c85SLoGin size = u64::from_be_bytes( 18245626c85SLoGin reg.value[base_index..base_index + 8].try_into().unwrap(), 18345626c85SLoGin ); 18445626c85SLoGin } 18545626c85SLoGin _ => { 18645626c85SLoGin panic!("size_cells must be 1 or 2"); 18745626c85SLoGin } 18845626c85SLoGin } 18945626c85SLoGin 19045626c85SLoGin if size == 0 { 19145626c85SLoGin continue; 19245626c85SLoGin } 19345626c85SLoGin 19445626c85SLoGin kdebug!("Found memory: base={:#x}, size={:#x}", base, size); 19545626c85SLoGin self.early_init_dt_add_memory(base, size); 19645626c85SLoGin found_memory = true; 19745626c85SLoGin } 19845626c85SLoGin } 19945626c85SLoGin 20045626c85SLoGin return found_memory; 20145626c85SLoGin } 20245626c85SLoGin 203*92849878SLoGin #[cfg(target_arch = "x86_64")] 204*92849878SLoGin pub fn early_init_dt_add_memory(&self, _base: u64, _size: u64) { 205*92849878SLoGin kBUG!("x86_64 should not call early_init_dt_add_memory"); 206*92849878SLoGin } 207*92849878SLoGin 208*92849878SLoGin #[cfg(not(target_arch = "x86_64"))] 209*92849878SLoGin pub fn early_init_dt_add_memory(&self, base: u64, size: u64) { 210*92849878SLoGin use crate::{ 211*92849878SLoGin arch::MMArch, 212*92849878SLoGin libs::align::page_align_down, 213*92849878SLoGin mm::{ 214*92849878SLoGin memblock::{mem_block_manager, MemBlockManager}, 215*92849878SLoGin MemoryManagementArch, PhysAddr, 216*92849878SLoGin }, 217*92849878SLoGin }; 218*92849878SLoGin 21945626c85SLoGin let mut base = base as usize; 22045626c85SLoGin let mut size = size as usize; 22145626c85SLoGin 22245626c85SLoGin if size < (MMArch::PAGE_SIZE - (base & (!MMArch::PAGE_MASK))) { 22345626c85SLoGin kwarn!("Ignoring memory block {:#x}-{:#x}", base, base + size); 22445626c85SLoGin } 22545626c85SLoGin 22645626c85SLoGin if PhysAddr::new(base).check_aligned(MMArch::PAGE_SIZE) == false { 22745626c85SLoGin size -= MMArch::PAGE_SIZE - (base & (!MMArch::PAGE_MASK)); 22845626c85SLoGin base = page_align_down(base); 22945626c85SLoGin } 23045626c85SLoGin 23145626c85SLoGin size = page_align_down(size); 23245626c85SLoGin 23345626c85SLoGin if base > MemBlockManager::MAX_MEMBLOCK_ADDR.data() { 23445626c85SLoGin kwarn!("Ignoring memory block {:#x}-{:#x}", base, base + size); 23545626c85SLoGin } 23645626c85SLoGin 23745626c85SLoGin if base + size - 1 > MemBlockManager::MAX_MEMBLOCK_ADDR.data() { 23845626c85SLoGin kwarn!( 23945626c85SLoGin "Ignoring memory range {:#x}-{:#x}", 24045626c85SLoGin MemBlockManager::MAX_MEMBLOCK_ADDR.data() + 1, 24145626c85SLoGin base + size 24245626c85SLoGin ); 24345626c85SLoGin size = MemBlockManager::MAX_MEMBLOCK_ADDR.data() - base + 1; 24445626c85SLoGin } 24545626c85SLoGin 24645626c85SLoGin if base + size < MemBlockManager::MIN_MEMBLOCK_ADDR.data() { 24745626c85SLoGin kwarn!("Ignoring memory range {:#x}-{:#x}", base, base + size); 24845626c85SLoGin return; 24945626c85SLoGin } 25045626c85SLoGin 25145626c85SLoGin if base < MemBlockManager::MIN_MEMBLOCK_ADDR.data() { 25245626c85SLoGin { 25345626c85SLoGin kwarn!( 25445626c85SLoGin "Ignoring memory range {:#x}-{:#x}", 25545626c85SLoGin base, 25645626c85SLoGin MemBlockManager::MIN_MEMBLOCK_ADDR.data() 25745626c85SLoGin ); 25845626c85SLoGin size -= MemBlockManager::MIN_MEMBLOCK_ADDR.data() - base; 25945626c85SLoGin base = MemBlockManager::MIN_MEMBLOCK_ADDR.data(); 26045626c85SLoGin } 26145626c85SLoGin 26245626c85SLoGin mem_block_manager() 26345626c85SLoGin .add_block(PhysAddr::new(base), size) 26445626c85SLoGin .unwrap_or_else(|e| { 26545626c85SLoGin panic!( 26645626c85SLoGin "Failed to add memory block '{:#x}-{:#x}', err={:?}", 26745626c85SLoGin base, 26845626c85SLoGin base + size, 26945626c85SLoGin e 27045626c85SLoGin ); 27145626c85SLoGin }); 27245626c85SLoGin } 27345626c85SLoGin } 27445626c85SLoGin 27545626c85SLoGin fn is_device_avaliable(&self, node: &FdtNode) -> bool { 27645626c85SLoGin let status = node.property("status"); 27745626c85SLoGin if status.is_none() { 27845626c85SLoGin return true; 27945626c85SLoGin } 28045626c85SLoGin 28145626c85SLoGin let status = status.unwrap().as_str(); 28245626c85SLoGin if let Some(status) = status { 28345626c85SLoGin if status == "okay" || status == "ok" { 28445626c85SLoGin return true; 28545626c85SLoGin } 28645626c85SLoGin } 28745626c85SLoGin 28845626c85SLoGin return false; 28945626c85SLoGin } 29045626c85SLoGin } 291