From 90774d68e043ced35fa0db175a5cd0d217c3e6ca Mon Sep 17 00:00:00 2001 From: Alex Date: Mon, 10 Oct 2022 07:02:44 +0300 Subject: [PATCH] Implemented CPU::Vendor, CPU::Name & CPU::Hypervisor but not tested enough --- arch/CPU.cpp | 84 +++++++++++++++++++++++++++++++++++++++++++++++-- include/cpu.hpp | 33 +++++++++++++++++++ 2 files changed, 115 insertions(+), 2 deletions(-) diff --git a/arch/CPU.cpp b/arch/CPU.cpp index 6e8e058..2c540aa 100644 --- a/arch/CPU.cpp +++ b/arch/CPU.cpp @@ -3,6 +3,72 @@ namespace CPU { + char *Vendor() + { + static char Vendor[16]; +#if defined(__amd64__) + asmv("cpuid" + : "=a"(Vendor[0]), "=b"(Vendor[4]), "=c"(Vendor[8]), "=d"(Vendor[12]) + : "a"(0)); +#elif defined(__i386__) + asmv("cpuid" + : "=a"(Vendor[0]), "=b"(Vendor[4]), "=c"(Vendor[8]), "=d"(Vendor[12]) + : "a"(0)); +#elif defined(__aarch64__) + asmv("mrs %0, MIDR_EL1" + : "=r"(Vendor[0])); +#endif + return Vendor; + } + + char *Name() + { + static char Name[48]; +#if defined(__amd64__) + asmv("cpuid" + : "=a"(Name[0]), "=b"(Name[4]), "=c"(Name[8]), "=d"(Name[12]) + : "a"(0x80000002)); + asmv("cpuid" + : "=a"(Name[16]), "=b"(Name[20]), "=c"(Name[24]), "=d"(Name[28]) + : "a"(0x80000003)); + asmv("cpuid" + : "=a"(Name[32]), "=b"(Name[36]), "=c"(Name[40]), "=d"(Name[44]) + : "a"(0x80000004)); +#elif defined(__i386__) + asmv("cpuid" + : "=a"(Name[0]), "=b"(Name[4]), "=c"(Name[8]), "=d"(Name[12]) + : "a"(0x80000002)); + asmv("cpuid" + : "=a"(Name[16]), "=b"(Name[20]), "=c"(Name[24]), "=d"(Name[28]) + : "a"(0x80000003)); + asmv("cpuid" + : "=a"(Name[32]), "=b"(Name[36]), "=c"(Name[40]), "=d"(Name[44]) + : "a"(0x80000004)); +#elif defined(__aarch64__) + asmv("mrs %0, MIDR_EL1" + : "=r"(Name[0])); +#endif + return Name; + } + + char *Hypervisor() + { + static char Hypervisor[16]; +#if defined(__amd64__) + asmv("cpuid" + : "=a"(Hypervisor[0]), "=b"(Hypervisor[4]), "=c"(Hypervisor[8]), "=d"(Hypervisor[12]) + : "a"(0x40000000)); +#elif defined(__i386__) + asmv("cpuid" + : "=a"(Hypervisor[0]), "=b"(Hypervisor[4]), "=c"(Hypervisor[8]), "=d"(Hypervisor[12]) + : "a"(0x40000000)); +#elif defined(__aarch64__) + asmv("mrs %0, MIDR_EL1" + : "=r"(Hypervisor[0])); +#endif + return Hypervisor; + } + void Pause() { #if defined(__amd64__) || defined(__i386__) @@ -27,12 +93,18 @@ namespace CPU { case Check: { -#if defined(__amd64__) || defined(__i386__) +#if defined(__amd64__) uint64_t rflags; asmv("pushfq"); asmv("popq %0" : "=r"(rflags)); return rflags & (1 << 9); +#elif defined(__i386__) + uint32_t rflags; + asmv("pushfl"); + asmv("popl %0" + : "=r"(rflags)); + return rflags & (1 << 9); #elif defined(__aarch64__) uint64_t daif; asmv("mrs %0, daif" @@ -64,7 +136,7 @@ namespace CPU void *PageTable(void *PT) { -#if defined(__amd64__) || defined(__i386__) +#if defined(__amd64__) if (PT) asmv("movq %0, %%cr3" : @@ -72,6 +144,14 @@ namespace CPU else asmv("movq %%cr3, %0" : "=r"(PT)); +#elif defined(__i386__) + if (PT) + asmv("movl %0, %%cr3" + : + : "r"(PT)); + else + asmv("movl %%cr3, %0" + : "=r"(PT)); #elif defined(__aarch64__) if (PT) asmv("msr ttbr0_el1, %0" diff --git a/include/cpu.hpp b/include/cpu.hpp index 9a8efcc..9a634b9 100644 --- a/include/cpu.hpp +++ b/include/cpu.hpp @@ -27,14 +27,37 @@ namespace CPU Disable }; + /** + * @brief Get CPU vendor identifier. + * + * @return char* CPU Vendor ID. + */ + char *Vendor(); + + /** + * @brief Get CPU name. + * + * @return char* CPU Name. + */ + char *Name(); + + /** + * @brief Get CPU hypervisor vendor. + * + * @return char* Hypervisor vendor. + */ + char *Hypervisor(); + /** * @brief Pause the CPU */ void Pause(); + /** * @brief Halt the CPU */ void Halt(); + /** * @brief Check if interrupts are enabled * @@ -42,6 +65,7 @@ namespace CPU * @return false If InterruptsType::Check and interrupts are disabled, or if other InterruptsType failed */ bool Interrupts(InterruptsType Type = Check); + /** * @brief Get/Set the CPU's page table * @@ -133,6 +157,15 @@ namespace CPU : : "r"(Address) : "memory"); +#endif + } + + static inline void cpuid(uint32_t Function, uint32_t *eax, uint32_t *ebx, uint32_t *ecx, uint32_t *edx) + { +#if defined(__amd64__) || defined(__i386__) + asmv("cpuid" + : "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx) + : "a"(Function)); #endif } }