use crate::proc::context::CpuContext; use crate::syscall::SyscallResult; pub const KEY_COM1_GSI: u64 = 0; pub const KEY_KBD_GSI: u64 = 1; pub const KEY_VIRTIO_NET_GSI: u64 = 2; pub const KEY_HAS_FRAMEBUFFER: u64 = 3; pub const KEY_HAS_IOMMU: u64 = 4; struct BootPlatformInfo { com1_gsi: i64, kbd_gsi: i64, virtio_net_gsi: i64, } static mut PLATFORM_INFO: BootPlatformInfo = BootPlatformInfo { com1_gsi: -1, kbd_gsi: -1, virtio_net_gsi: -1, }; static PLATFORM_INITIALIZED: core::sync::atomic::AtomicBool = core::sync::atomic::AtomicBool::new(false); #[allow(clippy::deref_addrof)] pub fn store_platform_info( com1_gsi: Option, kbd_gsi: Option, virtio_net_gsi: Option, ) { unsafe { let info = &mut *(&raw mut PLATFORM_INFO); info.com1_gsi = com1_gsi.map_or(-1, |g| g.raw() as i64); info.kbd_gsi = kbd_gsi.map_or(-1, |g| g.raw() as i64); info.virtio_net_gsi = virtio_net_gsi.map_or(-1, |g| g.raw() as i64); } PLATFORM_INITIALIZED.store(true, core::sync::atomic::Ordering::Release); } #[allow(clippy::deref_addrof)] pub fn sys_platform_info(ctx: &mut CpuContext) { let pid = crate::arch::syscall::current_pid(); if pid != crate::types::Pid::new(0) { ctx.rax = SyscallResult::error(crate::error::KernelError::PermissionDenied).raw(); return; } let key = ctx.rdi; ctx.rax = match key { KEY_COM1_GSI => unsafe { (&*(&raw const PLATFORM_INFO)).com1_gsi as u64 }, KEY_KBD_GSI => unsafe { (&*(&raw const PLATFORM_INFO)).kbd_gsi as u64 }, KEY_VIRTIO_NET_GSI => unsafe { (&*(&raw const PLATFORM_INFO)).virtio_net_gsi as u64 }, KEY_HAS_FRAMEBUFFER => match crate::arch::boot::framebuffer().is_some() { true => 1, false => 0, }, KEY_HAS_IOMMU => match crate::iommu::is_available() { true => 1, false => 0, }, _ => SyscallResult::error(crate::error::KernelError::InvalidParameter).raw(), }; }