[coreboot-gerrit] Patch set updated for coreboot: 143fc0c x86: mtrr: add CONFIG_CACHE_ROM support

Aaron Durbin (adurbin@google.com) gerrit at coreboot.org
Wed Mar 27 18:19:48 CET 2013


Aaron Durbin (adurbin at google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2918

-gerrit

commit 143fc0c2d44827ba2180bda74d53e9edc9b93886
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Tue Mar 26 12:47:47 2013 -0500

    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 at chromium.org>
---
 src/cpu/x86/Kconfig        |  5 +++-
 src/cpu/x86/mtrr/mtrr.c    | 59 ++++++++++++++++++++++++++++++++++++++++++++++
 src/include/cpu/x86/mtrr.h | 16 +++++++++++++
 3 files changed, 79 insertions(+), 1 deletion(-)

diff --git a/src/cpu/x86/Kconfig b/src/cpu/x86/Kconfig
index 8f05bf3..4c5176b 100644
--- a/src/cpu/x86/Kconfig
+++ b/src/cpu/x86/Kconfig
@@ -56,8 +56,11 @@ config LOGICAL_CPUS
 	default y
 
 config CACHE_ROM
-	bool
+	bool "Allow for caching system ROM."
 	default n
+	help
+	 When selected a variable range MTRR is allocated for coreboot and
+	 the bootloader enables caching of the system ROM for faster access.
 
 config SMM_TSEG
 	bool
diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c
index 8bf69c5..c847d2c 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);
 
diff --git a/src/include/cpu/x86/mtrr.h b/src/include/cpu/x86/mtrr.h
index 618a93c..bff736d 100644
--- a/src/include/cpu/x86/mtrr.h
+++ b/src/include/cpu/x86/mtrr.h
@@ -52,6 +52,10 @@
  *    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.
+ * 3. If CONFIG_CACHE_ROM is selected an MTRR is allocated for enabling
+ *    the caching of the ROM. However, it is set to uncacheable (UC). It
+ *    is the responsiblity of the caller to enable it by calling
+ *    x86_mtrr_enable_rom_caching().
  */
 void x86_setup_mtrrs(void);
 /*
@@ -67,6 +71,18 @@ 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);
+/* ROM caching can be used after variable MTRRs are set up. Beware that
+ * enabling CONFIG_CACHE_ROM will eat through quite a few MTRRs based on
+ * one's IO hole size and WRCOMB resources. Be sure to check the console
+ * log when enabling CONFIG_CACHE_ROM or adding WRCOMB resources. */
+#if CONFIG_CACHE_ROM
+void x86_mtrr_enable_rom_caching(void);
+void x86_mtrr_disable_rom_caching(void);
+#else
+static inline void x86_mtrr_enable_rom_caching(void) {}
+static inline void x86_mtrr_disable_rom_caching(void) {}
+#endif /* CONFIG_CACHE_ROM */
+
 #endif
 
 #if !defined(CONFIG_RAMTOP)



More information about the coreboot-gerrit mailing list