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
try_from(value: u64) -> Result<Self, Self::Error>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)]
early_boot_init( boot_entry_type: u64, arg1: u64, arg2: u64, ) -> Result<(), SystemError>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