[coreboot-gerrit] Patch set updated for coreboot: 05efa9e mtrr: only add prefetchable resources as WRCOMB for VGA devices

Aaron Durbin (adurbin@google.com) gerrit at coreboot.org
Sun Feb 9 22:03:35 CET 2014


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

-gerrit

commit 05efa9e58f2488fa611257c6296d10f20d06bca0
Author: Aaron Durbin <adurbin at chromium.org>
Date:   Sat Feb 8 15:41:52 2014 -0600

    mtrr: only add prefetchable resources as WRCOMB for VGA devices
    
    Be more conservative and only add VGA devices' prefetchable
    resources as write-combining in the address space. Previously
    all prefetchable memory was added as a write-combining memory
    type. Some hardware incorrectly advertises its BAR as
    prefetchable when it shouldn't be.
    
    A new memranges_add_resources_filter() function is added
    to provide additional filtering on device and resource.
    
    Change-Id: I3fc55b90d8c5b694c5aa9e2f34db1b4ef845ce10
    Signed-off-by: Aaron Durbin <adurbin at chromium.org>
---
 src/cpu/x86/mtrr/mtrr.c | 19 +++++++++++++++++--
 src/include/memrange.h  | 13 +++++++++++++
 src/lib/memrange.c      | 19 +++++++++++++++----
 3 files changed, 45 insertions(+), 6 deletions(-)

diff --git a/src/cpu/x86/mtrr/mtrr.c b/src/cpu/x86/mtrr/mtrr.c
index dfb9c94..d85a869 100644
--- a/src/cpu/x86/mtrr/mtrr.c
+++ b/src/cpu/x86/mtrr/mtrr.c
@@ -30,6 +30,7 @@
 #include <bootstate.h>
 #include <console/console.h>
 #include <device/device.h>
+#include <device/pci_ids.h>
 #include <cpu/cpu.h>
 #include <cpu/x86/msr.h>
 #include <cpu/x86/mtrr.h>
@@ -154,6 +155,20 @@ static inline int range_entry_mtrr_type(struct range_entry *r)
 	return range_entry_tag(r) & MTRR_TAG_MASK;
 }
 
+static int filter_vga_wrcomb(struct device *dev, struct resource *res)
+{
+	/* Only handle PCI devices. */
+	if (dev->path.type != DEVICE_PATH_PCI)
+		return 0;
+
+	/* Only handle VGA class devices. */
+	if (((dev->class >> 8) != PCI_CLASS_DISPLAY_VGA))
+		return 0;
+
+	/* Add resource as write-combining in the address space. */
+	return 1;
+}
+
 static struct memranges *get_physical_address_space(void)
 {
 	static struct memranges *addr_space;
@@ -181,8 +196,8 @@ static struct memranges *get_physical_address_space(void)
 		 * resources are appropriate for this MTRR type. */
 		match = IORESOURCE_PREFETCH;
 		mask |= match;
-		memranges_add_resources(addr_space, mask, match,
-		                        MTRR_TYPE_WRCOMB);
+		memranges_add_resources_filter(addr_space, mask, match, MTRR_TYPE_WRCOMB,
+		                               filter_vga_wrcomb);
 
 #if CONFIG_CACHE_ROM
 		/* Add a write-protect region covering the ROM size
diff --git a/src/include/memrange.h b/src/include/memrange.h
index 4f094f5..ba85bef 100644
--- a/src/include/memrange.h
+++ b/src/include/memrange.h
@@ -94,6 +94,19 @@ void memranges_add_resources(struct memranges *ranges,
                              unsigned long mask, unsigned long match,
                              unsigned long tag);
 
+/* Add memory resources that match with the corresponding mask and match but
+ * also provide filter as additional check. The filter will return non-zero
+ * to add the resource or zero to not add the resource. Each entry will be
+ * tagged with the provided tag. e.g.  To populate all cacheable memory
+ * resources in the range with a filter:
+ * memranges_add_resources_filter(range, IORESOURCE_CACHEABLE,
+ *                         IORESROUCE_CACHEABLE, my_cacheable_tag, filter); */
+typedef int (*memrange_filter_t)(struct device *dev, struct resource *res);
+void memranges_add_resources_filter(struct memranges *ranges,
+                                    unsigned long mask, unsigned long match,
+                                    unsigned long tag,
+                                    memrange_filter_t filter);
+
 /* Fill all address ranges up to limit (exclusive) not covered by an entry by
  * inserting new entries with the provided tag. */
 void memranges_fill_holes_up_to(struct memranges *ranges,
diff --git a/src/lib/memrange.c b/src/lib/memrange.c
index 7fb6ef7..a85bc01 100644
--- a/src/lib/memrange.c
+++ b/src/lib/memrange.c
@@ -252,6 +252,7 @@ void memranges_insert(struct memranges *ranges,
 struct collect_context {
 	struct memranges *ranges;
 	unsigned long tag;
+	memrange_filter_t filter;
 };
 
 static void collect_ranges(void *gp, struct device *dev, struct resource *res)
@@ -261,12 +262,14 @@ static void collect_ranges(void *gp, struct device *dev, struct resource *res)
 	if (res->size == 0)
 		return;
 
-	memranges_insert(ctx->ranges, res->base, res->size, ctx->tag);
+	if (ctx->filter == NULL || ctx->filter(dev, res))
+		memranges_insert(ctx->ranges, res->base, res->size, ctx->tag);
 }
 
-void memranges_add_resources(struct memranges *ranges,
-                                 unsigned long mask, unsigned long match,
-                                 unsigned long tag)
+void memranges_add_resources_filter(struct memranges *ranges,
+                                    unsigned long mask, unsigned long match,
+                                    unsigned long tag,
+                                    memrange_filter_t filter)
 {
 	struct collect_context context;
 
@@ -276,9 +279,17 @@ void memranges_add_resources(struct memranges *ranges,
 
 	context.ranges = ranges;
 	context.tag = tag;
+	context.filter = filter;
 	search_global_resources(mask, match, collect_ranges, &context);
 }
 
+void memranges_add_resources(struct memranges *ranges,
+                             unsigned long mask, unsigned long match,
+                             unsigned long tag)
+{
+	memranges_add_resources_filter(ranges, mask, match, tag, NULL);
+}
+
 void memranges_init(struct memranges *ranges,
                     unsigned long mask, unsigned long match,
                     unsigned long tag)



More information about the coreboot-gerrit mailing list