mirror of
https://github.com/Mathewnd/Astral.git
synced 2026-10-29 05:38:21 +00:00
cpuid: better implementation
This commit is contained in:
@@ -2,12 +2,8 @@
|
||||
#include <arch/apic.h>
|
||||
#include <cpuid.h>
|
||||
#include <logging.h>
|
||||
#include <arch/cpuid.h>
|
||||
|
||||
#define CPUID_VENDOR_AMD "AuthenticAMD"
|
||||
#define CPUID_VENDOR_INTEL "GenuineIntel"
|
||||
|
||||
#define CPUID_SYSCALL (1 << 11)
|
||||
#define CPUID_LEAF_1_EDX_HTT (1 << 28)
|
||||
#define EFER_SYSCALLENABLE 1
|
||||
|
||||
void arch_syscall_entry();
|
||||
@@ -43,34 +39,6 @@ static void x87isr(isr_t *self, context_t *ctx) {
|
||||
}
|
||||
}
|
||||
|
||||
static bool cpuid_leaf_0xb_available(void) {
|
||||
if (current_cpu()->cpuid_max < 0xb)
|
||||
return false;
|
||||
|
||||
unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
|
||||
__get_cpuid_count(0xb, 0, &eax, &ebx, &ecx, &edx);
|
||||
return ebx != 0;
|
||||
}
|
||||
|
||||
static bool cpuid_leaf_0x80000008_available(void) {
|
||||
unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
|
||||
__get_cpuid(0x80000000, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
if (eax < 0x80000008)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool cpuid_leaf_0x4_available(void) {
|
||||
if (current_cpu()->cpuid_max < 0x4)
|
||||
return false;
|
||||
|
||||
unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
|
||||
__get_cpuid_count(0xb, 0, &eax, &ebx, &ecx, &edx);
|
||||
return eax != 0;
|
||||
}
|
||||
|
||||
#define TOPOLOGY_TYPE_THREAD 1
|
||||
#define TOPOLOGY_TYPE_CORE 2
|
||||
#define TOPOLOGY_TYPE_PACKAGE 0xffffffff
|
||||
@@ -183,7 +151,7 @@ void cpu_initstate() {
|
||||
unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
|
||||
__get_cpuid(0x80000001, &eax, &ebx, &ecx, &edx);
|
||||
|
||||
__assert(edx & CPUID_SYSCALL);
|
||||
__assert(edx & CPUID_LEAF_0x80000001_EDX_SYSCALL);
|
||||
uint64_t efer = rdmsr(MSR_EFER);
|
||||
efer |= EFER_SYSCALLENABLE;
|
||||
wrmsr(MSR_EFER, efer);
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
#ifndef _CPUID_H
|
||||
#define _CPUID_H
|
||||
|
||||
typedef struct {
|
||||
uint32_t eax;
|
||||
uint32_t ebx;
|
||||
uint32_t ecx;
|
||||
uint32_t edx;
|
||||
} cpuid_results_t;
|
||||
|
||||
#define CPUID_HYPERVISOR_KVM_EBX 0x4b4d564b
|
||||
#define CPUID_HYPERVISOR_KVM_ECX 0x564b4d56
|
||||
#define CPUID_HYPERVISOR_KVM_EDX 0x4d
|
||||
|
||||
#define CPUID_HYPERVISOR_IS_KVM(ebx, ecx, edx) ((ebx) == CPUID_HYPERVISOR_KVM && (ecx) == CPUID_HYPERVISOR_KVM_ECX && (edx) == CPUID_HYPERVISOR_KVM_EDX)
|
||||
|
||||
#define CPUID_VENDOR_AMD "AuthenticAMD"
|
||||
#define CPUID_VENDOR_INTEL "GenuineIntel"
|
||||
|
||||
#define CPUID_LEAF_0x80000001_EDX_SYSCALL (1 << 11)
|
||||
#define CPUID_LEAF_1_EDX_HTT (1 << 28)
|
||||
|
||||
static inline void cpuid_with_ecx(uint32_t leaf, uint32_t ecx, cpuid_results_t *cpuid_results) {
|
||||
asm volatile ("cpuid"
|
||||
:
|
||||
"=a"(cpuid_results->eax),
|
||||
"=b"(cpuid_results->ebx),
|
||||
"=c"(cpuid_results->ecx),
|
||||
"=d"(cpuid_results->edx)
|
||||
:
|
||||
"a"(leaf),
|
||||
"c"(ecx));
|
||||
}
|
||||
|
||||
static inline void cpuid(uint32_t leaf, cpuid_results_t *cpuid_results) {
|
||||
return cpuid_with_ecx(leaf, 0, cpuid_results);
|
||||
}
|
||||
|
||||
static inline uint32_t cpuid_find_hypervisor_base(uint32_t ebx, uint32_t ecx, uint32_t edx) {
|
||||
uint32_t return_base = 0;
|
||||
cpuid_results_t cpuid_results = {0};
|
||||
|
||||
for (uint32_t base = 0x40000000; base < 0x40001000; base += 0x100) {
|
||||
cpuid(base, &cpuid_results);
|
||||
if (cpuid_results.ebx == ebx && cpuid_results.ecx == ecx && cpuid_results.edx == edx) {
|
||||
return_base = base;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return return_base;
|
||||
}
|
||||
|
||||
static inline uint32_t cpuid_find_hypervisor_base_kvm(void) {
|
||||
return cpuid_find_hypervisor_base(CPUID_HYPERVISOR_KVM_EBX, CPUID_HYPERVISOR_KVM_ECX, CPUID_HYPERVISOR_KVM_EDX);
|
||||
}
|
||||
|
||||
static inline uint32_t cpuid_base_max_leaf(void) {
|
||||
cpuid_results_t cpuid_results;
|
||||
cpuid(0, &cpuid_results);
|
||||
return cpuid_results.eax;
|
||||
}
|
||||
|
||||
static inline uint32_t cpuid_hypervisor_max_leaf(uint32_t base) {
|
||||
cpuid_results_t cpuid_results;
|
||||
cpuid(base, &cpuid_results);
|
||||
return cpuid_results.eax;
|
||||
}
|
||||
|
||||
static inline uint32_t cpuid_extended_max_leaf(void) {
|
||||
cpuid_results_t cpuid_results;
|
||||
cpuid(0x80000000, &cpuid_results);
|
||||
return cpuid_results.eax;
|
||||
}
|
||||
|
||||
static inline bool cpuid_leaf_0xb_available(void) {
|
||||
if (cpuid_base_max_leaf() < 0xb)
|
||||
return false;
|
||||
|
||||
cpuid_results_t cpuid_results;
|
||||
cpuid(0xb, &cpuid_results);
|
||||
return cpuid_results.ebx != 0;
|
||||
}
|
||||
|
||||
static inline bool cpuid_leaf_0x80000008_available(void) {
|
||||
return cpuid_extended_max_leaf() >= 0x80000008;
|
||||
}
|
||||
|
||||
static inline bool cpuid_leaf_0x4_available(void) {
|
||||
if (cpuid_base_max_leaf() < 0x4)
|
||||
return false;
|
||||
|
||||
unsigned int eax = 0, ebx = 0, ecx = 0, edx = 0;
|
||||
__get_cpuid_count(0x4, 0, &eax, &ebx, &ecx, &edx);
|
||||
return eax != 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user