Kernel/include/cpu.hpp
2022-10-15 15:34:26 +03:00

1345 lines
42 KiB
C++

#ifndef __FENNIX_KERNEL_CPU_H__
#define __FENNIX_KERNEL_CPU_H__
#include <types.h>
#define x86_CPUID_VENDOR_OLDAMD "AMDisbetter!" /* Early engineering samples of AMD K5 processor */
#define x86_CPUID_VENDOR_AMD "AuthenticAMD"
#define x86_CPUID_VENDOR_INTEL "GenuineIntel"
#define x86_CPUID_VENDOR_VIA "CentaurHauls"
#define x86_CPUID_VENDOR_OLDTRANSMETA "TransmetaCPU"
#define x86_CPUID_VENDOR_TRANSMETA "GenuineTMx86"
#define x86_CPUID_VENDOR_CYRIX "CyrixInstead"
#define x86_CPUID_VENDOR_CENTAUR "CentaurHauls"
#define x86_CPUID_VENDOR_NEXGEN "NexGenDriven"
#define x86_CPUID_VENDOR_UMC "UMC UMC UMC "
#define x86_CPUID_VENDOR_SIS "SiS SiS SiS "
#define x86_CPUID_VENDOR_NSC "Geode by NSC"
#define x86_CPUID_VENDOR_RISE "RiseRiseRise"
#define x86_CPUID_VENDOR_VORTEX "Vortex86 SoC"
#define x86_CPUID_VENDOR_VIA2 "VIA VIA VIA "
#define x86_CPUID_VENDOR_HYGON "HygonGenuine"
#define x86_CPUID_VENDOR_E2K "E2K MACHINE"
#define x86_CPUID_VENDOR_MISTER "MiSTer AO486"
/* Vendor-strings from Virtual Machines. */
#define x86_CPUID_VENDOR_VMWARE "VMwareVMware"
#define x86_CPUID_VENDOR_XENHVM "XenVMMXenVMM"
#define x86_CPUID_VENDOR_MICROSOFT_HV "Microsoft Hv"
#define x86_CPUID_VENDOR_MICROSOFT_XTA "MicrosoftXTA"
#define x86_CPUID_VENDOR_PARALLELS " lrpepyh vr"
#define x86_CPUID_VENDOR_KVM "KVMKVMKVM"
#define x86_CPUID_VENDOR_VIRTUALBOX "VBoxVBoxVBox"
#define x86_CPUID_VENDOR_TCG "TCGTCGTCGTCG"
#define x86_CPUID_VENDOR_BHYVE "bhyve bhyve "
#define x86_CPUID_VENDOR_ACRN "ACRNACRNACRN"
#define x86_CPUID_VENDOR_QNX "QNXQVMBSQG"
#define x86_CPUID_VENDOR_APPLE "VirtualApple"
#define x86_CPUID_SIGNATURE_INTEL_b 0x756e6547
#define x86_CPUID_SIGNATURE_INTEL_c 0x6c65746e
#define x86_CPUID_SIGNATURE_INTEL_d 0x49656e69
#define x86_CPUID_SIGNATURE_AMD_b 0x68747541
#define x86_CPUID_SIGNATURE_AMD_c 0x444d4163
#define x86_CPUID_SIGNATURE_AMD_d 0x69746e65
#define x86_CPUID_SIGNATURE_CENTAUR_b 0x746e6543
#define x86_CPUID_SIGNATURE_CENTAUR_c 0x736c7561
#define x86_CPUID_SIGNATURE_CENTAUR_d 0x48727561
#define x86_CPUID_SIGNATURE_CYRIX_b 0x69727943
#define x86_CPUID_SIGNATURE_CYRIX_c 0x64616574
#define x86_CPUID_SIGNATURE_CYRIX_d 0x736e4978
#define x86_CPUID_SIGNATURE_TM1_b 0x6e617254
#define x86_CPUID_SIGNATURE_TM1_c 0x55504361
#define x86_CPUID_SIGNATURE_TM1_d 0x74656d73
#define x86_CPUID_SIGNATURE_TM2_b 0x756e6547
#define x86_CPUID_SIGNATURE_TM2_c 0x3638784d
#define x86_CPUID_SIGNATURE_TM2_d 0x54656e69
#define x86_CPUID_SIGNATURE_NSC_b 0x646f6547
#define x86_CPUID_SIGNATURE_NSC_c 0x43534e20
#define x86_CPUID_SIGNATURE_NSC_d 0x79622065
#define x86_CPUID_SIGNATURE_NEXGEN_b 0x4778654e
#define x86_CPUID_SIGNATURE_NEXGEN_c 0x6e657669
#define x86_CPUID_SIGNATURE_NEXGEN_d 0x72446e65
#define x86_CPUID_SIGNATURE_RISE_b 0x65736952
#define x86_CPUID_SIGNATURE_RISE_c 0x65736952
#define x86_CPUID_SIGNATURE_RISE_d 0x65736952
#define x86_CPUID_SIGNATURE_SIS_b 0x20536953
#define x86_CPUID_SIGNATURE_SIS_c 0x20536953
#define x86_CPUID_SIGNATURE_SIS_d 0x20536953
#define x86_CPUID_SIGNATURE_UMC_b 0x20434d55
#define x86_CPUID_SIGNATURE_UMC_c 0x20434d55
#define x86_CPUID_SIGNATURE_UMC_d 0x20434d55
#define x86_CPUID_SIGNATURE_VIA_b 0x20414956
#define x86_CPUID_SIGNATURE_VIA_c 0x20414956
#define x86_CPUID_SIGNATURE_VIA_d 0x20414956
#define x86_CPUID_SIGNATURE_VORTEX_b 0x74726f56
#define x86_CPUID_SIGNATURE_VORTEX_c 0x436f5320
#define x86_CPUID_SIGNATURE_VORTEX_d 0x36387865
/**
* @brief CPU related functions.
*/
namespace CPU
{
/**
* @brief Enum for CPU::Interrupts() function.
*/
enum InterruptsType
{
/**
* @brief Check if interrupts are enabled.
*/
Check,
/**
* @brief Enable interrupts.
*/
Enable,
/**
* @brief Disable interrupts.
*/
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 Stop the CPU (infinite loop)
*/
void Stop();
/**
* @brief Halt the CPU
*/
void Halt();
/**
* @brief Check if interrupts are enabled
*
* @return true If InterruptsType::Check and interrupts are enabled, or if other InterruptsType were executed successfully
* @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
*
* @param PT The new page table, if empty, the current page table will be returned
* @return void* The current page table
*/
void *PageTable(void *PT = nullptr);
/** @brief To be used only once. */
void InitializeFeatures();
namespace MemBar
{
static inline void Barrier()
{
#if defined(__amd64__) || defined(__i386__)
asmv("" ::
: "memory");
#elif defined(__aarch64__)
asmv("dmb ish" ::
: "memory");
#endif
}
static inline void Fence()
{
#if defined(__amd64__) || defined(__i386__)
asmv("mfence" ::
: "memory");
#elif defined(__aarch64__)
asmv("dmb ish" ::
: "memory");
#endif
}
static inline void StoreFence()
{
#if defined(__amd64__) || defined(__i386__)
asmv("sfence" ::
: "memory");
#elif defined(__aarch64__)
asmv("dmb ishst" ::
: "memory");
#endif
}
static inline void LoadFence()
{
#if defined(__amd64__) || defined(__i386__)
asmv("lfence" ::
: "memory");
#elif defined(__aarch64__)
asmv("dmb ishld" ::
: "memory");
#endif
}
}
namespace x32
{
}
namespace x64
{
enum CPUIDFeatures
{
CPUID_FEAT_RCX_SSE3 = 1 << 0,
CPUID_FEAT_RCX_PCLMULQDQ = 1 << 1,
CPUID_FEAT_RCX_DTES64 = 1 << 2,
CPUID_FEAT_RCX_MONITOR = 1 << 3,
CPUID_FEAT_RCX_DS_CPL = 1 << 4,
CPUID_FEAT_RCX_VMX = 1 << 5,
CPUID_FEAT_RCX_SMX = 1 << 6,
CPUID_FEAT_RCX_EST = 1 << 7,
CPUID_FEAT_RCX_TM2 = 1 << 8,
CPUID_FEAT_RCX_SSSE3 = 1 << 9,
CPUID_FEAT_RCX_CID = 1 << 10,
CPUID_FEAT_RCX_FMA = 1 << 12,
CPUID_FEAT_RCX_CX16 = 1 << 13,
CPUID_FEAT_RCX_ETPRD = 1 << 14,
CPUID_FEAT_RCX_PDCM = 1 << 15,
CPUID_FEAT_RCX_PCIDE = 1 << 17,
CPUID_FEAT_RCX_DCA = 1 << 18,
CPUID_FEAT_RCX_SSE4_1 = 1 << 19,
CPUID_FEAT_RCX_SSE4_2 = 1 << 20,
CPUID_FEAT_RCX_x2APIC = 1 << 21,
CPUID_FEAT_RCX_MOVBE = 1 << 22,
CPUID_FEAT_RCX_POPCNT = 1 << 23,
CPUID_FEAT_RCX_AES = 1 << 25,
CPUID_FEAT_RCX_XSAVE = 1 << 26,
CPUID_FEAT_RCX_OSXSAVE = 1 << 27,
CPUID_FEAT_RCX_AVX = 1 << 28,
CPUID_FEAT_RCX_F16C = 1 << 29,
CPUID_FEAT_RCX_RDRAND = 1 << 30,
CPUID_FEAT_RDX_FPU = 1 << 0,
CPUID_FEAT_RDX_VME = 1 << 1,
CPUID_FEAT_RDX_DE = 1 << 2,
CPUID_FEAT_RDX_PSE = 1 << 3,
CPUID_FEAT_RDX_TSC = 1 << 4,
CPUID_FEAT_RDX_MSR = 1 << 5,
CPUID_FEAT_RDX_PAE = 1 << 6,
CPUID_FEAT_RDX_MCE = 1 << 7,
CPUID_FEAT_RDX_CX8 = 1 << 8,
CPUID_FEAT_RDX_APIC = 1 << 9,
CPUID_FEAT_RDX_SEP = 1 << 11,
CPUID_FEAT_RDX_MTRR = 1 << 12,
CPUID_FEAT_RDX_PGE = 1 << 13,
CPUID_FEAT_RDX_MCA = 1 << 14,
CPUID_FEAT_RDX_CMOV = 1 << 15,
CPUID_FEAT_RDX_PAT = 1 << 16,
CPUID_FEAT_RDX_PSE36 = 1 << 17,
CPUID_FEAT_RDX_PSN = 1 << 18,
CPUID_FEAT_RDX_CLF = 1 << 19,
CPUID_FEAT_RDX_DTES = 1 << 21,
CPUID_FEAT_RDX_ACPI = 1 << 22,
CPUID_FEAT_RDX_MMX = 1 << 23,
CPUID_FEAT_RDX_FXSR = 1 << 24,
CPUID_FEAT_RDX_SSE = 1 << 25,
CPUID_FEAT_RDX_SSE2 = 1 << 26,
CPUID_FEAT_RDX_SS = 1 << 27,
CPUID_FEAT_RDX_HTT = 1 << 28,
CPUID_FEAT_RDX_TM1 = 1 << 29,
CPUID_FEAT_RDX_IA64 = 1 << 30,
CPUID_FEAT_RDX_PBE = 1 << 31,
// ? Not sure how to get it.
CPUID_FEAT_RDX_SMEP = 1 << 7,
CPUID_FEAT_RDX_UMIP = 1 << 2,
CPUID_FEAT_RDX_SYSCALL = 1 << 11,
CPUID_FEAT_XD = 1 << 20,
CPUID_FEAT_1GB_PAGE = 1 << 26,
CPUID_FEAT_RDTSCP = 1 << 27,
CPUID_FEAT_LONG_MODE = 1 << 29,
CPUID_FEAT_RDX_SMAP = (1 << 20)
};
enum MSRID
{
MSR_MONITOR_FILTER_SIZE = 0x6,
MSR_TIME_STAMP_COUNTER = 0x10,
MSR_PLATFORM_ID = 0x17,
MSR_APIC_BASE = 0x1B,
MSR_FEATURE_CONTROL = 0x3A,
MSR_TSC_ADJUST = 0x3B,
MSR_SPEC_CTRL = 0x48,
MSR_PRED_CMD = 0x49,
MSR_BIOS_UPDT_TRIG = 0x79,
MSR_BIOS_SIGN_ID = 0x8B,
MSR_SGXLEPUBKEYHASH0 = 0x8C,
MSR_SGXLEPUBKEYHASH1 = 0x8D,
MSR_SGXLEPUBKEYHASH2 = 0x8E,
MSR_SGXLEPUBKEYHASH3 = 0x8F,
MSR_SMM_MONITOR_CTL = 0x9B,
MSR_SMBASE = 0x9E,
MSR_PMC0 = 0xC1,
MSR_PMC1 = 0xC2,
MSR_PMC2 = 0xC3,
MSR_PMC3 = 0xC4,
MSR_PMC4 = 0xC5,
MSR_PMC5 = 0xC6,
MSR_PMC6 = 0xC7,
MSR_PMC7 = 0xC8,
MSR_UMWAIT_CONTROL = 0xE1,
MSR_MPERF = 0xE7,
MSR_APERF = 0xE8,
MSR_MTRRCAP = 0xFE,
MSR_ARCH_CAPABILITIES = 0x10A,
MSR_FLUSH_CMD = 0x10B,
MSR_SYSENTER_CS = 0x17A,
MSR_SYSENTER_ESP = 0x175,
MSR_SYSENTER_EIP = 0x176,
MSR_MCG_CAP = 0x179,
MSR_MCG_STATUS = 0x17A,
MSR_MCG_CTL = 0x17B,
MSR_PERFEVTSEL0 = 0x186,
MSR_PERFEVTSEL1 = 0x187,
MSR_PERFEVTSEL2 = 0x188,
MSR_PERFEVTSEL3 = 0x189,
MSR_PERF_STATUS = 0x198,
MSR_PERF_CTL = 0x199,
MSR_CLOCK_MODULATION = 0x19A,
MSR_THERM_INTERRUPT = 0x19B,
MSR_THERM_STATUS = 0x19C,
MSR_MISC_ENABLE = 0x1A0,
MSR_ENERGY_PERF_BIAS = 0x1B0,
MSR_PACKAGE_THERM_STATUS = 0x1B1,
MSR_PACKAGE_THERM_INTERRUPT = 0x1B2,
MSR_DEBUGCTL = 0x1D9,
MSR_SMRR_PHYSBASE = 0x1F2,
MSR_SMRR_PHYSMASK = 0x1F3,
MSR_PLATFORM_DCA_CAP = 0x1F8,
MSR_CPU_DCA_CAP = 0x1F9,
MSR_DCA_0_CAP = 0x1FA,
MSR_MTRR_PHYSBASE0 = 0x200,
MSR_MTRR_PHYSMASK0 = 0x201,
MSR_MTRR_PHYSBASE1 = 0x202,
MSR_MTRR_PHYSMASK1 = 0x203,
MSR_MTRR_PHYSBASE2 = 0x204,
MSR_MTRR_PHYSMASK2 = 0x205,
MSR_MTRR_PHYSBASE3 = 0x206,
MSR_MTRR_PHYSMASK3 = 0x207,
MSR_MTRR_PHYSBASE4 = 0x208,
MSR_MTRR_PHYSMASK4 = 0x209,
MSR_MTRR_PHYSBASE5 = 0x20A,
MSR_MTRR_PHYSMASK5 = 0x20B,
MSR_MTRR_PHYSBASE6 = 0x20C,
MSR_MTRR_PHYSMASK6 = 0x20D,
MSR_MTRR_PHYSBASE7 = 0x20E,
MSR_MTRR_PHYSMASK7 = 0x20F,
MSR_MTRR_PHYSBASE8 = 0x210,
MSR_MTRR_PHYSMASK8 = 0x211,
MSR_MTRR_PHYSBASE9 = 0x212,
MSR_MTRR_PHYSMASK9 = 0x213,
MSR_MTRR_FIX64K_00000 = 0x250,
MSR_MTRR_FIX16K_80000 = 0x258,
MSR_MTRR_FIX16K_A0000 = 0x259,
MSR_MTRR_FIX4K_C0000 = 0x268,
MSR_MTRR_FIX4K_C8000 = 0x269,
MSR_MTRR_FIX4K_D0000 = 0x26A,
MSR_MTRR_FIX4K_D8000 = 0x26B,
MSR_MTRR_FIX4K_E0000 = 0x26C,
MSR_MTRR_FIX4K_E8000 = 0x26D,
MSR_MTRR_FIX4K_F0000 = 0x26E,
MSR_MTRR_FIX4K_F8000 = 0x26F,
MSR_PAT = 0x277,
MSR_MC0_CTL2 = 0x280,
MSR_MC1_CTL2 = 0x281,
MSR_MC2_CTL2 = 0x282,
MSR_MC3_CTL2 = 0x283,
MSR_MC4_CTL2 = 0x284,
MSR_MC5_CTL2 = 0x285,
MSR_MC6_CTL2 = 0x286,
MSR_MC7_CTL2 = 0x287,
MSR_MC8_CTL2 = 0x288,
MSR_MC9_CTL2 = 0x289,
MSR_MC10_CTL2 = 0x28A,
MSR_MC11_CTL2 = 0x28B,
MSR_MC12_CTL2 = 0x28C,
MSR_MC13_CTL2 = 0x28D,
MSR_MC14_CTL2 = 0x28E,
MSR_MC15_CTL2 = 0x28F,
MSR_MC16_CTL2 = 0x290,
MSR_MC17_CTL2 = 0x291,
MSR_MC18_CTL2 = 0x292,
MSR_MC19_CTL2 = 0x293,
MSR_MC20_CTL2 = 0x294,
MSR_MC21_CTL2 = 0x295,
MSR_MC22_CTL2 = 0x296,
MSR_MC23_CTL2 = 0x297,
MSR_MC24_CTL2 = 0x298,
MSR_MC25_CTL2 = 0x299,
MSR_MC26_CTL2 = 0x29A,
MSR_MC27_CTL2 = 0x29B,
MSR_MC28_CTL2 = 0x29C,
MSR_MC29_CTL2 = 0x29D,
MSR_MC30_CTL2 = 0x29E,
MSR_MC31_CTL2 = 0x29F,
MSR_MTRR_DEF_TYPE = 0x2FF,
MSR_FIXED_CTR0 = 0x309,
MSR_FIXED_CTR1 = 0x30A,
MSR_FIXED_CTR2 = 0x30B,
MSR_PERF_CAPABILITIES = 0x345,
MSR_FIXED_CTR_CTRL = 0x38D,
MSR_PERF_GLOBAL_STATUS = 0x38E,
MSR_PERF_GLOBAL_CTRL = 0x38F,
MSR_PERF_GLOBAL_STATUS_RESET = 0x390,
MSR_PERF_GLOBAL_STATUS_SET = 0x391,
MSR_PERF_GLOBAL_INUSE = 0x392,
MSR_PEBS_ENABLE = 0x3F1,
MSR_MC0_CTL = 0x400,
MSR_MC0_STATUS = 0x401,
MSR_MC0_ADDR = 0x402,
MSR_MC0_MISC = 0x403,
MSR_MC1_CTL = 0x404,
MSR_MC1_STATUS = 0x405,
MSR_MC1_ADDR = 0x406,
MSR_MC1_MISC = 0x407,
MSR_MC2_CTL = 0x408,
MSR_MC2_STATUS = 0x409,
MSR_MC2_ADDR = 0x40A,
MSR_MC2_MISC = 0x40B,
MSR_MC3_CTL = 0x40C,
MSR_MC3_STATUS = 0x40D,
MSR_MC3_ADDR = 0x40E,
MSR_MC3_MISC = 0x40F,
MSR_MC4_CTL = 0x410,
MSR_MC4_STATUS = 0x411,
MSR_MC4_ADDR = 0x412,
MSR_MC4_MISC = 0x413,
MSR_MC5_CTL = 0x414,
MSR_MC5_STATUS = 0x415,
MSR_MC5_ADDR = 0x416,
MSR_MC5_MISC = 0x417,
MSR_MC6_CTL = 0x418,
MSR_MC6_STATUS = 0x419,
MSR_MC6_ADDR = 0x41A,
MSR_MC6_MISC = 0x41B,
MSR_MC7_CTL = 0x41C,
MSR_MC7_STATUS = 0x41D,
MSR_MC7_ADDR = 0x41E,
MSR_MC7_MISC = 0x41F,
MSR_MC8_CTL = 0x420,
MSR_MC8_STATUS = 0x421,
MSR_MC8_ADDR = 0x422,
MSR_MC8_MISC = 0x423,
MSR_MC9_CTL = 0x424,
MSR_MC9_STATUS = 0x425,
MSR_MC9_ADDR = 0x426,
MSR_MC9_MISC = 0x427,
MSR_MC10_CTL = 0x428,
MSR_MC10_STATUS = 0x429,
MSR_MC10_ADDR = 0x42A,
MSR_MC10_MISC = 0x42B,
MSR_MC11_CTL = 0x42C,
MSR_MC11_STATUS = 0x42D,
MSR_MC11_ADDR = 0x42E,
MSR_MC11_MISC = 0x42F,
MSR_MC12_CTL = 0x430,
MSR_MC12_STATUS = 0x431,
MSR_MC12_ADDR = 0x432,
MSR_MC12_MISC = 0x433,
MSR_MC13_CTL = 0x434,
MSR_MC13_STATUS = 0x435,
MSR_MC13_ADDR = 0x436,
MSR_MC13_MISC = 0x437,
MSR_MC14_CTL = 0x438,
MSR_MC14_STATUS = 0x439,
MSR_MC14_ADDR = 0x43A,
MSR_MC14_MISC = 0x43B,
MSR_MC15_CTL = 0x43C,
MSR_MC15_STATUS = 0x43D,
MSR_MC15_ADDR = 0x43E,
MSR_MC15_MISC = 0x43F,
MSR_MC16_CTL = 0x440,
MSR_MC16_STATUS = 0x441,
MSR_MC16_ADDR = 0x442,
MSR_MC16_MISC = 0x443,
MSR_MC17_CTL = 0x444,
MSR_MC17_STATUS = 0x445,
MSR_MC17_ADDR = 0x446,
MSR_MC17_MISC = 0x447,
MSR_MC18_CTL = 0x448,
MSR_MC18_STATUS = 0x449,
MSR_MC18_ADDR = 0x44A,
MSR_MC18_MISC = 0x44B,
MSR_MC19_CTL = 0x44C,
MSR_MC19_STATUS = 0x44D,
MSR_MC19_ADDR = 0x44E,
MSR_MC19_MISC = 0x44F,
MSR_MC20_CTL = 0x450,
MSR_MC20_STATUS = 0x451,
MSR_MC20_ADDR = 0x452,
MSR_MC20_MISC = 0x453,
MSR_MC21_CTL = 0x454,
MSR_MC21_STATUS = 0x455,
MSR_MC21_ADDR = 0x456,
MSR_MC21_MISC = 0x457,
MSR_MC22_CTL = 0x458,
MSR_MC22_STATUS = 0x459,
MSR_MC22_ADDR = 0x45A,
MSR_MC22_MISC = 0x45B,
MSR_MC23_CTL = 0x45C,
MSR_MC23_STATUS = 0x45D,
MSR_MC23_ADDR = 0x45E,
MSR_MC23_MISC = 0x45F,
MSR_MC24_CTL = 0x460,
MSR_MC24_STATUS = 0x461,
MSR_MC24_ADDR = 0x462,
MSR_MC24_MISC = 0x463,
MSR_MC25_CTL = 0x464,
MSR_MC25_STATUS = 0x465,
MSR_MC25_ADDR = 0x466,
MSR_MC25_MISC = 0x467,
MSR_MC26_CTL = 0x468,
MSR_MC26_STATUS = 0x469,
MSR_MC26_ADDR = 0x46A,
MSR_MC26_MISC = 0x46B,
MSR_MC27_CTL = 0x46C,
MSR_MC27_STATUS = 0x46D,
MSR_MC27_ADDR = 0x46E,
MSR_MC27_MISC = 0x46F,
MSR_MC28_CTL = 0x470,
MSR_MC28_STATUS = 0x471,
MSR_MC28_ADDR = 0x472,
MSR_MC28_MISC = 0x473,
MSR_VMX_BASIC = 0x480,
MSR_VMX_PINBASED_CTLS = 0x481,
MSR_VMX_PROCBASED_CTLS = 0x482,
MSR_VMX_EXIT_CTLS = 0x483,
MSR_VMX_ENTRY_CTLS = 0x484,
MSR_VMX_MISC = 0x485,
MSR_VMX_CR0_FIXED0 = 0x486,
MSR_VMX_CR0_FIXED1 = 0x487,
MSR_VMX_CR4_FIXED0 = 0x488,
MSR_VMX_CR4_FIXED1 = 0x489,
MSR_VMX_VMCS_ENUM = 0x48A,
MSR_VMX_PROCBASED_CTLS2 = 0x48B,
MSR_VMX_EPT_VPID_CAP = 0x48C,
MSR_VMX_TRUE_PINBASED_CTLS = 0x48D,
MSR_VMX_TRUE_PROCBASED_CTLS = 0x48E,
MSR_VMX_TRUE_EXIT_CTLS = 0x48F,
MSR_VMX_TRUE_ENTRY_CTLS = 0x490,
MSR_VMX_VMFUNC = 0x491,
MSR_A_PMC0 = 0x4C1,
MSR_A_PMC1 = 0x4C2,
MSR_A_PMC2 = 0x4C3,
MSR_A_PMC3 = 0x4C4,
MSR_A_PMC4 = 0x4C5,
MSR_A_PMC5 = 0x4C6,
MSR_A_PMC6 = 0x4C7,
MSR_A_PMC7 = 0x4C8,
MSR_MCG_EXT_CTL = 0x4D0,
MSR_SGX_SVN_STATUS = 0x500,
MSR_RTIT_OUTPUT_BASE = 0x560,
MSR_RTIT_OUTPUT_MASK_PTRS = 0x561,
MSR_RTIT_CTL = 0x570,
MSR_RTIT_STATUS = 0x571,
MSR_RTIT_CR3_MATCH = 0x572,
MSR_RTIT_ADDR0_A = 0x580,
MSR_RTIT_ADDR0_B = 0x581,
MSR_RTIT_ADDR1_A = 0x582,
MSR_RTIT_ADDR1_B = 0x583,
MSR_RTIT_ADDR2_A = 0x584,
MSR_RTIT_ADDR2_B = 0x585,
MSR_RTIT_ADDR3_A = 0x586,
MSR_RTIT_ADDR3_B = 0x587,
MSR_DS_AREA = 0x600,
MSR_TSC_DEADLINE = 0x6E0,
MSR_PM_ENABLE = 0x770,
MSR_HWP_CAPABILITIES = 0x771,
MSR_HWP_REQUEST_PKG = 0x772,
MSR_HWP_INTERRUPT = 0x773,
MSR_HWP_REQUEST = 0x774,
MSR_HWP_STATUS = 0x777,
MSR_X2APIC_APICID = 0x802,
MSR_X2APIC_VERSION = 0x803,
MSR_X2APIC_TPR = 0x808,
MSR_X2APIC_PPR = 0x80A,
MSR_X2APIC_EOI = 0x80B,
MSR_X2APIC_LDR = 0x80D,
MSR_X2APIC_SIVR = 0x80F,
MSR_X2APIC_ISR0 = 0x810,
MSR_X2APIC_ISR1 = 0x811,
MSR_X2APIC_ISR2 = 0x812,
MSR_X2APIC_ISR3 = 0x813,
MSR_X2APIC_ISR4 = 0x814,
MSR_X2APIC_ISR5 = 0x815,
MSR_X2APIC_ISR6 = 0x816,
MSR_X2APIC_ISR7 = 0x817,
MSR_X2APIC_TMR0 = 0x818,
MSR_X2APIC_TMR1 = 0x819,
MSR_X2APIC_TMR2 = 0x81A,
MSR_X2APIC_TMR3 = 0x81B,
MSR_X2APIC_TMR4 = 0x81C,
MSR_X2APIC_TMR5 = 0x81D,
MSR_X2APIC_TMR6 = 0x81E,
MSR_X2APIC_TMR7 = 0x81F,
MSR_X2APIC_IRR0 = 0x820,
MSR_X2APIC_IRR1 = 0x821,
MSR_X2APIC_IRR2 = 0x822,
MSR_X2APIC_IRR3 = 0x823,
MSR_X2APIC_IRR4 = 0x824,
MSR_X2APIC_IRR5 = 0x825,
MSR_X2APIC_IRR6 = 0x826,
MSR_X2APIC_IRR7 = 0x827,
MSR_X2APIC_ESR = 0x828,
MSR_X2APIC_LVT_CMCI = 0x82F,
MSR_X2APIC_ICR = 0x830,
MSR_X2APIC_LVT_TIMER = 0x832,
MSR_X2APIC_LVT_THERMAL = 0x833,
MSR_X2APIC_LVT_PMI = 0x834,
MSR_X2APIC_LVT_LINT0 = 0x835,
MSR_X2APIC_LVT_LINT1 = 0x836,
MSR_X2APIC_LVT_ERROR = 0x837,
MSR_X2APIC_INIT_COUNT = 0x838,
MSR_X2APIC_CUR_COUNT = 0x839,
MSR_X2APIC_DIV_CONF = 0x83E,
MSR_X2APIC_SELF_IPI = 0x83F,
MSR_DEBUG_INTERFACE = 0xC80,
MSR_L3_QOS_CFG = 0xC81,
MSR_L2_QOS_CFG = 0xC82,
MSR_QM_EVTSEL = 0xC8D,
MSR_QM_CTR = 0xC8E,
MSR_PQR_ASSOC = 0xC8F,
MSR_L3_MASK_0 = 0xC90,
MSR_L2_MASK_0 = 0xD10,
MSR_BNDCFGS = 0xD90,
MSR_XSS = 0xDA0,
MSR_PKG_HDC_CTL = 0xDB0,
MSR_PM_CTL1 = 0xDB1,
MSR_THREAD_STALL = 0xDB2,
/** @brief Extended Feature Enable Register (0xc0000080) */
MSR_EFER = 0xC0000080,
/** @brief legacy SYSCALL (0xC0000081) */
MSR_STAR = 0xC0000081,
/** @brief 64bit SYSCALL (0xC0000082) */
MSR_LSTAR = 0xC0000082,
/** @brief compatibility mode SYSCALL (0xC0000083) */
MSR_CSTAR = 0xC0000083,
/** @brief EFLAGS mask for syscall (0xC0000084) */
MSR_SYSCALL_MASK = 0xC0000084,
/** @brief 64bit FS base (0xC0000100) */
MSR_FS_BASE = 0xC0000100,
/** @brief 64bit GS base (0xC0000101) */
MSR_GS_BASE = 0xC0000101,
/** @brief SwapGS GS shadow (0xC0000102) */
MSR_SHADOW_GS_BASE = 0xC0000102,
/** @brief Auxiliary TSC (0xC0000103) */
MSR_TSC_AUX = 0xC0000103,
MSR_CR_PAT = 0x00000277,
MSR_CR_PAT_RESET = 0x0007040600070406ULL
};
typedef enum
{
DivideByZero = 0x0,
Debug = 0x1,
NonMaskableInterrupt = 0x2,
Breakpoint = 0x3,
Overflow = 0x4,
BoundRange = 0x5,
InvalidOpcode = 0x6,
DeviceNotAvailable = 0x7,
DoubleFault = 0x8,
CoprocessorSegmentOverrun = 0x9,
InvalidTSS = 0xa,
SegmentNotPresent = 0xb,
StackSegmentFault = 0xc,
GeneralProtectionFault = 0xd,
PageFault = 0xe,
x87FloatingPoint = 0x10,
AlignmentCheck = 0x11,
MachineCheck = 0x12,
SIMDFloatingPoint = 0x13,
Virtualization = 0x14,
Security = 0x1e
} ISRExceptions;
typedef enum
{
ISR0 = 0x0, // Divide-by-zero Error
ISR1 = 0x1, // Debug
ISR2 = 0x2, // Non-maskable Interrupt
ISR3 = 0x3, // Breakpoint
ISR4 = 0x4, // Overflow
ISR5 = 0x5, // Bound Range Exceeded
ISR6 = 0x6, // Invalid Opcode
ISR7 = 0x7, // Device Not Available
ISR8 = 0x8, // Double Fault
ISR9 = 0x9, // Coprocessor Segment Overrun
ISR10 = 0xa, // Invalid TSS
ISR11 = 0xb, // Segment Not P
ISR12 = 0xc, // Stack-Segment Fault
ISR13 = 0xd, // General Protection Fault
ISR14 = 0xe, // Page Fault
ISR15 = 0xf, // Reserved
ISR16 = 0x10, // x87 Floating-Point Exception
ISR17 = 0x11, // Alignment Check
ISR18 = 0x12, // Machine Check
ISR19 = 0x13, // SIMD Floating-Point Exception
ISR20 = 0x14, // Virtualization Exception
ISR21 = 0x15, // Reserved
ISR22 = 0x16, // Reserved
ISR23 = 0x17, // Reserved
ISR24 = 0x18, // Reserved
ISR25 = 0x19, // Reserved
ISR26 = 0x1a, // Reserved
ISR27 = 0x1b, // Reserved
ISR28 = 0x1c, // Reserved
ISR29 = 0x1d, // Reserved
ISR30 = 0x1e, // Security Exception
ISR31 = 0x1f, // Reserved
IRQ0 = 0x20, // Programmable Interrupt Timer Interrupt
IRQ1 = 0x21, // Keyboard Interrupt
IRQ2 = 0x22, // Cascade (used internally by the two PICs. never raised)
IRQ3 = 0x23, // COM2 (if enabled)
IRQ4 = 0x24, // COM1 (if enabled)
IRQ5 = 0x25, // LPT2 (if enabled)
IRQ6 = 0x26, // Floppy Disk
IRQ7 = 0x27, // LPT1 / Unreliable "spurious" interrupt (usually)
IRQ8 = 0x28, // CMOS real-time clock (if enabled)
IRQ9 = 0x29, // Free for peripherals / legacy SCSI / NIC
IRQ10 = 0x2a, // Free for peripherals / SCSI / NIC
IRQ11 = 0x2b, // Free for peripherals / SCSI / NIC
IRQ12 = 0x2c, // PS2 Mouse
IRQ13 = 0x2d, // FPU / Coprocessor / Inter-processor
IRQ14 = 0x2e, // Primary ATA Hard Disk
IRQ15 = 0x2f, // Secondary ATA Hard Disk
IRQ16 = 0x30, // Reserved for multitasking
IRQ17 = 0x31, // Reserved for monotasking
IRQ18 = 0x32,
IRQ19 = 0x33,
IRQ20 = 0x34,
IRQ21 = 0x35,
IRQ22 = 0x36,
IRQ23 = 0x37,
IRQ24 = 0x38,
IRQ25 = 0x39,
IRQ26 = 0x3a,
IRQ27 = 0x3b,
IRQ28 = 0x3c,
IRQ29 = 0x3d,
IRQ30 = 0x3e,
IRQ31 = 0x3f,
IRQ32 = 0x40,
IRQ33 = 0x41,
IRQ34 = 0x42,
IRQ35 = 0x43,
IRQ36 = 0x44,
IRQ37 = 0x45,
IRQ38 = 0x46,
IRQ39 = 0x47,
IRQ40 = 0x48,
IRQ41 = 0x49,
IRQ42 = 0x4a,
IRQ43 = 0x4b,
IRQ44 = 0x4c,
IRQ45 = 0x4d,
IRQ46 = 0x4e,
IRQ47 = 0x4f,
IRQ48 = 0x50,
IRQ49 = 0x51,
IRQ50 = 0x52,
IRQ51 = 0x53,
IRQ52 = 0x54,
IRQ53 = 0x55,
IRQ54 = 0x56,
IRQ55 = 0x57,
IRQ56 = 0x58,
IRQ57 = 0x59,
IRQ58 = 0x5a,
IRQ59 = 0x5b,
IRQ60 = 0x5c,
IRQ61 = 0x5d,
IRQ62 = 0x5e,
IRQ63 = 0x5f,
IRQ64 = 0x60,
IRQ65 = 0x61,
IRQ66 = 0x62,
IRQ67 = 0x63,
IRQ68 = 0x64,
IRQ69 = 0x65,
IRQ70 = 0x66,
IRQ71 = 0x67,
IRQ72 = 0x68,
IRQ73 = 0x69,
IRQ74 = 0x6a,
IRQ75 = 0x6b,
IRQ76 = 0x6c,
IRQ77 = 0x6d,
IRQ78 = 0x6e,
IRQ79 = 0x6f,
IRQ80 = 0x70,
IRQ81 = 0x71,
IRQ82 = 0x72,
IRQ83 = 0x73,
IRQ84 = 0x74,
IRQ85 = 0x75,
IRQ86 = 0x76,
IRQ87 = 0x77,
IRQ88 = 0x78,
IRQ89 = 0x79,
IRQ90 = 0x7a,
IRQ91 = 0x7b,
IRQ92 = 0x7c,
IRQ93 = 0x7d,
IRQ94 = 0x7e,
IRQ95 = 0x7f,
IRQ96 = 0x80,
IRQ97 = 0x81,
IRQ98 = 0x82,
IRQ99 = 0x83,
IRQ100 = 0x84,
IRQ101 = 0x85,
IRQ102 = 0x86,
IRQ103 = 0x87,
IRQ104 = 0x88,
IRQ105 = 0x89,
IRQ106 = 0x8a,
IRQ107 = 0x8b,
IRQ108 = 0x8c,
IRQ109 = 0x8d,
IRQ110 = 0x8e,
IRQ111 = 0x8f,
IRQ112 = 0x90,
IRQ113 = 0x91,
IRQ114 = 0x92,
IRQ115 = 0x93,
IRQ116 = 0x94,
IRQ117 = 0x95,
IRQ118 = 0x96,
IRQ119 = 0x97,
IRQ120 = 0x98,
IRQ121 = 0x99,
IRQ122 = 0x9a,
IRQ123 = 0x9b,
IRQ124 = 0x9c,
IRQ125 = 0x9d,
IRQ126 = 0x9e,
IRQ127 = 0x9f,
IRQ128 = 0xa0,
IRQ129 = 0xa1,
IRQ130 = 0xa2,
IRQ131 = 0xa3,
IRQ132 = 0xa4,
IRQ133 = 0xa5,
IRQ134 = 0xa6,
IRQ135 = 0xa7,
IRQ136 = 0xa8,
IRQ137 = 0xa9,
IRQ138 = 0xaa,
IRQ139 = 0xab,
IRQ140 = 0xac,
IRQ141 = 0xad,
IRQ142 = 0xae,
IRQ143 = 0xaf,
IRQ144 = 0xb0,
IRQ145 = 0xb1,
IRQ146 = 0xb2,
IRQ147 = 0xb3,
IRQ148 = 0xb4,
IRQ149 = 0xb5,
IRQ150 = 0xb6,
IRQ151 = 0xb7,
IRQ152 = 0xb8,
IRQ153 = 0xb9,
IRQ154 = 0xba,
IRQ155 = 0xbb,
IRQ156 = 0xbc,
IRQ157 = 0xbd,
IRQ158 = 0xbe,
IRQ159 = 0xbf,
IRQ160 = 0xc0,
IRQ161 = 0xc1,
IRQ162 = 0xc2,
IRQ163 = 0xc3,
IRQ164 = 0xc4,
IRQ165 = 0xc5,
IRQ166 = 0xc6,
IRQ167 = 0xc7,
IRQ168 = 0xc8,
IRQ169 = 0xc9,
IRQ170 = 0xca,
IRQ171 = 0xcb,
IRQ172 = 0xcc,
IRQ173 = 0xcd,
IRQ174 = 0xce,
IRQ175 = 0xcf,
IRQ176 = 0xd0,
IRQ177 = 0xd1,
IRQ178 = 0xd2,
IRQ179 = 0xd3,
IRQ180 = 0xd4,
IRQ181 = 0xd5,
IRQ182 = 0xd6,
IRQ183 = 0xd7,
IRQ184 = 0xd8,
IRQ185 = 0xd9,
IRQ186 = 0xda,
IRQ187 = 0xdb,
IRQ188 = 0xdc,
IRQ189 = 0xdd,
IRQ190 = 0xde,
IRQ191 = 0xdf,
IRQ192 = 0xe0,
IRQ193 = 0xe1,
IRQ194 = 0xe2,
IRQ195 = 0xe3,
IRQ196 = 0xe4,
IRQ197 = 0xe5,
IRQ198 = 0xe6,
IRQ199 = 0xe7,
IRQ200 = 0xe8,
IRQ201 = 0xe9,
IRQ202 = 0xea,
IRQ203 = 0xeb,
IRQ204 = 0xec,
IRQ205 = 0xed,
IRQ206 = 0xee,
IRQ207 = 0xef,
IRQ208 = 0xf0,
IRQ209 = 0xf1,
IRQ210 = 0xf2,
IRQ211 = 0xf3,
IRQ212 = 0xf4,
IRQ213 = 0xf5,
IRQ214 = 0xf6,
IRQ215 = 0xf7,
IRQ216 = 0xf8,
IRQ217 = 0xf9,
IRQ218 = 0xfa,
IRQ219 = 0xfb,
IRQ220 = 0xfc,
IRQ221 = 0xfd,
IRQ222 = 0xfe,
IRQ223 = 0xff,
} Interrupts;
typedef union
{
struct
{
/** @brief Carry Flag */
uint64_t CF : 1;
/** @brief Reserved */
uint64_t always_one : 1;
/** @brief Parity Flag */
uint64_t PF : 1;
/** @brief Reserved */
uint64_t _reserved0 : 1;
/** @brief Auxiliary Carry Flag */
uint64_t AF : 1;
/** @brief Reserved */
uint64_t _reserved1 : 1;
/** @brief Zero Flag */
uint64_t ZF : 1;
/** @brief Sign Flag */
uint64_t SF : 1;
/** @brief Trap Flag */
uint64_t TF : 1;
/** @brief Interrupt Enable Flag */
uint64_t IF : 1;
/** @brief Direction Flag */
uint64_t DF : 1;
/** @brief Overflow Flag */
uint64_t OF : 1;
/** @brief I/O Privilege Level */
uint64_t IOPL : 2;
/** @brief Nested Task */
uint64_t NT : 1;
/** @brief Reserved */
uint64_t _reserved2 : 1;
/** @brief Resume Flag */
uint64_t RF : 1;
/** @brief Virtual 8086 Mode */
uint64_t VM : 1;
/** @brief Alignment Check */
uint64_t AC : 1;
/** @brief Virtual Interrupt Flag */
uint64_t VIF : 1;
/** @brief Virtual Interrupt Pending */
uint64_t VIP : 1;
/** @brief ID Flag */
uint64_t ID : 1;
/** @brief Reserved */
uint64_t _reserved3 : 10;
};
uint64_t raw;
} RFLAGS;
typedef struct TrapFrame
{
// uint64_t gs; // General-purpose Segment
// uint64_t fs; // General-purpose Segment
// uint64_t es; // Extra Segment (used for string operations)
uint64_t ds; // Data Segment
uint64_t r15; // General purpose
uint64_t r14; // General purpose
uint64_t r13; // General purpose
uint64_t r12; // General purpose
uint64_t r11; // General purpose
uint64_t r10; // General purpose
uint64_t r9; // General purpose
uint64_t r8; // General purpose
uint64_t rbp; // Base Pointer (meant for stack frames)
uint64_t rdi; // Destination index for string operations
uint64_t rsi; // Source index for string operations
uint64_t rdx; // Data (commonly extends the A register)
uint64_t rcx; // Counter
uint64_t rbx; // Base
uint64_t rax; // Accumulator
uint64_t int_num; // Interrupt Number
uint64_t error_code; // Error code
uint64_t rip; // Instruction Pointer
uint64_t cs; // Code Segment
RFLAGS rflags; // Register Flags
uint64_t rsp; // Stack Pointer
uint64_t ss; // Stack Segment
} TrapFrame;
typedef union CR0
{
struct
{
/** @brief Protection Enable */
uint64_t PE : 1;
/** @brief Monitor Coprocessor */
uint64_t MP : 1;
/** @brief Emulation */
uint64_t EM : 1;
/** @brief Task Switched */
uint64_t TS : 1;
/** @brief Extension Type */
uint64_t ET : 1;
/** @brief Numeric Error */
uint64_t NE : 1;
/** @brief Reserved */
uint64_t _reserved0 : 10;
/** @brief Write Protect */
uint64_t WP : 1;
/** @brief Reserved */
uint64_t _reserved1 : 1;
/** @brief Alignment Mask */
uint64_t AM : 1;
/** @brief Reserved */
uint64_t _reserved2 : 10;
/** @brief Mot Write-through */
uint64_t NW : 1;
/** @brief Cache Disable */
uint64_t CD : 1;
/** @brief Paging */
uint64_t PG : 1;
};
uint64_t raw;
} CR0;
typedef union CR2
{
struct
{
/** @brief Page Fault Linear Address */
uint64_t PFLA;
};
uint64_t raw;
} CR2;
typedef union CR3
{
struct
{
/** @brief Not used if bit 17 of CR4 is 1 */
uint64_t PWT : 1;
/** @brief Not used if bit 17 of CR4 is 1 */
uint64_t PCD : 1;
/** @brief Base of PML4T/PML5T */
uint64_t PDBR;
};
uint64_t raw;
} CR3;
typedef union CR4
{
struct
{
/** @brief Virtual-8086 Mode Extensions */
uint64_t VME : 1;
/** @brief Protected-Mode Virtual Interrupts */
uint64_t PVI : 1;
/** @brief Time Stamp Disable */
uint64_t TSD : 1;
/** @brief Debugging Extensions */
uint64_t DE : 1;
/** @brief Page Size Extensions */
uint64_t PSE : 1;
/** @brief Physical Address Extension */
uint64_t PAE : 1;
/** @brief Machine Check Enable */
uint64_t MCE : 1;
/** @brief Page Global Enable */
uint64_t PGE : 1;
/** @brief Performance Monitoring Counter */
uint64_t PCE : 1;
/** @brief Operating System Support */
uint64_t OSFXSR : 1;
/** @brief Operating System Support */
uint64_t OSXMMEXCPT : 1;
/** @brief User-Mode Instruction Prevention */
uint64_t UMIP : 1;
/** @brief Linear Address 57bit */
uint64_t LA57 : 1;
/** @brief VMX Enable */
uint64_t VMXE : 1;
/** @brief SMX Enable */
uint64_t SMXE : 1;
/** @brief Reserved */
uint64_t _reserved0 : 1;
/** @brief FSGSBASE Enable */
uint64_t FSGSBASE : 1;
/** @brief PCID Enable */
uint64_t PCIDE : 1;
/** @brief XSAVE and Processor Extended States Enable */
uint64_t OSXSAVE : 1;
/** @brief Reserved */
uint64_t _reserved1 : 1;
/** @brief SMEP Enable */
uint64_t SMEP : 1;
/** @brief SMAP Enable */
uint64_t SMAP : 1;
/** @brief Protection-Key Enable */
uint64_t PKE : 1;
/** @brief Reserved */
uint64_t _reserved2 : 9;
};
uint64_t raw;
} CR4;
typedef union CR8
{
struct
{
/** @brief Task Priority Level */
uint64_t TPL : 1;
};
uint64_t raw;
} CR8;
static inline void lgdt(void *gdt)
{
#if defined(__amd64__)
asmv("lgdt (%0)"
:
: "r"(gdt));
#endif
}
static inline void lidt(void *idt)
{
#if defined(__amd64__)
asmv("lidt (%0)"
:
: "r"(idt));
#endif
}
static inline void ltr(uint16_t Segment)
{
#if defined(__amd64__)
asmv("ltr %0"
:
: "r"(Segment));
#endif
}
static inline void invlpg(void *Address)
{
#if defined(__amd64__)
asmv("invlpg (%0)"
:
: "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__)
asmv("cpuid"
: "=a"(*eax), "=b"(*ebx), "=c"(*ecx), "=d"(*edx)
: "a"(Function));
#endif
}
static inline uint64_t rdmsr(uint32_t msr)
{
uint32_t Low, High;
#if defined(__amd64__)
asmv("rdmsr"
: "=a"(Low), "=d"(High)
: "c"(msr)
: "memory");
#endif
return ((uint64_t)Low) | (((uint64_t)High) << 32);
}
static inline void wrmsr(uint32_t msr, uint64_t Value)
{
uint32_t Low = Value, High = Value >> 32;
#if defined(__amd64__)
asmv("wrmsr"
:
: "c"(msr), "a"(Low), "d"(High)
: "memory");
#endif
}
static inline CR0 readcr0()
{
uint64_t Result;
#if defined(__amd64__)
asmv("mov %%cr0, %[Result]"
: [Result] "=q"(Result));
#endif
return (CR0){.raw = Result};
}
static inline CR2 readcr2()
{
uint64_t Result;
#if defined(__amd64__)
asmv("mov %%cr2, %[Result]"
: [Result] "=q"(Result));
#endif
return (CR2){.raw = Result};
}
static inline CR3 readcr3()
{
uint64_t Result;
#if defined(__amd64__)
asmv("mov %%cr3, %[Result]"
: [Result] "=q"(Result));
#endif
return (CR3){.raw = Result};
}
static inline CR4 readcr4()
{
uint64_t Result;
#if defined(__amd64__)
asmv("mov %%cr4, %[Result]"
: [Result] "=q"(Result));
#endif
return (CR4){.raw = Result};
}
static inline CR8 readcr8()
{
uint64_t Result;
#if defined(__amd64__)
asmv("mov %%cr8, %[Result]"
: [Result] "=q"(Result));
#endif
return (CR8){.raw = Result};
}
static inline void writecr0(CR0 ControlRegister)
{
#if defined(__amd64__)
asmv("mov %[ControlRegister], %%cr0"
:
: [ControlRegister] "q"(ControlRegister.raw)
: "memory");
#endif
}
static inline void writecr2(CR2 ControlRegister)
{
#if defined(__amd64__)
asmv("mov %[ControlRegister], %%cr2"
:
: [ControlRegister] "q"(ControlRegister.raw)
: "memory");
#endif
}
static inline void writecr3(CR3 ControlRegister)
{
#if defined(__amd64__)
asmv("mov %[ControlRegister], %%cr3"
:
: [ControlRegister] "q"(ControlRegister.raw)
: "memory");
#endif
}
static inline void writecr4(CR4 ControlRegister)
{
#if defined(__amd64__)
asmv("mov %[ControlRegister], %%cr4"
:
: [ControlRegister] "q"(ControlRegister.raw)
: "memory");
#endif
}
static inline void writecr8(CR8 ControlRegister)
{
#if defined(__amd64__)
asmv("mov %[ControlRegister], %%cr8"
:
: [ControlRegister] "q"(ControlRegister.raw)
: "memory");
#endif
}
}
}
#endif // !__FENNIX_KERNEL_CPU_H__