From 5eb6e9a77e46a0e809f12fd3c636aa77d10ea7be Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= Date: Sat, 14 Mar 2026 20:49:20 +0100 Subject: [PATCH] kernel/x86: add FRED MSR and CPUID definitions also add CR4 bits Change-Id: I51ee29e1cf8124e7d1ab722bfbf4e077e31a59f1 Reviewed-on: https://review.haiku-os.org/c/haiku/+/10498 Tested-by: Commit checker robot Reviewed-by: waddlesplash Reviewed-by: Adrien Destugues --- headers/private/kernel/arch/x86/arch_cpu.h | 28 +++++++++++++++++++++- src/system/kernel/arch/x86/arch_cpu.cpp | 13 ++++++++++ 2 files changed, 40 insertions(+), 1 deletion(-) diff --git a/headers/private/kernel/arch/x86/arch_cpu.h b/headers/private/kernel/arch/x86/arch_cpu.h index 279d90f9bb..fbf9009046 100644 --- a/headers/private/kernel/arch/x86/arch_cpu.h +++ b/headers/private/kernel/arch/x86/arch_cpu.h @@ -47,6 +47,15 @@ #define IA32_MSR_MTRR_CAPABILITIES 0xfe #define IA32_MSR_ARCH_CAPABILITIES 0x10a #define IA32_MSR_FLUSH_CMD 0x10b +#define IA32_MSR_FRED_RSP0 0x1cc +#define IA32_MSR_FRED_RSP1 0x1cd +#define IA32_MSR_FRED_RSP2 0x1ce +#define IA32_MSR_FRED_RSP3 0x1cf +#define IA32_MSR_FRED_STKLVLS 0x1d0 +#define IA32_MSR_FRED_SSP1 0x1d1 +#define IA32_MSR_FRED_SSP2 0x1d2 +#define IA32_MSR_FRED_SSP3 0x1d3 +#define IA32_MSR_FRED_CONFIG 0x1d4 #define IA32_MSR_SYSENTER_CS 0x174 #define IA32_MSR_SYSENTER_ESP 0x175 #define IA32_MSR_SYSENTER_EIP 0x176 @@ -378,6 +387,14 @@ #define IA32_FEATURE_ARCH_CAPABILITIES (1 << 29) // IA32_ARCH_CAPABILITIES MSR #define IA32_FEATURE_SSBD (1 << 31) // Speculative Store Bypass Disable +// x86 features from cpuid eax 0x7, ecx 1, eax register +// https://www.intel.com/content/www/us/en/content-details/819481/flexible-return-and-event-delivery-fred-specification.html +#define IA32_FEATURE_LASS (1 << 0) // Linear Address Space Separation +#define IA32_FEATURE_FRED (1 << 17) // FRED transitions +#define IA32_FEATURE_LKGS (1 << 18) // LKGS Instruction +#define IA32_FEATURE_WRMSRNS (1 << 19) // WRMSRNS Instruction +#define IA32_FEATURE_NMI_SRC (1 << 20) // NMI-Source Reporting + // x86 features from cpuid eax 0xd, ecx 1, eax register // reference http://www.intel.com/Assets/en_US/PDF/appnote/241618.pdf (Table 3-8) #define IA32_FEATURE_XSAVEOPT (1 << 0) // XSAVEOPT Instruction @@ -438,7 +455,9 @@ #define CR0_MONITOR_FPU (1UL << 1) // Control Register CR4 flags §2.5 -// https://www.intel.com/content/dam/www/public/us/en/documents/manuals/64-ia-32-architectures-software-developer-vol-3a-part-1-manual.pdf +// Intel® 64 and IA-32 Architectures Software Developer's Manual Volume 3A: System Programming Guide, Part 1 +// https://www.intel.com/content/www/us/en/developer/articles/technical/intel-sdm.html + #define IA32_CR4_VME (1UL << 0) #define IA32_CR4_PVI (1UL << 1) #define IA32_CR4_TSD (1UL << 2) @@ -460,6 +479,12 @@ #define IA32_CR4_SMEP (1UL << 20) #define IA32_CR4_SMAP (1UL << 21) #define IA32_CR4_PKE (1UL << 22) +#define IA32_CR4_CET (1UL << 23) +#define IA32_CR4_PKS (1UL << 24) +#define IA32_CR4_UINTR (1UL << 25) +#define IA32_CR4_LASS (1UL << 27) +#define IA32_CR4_LAM_SUP (1UL << 28) +#define IA32_CR4_FRED (1ULL << 32) // Extended Control Register XCR0 flags §13.3 // https://software.intel.com/content/dam/develop/public/us/en/documents/253665-sdm-vol-1.pdf @@ -526,6 +551,7 @@ enum x86_feature_type { FEATURE_EXT_7_EDX, // cpuid eax=0x80000007, edx register FEATURE_EXT_8_EBX, // cpuid eax=0x80000008, ebx register FEATURE_D_1_EAX, // cpuid eax=0xd, ecx=1, eax register + FEATURE_7_1_EAX, // cpuid eax=0x7, ecx=1, eax register FEATURE_NUM }; diff --git a/src/system/kernel/arch/x86/arch_cpu.cpp b/src/system/kernel/arch/x86/arch_cpu.cpp index d195c8988b..e2d10a5595 100644 --- a/src/system/kernel/arch/x86/arch_cpu.cpp +++ b/src/system/kernel/arch/x86/arch_cpu.cpp @@ -660,6 +660,16 @@ dump_feature_string(int currentCPU, cpu_ent* cpu) strlcat(features, "msr_arch ", sizeof(features)); if (cpu->arch.feature[FEATURE_7_EDX] & IA32_FEATURE_SSBD) strlcat(features, "ssbd ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_1_EAX] & IA32_FEATURE_LASS) + strlcat(features, "lass ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_1_EAX] & IA32_FEATURE_FRED) + strlcat(features, "fred ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_1_EAX] & IA32_FEATURE_LKGS) + strlcat(features, "lkgs ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_1_EAX] & IA32_FEATURE_WRMSRNS) + strlcat(features, "wrmsrns ", sizeof(features)); + if (cpu->arch.feature[FEATURE_7_1_EAX] & IA32_FEATURE_NMI_SRC) + strlcat(features, "nmi_src ", sizeof(features)); if (cpu->arch.feature[FEATURE_EXT_7_EDX] & IA32_FEATURE_AMD_HW_PSTATE) strlcat(features, "hwpstate ", sizeof(features)); if (cpu->arch.feature[FEATURE_EXT_7_EDX] & IA32_FEATURE_INVARIANT_TSC) @@ -1344,6 +1354,7 @@ detect_cpu(int currentCPU, bool full = true) cpu->arch.feature[FEATURE_7_ECX] = 0; cpu->arch.feature[FEATURE_7_EDX] = 0; cpu->arch.feature[FEATURE_D_1_EAX] = 0; + cpu->arch.feature[FEATURE_7_1_EAX] = 0; cpu->arch.model_name[0] = 0; // print some fun data @@ -1460,6 +1471,8 @@ detect_cpu(int currentCPU, bool full = true) cpu->arch.feature[FEATURE_7_EBX] = cpuid.regs.ebx; cpu->arch.feature[FEATURE_7_ECX] = cpuid.regs.ecx; cpu->arch.feature[FEATURE_7_EDX] = cpuid.regs.edx; + get_current_cpuid(&cpuid, 7, 1); + cpu->arch.feature[FEATURE_7_1_EAX] = cpuid.regs.eax; } if (maxBasicLeaf >= 0xd) {