[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [Xen-changelog] [xen-unstable] hvmloader: Dynamically size the PCI hole.
# HG changeset patch # User Keir Fraser <keir.fraser@xxxxxxxxxx> # Date 1231504885 0 # Node ID b84345ee0d41435766d1fda4658c582446ef5326 # Parent bf847041d98f507ca005ceee47de3f49136fa52f hvmloader: Dynamically size the PCI hole. Signed-off-by: Keir Fraser <keir.fraser@xxxxxxxxxx> --- tools/firmware/hvmloader/acpi/build.c | 4 +- tools/firmware/hvmloader/cacheattr.c | 6 ++-- tools/firmware/hvmloader/config.h | 8 +++-- tools/firmware/hvmloader/hvmloader.c | 42 +++++++++++++++++++++++++----- tools/firmware/hvmloader/util.c | 47 +++++++++++++++++----------------- 5 files changed, 70 insertions(+), 37 deletions(-) diff -r bf847041d98f -r b84345ee0d41 tools/firmware/hvmloader/acpi/build.c --- a/tools/firmware/hvmloader/acpi/build.c Fri Jan 09 11:44:35 2009 +0000 +++ b/tools/firmware/hvmloader/acpi/build.c Fri Jan 09 12:41:25 2009 +0000 @@ -85,8 +85,8 @@ static int construct_bios_info_table(uin bios_info->hpet_present = hpet_exists(ACPI_HPET_ADDRESS); - bios_info->pci_min = PCI_MEMBASE; - bios_info->pci_len = PCI_MEMSIZE; + bios_info->pci_min = pci_mem_start; + bios_info->pci_len = pci_mem_end - pci_mem_start; bios_info->xen_pfiob = 0xdead; return align16(sizeof(*bios_info)); diff -r bf847041d98f -r b84345ee0d41 tools/firmware/hvmloader/cacheattr.c --- a/tools/firmware/hvmloader/cacheattr.c Fri Jan 09 11:44:35 2009 +0000 +++ b/tools/firmware/hvmloader/cacheattr.c Fri Jan 09 12:41:25 2009 +0000 @@ -89,9 +89,11 @@ void cacheattr_init(void) if ( nr_var_ranges != 0 ) { /* A single UC range covering PCI space. */ - wrmsr(MSR_MTRRphysBase(0), PCI_MEMBASE); + /* 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_MEMBASE & addr_mask) | (1u << 11)); + ((uint64_t)(int32_t)pci_mem_start & addr_mask) | (1u << 11)); printf("var MTRRs ... "); } diff -r bf847041d98f -r b84345ee0d41 tools/firmware/hvmloader/config.h --- a/tools/firmware/hvmloader/config.h Fri Jan 09 11:44:35 2009 +0000 +++ b/tools/firmware/hvmloader/config.h Fri Jan 09 12:41:25 2009 +0000 @@ -14,8 +14,10 @@ #define PCI_ISA_DEVFN 0x08 /* dev 1, fn 0 */ #define PCI_ISA_IRQ_MASK 0x0c20U /* ISA IRQs 5,10,11 are PCI connected */ -#define PCI_MEMBASE 0xf0000000 -#define PCI_MEMSIZE 0x0c000000 +/* MMIO hole: Hardcoded defaults, which can be dynamically expanded. */ +#define PCI_MEM_START 0xf0000000 +#define PCI_MEM_END 0xfc000000 +extern unsigned long pci_mem_start, pci_mem_end; /* We reserve 16MB at the top of the 4GB memory hole. */ #define RESERVED_MEMBASE 0xff000000 @@ -28,6 +30,7 @@ #define ROMBIOS_END (ROMBIOS_BEGIN + ROMBIOS_SIZE) /* Memory map. */ +#define SCRATCH_PHYSICAL_ADDRESS 0x00010000 #define HYPERCALL_PHYSICAL_ADDRESS 0x00080000 #define VGABIOS_PHYSICAL_ADDRESS 0x000C0000 #define OPTIONROM_PHYSICAL_ADDRESS 0x000C8000 @@ -37,7 +40,6 @@ #define SMBIOS_PHYSICAL_ADDRESS 0x000EB000 #define SMBIOS_MAXIMUM_SIZE 0x00005000 #define ROMBIOS_PHYSICAL_ADDRESS 0x000F0000 -#define SCRATCH_PHYSICAL_ADDRESS 0x00010000 /* Offsets from E820_PHYSICAL_ADDRESS. */ #define E820_NR_OFFSET 0x0 diff -r bf847041d98f -r b84345ee0d41 tools/firmware/hvmloader/hvmloader.c --- a/tools/firmware/hvmloader/hvmloader.c Fri Jan 09 11:44:35 2009 +0000 +++ b/tools/firmware/hvmloader/hvmloader.c Fri Jan 09 12:41:25 2009 +0000 @@ -31,6 +31,7 @@ #include "option_rom.h" #include <xen/version.h> #include <xen/hvm/params.h> +#include <xen/memory.h> asm ( " .text \n" @@ -99,6 +100,9 @@ asm ( " .text \n" ); +unsigned long pci_mem_start = PCI_MEM_START; +unsigned long pci_mem_end = PCI_MEM_END; + static enum { VGA_none, VGA_std, VGA_cirrus } virtual_vga = VGA_none; static void init_hypercalls(void) @@ -148,16 +152,14 @@ static void apic_setup(void) static void pci_setup(void) { - uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd; + uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd, mmio_total = 0; uint16_t class, vendor_id, device_id; unsigned int bar, pin, link, isa_irq; /* Resources assignable to PCI devices via BARs. */ struct resource { uint32_t base, max; - } *resource; - struct resource mem_resource = { PCI_MEMBASE, PCI_MEMBASE + PCI_MEMSIZE }; - struct resource io_resource = { 0xc000, 0x10000 }; + } *resource, mem_resource, io_resource; /* Create a list of device BARs in descending order of size. */ struct bars { @@ -248,6 +250,10 @@ static void pci_setup(void) bars[i].bar_reg = bar_reg; bars[i].bar_sz = bar_sz; + if ( (bar_data & PCI_BASE_ADDRESS_SPACE) == + PCI_BASE_ADDRESS_SPACE_MEMORY ) + mmio_total += bar_sz; + nr_bars++; /* Skip the upper-half of the address for a 64-bit BAR. */ @@ -276,6 +282,28 @@ static void pci_setup(void) pci_writew(devfn, PCI_COMMAND, cmd); } + while ( (mmio_total > (pci_mem_end - pci_mem_start)) && + ((pci_mem_start << 1) != 0) ) + pci_mem_start <<= 1; + + while ( (pci_mem_start >> PAGE_SHIFT) < hvm_info->low_mem_pgend ) + { + struct xen_add_to_physmap xatp; + if ( hvm_info->high_mem_pgend == 0 ) + hvm_info->high_mem_pgend = 1ull << (32 - PAGE_SHIFT); + xatp.domid = DOMID_SELF; + xatp.space = XENMAPSPACE_gmfn; + xatp.idx = --hvm_info->low_mem_pgend; + xatp.gpfn = hvm_info->high_mem_pgend++; + if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) + BUG(); + } + + mem_resource.base = pci_mem_start; + mem_resource.max = pci_mem_end; + io_resource.base = 0xc000; + io_resource.max = 0x10000; + /* Assign iomem and ioport resources in descending order of size. */ for ( i = 0; i < nr_bars; i++ ) { @@ -625,6 +653,9 @@ int main(void) printf("CPU speed is %u MHz\n", get_cpu_mhz()); + apic_setup(); + pci_setup(); + smp_initialise(); perform_tests(); @@ -638,9 +669,6 @@ int main(void) rombios_sz = 0x10000; memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, rombios_sz); highbios_setup(); - - apic_setup(); - pci_setup(); if ( (hvm_info->nr_vcpus > 1) || hvm_info->apic_mode ) create_mp_tables(); diff -r bf847041d98f -r b84345ee0d41 tools/firmware/hvmloader/util.c --- a/tools/firmware/hvmloader/util.c Fri Jan 09 11:44:35 2009 +0000 +++ b/tools/firmware/hvmloader/util.c Fri Jan 09 12:41:25 2009 +0000 @@ -307,6 +307,7 @@ void *mem_alloc(uint32_t size, uint32_t { static uint32_t reserve = RESERVED_MEMBASE - 1; static int over_allocated; + struct xen_add_to_physmap xatp; struct xen_memory_reservation xmr; xen_pfn_t mfn; uint32_t s, e; @@ -323,36 +324,36 @@ void *mem_alloc(uint32_t size, uint32_t while ( (reserve >> PAGE_SHIFT) != (e >> PAGE_SHIFT) ) { reserve += PAGE_SIZE; - - /* Try to allocate another page in the reserved area. */ - xmr.domid = DOMID_SELF; - xmr.mem_flags = 0; - xmr.extent_order = 0; - xmr.nr_extents = 1; - set_xen_guest_handle(xmr.extent_start, &mfn); mfn = reserve >> PAGE_SHIFT; - if ( !over_allocated && - (hypercall_memory_op(XENMEM_populate_physmap, &xmr) == 1) ) - continue; - - /* If we fail, steal a page from the ordinary RAM map. */ - over_allocated = 1; + + /* Try to allocate a brand new page in the reserved area. */ + if ( !over_allocated ) + { + xmr.domid = DOMID_SELF; + xmr.mem_flags = 0; + xmr.extent_order = 0; + xmr.nr_extents = 1; + set_xen_guest_handle(xmr.extent_start, &mfn); + if ( hypercall_memory_op(XENMEM_populate_physmap, &xmr) == 1 ) + continue; + over_allocated = 1; + } + + /* Otherwise, relocate a page from the ordinary RAM map. */ if ( hvm_info->high_mem_pgend ) { - mfn = --hvm_info->high_mem_pgend; - if ( mfn == (1ull << (32 - PAGE_SHIFT)) ) + xatp.idx = --hvm_info->high_mem_pgend; + if ( xatp.idx == (1ull << (32 - PAGE_SHIFT)) ) hvm_info->high_mem_pgend = 0; } else { - mfn = --hvm_info->low_mem_pgend; - } - if ( hypercall_memory_op(XENMEM_decrease_reservation, &xmr) != 1 ) - BUG(); - - /* Now try the allocation again. Must not fail. */ - mfn = reserve >> PAGE_SHIFT; - if ( hypercall_memory_op(XENMEM_populate_physmap, &xmr) != 1 ) + xatp.idx = --hvm_info->low_mem_pgend; + } + xatp.domid = DOMID_SELF; + xatp.space = XENMAPSPACE_gmfn; + xatp.gpfn = mfn; + if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 ) BUG(); } _______________________________________________ Xen-changelog mailing list Xen-changelog@xxxxxxxxxxxxxxxxxxx http://lists.xensource.com/xen-changelog
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |