xref: /DragonOS/kernel/src/arch/riscv64/init/mod.rs (revision c3dc6f2ff9169c309d1cbf47dcb9e4528d509b2f)
1 use fdt::node::FdtNode;
2 use system_error::SystemError;
3 
4 use crate::{
5     arch::{driver::sbi::SbiDriver, mm::init::mm_early_init},
6     driver::{
7         firmware::efi::init::efi_init, irqchip::riscv_intc::riscv_intc_init,
8         open_firmware::fdt::open_firmware_fdt_driver,
9     },
10     init::{boot_params, init::start_kernel},
11     kdebug, kinfo,
12     mm::{memblock::mem_block_manager, PhysAddr, VirtAddr},
13     print, println,
14     smp::cpu::ProcessorId,
15 };
16 
17 use super::{cpu::init_local_context, driver::sbi::console_putstr};
18 
19 #[derive(Debug)]
20 pub struct ArchBootParams {
21     /// 启动时的fdt物理地址
22     pub fdt_paddr: PhysAddr,
23     pub fdt_vaddr: Option<VirtAddr>,
24 
25     pub boot_hartid: ProcessorId,
26 }
27 
28 impl ArchBootParams {
29     pub const DEFAULT: Self = ArchBootParams {
30         fdt_paddr: PhysAddr::new(0),
31         fdt_vaddr: None,
32         boot_hartid: ProcessorId::new(0),
33     };
34 
35     pub fn arch_fdt(&self) -> VirtAddr {
36         // 如果fdt_vaddr为None,则说明还没有进行内核虚拟地址空间的映射,此时返回物理地址
37         if self.fdt_vaddr.is_none() {
38             return VirtAddr::new(self.fdt_paddr.data());
39         }
40         self.fdt_vaddr.unwrap()
41     }
42 }
43 
44 static mut BOOT_HARTID: u32 = 0;
45 static mut BOOT_FDT_PADDR: PhysAddr = PhysAddr::new(0);
46 
47 #[no_mangle]
48 unsafe extern "C" fn kernel_main(hartid: usize, fdt_paddr: usize) -> ! {
49     let fdt_paddr = PhysAddr::new(fdt_paddr);
50 
51     unsafe {
52         BOOT_HARTID = hartid as u32;
53         BOOT_FDT_PADDR = fdt_paddr;
54     }
55 
56     start_kernel();
57 }
58 
59 #[inline(never)]
60 fn print_node(node: FdtNode<'_, '_>, n_spaces: usize) {
61     (0..n_spaces).for_each(|_| print!(" "));
62     println!("{}/", node.name);
63     node.properties().for_each(|p| {
64         (0..n_spaces + 4).for_each(|_| print!(" "));
65         println!("{}: {:?}", p.name, p.value);
66     });
67 
68     for child in node.children() {
69         print_node(child, n_spaces + 4);
70     }
71 }
72 
73 /// 解析fdt,获取内核启动参数
74 #[inline(never)]
75 unsafe fn parse_dtb() {
76     let fdt_paddr = boot_params().read().arch.fdt_paddr;
77     if fdt_paddr.is_null() {
78         panic!("Failed to get fdt address!");
79     }
80 
81     open_firmware_fdt_driver()
82         .early_scan_device_tree()
83         .expect("Failed to scan device tree at boottime.");
84 }
85 
86 #[inline(never)]
87 pub fn early_setup_arch() -> Result<(), SystemError> {
88     SbiDriver::early_init();
89     let hartid = unsafe { BOOT_HARTID };
90     let fdt_paddr = unsafe { BOOT_FDT_PADDR };
91 
92     let mut arch_boot_params_guard = boot_params().write();
93     arch_boot_params_guard.arch.fdt_paddr = fdt_paddr;
94     arch_boot_params_guard.arch.boot_hartid = ProcessorId::new(hartid);
95 
96     drop(arch_boot_params_guard);
97 
98     kinfo!(
99         "DragonOS kernel is running on hart {}, fdt address:{:?}",
100         hartid,
101         fdt_paddr
102     );
103     mm_early_init();
104 
105     let fdt =
106         unsafe { fdt::Fdt::from_ptr(fdt_paddr.data() as *const u8).expect("Failed to parse fdt!") };
107     print_node(fdt.find_node("/").unwrap(), 0);
108 
109     unsafe { parse_dtb() };
110 
111     for x in mem_block_manager().to_iter() {
112         kdebug!("before efi: {x:?}");
113     }
114 
115     efi_init();
116 
117     open_firmware_fdt_driver().early_init_fdt_scan_reserved_mem();
118 
119     return Ok(());
120 }
121 
122 #[inline(never)]
123 pub fn setup_arch() -> Result<(), SystemError> {
124     init_local_context();
125     return Ok(());
126 }
127 
128 #[inline(never)]
129 pub fn setup_arch_post() -> Result<(), SystemError> {
130     // todo
131     return Ok(());
132 }
133