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