1*453452ccSLoGin use core::mem::size_of; 2*453452ccSLoGin 345626c85SLoGin use fdt::{ 445626c85SLoGin node::{FdtNode, NodeProperty}, 545626c85SLoGin Fdt, 645626c85SLoGin }; 745626c85SLoGin use system_error::SystemError; 845626c85SLoGin 9*453452ccSLoGin use crate::{ 10*453452ccSLoGin init::boot_params, 11*453452ccSLoGin libs::rwlock::RwLock, 12*453452ccSLoGin mm::{memblock::mem_block_manager, PhysAddr}, 13*453452ccSLoGin }; 1445626c85SLoGin 1545626c85SLoGin #[inline(always)] 1645626c85SLoGin pub fn open_firmware_fdt_driver() -> &'static OpenFirmwareFdtDriver { 1745626c85SLoGin &OpenFirmwareFdtDriver 1845626c85SLoGin } 1945626c85SLoGin 2045626c85SLoGin static FDT_GLOBAL_DATA: RwLock<FdtGlobalData> = RwLock::new(FdtGlobalData::new()); 2145626c85SLoGin 2245626c85SLoGin #[derive(Debug)] 2345626c85SLoGin struct FdtGlobalData { 2445626c85SLoGin /// FDT根节点下的`size-cells`属性值 2545626c85SLoGin root_size_cells: u32, 2645626c85SLoGin 2745626c85SLoGin /// FDT根节点下的`address-cells`属性值 2845626c85SLoGin root_addr_cells: u32, 2945626c85SLoGin 3045626c85SLoGin chosen_node_name: Option<&'static str>, 3145626c85SLoGin } 3245626c85SLoGin 3345626c85SLoGin impl FdtGlobalData { 3445626c85SLoGin pub const fn new() -> Self { 3545626c85SLoGin Self { 3645626c85SLoGin root_size_cells: 1, 3745626c85SLoGin root_addr_cells: 1, 3845626c85SLoGin chosen_node_name: None, 3945626c85SLoGin } 4045626c85SLoGin } 4145626c85SLoGin } 4245626c85SLoGin 4345626c85SLoGin pub struct OpenFirmwareFdtDriver; 4445626c85SLoGin 4545626c85SLoGin impl OpenFirmwareFdtDriver { 4692849878SLoGin #[allow(dead_code)] 4745626c85SLoGin pub fn early_scan_device_tree(&self) -> Result<(), SystemError> { 487a29d4fcSLoGin let fdt_vaddr = boot_params().read().fdt().unwrap(); 4945626c85SLoGin let fdt = unsafe { 5045626c85SLoGin fdt::Fdt::from_ptr(fdt_vaddr.as_ptr()).map_err(|e| { 5145626c85SLoGin kerror!("failed to parse fdt, err={:?}", e); 5245626c85SLoGin SystemError::EINVAL 5345626c85SLoGin }) 5445626c85SLoGin }?; 5545626c85SLoGin 5645626c85SLoGin self.early_init_scan_nodes(&fdt); 5745626c85SLoGin 5845626c85SLoGin return Ok(()); 5945626c85SLoGin } 6045626c85SLoGin 6145626c85SLoGin fn early_init_scan_nodes(&self, fdt: &Fdt) { 6245626c85SLoGin self.early_init_scan_root(fdt) 6345626c85SLoGin .expect("Failed to scan fdt root node."); 6445626c85SLoGin 6545626c85SLoGin self.early_init_scan_chosen(fdt).unwrap_or_else(|_| { 6645626c85SLoGin kwarn!("No `chosen` node found"); 6745626c85SLoGin }); 6845626c85SLoGin 6945626c85SLoGin self.early_init_scan_memory(fdt); 7045626c85SLoGin } 7145626c85SLoGin 7245626c85SLoGin /// 扫描根节点 7345626c85SLoGin fn early_init_scan_root(&self, fdt: &Fdt) -> Result<(), SystemError> { 7445626c85SLoGin let node = fdt.find_node("/").ok_or(SystemError::ENODEV)?; 7545626c85SLoGin 7645626c85SLoGin let mut guard = FDT_GLOBAL_DATA.write(); 7745626c85SLoGin 7845626c85SLoGin if let Some(prop) = node.property("#size-cells") { 7945626c85SLoGin guard.root_size_cells = prop.as_usize().unwrap() as u32; 8045626c85SLoGin 81*453452ccSLoGin // kdebug!("fdt_root_size_cells={}", guard.root_size_cells); 8245626c85SLoGin } 8345626c85SLoGin 8445626c85SLoGin if let Some(prop) = node.property("#address-cells") { 8545626c85SLoGin guard.root_addr_cells = prop.as_usize().unwrap() as u32; 8645626c85SLoGin 87*453452ccSLoGin // kdebug!("fdt_root_addr_cells={}", guard.root_addr_cells); 8845626c85SLoGin } 8945626c85SLoGin 9045626c85SLoGin return Ok(()); 9145626c85SLoGin } 9245626c85SLoGin 9345626c85SLoGin /// 扫描 `/chosen` 节点 9445626c85SLoGin fn early_init_scan_chosen(&self, fdt: &Fdt) -> Result<(), SystemError> { 9545626c85SLoGin const CHOSEN_NAME1: &'static str = "/chosen"; 9645626c85SLoGin let mut node = fdt.find_node(CHOSEN_NAME1); 9745626c85SLoGin if node.is_none() { 9845626c85SLoGin const CHOSEN_NAME2: &'static str = "/chosen@0"; 9945626c85SLoGin node = fdt.find_node(CHOSEN_NAME2); 10045626c85SLoGin if node.is_some() { 10145626c85SLoGin FDT_GLOBAL_DATA.write().chosen_node_name = Some(CHOSEN_NAME2); 10245626c85SLoGin } 10345626c85SLoGin } else { 10445626c85SLoGin FDT_GLOBAL_DATA.write().chosen_node_name = Some(CHOSEN_NAME1); 10545626c85SLoGin } 10645626c85SLoGin 10745626c85SLoGin if let Some(node) = node { 10845626c85SLoGin if let Some(prop) = node.property("bootargs") { 10945626c85SLoGin let bootargs = prop.as_str().unwrap(); 11045626c85SLoGin 11145626c85SLoGin boot_params() 11245626c85SLoGin .write() 11345626c85SLoGin .boot_cmdline_append(bootargs.as_bytes()); 11445626c85SLoGin } 11545626c85SLoGin } 11645626c85SLoGin 11745626c85SLoGin // TODO: 拼接内核自定义的command line参数 11845626c85SLoGin 11945626c85SLoGin kdebug!("Command line: {}", boot_params().read().boot_cmdline_str()); 12045626c85SLoGin return Ok(()); 12145626c85SLoGin } 12245626c85SLoGin 12345626c85SLoGin /// 扫描 `/memory` 节点 12445626c85SLoGin /// 12545626c85SLoGin /// ## 参数 12645626c85SLoGin /// 12745626c85SLoGin /// - `fdt`:FDT 12845626c85SLoGin /// 12945626c85SLoGin /// ## 返回值 13045626c85SLoGin /// 13145626c85SLoGin /// 如果扫描成功,找到可用内存,则返回`true`,否则返回`false`。 13245626c85SLoGin fn early_init_scan_memory(&self, fdt: &Fdt) -> bool { 13345626c85SLoGin let mut found_memory = false; 13445626c85SLoGin for node in fdt.all_nodes() { 13545626c85SLoGin let device_type: Option<NodeProperty<'_>> = node.property("device_type"); 13645626c85SLoGin if device_type.is_none() { 13745626c85SLoGin continue; 13845626c85SLoGin } 13945626c85SLoGin let device_type = device_type.unwrap().as_str(); 14045626c85SLoGin if device_type.is_none() || device_type.unwrap() != "memory" { 14145626c85SLoGin continue; 14245626c85SLoGin } 14345626c85SLoGin 14445626c85SLoGin if !self.is_device_avaliable(&node) { 14545626c85SLoGin continue; 14645626c85SLoGin } 14745626c85SLoGin 14845626c85SLoGin let reg = node.property("reg"); 14945626c85SLoGin if reg.is_none() { 15045626c85SLoGin continue; 15145626c85SLoGin } 15245626c85SLoGin let reg = reg.unwrap(); 15345626c85SLoGin // 每个cell是4字节 15445626c85SLoGin let addr_cells = FDT_GLOBAL_DATA.read().root_addr_cells as usize; 15545626c85SLoGin let size_cells = FDT_GLOBAL_DATA.read().root_size_cells as usize; 15645626c85SLoGin 15745626c85SLoGin let total_elements_in_reg = reg.value.len() / ((addr_cells + size_cells) * 4); 15845626c85SLoGin 15945626c85SLoGin for i in 0..total_elements_in_reg { 160*453452ccSLoGin let base_index = i * (addr_cells + size_cells); 16145626c85SLoGin 162*453452ccSLoGin let (base, base_index) = read_cell(reg.value, base_index, addr_cells); 163*453452ccSLoGin let (size, _) = read_cell(reg.value, base_index, size_cells); 16445626c85SLoGin 16545626c85SLoGin if size == 0 { 16645626c85SLoGin continue; 16745626c85SLoGin } 16845626c85SLoGin 16945626c85SLoGin kdebug!("Found memory: base={:#x}, size={:#x}", base, size); 17045626c85SLoGin self.early_init_dt_add_memory(base, size); 17145626c85SLoGin found_memory = true; 17245626c85SLoGin } 17345626c85SLoGin } 17445626c85SLoGin 17545626c85SLoGin return found_memory; 17645626c85SLoGin } 17745626c85SLoGin 17892849878SLoGin #[cfg(target_arch = "x86_64")] 17992849878SLoGin pub fn early_init_dt_add_memory(&self, _base: u64, _size: u64) { 18092849878SLoGin kBUG!("x86_64 should not call early_init_dt_add_memory"); 18192849878SLoGin } 18292849878SLoGin 18392849878SLoGin #[cfg(not(target_arch = "x86_64"))] 18492849878SLoGin pub fn early_init_dt_add_memory(&self, base: u64, size: u64) { 18592849878SLoGin use crate::{ 18692849878SLoGin arch::MMArch, 18792849878SLoGin libs::align::page_align_down, 18892849878SLoGin mm::{ 18992849878SLoGin memblock::{mem_block_manager, MemBlockManager}, 19092849878SLoGin MemoryManagementArch, PhysAddr, 19192849878SLoGin }, 19292849878SLoGin }; 19392849878SLoGin 19445626c85SLoGin let mut base = base as usize; 19545626c85SLoGin let mut size = size as usize; 19645626c85SLoGin 19745626c85SLoGin if size < (MMArch::PAGE_SIZE - (base & (!MMArch::PAGE_MASK))) { 19845626c85SLoGin kwarn!("Ignoring memory block {:#x}-{:#x}", base, base + size); 19945626c85SLoGin } 20045626c85SLoGin 20145626c85SLoGin if PhysAddr::new(base).check_aligned(MMArch::PAGE_SIZE) == false { 20245626c85SLoGin size -= MMArch::PAGE_SIZE - (base & (!MMArch::PAGE_MASK)); 20345626c85SLoGin base = page_align_down(base); 20445626c85SLoGin } 20545626c85SLoGin 20645626c85SLoGin size = page_align_down(size); 20745626c85SLoGin 20845626c85SLoGin if base > MemBlockManager::MAX_MEMBLOCK_ADDR.data() { 20945626c85SLoGin kwarn!("Ignoring memory block {:#x}-{:#x}", base, base + size); 21045626c85SLoGin } 21145626c85SLoGin 21245626c85SLoGin if base + size - 1 > MemBlockManager::MAX_MEMBLOCK_ADDR.data() { 21345626c85SLoGin kwarn!( 21445626c85SLoGin "Ignoring memory range {:#x}-{:#x}", 21545626c85SLoGin MemBlockManager::MAX_MEMBLOCK_ADDR.data() + 1, 21645626c85SLoGin base + size 21745626c85SLoGin ); 21845626c85SLoGin size = MemBlockManager::MAX_MEMBLOCK_ADDR.data() - base + 1; 21945626c85SLoGin } 22045626c85SLoGin 22145626c85SLoGin if base + size < MemBlockManager::MIN_MEMBLOCK_ADDR.data() { 22245626c85SLoGin kwarn!("Ignoring memory range {:#x}-{:#x}", base, base + size); 22345626c85SLoGin return; 22445626c85SLoGin } 22545626c85SLoGin 22645626c85SLoGin if base < MemBlockManager::MIN_MEMBLOCK_ADDR.data() { 22745626c85SLoGin { 22845626c85SLoGin kwarn!( 22945626c85SLoGin "Ignoring memory range {:#x}-{:#x}", 23045626c85SLoGin base, 23145626c85SLoGin MemBlockManager::MIN_MEMBLOCK_ADDR.data() 23245626c85SLoGin ); 23345626c85SLoGin size -= MemBlockManager::MIN_MEMBLOCK_ADDR.data() - base; 23445626c85SLoGin base = MemBlockManager::MIN_MEMBLOCK_ADDR.data(); 23545626c85SLoGin } 236*453452ccSLoGin } 23745626c85SLoGin 23845626c85SLoGin mem_block_manager() 23945626c85SLoGin .add_block(PhysAddr::new(base), size) 24045626c85SLoGin .unwrap_or_else(|e| { 24145626c85SLoGin panic!( 24245626c85SLoGin "Failed to add memory block '{:#x}-{:#x}', err={:?}", 24345626c85SLoGin base, 24445626c85SLoGin base + size, 24545626c85SLoGin e 24645626c85SLoGin ); 24745626c85SLoGin }); 24845626c85SLoGin } 24945626c85SLoGin 250*453452ccSLoGin /// 判断设备是否可用 25145626c85SLoGin fn is_device_avaliable(&self, node: &FdtNode) -> bool { 25245626c85SLoGin let status = node.property("status"); 25345626c85SLoGin if status.is_none() { 25445626c85SLoGin return true; 25545626c85SLoGin } 25645626c85SLoGin 25745626c85SLoGin let status = status.unwrap().as_str(); 25845626c85SLoGin if let Some(status) = status { 25945626c85SLoGin if status == "okay" || status == "ok" { 26045626c85SLoGin return true; 26145626c85SLoGin } 26245626c85SLoGin } 26345626c85SLoGin 26445626c85SLoGin return false; 26545626c85SLoGin } 266*453452ccSLoGin 267*453452ccSLoGin /// 在UEFI初始化后,扫描FDT中的`/reserved-memory`节点,设置保留的内存 268*453452ccSLoGin /// 269*453452ccSLoGin /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/of/fdt.c#634 270*453452ccSLoGin pub fn early_init_fdt_scan_reserved_mem(&self) { 271*453452ccSLoGin let vaddr = boot_params().read().fdt(); 272*453452ccSLoGin if vaddr.is_none() { 273*453452ccSLoGin return; 274*453452ccSLoGin } 275*453452ccSLoGin let vaddr = vaddr.unwrap(); 276*453452ccSLoGin let fdt = unsafe { Fdt::from_ptr(vaddr.data() as *const u8) }; 277*453452ccSLoGin if fdt.is_err() { 278*453452ccSLoGin return; 279*453452ccSLoGin } 280*453452ccSLoGin 281*453452ccSLoGin let fdt = fdt.unwrap(); 282*453452ccSLoGin self.early_reserve_fdt_itself(&fdt); 283*453452ccSLoGin 284*453452ccSLoGin let reserved_mem_nodes = fdt.memory_reservations(); 285*453452ccSLoGin 286*453452ccSLoGin for node in reserved_mem_nodes { 287*453452ccSLoGin if node.size() != 0 { 288*453452ccSLoGin let address = PhysAddr::new(node.address() as usize); 289*453452ccSLoGin let size = node.size(); 290*453452ccSLoGin kdebug!("Reserve memory: {:?}-{:?}", address, address + size); 291*453452ccSLoGin mem_block_manager().reserve_block(address, size).unwrap(); 292*453452ccSLoGin } 293*453452ccSLoGin } 294*453452ccSLoGin 295*453452ccSLoGin self.fdt_scan_reserved_mem(&fdt) 296*453452ccSLoGin .expect("Failed to scan reserved memory"); 297*453452ccSLoGin } 298*453452ccSLoGin 299*453452ccSLoGin /// 保留fdt自身的内存空间 300*453452ccSLoGin 301*453452ccSLoGin fn early_reserve_fdt_itself(&self, fdt: &Fdt) { 302*453452ccSLoGin #[cfg(target_arch = "riscv64")] 303*453452ccSLoGin { 304*453452ccSLoGin use crate::libs::align::{page_align_down, page_align_up}; 305*453452ccSLoGin 306*453452ccSLoGin let fdt_paddr = boot_params().read().arch.fdt_paddr; 307*453452ccSLoGin let rsvd_start = PhysAddr::new(page_align_down(fdt_paddr.data())); 308*453452ccSLoGin let rsvd_size = page_align_up(fdt_paddr.data() - rsvd_start.data() + fdt.total_size()); 309*453452ccSLoGin mem_block_manager() 310*453452ccSLoGin .reserve_block(rsvd_start, rsvd_size) 311*453452ccSLoGin .expect("Failed to reserve memory for fdt"); 312*453452ccSLoGin } 313*453452ccSLoGin 314*453452ccSLoGin #[cfg(target_arch = "x86_64")] 315*453452ccSLoGin { 316*453452ccSLoGin let _ = fdt; 317*453452ccSLoGin } 318*453452ccSLoGin } 319*453452ccSLoGin 320*453452ccSLoGin fn fdt_scan_reserved_mem(&self, fdt: &Fdt) -> Result<(), SystemError> { 321*453452ccSLoGin let node = fdt 322*453452ccSLoGin .find_node("/reserved-memory") 323*453452ccSLoGin .ok_or(SystemError::ENODEV)?; 324*453452ccSLoGin 325*453452ccSLoGin for child in node.children() { 326*453452ccSLoGin if !self.is_device_avaliable(&child) { 327*453452ccSLoGin continue; 328*453452ccSLoGin } 329*453452ccSLoGin 330*453452ccSLoGin reserved_mem_reserve_reg(&child).ok(); 331*453452ccSLoGin } 332*453452ccSLoGin 333*453452ccSLoGin return Ok(()); 334*453452ccSLoGin } 335*453452ccSLoGin 336*453452ccSLoGin fn early_init_dt_reserve_memory( 337*453452ccSLoGin &self, 338*453452ccSLoGin base: PhysAddr, 339*453452ccSLoGin size: usize, 340*453452ccSLoGin nomap: bool, 341*453452ccSLoGin ) -> Result<(), SystemError> { 342*453452ccSLoGin if nomap { 343*453452ccSLoGin if mem_block_manager().is_overlapped(base, size) 344*453452ccSLoGin && mem_block_manager().is_overlapped_with_reserved(base, size) 345*453452ccSLoGin { 346*453452ccSLoGin // 如果内存已经被其他区域预留(即已经被映射),我们不应该允许它被标记为`nomap`, 347*453452ccSLoGin // 但是不需要担心如果该区域不是内存(即不会被映射)的情况。 348*453452ccSLoGin return Err(SystemError::EBUSY); 349*453452ccSLoGin } 350*453452ccSLoGin 351*453452ccSLoGin return mem_block_manager().mark_nomap(base, size); 352*453452ccSLoGin } 353*453452ccSLoGin 354*453452ccSLoGin return mem_block_manager().reserve_block(base, size); 355*453452ccSLoGin } 356*453452ccSLoGin } 357*453452ccSLoGin 358*453452ccSLoGin #[allow(dead_code)] 359*453452ccSLoGin fn reserved_mem_reserve_reg(node: &FdtNode<'_, '_>) -> Result<(), SystemError> { 360*453452ccSLoGin let global_data_guard: crate::libs::rwlock::RwLockReadGuard<'_, FdtGlobalData> = 361*453452ccSLoGin FDT_GLOBAL_DATA.read(); 362*453452ccSLoGin let t_len = ((global_data_guard.root_addr_cells + global_data_guard.root_size_cells) as usize) 363*453452ccSLoGin * size_of::<u32>(); 364*453452ccSLoGin drop(global_data_guard); 365*453452ccSLoGin 366*453452ccSLoGin let reg = node.property("reg").ok_or(SystemError::ENOENT)?; 367*453452ccSLoGin 368*453452ccSLoGin let mut reg_size = reg.value.len(); 369*453452ccSLoGin if reg_size > 0 && reg_size % t_len != 0 { 370*453452ccSLoGin kerror!( 371*453452ccSLoGin "Reserved memory: invalid reg property in '{}', skipping node.", 372*453452ccSLoGin node.name 373*453452ccSLoGin ); 374*453452ccSLoGin return Err(SystemError::EINVAL); 375*453452ccSLoGin } 376*453452ccSLoGin // 每个cell是4字节 377*453452ccSLoGin let addr_cells = FDT_GLOBAL_DATA.read().root_addr_cells as usize; 378*453452ccSLoGin let size_cells = FDT_GLOBAL_DATA.read().root_size_cells as usize; 379*453452ccSLoGin 380*453452ccSLoGin let nomap = node.property("no-map").is_some(); 381*453452ccSLoGin 382*453452ccSLoGin let mut base_index = 0; 383*453452ccSLoGin 384*453452ccSLoGin while reg_size >= t_len { 385*453452ccSLoGin let (base, bi) = read_cell(reg.value, base_index, addr_cells); 386*453452ccSLoGin base_index = bi; 387*453452ccSLoGin let (size, bi) = read_cell(reg.value, base_index, size_cells); 388*453452ccSLoGin base_index = bi; 389*453452ccSLoGin 390*453452ccSLoGin if size > 0 391*453452ccSLoGin && open_firmware_fdt_driver() 392*453452ccSLoGin .early_init_dt_reserve_memory(PhysAddr::new(base as usize), size as usize, nomap) 393*453452ccSLoGin .is_ok() 394*453452ccSLoGin { 395*453452ccSLoGin kdebug!( 396*453452ccSLoGin "Reserved memory: base={:#x}, size={:#x}, nomap={}", 397*453452ccSLoGin base, 398*453452ccSLoGin size, 399*453452ccSLoGin nomap 400*453452ccSLoGin ); 401*453452ccSLoGin } else { 402*453452ccSLoGin kerror!( 403*453452ccSLoGin "Failed to reserve memory: base={:#x}, size={:#x}, nomap={}", 404*453452ccSLoGin base, 405*453452ccSLoGin size, 406*453452ccSLoGin nomap 407*453452ccSLoGin ); 408*453452ccSLoGin } 409*453452ccSLoGin 410*453452ccSLoGin reg_size -= t_len; 411*453452ccSLoGin 412*453452ccSLoGin // todo: linux这里保存了节点,但是我感觉现在还用不着。 413*453452ccSLoGin } 414*453452ccSLoGin 415*453452ccSLoGin return Ok(()); 416*453452ccSLoGin } 417*453452ccSLoGin 418*453452ccSLoGin /// 从FDT的`reg`属性中读取指定数量的cell,作为一个小端u64返回 419*453452ccSLoGin /// 420*453452ccSLoGin /// ## 参数 421*453452ccSLoGin /// 422*453452ccSLoGin /// - `reg_value`:`reg`属性数组的引用 423*453452ccSLoGin /// - `base_index`:起始索引 424*453452ccSLoGin /// - `cells`:要读取的cell数量,必须是1或2 425*453452ccSLoGin /// 426*453452ccSLoGin /// ## 返回值 427*453452ccSLoGin /// 428*453452ccSLoGin /// (value, next_base_index) 429*453452ccSLoGin fn read_cell(reg_value: &[u8], base_index: usize, cells: usize) -> (u64, usize) { 430*453452ccSLoGin let next_base_index = base_index + cells * 4; 431*453452ccSLoGin match cells { 432*453452ccSLoGin 1 => { 433*453452ccSLoGin return ( 434*453452ccSLoGin u32::from_be_bytes(reg_value[base_index..base_index + 4].try_into().unwrap()) 435*453452ccSLoGin .try_into() 436*453452ccSLoGin .unwrap(), 437*453452ccSLoGin next_base_index, 438*453452ccSLoGin ); 439*453452ccSLoGin } 440*453452ccSLoGin 441*453452ccSLoGin 2 => { 442*453452ccSLoGin return ( 443*453452ccSLoGin u64::from_be_bytes(reg_value[base_index..base_index + 8].try_into().unwrap()), 444*453452ccSLoGin next_base_index, 445*453452ccSLoGin ); 446*453452ccSLoGin } 447*453452ccSLoGin _ => { 448*453452ccSLoGin panic!("cells must be 1 or 2"); 449*453452ccSLoGin } 450*453452ccSLoGin } 45145626c85SLoGin } 452