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…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Michael S. Tsirkin
						Michael S. Tsirkin