hvmloader: MTRR UC type covers the pci regions only.
authorKeir Fraser <keir.fraser@citrix.com>
Fri, 9 Jan 2009 13:00:10 +0000 (13:00 +0000)
committerKeir Fraser <keir.fraser@citrix.com>
Fri, 9 Jan 2009 13:00:10 +0000 (13:00 +0000)
Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
tools/firmware/hvmloader/cacheattr.c

index fb6e9f44808be45e2ba62145087c1d6ae5ab5205..ae23b3e159a5f8e371b15f25c1a67a6b9c2bbca1 100644 (file)
@@ -88,13 +88,25 @@ void cacheattr_init(void)
     nr_var_ranges = (uint8_t)mtrr_cap;
     if ( nr_var_ranges != 0 )
     {
-        /* A single UC range covering PCI space. */
-        /* pci_mem_start must be of the binary form 1....10....0 */
-        BUG_ON(~(pci_mem_start | (pci_mem_start - 1)));
-        wrmsr(MSR_MTRRphysBase(0), pci_mem_start);
-        wrmsr(MSR_MTRRphysMask(0),
-              ((uint64_t)(int32_t)pci_mem_start & addr_mask) | (1u << 11));
-        printf("var MTRRs ... ");
+        unsigned long base = pci_mem_start, size;
+        int i;
+
+        for ( i = 0; (base != pci_mem_end) && (i < nr_var_ranges); i++ )
+        {
+            size = PAGE_SIZE;
+            while ( !(base & size) )
+                size <<= 1;
+            while ( ((base + size) < base) || ((base + size) > pci_mem_end) )
+                size >>= 1;
+
+            wrmsr(MSR_MTRRphysBase(i), base);
+            wrmsr(MSR_MTRRphysMask(i),
+                  (~(uint64_t)(size-1) & addr_mask) | (1u << 11));
+
+            base += size;
+        }
+
+        printf("var MTRRs [%d/%d] ... ", i, nr_var_ranges);
     }
 
     wrmsr(MSR_MTRRdefType, mtrr_def);