xref: /DragonOS/kernel/src/driver/open_firmware/fdt.rs (revision 9284987850c1da2ce607a539eeae8a353a8f6df9)
145626c85SLoGin use fdt::{
245626c85SLoGin     node::{FdtNode, NodeProperty},
345626c85SLoGin     Fdt,
445626c85SLoGin };
545626c85SLoGin use system_error::SystemError;
645626c85SLoGin 
7*92849878SLoGin use crate::{init::boot_params, libs::rwlock::RwLock};
845626c85SLoGin 
945626c85SLoGin #[inline(always)]
1045626c85SLoGin pub fn open_firmware_fdt_driver() -> &'static OpenFirmwareFdtDriver {
1145626c85SLoGin     &OpenFirmwareFdtDriver
1245626c85SLoGin }
1345626c85SLoGin 
1445626c85SLoGin static FDT_GLOBAL_DATA: RwLock<FdtGlobalData> = RwLock::new(FdtGlobalData::new());
1545626c85SLoGin 
1645626c85SLoGin #[derive(Debug)]
1745626c85SLoGin struct FdtGlobalData {
1845626c85SLoGin     /// FDT根节点下的`size-cells`属性值
1945626c85SLoGin     root_size_cells: u32,
2045626c85SLoGin 
2145626c85SLoGin     /// FDT根节点下的`address-cells`属性值
2245626c85SLoGin     root_addr_cells: u32,
2345626c85SLoGin 
2445626c85SLoGin     chosen_node_name: Option<&'static str>,
2545626c85SLoGin }
2645626c85SLoGin 
2745626c85SLoGin impl FdtGlobalData {
2845626c85SLoGin     pub const fn new() -> Self {
2945626c85SLoGin         Self {
3045626c85SLoGin             root_size_cells: 1,
3145626c85SLoGin             root_addr_cells: 1,
3245626c85SLoGin             chosen_node_name: None,
3345626c85SLoGin         }
3445626c85SLoGin     }
3545626c85SLoGin }
3645626c85SLoGin 
3745626c85SLoGin pub struct OpenFirmwareFdtDriver;
3845626c85SLoGin 
3945626c85SLoGin impl OpenFirmwareFdtDriver {
40*92849878SLoGin     #[allow(dead_code)]
4145626c85SLoGin     pub fn early_scan_device_tree(&self) -> Result<(), SystemError> {
427a29d4fcSLoGin         let fdt_vaddr = boot_params().read().fdt().unwrap();
4345626c85SLoGin         let fdt = unsafe {
4445626c85SLoGin             fdt::Fdt::from_ptr(fdt_vaddr.as_ptr()).map_err(|e| {
4545626c85SLoGin                 kerror!("failed to parse fdt, err={:?}", e);
4645626c85SLoGin                 SystemError::EINVAL
4745626c85SLoGin             })
4845626c85SLoGin         }?;
4945626c85SLoGin 
5045626c85SLoGin         self.early_init_scan_nodes(&fdt);
5145626c85SLoGin 
5245626c85SLoGin         return Ok(());
5345626c85SLoGin     }
5445626c85SLoGin 
5545626c85SLoGin     fn early_init_scan_nodes(&self, fdt: &Fdt) {
5645626c85SLoGin         self.early_init_scan_root(fdt)
5745626c85SLoGin             .expect("Failed to scan fdt root node.");
5845626c85SLoGin 
5945626c85SLoGin         self.early_init_scan_chosen(fdt).unwrap_or_else(|_| {
6045626c85SLoGin             kwarn!("No `chosen` node found");
6145626c85SLoGin         });
6245626c85SLoGin 
6345626c85SLoGin         self.early_init_scan_memory(fdt);
6445626c85SLoGin     }
6545626c85SLoGin 
6645626c85SLoGin     /// 扫描根节点
6745626c85SLoGin     fn early_init_scan_root(&self, fdt: &Fdt) -> Result<(), SystemError> {
6845626c85SLoGin         let node = fdt.find_node("/").ok_or(SystemError::ENODEV)?;
6945626c85SLoGin 
7045626c85SLoGin         let mut guard = FDT_GLOBAL_DATA.write();
7145626c85SLoGin 
7245626c85SLoGin         if let Some(prop) = node.property("#size-cells") {
7345626c85SLoGin             guard.root_size_cells = prop.as_usize().unwrap() as u32;
7445626c85SLoGin 
7545626c85SLoGin             kdebug!("fdt_root_size_cells={}", guard.root_size_cells);
7645626c85SLoGin         }
7745626c85SLoGin 
7845626c85SLoGin         if let Some(prop) = node.property("#address-cells") {
7945626c85SLoGin             guard.root_addr_cells = prop.as_usize().unwrap() as u32;
8045626c85SLoGin 
8145626c85SLoGin             kdebug!("fdt_root_addr_cells={}", guard.root_addr_cells);
8245626c85SLoGin         }
8345626c85SLoGin 
8445626c85SLoGin         return Ok(());
8545626c85SLoGin     }
8645626c85SLoGin 
8745626c85SLoGin     /// 扫描 `/chosen` 节点
8845626c85SLoGin     fn early_init_scan_chosen(&self, fdt: &Fdt) -> Result<(), SystemError> {
8945626c85SLoGin         const CHOSEN_NAME1: &'static str = "/chosen";
9045626c85SLoGin         let mut node = fdt.find_node(CHOSEN_NAME1);
9145626c85SLoGin         if node.is_none() {
9245626c85SLoGin             const CHOSEN_NAME2: &'static str = "/chosen@0";
9345626c85SLoGin             node = fdt.find_node(CHOSEN_NAME2);
9445626c85SLoGin             if node.is_some() {
9545626c85SLoGin                 FDT_GLOBAL_DATA.write().chosen_node_name = Some(CHOSEN_NAME2);
9645626c85SLoGin             }
9745626c85SLoGin         } else {
9845626c85SLoGin             FDT_GLOBAL_DATA.write().chosen_node_name = Some(CHOSEN_NAME1);
9945626c85SLoGin         }
10045626c85SLoGin 
10145626c85SLoGin         if let Some(node) = node {
10245626c85SLoGin             if let Some(prop) = node.property("bootargs") {
10345626c85SLoGin                 let bootargs = prop.as_str().unwrap();
10445626c85SLoGin 
10545626c85SLoGin                 boot_params()
10645626c85SLoGin                     .write()
10745626c85SLoGin                     .boot_cmdline_append(bootargs.as_bytes());
10845626c85SLoGin             }
10945626c85SLoGin         }
11045626c85SLoGin 
11145626c85SLoGin         // TODO: 拼接内核自定义的command line参数
11245626c85SLoGin 
11345626c85SLoGin         kdebug!("Command line: {}", boot_params().read().boot_cmdline_str());
11445626c85SLoGin         return Ok(());
11545626c85SLoGin     }
11645626c85SLoGin 
11745626c85SLoGin     /// 扫描 `/memory` 节点
11845626c85SLoGin     ///
11945626c85SLoGin     /// ## 参数
12045626c85SLoGin     ///
12145626c85SLoGin     /// - `fdt`:FDT
12245626c85SLoGin     ///
12345626c85SLoGin     /// ## 返回值
12445626c85SLoGin     ///
12545626c85SLoGin     /// 如果扫描成功,找到可用内存,则返回`true`,否则返回`false`。
12645626c85SLoGin     fn early_init_scan_memory(&self, fdt: &Fdt) -> bool {
12745626c85SLoGin         let mut found_memory = false;
12845626c85SLoGin         for node in fdt.all_nodes() {
12945626c85SLoGin             let device_type: Option<NodeProperty<'_>> = node.property("device_type");
13045626c85SLoGin             if device_type.is_none() {
13145626c85SLoGin                 continue;
13245626c85SLoGin             }
13345626c85SLoGin             let device_type = device_type.unwrap().as_str();
13445626c85SLoGin             if device_type.is_none() || device_type.unwrap() != "memory" {
13545626c85SLoGin                 continue;
13645626c85SLoGin             }
13745626c85SLoGin 
13845626c85SLoGin             if !self.is_device_avaliable(&node) {
13945626c85SLoGin                 continue;
14045626c85SLoGin             }
14145626c85SLoGin 
14245626c85SLoGin             let reg = node.property("reg");
14345626c85SLoGin             if reg.is_none() {
14445626c85SLoGin                 continue;
14545626c85SLoGin             }
14645626c85SLoGin             let reg = reg.unwrap();
14745626c85SLoGin             // 每个cell是4字节
14845626c85SLoGin             let addr_cells = FDT_GLOBAL_DATA.read().root_addr_cells as usize;
14945626c85SLoGin             let size_cells = FDT_GLOBAL_DATA.read().root_size_cells as usize;
15045626c85SLoGin 
15145626c85SLoGin             let total_elements_in_reg = reg.value.len() / ((addr_cells + size_cells) * 4);
15245626c85SLoGin 
15345626c85SLoGin             for i in 0..total_elements_in_reg {
15445626c85SLoGin                 let mut base_index = i * (addr_cells + size_cells);
15545626c85SLoGin                 let base: u64;
15645626c85SLoGin                 let size: u64;
15745626c85SLoGin                 match addr_cells {
15845626c85SLoGin                     1 => {
15945626c85SLoGin                         base = u32::from_be_bytes(
16045626c85SLoGin                             reg.value[base_index..base_index + 4].try_into().unwrap(),
16145626c85SLoGin                         ) as u64;
16245626c85SLoGin                     }
16345626c85SLoGin                     2 => {
16445626c85SLoGin                         base = u64::from_be_bytes(
16545626c85SLoGin                             reg.value[base_index..base_index + 8].try_into().unwrap(),
16645626c85SLoGin                         );
16745626c85SLoGin                     }
16845626c85SLoGin                     _ => {
16945626c85SLoGin                         panic!("addr_cells must be 1 or 2");
17045626c85SLoGin                     }
17145626c85SLoGin                 }
17245626c85SLoGin                 base_index += addr_cells * 4;
17345626c85SLoGin 
17445626c85SLoGin                 match size_cells {
17545626c85SLoGin                     1 => {
17645626c85SLoGin                         size = u32::from_be_bytes(
17745626c85SLoGin                             reg.value[base_index..base_index + 4].try_into().unwrap(),
17845626c85SLoGin                         ) as u64;
17945626c85SLoGin                     }
18045626c85SLoGin                     2 => {
18145626c85SLoGin                         size = u64::from_be_bytes(
18245626c85SLoGin                             reg.value[base_index..base_index + 8].try_into().unwrap(),
18345626c85SLoGin                         );
18445626c85SLoGin                     }
18545626c85SLoGin                     _ => {
18645626c85SLoGin                         panic!("size_cells must be 1 or 2");
18745626c85SLoGin                     }
18845626c85SLoGin                 }
18945626c85SLoGin 
19045626c85SLoGin                 if size == 0 {
19145626c85SLoGin                     continue;
19245626c85SLoGin                 }
19345626c85SLoGin 
19445626c85SLoGin                 kdebug!("Found memory: base={:#x}, size={:#x}", base, size);
19545626c85SLoGin                 self.early_init_dt_add_memory(base, size);
19645626c85SLoGin                 found_memory = true;
19745626c85SLoGin             }
19845626c85SLoGin         }
19945626c85SLoGin 
20045626c85SLoGin         return found_memory;
20145626c85SLoGin     }
20245626c85SLoGin 
203*92849878SLoGin     #[cfg(target_arch = "x86_64")]
204*92849878SLoGin     pub fn early_init_dt_add_memory(&self, _base: u64, _size: u64) {
205*92849878SLoGin         kBUG!("x86_64 should not call early_init_dt_add_memory");
206*92849878SLoGin     }
207*92849878SLoGin 
208*92849878SLoGin     #[cfg(not(target_arch = "x86_64"))]
209*92849878SLoGin     pub fn early_init_dt_add_memory(&self, base: u64, size: u64) {
210*92849878SLoGin         use crate::{
211*92849878SLoGin             arch::MMArch,
212*92849878SLoGin             libs::align::page_align_down,
213*92849878SLoGin             mm::{
214*92849878SLoGin                 memblock::{mem_block_manager, MemBlockManager},
215*92849878SLoGin                 MemoryManagementArch, PhysAddr,
216*92849878SLoGin             },
217*92849878SLoGin         };
218*92849878SLoGin 
21945626c85SLoGin         let mut base = base as usize;
22045626c85SLoGin         let mut size = size as usize;
22145626c85SLoGin 
22245626c85SLoGin         if size < (MMArch::PAGE_SIZE - (base & (!MMArch::PAGE_MASK))) {
22345626c85SLoGin             kwarn!("Ignoring memory block {:#x}-{:#x}", base, base + size);
22445626c85SLoGin         }
22545626c85SLoGin 
22645626c85SLoGin         if PhysAddr::new(base).check_aligned(MMArch::PAGE_SIZE) == false {
22745626c85SLoGin             size -= MMArch::PAGE_SIZE - (base & (!MMArch::PAGE_MASK));
22845626c85SLoGin             base = page_align_down(base);
22945626c85SLoGin         }
23045626c85SLoGin 
23145626c85SLoGin         size = page_align_down(size);
23245626c85SLoGin 
23345626c85SLoGin         if base > MemBlockManager::MAX_MEMBLOCK_ADDR.data() {
23445626c85SLoGin             kwarn!("Ignoring memory block {:#x}-{:#x}", base, base + size);
23545626c85SLoGin         }
23645626c85SLoGin 
23745626c85SLoGin         if base + size - 1 > MemBlockManager::MAX_MEMBLOCK_ADDR.data() {
23845626c85SLoGin             kwarn!(
23945626c85SLoGin                 "Ignoring memory range {:#x}-{:#x}",
24045626c85SLoGin                 MemBlockManager::MAX_MEMBLOCK_ADDR.data() + 1,
24145626c85SLoGin                 base + size
24245626c85SLoGin             );
24345626c85SLoGin             size = MemBlockManager::MAX_MEMBLOCK_ADDR.data() - base + 1;
24445626c85SLoGin         }
24545626c85SLoGin 
24645626c85SLoGin         if base + size < MemBlockManager::MIN_MEMBLOCK_ADDR.data() {
24745626c85SLoGin             kwarn!("Ignoring memory range {:#x}-{:#x}", base, base + size);
24845626c85SLoGin             return;
24945626c85SLoGin         }
25045626c85SLoGin 
25145626c85SLoGin         if base < MemBlockManager::MIN_MEMBLOCK_ADDR.data() {
25245626c85SLoGin             {
25345626c85SLoGin                 kwarn!(
25445626c85SLoGin                     "Ignoring memory range {:#x}-{:#x}",
25545626c85SLoGin                     base,
25645626c85SLoGin                     MemBlockManager::MIN_MEMBLOCK_ADDR.data()
25745626c85SLoGin                 );
25845626c85SLoGin                 size -= MemBlockManager::MIN_MEMBLOCK_ADDR.data() - base;
25945626c85SLoGin                 base = MemBlockManager::MIN_MEMBLOCK_ADDR.data();
26045626c85SLoGin             }
26145626c85SLoGin 
26245626c85SLoGin             mem_block_manager()
26345626c85SLoGin                 .add_block(PhysAddr::new(base), size)
26445626c85SLoGin                 .unwrap_or_else(|e| {
26545626c85SLoGin                     panic!(
26645626c85SLoGin                         "Failed to add memory block '{:#x}-{:#x}', err={:?}",
26745626c85SLoGin                         base,
26845626c85SLoGin                         base + size,
26945626c85SLoGin                         e
27045626c85SLoGin                     );
27145626c85SLoGin                 });
27245626c85SLoGin         }
27345626c85SLoGin     }
27445626c85SLoGin 
27545626c85SLoGin     fn is_device_avaliable(&self, node: &FdtNode) -> bool {
27645626c85SLoGin         let status = node.property("status");
27745626c85SLoGin         if status.is_none() {
27845626c85SLoGin             return true;
27945626c85SLoGin         }
28045626c85SLoGin 
28145626c85SLoGin         let status = status.unwrap().as_str();
28245626c85SLoGin         if let Some(status) = status {
28345626c85SLoGin             if status == "okay" || status == "ok" {
28445626c85SLoGin                 return true;
28545626c85SLoGin             }
28645626c85SLoGin         }
28745626c85SLoGin 
28845626c85SLoGin         return false;
28945626c85SLoGin     }
29045626c85SLoGin }
291