xref: /DragonOS/kernel/src/driver/open_firmware/fdt.rs (revision bd70d2d1f490aabd570a5301b858bd5eb04149fa)
1453452ccSLoGin use core::mem::size_of;
2453452ccSLoGin 
345626c85SLoGin use fdt::{
445626c85SLoGin     node::{FdtNode, NodeProperty},
545626c85SLoGin     Fdt,
645626c85SLoGin };
72eab6dd7S曾俊 use log::{debug, error, warn};
845626c85SLoGin use system_error::SystemError;
945626c85SLoGin 
10453452ccSLoGin use crate::{
11453452ccSLoGin     init::boot_params,
12453452ccSLoGin     libs::rwlock::RwLock,
1323ef2b33SLoGin     mm::{memblock::mem_block_manager, mmio_buddy::MMIOSpaceGuard, PhysAddr},
14453452ccSLoGin };
1545626c85SLoGin 
1623ef2b33SLoGin static OPEN_FIRMWARE_FDT_DRIVER: OpenFirmwareFdtDriver = OpenFirmwareFdtDriver::new();
1723ef2b33SLoGin 
1845626c85SLoGin #[inline(always)]
open_firmware_fdt_driver() -> &'static OpenFirmwareFdtDriver1945626c85SLoGin pub fn open_firmware_fdt_driver() -> &'static OpenFirmwareFdtDriver {
2023ef2b33SLoGin     &OPEN_FIRMWARE_FDT_DRIVER
2145626c85SLoGin }
2245626c85SLoGin 
2345626c85SLoGin static FDT_GLOBAL_DATA: RwLock<FdtGlobalData> = RwLock::new(FdtGlobalData::new());
2445626c85SLoGin 
2545626c85SLoGin #[derive(Debug)]
2645626c85SLoGin struct FdtGlobalData {
2745626c85SLoGin     /// FDT根节点下的`size-cells`属性值
2845626c85SLoGin     root_size_cells: u32,
2945626c85SLoGin 
3045626c85SLoGin     /// FDT根节点下的`address-cells`属性值
3145626c85SLoGin     root_addr_cells: u32,
3245626c85SLoGin 
3345626c85SLoGin     chosen_node_name: Option<&'static str>,
3445626c85SLoGin }
3545626c85SLoGin 
3645626c85SLoGin impl FdtGlobalData {
new() -> Self3745626c85SLoGin     pub const fn new() -> Self {
3845626c85SLoGin         Self {
3945626c85SLoGin             root_size_cells: 1,
4045626c85SLoGin             root_addr_cells: 1,
4145626c85SLoGin             chosen_node_name: None,
4245626c85SLoGin         }
4345626c85SLoGin     }
4445626c85SLoGin }
4545626c85SLoGin 
4623ef2b33SLoGin #[allow(dead_code)]
4723ef2b33SLoGin pub struct OpenFirmwareFdtDriver {
4823ef2b33SLoGin     inner: RwLock<InnerOpenFirmwareFdtDriver>,
4923ef2b33SLoGin }
5023ef2b33SLoGin 
5123ef2b33SLoGin #[allow(dead_code)]
5223ef2b33SLoGin pub struct InnerOpenFirmwareFdtDriver {
5323ef2b33SLoGin     /// FDT自身映射的MMIO空间
5423ef2b33SLoGin     fdt_map_guard: Option<MMIOSpaceGuard>,
5523ef2b33SLoGin }
5645626c85SLoGin 
5745626c85SLoGin impl OpenFirmwareFdtDriver {
new() -> Self5823ef2b33SLoGin     const fn new() -> Self {
5923ef2b33SLoGin         Self {
6023ef2b33SLoGin             inner: RwLock::new(InnerOpenFirmwareFdtDriver {
6123ef2b33SLoGin                 fdt_map_guard: None,
6223ef2b33SLoGin             }),
6323ef2b33SLoGin         }
6423ef2b33SLoGin     }
6523ef2b33SLoGin 
6692849878SLoGin     #[allow(dead_code)]
early_scan_device_tree(&self) -> Result<(), SystemError>6745626c85SLoGin     pub fn early_scan_device_tree(&self) -> Result<(), SystemError> {
6823ef2b33SLoGin         let fdt = self.fdt_ref()?;
6923ef2b33SLoGin         self.early_init_scan_nodes(&fdt);
7023ef2b33SLoGin 
7123ef2b33SLoGin         return Ok(());
7223ef2b33SLoGin     }
7323ef2b33SLoGin 
set_fdt_map_guard(&self, guard: Option<MMIOSpaceGuard>)7423ef2b33SLoGin     pub unsafe fn set_fdt_map_guard(&self, guard: Option<MMIOSpaceGuard>) {
7523ef2b33SLoGin         self.inner.write().fdt_map_guard = guard;
7623ef2b33SLoGin     }
7723ef2b33SLoGin 
7823ef2b33SLoGin     /// 获取FDT的引用
fdt_ref(&self) -> Result<Fdt<'static>, SystemError>7923ef2b33SLoGin     pub fn fdt_ref(&self) -> Result<Fdt<'static>, SystemError> {
80731bc2b3SLoGin         let fdt_vaddr = boot_params().read().fdt().ok_or(SystemError::ENODEV)?;
8123ef2b33SLoGin         let fdt: Fdt<'_> = unsafe {
8245626c85SLoGin             fdt::Fdt::from_ptr(fdt_vaddr.as_ptr()).map_err(|e| {
832eab6dd7S曾俊                 error!("failed to parse fdt, err={:?}", e);
8445626c85SLoGin                 SystemError::EINVAL
8545626c85SLoGin             })
8645626c85SLoGin         }?;
8723ef2b33SLoGin         Ok(fdt)
8845626c85SLoGin     }
8945626c85SLoGin 
early_init_scan_nodes(&self, fdt: &Fdt)9045626c85SLoGin     fn early_init_scan_nodes(&self, fdt: &Fdt) {
9145626c85SLoGin         self.early_init_scan_root(fdt)
9245626c85SLoGin             .expect("Failed to scan fdt root node.");
9345626c85SLoGin 
9445626c85SLoGin         self.early_init_scan_chosen(fdt).unwrap_or_else(|_| {
952eab6dd7S曾俊             warn!("No `chosen` node found");
9645626c85SLoGin         });
9745626c85SLoGin 
9845626c85SLoGin         self.early_init_scan_memory(fdt);
9945626c85SLoGin     }
10045626c85SLoGin 
10145626c85SLoGin     /// 扫描根节点
early_init_scan_root(&self, fdt: &Fdt) -> Result<(), SystemError>10245626c85SLoGin     fn early_init_scan_root(&self, fdt: &Fdt) -> Result<(), SystemError> {
10345626c85SLoGin         let node = fdt.find_node("/").ok_or(SystemError::ENODEV)?;
10445626c85SLoGin 
10545626c85SLoGin         let mut guard = FDT_GLOBAL_DATA.write();
10645626c85SLoGin 
10745626c85SLoGin         if let Some(prop) = node.property("#size-cells") {
10845626c85SLoGin             guard.root_size_cells = prop.as_usize().unwrap() as u32;
10945626c85SLoGin 
1102eab6dd7S曾俊             // debug!("fdt_root_size_cells={}", guard.root_size_cells);
11145626c85SLoGin         }
11245626c85SLoGin 
11345626c85SLoGin         if let Some(prop) = node.property("#address-cells") {
11445626c85SLoGin             guard.root_addr_cells = prop.as_usize().unwrap() as u32;
11545626c85SLoGin 
1162eab6dd7S曾俊             // debug!("fdt_root_addr_cells={}", guard.root_addr_cells);
11745626c85SLoGin         }
11845626c85SLoGin 
11945626c85SLoGin         return Ok(());
12045626c85SLoGin     }
12145626c85SLoGin 
12245626c85SLoGin     /// 扫描 `/chosen` 节点
early_init_scan_chosen(&self, fdt: &Fdt) -> Result<(), SystemError>12345626c85SLoGin     fn early_init_scan_chosen(&self, fdt: &Fdt) -> Result<(), SystemError> {
124b5b571e0SLoGin         const CHOSEN_NAME1: &str = "/chosen";
12545626c85SLoGin         let mut node = fdt.find_node(CHOSEN_NAME1);
12645626c85SLoGin         if node.is_none() {
127b5b571e0SLoGin             const CHOSEN_NAME2: &str = "/chosen@0";
12845626c85SLoGin             node = fdt.find_node(CHOSEN_NAME2);
12945626c85SLoGin             if node.is_some() {
13045626c85SLoGin                 FDT_GLOBAL_DATA.write().chosen_node_name = Some(CHOSEN_NAME2);
13145626c85SLoGin             }
13245626c85SLoGin         } else {
13345626c85SLoGin             FDT_GLOBAL_DATA.write().chosen_node_name = Some(CHOSEN_NAME1);
13445626c85SLoGin         }
13545626c85SLoGin 
13645626c85SLoGin         if let Some(node) = node {
13745626c85SLoGin             if let Some(prop) = node.property("bootargs") {
13845626c85SLoGin                 let bootargs = prop.as_str().unwrap();
13945626c85SLoGin 
14045626c85SLoGin                 boot_params()
14145626c85SLoGin                     .write()
14245626c85SLoGin                     .boot_cmdline_append(bootargs.as_bytes());
14345626c85SLoGin             }
14445626c85SLoGin         }
14545626c85SLoGin 
14645626c85SLoGin         // TODO: 拼接内核自定义的command line参数
14745626c85SLoGin 
1482eab6dd7S曾俊         debug!("Command line: {}", boot_params().read().boot_cmdline_str());
14945626c85SLoGin         return Ok(());
15045626c85SLoGin     }
15145626c85SLoGin 
15245626c85SLoGin     /// 扫描 `/memory` 节点
15345626c85SLoGin     ///
15445626c85SLoGin     /// ## 参数
15545626c85SLoGin     ///
15645626c85SLoGin     /// - `fdt`:FDT
15745626c85SLoGin     ///
15845626c85SLoGin     /// ## 返回值
15945626c85SLoGin     ///
16045626c85SLoGin     /// 如果扫描成功,找到可用内存,则返回`true`,否则返回`false`。
early_init_scan_memory(&self, fdt: &Fdt) -> bool16145626c85SLoGin     fn early_init_scan_memory(&self, fdt: &Fdt) -> bool {
16245626c85SLoGin         let mut found_memory = false;
16345626c85SLoGin         for node in fdt.all_nodes() {
16445626c85SLoGin             let device_type: Option<NodeProperty<'_>> = node.property("device_type");
16545626c85SLoGin             if device_type.is_none() {
16645626c85SLoGin                 continue;
16745626c85SLoGin             }
16845626c85SLoGin             let device_type = device_type.unwrap().as_str();
16945626c85SLoGin             if device_type.is_none() || device_type.unwrap() != "memory" {
17045626c85SLoGin                 continue;
17145626c85SLoGin             }
17245626c85SLoGin 
17345626c85SLoGin             if !self.is_device_avaliable(&node) {
17445626c85SLoGin                 continue;
17545626c85SLoGin             }
17645626c85SLoGin 
17745626c85SLoGin             let reg = node.property("reg");
17845626c85SLoGin             if reg.is_none() {
17945626c85SLoGin                 continue;
18045626c85SLoGin             }
18145626c85SLoGin             let reg = reg.unwrap();
18245626c85SLoGin             // 每个cell是4字节
18345626c85SLoGin             let addr_cells = FDT_GLOBAL_DATA.read().root_addr_cells as usize;
18445626c85SLoGin             let size_cells = FDT_GLOBAL_DATA.read().root_size_cells as usize;
18545626c85SLoGin 
18645626c85SLoGin             let total_elements_in_reg = reg.value.len() / ((addr_cells + size_cells) * 4);
18745626c85SLoGin 
18845626c85SLoGin             for i in 0..total_elements_in_reg {
189453452ccSLoGin                 let base_index = i * (addr_cells + size_cells);
19045626c85SLoGin 
191453452ccSLoGin                 let (base, base_index) = read_cell(reg.value, base_index, addr_cells);
192453452ccSLoGin                 let (size, _) = read_cell(reg.value, base_index, size_cells);
19345626c85SLoGin 
19445626c85SLoGin                 if size == 0 {
19545626c85SLoGin                     continue;
19645626c85SLoGin                 }
19745626c85SLoGin 
1982eab6dd7S曾俊                 debug!("Found memory: base={:#x}, size={:#x}", base, size);
19945626c85SLoGin                 self.early_init_dt_add_memory(base, size);
20045626c85SLoGin                 found_memory = true;
20145626c85SLoGin             }
20245626c85SLoGin         }
20345626c85SLoGin 
20445626c85SLoGin         return found_memory;
20545626c85SLoGin     }
20645626c85SLoGin 
20792849878SLoGin     #[cfg(target_arch = "x86_64")]
early_init_dt_add_memory(&self, _base: u64, _size: u64)20892849878SLoGin     pub fn early_init_dt_add_memory(&self, _base: u64, _size: u64) {
2092eab6dd7S曾俊         panic!("x86_64 should not call early_init_dt_add_memory");
21092849878SLoGin     }
21192849878SLoGin 
21292849878SLoGin     #[cfg(not(target_arch = "x86_64"))]
early_init_dt_add_memory(&self, base: u64, size: u64)21392849878SLoGin     pub fn early_init_dt_add_memory(&self, base: u64, size: u64) {
21492849878SLoGin         use crate::{
21592849878SLoGin             arch::MMArch,
21692849878SLoGin             libs::align::page_align_down,
217731bc2b3SLoGin             mm::{memblock::MemBlockManager, MemoryManagementArch},
21892849878SLoGin         };
21992849878SLoGin 
22045626c85SLoGin         let mut base = base as usize;
22145626c85SLoGin         let mut size = size as usize;
22245626c85SLoGin 
22345626c85SLoGin         if size < (MMArch::PAGE_SIZE - (base & (!MMArch::PAGE_MASK))) {
2242eab6dd7S曾俊             warn!("Ignoring memory block {:#x}-{:#x}", base, base + size);
22545626c85SLoGin         }
22645626c85SLoGin 
22745626c85SLoGin         if PhysAddr::new(base).check_aligned(MMArch::PAGE_SIZE) == false {
22845626c85SLoGin             size -= MMArch::PAGE_SIZE - (base & (!MMArch::PAGE_MASK));
22945626c85SLoGin             base = page_align_down(base);
23045626c85SLoGin         }
23145626c85SLoGin 
23245626c85SLoGin         size = page_align_down(size);
23345626c85SLoGin 
23445626c85SLoGin         if base > MemBlockManager::MAX_MEMBLOCK_ADDR.data() {
2352eab6dd7S曾俊             warn!("Ignoring memory block {:#x}-{:#x}", base, base + size);
23645626c85SLoGin         }
23745626c85SLoGin 
23845626c85SLoGin         if base + size - 1 > MemBlockManager::MAX_MEMBLOCK_ADDR.data() {
2392eab6dd7S曾俊             warn!(
24045626c85SLoGin                 "Ignoring memory range {:#x}-{:#x}",
24145626c85SLoGin                 MemBlockManager::MAX_MEMBLOCK_ADDR.data() + 1,
24245626c85SLoGin                 base + size
24345626c85SLoGin             );
24445626c85SLoGin             size = MemBlockManager::MAX_MEMBLOCK_ADDR.data() - base + 1;
24545626c85SLoGin         }
24645626c85SLoGin 
24745626c85SLoGin         if base + size < MemBlockManager::MIN_MEMBLOCK_ADDR.data() {
2482eab6dd7S曾俊             warn!("Ignoring memory range {:#x}-{:#x}", base, base + size);
24945626c85SLoGin             return;
25045626c85SLoGin         }
25145626c85SLoGin 
25245626c85SLoGin         if base < MemBlockManager::MIN_MEMBLOCK_ADDR.data() {
25345626c85SLoGin             {
2542eab6dd7S曾俊                 warn!(
25545626c85SLoGin                     "Ignoring memory range {:#x}-{:#x}",
25645626c85SLoGin                     base,
25745626c85SLoGin                     MemBlockManager::MIN_MEMBLOCK_ADDR.data()
25845626c85SLoGin                 );
25945626c85SLoGin                 size -= MemBlockManager::MIN_MEMBLOCK_ADDR.data() - base;
26045626c85SLoGin                 base = MemBlockManager::MIN_MEMBLOCK_ADDR.data();
26145626c85SLoGin             }
262453452ccSLoGin         }
26345626c85SLoGin 
26445626c85SLoGin         mem_block_manager()
26545626c85SLoGin             .add_block(PhysAddr::new(base), size)
26645626c85SLoGin             .unwrap_or_else(|e| {
26745626c85SLoGin                 panic!(
26845626c85SLoGin                     "Failed to add memory block '{:#x}-{:#x}', err={:?}",
26945626c85SLoGin                     base,
27045626c85SLoGin                     base + size,
27145626c85SLoGin                     e
27245626c85SLoGin                 );
27345626c85SLoGin             });
27445626c85SLoGin     }
27545626c85SLoGin 
276453452ccSLoGin     /// 判断设备是否可用
is_device_avaliable(&self, node: &FdtNode) -> bool27745626c85SLoGin     fn is_device_avaliable(&self, node: &FdtNode) -> bool {
27845626c85SLoGin         let status = node.property("status");
27945626c85SLoGin         if status.is_none() {
28045626c85SLoGin             return true;
28145626c85SLoGin         }
28245626c85SLoGin 
28345626c85SLoGin         let status = status.unwrap().as_str();
28445626c85SLoGin         if let Some(status) = status {
28545626c85SLoGin             if status == "okay" || status == "ok" {
28645626c85SLoGin                 return true;
28745626c85SLoGin             }
28845626c85SLoGin         }
28945626c85SLoGin 
29045626c85SLoGin         return false;
29145626c85SLoGin     }
292453452ccSLoGin 
293453452ccSLoGin     /// 在UEFI初始化后,扫描FDT中的`/reserved-memory`节点,设置保留的内存
294453452ccSLoGin     ///
295453452ccSLoGin     /// 参考: https://code.dragonos.org.cn/xref/linux-6.1.9/drivers/of/fdt.c#634
early_init_fdt_scan_reserved_mem(&self)296453452ccSLoGin     pub fn early_init_fdt_scan_reserved_mem(&self) {
297453452ccSLoGin         let vaddr = boot_params().read().fdt();
298453452ccSLoGin         if vaddr.is_none() {
299453452ccSLoGin             return;
300453452ccSLoGin         }
301453452ccSLoGin         let vaddr = vaddr.unwrap();
302453452ccSLoGin         let fdt = unsafe { Fdt::from_ptr(vaddr.data() as *const u8) };
303453452ccSLoGin         if fdt.is_err() {
304453452ccSLoGin             return;
305453452ccSLoGin         }
306453452ccSLoGin 
307453452ccSLoGin         let fdt = fdt.unwrap();
308453452ccSLoGin         self.early_reserve_fdt_itself(&fdt);
309453452ccSLoGin 
310453452ccSLoGin         let reserved_mem_nodes = fdt.memory_reservations();
311453452ccSLoGin 
312453452ccSLoGin         for node in reserved_mem_nodes {
313453452ccSLoGin             if node.size() != 0 {
314453452ccSLoGin                 let address = PhysAddr::new(node.address() as usize);
315453452ccSLoGin                 let size = node.size();
3162eab6dd7S曾俊                 debug!("Reserve memory: {:?}-{:?}", address, address + size);
317453452ccSLoGin                 mem_block_manager().reserve_block(address, size).unwrap();
318453452ccSLoGin             }
319453452ccSLoGin         }
320453452ccSLoGin 
321453452ccSLoGin         self.fdt_scan_reserved_mem(&fdt)
322453452ccSLoGin             .expect("Failed to scan reserved memory");
323453452ccSLoGin     }
324453452ccSLoGin 
325453452ccSLoGin     /// 保留fdt自身的内存空间
326453452ccSLoGin 
early_reserve_fdt_itself(&self, fdt: &Fdt)327453452ccSLoGin     fn early_reserve_fdt_itself(&self, fdt: &Fdt) {
328453452ccSLoGin         #[cfg(target_arch = "riscv64")]
329453452ccSLoGin         {
330453452ccSLoGin             use crate::libs::align::{page_align_down, page_align_up};
331453452ccSLoGin 
332453452ccSLoGin             let fdt_paddr = boot_params().read().arch.fdt_paddr;
333453452ccSLoGin             let rsvd_start = PhysAddr::new(page_align_down(fdt_paddr.data()));
334453452ccSLoGin             let rsvd_size = page_align_up(fdt_paddr.data() - rsvd_start.data() + fdt.total_size());
335453452ccSLoGin             mem_block_manager()
336453452ccSLoGin                 .reserve_block(rsvd_start, rsvd_size)
337453452ccSLoGin                 .expect("Failed to reserve memory for fdt");
338453452ccSLoGin         }
339453452ccSLoGin 
340453452ccSLoGin         #[cfg(target_arch = "x86_64")]
341453452ccSLoGin         {
342453452ccSLoGin             let _ = fdt;
343453452ccSLoGin         }
344453452ccSLoGin     }
345453452ccSLoGin 
fdt_scan_reserved_mem(&self, fdt: &Fdt) -> Result<(), SystemError>346453452ccSLoGin     fn fdt_scan_reserved_mem(&self, fdt: &Fdt) -> Result<(), SystemError> {
347453452ccSLoGin         let node = fdt
348453452ccSLoGin             .find_node("/reserved-memory")
349453452ccSLoGin             .ok_or(SystemError::ENODEV)?;
350453452ccSLoGin 
351453452ccSLoGin         for child in node.children() {
352453452ccSLoGin             if !self.is_device_avaliable(&child) {
353453452ccSLoGin                 continue;
354453452ccSLoGin             }
355453452ccSLoGin 
356453452ccSLoGin             reserved_mem_reserve_reg(&child).ok();
357453452ccSLoGin         }
358453452ccSLoGin 
359453452ccSLoGin         return Ok(());
360453452ccSLoGin     }
361453452ccSLoGin 
early_init_dt_reserve_memory( &self, base: PhysAddr, size: usize, nomap: bool, ) -> Result<(), SystemError>362453452ccSLoGin     fn early_init_dt_reserve_memory(
363453452ccSLoGin         &self,
364453452ccSLoGin         base: PhysAddr,
365453452ccSLoGin         size: usize,
366453452ccSLoGin         nomap: bool,
367453452ccSLoGin     ) -> Result<(), SystemError> {
368453452ccSLoGin         if nomap {
369453452ccSLoGin             if mem_block_manager().is_overlapped(base, size)
370453452ccSLoGin                 && mem_block_manager().is_overlapped_with_reserved(base, size)
371453452ccSLoGin             {
372453452ccSLoGin                 // 如果内存已经被其他区域预留(即已经被映射),我们不应该允许它被标记为`nomap`,
373453452ccSLoGin                 // 但是不需要担心如果该区域不是内存(即不会被映射)的情况。
374453452ccSLoGin                 return Err(SystemError::EBUSY);
375453452ccSLoGin             }
376453452ccSLoGin 
377453452ccSLoGin             return mem_block_manager().mark_nomap(base, size);
378453452ccSLoGin         }
379453452ccSLoGin 
380453452ccSLoGin         return mem_block_manager().reserve_block(base, size);
381453452ccSLoGin     }
382370472f7SLoGin 
find_node_by_compatible<'b>( &self, fdt: &'b Fdt<'b>, compatible: &'b str, ) -> impl Iterator<Item = fdt::node::FdtNode<'b, 'b>> + 'b383370472f7SLoGin     pub fn find_node_by_compatible<'b>(
384370472f7SLoGin         &self,
385370472f7SLoGin         fdt: &'b Fdt<'b>,
386370472f7SLoGin         compatible: &'b str,
387370472f7SLoGin     ) -> impl Iterator<Item = fdt::node::FdtNode<'b, 'b>> + 'b {
388370472f7SLoGin         // compatible = compatible.trim();
389370472f7SLoGin         let r = fdt.all_nodes().filter(move |x| {
390370472f7SLoGin             x.compatible()
391370472f7SLoGin                 .is_some_and(|x| x.all().any(|x| x == compatible))
392370472f7SLoGin         });
393370472f7SLoGin 
394370472f7SLoGin         return r;
395370472f7SLoGin     }
396453452ccSLoGin }
397453452ccSLoGin 
398453452ccSLoGin #[allow(dead_code)]
reserved_mem_reserve_reg(node: &FdtNode<'_, '_>) -> Result<(), SystemError>399453452ccSLoGin fn reserved_mem_reserve_reg(node: &FdtNode<'_, '_>) -> Result<(), SystemError> {
400453452ccSLoGin     let global_data_guard: crate::libs::rwlock::RwLockReadGuard<'_, FdtGlobalData> =
401453452ccSLoGin         FDT_GLOBAL_DATA.read();
402453452ccSLoGin     let t_len = ((global_data_guard.root_addr_cells + global_data_guard.root_size_cells) as usize)
403453452ccSLoGin         * size_of::<u32>();
404453452ccSLoGin     drop(global_data_guard);
405453452ccSLoGin 
406453452ccSLoGin     let reg = node.property("reg").ok_or(SystemError::ENOENT)?;
407453452ccSLoGin 
408453452ccSLoGin     let mut reg_size = reg.value.len();
409453452ccSLoGin     if reg_size > 0 && reg_size % t_len != 0 {
4102eab6dd7S曾俊         error!(
411453452ccSLoGin             "Reserved memory: invalid reg property in '{}', skipping node.",
412453452ccSLoGin             node.name
413453452ccSLoGin         );
414453452ccSLoGin         return Err(SystemError::EINVAL);
415453452ccSLoGin     }
416453452ccSLoGin     // 每个cell是4字节
417453452ccSLoGin     let addr_cells = FDT_GLOBAL_DATA.read().root_addr_cells as usize;
418453452ccSLoGin     let size_cells = FDT_GLOBAL_DATA.read().root_size_cells as usize;
419453452ccSLoGin 
420453452ccSLoGin     let nomap = node.property("no-map").is_some();
421453452ccSLoGin 
422453452ccSLoGin     let mut base_index = 0;
423453452ccSLoGin 
424453452ccSLoGin     while reg_size >= t_len {
425453452ccSLoGin         let (base, bi) = read_cell(reg.value, base_index, addr_cells);
426453452ccSLoGin         base_index = bi;
427453452ccSLoGin         let (size, bi) = read_cell(reg.value, base_index, size_cells);
428453452ccSLoGin         base_index = bi;
429453452ccSLoGin 
430453452ccSLoGin         if size > 0
431453452ccSLoGin             && open_firmware_fdt_driver()
432453452ccSLoGin                 .early_init_dt_reserve_memory(PhysAddr::new(base as usize), size as usize, nomap)
433453452ccSLoGin                 .is_ok()
434453452ccSLoGin         {
4352eab6dd7S曾俊             debug!(
436453452ccSLoGin                 "Reserved memory: base={:#x}, size={:#x}, nomap={}",
4372eab6dd7S曾俊                 base, size, nomap
438453452ccSLoGin             );
439453452ccSLoGin         } else {
4402eab6dd7S曾俊             error!(
441453452ccSLoGin                 "Failed to reserve memory: base={:#x}, size={:#x}, nomap={}",
4422eab6dd7S曾俊                 base, size, nomap
443453452ccSLoGin             );
444453452ccSLoGin         }
445453452ccSLoGin 
446453452ccSLoGin         reg_size -= t_len;
447453452ccSLoGin 
448453452ccSLoGin         // todo: linux这里保存了节点,但是我感觉现在还用不着。
449453452ccSLoGin     }
450453452ccSLoGin 
451453452ccSLoGin     return Ok(());
452453452ccSLoGin }
453453452ccSLoGin 
454453452ccSLoGin /// 从FDT的`reg`属性中读取指定数量的cell,作为一个小端u64返回
455453452ccSLoGin ///
456453452ccSLoGin /// ## 参数
457453452ccSLoGin ///
458453452ccSLoGin /// - `reg_value`:`reg`属性数组的引用
459453452ccSLoGin /// - `base_index`:起始索引
460453452ccSLoGin /// - `cells`:要读取的cell数量,必须是1或2
461453452ccSLoGin ///
462453452ccSLoGin /// ## 返回值
463453452ccSLoGin ///
464453452ccSLoGin /// (value, next_base_index)
read_cell(reg_value: &[u8], base_index: usize, cells: usize) -> (u64, usize)465453452ccSLoGin fn read_cell(reg_value: &[u8], base_index: usize, cells: usize) -> (u64, usize) {
466453452ccSLoGin     let next_base_index = base_index + cells * 4;
467453452ccSLoGin     match cells {
468453452ccSLoGin         1 => {
469453452ccSLoGin             return (
470453452ccSLoGin                 u32::from_be_bytes(reg_value[base_index..base_index + 4].try_into().unwrap())
471*bd70d2d1SLoGin                     .into(),
472453452ccSLoGin                 next_base_index,
473453452ccSLoGin             );
474453452ccSLoGin         }
475453452ccSLoGin 
476453452ccSLoGin         2 => {
477453452ccSLoGin             return (
478453452ccSLoGin                 u64::from_be_bytes(reg_value[base_index..base_index + 8].try_into().unwrap()),
479453452ccSLoGin                 next_base_index,
480453452ccSLoGin             );
481453452ccSLoGin         }
482453452ccSLoGin         _ => {
483453452ccSLoGin             panic!("cells must be 1 or 2");
484453452ccSLoGin         }
485453452ccSLoGin     }
48645626c85SLoGin }
487