1 /* 2 * QEMU SPAPR PCI BUS definitions 3 * 4 * Copyright (c) 2011 Alexey Kardashevskiy <aik@au1.ibm.com> 5 * 6 * This library is free software; you can redistribute it and/or 7 * modify it under the terms of the GNU Lesser General Public 8 * License as published by the Free Software Foundation; either 9 * version 2.1 of the License, or (at your option) any later version. 10 * 11 * This library is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14 * Lesser General Public License for more details. 15 * 16 * You should have received a copy of the GNU Lesser General Public 17 * License along with this library; if not, see <http://www.gnu.org/licenses/>. 18 */ 19 20 #ifndef PCI_HOST_SPAPR_H 21 #define PCI_HOST_SPAPR_H 22 23 #include "hw/ppc/spapr.h" 24 #include "hw/pci/pci.h" 25 #include "hw/pci/pci_host.h" 26 #include "hw/ppc/xics.h" 27 #include "qom/object.h" 28 29 #define TYPE_SPAPR_PCI_HOST_BRIDGE "spapr-pci-host-bridge" 30 31 OBJECT_DECLARE_SIMPLE_TYPE(SpaprPhbState, SPAPR_PCI_HOST_BRIDGE) 32 33 #define SPAPR_PCI_DMA_MAX_WINDOWS 2 34 35 36 typedef struct SpaprPciMsi { 37 uint32_t first_irq; 38 uint32_t num; 39 } SpaprPciMsi; 40 41 typedef struct SpaprPciMsiMig { 42 uint32_t key; 43 SpaprPciMsi value; 44 } SpaprPciMsiMig; 45 46 typedef struct SpaprPciLsi { 47 uint32_t irq; 48 } SpaprPciLsi; 49 50 struct SpaprPhbState { 51 PCIHostState parent_obj; 52 53 uint32_t index; 54 uint64_t buid; 55 char *dtbusname; 56 bool dr_enabled; 57 58 MemoryRegion memspace, iospace; 59 hwaddr mem_win_addr, mem_win_size, mem64_win_addr, mem64_win_size; 60 uint64_t mem64_win_pciaddr; 61 hwaddr io_win_addr, io_win_size; 62 MemoryRegion mem32window, mem64window, iowindow, msiwindow; 63 64 uint32_t dma_liobn[SPAPR_PCI_DMA_MAX_WINDOWS]; 65 hwaddr dma_win_addr, dma_win_size; 66 AddressSpace iommu_as; 67 MemoryRegion iommu_root; 68 69 SpaprPciLsi lsi_table[PCI_NUM_PINS]; 70 71 GHashTable *msi; 72 /* Temporary cache for migration purposes */ 73 int32_t msi_devs_num; 74 SpaprPciMsiMig *msi_devs; 75 76 QLIST_ENTRY(SpaprPhbState) list; 77 78 bool ddw_enabled; 79 uint64_t page_size_mask; 80 uint64_t dma64_win_addr; 81 82 uint32_t numa_node; 83 84 bool pcie_ecs; /* Allow access to PCIe extended config space? */ 85 86 /* Fields for migration compatibility hacks */ 87 bool pre_2_8_migration; 88 uint32_t mig_liobn; 89 hwaddr mig_mem_win_addr, mig_mem_win_size; 90 hwaddr mig_io_win_addr, mig_io_win_size; 91 bool pre_5_1_assoc; 92 }; 93 94 #define SPAPR_PCI_MEM_WIN_BUS_OFFSET 0x80000000ULL 95 #define SPAPR_PCI_MEM32_WIN_SIZE \ 96 ((1ULL << 32) - SPAPR_PCI_MEM_WIN_BUS_OFFSET) 97 #define SPAPR_PCI_MEM64_WIN_SIZE 0x10000000000ULL /* 1 TiB */ 98 99 /* All PCI outbound windows will be within this range */ 100 #define SPAPR_PCI_BASE (1ULL << 45) /* 32 TiB */ 101 #define SPAPR_PCI_LIMIT (1ULL << 46) /* 64 TiB */ 102 103 #define SPAPR_MAX_PHBS ((SPAPR_PCI_LIMIT - SPAPR_PCI_BASE) / \ 104 SPAPR_PCI_MEM64_WIN_SIZE - 1) 105 106 #define SPAPR_PCI_IO_WIN_SIZE 0x10000 107 108 #define SPAPR_PCI_MSI_WINDOW 0x40000000000ULL 109 110 int spapr_dt_phb(SpaprMachineState *spapr, SpaprPhbState *phb, 111 uint32_t intc_phandle, void *fdt, int *node_offset); 112 113 void spapr_pci_rtas_init(void); 114 115 SpaprPhbState *spapr_pci_find_phb(SpaprMachineState *spapr, uint64_t buid); 116 PCIDevice *spapr_pci_find_dev(SpaprMachineState *spapr, uint64_t buid, 117 uint32_t config_addr); 118 119 /* DRC callbacks */ 120 void spapr_phb_remove_pci_device_cb(DeviceState *dev); 121 int spapr_pci_dt_populate(SpaprDrc *drc, SpaprMachineState *spapr, 122 void *fdt, int *fdt_start_offset, Error **errp); 123 124 /* VFIO EEH hooks */ 125 #ifdef CONFIG_LINUX 126 bool spapr_phb_eeh_available(SpaprPhbState *sphb); 127 int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb, 128 unsigned int addr, int option); 129 int spapr_phb_vfio_eeh_get_state(SpaprPhbState *sphb, int *state); 130 int spapr_phb_vfio_eeh_reset(SpaprPhbState *sphb, int option); 131 int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb); 132 void spapr_phb_vfio_reset(DeviceState *qdev); 133 #else 134 static inline bool spapr_phb_eeh_available(SpaprPhbState *sphb) 135 { 136 return false; 137 } 138 static inline int spapr_phb_vfio_eeh_set_option(SpaprPhbState *sphb, 139 unsigned int addr, int option) 140 { 141 return RTAS_OUT_HW_ERROR; 142 } 143 static inline int spapr_phb_vfio_eeh_get_state(SpaprPhbState *sphb, 144 int *state) 145 { 146 return RTAS_OUT_HW_ERROR; 147 } 148 static inline int spapr_phb_vfio_eeh_reset(SpaprPhbState *sphb, int option) 149 { 150 return RTAS_OUT_HW_ERROR; 151 } 152 static inline int spapr_phb_vfio_eeh_configure(SpaprPhbState *sphb) 153 { 154 return RTAS_OUT_HW_ERROR; 155 } 156 static inline void spapr_phb_vfio_reset(DeviceState *qdev) 157 { 158 } 159 #endif 160 161 void spapr_phb_dma_reset(SpaprPhbState *sphb); 162 163 static inline unsigned spapr_phb_windows_supported(SpaprPhbState *sphb) 164 { 165 return sphb->ddw_enabled ? SPAPR_PCI_DMA_MAX_WINDOWS : 1; 166 } 167 168 char *spapr_pci_fw_dev_name(PCIDevice *dev); 169 170 #endif /* PCI_HOST_SPAPR_H */ 171