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>
Reviewed-on: http://review.coreboot.org/529
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
This commit is contained in:
Sven Schnelle 2012-01-10 12:01:43 +01:00
parent 75fb40e15d
commit adfbcb79ab
23 changed files with 48 additions and 22 deletions

View 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;

View 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];

View 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 */

View 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

View 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

View 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 */

View 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 */

View 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

View 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 */

View 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

View 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 */

View 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

View 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) */

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */

View 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 */

View 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);
}

View 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);