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