diff options
Diffstat (limited to 'src/arch/x86')
-rw-r--r-- | src/arch/x86/include/arch/cpu.h | 2 | ||||
-rw-r--r-- | src/arch/x86/lib/cpu.c | 20 |
2 files changed, 22 insertions, 0 deletions
diff --git a/src/arch/x86/include/arch/cpu.h b/src/arch/x86/include/arch/cpu.h index 4d7be86223..85357d744e 100644 --- a/src/arch/x86/include/arch/cpu.h +++ b/src/arch/x86/include/arch/cpu.h @@ -108,6 +108,8 @@ static inline unsigned int cpuid_edx(unsigned int op) #if !defined(__PRE_RAM__) #include <device/device.h> +int cpu_phys_address_size(void); + struct cpu_device_id { unsigned vendor; unsigned device; diff --git a/src/arch/x86/lib/cpu.c b/src/arch/x86/lib/cpu.c index 3732ae296e..aaa0a16185 100644 --- a/src/arch/x86/lib/cpu.c +++ b/src/arch/x86/lib/cpu.c @@ -131,6 +131,26 @@ static const char *cpu_vendor_name(int vendor) return name; } +static int cpu_cpuid_extended_level(void) +{ + return cpuid_eax(0x80000000); +} + +#define CPUID_FEATURE_PAE (1 << 6) +#define CPUID_FEATURE_PSE36 (1 << 17) + +int cpu_phys_address_size(void) +{ + if (!(have_cpuid_p())) + return 32; + + if (cpu_cpuid_extended_level() > 0x80000008) + return cpuid_eax(0x80000008) & 0xff; + + if (cpuid_eax(1) & (CPUID_FEATURE_PAE | CPUID_FEATURE_PSE36)) + return 36; + return 32; +} static void identify_cpu(struct device *cpu) { char vendor_name[16]; |