* [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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.