aboutsummaryrefslogtreecommitdiff
path: root/src/cpu/x86/mtrr
diff options
context:
space:
mode:
authorAaron Durbin <adurbin@chromium.org>2013-03-26 12:47:47 -0500
committerStefan Reinauer <stefan.reinauer@coreboot.org>2013-03-29 19:59:53 +0100
commit77a5b4046ab7e7bee887990b342a7356554fd391 (patch)
tree81e6d965976a65dd62899459a41a75a48033d625 /src/cpu/x86/mtrr
parent9b027fe5b028011593c98d2af8727199b74d3e4c (diff)
x86: mtrr: add CONFIG_CACHE_ROM support
The CONFIG_CACHE_ROM support in the MTRR code allocates an MTRR specifically for setting up write-protect cachine of the ROM. It is assumed that CONFIG_ROM_SIZE is the size of the ROM and the whole area should be cached just under 4GiB. If enabled, the MTRR code will allocate but not enable rom caching. It is up to the callers of the MTRR code to explicitly enable (and disable afterwards) through the use of 2 new functions: - x86_mtrr_enable_rom_caching() - x86_mtrr_disable_rom_caching() Additionally, the CACHE_ROM option is exposed to the config menu so that it is not just selected by the chipset or board. The reasoning is that through a multitude of options CACHE_ROM may not be appropriate for enabling. Change-Id: I4483df850f442bdcef969ffeaf7608ed70b88085 Signed-off-by: Aaron Durbin <adurbin@chromium.org> Reviewed-on: http://review.coreboot.org/2918 Tested-by: build bot (Jenkins) Reviewed-by: Stefan Reinauer <stefan.reinauer@coreboot.org>
Diffstat (limited to 'src/cpu/x86/mtrr')
-rw-r--r--src/cpu/x86/mtrr/mtrr.c59
1 files changed, 59 insertions, 0 deletions
diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c
index 74aae64a89..dad10292a9 100644
--- a/src/cpu/x86/mtrr/mtrr.c
+++ b/src/cpu/x86/mtrr/mtrr.c
@@ -163,6 +163,16 @@ static struct memranges *get_physical_address_space(void)
memranges_add_resources(addr_space, mask, match,
MTRR_TYPE_WRCOMB);
+#if CONFIG_CACHE_ROM
+ /* Add a write-protect region covering the ROM size
+ * when CONFIG_CACHE_ROM is enabled. The ROM is assumed
+ * to be located at 4GiB - rom size. */
+ resource_t rom_base = RANGE_TO_PHYS_ADDR(
+ RANGE_4GB - PHYS_TO_RANGE_ADDR(CONFIG_ROM_SIZE));
+ memranges_insert(addr_space, rom_base, CONFIG_ROM_SIZE,
+ MTRR_TYPE_WRPROT);
+#endif
+
/* The address space below 4GiB is special. It needs to be
* covered entirly by range entries so that MTRR calculations
* can be properly done for the full 32-bit address space.
@@ -335,6 +345,44 @@ void x86_setup_fixed_mtrrs(void)
enable_fixed_mtrr();
}
+/* Keep track of the MTRR that covers the ROM for caching purposes. */
+#if CONFIG_CACHE_ROM
+static long rom_cache_mtrr = -1;
+
+void x86_mtrr_enable_rom_caching(void)
+{
+ msr_t msr_val;
+ unsigned long index;
+
+ if (rom_cache_mtrr < 0)
+ return;
+
+ index = rom_cache_mtrr;
+ disable_cache();
+ msr_val = rdmsr(MTRRphysBase_MSR(index));
+ msr_val.lo &= ~0xff;
+ msr_val.lo |= MTRR_TYPE_WRPROT;
+ wrmsr(MTRRphysBase_MSR(index), msr_val);
+ enable_cache();
+}
+
+void x86_mtrr_disable_rom_caching(void)
+{
+ msr_t msr_val;
+ unsigned long index;
+
+ if (rom_cache_mtrr < 0)
+ return;
+
+ index = rom_cache_mtrr;
+ disable_cache();
+ msr_val = rdmsr(MTRRphysBase_MSR(index));
+ msr_val.lo &= ~0xff;
+ wrmsr(MTRRphysBase_MSR(index), msr_val);
+ enable_cache();
+}
+#endif
+
struct var_mtrr_state {
struct memranges *addr_space;
int above4gb;
@@ -382,6 +430,17 @@ static void write_var_mtrr(struct var_mtrr_state *var_state,
mask = (1ULL << var_state->address_bits) - 1;
rsize = rsize & mask;
+#if CONFIG_CACHE_ROM
+ /* CONFIG_CACHE_ROM allocates an MTRR specifically for allowing
+ * one to turn on caching for faster ROM access. However, it is
+ * left to the MTRR callers to enable it. */
+ if (mtrr_type == MTRR_TYPE_WRPROT) {
+ mtrr_type = MTRR_TYPE_UNCACHEABLE;
+ if (rom_cache_mtrr < 0)
+ rom_cache_mtrr = var_state->mtrr_index;
+ }
+#endif
+
printk(BIOS_DEBUG, "MTRR: %d base 0x%016llx mask 0x%016llx type %d\n",
var_state->mtrr_index, rbase, rsize, mtrr_type);