MTRR: get physical address size from CPUID
authorSven Schnelle <svens@stackframe.org>
Tue, 10 Jan 2012 11:01:43 +0000 (12:01 +0100)
committerSven Schnelle <svens@stackframe.org>
Tue, 10 Jan 2012 20:51:40 +0000 (21:51 +0100)
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>
Reviewed-on: http://review.coreboot.org/529
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
23 files changed:
src/arch/x86/include/arch/cpu.h
src/arch/x86/lib/cpu.c
src/cpu/intel/ep80579/ep80579_init.c
src/cpu/intel/model_1067x/model_1067x_init.c
src/cpu/intel/model_106cx/model_106cx_init.c
src/cpu/intel/model_65x/model_65x_init.c
src/cpu/intel/model_67x/model_67x_init.c
src/cpu/intel/model_68x/model_68x_init.c
src/cpu/intel/model_69x/model_69x_init.c
src/cpu/intel/model_6bx/model_6bx_init.c
src/cpu/intel/model_6dx/model_6dx_init.c
src/cpu/intel/model_6ex/model_6ex_init.c
src/cpu/intel/model_6fx/model_6fx_init.c
src/cpu/intel/model_6xx/model_6xx_init.c
src/cpu/intel/model_f0x/model_f0x_init.c
src/cpu/intel/model_f1x/model_f1x_init.c
src/cpu/intel/model_f2x/model_f2x_init.c
src/cpu/intel/model_f3x/model_f3x_init.c
src/cpu/intel/model_f4x/model_f4x_init.c
src/cpu/via/model_c3/model_c3_init.c
src/cpu/via/model_c7/model_c7_init.c
src/cpu/x86/mtrr/mtrr.c
src/include/cpu/x86/mtrr.h

index 4d7be862230f37771c29e9b525ed0008ec966824..85357d744e6b563cc7ad640645a956b4c32a5529 100644 (file)
@@ -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;
index 3732ae296e96d7f0573b572d497b0640d27c496c..aaa0a161853f51a81aae13da66b7b0a24e7838d5 100644 (file)
@@ -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];
index 2f47158efb0a5d223f4e26244542bb9c53e39460..8b7dba01a853e8fe67f73faebe93d5cbf1106bb5 100644 (file)
@@ -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 */
index ca2b960b8b4780ba8886525a47d5053d0d37afb3..c6d716d9580beacd44586a6db7df6ac87ee47b59 100644 (file)
@@ -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
index 1199315c4820878ed8269fff0f49daa83389902d..4bf2924fedf8c6b4407a3b799c3a4919440d7cef 100644 (file)
@@ -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
index ef9759782c1558c80809b9fe2caf462d1d6cd3f8..285bacd94b02def4305f127f5a00e4989b5c368d 100644 (file)
@@ -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 */
index 0c9b3d2a0857f5a985edd97fd09f70121e32fa47..d34e4daa9de1ec9e65ea20ab5fd030f3ddd94711 100644 (file)
@@ -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 */
index 724469345248e0daa08662b7d0c15067cbb61b5a..fa35e55b504b815c54f0db184b9975d81f086b29 100644 (file)
@@ -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
index db8e661d8e8e0ab28ac11ae87902da2c11b84c84..cb805aec512cf76d40ea599f856f0313abc60847 100644 (file)
@@ -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 */
index a8883ecc6589a140db4e105a4cc2db48da18adaf..a06d7fb23d2dc56fb836f9c7b7d2bae5ee47b98d 100644 (file)
@@ -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
index 820597da400e586e16572ea819b70e5ef37c71c8..19b351dd1c7ae2d72914d43f79d48f6b18dbbf03 100644 (file)
@@ -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 */
index abd9cf4bc2ce0c1a59fde15a428852e88d7035fc..1c8c72b3f05703acfdc6ca68bedd7424dcf01382 100644 (file)
@@ -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
index 5cb1caed8929b202ec1af10893981daea5ac1fdd..033dfe6639ef78c1f83582d8347b127e01062f77 100644 (file)
@@ -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) */
index 34599e91f8edc1ef01f8fe13e8c68f246435e365..5724add4e8111aae5d8960d3f63326560fac3fba 100644 (file)
@@ -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 */
index 11e0c7c0c08e944d5ce8c9d4e8cd4785ae54eeb5..ed12b6edfd1037290766f4fb3a938f606e91eec1 100644 (file)
@@ -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 */
index 106968720ae32302a57abba4298b67515728553f..feb841050c878c7c0530e915ccaf01cb0c8af199 100644 (file)
@@ -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 */
index c1c2b7c514a9990905ad38e418ac3221bd0df1fd..ec78672de648534bf83f3913feaedccac44c82b4 100644 (file)
@@ -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 */
index f04ddcc0ce545d6fbda41ff5770c7582fec0ee12..580c98b4d75438e31763a6ebde4425230fd4f090 100644 (file)
@@ -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 */
index d4c163430829fb654455404473afe5b8059df1a4..54edf2e335ac1b027061ca93a05d58800e2ff8a2 100644 (file)
@@ -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 */
index 2fd2be405636fa5a8db01ad8240680b18da9bb55..0c5315bb532f6244a27372e8de52009661ceabba 100644 (file)
@@ -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 */
index bc326164a162bf43490a22d2401d295a8ee2a99c..585f7494b8ce6fce90391333c1f004e76cd57bd5 100644 (file)
@@ -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 */
index 8e7beea76e77d310ee59e8924ed343e690d8a63e..46d8e2d4c7a50cdadb5b5fe42ff358752d053ac8 100644 (file)
@@ -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);
 }
 
 
index c3b3e222f90eba54600692fadb6a62e3d1b8c25b..62cb8b7a3f2dfa387dc607ba3874f5266807363d 100644 (file)
@@ -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);