Sven Schnelle (svens@stackframe.org) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/529
-gerrit
commit a311aff916acb0ee221b599f2cc3a707c9b6761f Author: Sven Schnelle svens@stackframe.org Date: Tue Jan 10 12:01:43 2012 +0100
MTRR: get physical address size from CPUID
The current code uses static values for the physical address size supported by a CPU. This isn't always the right value: I.e. on model_6[ef]x Core (2) Duo CPUs physical address size is 36, while Xeons from the same family have 38 bits, which results in invalid MTRR setup. Fix this by getting the right number from CPUID.
Change-Id: If019c3d9147c3b86357f0ef0d9fda94d49d811ca Signed-off-by: Sven Schnelle svens@stackframe.org --- src/arch/x86/include/arch/cpu.h | 3 +++ src/arch/x86/lib/cpu.c | 20 ++++++++++++++++++++ src/cpu/intel/ep80579/ep80579_init.c | 2 +- src/cpu/intel/model_1067x/model_1067x_init.c | 2 +- src/cpu/intel/model_106cx/model_106cx_init.c | 2 +- src/cpu/intel/model_65x/model_65x_init.c | 2 +- src/cpu/intel/model_67x/model_67x_init.c | 2 +- src/cpu/intel/model_68x/model_68x_init.c | 2 +- src/cpu/intel/model_69x/model_69x_init.c | 2 +- src/cpu/intel/model_6bx/model_6bx_init.c | 2 +- src/cpu/intel/model_6dx/model_6dx_init.c | 2 +- src/cpu/intel/model_6ex/model_6ex_init.c | 2 +- src/cpu/intel/model_6fx/model_6fx_init.c | 2 +- src/cpu/intel/model_6xx/model_6xx_init.c | 2 +- src/cpu/intel/model_f0x/model_f0x_init.c | 2 +- src/cpu/intel/model_f1x/model_f1x_init.c | 2 +- src/cpu/intel/model_f2x/model_f2x_init.c | 2 +- src/cpu/intel/model_f3x/model_f3x_init.c | 2 +- src/cpu/intel/model_f4x/model_f4x_init.c | 2 +- src/cpu/via/model_c3/model_c3_init.c | 2 +- src/cpu/via/model_c7/model_c7_init.c | 2 +- src/cpu/x86/mtrr/mtrr.c | 8 ++++++-- src/include/cpu/x86/mtrr.h | 2 +- 23 files changed, 49 insertions(+), 22 deletions(-)
diff --git a/src/arch/x86/include/arch/cpu.h b/src/arch/x86/include/arch/cpu.h index 4d7be86..79f9113 100644 --- a/src/arch/x86/include/arch/cpu.h +++ b/src/arch/x86/include/arch/cpu.h @@ -22,6 +22,7 @@ #define X86_EFLAGS_VIP 0x00100000 /* Virtual Interrupt Pending */ #define X86_EFLAGS_ID 0x00200000 /* CPUID detection flag */
+ struct cpuid_result { uint32_t eax; uint32_t ebx; @@ -108,6 +109,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 3732ae2..aaa0a16 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]; diff --git a/src/cpu/intel/ep80579/ep80579_init.c b/src/cpu/intel/ep80579/ep80579_init.c index 2f47158..8b7dba0 100644 --- a/src/cpu/intel/ep80579/ep80579_init.c +++ b/src/cpu/intel/ep80579/ep80579_init.c @@ -41,7 +41,7 @@ static void ep80579_init(device_t dev) { /* Turn on caching if we haven't already */ x86_enable_cache(); - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
/* Update the microcode */ diff --git a/src/cpu/intel/model_1067x/model_1067x_init.c b/src/cpu/intel/model_1067x/model_1067x_init.c index ca2b960..c6d716d 100644 --- a/src/cpu/intel/model_1067x/model_1067x_init.c +++ b/src/cpu/intel/model_1067x/model_1067x_init.c @@ -197,7 +197,7 @@ static void model_1067x_init(device_t cpu) #endif
/* Setup MTRRs */ - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
#if CONFIG_USBDEBUG diff --git a/src/cpu/intel/model_106cx/model_106cx_init.c b/src/cpu/intel/model_106cx/model_106cx_init.c index 1199315..4bf2924 100644 --- a/src/cpu/intel/model_106cx/model_106cx_init.c +++ b/src/cpu/intel/model_106cx/model_106cx_init.c @@ -158,7 +158,7 @@ static void model_106cx_init(device_t cpu) #endif
/* Setup MTRRs */ - x86_setup_mtrrs(32); + x86_setup_mtrrs(); x86_mtrr_check();
#if CONFIG_USBDEBUG diff --git a/src/cpu/intel/model_65x/model_65x_init.c b/src/cpu/intel/model_65x/model_65x_init.c index ef97597..285bacd 100644 --- a/src/cpu/intel/model_65x/model_65x_init.c +++ b/src/cpu/intel/model_65x/model_65x_init.c @@ -65,7 +65,7 @@ static void model_65x_init(device_t dev)
/* Turn on caching if we haven't already */ x86_enable_cache(); - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
/* Enable the local cpu apics */ diff --git a/src/cpu/intel/model_67x/model_67x_init.c b/src/cpu/intel/model_67x/model_67x_init.c index 0c9b3d2..d34e4da 100644 --- a/src/cpu/intel/model_67x/model_67x_init.c +++ b/src/cpu/intel/model_67x/model_67x_init.c @@ -54,7 +54,7 @@ static void model_67x_init(device_t cpu) x86_enable_cache();
/* Setup MTRRs */ - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
/* Enable the local cpu apics */ diff --git a/src/cpu/intel/model_68x/model_68x_init.c b/src/cpu/intel/model_68x/model_68x_init.c index 7244693..fa35e55 100644 --- a/src/cpu/intel/model_68x/model_68x_init.c +++ b/src/cpu/intel/model_68x/model_68x_init.c @@ -85,7 +85,7 @@ static void model_68x_init(device_t cpu) #endif
/* Setup MTRRs */ - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
#if CONFIG_USBDEBUG diff --git a/src/cpu/intel/model_69x/model_69x_init.c b/src/cpu/intel/model_69x/model_69x_init.c index db8e661..cb805ae 100644 --- a/src/cpu/intel/model_69x/model_69x_init.c +++ b/src/cpu/intel/model_69x/model_69x_init.c @@ -25,7 +25,7 @@ static void model_69x_init(device_t dev) { /* Turn on caching if we haven't already */ x86_enable_cache(); - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
/* Update the microcode */ diff --git a/src/cpu/intel/model_6bx/model_6bx_init.c b/src/cpu/intel/model_6bx/model_6bx_init.c index a8883ec..a06d7fb 100644 --- a/src/cpu/intel/model_6bx/model_6bx_init.c +++ b/src/cpu/intel/model_6bx/model_6bx_init.c @@ -71,7 +71,7 @@ static void model_6bx_init(device_t cpu) #endif
/* Setup MTRRs */ - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
#if CONFIG_USBDEBUG diff --git a/src/cpu/intel/model_6dx/model_6dx_init.c b/src/cpu/intel/model_6dx/model_6dx_init.c index 820597d..19b351d 100644 --- a/src/cpu/intel/model_6dx/model_6dx_init.c +++ b/src/cpu/intel/model_6dx/model_6dx_init.c @@ -23,7 +23,7 @@ static void model_6dx_init(device_t dev) { /* Turn on caching if we haven't already */ x86_enable_cache(); - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
/* Update the microcode */ diff --git a/src/cpu/intel/model_6ex/model_6ex_init.c b/src/cpu/intel/model_6ex/model_6ex_init.c index abd9cf4..1c8c72b 100644 --- a/src/cpu/intel/model_6ex/model_6ex_init.c +++ b/src/cpu/intel/model_6ex/model_6ex_init.c @@ -184,7 +184,7 @@ static void model_6ex_init(device_t cpu) #endif
/* Setup MTRRs */ - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
#if CONFIG_USBDEBUG diff --git a/src/cpu/intel/model_6fx/model_6fx_init.c b/src/cpu/intel/model_6fx/model_6fx_init.c index 5cb1cae..033dfe6 100644 --- a/src/cpu/intel/model_6fx/model_6fx_init.c +++ b/src/cpu/intel/model_6fx/model_6fx_init.c @@ -211,7 +211,7 @@ static void model_6fx_init(device_t cpu) #endif
/* Setup MTRRs */ - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
/* Setup Page Attribute Tables (PAT) */ diff --git a/src/cpu/intel/model_6xx/model_6xx_init.c b/src/cpu/intel/model_6xx/model_6xx_init.c index 34599e9..5724add 100644 --- a/src/cpu/intel/model_6xx/model_6xx_init.c +++ b/src/cpu/intel/model_6xx/model_6xx_init.c @@ -47,7 +47,7 @@ static void model_6xx_init(device_t dev) { /* Turn on caching if we haven't already */ x86_enable_cache(); - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
/* Update the microcode */ diff --git a/src/cpu/intel/model_f0x/model_f0x_init.c b/src/cpu/intel/model_f0x/model_f0x_init.c index 11e0c7c..ed12b6e 100644 --- a/src/cpu/intel/model_f0x/model_f0x_init.c +++ b/src/cpu/intel/model_f0x/model_f0x_init.c @@ -28,7 +28,7 @@ static void model_f0x_init(device_t dev) { /* Turn on caching if we haven't already */ x86_enable_cache(); - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
/* Update the microcode */ diff --git a/src/cpu/intel/model_f1x/model_f1x_init.c b/src/cpu/intel/model_f1x/model_f1x_init.c index 1069687..feb8410 100644 --- a/src/cpu/intel/model_f1x/model_f1x_init.c +++ b/src/cpu/intel/model_f1x/model_f1x_init.c @@ -31,7 +31,7 @@ static void model_f1x_init(device_t dev) { /* Turn on caching if we haven't already */ x86_enable_cache(); - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
/* Update the microcode */ diff --git a/src/cpu/intel/model_f2x/model_f2x_init.c b/src/cpu/intel/model_f2x/model_f2x_init.c index c1c2b7c..ec78672 100644 --- a/src/cpu/intel/model_f2x/model_f2x_init.c +++ b/src/cpu/intel/model_f2x/model_f2x_init.c @@ -48,7 +48,7 @@ static void model_f2x_init(device_t cpu) { /* Turn on caching if we haven't already */ x86_enable_cache(); - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
/* Update the microcode */ diff --git a/src/cpu/intel/model_f3x/model_f3x_init.c b/src/cpu/intel/model_f3x/model_f3x_init.c index f04ddcc..580c98b 100644 --- a/src/cpu/intel/model_f3x/model_f3x_init.c +++ b/src/cpu/intel/model_f3x/model_f3x_init.c @@ -31,7 +31,7 @@ static void model_f3x_init(device_t cpu) { /* Turn on caching if we haven't already */ x86_enable_cache(); - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
/* Update the microcode */ diff --git a/src/cpu/intel/model_f4x/model_f4x_init.c b/src/cpu/intel/model_f4x/model_f4x_init.c index d4c1634..54edf2e 100644 --- a/src/cpu/intel/model_f4x/model_f4x_init.c +++ b/src/cpu/intel/model_f4x/model_f4x_init.c @@ -39,7 +39,7 @@ static void model_f4x_init(device_t cpu) { /* Turn on caching if we haven't already */ x86_enable_cache(); - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
/* Update the microcode */ diff --git a/src/cpu/via/model_c3/model_c3_init.c b/src/cpu/via/model_c3/model_c3_init.c index 2fd2be4..0c5315b 100644 --- a/src/cpu/via/model_c3/model_c3_init.c +++ b/src/cpu/via/model_c3/model_c3_init.c @@ -29,7 +29,7 @@ static void model_c3_init(device_t dev) { x86_enable_cache(); - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
/* Enable the local cpu apics */ diff --git a/src/cpu/via/model_c7/model_c7_init.c b/src/cpu/via/model_c7/model_c7_init.c index bc32616..585f749 100644 --- a/src/cpu/via/model_c7/model_c7_init.c +++ b/src/cpu/via/model_c7/model_c7_init.c @@ -202,7 +202,7 @@ static void model_c7_init(device_t dev) x86_enable_cache();
/* Set up Memory Type Range Registers */ - x86_setup_mtrrs(36); + x86_setup_mtrrs(); x86_mtrr_check();
/* Enable the local cpu apics */ diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c index 8e7beea..46d8e2d 100644 --- a/src/cpu/x86/mtrr/mtrr.c +++ b/src/cpu/x86/mtrr/mtrr.c @@ -36,6 +36,7 @@ #include <cpu/x86/msr.h> #include <cpu/x86/mtrr.h> #include <cpu/x86/cache.h> +#include <arch/cpu.h>
#if CONFIG_GFXUMA extern uint64_t uma_memory_base, uma_memory_size; @@ -462,10 +463,13 @@ void x86_setup_var_mtrrs(unsigned int address_bits, unsigned int above4gb) }
-void x86_setup_mtrrs(unsigned address_bits) +void x86_setup_mtrrs(void) { + int address_size; x86_setup_fixed_mtrrs(); - x86_setup_var_mtrrs(address_bits, 1); + address_size = cpu_phys_address_size(); + printk(BIOS_DEBUG, "CPU physical address size: %d bits\n", address_size); + x86_setup_var_mtrrs(address_size, 1); }
diff --git a/src/include/cpu/x86/mtrr.h b/src/include/cpu/x86/mtrr.h index c3b3e22..62cb8b7 100644 --- a/src/include/cpu/x86/mtrr.h +++ b/src/include/cpu/x86/mtrr.h @@ -39,7 +39,7 @@ #include <device/device.h> void enable_fixed_mtrr(void); void x86_setup_var_mtrrs(unsigned int address_bits, unsigned int above4gb); -void x86_setup_mtrrs(unsigned address_bits); +void x86_setup_mtrrs(void); int x86_mtrr_check(void); void set_var_mtrr_resource(void *gp, struct device *dev, struct resource *res); void x86_setup_fixed_mtrrs(void);