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 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() void Pause()
{ {
#if defined(__amd64__) || defined(__i386__) #if defined(__amd64__) || defined(__i386__)
@ -27,12 +93,18 @@ namespace CPU
{ {
case Check: case Check:
{ {
#if defined(__amd64__) || defined(__i386__) #if defined(__amd64__)
uint64_t rflags; uint64_t rflags;
asmv("pushfq"); asmv("pushfq");
asmv("popq %0" asmv("popq %0"
: "=r"(rflags)); : "=r"(rflags));
return rflags & (1 << 9); return rflags & (1 << 9);
#elif defined(__i386__)
uint32_t rflags;
asmv("pushfl");
asmv("popl %0"
: "=r"(rflags));
return rflags & (1 << 9);
#elif defined(__aarch64__) #elif defined(__aarch64__)
uint64_t daif; uint64_t daif;
asmv("mrs %0, daif" asmv("mrs %0, daif"
@ -64,7 +136,7 @@ namespace CPU
void *PageTable(void *PT) void *PageTable(void *PT)
{ {
#if defined(__amd64__) || defined(__i386__) #if defined(__amd64__)
if (PT) if (PT)
asmv("movq %0, %%cr3" asmv("movq %0, %%cr3"
: :
@ -72,6 +144,14 @@ namespace CPU
else else
asmv("movq %%cr3, %0" asmv("movq %%cr3, %0"
: "=r"(PT)); : "=r"(PT));
#elif defined(__i386__)
if (PT)
asmv("movl %0, %%cr3"
:
: "r"(PT));
else
asmv("movl %%cr3, %0"
: "=r"(PT));
#elif defined(__aarch64__) #elif defined(__aarch64__)
if (PT) if (PT)
asmv("msr ttbr0_el1, %0" asmv("msr ttbr0_el1, %0"

View File

@ -27,14 +27,37 @@ namespace CPU
Disable 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 * @brief Pause the CPU
*/ */
void Pause(); void Pause();
/** /**
* @brief Halt the CPU * @brief Halt the CPU
*/ */
void Halt(); void Halt();
/** /**
* @brief Check if interrupts are enabled * @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 * @return false If InterruptsType::Check and interrupts are disabled, or if other InterruptsType failed
*/ */
bool Interrupts(InterruptsType Type = Check); bool Interrupts(InterruptsType Type = Check);
/** /**
* @brief Get/Set the CPU's page table * @brief Get/Set the CPU's page table
* *
@ -133,6 +157,15 @@ namespace CPU
: :
: "r"(Address) : "r"(Address)
: "memory"); : "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 #endif
} }
} }