Patchwork [seabios,4/5] pciinit: make pci ressources configurable

login
register
mail settings
Submitter Gerd Hoffmann
Date May 4, 2012, 8:21 a.m.
Message ID <1336119687-6295-5-git-send-email-kraxel@redhat.com>
Download mbox | patch
Permalink /patch/156814/
State New
Headers show

Comments

Gerd Hoffmann - May 4, 2012, 8:21 a.m.
Try to get the pci window information from the qemu firmware config
interface and use them if available, otherwise fall back to the compile
time defaults.

Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
---
 src/paravirt.c |    8 ++++++++
 src/paravirt.h |    2 ++
 src/pciinit.c  |   29 ++++++++++++++++++++++++-----
 3 files changed, 34 insertions(+), 5 deletions(-)

Patch

diff --git a/src/paravirt.c b/src/paravirt.c
index 9cf77de..61ed086 100644
--- a/src/paravirt.c
+++ b/src/paravirt.c
@@ -305,6 +305,14 @@  u16 qemu_cfg_get_max_cpus(void)
     return cnt;
 }
 
+void qemu_cfg_get_pci_windows(u64 *pcimem)
+{
+    if (!qemu_cfg_present)
+        return;
+
+    qemu_cfg_read_entry(pcimem, QEMU_CFG_PCI_WINDOWS, 64);
+}
+
 static QemuCfgFile LastFile;
 
 static u32
diff --git a/src/paravirt.h b/src/paravirt.h
index f39e226..6dc8ede 100644
--- a/src/paravirt.h
+++ b/src/paravirt.h
@@ -35,6 +35,7 @@  static inline int kvm_para_available(void)
 #define QEMU_CFG_BOOT_MENU              0x0e
 #define QEMU_CFG_MAX_CPUS               0x0f
 #define QEMU_CFG_FILE_DIR               0x19
+#define QEMU_CFG_PCI_WINDOWS            0x1a
 #define QEMU_CFG_ARCH_LOCAL             0x8000
 #define QEMU_CFG_ACPI_TABLES            (QEMU_CFG_ARCH_LOCAL + 0)
 #define QEMU_CFG_SMBIOS_ENTRIES         (QEMU_CFG_ARCH_LOCAL + 1)
@@ -57,6 +58,7 @@  int qemu_cfg_smbios_load_external(int type, char **p, unsigned *nr_structs,
 int qemu_cfg_get_numa_nodes(void);
 void qemu_cfg_get_numa_data(u64 *data, int n);
 u16 qemu_cfg_get_max_cpus(void);
+void qemu_cfg_get_pci_windows(u64 *pcimem);
 
 typedef struct QemuCfgFile {
     u32  size;        /* file size */
diff --git a/src/pciinit.c b/src/pciinit.c
index 6a7a0d2..52c5b69 100644
--- a/src/pciinit.c
+++ b/src/pciinit.c
@@ -11,6 +11,7 @@ 
 #include "pci_ids.h" // PCI_VENDOR_ID_INTEL
 #include "pci_regs.h" // PCI_COMMAND
 #include "xen.h" // usingXen
+#include "paravirt.h" // qemu_cfg_get_pci_windows
 
 #define PCI_DEVICE_MEM_MIN     0x1000
 #define PCI_BRIDGE_IO_MIN      0x1000
@@ -29,6 +30,12 @@  static const char *region_type_name[] = {
     [ PCI_REGION_TYPE_PREFMEM ] = "prefmem",
 };
 
+static u64 pcimem[4];
+static u64 pcimem_start   = BUILD_PCIMEM_START;
+static u64 pcimem_end     = BUILD_PCIMEM_END;
+static u64 pcimem64_start = BUILD_PCIMEM64_START;
+static u64 pcimem64_end   = BUILD_PCIMEM64_END;
+
 struct pci_region_entry {
     struct pci_device *dev;
     int bar;
@@ -511,13 +518,13 @@  static int pci_bios_init_root_regions(struct pci_bus *bus)
     }
     u64 sum = pci_region_sum(r_end);
     u64 align = pci_region_align(r_end);
-    r_end->base = ALIGN_DOWN((BUILD_PCIMEM_END - sum), align);
+    r_end->base = ALIGN_DOWN((pcimem_end - sum), align);
     sum = pci_region_sum(r_start);
     align = pci_region_align(r_start);
     r_start->base = ALIGN_DOWN((r_end->base - sum), align);
 
-    if ((r_start->base < BUILD_PCIMEM_START) ||
-         (r_start->base > BUILD_PCIMEM_END))
+    if ((r_start->base < pcimem_start) ||
+         (r_start->base > pcimem_end))
         // Memory range requested is larger than available.
         return -1;
     return 0;
@@ -595,11 +602,11 @@  static void pci_bios_map_devices(struct pci_bus *busses)
         if (pci_bios_init_root_regions(busses))
             panic("PCI: out of 32bit address space\n");
 
-        r64_mem.base = BUILD_PCIMEM64_START;
+        r64_mem.base = pcimem64_start;
         u64 sum = pci_region_sum(&r64_mem);
         u64 align = pci_region_align(&r64_pref);
         r64_pref.base = ALIGN(r64_mem.base + sum, align);
-        if (r64_pref.base + pci_region_sum(&r64_pref) > BUILD_PCIMEM64_END)
+        if (r64_pref.base + pci_region_sum(&r64_pref) > pcimem64_end)
             panic("PCI: out of 64bit address space\n");
         pci_region_map_entries(busses, &r64_mem);
         pci_region_map_entries(busses, &r64_pref);
@@ -629,6 +636,18 @@  pci_setup(void)
 
     dprintf(3, "pci setup\n");
 
+    qemu_cfg_get_pci_windows(pcimem);
+    if (pcimem[0] && pcimem[1]) {
+        pcimem_start = pcimem[0];
+        pcimem_end = pcimem[1] + 1;
+        dprintf(1, "32bit pci window: %llx - %llx\n", pcimem_start, pcimem_end);
+    }
+    if (pcimem[2] && pcimem[3]) {
+        pcimem64_start = pcimem[2];
+        pcimem64_end = pcimem[3] + 1;
+        dprintf(1, "64bit pci window: %llx - %llx\n", pcimem64_start, pcimem64_end);
+    }
+
     dprintf(1, "=== PCI bus & bridge init ===\n");
     if (pci_probe_host() != 0) {
         return;