[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Xen-changelog] [xen master] hvmloader: also cover PCI MMIO ranges above 4G with UC MTRR ranges



commit d06886694328a31369addc1f614cf326728d65a6
Author:     Jan Beulich <jbeulich@xxxxxxxx>
AuthorDate: Wed May 21 18:13:36 2014 +0200
Commit:     Jan Beulich <jbeulich@xxxxxxxx>
CommitDate: Wed May 21 18:13:36 2014 +0200

    hvmloader: also cover PCI MMIO ranges above 4G with UC MTRR ranges
    
    When adding support for BAR assignments to addresses above 4G, the MTRR
    side of things was left out.
    
    Additionally the MMIO ranges in the DSDT's \_SB.PCI0._CRS were having
    memory types not matching the ones put into MTRRs: The legacy VGA range
    is supposed to be WC, and the other ones should be UC.
    
    Signed-off-by: Jan Beulich <jbeulich@xxxxxxxx>
    Acked-by: Ian Campbell <ian.campbell@xxxxxxxxxx>
---
 tools/firmware/hvmloader/acpi/build.c  |    6 ++++++
 tools/firmware/hvmloader/acpi/dsdt.asl |   32 ++++++++++++++++++++++++++++----
 tools/firmware/hvmloader/cacheattr.c   |   21 +++++++++++++++++----
 tools/firmware/hvmloader/config.h      |    2 +-
 tools/firmware/hvmloader/pci.c         |   16 +++++++++++++---
 5 files changed, 65 insertions(+), 12 deletions(-)

diff --git a/tools/firmware/hvmloader/acpi/build.c 
b/tools/firmware/hvmloader/acpi/build.c
index f1dd3f0..5c42d89 100644
--- a/tools/firmware/hvmloader/acpi/build.c
+++ b/tools/firmware/hvmloader/acpi/build.c
@@ -51,6 +51,7 @@ struct acpi_info {
     uint32_t madt_csum_addr;    /* 12   - Address of MADT checksum */
     uint32_t madt_lapic0_addr;  /* 16   - Address of first MADT LAPIC struct */
     uint32_t vm_gid_addr;       /* 20   - Address of VM generation id buffer */
+    uint64_t pci_hi_min, pci_hi_len; /* 24, 32 - PCI I/O hole boundaries */
 };
 
 /* Number of processor objects in the chosen DSDT. */
@@ -525,6 +526,11 @@ void acpi_build_tables(struct acpi_config *config, 
unsigned int physical)
     acpi_info->hpet_present = hpet_exists(ACPI_HPET_ADDRESS);
     acpi_info->pci_min = pci_mem_start;
     acpi_info->pci_len = pci_mem_end - pci_mem_start;
+    if ( pci_hi_mem_end > pci_hi_mem_start )
+    {
+        acpi_info->pci_hi_min = pci_hi_mem_start;
+        acpi_info->pci_hi_len = pci_hi_mem_end - pci_hi_mem_start;
+    }
 
     return;
 
diff --git a/tools/firmware/hvmloader/acpi/dsdt.asl 
b/tools/firmware/hvmloader/acpi/dsdt.asl
index 247a8ad..958ebb1 100644
--- a/tools/firmware/hvmloader/acpi/dsdt.asl
+++ b/tools/firmware/hvmloader/acpi/dsdt.asl
@@ -45,7 +45,7 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "Xen", "HVM", 0)
     Scope (\_SB)
     {
        /* ACPI_INFO_PHYSICAL_ADDRESS == 0xFC000000 */
-       OperationRegion(BIOS, SystemMemory, 0xFC000000, 24)
+       OperationRegion(BIOS, SystemMemory, 0xFC000000, 40)
        Field(BIOS, ByteAcc, NoLock, Preserve) {
            UAR1, 1,
            UAR2, 1,
@@ -56,7 +56,9 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "Xen", "HVM", 0)
            PLEN, 32,
            MSUA, 32, /* MADT checksum address */
            MAPA, 32, /* MADT LAPIC0 address */
-           VGIA, 32  /* VM generation id address */
+           VGIA, 32, /* VM generation id address */
+           HMIN, 64,
+           HLEN, 64
        }
 
         /* Fix HCT test for 0x400 pci memory:
@@ -136,7 +138,7 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "Xen", "HVM", 0)
                     /* reserve memory for pci devices */
                     DWordMemory(
                         ResourceProducer, PosDecode, MinFixed, MaxFixed,
-                        Cacheable, ReadWrite,
+                        WriteCombining, ReadWrite,
                         0x00000000,
                         0x000A0000,
                         0x000BFFFF,
@@ -145,13 +147,24 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "Xen", "HVM", 0)
 
                     DWordMemory(
                         ResourceProducer, PosDecode, MinFixed, MaxFixed,
-                        Cacheable, ReadWrite,
+                        NonCacheable, ReadWrite,
                         0x00000000,
                         0xF0000000,
                         0xF4FFFFFF,
                         0x00000000,
                         0x05000000,
                         ,, _Y01)
+
+                    QWordMemory (
+                        ResourceProducer, PosDecode, MinFixed, MaxFixed,
+                        NonCacheable, ReadWrite,
+                        0x0000000000000000,
+                        0x0000000000000000,
+                        0x0000000000000000,
+                        0x0000000000000000,
+                        0x0000000000000000,
+                        ,, _Y02)
+
                 })
 
                 CreateDWordField(PRT0, \_SB.PCI0._CRS._Y01._MIN, MMIN)
@@ -163,6 +176,17 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, "Xen", "HVM", 0)
                 Add(MMIN, MLEN, MMAX)
                 Subtract(MMAX, One, MMAX)
 
+                CreateQWordField(PRT0, \_SB.PCI0._CRS._Y02._MIN, HMIN)
+                CreateQWordField(PRT0, \_SB.PCI0._CRS._Y02._MAX, HMAX)
+                CreateQWordField(PRT0, \_SB.PCI0._CRS._Y02._LEN, HLEN)
+
+                Store(\_SB.HMIN, HMIN)
+                Store(\_SB.HLEN, HLEN)
+                Add(HMIN, HLEN, HMAX)
+                If(LOr(HMIN, HLEN)) {
+                    Subtract(HMAX, One, HMAX)
+                }
+
                 Return (PRT0)
             }
 
diff --git a/tools/firmware/hvmloader/cacheattr.c 
b/tools/firmware/hvmloader/cacheattr.c
index 2f6c2f6..e7c219f 100644
--- a/tools/firmware/hvmloader/cacheattr.c
+++ b/tools/firmware/hvmloader/cacheattr.c
@@ -97,8 +97,7 @@ void cacheattr_init(void)
     nr_var_ranges = (uint8_t)mtrr_cap;
     if ( nr_var_ranges != 0 )
     {
-        unsigned long base = pci_mem_start, size;
-        int i;
+        uint64_t base = pci_mem_start, size;
 
         for ( i = 0; (base != pci_mem_end) && (i < nr_var_ranges); i++ )
         {
@@ -109,8 +108,22 @@ void cacheattr_init(void)
                 size >>= 1;
 
             wrmsr(MSR_MTRRphysBase(i), base);
-            wrmsr(MSR_MTRRphysMask(i),
-                  (~(uint64_t)(size-1) & addr_mask) | (1u << 11));
+            wrmsr(MSR_MTRRphysMask(i), (~(size - 1) & addr_mask) | (1u << 11));
+
+            base += size;
+        }
+
+        for ( base = pci_hi_mem_start;
+              (base != pci_hi_mem_end) && (i < nr_var_ranges); i++ )
+        {
+            size = PAGE_SIZE;
+            while ( !(base & size) )
+                size <<= 1;
+            while ( (base + size < base) || (base + size > pci_hi_mem_end) )
+                size >>= 1;
+
+            wrmsr(MSR_MTRRphysBase(i), base);
+            wrmsr(MSR_MTRRphysMask(i), (~(size - 1) & addr_mask) | (1u << 11));
 
             base += size;
         }
diff --git a/tools/firmware/hvmloader/config.h 
b/tools/firmware/hvmloader/config.h
index 6641197..80bea46 100644
--- a/tools/firmware/hvmloader/config.h
+++ b/tools/firmware/hvmloader/config.h
@@ -57,7 +57,7 @@ extern struct bios_config ovmf_config;
 #define PCI_MEM_END         0xfc000000
 
 extern unsigned long pci_mem_start, pci_mem_end;
-
+extern uint64_t pci_hi_mem_start, pci_hi_mem_end;
 
 /* Memory map. */
 #define SCRATCH_PHYSICAL_ADDRESS      0x00010000
diff --git a/tools/firmware/hvmloader/pci.c b/tools/firmware/hvmloader/pci.c
index 627e8cb..3712988 100644
--- a/tools/firmware/hvmloader/pci.c
+++ b/tools/firmware/hvmloader/pci.c
@@ -32,6 +32,7 @@
 
 unsigned long pci_mem_start = PCI_MEM_START;
 unsigned long pci_mem_end = PCI_MEM_END;
+uint64_t pci_hi_mem_start = 0, pci_hi_mem_end = 0;
 
 enum virtual_vga virtual_vga = VGA_none;
 unsigned long igd_opregion_pgbase = 0;
@@ -345,9 +346,8 @@ void pci_setup(void)
                 if ( high_mem_resource.base & (bar_sz - 1) )
                     high_mem_resource.base = high_mem_resource.base - 
                         (high_mem_resource.base & (bar_sz - 1)) + bar_sz;
-                else
-                    high_mem_resource.base = high_mem_resource.base - 
-                        (high_mem_resource.base & (bar_sz - 1));
+                if ( !pci_hi_mem_start )
+                    pci_hi_mem_start = high_mem_resource.base;
                 resource = &high_mem_resource;
                 bar_data &= ~PCI_BASE_ADDRESS_MEM_MASK;
             } 
@@ -398,6 +398,16 @@ void pci_setup(void)
         pci_writew(devfn, PCI_COMMAND, cmd);
     }
 
+    if ( pci_hi_mem_start )
+    {
+        /*
+         * Make end address alignment match the start address one's so that
+         * fewer variable range MTRRs are needed to cover the range.
+         */
+        pci_hi_mem_end = ((high_mem_resource.base - 1) |
+                          ((pci_hi_mem_start & -pci_hi_mem_start) - 1)) + 1;
+    }
+
     if ( vga_devfn != 256 )
     {
         /*
--
generated by git-patchbot for /home/xen/git/xen.git#master

_______________________________________________
Xen-changelog mailing list
Xen-changelog@xxxxxxxxxxxxx
http://lists.xensource.com/xen-changelog


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.