xref: /DragonOS/kernel/src/driver/open_firmware/fdt.rs (revision 370472f7288b568c7b80815f5b150daf4496446c)
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