diff options
author | Aaron Durbin <adurbin@chromium.org> | 2013-03-26 14:09:47 -0500 |
---|---|---|
committer | Stefan Reinauer <stefan.reinauer@coreboot.org> | 2013-03-29 19:53:43 +0100 |
commit | bb4e79a332f0a4f79d402c91b61010157d8a7886 (patch) | |
tree | c886bd2f1d047392dac8dcdae78d7387d79904a3 /src/include/cpu | |
parent | 28adb6ead6d82073f32e4e786728e27326ccbc6c (diff) | |
download | coreboot-bb4e79a332f0a4f79d402c91b61010157d8a7886.tar.xz |
x86: add new mtrr implementation
The old MTRR code had issues using too many variable
MTRRs depending on the physical address space layout dictated
by the device resources. This new implementation calculates
the default MTRR type by comparing the number of variable MTRRs
used for each type. This avoids the need for IORESOURE_UMA_FB
because in many of those situations setting the default type to WB
frees up the variable MTTRs to set that space to UC.
Additionally, it removes the need for IORESOURCE_IGNORE_MTRR
becuase the new mtrr uses the memrange library which does merging
of resources.
Lastly, the sandybridge gma has its speedup optimization removed
for the graphics memory by writing a pre-determined MTRR index.
That will be fixed in an upcoming patch once write-combining support
is added to the resources.
Slight differences from previous MTRR code:
- The number of reserved OS MTRRs is not a hard limit. It's now advisory
as PAT can be used by the OS to setup the regions to the caching
policy desired.
- The memory types are calculated once by the first CPU to run the code.
After that all other CPUs use that value.
- CONFIG_CACHE_ROM support was dropped. It will be added back in its own
change.
A pathological case that was previously fixed by changing vendor code
to adjust the IO hole location looked like the following:
MTRR: Physical address space:
0x0000000000000000 - 0x00000000000a0000 size 0x000a0000 type 6
0x00000000000a0000 - 0x00000000000c0000 size 0x00020000 type 0
0x00000000000c0000 - 0x00000000ad800000 size 0xad740000 type 6
0x00000000ad800000 - 0x00000000d0000000 size 0x22800000 type 0
0x00000000d0000000 - 0x00000000e0000000 size 0x10000000 type 1
0x00000000e0000000 - 0x0000000100000000 size 0x20000000 type 0
0x0000000100000000 - 0x000000014f600000 size 0x4f600000 type 6
As noted by the output below it's impossible to accomodate those
ranges even with 10 variable MTRRS. However, because the code
can select WB as the default MTRR type it can be done in 6 MTRRs:
MTRR: default type WB/UC MTRR counts: 6/14.
MTRR: WB selected as default type.
MTRR: 0 base 0x00000000ad800000 mask 0x0000007fff800000 type 0
MTRR: 1 base 0x00000000ae000000 mask 0x0000007ffe000000 type 0
MTRR: 2 base 0x00000000b0000000 mask 0x0000007ff0000000 type 0
MTRR: 3 base 0x00000000c0000000 mask 0x0000007ff0000000 type 0
MTRR: 4 base 0x00000000d0000000 mask 0x0000007ff0000000 type 1
MTRR: 5 base 0x00000000e0000000 mask 0x0000007fe0000000 type 0
Change-Id: Idfcc78d9afef9d44c769a676716aae3ff2bd79de
Signed-off-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/2889
Tested-by: build bot (Jenkins)
Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/include/cpu')
-rw-r--r-- | src/include/cpu/x86/mtrr.h | 34 |
1 files changed, 23 insertions, 11 deletions
diff --git a/src/include/cpu/x86/mtrr.h b/src/include/cpu/x86/mtrr.h index fe85ad0a83..618a93c44e 100644 --- a/src/include/cpu/x86/mtrr.h +++ b/src/include/cpu/x86/mtrr.h @@ -26,6 +26,7 @@ #define MTRRphysMaskValid (1 << 11) #define NUM_FIXED_RANGES 88 +#define RANGES_PER_FIXED_MTRR 8 #define MTRRfix64K_00000_MSR 0x250 #define MTRRfix16K_80000_MSR 0x258 #define MTRRfix16K_A0000_MSR 0x259 @@ -39,22 +40,33 @@ #define MTRRfix4K_F8000_MSR 0x26f #if !defined (__ASSEMBLER__) && !defined(__PRE_RAM__) -#include <device/device.h> -/* You should almost NEVER use this function. - * N.B. We worked on a lot of ways to make this continue as static, - * but just making it available ended up being the simplest solution. + +/* + * The MTRR code has some side effects that the callers should be aware for. + * 1. The call sequence matters. x86_setup_mtrrs() calls + * x86_setup_fixed_mtrrs_no_enable() then enable_fixed_mtrrs() (equivalent + * of x86_setup_fixed_mtrrs()) then x86_setup_var_mtrrs(). If the callers + * want to call the components of x86_setup_mtrrs() because of other + * rquirements the ordering should still preserved. + * 2. enable_fixed_mtrr() will enable both variable and fixed MTRRs because + * of the nature of the global MTRR enable flag. Therefore, all direct + * or indirect callers of enable_fixed_mtrr() should ensure that the + * variable MTRR MSRs do not contain bad ranges. */ -void set_var_mtrr( - unsigned int reg, unsigned long basek, unsigned long sizek, - unsigned char type, unsigned address_bits); -void enable_fixed_mtrr(void); -void x86_setup_var_mtrrs(unsigned int address_bits, unsigned int above4gb); void x86_setup_mtrrs(void); -int x86_mtrr_check(void); -void set_var_mtrr_resource(void *gp, struct device *dev, struct resource *res); +/* + * x86_setup_var_mtrrs() parameters: + * address_bits - number of physical address bits supported by cpu + * above4gb - 2 means dynamically detect number of variable MTRRs available. + * non-zero means handle memory ranges above 4GiB. + * 0 means ignore memory ranges above 4GiB + */ +void x86_setup_var_mtrrs(unsigned int address_bits, unsigned int above4gb); +void enable_fixed_mtrr(void); void x86_setup_fixed_mtrrs(void); /* Set up fixed MTRRs but do not enable them. */ void x86_setup_fixed_mtrrs_no_enable(void); +int x86_mtrr_check(void); #endif #if !defined(CONFIG_RAMTOP) |