1453452ccSLoGin use core::mem::size_of; 2453452ccSLoGin 345626c85SLoGin use fdt::{ 445626c85SLoGin node::{FdtNode, NodeProperty}, 545626c85SLoGin Fdt, 645626c85SLoGin }; 745626c85SLoGin use system_error::SystemError; 845626c85SLoGin 9453452ccSLoGin use crate::{ 10453452ccSLoGin init::boot_params, 11453452ccSLoGin libs::rwlock::RwLock, 12453452ccSLoGin mm::{memblock::mem_block_manager, PhysAddr}, 13453452ccSLoGin }; 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 81453452ccSLoGin // 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 87453452ccSLoGin // 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> { 95*b5b571e0SLoGin const CHOSEN_NAME1: &str = "/chosen"; 9645626c85SLoGin let mut node = fdt.find_node(CHOSEN_NAME1); 9745626c85SLoGin if node.is_none() { 98*b5b571e0SLoGin const CHOSEN_NAME2: &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 { 160453452ccSLoGin let base_index = i * (addr_cells + size_cells); 16145626c85SLoGin 162453452ccSLoGin let (base, base_index) = read_cell(reg.value, base_index, addr_cells); 163453452ccSLoGin 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 } 236453452ccSLoGin } 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 250453452ccSLoGin /// 判断设备是否可用 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 } 266453452ccSLoGin 267453452ccSLoGin /// 在UEFI初始化后,扫描FDT中的`/reserved-memory`节点,设置保留的内存 268453452ccSLoGin /// 269453452ccSLoGin /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/of/fdt.c#634 270453452ccSLoGin pub fn early_init_fdt_scan_reserved_mem(&self) { 271453452ccSLoGin let vaddr = boot_params().read().fdt(); 272453452ccSLoGin if vaddr.is_none() { 273453452ccSLoGin return; 274453452ccSLoGin } 275453452ccSLoGin let vaddr = vaddr.unwrap(); 276453452ccSLoGin let fdt = unsafe { Fdt::from_ptr(vaddr.data() as *const u8) }; 277453452ccSLoGin if fdt.is_err() { 278453452ccSLoGin return; 279453452ccSLoGin } 280453452ccSLoGin 281453452ccSLoGin let fdt = fdt.unwrap(); 282453452ccSLoGin self.early_reserve_fdt_itself(&fdt); 283453452ccSLoGin 284453452ccSLoGin let reserved_mem_nodes = fdt.memory_reservations(); 285453452ccSLoGin 286453452ccSLoGin for node in reserved_mem_nodes { 287453452ccSLoGin if node.size() != 0 { 288453452ccSLoGin let address = PhysAddr::new(node.address() as usize); 289453452ccSLoGin let size = node.size(); 290453452ccSLoGin kdebug!("Reserve memory: {:?}-{:?}", address, address + size); 291453452ccSLoGin mem_block_manager().reserve_block(address, size).unwrap(); 292453452ccSLoGin } 293453452ccSLoGin } 294453452ccSLoGin 295453452ccSLoGin self.fdt_scan_reserved_mem(&fdt) 296453452ccSLoGin .expect("Failed to scan reserved memory"); 297453452ccSLoGin } 298453452ccSLoGin 299453452ccSLoGin /// 保留fdt自身的内存空间 300453452ccSLoGin 301453452ccSLoGin fn early_reserve_fdt_itself(&self, fdt: &Fdt) { 302453452ccSLoGin #[cfg(target_arch = "riscv64")] 303453452ccSLoGin { 304453452ccSLoGin use crate::libs::align::{page_align_down, page_align_up}; 305453452ccSLoGin 306453452ccSLoGin let fdt_paddr = boot_params().read().arch.fdt_paddr; 307453452ccSLoGin let rsvd_start = PhysAddr::new(page_align_down(fdt_paddr.data())); 308453452ccSLoGin let rsvd_size = page_align_up(fdt_paddr.data() - rsvd_start.data() + fdt.total_size()); 309453452ccSLoGin mem_block_manager() 310453452ccSLoGin .reserve_block(rsvd_start, rsvd_size) 311453452ccSLoGin .expect("Failed to reserve memory for fdt"); 312453452ccSLoGin } 313453452ccSLoGin 314453452ccSLoGin #[cfg(target_arch = "x86_64")] 315453452ccSLoGin { 316453452ccSLoGin let _ = fdt; 317453452ccSLoGin } 318453452ccSLoGin } 319453452ccSLoGin 320453452ccSLoGin fn fdt_scan_reserved_mem(&self, fdt: &Fdt) -> Result<(), SystemError> { 321453452ccSLoGin let node = fdt 322453452ccSLoGin .find_node("/reserved-memory") 323453452ccSLoGin .ok_or(SystemError::ENODEV)?; 324453452ccSLoGin 325453452ccSLoGin for child in node.children() { 326453452ccSLoGin if !self.is_device_avaliable(&child) { 327453452ccSLoGin continue; 328453452ccSLoGin } 329453452ccSLoGin 330453452ccSLoGin reserved_mem_reserve_reg(&child).ok(); 331453452ccSLoGin } 332453452ccSLoGin 333453452ccSLoGin return Ok(()); 334453452ccSLoGin } 335453452ccSLoGin 336453452ccSLoGin fn early_init_dt_reserve_memory( 337453452ccSLoGin &self, 338453452ccSLoGin base: PhysAddr, 339453452ccSLoGin size: usize, 340453452ccSLoGin nomap: bool, 341453452ccSLoGin ) -> Result<(), SystemError> { 342453452ccSLoGin if nomap { 343453452ccSLoGin if mem_block_manager().is_overlapped(base, size) 344453452ccSLoGin && mem_block_manager().is_overlapped_with_reserved(base, size) 345453452ccSLoGin { 346453452ccSLoGin // 如果内存已经被其他区域预留(即已经被映射),我们不应该允许它被标记为`nomap`, 347453452ccSLoGin // 但是不需要担心如果该区域不是内存(即不会被映射)的情况。 348453452ccSLoGin return Err(SystemError::EBUSY); 349453452ccSLoGin } 350453452ccSLoGin 351453452ccSLoGin return mem_block_manager().mark_nomap(base, size); 352453452ccSLoGin } 353453452ccSLoGin 354453452ccSLoGin return mem_block_manager().reserve_block(base, size); 355453452ccSLoGin } 356453452ccSLoGin } 357453452ccSLoGin 358453452ccSLoGin #[allow(dead_code)] 359453452ccSLoGin fn reserved_mem_reserve_reg(node: &FdtNode<'_, '_>) -> Result<(), SystemError> { 360453452ccSLoGin let global_data_guard: crate::libs::rwlock::RwLockReadGuard<'_, FdtGlobalData> = 361453452ccSLoGin FDT_GLOBAL_DATA.read(); 362453452ccSLoGin let t_len = ((global_data_guard.root_addr_cells + global_data_guard.root_size_cells) as usize) 363453452ccSLoGin * size_of::<u32>(); 364453452ccSLoGin drop(global_data_guard); 365453452ccSLoGin 366453452ccSLoGin let reg = node.property("reg").ok_or(SystemError::ENOENT)?; 367453452ccSLoGin 368453452ccSLoGin let mut reg_size = reg.value.len(); 369453452ccSLoGin if reg_size > 0 && reg_size % t_len != 0 { 370453452ccSLoGin kerror!( 371453452ccSLoGin "Reserved memory: invalid reg property in '{}', skipping node.", 372453452ccSLoGin node.name 373453452ccSLoGin ); 374453452ccSLoGin return Err(SystemError::EINVAL); 375453452ccSLoGin } 376453452ccSLoGin // 每个cell是4字节 377453452ccSLoGin let addr_cells = FDT_GLOBAL_DATA.read().root_addr_cells as usize; 378453452ccSLoGin let size_cells = FDT_GLOBAL_DATA.read().root_size_cells as usize; 379453452ccSLoGin 380453452ccSLoGin let nomap = node.property("no-map").is_some(); 381453452ccSLoGin 382453452ccSLoGin let mut base_index = 0; 383453452ccSLoGin 384453452ccSLoGin while reg_size >= t_len { 385453452ccSLoGin let (base, bi) = read_cell(reg.value, base_index, addr_cells); 386453452ccSLoGin base_index = bi; 387453452ccSLoGin let (size, bi) = read_cell(reg.value, base_index, size_cells); 388453452ccSLoGin base_index = bi; 389453452ccSLoGin 390453452ccSLoGin if size > 0 391453452ccSLoGin && open_firmware_fdt_driver() 392453452ccSLoGin .early_init_dt_reserve_memory(PhysAddr::new(base as usize), size as usize, nomap) 393453452ccSLoGin .is_ok() 394453452ccSLoGin { 395453452ccSLoGin kdebug!( 396453452ccSLoGin "Reserved memory: base={:#x}, size={:#x}, nomap={}", 397453452ccSLoGin base, 398453452ccSLoGin size, 399453452ccSLoGin nomap 400453452ccSLoGin ); 401453452ccSLoGin } else { 402453452ccSLoGin kerror!( 403453452ccSLoGin "Failed to reserve memory: base={:#x}, size={:#x}, nomap={}", 404453452ccSLoGin base, 405453452ccSLoGin size, 406453452ccSLoGin nomap 407453452ccSLoGin ); 408453452ccSLoGin } 409453452ccSLoGin 410453452ccSLoGin reg_size -= t_len; 411453452ccSLoGin 412453452ccSLoGin // todo: linux这里保存了节点,但是我感觉现在还用不着。 413453452ccSLoGin } 414453452ccSLoGin 415453452ccSLoGin return Ok(()); 416453452ccSLoGin } 417453452ccSLoGin 418453452ccSLoGin /// 从FDT的`reg`属性中读取指定数量的cell,作为一个小端u64返回 419453452ccSLoGin /// 420453452ccSLoGin /// ## 参数 421453452ccSLoGin /// 422453452ccSLoGin /// - `reg_value`:`reg`属性数组的引用 423453452ccSLoGin /// - `base_index`:起始索引 424453452ccSLoGin /// - `cells`:要读取的cell数量,必须是1或2 425453452ccSLoGin /// 426453452ccSLoGin /// ## 返回值 427453452ccSLoGin /// 428453452ccSLoGin /// (value, next_base_index) 429453452ccSLoGin fn read_cell(reg_value: &[u8], base_index: usize, cells: usize) -> (u64, usize) { 430453452ccSLoGin let next_base_index = base_index + cells * 4; 431453452ccSLoGin match cells { 432453452ccSLoGin 1 => { 433453452ccSLoGin return ( 434453452ccSLoGin u32::from_be_bytes(reg_value[base_index..base_index + 4].try_into().unwrap()) 435453452ccSLoGin .try_into() 436453452ccSLoGin .unwrap(), 437453452ccSLoGin next_base_index, 438453452ccSLoGin ); 439453452ccSLoGin } 440453452ccSLoGin 441453452ccSLoGin 2 => { 442453452ccSLoGin return ( 443453452ccSLoGin u64::from_be_bytes(reg_value[base_index..base_index + 8].try_into().unwrap()), 444453452ccSLoGin next_base_index, 445453452ccSLoGin ); 446453452ccSLoGin } 447453452ccSLoGin _ => { 448453452ccSLoGin panic!("cells must be 1 or 2"); 449453452ccSLoGin } 450453452ccSLoGin } 45145626c85SLoGin } 452