ia64/xen-unstable

changeset 19022:b84345ee0d41

hvmloader: Dynamically size the PCI hole.

Signed-off-by: Keir Fraser <keir.fraser@citrix.com>
author Keir Fraser <keir.fraser@citrix.com>
date Fri Jan 09 12:41:25 2009 +0000 (2009-01-09)
parents bf847041d98f
children 6d040d138e8f
files tools/firmware/hvmloader/acpi/build.c tools/firmware/hvmloader/cacheattr.c tools/firmware/hvmloader/config.h tools/firmware/hvmloader/hvmloader.c tools/firmware/hvmloader/util.c
line diff
     1.1 --- a/tools/firmware/hvmloader/acpi/build.c	Fri Jan 09 11:44:35 2009 +0000
     1.2 +++ b/tools/firmware/hvmloader/acpi/build.c	Fri Jan 09 12:41:25 2009 +0000
     1.3 @@ -85,8 +85,8 @@ static int construct_bios_info_table(uin
     1.4  
     1.5      bios_info->hpet_present = hpet_exists(ACPI_HPET_ADDRESS);
     1.6  
     1.7 -    bios_info->pci_min = PCI_MEMBASE;
     1.8 -    bios_info->pci_len = PCI_MEMSIZE;
     1.9 +    bios_info->pci_min = pci_mem_start;
    1.10 +    bios_info->pci_len = pci_mem_end - pci_mem_start;
    1.11      bios_info->xen_pfiob = 0xdead;
    1.12  
    1.13      return align16(sizeof(*bios_info));
     2.1 --- a/tools/firmware/hvmloader/cacheattr.c	Fri Jan 09 11:44:35 2009 +0000
     2.2 +++ b/tools/firmware/hvmloader/cacheattr.c	Fri Jan 09 12:41:25 2009 +0000
     2.3 @@ -89,9 +89,11 @@ void cacheattr_init(void)
     2.4      if ( nr_var_ranges != 0 )
     2.5      {
     2.6          /* A single UC range covering PCI space. */
     2.7 -        wrmsr(MSR_MTRRphysBase(0), PCI_MEMBASE);
     2.8 +        /* pci_mem_start must be of the binary form 1....10....0 */
     2.9 +        BUG_ON(~(pci_mem_start | (pci_mem_start - 1)));
    2.10 +        wrmsr(MSR_MTRRphysBase(0), pci_mem_start);
    2.11          wrmsr(MSR_MTRRphysMask(0),
    2.12 -              ((uint64_t)(int32_t)PCI_MEMBASE & addr_mask) | (1u << 11));
    2.13 +              ((uint64_t)(int32_t)pci_mem_start & addr_mask) | (1u << 11));
    2.14          printf("var MTRRs ... ");
    2.15      }
    2.16  
     3.1 --- a/tools/firmware/hvmloader/config.h	Fri Jan 09 11:44:35 2009 +0000
     3.2 +++ b/tools/firmware/hvmloader/config.h	Fri Jan 09 12:41:25 2009 +0000
     3.3 @@ -14,8 +14,10 @@
     3.4  #define PCI_ISA_DEVFN       0x08    /* dev 1, fn 0 */
     3.5  #define PCI_ISA_IRQ_MASK    0x0c20U /* ISA IRQs 5,10,11 are PCI connected */
     3.6  
     3.7 -#define PCI_MEMBASE         0xf0000000
     3.8 -#define PCI_MEMSIZE         0x0c000000
     3.9 +/* MMIO hole: Hardcoded defaults, which can be dynamically expanded. */
    3.10 +#define PCI_MEM_START       0xf0000000
    3.11 +#define PCI_MEM_END         0xfc000000
    3.12 +extern unsigned long pci_mem_start, pci_mem_end;
    3.13  
    3.14  /* We reserve 16MB at the top of the 4GB memory hole. */
    3.15  #define RESERVED_MEMBASE    0xff000000
    3.16 @@ -28,6 +30,7 @@
    3.17  #define ROMBIOS_END            (ROMBIOS_BEGIN + ROMBIOS_SIZE)
    3.18  
    3.19  /* Memory map. */
    3.20 +#define SCRATCH_PHYSICAL_ADDRESS      0x00010000
    3.21  #define HYPERCALL_PHYSICAL_ADDRESS    0x00080000
    3.22  #define VGABIOS_PHYSICAL_ADDRESS      0x000C0000
    3.23  #define OPTIONROM_PHYSICAL_ADDRESS    0x000C8000
    3.24 @@ -37,7 +40,6 @@
    3.25  #define SMBIOS_PHYSICAL_ADDRESS       0x000EB000
    3.26  #define SMBIOS_MAXIMUM_SIZE           0x00005000
    3.27  #define ROMBIOS_PHYSICAL_ADDRESS      0x000F0000
    3.28 -#define SCRATCH_PHYSICAL_ADDRESS      0x00010000
    3.29  
    3.30  /* Offsets from E820_PHYSICAL_ADDRESS. */
    3.31  #define E820_NR_OFFSET                0x0
     4.1 --- a/tools/firmware/hvmloader/hvmloader.c	Fri Jan 09 11:44:35 2009 +0000
     4.2 +++ b/tools/firmware/hvmloader/hvmloader.c	Fri Jan 09 12:41:25 2009 +0000
     4.3 @@ -31,6 +31,7 @@
     4.4  #include "option_rom.h"
     4.5  #include <xen/version.h>
     4.6  #include <xen/hvm/params.h>
     4.7 +#include <xen/memory.h>
     4.8  
     4.9  asm (
    4.10      "    .text                       \n"
    4.11 @@ -99,6 +100,9 @@ asm (
    4.12      "    .text                       \n"
    4.13      );
    4.14  
    4.15 +unsigned long pci_mem_start = PCI_MEM_START;
    4.16 +unsigned long pci_mem_end = PCI_MEM_END;
    4.17 +
    4.18  static enum { VGA_none, VGA_std, VGA_cirrus } virtual_vga = VGA_none;
    4.19  
    4.20  static void init_hypercalls(void)
    4.21 @@ -148,16 +152,14 @@ static void apic_setup(void)
    4.22  
    4.23  static void pci_setup(void)
    4.24  {
    4.25 -    uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd;
    4.26 +    uint32_t base, devfn, bar_reg, bar_data, bar_sz, cmd, mmio_total = 0;
    4.27      uint16_t class, vendor_id, device_id;
    4.28      unsigned int bar, pin, link, isa_irq;
    4.29  
    4.30      /* Resources assignable to PCI devices via BARs. */
    4.31      struct resource {
    4.32          uint32_t base, max;
    4.33 -    } *resource;
    4.34 -    struct resource mem_resource = { PCI_MEMBASE, PCI_MEMBASE + PCI_MEMSIZE };
    4.35 -    struct resource io_resource  = { 0xc000, 0x10000 };
    4.36 +    } *resource, mem_resource, io_resource;
    4.37  
    4.38      /* Create a list of device BARs in descending order of size. */
    4.39      struct bars {
    4.40 @@ -248,6 +250,10 @@ static void pci_setup(void)
    4.41              bars[i].bar_reg = bar_reg;
    4.42              bars[i].bar_sz  = bar_sz;
    4.43  
    4.44 +            if ( (bar_data & PCI_BASE_ADDRESS_SPACE) ==
    4.45 +                 PCI_BASE_ADDRESS_SPACE_MEMORY )
    4.46 +                mmio_total += bar_sz;
    4.47 +
    4.48              nr_bars++;
    4.49  
    4.50              /* Skip the upper-half of the address for a 64-bit BAR. */
    4.51 @@ -276,6 +282,28 @@ static void pci_setup(void)
    4.52          pci_writew(devfn, PCI_COMMAND, cmd);
    4.53      }
    4.54  
    4.55 +    while ( (mmio_total > (pci_mem_end - pci_mem_start)) &&
    4.56 +            ((pci_mem_start << 1) != 0) )
    4.57 +        pci_mem_start <<= 1;
    4.58 +
    4.59 +    while ( (pci_mem_start >> PAGE_SHIFT) < hvm_info->low_mem_pgend )
    4.60 +    {
    4.61 +        struct xen_add_to_physmap xatp;
    4.62 +        if ( hvm_info->high_mem_pgend == 0 )
    4.63 +            hvm_info->high_mem_pgend = 1ull << (32 - PAGE_SHIFT);
    4.64 +        xatp.domid = DOMID_SELF;
    4.65 +        xatp.space = XENMAPSPACE_gmfn;
    4.66 +        xatp.idx   = --hvm_info->low_mem_pgend;
    4.67 +        xatp.gpfn  = hvm_info->high_mem_pgend++;
    4.68 +        if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 )
    4.69 +            BUG();
    4.70 +    }
    4.71 +
    4.72 +    mem_resource.base = pci_mem_start;
    4.73 +    mem_resource.max = pci_mem_end;
    4.74 +    io_resource.base = 0xc000;
    4.75 +    io_resource.max = 0x10000;
    4.76 +
    4.77      /* Assign iomem and ioport resources in descending order of size. */
    4.78      for ( i = 0; i < nr_bars; i++ )
    4.79      {
    4.80 @@ -625,6 +653,9 @@ int main(void)
    4.81  
    4.82      printf("CPU speed is %u MHz\n", get_cpu_mhz());
    4.83  
    4.84 +    apic_setup();
    4.85 +    pci_setup();
    4.86 +
    4.87      smp_initialise();
    4.88  
    4.89      perform_tests();
    4.90 @@ -639,9 +670,6 @@ int main(void)
    4.91      memcpy((void *)ROMBIOS_PHYSICAL_ADDRESS, rombios, rombios_sz);
    4.92      highbios_setup();
    4.93  
    4.94 -    apic_setup();
    4.95 -    pci_setup();
    4.96 -
    4.97      if ( (hvm_info->nr_vcpus > 1) || hvm_info->apic_mode )
    4.98          create_mp_tables();
    4.99  
     5.1 --- a/tools/firmware/hvmloader/util.c	Fri Jan 09 11:44:35 2009 +0000
     5.2 +++ b/tools/firmware/hvmloader/util.c	Fri Jan 09 12:41:25 2009 +0000
     5.3 @@ -307,6 +307,7 @@ void *mem_alloc(uint32_t size, uint32_t 
     5.4  {
     5.5      static uint32_t reserve = RESERVED_MEMBASE - 1;
     5.6      static int over_allocated;
     5.7 +    struct xen_add_to_physmap xatp;
     5.8      struct xen_memory_reservation xmr;
     5.9      xen_pfn_t mfn;
    5.10      uint32_t s, e;
    5.11 @@ -323,36 +324,36 @@ void *mem_alloc(uint32_t size, uint32_t 
    5.12      while ( (reserve >> PAGE_SHIFT) != (e >> PAGE_SHIFT) )
    5.13      {
    5.14          reserve += PAGE_SIZE;
    5.15 +        mfn = reserve >> PAGE_SHIFT;
    5.16  
    5.17 -        /* Try to allocate another page in the reserved area. */
    5.18 -        xmr.domid = DOMID_SELF;
    5.19 -        xmr.mem_flags = 0;
    5.20 -        xmr.extent_order = 0;
    5.21 -        xmr.nr_extents = 1;
    5.22 -        set_xen_guest_handle(xmr.extent_start, &mfn);
    5.23 -        mfn = reserve >> PAGE_SHIFT;
    5.24 -        if ( !over_allocated &&
    5.25 -             (hypercall_memory_op(XENMEM_populate_physmap, &xmr) == 1) )
    5.26 -            continue;
    5.27 +        /* Try to allocate a brand new page in the reserved area. */
    5.28 +        if ( !over_allocated )
    5.29 +        {
    5.30 +            xmr.domid = DOMID_SELF;
    5.31 +            xmr.mem_flags = 0;
    5.32 +            xmr.extent_order = 0;
    5.33 +            xmr.nr_extents = 1;
    5.34 +            set_xen_guest_handle(xmr.extent_start, &mfn);
    5.35 +            if ( hypercall_memory_op(XENMEM_populate_physmap, &xmr) == 1 )
    5.36 +                continue;
    5.37 +            over_allocated = 1;
    5.38 +        }
    5.39  
    5.40 -        /* If we fail, steal a page from the ordinary RAM map. */
    5.41 -        over_allocated = 1;
    5.42 +        /* Otherwise, relocate a page from the ordinary RAM map. */
    5.43          if ( hvm_info->high_mem_pgend )
    5.44          {
    5.45 -            mfn = --hvm_info->high_mem_pgend;
    5.46 -            if ( mfn == (1ull << (32 - PAGE_SHIFT)) )
    5.47 +            xatp.idx = --hvm_info->high_mem_pgend;
    5.48 +            if ( xatp.idx == (1ull << (32 - PAGE_SHIFT)) )
    5.49                  hvm_info->high_mem_pgend = 0;
    5.50          }
    5.51          else
    5.52          {
    5.53 -            mfn = --hvm_info->low_mem_pgend;
    5.54 +            xatp.idx = --hvm_info->low_mem_pgend;
    5.55          }
    5.56 -        if ( hypercall_memory_op(XENMEM_decrease_reservation, &xmr) != 1 )
    5.57 -            BUG();
    5.58 -
    5.59 -        /* Now try the allocation again. Must not fail. */
    5.60 -        mfn = reserve >> PAGE_SHIFT;
    5.61 -        if ( hypercall_memory_op(XENMEM_populate_physmap, &xmr) != 1 )
    5.62 +        xatp.domid = DOMID_SELF;
    5.63 +        xatp.space = XENMAPSPACE_gmfn;
    5.64 +        xatp.gpfn  = mfn;
    5.65 +        if ( hypercall_memory_op(XENMEM_add_to_physmap, &xatp) != 0 )
    5.66              BUG();
    5.67      }
    5.68