@@ -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,
@@ -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;
@@ -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;
@@ -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 */
@@ -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,
@@ -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 {
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(-)