1 /* 2 * Copyright (c) 2007, Neocleus Corporation. 3 * Copyright (c) 2007, Intel Corporation. 4 * 5 * SPDX-License-Identifier: GPL-2.0-only 6 * 7 * Alex Novik <alex@neocleus.com> 8 * Allen Kay <allen.m.kay@intel.com> 9 * Guy Zana <guy@neocleus.com> 10 */ 11 #ifndef XEN_PT_H 12 #define XEN_PT_H 13 14 #include "hw/xen/xen_native.h" 15 #include "xen-host-pci-device.h" 16 #include "qom/object.h" 17 18 void xen_pt_log(const PCIDevice *d, const char *f, ...) G_GNUC_PRINTF(2, 3); 19 20 #define XEN_PT_ERR(d, _f, _a...) xen_pt_log(d, "%s: Error: "_f, __func__, ##_a) 21 22 #ifdef XEN_PT_LOGGING_ENABLED 23 # define XEN_PT_LOG(d, _f, _a...) xen_pt_log(d, "%s: " _f, __func__, ##_a) 24 # define XEN_PT_WARN(d, _f, _a...) \ 25 xen_pt_log(d, "%s: Warning: "_f, __func__, ##_a) 26 #else 27 # define XEN_PT_LOG(d, _f, _a...) 28 # define XEN_PT_WARN(d, _f, _a...) 29 #endif 30 31 #ifdef XEN_PT_DEBUG_PCI_CONFIG_ACCESS 32 # define XEN_PT_LOG_CONFIG(d, addr, val, len) \ 33 xen_pt_log(d, "%s: address=0x%04x val=0x%08x len=%d\n", \ 34 __func__, addr, val, len) 35 #else 36 # define XEN_PT_LOG_CONFIG(d, addr, val, len) 37 #endif 38 39 40 /* Helper */ 41 #define XEN_PFN(x) ((x) >> XC_PAGE_SHIFT) 42 43 typedef const struct XenPTRegInfo XenPTRegInfo; 44 typedef struct XenPTReg XenPTReg; 45 46 47 #define TYPE_XEN_PT_DEVICE "xen-pci-passthrough" 48 OBJECT_DECLARE_SIMPLE_TYPE(XenPCIPassthroughState, XEN_PT_DEVICE) 49 50 #define XEN_PT_DEVICE_CLASS(klass) \ 51 OBJECT_CLASS_CHECK(XenPTDeviceClass, klass, TYPE_XEN_PT_DEVICE) 52 #define XEN_PT_DEVICE_GET_CLASS(obj) \ 53 OBJECT_GET_CLASS(XenPTDeviceClass, obj, TYPE_XEN_PT_DEVICE) 54 55 typedef void (*XenPTQdevRealize)(DeviceState *qdev, Error **errp); 56 57 typedef struct XenPTDeviceClass { 58 PCIDeviceClass parent_class; 59 XenPTQdevRealize pci_qdev_realize; 60 } XenPTDeviceClass; 61 62 /* function type for config reg */ 63 typedef int (*xen_pt_conf_reg_init) 64 (XenPCIPassthroughState *, XenPTRegInfo *, uint32_t real_offset, 65 uint32_t *data); 66 typedef int (*xen_pt_conf_dword_write) 67 (XenPCIPassthroughState *, XenPTReg *cfg_entry, 68 uint32_t *val, uint32_t dev_value, uint32_t valid_mask); 69 typedef int (*xen_pt_conf_word_write) 70 (XenPCIPassthroughState *, XenPTReg *cfg_entry, 71 uint16_t *val, uint16_t dev_value, uint16_t valid_mask); 72 typedef int (*xen_pt_conf_byte_write) 73 (XenPCIPassthroughState *, XenPTReg *cfg_entry, 74 uint8_t *val, uint8_t dev_value, uint8_t valid_mask); 75 typedef int (*xen_pt_conf_dword_read) 76 (XenPCIPassthroughState *, XenPTReg *cfg_entry, 77 uint32_t *val, uint32_t valid_mask); 78 typedef int (*xen_pt_conf_word_read) 79 (XenPCIPassthroughState *, XenPTReg *cfg_entry, 80 uint16_t *val, uint16_t valid_mask); 81 typedef int (*xen_pt_conf_byte_read) 82 (XenPCIPassthroughState *, XenPTReg *cfg_entry, 83 uint8_t *val, uint8_t valid_mask); 84 85 #define XEN_PT_BAR_ALLF 0xFFFFFFFF 86 #define XEN_PT_BAR_UNMAPPED (-1) 87 88 #define XEN_PCI_CAP_MAX 48 89 90 #define XEN_PCI_INTEL_OPREGION 0xfc 91 92 #define XEN_PCI_IGD_DOMAIN 0 93 #define XEN_PCI_IGD_BUS 0 94 #define XEN_PCI_IGD_DEV 2 95 #define XEN_PCI_IGD_FN 0 96 #define XEN_PCI_IGD_SLOT_MASK \ 97 (1UL << PCI_SLOT(PCI_DEVFN(XEN_PCI_IGD_DEV, XEN_PCI_IGD_FN))) 98 99 typedef enum { 100 XEN_PT_GRP_TYPE_HARDWIRED = 0, /* 0 Hardwired reg group */ 101 XEN_PT_GRP_TYPE_EMU, /* emul reg group */ 102 } XenPTRegisterGroupType; 103 104 typedef enum { 105 XEN_PT_BAR_FLAG_MEM = 0, /* Memory type BAR */ 106 XEN_PT_BAR_FLAG_IO, /* I/O type BAR */ 107 XEN_PT_BAR_FLAG_UPPER, /* upper 64bit BAR */ 108 XEN_PT_BAR_FLAG_UNUSED, /* unused BAR */ 109 } XenPTBarFlag; 110 111 112 typedef struct XenPTRegion { 113 /* BAR flag */ 114 XenPTBarFlag bar_flag; 115 /* Translation of the emulated address */ 116 union { 117 uint64_t maddr; 118 uint64_t pio_base; 119 uint64_t u; 120 } access; 121 } XenPTRegion; 122 123 /* XenPTRegInfo declaration 124 * - only for emulated register (either a part or whole bit). 125 * - for passthrough register that need special behavior (like interacting with 126 * other component), set emu_mask to all 0 and specify r/w func properly. 127 * - do NOT use ALL F for init_val, otherwise the tbl will not be registered. 128 */ 129 130 /* emulated register information */ 131 struct XenPTRegInfo { 132 uint32_t offset; 133 uint32_t size; 134 uint32_t init_val; 135 /* reg reserved field mask (ON:reserved, OFF:defined) */ 136 uint32_t res_mask; 137 /* reg read only field mask (ON:RO/ROS, OFF:other) */ 138 uint32_t ro_mask; 139 /* reg read/write-1-clear field mask (ON:RW1C/RW1CS, OFF:other) */ 140 uint32_t rw1c_mask; 141 /* reg emulate field mask (ON:emu, OFF:passthrough) */ 142 uint32_t emu_mask; 143 xen_pt_conf_reg_init init; 144 /* read/write function pointer 145 * for double_word/word/byte size */ 146 union { 147 struct { 148 xen_pt_conf_dword_write write; 149 xen_pt_conf_dword_read read; 150 } dw; 151 struct { 152 xen_pt_conf_word_write write; 153 xen_pt_conf_word_read read; 154 } w; 155 struct { 156 xen_pt_conf_byte_write write; 157 xen_pt_conf_byte_read read; 158 } b; 159 } u; 160 }; 161 162 /* emulated register management */ 163 struct XenPTReg { 164 QLIST_ENTRY(XenPTReg) entries; 165 XenPTRegInfo *reg; 166 union { 167 uint8_t *byte; 168 uint16_t *half_word; 169 uint32_t *word; 170 } ptr; /* pointer to dev.config. */ 171 }; 172 173 typedef const struct XenPTRegGroupInfo XenPTRegGroupInfo; 174 175 /* emul reg group size initialize method */ 176 typedef int (*xen_pt_reg_size_init_fn) 177 (XenPCIPassthroughState *, XenPTRegGroupInfo *, 178 uint32_t base_offset, uint8_t *size); 179 180 /* emulated register group information */ 181 struct XenPTRegGroupInfo { 182 uint8_t grp_id; 183 XenPTRegisterGroupType grp_type; 184 uint8_t grp_size; 185 xen_pt_reg_size_init_fn size_init; 186 XenPTRegInfo *emu_regs; 187 }; 188 189 /* emul register group management table */ 190 typedef struct XenPTRegGroup { 191 QLIST_ENTRY(XenPTRegGroup) entries; 192 XenPTRegGroupInfo *reg_grp; 193 uint32_t base_offset; 194 uint8_t size; 195 QLIST_HEAD(, XenPTReg) reg_tbl_list; 196 } XenPTRegGroup; 197 198 199 #define XEN_PT_UNASSIGNED_PIRQ (-1) 200 typedef struct XenPTMSI { 201 uint16_t flags; 202 uint32_t addr_lo; /* guest message address */ 203 uint32_t addr_hi; /* guest message upper address */ 204 uint16_t data; /* guest message data */ 205 uint32_t ctrl_offset; /* saved control offset */ 206 uint32_t mask; /* guest mask bits */ 207 int pirq; /* guest pirq corresponding */ 208 bool initialized; /* when guest MSI is initialized */ 209 bool mapped; /* when pirq is mapped */ 210 } XenPTMSI; 211 212 typedef struct XenPTMSIXEntry { 213 int pirq; 214 uint64_t addr; 215 uint32_t data; 216 uint32_t latch[4]; 217 bool updated; /* indicate whether MSI ADDR or DATA is updated */ 218 } XenPTMSIXEntry; 219 typedef struct XenPTMSIX { 220 uint32_t ctrl_offset; 221 bool enabled; 222 bool maskall; 223 int total_entries; 224 int bar_index; 225 uint64_t table_base; 226 uint32_t table_offset_adjust; /* page align mmap */ 227 uint64_t mmio_base_addr; 228 MemoryRegion mmio; 229 void *phys_iomem_base; 230 XenPTMSIXEntry msix_entry[]; 231 } XenPTMSIX; 232 233 struct XenPCIPassthroughState { 234 PCIDevice dev; 235 236 PCIHostDeviceAddress hostaddr; 237 bool is_virtfn; 238 bool permissive; 239 bool permissive_warned; 240 XenHostPCIDevice real_device; 241 XenPTRegion bases[PCI_NUM_REGIONS]; /* Access regions */ 242 QLIST_HEAD(, XenPTRegGroup) reg_grps; 243 244 uint32_t machine_irq; 245 246 XenPTMSI *msi; 247 XenPTMSIX *msix; 248 249 MemoryRegion bar[PCI_NUM_REGIONS - 1]; 250 MemoryRegion rom; 251 252 MemoryListener memory_listener; 253 MemoryListener io_listener; 254 bool listener_set; 255 }; 256 257 void xen_pt_config_init(XenPCIPassthroughState *s, Error **errp); 258 void xen_pt_config_delete(XenPCIPassthroughState *s); 259 XenPTRegGroup *xen_pt_find_reg_grp(XenPCIPassthroughState *s, uint32_t address); 260 XenPTReg *xen_pt_find_reg(XenPTRegGroup *reg_grp, uint32_t address); 261 int xen_pt_bar_offset_to_index(uint32_t offset); 262 263 static inline pcibus_t xen_pt_get_emul_size(XenPTBarFlag flag, pcibus_t r_size) 264 { 265 /* align resource size (memory type only) */ 266 if (flag == XEN_PT_BAR_FLAG_MEM) { 267 return (r_size + XC_PAGE_SIZE - 1) & XC_PAGE_MASK; 268 } else { 269 return r_size; 270 } 271 } 272 273 /* INTx */ 274 /* The PCI Local Bus Specification, Rev. 3.0, 275 * Section 6.2.4 Miscellaneous Registers, pp 223 276 * outlines 5 valid values for the interrupt pin (intx). 277 * 0: For devices (or device functions) that don't use an interrupt in 278 * 1: INTA# 279 * 2: INTB# 280 * 3: INTC# 281 * 4: INTD# 282 * 283 * Xen uses the following 4 values for intx 284 * 0: INTA# 285 * 1: INTB# 286 * 2: INTC# 287 * 3: INTD# 288 * 289 * Observing that these list of values are not the same, xen_pt_pci_read_intx() 290 * uses the following mapping from hw to xen values. 291 * This seems to reflect the current usage within Xen. 292 * 293 * PCI hardware | Xen | Notes 294 * ----------------+-----+---------------------------------------------------- 295 * 0 | 0 | No interrupt 296 * 1 | 0 | INTA# 297 * 2 | 1 | INTB# 298 * 3 | 2 | INTC# 299 * 4 | 3 | INTD# 300 * any other value | 0 | This should never happen, log error message 301 */ 302 303 static inline uint8_t xen_pt_pci_read_intx(XenPCIPassthroughState *s) 304 { 305 uint8_t v = 0; 306 xen_host_pci_get_byte(&s->real_device, PCI_INTERRUPT_PIN, &v); 307 return v; 308 } 309 310 static inline uint8_t xen_pt_pci_intx(XenPCIPassthroughState *s) 311 { 312 uint8_t r_val = xen_pt_pci_read_intx(s); 313 314 XEN_PT_LOG(&s->dev, "intx=%i\n", r_val); 315 if (r_val < 1 || r_val > 4) { 316 XEN_PT_LOG(&s->dev, "Interrupt pin read from hardware is out of range:" 317 " value=%i, acceptable range is 1 - 4\n", r_val); 318 r_val = 0; 319 } else { 320 /* Note that if s.real_device.config_fd is closed we make 0xff. */ 321 r_val -= 1; 322 } 323 324 return r_val; 325 } 326 327 /* MSI/MSI-X */ 328 int xen_pt_msi_setup(XenPCIPassthroughState *s); 329 int xen_pt_msi_update(XenPCIPassthroughState *d); 330 void xen_pt_msi_disable(XenPCIPassthroughState *s); 331 332 int xen_pt_msix_init(XenPCIPassthroughState *s, uint32_t base); 333 void xen_pt_msix_delete(XenPCIPassthroughState *s); 334 void xen_pt_msix_unmap(XenPCIPassthroughState *s); 335 int xen_pt_msix_update(XenPCIPassthroughState *s); 336 int xen_pt_msix_update_remap(XenPCIPassthroughState *s, int bar_index); 337 void xen_pt_msix_disable(XenPCIPassthroughState *s); 338 339 static inline bool xen_pt_has_msix_mapping(XenPCIPassthroughState *s, int bar) 340 { 341 return s->msix && s->msix->bar_index == bar; 342 } 343 344 void *pci_assign_dev_load_option_rom(PCIDevice *dev, int *size, 345 unsigned int domain, unsigned int bus, 346 unsigned int slot, unsigned int function); 347 int xen_pt_register_vga_regions(XenHostPCIDevice *dev); 348 int xen_pt_unregister_vga_regions(XenHostPCIDevice *dev); 349 void xen_pt_setup_vga(XenPCIPassthroughState *s, XenHostPCIDevice *dev, 350 Error **errp); 351 #endif /* XEN_PT_H */ 352