# 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
|