xref: /DragonOS/kernel/src/arch/x86_64/init/boot.rs (revision fae6e9ade46a52976ad5d099643d51cc20876448)
1 use core::hint::spin_loop;
2 
3 use system_error::SystemError;
4 
5 use super::{multiboot2::early_multiboot2_init, pvh::early_linux32_pvh_init};
6 
7 const BOOT_ENTRY_TYPE_MULTIBOOT: u64 = 1;
8 const BOOT_ENTRY_TYPE_MULTIBOOT2: u64 = 2;
9 const BOOT_ENTRY_TYPE_LINUX_32: u64 = 3;
10 const BOOT_ENTRY_TYPE_LINUX_64: u64 = 4;
11 const BOOT_ENTRY_TYPE_LINUX_32_PVH: u64 = 5;
12 
13 #[derive(Debug)]
14 #[repr(u64)]
15 enum BootProtocol {
16     Multiboot = 1,
17     Multiboot2,
18     Linux32,
19     Linux64,
20     Linux32Pvh,
21 }
22 
23 impl TryFrom<u64> for BootProtocol {
24     type Error = SystemError;
25 
26     fn try_from(value: u64) -> Result<Self, Self::Error> {
27         match value {
28             BOOT_ENTRY_TYPE_MULTIBOOT => Ok(BootProtocol::Multiboot),
29             BOOT_ENTRY_TYPE_MULTIBOOT2 => Ok(BootProtocol::Multiboot2),
30             BOOT_ENTRY_TYPE_LINUX_32 => Ok(BootProtocol::Linux32),
31             BOOT_ENTRY_TYPE_LINUX_64 => Ok(BootProtocol::Linux64),
32             BOOT_ENTRY_TYPE_LINUX_32_PVH => Ok(BootProtocol::Linux32Pvh),
33             _ => Err(SystemError::EINVAL),
34         }
35     }
36 }
37 
38 #[inline(never)]
39 pub(super) fn early_boot_init(
40     boot_entry_type: u64,
41     arg1: u64,
42     arg2: u64,
43 ) -> Result<(), SystemError> {
44     let boot_protocol = BootProtocol::try_from(boot_entry_type)?;
45     match boot_protocol {
46         BootProtocol::Multiboot2 => early_multiboot2_init(arg1 as u32, arg2),
47         BootProtocol::Linux32 | BootProtocol::Linux64 | BootProtocol::Multiboot => loop {
48             spin_loop();
49         },
50         BootProtocol::Linux32Pvh => early_linux32_pvh_init(arg2 as usize),
51     }
52 }
53