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 75 if p.name == "compatible" { 76 println!("{}: {:?}", p.name, p.as_str()); 77 } else { 78 println!("{}: {:?}", p.name, p.value); 79 } 80 }); 81 82 for child in node.children() { 83 print_node(child, n_spaces + 4); 84 } 85 } 86 87 /// 解析fdt,获取内核启动参数 88 #[inline(never)] 89 unsafe fn parse_dtb() { 90 let fdt_paddr = boot_params().read().arch.fdt_paddr; 91 if fdt_paddr.is_null() { 92 panic!("Failed to get fdt address!"); 93 } 94 95 open_firmware_fdt_driver() 96 .early_scan_device_tree() 97 .expect("Failed to scan device tree at boottime."); 98 } 99 100 #[inline(never)] 101 pub fn early_setup_arch() -> Result<(), SystemError> { 102 SbiDriver::early_init(); 103 let hartid = unsafe { BOOT_HARTID }; 104 let fdt_paddr = unsafe { BOOT_FDT_PADDR }; 105 106 let mut arch_boot_params_guard = boot_params().write(); 107 arch_boot_params_guard.arch.fdt_paddr = fdt_paddr; 108 arch_boot_params_guard.arch.boot_hartid = ProcessorId::new(hartid); 109 110 drop(arch_boot_params_guard); 111 112 kinfo!( 113 "DragonOS kernel is running on hart {}, fdt address:{:?}", 114 hartid, 115 fdt_paddr 116 ); 117 mm_early_init(); 118 119 let fdt = 120 unsafe { fdt::Fdt::from_ptr(fdt_paddr.data() as *const u8).expect("Failed to parse fdt!") }; 121 print_node(fdt.find_node("/").unwrap(), 0); 122 123 unsafe { parse_dtb() }; 124 125 for x in mem_block_manager().to_iter() { 126 kdebug!("before efi: {x:?}"); 127 } 128 129 efi_init(); 130 131 open_firmware_fdt_driver().early_init_fdt_scan_reserved_mem(); 132 133 return Ok(()); 134 } 135 136 #[inline(never)] 137 pub fn setup_arch() -> Result<(), SystemError> { 138 init_local_context(); 139 return Ok(()); 140 } 141 142 #[inline(never)] 143 pub fn setup_arch_post() -> Result<(), SystemError> { 144 // todo 145 return Ok(()); 146 } 147