Implemented CPU::Vendor, CPU::Name & CPU::Hypervisor but not tested enough

This commit is contained in:
Alex 2022-10-10 07:02:44 +03:00
parent 2bf2bf3280
commit 90774d68e0
Signed by untrusted user who does not match committer: enderice2
GPG Key ID: EACC3AD603BAB4DD
2 changed files with 115 additions and 2 deletions

View File

@ -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"

View File

@ -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
}
}