x86: Support CPU functions in long mode

At present it is not possible to find out the physical-address size in
long mode, so a predefined value is used.

Update the macros to support this properly, since it is important when
programming MTRRs.

Signed-off-by: Simon Glass <sjg@chromium.org>
This commit is contained in:
Simon Glass
2025-03-06 09:03:48 -07:00
parent 10b612383f
commit 5ef7e0a18b
4 changed files with 39 additions and 35 deletions

View File

@@ -364,3 +364,27 @@ long locate_coreboot_table(void)
return addr;
}
static bool has_cpuid(void)
{
return flag_is_changeable_p(X86_EFLAGS_ID);
}
static uint cpu_cpuid_extended_level(void)
{
return cpuid_eax(0x80000000);
}
int cpu_phys_address_size(void)
{
if (!has_cpuid())
return 32;
if (cpu_cpuid_extended_level() >= 0x80000008)
return cpuid_eax(0x80000008) & 0xff;
if (cpuid_edx(1) & (CPUID_FEATURE_PAE | CPUID_FEATURE_PSE36))
return 36;
return 32;
}

View File

@@ -35,10 +35,6 @@
DECLARE_GLOBAL_DATA_PTR;
#define CPUID_FEATURE_PAE BIT(6)
#define CPUID_FEATURE_PSE36 BIT(17)
#define CPUID_FEAURE_HTT BIT(28)
/*
* Constructor for a conventional segment GDT (or LDT) entry
* This is a macro so it can be used in initialisers
@@ -412,25 +408,6 @@ static void setup_identity(void)
}
}
static uint cpu_cpuid_extended_level(void)
{
return cpuid_eax(0x80000000);
}
int cpu_phys_address_size(void)
{
if (!has_cpuid())
return 32;
if (cpu_cpuid_extended_level() >= 0x80000008)
return cpuid_eax(0x80000008) & 0xff;
if (cpuid_edx(1) & (CPUID_FEATURE_PAE | CPUID_FEATURE_PSE36))
return 36;
return 32;
}
static void setup_mtrr(void)
{
u64 mtrr_cap;

View File

@@ -59,11 +59,6 @@ int x86_cpu_reinit_f(void)
return 0;
}
int cpu_phys_address_size(void)
{
return CONFIG_CPU_ADDR_BITS;
}
int x86_cpu_init_f(void)
{
return 0;

View File

@@ -58,6 +58,10 @@ enum {
X86_SYSCON_PUNIT, /* Power unit */
};
#define CPUID_FEATURE_PAE BIT(6)
#define CPUID_FEATURE_PSE36 BIT(17)
#define CPUID_FEAURE_HTT BIT(28)
struct cpuid_result {
uint32_t eax;
uint32_t ebx;
@@ -161,12 +165,16 @@ static inline unsigned int cpuid_edx(unsigned int op)
return edx;
}
#if !CONFIG_IS_ENABLED(X86_64)
/* Standard macro to see if a specific flag is changeable */
static inline int flag_is_changeable_p(uint32_t flag)
#if CONFIG_IS_ENABLED(X86_64)
static inline int flag_is_changeable_p(u32 flag)
{
uint32_t f1, f2;
return 1;
}
#else
/* Standard macro to see if a specific flag is changeable */
static inline int flag_is_changeable_p(u32 flag)
{
u32 f1, f2;
asm(
"pushfl\n\t"
@@ -181,9 +189,9 @@ static inline int flag_is_changeable_p(uint32_t flag)
"popfl\n\t"
: "=&r" (f1), "=&r" (f2)
: "ir" (flag));
return ((f1^f2) & flag) != 0;
return ((f1 ^ f2) & flag) != 0;
}
#endif
#endif /* X86_64 */
/**
* cpu_enable_paging_pae() - Enable PAE-paging