gila/kernel/src/arch/x86_64/cpuid.rs
August 88fe204b02
Some checks failed
Continuous Integration / Check (push) Successful in 1m57s
Continuous Integration / Clippy (push) Has been cancelled
Convert to workspace
2025-11-13 17:09:20 -05:00

131 lines
3.5 KiB
Rust

// Copyright (c) 2025 shibedrill
// SPDX-License-Identifier: MIT
#![allow(dead_code)]
use lazy_static::lazy_static;
use raw_cpuid::CpuId;
use raw_cpuid::CpuIdReaderNative;
use crate::arch::x86_64::amd_virt::amd_v_supported;
use crate::arch::x86_64::intel_virt::intel_vt_supported;
lazy_static! {
pub static ref CPUID: CpuId<CpuIdReaderNative> = CpuId::new();
}
#[derive(Debug)]
pub enum VirtualizationProvider {
AmdV,
IntelVTx,
None,
}
#[derive(PartialEq, Eq)]
#[allow(clippy::upper_case_acronyms)]
pub enum ProcessorVendor {
AMD,
Intel,
Via,
Transmeta,
Cyrix,
Centaur,
Nexgen,
UMC,
SiS,
NSC,
Rise,
Vortex,
AO486,
Zaoxin,
Hygon,
Elbrus,
QEMU,
KVM,
VMware,
VirtualBox,
Xen,
HyperV,
Parallels,
QNX,
}
impl TryFrom<&str> for ProcessorVendor {
type Error = ();
fn try_from(from: &str) -> Result<Self, Self::Error> {
match from {
"AuthenticAMD" | "AMDisbetter!" => Ok(Self::AMD),
// "GenuineIotel" is a legit string found in some mildly defective Intel CPUs
"GenuineIntel" | "GenuineIotel" => Ok(Self::Intel),
"VIA VIA VIA " => Ok(Self::Via),
"GenuineTMx86" | "TransmetaCPU" => Ok(Self::Transmeta),
"CyrixInstead" => Ok(Self::Cyrix),
"CentaurHauls" => Ok(Self::Centaur),
"NexGenDriven" => Ok(Self::Nexgen),
"UMC UMC UMC " => Ok(Self::UMC),
"SiS SiS SiS " => Ok(Self::SiS),
"Geode by NSC" => Ok(Self::NSC),
"RiseRiseRise" => Ok(Self::Rise),
"Vortex86 SoC" => Ok(Self::Vortex),
"MiSTer AO486" | "GenuineAO486" => Ok(Self::AO486),
" Shanghai " => Ok(Self::Zaoxin),
"HygonGenuine" => Ok(Self::Hygon),
"E2K MACHINE " => Ok(Self::Elbrus),
"TCGTCGTCGTCG" => Ok(Self::QEMU),
" KVMKVMKVM " => Ok(Self::KVM),
"VMwareVMware" => Ok(Self::VMware),
"VBoxVBoxVBox" => Ok(Self::VirtualBox),
"XenVMMXenVMM" => Ok(Self::Xen),
"Microsoft Hv" => Ok(Self::HyperV),
// " lrpepyh vr " is a legit string found in some implementations of the
// Parallels hypervisor due to an endianness mismatch
" prl hyperv " | " lrpepyh vr " => Ok(Self::Parallels),
" QNXQVMBSQG " => Ok(Self::QNX),
_ => Err(()),
}
}
}
impl ProcessorVendor {
pub fn is_hypervisor(&self) -> bool {
matches!(
self,
Self::QEMU
| Self::KVM
| Self::VMware
| Self::VirtualBox
| Self::HyperV
| Self::Parallels
| Self::QNX
)
}
pub fn try_get_current() -> Result<Self, ()> {
if let Some(brand_string) = CPUID.get_vendor_info() {
Self::try_from(brand_string.as_str())
} else {
Err(())
}
}
}
pub fn virt_supported() -> VirtualizationProvider {
match ProcessorVendor::try_get_current() {
Err(_) => VirtualizationProvider::None,
Ok(ProcessorVendor::Intel) => {
if intel_vt_supported() {
VirtualizationProvider::IntelVTx
} else {
VirtualizationProvider::None
}
}
Ok(ProcessorVendor::AMD) => {
if amd_v_supported() {
VirtualizationProvider::AmdV
} else {
VirtualizationProvider::None
}
}
_ => VirtualizationProvider::None,
}
}