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