qemu-devel.nongnu.org archive mirror
 help / color / mirror / Atom feed
* [Qemu-devel] [PATCH 0/3] pc: pass pci window data to guests
@ 2013-04-29 15:51 Michael S. Tsirkin
  2013-04-29 15:51 ` [Qemu-devel] [PATCH 1/3] range: add structure to pass ranges around Michael S. Tsirkin
                   ` (2 more replies)
  0 siblings, 3 replies; 4+ messages in thread
From: Michael S. Tsirkin @ 2013-04-29 15:51 UTC (permalink / raw)
  To: aliguori, qemu-devel, lersek, kevin

This makes it possible for bios to load pci window
data from host.

This makes it possible for host to make sure
setup matches hardware exactly: especially important
for when ACPI tables are loaded from host.
This will also make it easier to add more chipsets
down the road.



Michael S. Tsirkin (3):
  range: add structure to pass ranges around
  pc: factor out pci hole math
  pc: pass PCI hole ranges to Guests

 hw/i386/pc.c              | 34 +++++++++++++++++++++++++++++++---
 hw/i386/pc_piix.c         | 14 +++++++-------
 hw/i386/pc_q35.c          |  9 ++++++---
 hw/pci-host/q35.c         | 18 ++++++++----------
 include/hw/i386/pc.h      | 25 ++++++++++++++++++++++++-
 include/hw/pci-host/q35.h |  4 ++--
 include/qemu/range.h      | 24 ++++++++++++++++++++++++
 7 files changed, 102 insertions(+), 26 deletions(-)

-- 
MST

^ permalink raw reply	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH 1/3] range: add structure to pass ranges around
  2013-04-29 15:51 [Qemu-devel] [PATCH 0/3] pc: pass pci window data to guests Michael S. Tsirkin
@ 2013-04-29 15:51 ` Michael S. Tsirkin
  2013-04-29 15:51 ` [Qemu-devel] [PATCH 2/3] pc: factor out pci hole math Michael S. Tsirkin
  2013-04-29 15:51 ` [Qemu-devel] [PATCH 3/3] pc: pass PCI hole ranges to Guests Michael S. Tsirkin
  2 siblings, 0 replies; 4+ messages in thread
From: Michael S. Tsirkin @ 2013-04-29 15:51 UTC (permalink / raw)
  To: aliguori, qemu-devel, lersek, kevin

Convenient structure to pass ranges around,
and calculate length avoiding 64 bit overlap issues.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 include/qemu/range.h | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)

diff --git a/include/qemu/range.h b/include/qemu/range.h
index 3502372..aeef1fb 100644
--- a/include/qemu/range.h
+++ b/include/qemu/range.h
@@ -1,6 +1,30 @@
 #ifndef QEMU_RANGE_H
 #define QEMU_RANGE_H
 
+#include <inttypes.h>
+
+struct Range {
+    uint64_t min;
+    uint64_t max;
+};
+typedef struct Range Range;
+
+/* max <= min means not valid */
+static inline bool range_valid(Range *r)
+{
+    return r->max > r->min;
+}
+
+static inline uint64_t range_len(Range *r)
+{
+    return range_valid(r) ? r->max - r->min + 1 : 0;
+}
+
+static inline uint64_t range_start(Range *r)
+{
+    return r->min;
+}
+
 /* Get last byte of a range from offset + length.
  * Undefined for ranges that wrap around 0. */
 static inline uint64_t range_get_last(uint64_t offset, uint64_t len)
-- 
MST

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH 2/3] pc: factor out pci hole math
  2013-04-29 15:51 [Qemu-devel] [PATCH 0/3] pc: pass pci window data to guests Michael S. Tsirkin
  2013-04-29 15:51 ` [Qemu-devel] [PATCH 1/3] range: add structure to pass ranges around Michael S. Tsirkin
@ 2013-04-29 15:51 ` Michael S. Tsirkin
  2013-04-29 15:51 ` [Qemu-devel] [PATCH 3/3] pc: pass PCI hole ranges to Guests Michael S. Tsirkin
  2 siblings, 0 replies; 4+ messages in thread
From: Michael S. Tsirkin @ 2013-04-29 15:51 UTC (permalink / raw)
  To: aliguori, qemu-devel, lersek, kevin

Move common code for calculating ranges for 32 and 64 bit pci holes
for use by guest to pc.c.
Pass ranges to Q35/PIIX respectively.

Note: ranges are passed within a generic GuestInfo
structure, we are going to add more fields of interest
to Guests in the future.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/i386/pc.c              | 15 +++++++++++++++
 hw/i386/pc_piix.c         | 12 ++++++------
 hw/i386/pc_q35.c          |  7 +++++--
 hw/pci-host/q35.c         | 18 ++++++++----------
 include/hw/i386/pc.h      | 13 +++++++++++++
 include/hw/pci-host/q35.h |  4 ++--
 6 files changed, 49 insertions(+), 20 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 0b84aa4..fbea5d0 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -922,6 +922,21 @@ void pc_acpi_init(const char *default_dsdt)
     }
 }
 
+void pc_guest_info_init(PcGuestInfo *guest_info,
+                        ram_addr_t below_4g_mem_size,
+                        ram_addr_t above_4g_mem_size)
+{
+    guest_info->pci_info.w32.min = below_4g_mem_size;
+    guest_info->pci_info.w32.max = 0x100000000ULL - 0x1;
+    if (sizeof(hwaddr) == 4) {
+        guest_info->pci_info.w64.min = 0x100000000ULL + above_4g_mem_size;
+        guest_info->pci_info.w64.max =
+            range_get_last(guest_info->pci_info.w64.min, (0x1ULL << 62));
+    } else {
+        guest_info->pci_info.w64.min = guest_info->pci_info.w64.max =  0;
+    }
+}
+
 FWCfgState *pc_memory_init(MemoryRegion *system_memory,
                            const char *kernel_filename,
                            const char *kernel_cmdline,
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index da10e6d..539f72a 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -86,6 +86,7 @@ static void pc_init1(MemoryRegion *system_memory,
     MemoryRegion *pci_memory;
     MemoryRegion *rom_memory;
     FWCfgState *fw_cfg = NULL;
+    PcGuestInfo guest_info;
 
     pc_cpus_init(cpu_model);
     pc_acpi_init("acpi-dsdt.aml");
@@ -111,6 +112,7 @@ static void pc_init1(MemoryRegion *system_memory,
         rom_memory = system_memory;
     }
 
+    pc_guest_info_init(&guest_info, below_4g_mem_size, above_4g_mem_size);
     /* allocate ram and load rom/bios */
     if (!xen_enabled()) {
         fw_cfg = pc_memory_init(system_memory,
@@ -131,12 +133,10 @@ static void pc_init1(MemoryRegion *system_memory,
     if (pci_enabled) {
         pci_bus = i440fx_init(&i440fx_state, &piix3_devfn, &isa_bus, gsi,
                               system_memory, system_io, ram_size,
-                              below_4g_mem_size,
-                              0x100000000ULL - below_4g_mem_size,
-                              0x100000000ULL + above_4g_mem_size,
-                              (sizeof(hwaddr) == 4
-                               ? 0
-                               : ((uint64_t)1 << 62)),
+                              range_start(&guest_info.pci_info.w32),
+                              range_len(&guest_info.pci_info.w32),
+                              range_start(&guest_info.pci_info.w64),
+                              range_len(&guest_info.pci_info.w64),
                               pci_memory, ram_memory);
     } else {
         pci_bus = NULL;
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 6ac1a89..50dc14d 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -85,6 +85,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
     ICH9LPCState *ich9_lpc;
     PCIDevice *ahci;
     qemu_irq *cmos_s3;
+    PcGuestInfo guest_info;
 
     pc_cpus_init(cpu_model);
     pc_acpi_init("q35-acpi-dsdt.aml");
@@ -109,6 +110,8 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
         rom_memory = get_system_memory();
     }
 
+    pc_guest_info_init(&guest_info, below_4g_mem_size, above_4g_mem_size);
+
     /* allocate ram and load rom/bios */
     if (!xen_enabled()) {
         pc_memory_init(get_system_memory(), kernel_filename, kernel_cmdline,
@@ -133,8 +136,8 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
     q35_host->mch.pci_address_space = pci_memory;
     q35_host->mch.system_memory = get_system_memory();
     q35_host->mch.address_space_io = get_system_io();;
-    q35_host->mch.below_4g_mem_size = below_4g_mem_size;
-    q35_host->mch.above_4g_mem_size = above_4g_mem_size;
+    q35_host->mch.below_4g_mem_range = guest_info.pci_info.w32;
+    q35_host->mch.above_4g_mem_range = guest_info.pci_info.w64;
     /* pci */
     qdev_init_nofail(DEVICE(q35_host));
     host_bus = q35_host->host.pci.bus;
diff --git a/hw/pci-host/q35.c b/hw/pci-host/q35.c
index 8467f86..c951255 100644
--- a/hw/pci-host/q35.c
+++ b/hw/pci-host/q35.c
@@ -240,25 +240,23 @@ static void mch_reset(DeviceState *qdev)
 static int mch_init(PCIDevice *d)
 {
     int i;
-    hwaddr pci_hole64_size;
     MCHPCIState *mch = MCH_PCI_DEVICE(d);
 
     /* setup pci memory regions */
     memory_region_init_alias(&mch->pci_hole, "pci-hole",
                              mch->pci_address_space,
-                             mch->below_4g_mem_size,
-                             0x100000000ULL - mch->below_4g_mem_size);
-    memory_region_add_subregion(mch->system_memory, mch->below_4g_mem_size,
+                             range_start(&mch->below_4g_mem_range),
+                             range_len(&mch->below_4g_mem_range));
+    memory_region_add_subregion(mch->system_memory,
+                                range_len(&mch->below_4g_mem_range),
                                 &mch->pci_hole);
-    pci_hole64_size = (sizeof(hwaddr) == 4 ? 0 :
-                       ((uint64_t)1 << 62));
     memory_region_init_alias(&mch->pci_hole_64bit, "pci-hole64",
                              mch->pci_address_space,
-                             0x100000000ULL + mch->above_4g_mem_size,
-                             pci_hole64_size);
-    if (pci_hole64_size) {
+                             range_start(&mch->above_4g_mem_range),
+                             range_len(&mch->above_4g_mem_range));
+    if (range_valid(&mch->above_4g_mem_range)) {
         memory_region_add_subregion(mch->system_memory,
-                                    0x100000000ULL + mch->above_4g_mem_size,
+                                    range_len(&mch->above_4g_mem_range),
                                     &mch->pci_hole_64bit);
     }
     /* smram */
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index a65c6a0..cf3b263 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -10,9 +10,19 @@
 #include "exec/memory.h"
 #include "hw/i386/ioapic.h"
 #include "hw/nvram/fw_cfg.h"
+#include "qemu/range.h"
 
 /* PC-style peripherals (also used by other machines).  */
 
+typedef struct PciGuestInfo {
+    Range w32;
+    Range w64;
+} PciGuestInfo;
+
+typedef struct PcGuestInfo {
+    PciGuestInfo pci_info;
+} PcGuestInfo;
+
 /* parallel.c */
 static inline bool parallel_init(ISABus *bus, int index, CharDriverState *chr)
 {
@@ -81,6 +91,9 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
 
 void pc_cpus_init(const char *cpu_model);
 void pc_acpi_init(const char *default_dsdt);
+void pc_guest_info_init(PcGuestInfo *guest_info,
+                        ram_addr_t below_4g_mem_size,
+                        ram_addr_t above_4g_mem_size);
 FWCfgState *pc_memory_init(MemoryRegion *system_memory,
                            const char *kernel_filename,
                            const char *kernel_cmdline,
diff --git a/include/hw/pci-host/q35.h b/include/hw/pci-host/q35.h
index e182c82..2766b6a 100644
--- a/include/hw/pci-host/q35.h
+++ b/include/hw/pci-host/q35.h
@@ -53,8 +53,8 @@ typedef struct MCHPCIState {
     MemoryRegion pci_hole;
     MemoryRegion pci_hole_64bit;
     uint8_t smm_enabled;
-    ram_addr_t below_4g_mem_size;
-    ram_addr_t above_4g_mem_size;
+    Range below_4g_mem_range;
+    Range above_4g_mem_range;
 } MCHPCIState;
 
 typedef struct Q35PCIHost {
-- 
MST

^ permalink raw reply related	[flat|nested] 4+ messages in thread

* [Qemu-devel] [PATCH 3/3] pc: pass PCI hole ranges to Guests
  2013-04-29 15:51 [Qemu-devel] [PATCH 0/3] pc: pass pci window data to guests Michael S. Tsirkin
  2013-04-29 15:51 ` [Qemu-devel] [PATCH 1/3] range: add structure to pass ranges around Michael S. Tsirkin
  2013-04-29 15:51 ` [Qemu-devel] [PATCH 2/3] pc: factor out pci hole math Michael S. Tsirkin
@ 2013-04-29 15:51 ` Michael S. Tsirkin
  2 siblings, 0 replies; 4+ messages in thread
From: Michael S. Tsirkin @ 2013-04-29 15:51 UTC (permalink / raw)
  To: aliguori, qemu-devel, lersek, kevin

Guest currently has to jump through lots of
hoops to guess the PCI hole ranges.
It's fragile, and makes us change BIOS each time we add a new chipset.
Let's report the window in a ROM file, to make
BIOS do exactly what QEMU intends.

Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
---
 hw/i386/pc.c         | 19 ++++++++++++++++---
 hw/i386/pc_piix.c    |  2 +-
 hw/i386/pc_q35.c     |  2 +-
 include/hw/i386/pc.h | 18 ++++++++++++++----
 4 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index fbea5d0..35c0dd9 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -567,7 +567,7 @@ static unsigned int pc_apic_id_limit(unsigned int max_cpus)
     return x86_cpu_apic_id_from_index(max_cpus - 1) + 1;
 }
 
-static FWCfgState *bochs_bios_init(void)
+static FWCfgState *bochs_bios_init(PcGuestInfo *guest_info)
 {
     FWCfgState *fw_cfg;
     uint8_t *smbios_table;
@@ -629,6 +629,9 @@ static FWCfgState *bochs_bios_init(void)
                      (1 + apic_id_limit + nb_numa_nodes) *
                      sizeof(*numa_fw_cfg));
 
+    fw_cfg_add_file(fw_cfg, "etc/pci-info", guest_info->pci_info_rom,
+                    sizeof *guest_info->pci_info_rom);
+
     return fw_cfg;
 }
 
@@ -926,6 +929,8 @@ void pc_guest_info_init(PcGuestInfo *guest_info,
                         ram_addr_t below_4g_mem_size,
                         ram_addr_t above_4g_mem_size)
 {
+    PcRomPciInfo *pci_info;
+
     guest_info->pci_info.w32.min = below_4g_mem_size;
     guest_info->pci_info.w32.max = 0x100000000ULL - 0x1;
     if (sizeof(hwaddr) == 4) {
@@ -935,6 +940,13 @@ void pc_guest_info_init(PcGuestInfo *guest_info,
     } else {
         guest_info->pci_info.w64.min = guest_info->pci_info.w64.max =  0;
     }
+
+    guest_info->pci_info_rom = pci_info = g_malloc0(sizeof *pci_info);
+    pci_info->w32_min = cpu_to_le64(guest_info->pci_info.w32.min);
+    pci_info->w32_max = cpu_to_le64(MIN(guest_info->pci_info.w32.max,
+                                        IO_APIC_DEFAULT_ADDRESS));
+    pci_info->w64_min = cpu_to_le64(guest_info->pci_info.w64.min);
+    pci_info->w64_max = cpu_to_le64(guest_info->pci_info.w64.max);
 }
 
 FWCfgState *pc_memory_init(MemoryRegion *system_memory,
@@ -944,7 +956,8 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
                            ram_addr_t below_4g_mem_size,
                            ram_addr_t above_4g_mem_size,
                            MemoryRegion *rom_memory,
-                           MemoryRegion **ram_memory)
+                           MemoryRegion **ram_memory,
+                           PcGuestInfo *guest_info)
 {
     int linux_boot, i;
     MemoryRegion *ram, *option_rom_mr;
@@ -986,7 +999,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
                                         option_rom_mr,
                                         1);
 
-    fw_cfg = bochs_bios_init();
+    fw_cfg = bochs_bios_init(guest_info);
     rom_set_fw(fw_cfg);
 
     if (linux_boot) {
diff --git a/hw/i386/pc_piix.c b/hw/i386/pc_piix.c
index 539f72a..524ce9b 100644
--- a/hw/i386/pc_piix.c
+++ b/hw/i386/pc_piix.c
@@ -118,7 +118,7 @@ static void pc_init1(MemoryRegion *system_memory,
         fw_cfg = pc_memory_init(system_memory,
                        kernel_filename, kernel_cmdline, initrd_filename,
                        below_4g_mem_size, above_4g_mem_size,
-                       rom_memory, &ram_memory);
+                       rom_memory, &ram_memory, &guest_info);
     }
 
     gsi_state = g_malloc0(sizeof(*gsi_state));
diff --git a/hw/i386/pc_q35.c b/hw/i386/pc_q35.c
index 50dc14d..5ac4f33 100644
--- a/hw/i386/pc_q35.c
+++ b/hw/i386/pc_q35.c
@@ -116,7 +116,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
     if (!xen_enabled()) {
         pc_memory_init(get_system_memory(), kernel_filename, kernel_cmdline,
                        initrd_filename, below_4g_mem_size, above_4g_mem_size,
-                       rom_memory, &ram_memory);
+                       rom_memory, &ram_memory, &guest_info);
     }
 
     /* irq lines */
diff --git a/include/hw/i386/pc.h b/include/hw/i386/pc.h
index cf3b263..afd494f 100644
--- a/include/hw/i386/pc.h
+++ b/include/hw/i386/pc.h
@@ -14,13 +14,22 @@
 
 /* PC-style peripherals (also used by other machines).  */
 
-typedef struct PciGuestInfo {
+typedef struct PcPciInfo {
     Range w32;
     Range w64;
-} PciGuestInfo;
+} PcPciInfo;
+
+/* pci-info ROM file. Little endian format */
+typedef struct PcRomPciInfo {
+    uint64_t w32_min;
+    uint64_t w32_max;
+    uint64_t w64_min;
+    uint64_t w64_max;
+} PcRomPciInfo;
 
 typedef struct PcGuestInfo {
-    PciGuestInfo pci_info;
+    PcPciInfo pci_info;
+    PcRomPciInfo *pci_info_rom;
 } PcGuestInfo;
 
 /* parallel.c */
@@ -101,7 +110,8 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
                            ram_addr_t below_4g_mem_size,
                            ram_addr_t above_4g_mem_size,
                            MemoryRegion *rom_memory,
-                           MemoryRegion **ram_memory);
+                           MemoryRegion **ram_memory,
+                           PcGuestInfo *guest_info);
 qemu_irq *pc_allocate_cpu_irq(void);
 DeviceState *pc_vga_init(ISABus *isa_bus, PCIBus *pci_bus);
 void pc_basic_device_init(ISABus *isa_bus, qemu_irq *gsi,
-- 
MST

^ permalink raw reply related	[flat|nested] 4+ messages in thread

end of thread, other threads:[~2013-04-29 15:51 UTC | newest]

Thread overview: 4+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-04-29 15:51 [Qemu-devel] [PATCH 0/3] pc: pass pci window data to guests Michael S. Tsirkin
2013-04-29 15:51 ` [Qemu-devel] [PATCH 1/3] range: add structure to pass ranges around Michael S. Tsirkin
2013-04-29 15:51 ` [Qemu-devel] [PATCH 2/3] pc: factor out pci hole math Michael S. Tsirkin
2013-04-29 15:51 ` [Qemu-devel] [PATCH 3/3] pc: pass PCI hole ranges to Guests Michael S. Tsirkin

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).