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, 1223ef2b33SLoGin mm::{memblock::mem_block_manager, mmio_buddy::MMIOSpaceGuard, PhysAddr}, 13453452ccSLoGin }; 1445626c85SLoGin 1523ef2b33SLoGin static OPEN_FIRMWARE_FDT_DRIVER: OpenFirmwareFdtDriver = OpenFirmwareFdtDriver::new(); 1623ef2b33SLoGin 1745626c85SLoGin #[inline(always)] 1845626c85SLoGin pub fn open_firmware_fdt_driver() -> &'static OpenFirmwareFdtDriver { 1923ef2b33SLoGin &OPEN_FIRMWARE_FDT_DRIVER 2045626c85SLoGin } 2145626c85SLoGin 2245626c85SLoGin static FDT_GLOBAL_DATA: RwLock<FdtGlobalData> = RwLock::new(FdtGlobalData::new()); 2345626c85SLoGin 2445626c85SLoGin #[derive(Debug)] 2545626c85SLoGin struct FdtGlobalData { 2645626c85SLoGin /// FDT根节点下的`size-cells`属性值 2745626c85SLoGin root_size_cells: u32, 2845626c85SLoGin 2945626c85SLoGin /// FDT根节点下的`address-cells`属性值 3045626c85SLoGin root_addr_cells: u32, 3145626c85SLoGin 3245626c85SLoGin chosen_node_name: Option<&'static str>, 3345626c85SLoGin } 3445626c85SLoGin 3545626c85SLoGin impl FdtGlobalData { 3645626c85SLoGin pub const fn new() -> Self { 3745626c85SLoGin Self { 3845626c85SLoGin root_size_cells: 1, 3945626c85SLoGin root_addr_cells: 1, 4045626c85SLoGin chosen_node_name: None, 4145626c85SLoGin } 4245626c85SLoGin } 4345626c85SLoGin } 4445626c85SLoGin 4523ef2b33SLoGin #[allow(dead_code)] 4623ef2b33SLoGin pub struct OpenFirmwareFdtDriver { 4723ef2b33SLoGin inner: RwLock<InnerOpenFirmwareFdtDriver>, 4823ef2b33SLoGin } 4923ef2b33SLoGin 5023ef2b33SLoGin #[allow(dead_code)] 5123ef2b33SLoGin pub struct InnerOpenFirmwareFdtDriver { 5223ef2b33SLoGin /// FDT自身映射的MMIO空间 5323ef2b33SLoGin fdt_map_guard: Option<MMIOSpaceGuard>, 5423ef2b33SLoGin } 5545626c85SLoGin 5645626c85SLoGin impl OpenFirmwareFdtDriver { 5723ef2b33SLoGin const fn new() -> Self { 5823ef2b33SLoGin Self { 5923ef2b33SLoGin inner: RwLock::new(InnerOpenFirmwareFdtDriver { 6023ef2b33SLoGin fdt_map_guard: None, 6123ef2b33SLoGin }), 6223ef2b33SLoGin } 6323ef2b33SLoGin } 6423ef2b33SLoGin 6592849878SLoGin #[allow(dead_code)] 6645626c85SLoGin pub fn early_scan_device_tree(&self) -> Result<(), SystemError> { 6723ef2b33SLoGin let fdt = self.fdt_ref()?; 6823ef2b33SLoGin self.early_init_scan_nodes(&fdt); 6923ef2b33SLoGin 7023ef2b33SLoGin return Ok(()); 7123ef2b33SLoGin } 7223ef2b33SLoGin 7323ef2b33SLoGin pub unsafe fn set_fdt_map_guard(&self, guard: Option<MMIOSpaceGuard>) { 7423ef2b33SLoGin self.inner.write().fdt_map_guard = guard; 7523ef2b33SLoGin } 7623ef2b33SLoGin 7723ef2b33SLoGin /// 获取FDT的引用 7823ef2b33SLoGin pub fn fdt_ref(&self) -> Result<Fdt<'static>, SystemError> { 797a29d4fcSLoGin let fdt_vaddr = boot_params().read().fdt().unwrap(); 8023ef2b33SLoGin let fdt: Fdt<'_> = unsafe { 8145626c85SLoGin fdt::Fdt::from_ptr(fdt_vaddr.as_ptr()).map_err(|e| { 8245626c85SLoGin kerror!("failed to parse fdt, err={:?}", e); 8345626c85SLoGin SystemError::EINVAL 8445626c85SLoGin }) 8545626c85SLoGin }?; 8623ef2b33SLoGin Ok(fdt) 8745626c85SLoGin } 8845626c85SLoGin 8945626c85SLoGin fn early_init_scan_nodes(&self, fdt: &Fdt) { 9045626c85SLoGin self.early_init_scan_root(fdt) 9145626c85SLoGin .expect("Failed to scan fdt root node."); 9245626c85SLoGin 9345626c85SLoGin self.early_init_scan_chosen(fdt).unwrap_or_else(|_| { 9445626c85SLoGin kwarn!("No `chosen` node found"); 9545626c85SLoGin }); 9645626c85SLoGin 9745626c85SLoGin self.early_init_scan_memory(fdt); 9845626c85SLoGin } 9945626c85SLoGin 10045626c85SLoGin /// 扫描根节点 10145626c85SLoGin fn early_init_scan_root(&self, fdt: &Fdt) -> Result<(), SystemError> { 10245626c85SLoGin let node = fdt.find_node("/").ok_or(SystemError::ENODEV)?; 10345626c85SLoGin 10445626c85SLoGin let mut guard = FDT_GLOBAL_DATA.write(); 10545626c85SLoGin 10645626c85SLoGin if let Some(prop) = node.property("#size-cells") { 10745626c85SLoGin guard.root_size_cells = prop.as_usize().unwrap() as u32; 10845626c85SLoGin 109453452ccSLoGin // kdebug!("fdt_root_size_cells={}", guard.root_size_cells); 11045626c85SLoGin } 11145626c85SLoGin 11245626c85SLoGin if let Some(prop) = node.property("#address-cells") { 11345626c85SLoGin guard.root_addr_cells = prop.as_usize().unwrap() as u32; 11445626c85SLoGin 115453452ccSLoGin // kdebug!("fdt_root_addr_cells={}", guard.root_addr_cells); 11645626c85SLoGin } 11745626c85SLoGin 11845626c85SLoGin return Ok(()); 11945626c85SLoGin } 12045626c85SLoGin 12145626c85SLoGin /// 扫描 `/chosen` 节点 12245626c85SLoGin fn early_init_scan_chosen(&self, fdt: &Fdt) -> Result<(), SystemError> { 123b5b571e0SLoGin const CHOSEN_NAME1: &str = "/chosen"; 12445626c85SLoGin let mut node = fdt.find_node(CHOSEN_NAME1); 12545626c85SLoGin if node.is_none() { 126b5b571e0SLoGin const CHOSEN_NAME2: &str = "/chosen@0"; 12745626c85SLoGin node = fdt.find_node(CHOSEN_NAME2); 12845626c85SLoGin if node.is_some() { 12945626c85SLoGin FDT_GLOBAL_DATA.write().chosen_node_name = Some(CHOSEN_NAME2); 13045626c85SLoGin } 13145626c85SLoGin } else { 13245626c85SLoGin FDT_GLOBAL_DATA.write().chosen_node_name = Some(CHOSEN_NAME1); 13345626c85SLoGin } 13445626c85SLoGin 13545626c85SLoGin if let Some(node) = node { 13645626c85SLoGin if let Some(prop) = node.property("bootargs") { 13745626c85SLoGin let bootargs = prop.as_str().unwrap(); 13845626c85SLoGin 13945626c85SLoGin boot_params() 14045626c85SLoGin .write() 14145626c85SLoGin .boot_cmdline_append(bootargs.as_bytes()); 14245626c85SLoGin } 14345626c85SLoGin } 14445626c85SLoGin 14545626c85SLoGin // TODO: 拼接内核自定义的command line参数 14645626c85SLoGin 14745626c85SLoGin kdebug!("Command line: {}", boot_params().read().boot_cmdline_str()); 14845626c85SLoGin return Ok(()); 14945626c85SLoGin } 15045626c85SLoGin 15145626c85SLoGin /// 扫描 `/memory` 节点 15245626c85SLoGin /// 15345626c85SLoGin /// ## 参数 15445626c85SLoGin /// 15545626c85SLoGin /// - `fdt`:FDT 15645626c85SLoGin /// 15745626c85SLoGin /// ## 返回值 15845626c85SLoGin /// 15945626c85SLoGin /// 如果扫描成功,找到可用内存,则返回`true`,否则返回`false`。 16045626c85SLoGin fn early_init_scan_memory(&self, fdt: &Fdt) -> bool { 16145626c85SLoGin let mut found_memory = false; 16245626c85SLoGin for node in fdt.all_nodes() { 16345626c85SLoGin let device_type: Option<NodeProperty<'_>> = node.property("device_type"); 16445626c85SLoGin if device_type.is_none() { 16545626c85SLoGin continue; 16645626c85SLoGin } 16745626c85SLoGin let device_type = device_type.unwrap().as_str(); 16845626c85SLoGin if device_type.is_none() || device_type.unwrap() != "memory" { 16945626c85SLoGin continue; 17045626c85SLoGin } 17145626c85SLoGin 17245626c85SLoGin if !self.is_device_avaliable(&node) { 17345626c85SLoGin continue; 17445626c85SLoGin } 17545626c85SLoGin 17645626c85SLoGin let reg = node.property("reg"); 17745626c85SLoGin if reg.is_none() { 17845626c85SLoGin continue; 17945626c85SLoGin } 18045626c85SLoGin let reg = reg.unwrap(); 18145626c85SLoGin // 每个cell是4字节 18245626c85SLoGin let addr_cells = FDT_GLOBAL_DATA.read().root_addr_cells as usize; 18345626c85SLoGin let size_cells = FDT_GLOBAL_DATA.read().root_size_cells as usize; 18445626c85SLoGin 18545626c85SLoGin let total_elements_in_reg = reg.value.len() / ((addr_cells + size_cells) * 4); 18645626c85SLoGin 18745626c85SLoGin for i in 0..total_elements_in_reg { 188453452ccSLoGin let base_index = i * (addr_cells + size_cells); 18945626c85SLoGin 190453452ccSLoGin let (base, base_index) = read_cell(reg.value, base_index, addr_cells); 191453452ccSLoGin let (size, _) = read_cell(reg.value, base_index, size_cells); 19245626c85SLoGin 19345626c85SLoGin if size == 0 { 19445626c85SLoGin continue; 19545626c85SLoGin } 19645626c85SLoGin 19745626c85SLoGin kdebug!("Found memory: base={:#x}, size={:#x}", base, size); 19845626c85SLoGin self.early_init_dt_add_memory(base, size); 19945626c85SLoGin found_memory = true; 20045626c85SLoGin } 20145626c85SLoGin } 20245626c85SLoGin 20345626c85SLoGin return found_memory; 20445626c85SLoGin } 20545626c85SLoGin 20692849878SLoGin #[cfg(target_arch = "x86_64")] 20792849878SLoGin pub fn early_init_dt_add_memory(&self, _base: u64, _size: u64) { 20892849878SLoGin kBUG!("x86_64 should not call early_init_dt_add_memory"); 20992849878SLoGin } 21092849878SLoGin 21192849878SLoGin #[cfg(not(target_arch = "x86_64"))] 21292849878SLoGin pub fn early_init_dt_add_memory(&self, base: u64, size: u64) { 21392849878SLoGin use crate::{ 21492849878SLoGin arch::MMArch, 21592849878SLoGin libs::align::page_align_down, 21692849878SLoGin mm::{ 21792849878SLoGin memblock::{mem_block_manager, MemBlockManager}, 21892849878SLoGin MemoryManagementArch, PhysAddr, 21992849878SLoGin }, 22092849878SLoGin }; 22192849878SLoGin 22245626c85SLoGin let mut base = base as usize; 22345626c85SLoGin let mut size = size as usize; 22445626c85SLoGin 22545626c85SLoGin if size < (MMArch::PAGE_SIZE - (base & (!MMArch::PAGE_MASK))) { 22645626c85SLoGin kwarn!("Ignoring memory block {:#x}-{:#x}", base, base + size); 22745626c85SLoGin } 22845626c85SLoGin 22945626c85SLoGin if PhysAddr::new(base).check_aligned(MMArch::PAGE_SIZE) == false { 23045626c85SLoGin size -= MMArch::PAGE_SIZE - (base & (!MMArch::PAGE_MASK)); 23145626c85SLoGin base = page_align_down(base); 23245626c85SLoGin } 23345626c85SLoGin 23445626c85SLoGin size = page_align_down(size); 23545626c85SLoGin 23645626c85SLoGin if base > MemBlockManager::MAX_MEMBLOCK_ADDR.data() { 23745626c85SLoGin kwarn!("Ignoring memory block {:#x}-{:#x}", base, base + size); 23845626c85SLoGin } 23945626c85SLoGin 24045626c85SLoGin if base + size - 1 > MemBlockManager::MAX_MEMBLOCK_ADDR.data() { 24145626c85SLoGin kwarn!( 24245626c85SLoGin "Ignoring memory range {:#x}-{:#x}", 24345626c85SLoGin MemBlockManager::MAX_MEMBLOCK_ADDR.data() + 1, 24445626c85SLoGin base + size 24545626c85SLoGin ); 24645626c85SLoGin size = MemBlockManager::MAX_MEMBLOCK_ADDR.data() - base + 1; 24745626c85SLoGin } 24845626c85SLoGin 24945626c85SLoGin if base + size < MemBlockManager::MIN_MEMBLOCK_ADDR.data() { 25045626c85SLoGin kwarn!("Ignoring memory range {:#x}-{:#x}", base, base + size); 25145626c85SLoGin return; 25245626c85SLoGin } 25345626c85SLoGin 25445626c85SLoGin if base < MemBlockManager::MIN_MEMBLOCK_ADDR.data() { 25545626c85SLoGin { 25645626c85SLoGin kwarn!( 25745626c85SLoGin "Ignoring memory range {:#x}-{:#x}", 25845626c85SLoGin base, 25945626c85SLoGin MemBlockManager::MIN_MEMBLOCK_ADDR.data() 26045626c85SLoGin ); 26145626c85SLoGin size -= MemBlockManager::MIN_MEMBLOCK_ADDR.data() - base; 26245626c85SLoGin base = MemBlockManager::MIN_MEMBLOCK_ADDR.data(); 26345626c85SLoGin } 264453452ccSLoGin } 26545626c85SLoGin 26645626c85SLoGin mem_block_manager() 26745626c85SLoGin .add_block(PhysAddr::new(base), size) 26845626c85SLoGin .unwrap_or_else(|e| { 26945626c85SLoGin panic!( 27045626c85SLoGin "Failed to add memory block '{:#x}-{:#x}', err={:?}", 27145626c85SLoGin base, 27245626c85SLoGin base + size, 27345626c85SLoGin e 27445626c85SLoGin ); 27545626c85SLoGin }); 27645626c85SLoGin } 27745626c85SLoGin 278453452ccSLoGin /// 判断设备是否可用 27945626c85SLoGin fn is_device_avaliable(&self, node: &FdtNode) -> bool { 28045626c85SLoGin let status = node.property("status"); 28145626c85SLoGin if status.is_none() { 28245626c85SLoGin return true; 28345626c85SLoGin } 28445626c85SLoGin 28545626c85SLoGin let status = status.unwrap().as_str(); 28645626c85SLoGin if let Some(status) = status { 28745626c85SLoGin if status == "okay" || status == "ok" { 28845626c85SLoGin return true; 28945626c85SLoGin } 29045626c85SLoGin } 29145626c85SLoGin 29245626c85SLoGin return false; 29345626c85SLoGin } 294453452ccSLoGin 295453452ccSLoGin /// 在UEFI初始化后,扫描FDT中的`/reserved-memory`节点,设置保留的内存 296453452ccSLoGin /// 297453452ccSLoGin /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/of/fdt.c#634 298453452ccSLoGin pub fn early_init_fdt_scan_reserved_mem(&self) { 299453452ccSLoGin let vaddr = boot_params().read().fdt(); 300453452ccSLoGin if vaddr.is_none() { 301453452ccSLoGin return; 302453452ccSLoGin } 303453452ccSLoGin let vaddr = vaddr.unwrap(); 304453452ccSLoGin let fdt = unsafe { Fdt::from_ptr(vaddr.data() as *const u8) }; 305453452ccSLoGin if fdt.is_err() { 306453452ccSLoGin return; 307453452ccSLoGin } 308453452ccSLoGin 309453452ccSLoGin let fdt = fdt.unwrap(); 310453452ccSLoGin self.early_reserve_fdt_itself(&fdt); 311453452ccSLoGin 312453452ccSLoGin let reserved_mem_nodes = fdt.memory_reservations(); 313453452ccSLoGin 314453452ccSLoGin for node in reserved_mem_nodes { 315453452ccSLoGin if node.size() != 0 { 316453452ccSLoGin let address = PhysAddr::new(node.address() as usize); 317453452ccSLoGin let size = node.size(); 318453452ccSLoGin kdebug!("Reserve memory: {:?}-{:?}", address, address + size); 319453452ccSLoGin mem_block_manager().reserve_block(address, size).unwrap(); 320453452ccSLoGin } 321453452ccSLoGin } 322453452ccSLoGin 323453452ccSLoGin self.fdt_scan_reserved_mem(&fdt) 324453452ccSLoGin .expect("Failed to scan reserved memory"); 325453452ccSLoGin } 326453452ccSLoGin 327453452ccSLoGin /// 保留fdt自身的内存空间 328453452ccSLoGin 329453452ccSLoGin fn early_reserve_fdt_itself(&self, fdt: &Fdt) { 330453452ccSLoGin #[cfg(target_arch = "riscv64")] 331453452ccSLoGin { 332453452ccSLoGin use crate::libs::align::{page_align_down, page_align_up}; 333453452ccSLoGin 334453452ccSLoGin let fdt_paddr = boot_params().read().arch.fdt_paddr; 335453452ccSLoGin let rsvd_start = PhysAddr::new(page_align_down(fdt_paddr.data())); 336453452ccSLoGin let rsvd_size = page_align_up(fdt_paddr.data() - rsvd_start.data() + fdt.total_size()); 337453452ccSLoGin mem_block_manager() 338453452ccSLoGin .reserve_block(rsvd_start, rsvd_size) 339453452ccSLoGin .expect("Failed to reserve memory for fdt"); 340453452ccSLoGin } 341453452ccSLoGin 342453452ccSLoGin #[cfg(target_arch = "x86_64")] 343453452ccSLoGin { 344453452ccSLoGin let _ = fdt; 345453452ccSLoGin } 346453452ccSLoGin } 347453452ccSLoGin 348453452ccSLoGin fn fdt_scan_reserved_mem(&self, fdt: &Fdt) -> Result<(), SystemError> { 349453452ccSLoGin let node = fdt 350453452ccSLoGin .find_node("/reserved-memory") 351453452ccSLoGin .ok_or(SystemError::ENODEV)?; 352453452ccSLoGin 353453452ccSLoGin for child in node.children() { 354453452ccSLoGin if !self.is_device_avaliable(&child) { 355453452ccSLoGin continue; 356453452ccSLoGin } 357453452ccSLoGin 358453452ccSLoGin reserved_mem_reserve_reg(&child).ok(); 359453452ccSLoGin } 360453452ccSLoGin 361453452ccSLoGin return Ok(()); 362453452ccSLoGin } 363453452ccSLoGin 364453452ccSLoGin fn early_init_dt_reserve_memory( 365453452ccSLoGin &self, 366453452ccSLoGin base: PhysAddr, 367453452ccSLoGin size: usize, 368453452ccSLoGin nomap: bool, 369453452ccSLoGin ) -> Result<(), SystemError> { 370453452ccSLoGin if nomap { 371453452ccSLoGin if mem_block_manager().is_overlapped(base, size) 372453452ccSLoGin && mem_block_manager().is_overlapped_with_reserved(base, size) 373453452ccSLoGin { 374453452ccSLoGin // 如果内存已经被其他区域预留(即已经被映射),我们不应该允许它被标记为`nomap`, 375453452ccSLoGin // 但是不需要担心如果该区域不是内存(即不会被映射)的情况。 376453452ccSLoGin return Err(SystemError::EBUSY); 377453452ccSLoGin } 378453452ccSLoGin 379453452ccSLoGin return mem_block_manager().mark_nomap(base, size); 380453452ccSLoGin } 381453452ccSLoGin 382453452ccSLoGin return mem_block_manager().reserve_block(base, size); 383453452ccSLoGin } 384*370472f7SLoGin 385*370472f7SLoGin pub fn find_node_by_compatible<'b>( 386*370472f7SLoGin &self, 387*370472f7SLoGin fdt: &'b Fdt<'b>, 388*370472f7SLoGin compatible: &'b str, 389*370472f7SLoGin ) -> impl Iterator<Item = fdt::node::FdtNode<'b, 'b>> + 'b { 390*370472f7SLoGin // compatible = compatible.trim(); 391*370472f7SLoGin let r = fdt.all_nodes().filter(move |x| { 392*370472f7SLoGin x.compatible() 393*370472f7SLoGin .is_some_and(|x| x.all().any(|x| x == compatible)) 394*370472f7SLoGin }); 395*370472f7SLoGin 396*370472f7SLoGin return r; 397*370472f7SLoGin } 398453452ccSLoGin } 399453452ccSLoGin 400453452ccSLoGin #[allow(dead_code)] 401453452ccSLoGin fn reserved_mem_reserve_reg(node: &FdtNode<'_, '_>) -> Result<(), SystemError> { 402453452ccSLoGin let global_data_guard: crate::libs::rwlock::RwLockReadGuard<'_, FdtGlobalData> = 403453452ccSLoGin FDT_GLOBAL_DATA.read(); 404453452ccSLoGin let t_len = ((global_data_guard.root_addr_cells + global_data_guard.root_size_cells) as usize) 405453452ccSLoGin * size_of::<u32>(); 406453452ccSLoGin drop(global_data_guard); 407453452ccSLoGin 408453452ccSLoGin let reg = node.property("reg").ok_or(SystemError::ENOENT)?; 409453452ccSLoGin 410453452ccSLoGin let mut reg_size = reg.value.len(); 411453452ccSLoGin if reg_size > 0 && reg_size % t_len != 0 { 412453452ccSLoGin kerror!( 413453452ccSLoGin "Reserved memory: invalid reg property in '{}', skipping node.", 414453452ccSLoGin node.name 415453452ccSLoGin ); 416453452ccSLoGin return Err(SystemError::EINVAL); 417453452ccSLoGin } 418453452ccSLoGin // 每个cell是4字节 419453452ccSLoGin let addr_cells = FDT_GLOBAL_DATA.read().root_addr_cells as usize; 420453452ccSLoGin let size_cells = FDT_GLOBAL_DATA.read().root_size_cells as usize; 421453452ccSLoGin 422453452ccSLoGin let nomap = node.property("no-map").is_some(); 423453452ccSLoGin 424453452ccSLoGin let mut base_index = 0; 425453452ccSLoGin 426453452ccSLoGin while reg_size >= t_len { 427453452ccSLoGin let (base, bi) = read_cell(reg.value, base_index, addr_cells); 428453452ccSLoGin base_index = bi; 429453452ccSLoGin let (size, bi) = read_cell(reg.value, base_index, size_cells); 430453452ccSLoGin base_index = bi; 431453452ccSLoGin 432453452ccSLoGin if size > 0 433453452ccSLoGin && open_firmware_fdt_driver() 434453452ccSLoGin .early_init_dt_reserve_memory(PhysAddr::new(base as usize), size as usize, nomap) 435453452ccSLoGin .is_ok() 436453452ccSLoGin { 437453452ccSLoGin kdebug!( 438453452ccSLoGin "Reserved memory: base={:#x}, size={:#x}, nomap={}", 439453452ccSLoGin base, 440453452ccSLoGin size, 441453452ccSLoGin nomap 442453452ccSLoGin ); 443453452ccSLoGin } else { 444453452ccSLoGin kerror!( 445453452ccSLoGin "Failed to reserve memory: base={:#x}, size={:#x}, nomap={}", 446453452ccSLoGin base, 447453452ccSLoGin size, 448453452ccSLoGin nomap 449453452ccSLoGin ); 450453452ccSLoGin } 451453452ccSLoGin 452453452ccSLoGin reg_size -= t_len; 453453452ccSLoGin 454453452ccSLoGin // todo: linux这里保存了节点,但是我感觉现在还用不着。 455453452ccSLoGin } 456453452ccSLoGin 457453452ccSLoGin return Ok(()); 458453452ccSLoGin } 459453452ccSLoGin 460453452ccSLoGin /// 从FDT的`reg`属性中读取指定数量的cell,作为一个小端u64返回 461453452ccSLoGin /// 462453452ccSLoGin /// ## 参数 463453452ccSLoGin /// 464453452ccSLoGin /// - `reg_value`:`reg`属性数组的引用 465453452ccSLoGin /// - `base_index`:起始索引 466453452ccSLoGin /// - `cells`:要读取的cell数量,必须是1或2 467453452ccSLoGin /// 468453452ccSLoGin /// ## 返回值 469453452ccSLoGin /// 470453452ccSLoGin /// (value, next_base_index) 471453452ccSLoGin fn read_cell(reg_value: &[u8], base_index: usize, cells: usize) -> (u64, usize) { 472453452ccSLoGin let next_base_index = base_index + cells * 4; 473453452ccSLoGin match cells { 474453452ccSLoGin 1 => { 475453452ccSLoGin return ( 476453452ccSLoGin u32::from_be_bytes(reg_value[base_index..base_index + 4].try_into().unwrap()) 477453452ccSLoGin .try_into() 478453452ccSLoGin .unwrap(), 479453452ccSLoGin next_base_index, 480453452ccSLoGin ); 481453452ccSLoGin } 482453452ccSLoGin 483453452ccSLoGin 2 => { 484453452ccSLoGin return ( 485453452ccSLoGin u64::from_be_bytes(reg_value[base_index..base_index + 8].try_into().unwrap()), 486453452ccSLoGin next_base_index, 487453452ccSLoGin ); 488453452ccSLoGin } 489453452ccSLoGin _ => { 490453452ccSLoGin panic!("cells must be 1 or 2"); 491453452ccSLoGin } 492453452ccSLoGin } 49345626c85SLoGin } 494