From adfbcb79ab719af4435e3fdbb8321cda825e076c Mon Sep 17 00:00:00 2001 From: Sven Schnelle Date: Tue, 10 Jan 2012 12:01:43 +0100 Subject: [PATCH] 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 Reviewed-on: http://review.coreboot.org/529 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer --- src/arch/x86/include/arch/cpu.h | 2 ++ 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, 48 insertions(+), 22 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 +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]; diff --git a/src/cpu/intel/ep80579/ep80579_init.c b/src/cpu/intel/ep80579/ep80579_init.c index 2f47158efb..8b7dba01a8 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 ca2b960b8b..c6d716d958 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 1199315c48..4bf2924fed 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 ef9759782c..285bacd94b 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 0c9b3d2a08..d34e4daa9d 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 7244693452..fa35e55b50 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 db8e661d8e..cb805aec51 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 a8883ecc65..a06d7fb23d 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 820597da40..19b351dd1c 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 abd9cf4bc2..1c8c72b3f0 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 5cb1caed89..033dfe6639 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 34599e91f8..5724add4e8 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 11e0c7c0c0..ed12b6edfd 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 106968720a..feb841050c 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 c1c2b7c514..ec78672de6 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 f04ddcc0ce..580c98b4d7 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 d4c1634308..54edf2e335 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 2fd2be4056..0c5315bb53 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 bc326164a1..585f7494b8 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 8e7beea76e..46d8e2d4c7 100644 --- a/src/cpu/x86/mtrr/mtrr.c +++ b/src/cpu/x86/mtrr/mtrr.c @@ -36,6 +36,7 @@ #include #include #include +#include #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 c3b3e222f9..62cb8b7a3f 100644 --- a/src/include/cpu/x86/mtrr.h +++ b/src/include/cpu/x86/mtrr.h @@ -39,7 +39,7 @@ #include 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);