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