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