Aaron Durbin (adurbin(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2924
-gerrit
commit 94d01fbc0b590385f793bfcfb80098515aaef597
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Tue Mar 26 21:22:42 2013 -0500
memrange: add 2 new range_entry routines
Two convenience functions are added to operate on a range_entry:
- range_entry_update_tag() - update the entry's tag
- memranges_next_entry() - get the next entry after the one provide
These functions will be used by a follow on patch to the MTRR code
to allow hole punching in WB region when the default MTRR type is
UC.
Change-Id: I3c2be19c8ea1bbbdf7736c867e4a2aa82df2d611
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/include/memrange.h | 9 +++++++++
src/lib/memrange.c | 10 ++++++++++
2 files changed, 19 insertions(+)
diff --git a/src/include/memrange.h b/src/include/memrange.h
index 222ce3c..5e14f75 100644
--- a/src/include/memrange.h
+++ b/src/include/memrange.h
@@ -62,6 +62,12 @@ static inline unsigned long range_entry_tag(const struct range_entry *r)
return r->tag;
}
+static inline void range_entry_update_tag(struct range_entry *r,
+ unsigned long new_tag)
+{
+ r->tag = new_tag;
+}
+
/* Iterate over each entry in a memranges structure. Ranges cannot
* be deleted while processing each entry as the list cannot be safely
* traversed after such an operation.
@@ -105,4 +111,7 @@ void memranges_create_hole(struct memranges *ranges,
void memranges_insert(struct memranges *ranges,
resource_t base, resource_t size, unsigned long tag);
+/* Returns next entry after the provided entry. NULL if r is last. */
+struct range_entry *memranges_next_entry(struct memranges *ranges,
+ const struct range_entry *r);
#endif /* MEMRANGE_H_ */
diff --git a/src/lib/memrange.c b/src/lib/memrange.c
index 57637ba..5bc7755 100644
--- a/src/lib/memrange.c
+++ b/src/lib/memrange.c
@@ -304,3 +304,13 @@ void memranges_fill_holes_up_to(struct memranges *ranges,
/* Merge all entries that were newly added. */
merge_neighbor_entries(ranges);
}
+
+/* Returns next entry after the provided entry. NULL if r is last. */
+struct range_entry *memranges_next_entry(struct memranges *ranges,
+ const struct range_entry *r)
+{
+ if (list_is_last(&r->siblings, &ranges->list))
+ return NULL;
+
+ return list_first_entry(&r->siblings, struct range_entry, siblings);
+}
Aaron Durbin (adurbin(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2921
-gerrit
commit feafe3ea0e659b349d0d72a9427926e165cf850e
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Tue Mar 26 14:52:04 2013 -0500
chromeos: remove CACHE_ROM automatic selection
It's not appropriate for the chromeos Kconfig to automatically
select CACHE_ROM. The reason is that enabling CACHE_ROM is
dependent on the board and chipset atrributes.
Change-Id: I47429f1cceefd40226c4b943215d627a3c869c7b
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/vendorcode/google/chromeos/Kconfig | 1 -
1 file changed, 1 deletion(-)
diff --git a/src/vendorcode/google/chromeos/Kconfig b/src/vendorcode/google/chromeos/Kconfig
index e99e2c8..d5ca212 100644
--- a/src/vendorcode/google/chromeos/Kconfig
+++ b/src/vendorcode/google/chromeos/Kconfig
@@ -20,7 +20,6 @@ config CHROMEOS
bool
default n
select TPM
- select CACHE_ROM
help
Enable ChromeOS specific features like the GPIO sub table in
the coreboot table. NOTE: Enabling this option on an unsupported
Aaron Durbin (adurbin(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2918
-gerrit
commit 5e7f0ca99cb1589c50d4a45c77ed4511a2245a55
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Tue Mar 26 12:47:47 2013 -0500
x86: mtrr: add CONFIG_ROM_CACHE 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(a)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..6c6a73f 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 enable 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)
Aaron Durbin (adurbin(a)google.com) just uploaded a new patch set to gerrit, which you can find at http://review.coreboot.org/2892
-gerrit
commit c9c21dcb0b4a245a9ed57f0ccca3593ede722e98
Author: Aaron Durbin <adurbin(a)chromium.org>
Date: Tue Mar 26 14:10:34 2013 -0500
mtrr: honor IORESOURCE_WRCOMB
All resources that set the IORESOURCE_WRCOMB attribute which are
also marked as IORESOURCE_PREFETCH will have a MTRR set up that
is of the write-combining cacheable type. The only resources on
x86 that can be set to write-combining are prefetchable ones.
Change-Id: Iba7452cff3677e07d7e263b79982a49c93be9c54
Signed-off-by: Aaron Durbin <adurbin(a)chromium.org>
---
src/cpu/x86/mtrr/mtrr.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c
index 8bcdc6e..8bf69c5 100644
--- a/src/cpu/x86/mtrr/mtrr.c
+++ b/src/cpu/x86/mtrr/mtrr.c
@@ -142,10 +142,12 @@ static struct memranges *get_physical_address_space(void)
* time remove unacheable regions from the cacheable ones. */
if (addr_space == NULL) {
struct range_entry *r;
- const unsigned long mask = IORESOURCE_CACHEABLE;
+ unsigned long mask;
+ unsigned long match;
addr_space = &addr_space_storage;
+ mask = IORESOURCE_CACHEABLE;
/* Collect cacheable and uncacheable address ranges. The
* uncacheable regions take precedence over the cacheable
* regions. */
@@ -153,6 +155,14 @@ static struct memranges *get_physical_address_space(void)
memranges_add_resources(addr_space, mask, 0,
MTRR_TYPE_UNCACHEABLE);
+ /* Handle any write combining resources. Only prefetchable
+ * resources with the IORESOURCE_WRCOMB flag are appropriate
+ * for this MTRR type. */
+ match = IORESOURCE_PREFETCH | IORESOURCE_WRCOMB;
+ mask |= match;
+ memranges_add_resources(addr_space, mask, match,
+ MTRR_TYPE_WRCOMB);
+
/* 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.