145626c85SLoGin use fdt::node::FdtNode;
22eab6dd7S曾俊 use log::{debug, info};
35b59005fSLoGin use system_error::SystemError;
445626c85SLoGin
545626c85SLoGin use crate::{
6*2b7818e8SLoGin arch::{
7*2b7818e8SLoGin driver::sbi::SbiDriver,
8*2b7818e8SLoGin init::boot::{early_boot_init, BootProtocol},
9*2b7818e8SLoGin mm::init::mm_early_init,
10*2b7818e8SLoGin },
115c4224e5SLoGin driver::{firmware::efi::init::efi_init, open_firmware::fdt::open_firmware_fdt_driver},
125b59005fSLoGin init::{boot_params, init::start_kernel},
135b59005fSLoGin mm::{memblock::mem_block_manager, PhysAddr, VirtAddr},
1445626c85SLoGin print, println,
15338f6903SLoGin smp::cpu::ProcessorId,
1645626c85SLoGin };
1745626c85SLoGin
185c4224e5SLoGin use super::{cpu::init_local_context, interrupt::entry::handle_exception};
19cb23beb2SLoGin
20*2b7818e8SLoGin mod boot;
21*2b7818e8SLoGin mod dragonstub;
22*2b7818e8SLoGin
2345626c85SLoGin #[derive(Debug)]
2445626c85SLoGin pub struct ArchBootParams {
2545626c85SLoGin /// 启动时的fdt物理地址
2645626c85SLoGin pub fdt_paddr: PhysAddr,
277a29d4fcSLoGin pub fdt_vaddr: Option<VirtAddr>,
2823ef2b33SLoGin pub fdt_size: usize,
29338f6903SLoGin
30338f6903SLoGin pub boot_hartid: ProcessorId,
3145626c85SLoGin }
3245626c85SLoGin
3345626c85SLoGin impl ArchBootParams {
3445626c85SLoGin pub const DEFAULT: Self = ArchBootParams {
3545626c85SLoGin fdt_paddr: PhysAddr::new(0),
367a29d4fcSLoGin fdt_vaddr: None,
3723ef2b33SLoGin fdt_size: 0,
38338f6903SLoGin boot_hartid: ProcessorId::new(0),
3945626c85SLoGin };
407a29d4fcSLoGin
arch_fdt(&self) -> VirtAddr417a29d4fcSLoGin pub fn arch_fdt(&self) -> VirtAddr {
427a29d4fcSLoGin // 如果fdt_vaddr为None,则说明还没有进行内核虚拟地址空间的映射,此时返回物理地址
437a29d4fcSLoGin if self.fdt_vaddr.is_none() {
447a29d4fcSLoGin return VirtAddr::new(self.fdt_paddr.data());
457a29d4fcSLoGin }
467a29d4fcSLoGin self.fdt_vaddr.unwrap()
477a29d4fcSLoGin }
4845626c85SLoGin }
491a72a751SLoGin
50338f6903SLoGin static mut BOOT_HARTID: u32 = 0;
515b59005fSLoGin static mut BOOT_FDT_PADDR: PhysAddr = PhysAddr::new(0);
525b59005fSLoGin
531a72a751SLoGin #[no_mangle]
kernel_main(hartid: usize, fdt_paddr: usize) -> !54666cffedSLoGin unsafe extern "C" fn kernel_main(hartid: usize, fdt_paddr: usize) -> ! {
55666cffedSLoGin let fdt_paddr = PhysAddr::new(fdt_paddr);
567a29d4fcSLoGin
575b59005fSLoGin unsafe {
58338f6903SLoGin BOOT_HARTID = hartid as u32;
595b59005fSLoGin BOOT_FDT_PADDR = fdt_paddr;
60453452ccSLoGin }
615c4224e5SLoGin setup_trap_vector();
625b59005fSLoGin start_kernel();
631a72a751SLoGin }
6445626c85SLoGin
655c4224e5SLoGin /// 设置中断、异常处理函数
setup_trap_vector()665c4224e5SLoGin fn setup_trap_vector() {
675c4224e5SLoGin let ptr = handle_exception as *const () as usize;
685c4224e5SLoGin
695c4224e5SLoGin unsafe {
705c4224e5SLoGin riscv::register::stvec::write(ptr, riscv::register::stvec::TrapMode::Direct);
715c4224e5SLoGin // Set sup0 scratch register to 0, indicating to exception vector that
725c4224e5SLoGin // we are presently executing in kernel.
735c4224e5SLoGin riscv::register::sscratch::write(0);
745c4224e5SLoGin }
755c4224e5SLoGin }
765c4224e5SLoGin
777a29d4fcSLoGin #[inline(never)]
print_node(node: FdtNode<'_, '_>, n_spaces: usize)7845626c85SLoGin fn print_node(node: FdtNode<'_, '_>, n_spaces: usize) {
7945626c85SLoGin (0..n_spaces).for_each(|_| print!(" "));
8045626c85SLoGin println!("{}/", node.name);
8145626c85SLoGin node.properties().for_each(|p| {
8245626c85SLoGin (0..n_spaces + 4).for_each(|_| print!(" "));
8340169973SLoGin
8440169973SLoGin if p.name == "compatible" {
8540169973SLoGin println!("{}: {:?}", p.name, p.as_str());
8640169973SLoGin } else {
8745626c85SLoGin println!("{}: {:?}", p.name, p.value);
8840169973SLoGin }
8945626c85SLoGin });
9045626c85SLoGin
9145626c85SLoGin for child in node.children() {
9245626c85SLoGin print_node(child, n_spaces + 4);
9345626c85SLoGin }
9445626c85SLoGin }
9545626c85SLoGin
9645626c85SLoGin /// 解析fdt,获取内核启动参数
977a29d4fcSLoGin #[inline(never)]
parse_dtb()9845626c85SLoGin unsafe fn parse_dtb() {
9945626c85SLoGin let fdt_paddr = boot_params().read().arch.fdt_paddr;
10045626c85SLoGin if fdt_paddr.is_null() {
10145626c85SLoGin panic!("Failed to get fdt address!");
10245626c85SLoGin }
10345626c85SLoGin
10445626c85SLoGin open_firmware_fdt_driver()
10545626c85SLoGin .early_scan_device_tree()
10645626c85SLoGin .expect("Failed to scan device tree at boottime.");
10745626c85SLoGin }
1085b59005fSLoGin
1095b59005fSLoGin #[inline(never)]
early_setup_arch() -> Result<(), SystemError>1105b59005fSLoGin pub fn early_setup_arch() -> Result<(), SystemError> {
111cb23beb2SLoGin SbiDriver::early_init();
112338f6903SLoGin let hartid = unsafe { BOOT_HARTID };
1135b59005fSLoGin let fdt_paddr = unsafe { BOOT_FDT_PADDR };
114338f6903SLoGin
11523ef2b33SLoGin let fdt =
11623ef2b33SLoGin unsafe { fdt::Fdt::from_ptr(fdt_paddr.data() as *const u8).expect("Failed to parse fdt!") };
11723ef2b33SLoGin
118338f6903SLoGin let mut arch_boot_params_guard = boot_params().write();
119338f6903SLoGin arch_boot_params_guard.arch.fdt_paddr = fdt_paddr;
12023ef2b33SLoGin arch_boot_params_guard.arch.fdt_size = fdt.total_size();
121338f6903SLoGin arch_boot_params_guard.arch.boot_hartid = ProcessorId::new(hartid);
1222eab6dd7S曾俊 // debug!("fdt_paddr: {:?}, fdt_size: {}", fdt_paddr, fdt.total_size());
123338f6903SLoGin drop(arch_boot_params_guard);
124cb23beb2SLoGin
1252eab6dd7S曾俊 info!(
1265b59005fSLoGin "DragonOS kernel is running on hart {}, fdt address:{:?}",
1272eab6dd7S曾俊 hartid, fdt_paddr
1285b59005fSLoGin );
129*2b7818e8SLoGin early_boot_init(BootProtocol::DragonStub).expect("Failed to init boot protocol!");
1305b59005fSLoGin mm_early_init();
1315b59005fSLoGin
1325b59005fSLoGin print_node(fdt.find_node("/").unwrap(), 0);
1335b59005fSLoGin
1345b59005fSLoGin unsafe { parse_dtb() };
1355b59005fSLoGin
1365b59005fSLoGin for x in mem_block_manager().to_iter() {
1372eab6dd7S曾俊 debug!("before efi: {x:?}");
1385b59005fSLoGin }
1395b59005fSLoGin
1405b59005fSLoGin efi_init();
1415b59005fSLoGin
1425b59005fSLoGin open_firmware_fdt_driver().early_init_fdt_scan_reserved_mem();
1435b59005fSLoGin
1445b59005fSLoGin return Ok(());
1455b59005fSLoGin }
1465b59005fSLoGin
1475b59005fSLoGin #[inline(never)]
setup_arch() -> Result<(), SystemError>1485b59005fSLoGin pub fn setup_arch() -> Result<(), SystemError> {
149338f6903SLoGin init_local_context();
1505b59005fSLoGin return Ok(());
1515b59005fSLoGin }
1525b59005fSLoGin
1535b59005fSLoGin #[inline(never)]
setup_arch_post() -> Result<(), SystemError>1545b59005fSLoGin pub fn setup_arch_post() -> Result<(), SystemError> {
1555b59005fSLoGin // todo
1565b59005fSLoGin return Ok(());
1575b59005fSLoGin }
158