Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
Please login to access the resource
SUSE:SLE-12:Update
xen.196
537cd0b0-hvmloader-also-cover-PCI-MMIO-ranges-a...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 537cd0b0-hvmloader-also-cover-PCI-MMIO-ranges-above-4G-with-UC-MTRR-ranges.patch of Package xen.196
# Commit d06886694328a31369addc1f614cf326728d65a6 # Date 2014-05-21 18:13:36 +0200 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> 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@suse.com> Acked-by: Ian Campbell <ian.campbell@citrix.com> # Commit 119d8a42d3bfe6ebc1785720e1a7260e5c698632 # Date 2014-05-22 14:20:19 +0200 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> hvmloader: fix build with certain iasl versions While most of them support what we have now, Wheezy's dislikes the empty range. Put a fake one in place - it's getting overwritten upon evaluation of _CRS anyway. The range could be grown (downwards) if necessary; the way it is now it is - the highest possible one below the 36-bit boundary (with 36 bits being the lowest common denominator for all supported systems), - the smallest possible one that said iasl accepts. Reported-by: Sander Eikelenboom <linux@eikelenboom.it> Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Ian Campbell <ian.campbell@citrix.com> # Commit 7f8d8abcf6dfb85fae591a547b24f9b27d92272c # Date 2014-05-28 10:57:18 +0200 # Author Jan Beulich <jbeulich@suse.com> # Committer Jan Beulich <jbeulich@suse.com> hvmloader: don't use AML operations on 64-bit fields WinXP and Win2K3, while having no problem with the QWordMemory resource (there was another one there before), don't like operations on 64-bit fields. Split the fields d0688669 ("hvmloader: also cover PCI MMIO ranges above 4G with UC MTRR ranges") added to 32-bit ones, handling carry over explicitly. Sadly the constructs needed to create the sub-fields - nominally CreateDWordField(PRT0, \_SB.PCI0._CRS._Y02._MIN, MINL) CreateDWordField(PRT0, Add(\_SB.PCI0._CRS._Y02._MIN, 4), MINH) - can't be used: The former gets warned upon by newer iasl, i.e. would need to be replaced by the latter just with the addend changed to 0, and the latter doesn't translate properly with recent iasl). Hence, short of having an ASL/iasl expert at hand, we need to work around the shortcomings of various iasl versions. See the code comment. Signed-off-by: Jan Beulich <jbeulich@suse.com> Acked-by: Ian Campbell <ian.campbell@citrix.com> --- 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_confi 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; --- a/tools/firmware/hvmloader/acpi/dsdt.asl +++ b/tools/firmware/hvmloader/acpi/dsdt.asl @@ -45,7 +45,7 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, 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,11 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, PLEN, 32, MSUA, 32, /* MADT checksum address */ MAPA, 32, /* MADT LAPIC0 address */ - VGIA, 32 /* VM generation id address */ + VGIA, 32, /* VM generation id address */ + LMIN, 32, + HMIN, 32, + LLEN, 32, + HLEN, 32 } /* Fix HCT test for 0x400 pci memory: @@ -136,7 +140,7 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, /* reserve memory for pci devices */ DWordMemory( ResourceProducer, PosDecode, MinFixed, MaxFixed, - Cacheable, ReadWrite, + WriteCombining, ReadWrite, 0x00000000, 0x000A0000, 0x000BFFFF, @@ -145,13 +149,24 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, DWordMemory( ResourceProducer, PosDecode, MinFixed, MaxFixed, - Cacheable, ReadWrite, + NonCacheable, ReadWrite, 0x00000000, 0xF0000000, 0xF4FFFFFF, 0x00000000, 0x05000000, ,, _Y01) + + QWordMemory ( + ResourceProducer, PosDecode, MinFixed, MaxFixed, + NonCacheable, ReadWrite, + 0x0000000000000000, + 0x0000000FFFFFFFF0, + 0x0000000FFFFFFFFF, + 0x0000000000000000, + 0x0000000000000010, + ,, _Y02) + }) CreateDWordField(PRT0, \_SB.PCI0._CRS._Y01._MIN, MMIN) @@ -163,6 +178,43 @@ DefinitionBlock ("DSDT.aml", "DSDT", 2, Add(MMIN, MLEN, MMAX) Subtract(MMAX, One, MMAX) + /* + * WinXP / Win2K3 blue-screen for operations on 64-bit values. + * Therefore we need to split the 64-bit calculations needed + * here, but different iasl versions evaluate name references + * to integers differently: + * Year (approximate) 2006 2008 2012 + * \_SB.PCI0._CRS._Y02 zero valid valid + * \_SB.PCI0._CRS._Y02._MIN valid valid huge + */ + If(LEqual(Zero, \_SB.PCI0._CRS._Y02)) { + Subtract(\_SB.PCI0._CRS._Y02._MIN, 14, Local0) + } Else { + Store(\_SB.PCI0._CRS._Y02, Local0) + } + CreateDWordField(PRT0, Add(Local0, 14), MINL) + CreateDWordField(PRT0, Add(Local0, 18), MINH) + CreateDWordField(PRT0, Add(Local0, 22), MAXL) + CreateDWordField(PRT0, Add(Local0, 26), MAXH) + CreateDWordField(PRT0, Add(Local0, 38), LENL) + CreateDWordField(PRT0, Add(Local0, 42), LENH) + + Store(\_SB.LMIN, MINL) + Store(\_SB.HMIN, MINH) + Store(\_SB.LLEN, LENL) + Store(\_SB.HLEN, LENH) + Add(MINL, LENL, MAXL) + Add(MINH, LENH, MAXH) + If(LLess(MAXL, MINL)) { + Add(MAXH, One, MAXH) + } + If(LOr(MINH, LENL)) { + If(LEqual(MAXL, 0)) { + Subtract(MAXH, One, MAXH) + } + Subtract(MAXL, One, MAXL) + } + Return (PRT0) } --- 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; } --- 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 --- 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 ) { /*
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor