* [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).