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>
This commit is contained in:
		
							parent
							
								
									620ac82eb0
								
							
						
					
					
						commit
						3459a62521
					
				
							
								
								
									
										46
									
								
								hw/i386/pc.c
								
								
								
								
							
							
						
						
									
										46
									
								
								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;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -90,6 +90,7 @@ static void pc_init1(MemoryRegion *system_memory,
 | 
			
		|||
    MemoryRegion *rom_memory;
 | 
			
		||||
    DeviceState *icc_bridge;
 | 
			
		||||
    FWCfgState *fw_cfg = NULL;
 | 
			
		||||
    PcGuestInfo *guest_info;
 | 
			
		||||
 | 
			
		||||
    if (xen_enabled() && xen_hvm_init() != 0) {
 | 
			
		||||
        fprintf(stderr, "xen hardware virtual machine initialisation failed\n");
 | 
			
		||||
| 
						 | 
				
			
			@ -124,12 +125,23 @@ static void pc_init1(MemoryRegion *system_memory,
 | 
			
		|||
        rom_memory = system_memory;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    guest_info = pc_guest_info_init(below_4g_mem_size, above_4g_mem_size);
 | 
			
		||||
 | 
			
		||||
    /* Set PCI window size the way seabios has always done it. */
 | 
			
		||||
    /* Power of 2 so bios can cover it with a single MTRR */
 | 
			
		||||
    if (ram_size <= 0x80000000)
 | 
			
		||||
        guest_info->pci_info.w32.begin = 0x80000000;
 | 
			
		||||
    else if (ram_size <= 0xc0000000)
 | 
			
		||||
        guest_info->pci_info.w32.begin = 0xc0000000;
 | 
			
		||||
    else
 | 
			
		||||
        guest_info->pci_info.w32.begin = 0xe0000000;
 | 
			
		||||
 | 
			
		||||
    /* allocate ram and load rom/bios */
 | 
			
		||||
    if (!xen_enabled()) {
 | 
			
		||||
        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));
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,6 +77,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 | 
			
		|||
    ICH9LPCState *ich9_lpc;
 | 
			
		||||
    PCIDevice *ahci;
 | 
			
		||||
    DeviceState *icc_bridge;
 | 
			
		||||
    PcGuestInfo *guest_info;
 | 
			
		||||
 | 
			
		||||
    icc_bridge = qdev_create(NULL, TYPE_ICC_BRIDGE);
 | 
			
		||||
    object_property_add_child(qdev_get_machine(), "icc-bridge",
 | 
			
		||||
| 
						 | 
				
			
			@ -105,11 +106,13 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 | 
			
		|||
        rom_memory = get_system_memory();
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    guest_info = pc_guest_info_init(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,
 | 
			
		||||
                       initrd_filename, below_4g_mem_size, above_4g_mem_size,
 | 
			
		||||
                       rom_memory, &ram_memory);
 | 
			
		||||
                       rom_memory, &ram_memory, guest_info);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* irq lines */
 | 
			
		||||
| 
						 | 
				
			
			@ -131,6 +134,7 @@ static void pc_q35_init(QEMUMachineInitArgs *args)
 | 
			
		|||
    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.guest_info = guest_info;
 | 
			
		||||
    /* pci */
 | 
			
		||||
    qdev_init_nofail(DEVICE(q35_host));
 | 
			
		||||
    host_bus = q35_host->host.pci.bus;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -244,6 +244,14 @@ static int mch_init(PCIDevice *d)
 | 
			
		|||
    hwaddr pci_hole64_size;
 | 
			
		||||
    MCHPCIState *mch = MCH_PCI_DEVICE(d);
 | 
			
		||||
 | 
			
		||||
    /* Leave enough space for the biggest MCFG BAR */
 | 
			
		||||
    /* TODO: this matches current bios behaviour, but
 | 
			
		||||
     * it's not a power of two, which means an MTRR
 | 
			
		||||
     * can't cover it exactly.
 | 
			
		||||
     */
 | 
			
		||||
    mch->guest_info->pci_info.w32.begin = MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT +
 | 
			
		||||
        MCH_HOST_BRIDGE_PCIEXBAR_MAX;
 | 
			
		||||
 | 
			
		||||
    /* setup pci memory regions */
 | 
			
		||||
    memory_region_init_alias(&mch->pci_hole, "pci-hole",
 | 
			
		||||
                             mch->pci_address_space,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -9,8 +9,20 @@
 | 
			
		|||
#include "net/net.h"
 | 
			
		||||
#include "hw/i386/ioapic.h"
 | 
			
		||||
 | 
			
		||||
#include "qemu/range.h"
 | 
			
		||||
 | 
			
		||||
/* PC-style peripherals (also used by other machines).  */
 | 
			
		||||
 | 
			
		||||
typedef struct PcPciInfo {
 | 
			
		||||
    Range w32;
 | 
			
		||||
    Range w64;
 | 
			
		||||
} PcPciInfo;
 | 
			
		||||
 | 
			
		||||
struct PcGuestInfo {
 | 
			
		||||
    PcPciInfo pci_info;
 | 
			
		||||
    FWCfgState *fw_cfg;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
/* parallel.c */
 | 
			
		||||
static inline bool parallel_init(ISABus *bus, int index, CharDriverState *chr)
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -82,6 +94,10 @@ void pc_acpi_smi_interrupt(void *opaque, int irq, int level);
 | 
			
		|||
void pc_cpus_init(const char *cpu_model, DeviceState *icc_bridge);
 | 
			
		||||
void pc_hot_add_cpu(const int64_t id, Error **errp);
 | 
			
		||||
void pc_acpi_init(const char *default_dsdt);
 | 
			
		||||
 | 
			
		||||
PcGuestInfo *pc_guest_info_init(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,
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +105,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,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -55,6 +55,7 @@ typedef struct MCHPCIState {
 | 
			
		|||
    uint8_t smm_enabled;
 | 
			
		||||
    ram_addr_t below_4g_mem_size;
 | 
			
		||||
    ram_addr_t above_4g_mem_size;
 | 
			
		||||
    PcGuestInfo *guest_info;
 | 
			
		||||
} MCHPCIState;
 | 
			
		||||
 | 
			
		||||
typedef struct Q35PCIHost {
 | 
			
		||||
| 
						 | 
				
			
			@ -81,6 +82,7 @@ typedef struct Q35PCIHost {
 | 
			
		|||
#define MCH_HOST_BRIDGE_PCIEXBAR               0x60    /* 64bit register */
 | 
			
		||||
#define MCH_HOST_BRIDGE_PCIEXBAR_SIZE          8       /* 64bit register */
 | 
			
		||||
#define MCH_HOST_BRIDGE_PCIEXBAR_DEFAULT       0xb0000000
 | 
			
		||||
#define MCH_HOST_BRIDGE_PCIEXBAR_MAX           (0x10000000) /* 256M */
 | 
			
		||||
#define MCH_HOST_BRIDGE_PCIEXBAR_ADMSK         Q35_MASK(64, 35, 28)
 | 
			
		||||
#define MCH_HOST_BRIDGE_PCIEXBAR_128ADMSK      ((uint64_t)(1 << 26))
 | 
			
		||||
#define MCH_HOST_BRIDGE_PCIEXBAR_64ADMSK       ((uint64_t)(1 << 25))
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -64,5 +64,6 @@ typedef struct VirtIODevice VirtIODevice;
 | 
			
		|||
typedef struct QEMUSGList QEMUSGList;
 | 
			
		||||
typedef struct SHPCDevice SHPCDevice;
 | 
			
		||||
typedef struct FWCfgState FWCfgState;
 | 
			
		||||
typedef struct PcGuestInfo PcGuestInfo;
 | 
			
		||||
 | 
			
		||||
#endif /* QEMU_TYPEDEFS_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue