xref: /DragonOS/kernel/src/driver/open_firmware/fdt.rs (revision 45626c859f95054b76d8b59afcbd24c6b235026f)
1*45626c85SLoGin use fdt::{
2*45626c85SLoGin     node::{FdtNode, NodeProperty},
3*45626c85SLoGin     Fdt,
4*45626c85SLoGin };
5*45626c85SLoGin use system_error::SystemError;
6*45626c85SLoGin 
7*45626c85SLoGin use crate::{
8*45626c85SLoGin     arch::MMArch,
9*45626c85SLoGin     init::boot_params,
10*45626c85SLoGin     libs::{align::page_align_down, rwlock::RwLock},
11*45626c85SLoGin     mm::{
12*45626c85SLoGin         memblock::{mem_block_manager, MemBlockManager},
13*45626c85SLoGin         MemoryManagementArch, PhysAddr, VirtAddr,
14*45626c85SLoGin     },
15*45626c85SLoGin };
16*45626c85SLoGin 
17*45626c85SLoGin #[inline(always)]
18*45626c85SLoGin pub fn open_firmware_fdt_driver() -> &'static OpenFirmwareFdtDriver {
19*45626c85SLoGin     &OpenFirmwareFdtDriver
20*45626c85SLoGin }
21*45626c85SLoGin 
22*45626c85SLoGin static FDT_GLOBAL_DATA: RwLock<FdtGlobalData> = RwLock::new(FdtGlobalData::new());
23*45626c85SLoGin 
24*45626c85SLoGin #[derive(Debug)]
25*45626c85SLoGin struct FdtGlobalData {
26*45626c85SLoGin     /// FDT根节点下的`size-cells`属性值
27*45626c85SLoGin     root_size_cells: u32,
28*45626c85SLoGin 
29*45626c85SLoGin     /// FDT根节点下的`address-cells`属性值
30*45626c85SLoGin     root_addr_cells: u32,
31*45626c85SLoGin 
32*45626c85SLoGin     chosen_node_name: Option<&'static str>,
33*45626c85SLoGin }
34*45626c85SLoGin 
35*45626c85SLoGin impl FdtGlobalData {
36*45626c85SLoGin     pub const fn new() -> Self {
37*45626c85SLoGin         Self {
38*45626c85SLoGin             root_size_cells: 1,
39*45626c85SLoGin             root_addr_cells: 1,
40*45626c85SLoGin             chosen_node_name: None,
41*45626c85SLoGin         }
42*45626c85SLoGin     }
43*45626c85SLoGin }
44*45626c85SLoGin 
45*45626c85SLoGin static mut FDT_VADDR: Option<VirtAddr> = None;
46*45626c85SLoGin 
47*45626c85SLoGin pub struct OpenFirmwareFdtDriver;
48*45626c85SLoGin 
49*45626c85SLoGin impl OpenFirmwareFdtDriver {
50*45626c85SLoGin     pub fn early_scan_device_tree(&self) -> Result<(), SystemError> {
51*45626c85SLoGin         let fdt_vaddr = unsafe { FDT_VADDR.ok_or(SystemError::EINVAL)? };
52*45626c85SLoGin         let fdt = unsafe {
53*45626c85SLoGin             fdt::Fdt::from_ptr(fdt_vaddr.as_ptr()).map_err(|e| {
54*45626c85SLoGin                 kerror!("failed to parse fdt, err={:?}", e);
55*45626c85SLoGin                 SystemError::EINVAL
56*45626c85SLoGin             })
57*45626c85SLoGin         }?;
58*45626c85SLoGin 
59*45626c85SLoGin         self.early_init_scan_nodes(&fdt);
60*45626c85SLoGin 
61*45626c85SLoGin         return Ok(());
62*45626c85SLoGin     }
63*45626c85SLoGin 
64*45626c85SLoGin     fn early_init_scan_nodes(&self, fdt: &Fdt) {
65*45626c85SLoGin         self.early_init_scan_root(fdt)
66*45626c85SLoGin             .expect("Failed to scan fdt root node.");
67*45626c85SLoGin 
68*45626c85SLoGin         self.early_init_scan_chosen(fdt).unwrap_or_else(|_| {
69*45626c85SLoGin             kwarn!("No `chosen` node found");
70*45626c85SLoGin         });
71*45626c85SLoGin 
72*45626c85SLoGin         self.early_init_scan_memory(fdt);
73*45626c85SLoGin     }
74*45626c85SLoGin 
75*45626c85SLoGin     /// 扫描根节点
76*45626c85SLoGin     fn early_init_scan_root(&self, fdt: &Fdt) -> Result<(), SystemError> {
77*45626c85SLoGin         let node = fdt.find_node("/").ok_or(SystemError::ENODEV)?;
78*45626c85SLoGin 
79*45626c85SLoGin         let mut guard = FDT_GLOBAL_DATA.write();
80*45626c85SLoGin 
81*45626c85SLoGin         if let Some(prop) = node.property("#size-cells") {
82*45626c85SLoGin             guard.root_size_cells = prop.as_usize().unwrap() as u32;
83*45626c85SLoGin 
84*45626c85SLoGin             kdebug!("fdt_root_size_cells={}", guard.root_size_cells);
85*45626c85SLoGin         }
86*45626c85SLoGin 
87*45626c85SLoGin         if let Some(prop) = node.property("#address-cells") {
88*45626c85SLoGin             guard.root_addr_cells = prop.as_usize().unwrap() as u32;
89*45626c85SLoGin 
90*45626c85SLoGin             kdebug!("fdt_root_addr_cells={}", guard.root_addr_cells);
91*45626c85SLoGin         }
92*45626c85SLoGin 
93*45626c85SLoGin         return Ok(());
94*45626c85SLoGin     }
95*45626c85SLoGin 
96*45626c85SLoGin     /// 扫描 `/chosen` 节点
97*45626c85SLoGin     fn early_init_scan_chosen(&self, fdt: &Fdt) -> Result<(), SystemError> {
98*45626c85SLoGin         const CHOSEN_NAME1: &'static str = "/chosen";
99*45626c85SLoGin         let mut node = fdt.find_node(CHOSEN_NAME1);
100*45626c85SLoGin         if node.is_none() {
101*45626c85SLoGin             const CHOSEN_NAME2: &'static str = "/chosen@0";
102*45626c85SLoGin             node = fdt.find_node(CHOSEN_NAME2);
103*45626c85SLoGin             if node.is_some() {
104*45626c85SLoGin                 FDT_GLOBAL_DATA.write().chosen_node_name = Some(CHOSEN_NAME2);
105*45626c85SLoGin             }
106*45626c85SLoGin         } else {
107*45626c85SLoGin             FDT_GLOBAL_DATA.write().chosen_node_name = Some(CHOSEN_NAME1);
108*45626c85SLoGin         }
109*45626c85SLoGin 
110*45626c85SLoGin         if let Some(node) = node {
111*45626c85SLoGin             if let Some(prop) = node.property("bootargs") {
112*45626c85SLoGin                 let bootargs = prop.as_str().unwrap();
113*45626c85SLoGin 
114*45626c85SLoGin                 boot_params()
115*45626c85SLoGin                     .write()
116*45626c85SLoGin                     .boot_cmdline_append(bootargs.as_bytes());
117*45626c85SLoGin             }
118*45626c85SLoGin         }
119*45626c85SLoGin 
120*45626c85SLoGin         // TODO: 拼接内核自定义的command line参数
121*45626c85SLoGin 
122*45626c85SLoGin         kdebug!("Command line: {}", boot_params().read().boot_cmdline_str());
123*45626c85SLoGin         return Ok(());
124*45626c85SLoGin     }
125*45626c85SLoGin 
126*45626c85SLoGin     /// 扫描 `/memory` 节点
127*45626c85SLoGin     ///
128*45626c85SLoGin     /// ## 参数
129*45626c85SLoGin     ///
130*45626c85SLoGin     /// - `fdt`:FDT
131*45626c85SLoGin     ///
132*45626c85SLoGin     /// ## 返回值
133*45626c85SLoGin     ///
134*45626c85SLoGin     /// 如果扫描成功,找到可用内存,则返回`true`,否则返回`false`。
135*45626c85SLoGin     fn early_init_scan_memory(&self, fdt: &Fdt) -> bool {
136*45626c85SLoGin         let mut found_memory = false;
137*45626c85SLoGin         for node in fdt.all_nodes() {
138*45626c85SLoGin             let device_type: Option<NodeProperty<'_>> = node.property("device_type");
139*45626c85SLoGin             if device_type.is_none() {
140*45626c85SLoGin                 continue;
141*45626c85SLoGin             }
142*45626c85SLoGin             let device_type = device_type.unwrap().as_str();
143*45626c85SLoGin             if device_type.is_none() || device_type.unwrap() != "memory" {
144*45626c85SLoGin                 continue;
145*45626c85SLoGin             }
146*45626c85SLoGin 
147*45626c85SLoGin             if !self.is_device_avaliable(&node) {
148*45626c85SLoGin                 continue;
149*45626c85SLoGin             }
150*45626c85SLoGin 
151*45626c85SLoGin             let reg = node.property("reg");
152*45626c85SLoGin             if reg.is_none() {
153*45626c85SLoGin                 continue;
154*45626c85SLoGin             }
155*45626c85SLoGin             let reg = reg.unwrap();
156*45626c85SLoGin             // 每个cell是4字节
157*45626c85SLoGin             let addr_cells = FDT_GLOBAL_DATA.read().root_addr_cells as usize;
158*45626c85SLoGin             let size_cells = FDT_GLOBAL_DATA.read().root_size_cells as usize;
159*45626c85SLoGin 
160*45626c85SLoGin             let total_elements_in_reg = reg.value.len() / ((addr_cells + size_cells) * 4);
161*45626c85SLoGin 
162*45626c85SLoGin             for i in 0..total_elements_in_reg {
163*45626c85SLoGin                 let mut base_index = i * (addr_cells + size_cells);
164*45626c85SLoGin                 let base: u64;
165*45626c85SLoGin                 let size: u64;
166*45626c85SLoGin                 match addr_cells {
167*45626c85SLoGin                     1 => {
168*45626c85SLoGin                         base = u32::from_be_bytes(
169*45626c85SLoGin                             reg.value[base_index..base_index + 4].try_into().unwrap(),
170*45626c85SLoGin                         ) as u64;
171*45626c85SLoGin                     }
172*45626c85SLoGin                     2 => {
173*45626c85SLoGin                         base = u64::from_be_bytes(
174*45626c85SLoGin                             reg.value[base_index..base_index + 8].try_into().unwrap(),
175*45626c85SLoGin                         );
176*45626c85SLoGin                     }
177*45626c85SLoGin                     _ => {
178*45626c85SLoGin                         panic!("addr_cells must be 1 or 2");
179*45626c85SLoGin                     }
180*45626c85SLoGin                 }
181*45626c85SLoGin                 base_index += addr_cells * 4;
182*45626c85SLoGin 
183*45626c85SLoGin                 match size_cells {
184*45626c85SLoGin                     1 => {
185*45626c85SLoGin                         size = u32::from_be_bytes(
186*45626c85SLoGin                             reg.value[base_index..base_index + 4].try_into().unwrap(),
187*45626c85SLoGin                         ) as u64;
188*45626c85SLoGin                     }
189*45626c85SLoGin                     2 => {
190*45626c85SLoGin                         size = u64::from_be_bytes(
191*45626c85SLoGin                             reg.value[base_index..base_index + 8].try_into().unwrap(),
192*45626c85SLoGin                         );
193*45626c85SLoGin                     }
194*45626c85SLoGin                     _ => {
195*45626c85SLoGin                         panic!("size_cells must be 1 or 2");
196*45626c85SLoGin                     }
197*45626c85SLoGin                 }
198*45626c85SLoGin 
199*45626c85SLoGin                 if size == 0 {
200*45626c85SLoGin                     continue;
201*45626c85SLoGin                 }
202*45626c85SLoGin 
203*45626c85SLoGin                 kdebug!("Found memory: base={:#x}, size={:#x}", base, size);
204*45626c85SLoGin                 self.early_init_dt_add_memory(base, size);
205*45626c85SLoGin                 found_memory = true;
206*45626c85SLoGin             }
207*45626c85SLoGin         }
208*45626c85SLoGin 
209*45626c85SLoGin         return found_memory;
210*45626c85SLoGin     }
211*45626c85SLoGin 
212*45626c85SLoGin     fn early_init_dt_add_memory(&self, base: u64, size: u64) {
213*45626c85SLoGin         let mut base = base as usize;
214*45626c85SLoGin         let mut size = size as usize;
215*45626c85SLoGin 
216*45626c85SLoGin         if size < (MMArch::PAGE_SIZE - (base & (!MMArch::PAGE_MASK))) {
217*45626c85SLoGin             kwarn!("Ignoring memory block {:#x}-{:#x}", base, base + size);
218*45626c85SLoGin         }
219*45626c85SLoGin 
220*45626c85SLoGin         if PhysAddr::new(base).check_aligned(MMArch::PAGE_SIZE) == false {
221*45626c85SLoGin             size -= MMArch::PAGE_SIZE - (base & (!MMArch::PAGE_MASK));
222*45626c85SLoGin             base = page_align_down(base);
223*45626c85SLoGin         }
224*45626c85SLoGin 
225*45626c85SLoGin         size = page_align_down(size);
226*45626c85SLoGin 
227*45626c85SLoGin         if base > MemBlockManager::MAX_MEMBLOCK_ADDR.data() {
228*45626c85SLoGin             kwarn!("Ignoring memory block {:#x}-{:#x}", base, base + size);
229*45626c85SLoGin         }
230*45626c85SLoGin 
231*45626c85SLoGin         if base + size - 1 > MemBlockManager::MAX_MEMBLOCK_ADDR.data() {
232*45626c85SLoGin             kwarn!(
233*45626c85SLoGin                 "Ignoring memory range {:#x}-{:#x}",
234*45626c85SLoGin                 MemBlockManager::MAX_MEMBLOCK_ADDR.data() + 1,
235*45626c85SLoGin                 base + size
236*45626c85SLoGin             );
237*45626c85SLoGin             size = MemBlockManager::MAX_MEMBLOCK_ADDR.data() - base + 1;
238*45626c85SLoGin         }
239*45626c85SLoGin 
240*45626c85SLoGin         if base + size < MemBlockManager::MIN_MEMBLOCK_ADDR.data() {
241*45626c85SLoGin             kwarn!("Ignoring memory range {:#x}-{:#x}", base, base + size);
242*45626c85SLoGin             return;
243*45626c85SLoGin         }
244*45626c85SLoGin 
245*45626c85SLoGin         if base < MemBlockManager::MIN_MEMBLOCK_ADDR.data() {
246*45626c85SLoGin             {
247*45626c85SLoGin                 kwarn!(
248*45626c85SLoGin                     "Ignoring memory range {:#x}-{:#x}",
249*45626c85SLoGin                     base,
250*45626c85SLoGin                     MemBlockManager::MIN_MEMBLOCK_ADDR.data()
251*45626c85SLoGin                 );
252*45626c85SLoGin                 size -= MemBlockManager::MIN_MEMBLOCK_ADDR.data() - base;
253*45626c85SLoGin                 base = MemBlockManager::MIN_MEMBLOCK_ADDR.data();
254*45626c85SLoGin             }
255*45626c85SLoGin 
256*45626c85SLoGin             mem_block_manager()
257*45626c85SLoGin                 .add_block(PhysAddr::new(base), size)
258*45626c85SLoGin                 .unwrap_or_else(|e| {
259*45626c85SLoGin                     panic!(
260*45626c85SLoGin                         "Failed to add memory block '{:#x}-{:#x}', err={:?}",
261*45626c85SLoGin                         base,
262*45626c85SLoGin                         base + size,
263*45626c85SLoGin                         e
264*45626c85SLoGin                     );
265*45626c85SLoGin                 });
266*45626c85SLoGin         }
267*45626c85SLoGin     }
268*45626c85SLoGin 
269*45626c85SLoGin     fn is_device_avaliable(&self, node: &FdtNode) -> bool {
270*45626c85SLoGin         let status = node.property("status");
271*45626c85SLoGin         if status.is_none() {
272*45626c85SLoGin             return true;
273*45626c85SLoGin         }
274*45626c85SLoGin 
275*45626c85SLoGin         let status = status.unwrap().as_str();
276*45626c85SLoGin         if let Some(status) = status {
277*45626c85SLoGin             if status == "okay" || status == "ok" {
278*45626c85SLoGin                 return true;
279*45626c85SLoGin             }
280*45626c85SLoGin         }
281*45626c85SLoGin 
282*45626c85SLoGin         return false;
283*45626c85SLoGin     }
284*45626c85SLoGin 
285*45626c85SLoGin     pub unsafe fn set_fdt_vaddr(&self, vaddr: VirtAddr) -> Result<(), SystemError> {
286*45626c85SLoGin         if vaddr.is_null() {
287*45626c85SLoGin             return Err(SystemError::EINVAL);
288*45626c85SLoGin         }
289*45626c85SLoGin         fdt::Fdt::from_ptr(vaddr.as_ptr()).map_err(|e| {
290*45626c85SLoGin             kerror!("failed to parse fdt, err={:?}", e);
291*45626c85SLoGin             SystemError::EINVAL
292*45626c85SLoGin         })?;
293*45626c85SLoGin 
294*45626c85SLoGin         unsafe {
295*45626c85SLoGin             FDT_VADDR = Some(vaddr);
296*45626c85SLoGin         }
297*45626c85SLoGin 
298*45626c85SLoGin         Ok(())
299*45626c85SLoGin     }
300*45626c85SLoGin }
301