diff --git a/arch/amd64/cpu/apic.cpp b/arch/amd64/cpu/apic.cpp index a94d048..3340c5b 100644 --- a/arch/amd64/cpu/apic.cpp +++ b/arch/amd64/cpu/apic.cpp @@ -302,7 +302,6 @@ namespace APIC if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { CPU::x86::AMD::CPUID0x00000001 cpuid; - cpuid.Get(); if (cpuid.ECX.x2APIC) { this->x2APICSupported = cpuid.ECX.x2APIC; @@ -312,7 +311,6 @@ namespace APIC else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { CPU::x86::Intel::CPUID0x00000001 cpuid; - cpuid.Get(); if (cpuid.ECX.x2APIC) { this->x2APICSupported = cpuid.ECX.x2APIC; diff --git a/arch/i386/cpu/apic.cpp b/arch/i386/cpu/apic.cpp index 59a7b15..6996e03 100644 --- a/arch/i386/cpu/apic.cpp +++ b/arch/i386/cpu/apic.cpp @@ -279,7 +279,6 @@ namespace APIC if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { CPU::x86::AMD::CPUID0x00000001 cpuid; - cpuid.Get(); if (cpuid.ECX.x2APIC) { // x2APICSupported = cpuid.ECX.x2APIC; @@ -289,7 +288,6 @@ namespace APIC else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { CPU::x86::Intel::CPUID0x00000001 cpuid; - cpuid.Get(); if (cpuid.ECX.x2APIC) { // x2APICSupported = cpuid.ECX.x2APIC; diff --git a/core/cpu.cpp b/core/cpu.cpp index 0a814ae..7c93bef 100644 --- a/core/cpu.cpp +++ b/core/cpu.cpp @@ -252,8 +252,6 @@ namespace CPU { CPU::x86::AMD::CPUID0x00000001 cpuid1; CPU::x86::AMD::CPUID0x00000007 cpuid7; - cpuid1.Get(); - cpuid7.Get(); feat.PGE = cpuid1.EDX.PGE; feat.SSE = cpuid1.EDX.SSE; @@ -266,8 +264,7 @@ namespace CPU { CPU::x86::Intel::CPUID0x00000001 cpuid1; CPU::x86::Intel::CPUID0x00000007_0 cpuid7_0; - cpuid1.Get(); - cpuid7_0.Get(); + feat.PGE = cpuid1.EDX.PGE; feat.SSE = cpuid1.EDX.SSE; feat.SMEP = cpuid7_0.EBX.SMEP; @@ -324,10 +321,36 @@ namespace CPU SSEEnableAfter = true; } + /* More info in AMD64 Architecture Programmer's Manual + Volume 2: 3.1.1 CR0 Register */ + + /* Not Write-Through + This is ignored on recent processors. + */ cr0.NW = false; + + /* Cache Disable + Wether the CPU should cache memory or not. + If it's enabled, PWT and PCD are ignored. + */ cr0.CD = false; + + /* Write Protect + When set, the supervisor can't write to read-only pages. + */ cr0.WP = true; + /* Alignment check + The CPU checks the alignment of memory operands + and generates #AC if the alignment is incorrect. + + The condition for an alignment check is: + - The AM flag in CR0 is set. + - The AC flag in the RFLAGS register is set. + - CPL is 3. + */ + cr0.AM = true; + writecr0(cr0); if (strcmp(Hypervisor(), x86_CPUID_VENDOR_VIRTUALBOX) != 0 && diff --git a/core/memory/memory.cpp b/core/memory/memory.cpp index e551880..2833935 100644 --- a/core/memory/memory.cpp +++ b/core/memory/memory.cpp @@ -251,14 +251,12 @@ NIF void CreatePageTable(PageTable *pt) if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { CPU::x86::AMD::CPUID0x80000001 cpuid; - cpuid.Get(); PSESupport = cpuid.EDX.PSE; Page1GBSupport = cpuid.EDX.Page1GB; } else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { CPU::x86::Intel::CPUID0x00000001 cpuid; - cpuid.Get(); PSESupport = cpuid.EDX.PSE; } diff --git a/core/random.cpp b/core/random.cpp index 7ef03bd..bcbd9a2 100644 --- a/core/random.cpp +++ b/core/random.cpp @@ -33,13 +33,11 @@ namespace Random if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { CPU::x86::AMD::CPUID0x00000001 cpuid; - cpuid.Get(); RDRANDFlag = cpuid.ECX.RDRAND; } else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { CPU::x86::Intel::CPUID0x00000001 cpuid; - cpuid.Get(); RDRANDFlag = cpuid.ECX.RDRAND; } } @@ -72,13 +70,11 @@ namespace Random if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { CPU::x86::AMD::CPUID0x00000001 cpuid; - cpuid.Get(); RDRANDFlag = cpuid.ECX.RDRAND; } else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { CPU::x86::Intel::CPUID0x00000001 cpuid; - cpuid.Get(); RDRANDFlag = cpuid.ECX.RDRAND; } } @@ -111,13 +107,11 @@ namespace Random if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { CPU::x86::AMD::CPUID0x00000001 cpuid; - cpuid.Get(); RDRANDFlag = cpuid.ECX.RDRAND; } else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { CPU::x86::Intel::CPUID0x00000001 cpuid; - cpuid.Get(); RDRANDFlag = cpuid.ECX.RDRAND; } } diff --git a/core/time/timer.cpp b/core/time/timer.cpp index 0e77986..3666180 100644 --- a/core/time/timer.cpp +++ b/core/time/timer.cpp @@ -175,7 +175,6 @@ namespace Time if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { CPU::x86::AMD::CPUID0x80000007 cpuid80000007; - cpuid80000007.Get(); if (cpuid80000007.EDX.TscInvariant) TSCInvariant = true; } @@ -183,7 +182,6 @@ namespace Time { // TODO: Intel 0x80000007 CPU::x86::AMD::CPUID0x80000007 cpuid80000007; - cpuid80000007.Get(); if (cpuid80000007.EDX.TscInvariant) TSCInvariant = true; } diff --git a/include/cpu/x86/cpuid_amd.hpp b/include/cpu/x86/cpuid_amd.hpp index 66293e7..189dc8c 100644 --- a/include/cpu/x86/cpuid_amd.hpp +++ b/include/cpu/x86/cpuid_amd.hpp @@ -19,6 +19,7 @@ #define __FENNIX_KERNEL_CPU_x86_CPUID_AMD_H__ #include +#include #if defined(a64) typedef uint64_t cpuid_t; @@ -28,6 +29,42 @@ typedef uint32_t cpuid_t; typedef uint64_t cpuid_t; #endif // a64 || a32 +#if defined(a86) +#define __amd_cpuid_init(leaf) \ + CPUID##leaf() \ + { \ + asmv("cpuid" \ + : "=a"(EAX.raw), "=b"(EBX.raw), \ + "=c"(ECX.raw), "=d"(EDX.raw) \ + : "a"(leaf)); \ + if (!EAX.raw && !EBX.raw && !ECX.raw && !EDX.raw) \ + warn("cpuid not supported"); \ + } + +#define __amd_cpuid_init2(leaf, leaf2, suffix) \ + CPUID##leaf##suffix() \ + { \ + asmv("cpuid" \ + : "=a"(EAX.raw), "=b"(EBX.raw), \ + "=c"(ECX.raw), "=d"(EDX.raw) \ + : "a"(leaf), "c"(leaf2)); \ + if (!EAX.raw && !EBX.raw && !ECX.raw && !EDX.raw) \ + warn("cpuid not supported"); \ + } +#else +#define __amd_cpuid_init(leaf) \ + CPUID##leaf() \ + { \ + assert(!"cpuid not implemented for this architecture"); \ + } + +#define __amd_cpuid_init2(leaf, leaf2, suffix) \ + CPUID##leaf##suffix() \ + { \ + assert(!"cpuid not implemented for this architecture"); \ + } +#endif + namespace CPU { namespace x86 @@ -38,14 +75,7 @@ namespace CPU /** @brief Basic CPU information */ struct CPUID0x00000000 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x0)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x00000000); /** @brief Largest Standard Function Number */ union @@ -91,14 +121,7 @@ namespace CPU /** @brief Additional CPU information */ struct CPUID0x00000001 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x00000001); /** @brief Family, Model, Stepping Identifiers */ union @@ -207,14 +230,7 @@ namespace CPU /** @brief Monitor and MWait Features */ struct CPUID0x00000005 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x5)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x00000005); /** @brief Monitor/MWait */ union @@ -264,14 +280,7 @@ namespace CPU /** @brief Power Management Related Features */ struct CPUID0x00000006 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x6)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x00000006); /** @brief Local APIC Timer Invariance */ union @@ -320,14 +329,7 @@ namespace CPU /** @brief Structured Extended Feature Identifiers */ struct CPUID0x00000007 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x7)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x00000007); /** @brief Structured Extended Feature Identifiers */ union @@ -408,14 +410,7 @@ namespace CPU /** @brief Thread Level - Extended Topology Enumeration */ struct CPUID0x0000000B_ECX_0 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0xB), "c"(0x0)); -#endif // a64 || a32 - } + __amd_cpuid_init2(0x0000000B, 0x0, _ECX_0); /** @brief Extended Topology Enumeration */ union @@ -465,14 +460,7 @@ namespace CPU /** @brief Core Level - Extended Topology Enumeration */ struct CPUID0x0000000B_ECX_1 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0xB), "c"(0x1)); -#endif // a64 || a32 - } + __amd_cpuid_init2(0x0000000B, 0x1, _ECX_1); /** @brief Extended Topology Enumeration */ union @@ -522,14 +510,7 @@ namespace CPU /** @brief Processor Extended State Enumeration */ struct CPUID0x0000000D_ECX_0 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0xD), "c"(0x0)); -#endif // a64 || a32 - } + __amd_cpuid_init2(0x0000000D, 0x0, _ECX_0); /** @brief Processor Extended State Enumeration */ union @@ -575,14 +556,7 @@ namespace CPU /** @brief Processor Extended State Enumeration */ struct CPUID0x0000000D_ECX_1 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0xD), "c"(0x1)); -#endif // a64 || a32 - } + __amd_cpuid_init2(0x0000000D, 0x1, _ECX_1); /** @brief Processor Extended State Enumeration */ union @@ -645,14 +619,7 @@ namespace CPU /** @brief Processor Extended State Enumeration */ struct CPUID0x0000000D_ECX_2 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0xD), "c"(0x2)); -#endif // a64 || a32 - } + __amd_cpuid_init2(0x0000000D, 0x2, _ECX_2); /** @brief Processor Extended State Enumeration */ union @@ -698,14 +665,7 @@ namespace CPU /** @brief Processor Extended State Emulation */ struct CPUID0x0000000D_ECX_11 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0xD), "c"(0x11)); -#endif // a64 || a32 - } + __amd_cpuid_init2(0x0000000D, 0x11, _ECX_11); /** @brief Processor Extended State Emulation */ union @@ -752,14 +712,7 @@ namespace CPU /** @brief Processor Extended State Emulation */ struct CPUID0x0000000D_ECX_12 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0xD), "c"(0x12)); -#endif // a64 || a32 - } + __amd_cpuid_init2(0x0000000D, 0x12, _ECX_12); /** @brief Processor Extended State Emulation */ union @@ -806,14 +759,7 @@ namespace CPU /** @brief Processor Extended State Enumeration */ struct CPUID0x0000000D_ECX_3E { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0xD), "c"(0x3E)); -#endif // a64 || a32 - } + __amd_cpuid_init2(0x0000000D, 0x3E, _ECX_3E); /** @brief Processor Extended State Enumeration */ union @@ -859,14 +805,7 @@ namespace CPU /** @brief Maximum Extended Function Number and Vendor String */ struct CPUID0x80000000 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000000)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x80000000); /** @brief Largest Extended Function Number */ union @@ -912,14 +851,7 @@ namespace CPU /** @brief Extended Processor and Processor Feature Identifiers */ struct CPUID0x80000001 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000001)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x80000001); /** @brief AMD Family, Model, Stepping */ union @@ -1033,14 +965,7 @@ namespace CPU /** @brief Extended Processor Name String */ struct CPUID0x80000002 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000002)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x80000002); union { @@ -1082,14 +1007,7 @@ namespace CPU /** @brief Extended Processor Name String */ struct CPUID0x80000003 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000003)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x80000003); union { @@ -1131,14 +1049,7 @@ namespace CPU /** @brief Extended Processor Name String */ struct CPUID0x80000004 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000004)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x80000004); union { @@ -1180,14 +1091,7 @@ namespace CPU /** @brief L1 Cache and TLB Information */ struct CPUID0x80000005 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000005)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x80000005); /** @brief L1 TLB 2M/4M Information */ union @@ -1245,14 +1149,7 @@ namespace CPU /** @brief L2 Cache and TLB and L3 Cache Information */ struct CPUID0x80000006 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000006)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x80000006); /** @brief L2 TLB 2M/4M Information */ union @@ -1311,14 +1208,7 @@ namespace CPU /** @brief Processor Power Management and RAS Capabilities */ struct CPUID0x80000007 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000007)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x80000007); union { @@ -1380,14 +1270,7 @@ namespace CPU /** @brief Processor Capacity Parameters and Extended Feature Identification */ struct CPUID0x80000008 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000008)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x80000008); /** @brief Long Mode Size Identifiers */ union @@ -1467,14 +1350,7 @@ namespace CPU /** @brief TODO */ struct CPUID0x8000000A { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x8000000A)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x8000000A); /** @brief */ union @@ -1547,14 +1423,7 @@ namespace CPU /** @brief TODO */ struct CPUID0x80000019 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000019)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x80000019); /** @brief */ union @@ -1600,14 +1469,7 @@ namespace CPU /** @brief TODO */ struct CPUID0x8000001A { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x8000001A)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x8000001A); /** @brief */ union @@ -1653,14 +1515,7 @@ namespace CPU /** @brief TODO */ struct CPUID0x8000001B { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x8000001B)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x8000001B); /** @brief */ union @@ -1706,14 +1561,7 @@ namespace CPU /** @brief TODO */ struct CPUID0x8000001C { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x8000001C)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x8000001C); /** @brief */ union @@ -1759,14 +1607,7 @@ namespace CPU /** @brief TODO */ struct CPUID0x8000001D { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x8000001D)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x8000001D); /** @brief */ union @@ -1812,14 +1653,7 @@ namespace CPU /** @brief TODO */ struct CPUID0x8000001E { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x8000001E)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x8000001E); /** @brief */ union @@ -1865,14 +1699,7 @@ namespace CPU /** @brief TODO */ struct CPUID0x8000001F { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x8000001F)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x8000001F); /** @brief */ union @@ -1918,14 +1745,7 @@ namespace CPU /** @brief TODO */ struct CPUID0x80000020 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000020)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x80000020); /** @brief */ union @@ -1971,14 +1791,7 @@ namespace CPU /** @brief TODO */ struct CPUID0x80000021 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000021)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x80000021); /** @brief */ union @@ -2024,14 +1837,7 @@ namespace CPU /** @brief TODO */ struct CPUID0x80000022 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000022)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x80000022); /** @brief */ union @@ -2077,14 +1883,7 @@ namespace CPU /** @brief TODO */ struct CPUID0x80000023 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000023)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x80000023); /** @brief */ union @@ -2130,14 +1929,7 @@ namespace CPU /** @brief TODO */ struct CPUID0x80000026 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000026)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x80000026); /** @brief */ union @@ -2191,14 +1983,7 @@ namespace CPU */ struct CPUID0x8FFFFFFF { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x8FFFFFFF)); -#endif // a64 || a32 - } + __amd_cpuid_init(0x8FFFFFFF); /** * String @@ -2252,4 +2037,7 @@ namespace CPU } } +#undef __amd_cpuid_init +#undef __amd_cpuid_init2 + #endif // !__FENNIX_KERNEL_CPU_x86_CPUID_AMD_H__ diff --git a/include/cpu/x86/cpuid_intel.hpp b/include/cpu/x86/cpuid_intel.hpp index 597f999..26f3ffa 100644 --- a/include/cpu/x86/cpuid_intel.hpp +++ b/include/cpu/x86/cpuid_intel.hpp @@ -19,6 +19,7 @@ #define __FENNIX_KERNEL_CPU_x86_CPUID_INTEL_H__ #include +#include #if defined(a64) typedef uint64_t cpuid_t; @@ -28,6 +29,42 @@ typedef uint32_t cpuid_t; typedef uint64_t cpuid_t; #endif // a64 || a32 +#if defined(a86) +#define __intel_cpuid_init(leaf) \ + CPUID##leaf() \ + { \ + asmv("cpuid" \ + : "=a"(EAX.raw), "=b"(EBX.raw), \ + "=c"(ECX.raw), "=d"(EDX.raw) \ + : "a"(leaf)); \ + if (!EAX.raw && !EBX.raw && !ECX.raw && !EDX.raw) \ + warn("cpuid not supported"); \ + } + +#define __intel_cpuid_init2(leaf, leaf2, suffix) \ + CPUID##leaf##suffix() \ + { \ + asmv("cpuid" \ + : "=a"(EAX.raw), "=b"(EBX.raw), \ + "=c"(ECX.raw), "=d"(EDX.raw) \ + : "a"(leaf), "c"(leaf2)); \ + if (!EAX.raw && !EBX.raw && !ECX.raw && !EDX.raw) \ + warn("cpuid not supported"); \ + } +#else +#define __intel_cpuid_init(leaf) \ + CPUID##leaf() \ + { \ + assert(!"cpuid not implemented for this architecture"); \ + } + +#define __intel_cpuid_init2(leaf, leaf2, suffix) \ + CPUID##leaf##suffix() \ + { \ + assert(!"cpuid not implemented for this architecture"); \ + } +#endif + namespace CPU { namespace x86 @@ -38,14 +75,7 @@ namespace CPU /** @brief Basic CPU information */ struct CPUID0x00000000 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x0)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x00000000); union { @@ -84,14 +114,7 @@ namespace CPU /** @brief Additional CPU information */ struct CPUID0x00000001 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x1)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x00000001); union { @@ -102,7 +125,7 @@ namespace CPU uint32_t Family : 4; /** * @brief Processor Type - * + * * 00: Original OEM Processor * 01: Intel OverDrive Processor * 10: Dual processor @@ -217,14 +240,7 @@ namespace CPU /** @brief CPU cache and TLB */ /* FIXME TODO */ struct CPUID0x00000002 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x2)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x00000002); union { @@ -278,14 +294,7 @@ namespace CPU /** @brief CPU serial number */ struct CPUID0x00000003 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x3)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x00000003); union { @@ -327,14 +336,7 @@ namespace CPU /** @brief Cache information */ struct CPUID0x00000004_1 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x4), "c"(0x1)); /* FIXME */ -#endif // a64 || a32 - } + __intel_cpuid_init2(0x00000004, 0x1, _1); union { @@ -384,14 +386,7 @@ namespace CPU /** @brief MONITOR information */ struct CPUID0x00000005 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x5)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x00000005); union { @@ -442,14 +437,7 @@ namespace CPU /** @brief Thermal and power management information */ struct CPUID0x00000006 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x6)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x00000006); union { @@ -494,14 +482,7 @@ namespace CPU /** @brief Extended feature flags enumeration */ struct CPUID0x00000007_0 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x7), "c"(0x0)); /* FIXME */ -#endif // a64 || a32 - } + __intel_cpuid_init2(0x00000007, 0x0, _0); union { @@ -720,14 +701,7 @@ namespace CPU /** @brief Extended feature flags enumeration */ struct CPUID0x00000007_1 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x7), "c"(0x1)); /* FIXME */ -#endif // a64 || a32 - } + __intel_cpuid_init2(0x00000007, 0x1, _1); union { @@ -826,14 +800,7 @@ namespace CPU /** @brief Performance monitors */ struct CPUID0x0000000A { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0xA)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x0000000A); union { @@ -887,14 +854,7 @@ namespace CPU /** @brief Get CPU frequency information */ struct CPUID0x00000015 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x15)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x00000015); union { @@ -948,14 +908,7 @@ namespace CPU /** @brief Get CPU frequency information */ struct CPUID0x00000016 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x16)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x00000016); union { @@ -1009,14 +962,7 @@ namespace CPU /** @brief Extended CPU information */ struct CPUID0x80000000 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000000)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x80000000); union { @@ -1059,14 +1005,7 @@ namespace CPU /** @brief Extended CPU information */ struct CPUID0x80000001 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000001)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x80000001); union { @@ -1116,14 +1055,7 @@ namespace CPU /** @brief CPU brand string */ struct CPUID0x80000002 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000002)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x80000002); union { @@ -1166,14 +1098,7 @@ namespace CPU /** @brief CPU brand string */ struct CPUID0x80000003 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000003)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x80000003); union { @@ -1216,14 +1141,7 @@ namespace CPU /** @brief CPU brand string */ struct CPUID0x80000004 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000004)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x80000004); union { @@ -1266,14 +1184,7 @@ namespace CPU /** @brief CPU cache line information */ struct CPUID0x80000006 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000006)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x80000006); union { @@ -1325,14 +1236,7 @@ namespace CPU /** @brief Virtual and physical memory size */ struct CPUID0x80000008 { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x80000008)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x80000008); union { @@ -1377,14 +1281,7 @@ namespace CPU /** @brief Secure virtual machine parameters */ struct CPUID0x8000000A { - __always_inline inline void Get() - { -#if defined(a86) - asmv("cpuid" - : "=a"(EAX.raw), "=b"(EBX.raw), "=c"(ECX.raw), "=d"(EDX.raw) - : "a"(0x8000000A)); -#endif // a64 || a32 - } + __intel_cpuid_init(0x8000000A); union { @@ -1428,4 +1325,7 @@ namespace CPU } } +#undef __intel_cpuid_init +#undef __intel_cpuid_init2 + #endif // !__FENNIX_KERNEL_CPU_x86_CPUID_INTEL_H__ diff --git a/tasking/task.cpp b/tasking/task.cpp index f4572bc..ec03670 100644 --- a/tasking/task.cpp +++ b/tasking/task.cpp @@ -398,13 +398,11 @@ namespace Tasking if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { CPU::x86::AMD::CPUID0x00000001 cpuid; - cpuid.Get(); MONITORSupported = cpuid.ECX.MONITOR; } else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { CPU::x86::Intel::CPUID0x00000001 cpuid; - cpuid.Get(); MONITORSupported = cpuid.ECX.MONITOR; } diff --git a/tests/cpuid.cpp b/tests/cpuid.cpp index 28f71a1..16d1300 100644 --- a/tests/cpuid.cpp +++ b/tests/cpuid.cpp @@ -66,42 +66,6 @@ __constructor void TestCPUIDStructs() CPU::x86::AMD::CPUID0x80000023 cpuid80000023; CPU::x86::AMD::CPUID0x80000026 cpuid80000026; - cpuid0.Get(); - cpuid1.Get(); - cpuid5.Get(); - cpuid6.Get(); - cpuid7.Get(); - cpuidB_C_0.Get(); - cpuidB_C_1.Get(); - cpuidD_C_0.Get(); - cpuidD_C_1.Get(); - cpuidD_C_2.Get(); - cpuidD_C_11.Get(); - cpuidD_C_12.Get(); - cpuidD_C_3E.Get(); - cpuid80000000.Get(); - cpuid80000001.Get(); - cpuid80000002.Get(); - cpuid80000003.Get(); - cpuid80000004.Get(); - cpuid80000005.Get(); - cpuid80000006.Get(); - cpuid80000007.Get(); - cpuid80000008.Get(); - cpuid8000000A.Get(); - cpuid80000019.Get(); - cpuid8000001A.Get(); - cpuid8000001B.Get(); - cpuid8000001C.Get(); - cpuid8000001D.Get(); - cpuid8000001E.Get(); - cpuid8000001F.Get(); - cpuid80000020.Get(); - cpuid80000021.Get(); - cpuid80000022.Get(); - cpuid80000023.Get(); - cpuid80000026.Get(); - // asmv("int3"); } else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) @@ -127,27 +91,6 @@ __constructor void TestCPUIDStructs() CPU::x86::Intel::CPUID0x80000008 cpuid80000008; CPU::x86::Intel::CPUID0x8000000A cpuid8000000A; - cpuid0.Get(); - cpuid1.Get(); - cpuid2.Get(); - cpuid3.Get(); - cpuid4_1.Get(); - cpuid5.Get(); - cpuid6.Get(); - cpuid7_0.Get(); - cpuid7_1.Get(); - cpuidA.Get(); - cpuid15.Get(); - cpuid16.Get(); - cpuid80000000.Get(); - cpuid80000001.Get(); - cpuid80000002.Get(); - cpuid80000003.Get(); - cpuid80000004.Get(); - cpuid80000006.Get(); - cpuid80000008.Get(); - cpuid8000000A.Get(); - // asmv("int3"); } } diff --git a/tests/rng.cpp b/tests/rng.cpp index 3f227a6..8bffb7b 100644 --- a/tests/rng.cpp +++ b/tests/rng.cpp @@ -27,13 +27,11 @@ __constructor void TestRandom() if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { CPU::x86::AMD::CPUID0x00000001 cpuid; - cpuid.Get(); RDRANDFlag = cpuid.ECX.RDRAND; } else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { CPU::x86::Intel::CPUID0x00000001 cpuid; - cpuid.Get(); RDRANDFlag = cpuid.ECX.RDRAND; } diff --git a/virtualization/detect.cpp b/virtualization/detect.cpp index dfe1ea5..4f2267a 100644 --- a/virtualization/detect.cpp +++ b/virtualization/detect.cpp @@ -121,7 +121,6 @@ bool DetectByCPUID() if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_INTEL) == 0) { CPU::x86::Intel::CPUID0x00000001 cpuid00000001; - cpuid00000001.Get(); if (cpuid00000001.ECX.Hypervisor == 1) { @@ -133,7 +132,6 @@ bool DetectByCPUID() else if (strcmp(CPU::Vendor(), x86_CPUID_VENDOR_AMD) == 0) { CPU::x86::AMD::CPUID0x00000001 cpuid00000001; - cpuid00000001.Get(); if (cpuid00000001.ECX.Hypervisor == 1) {