summaryrefslogtreecommitdiffstats
path: root/hw/i386/pc.c
diff options
context:
space:
mode:
authorMichael S. Tsirkin <mst@redhat.com>2013-05-30 12:57:26 +0300
committerMichael S. Tsirkin <mst@redhat.com>2013-07-04 10:40:56 +0300
commit3459a625215449b67b9c67d9151ff72892d0a42a (patch)
tree2f22e21c03a15b418a94b4d91db8fdaa711ce76a /hw/i386/pc.c
parent620ac82eb0fc4218fb6a4937bcef3fdab3126703 (diff)
downloadhqemu-3459a625215449b67b9c67d9151ff72892d0a42a.zip
hqemu-3459a625215449b67b9c67d9151ff72892d0a42a.tar.gz
pci: store PCI hole ranges in guestinfo structure
Will be used to pass hole ranges to guests. Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Diffstat (limited to 'hw/i386/pc.c')
-rw-r--r--hw/i386/pc.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/hw/i386/pc.c b/hw/i386/pc.c
index 78f92e2..8af1e4e 100644
--- a/hw/i386/pc.c
+++ b/hw/i386/pc.c
@@ -989,6 +989,48 @@ void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge)
}
}
+typedef struct PcGuestInfoState {
+ PcGuestInfo info;
+ Notifier machine_done;
+} PcGuestInfoState;
+
+static
+void pc_guest_info_machine_done(Notifier *notifier, void *data)
+{
+ PcGuestInfoState *guest_info_state = container_of(notifier,
+ PcGuestInfoState,
+ machine_done);
+}
+
+PcGuestInfo *pc_guest_info_init(ram_addr_t below_4g_mem_size,
+ ram_addr_t above_4g_mem_size)
+{
+ PcGuestInfoState *guest_info_state = g_malloc0(sizeof *guest_info_state);
+ PcGuestInfo *guest_info = &guest_info_state->info;
+
+ guest_info->pci_info.w32.end = IO_APIC_DEFAULT_ADDRESS;
+ if (sizeof(hwaddr) == 4) {
+ guest_info->pci_info.w64.begin = 0;
+ guest_info->pci_info.w64.end = 0;
+ } else {
+ /*
+ * BIOS does not set MTRR entries for the 64 bit window, so no need to
+ * align address to power of two. Align address at 1G, this makes sure
+ * it can be exactly covered with a PAT entry even when using huge
+ * pages.
+ */
+ guest_info->pci_info.w64.begin =
+ ROUND_UP((0x1ULL << 32) + above_4g_mem_size, 0x1ULL << 30);
+ guest_info->pci_info.w64.end = guest_info->pci_info.w64.begin +
+ (0x1ULL << 62);
+ assert(guest_info->pci_info.w64.begin <= guest_info->pci_info.w64.end);
+ }
+
+ guest_info_state->machine_done.notify = pc_guest_info_machine_done;
+ qemu_add_machine_init_done_notifier(&guest_info_state->machine_done);
+ return guest_info;
+}
+
void pc_acpi_init(const char *default_dsdt)
{
char *filename;
@@ -1030,7 +1072,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;
@@ -1082,6 +1125,7 @@ FWCfgState *pc_memory_init(MemoryRegion *system_memory,
for (i = 0; i < nb_option_roms; i++) {
rom_add_option(option_rom[i].name, option_rom[i].bootindex);
}
+ guest_info->fw_cfg = fw_cfg;
return fw_cfg;
}
OpenPOWER on IntegriCloud