#ifndef XEN_PT_H #define XEN_PT_H #include "qemu-common.h" #include "hw/xen/xen_common.h" #include "hw/pci/pci.h" #include "xen-host-pci-device.h" void xen_pt_log(const PCIDevice *d, const char *f, ...) GCC_FMT_ATTR(2, 3); #define XEN_PT_ERR(d, _f, _a...) xen_pt_log(d, "%s: Error: "_f, __func__, ##_a) #ifdef XEN_PT_LOGGING_ENABLED # define XEN_PT_LOG(d, _f, _a...) xen_pt_log(d, "%s: " _f, __func__, ##_a) # define XEN_PT_WARN(d, _f, _a...) \ xen_pt_log(d, "%s: Warning: "_f, __func__, ##_a) #else # define XEN_PT_LOG(d, _f, _a...) # define XEN_PT_WARN(d, _f, _a...) #endif #ifdef XEN_PT_DEBUG_PCI_CONFIG_ACCESS # define XEN_PT_LOG_CONFIG(d, addr, val, len) \ xen_pt_log(d, "%s: address=0x%04x val=0x%08x len=%d\n", \ __func__, addr, val, len) #else # define XEN_PT_LOG_CONFIG(d, addr, val, len) #endif /* Helper */ #define XEN_PFN(x) ((x) >> XC_PAGE_SHIFT) typedef const struct XenPTRegInfo XenPTRegInfo; typedef struct XenPTReg XenPTReg; typedef struct XenPCIPassthroughState XenPCIPassthroughState; #define TYPE_XEN_PT_DEVICE "xen-pci-passthrough" #define XEN_PT_DEVICE(obj) \ OBJECT_CHECK(XenPCIPassthroughState, (obj), TYPE_XEN_PT_DEVICE) uint32_t igd_read_opregion(XenPCIPassthroughState *s); void igd_write_opregion(XenPCIPassthroughState *s, uint32_t val); /* function type for config reg */ typedef int (*xen_pt_conf_reg_init) (XenPCIPassthroughState *, XenPTRegInfo *, uint32_t real_offset, uint32_t *data); typedef int (*xen_pt_conf_dword_write) (XenPCIPassthroughState *, XenPTReg *cfg_entry, uint32_t *val, uint32_t dev_value, uint32_t valid_mask); typedef int (*xen_pt_conf_word_write) (XenPCIPassthroughState *, XenPTReg *cfg_entry, uint16_t *val, uint16_t dev_value, uint16_t valid_mask); typedef int (*xen_pt_conf_byte_write) (XenPCIPassthroughState *, XenPTReg *cfg_entry, uint8_t *val, uint8_t dev_value, uint8_t valid_mask); typedef int (*xen_pt_conf_dword_read) (XenPCIPassthroughState *, XenPTReg *cfg_entry, uint32_t *val, uint32_t valid_mask); typedef int (*xen_pt_conf_word_read) (XenPCIPassthroughState *, XenPTReg *cfg_entry, uint16_t *val, uint16_t valid_mask); typedef int (*xen_pt_conf_byte_read) (XenPCIPassthroughState *, XenPTReg *cfg_entry, uint8_t *val, uint8_t valid_mask); #define XEN_PT_BAR_ALLF 0xFFFFFFFF #define XEN_PT_BAR_UNMAPPED (-1) #define XEN_PCI_CAP_MAX 48 #define XEN_PCI_INTEL_OPREGION 0xfc typedef enum { XEN_PT_GRP_TYPE_HARDWIRED = 0, /* 0 Hardwired reg group */ XEN_PT_GRP_TYPE_EMU, /* emul reg group */ } XenPTRegisterGroupType; typedef enum { XEN_PT_BAR_FLAG_MEM = 0, /* Memory type BAR */ XEN_PT_BAR_FLAG_IO, /* I/O type BAR */ XEN_PT_BAR_FLAG_UPPER, /* upper 64bit BAR */ XEN_PT_BAR_FLAG_UNUSED, /* unused BAR */ } XenPTBarFlag; typedef struct XenPTRegion { /* BAR flag */ XenPTBarFlag bar_flag; /* Translation of the emulated address */ union { uint64_t maddr; uint64_t pio_base; uint64_t u; } access; } XenPTRegion; /* XenPTRegInfo declaration * - only for emulated register (either a part or whole bit). * - for passthrough register that need special behavior (like interacting with * other component), set emu_mask to all 0 and specify r/w func properly. * - do NOT use ALL F for init_val, otherwise the tbl will not be registered. */ /* emulated register information */ struct XenPTRegInfo { uint32_t offset; uint32_t size; uint32_t init_val; /* reg reserved field mask (ON:reserved, OFF:defined) */ uint32_t res_mask; /* reg read only field mask (ON:RO/ROS, OFF:other) */ uint32_t ro_mask; /* reg read/write-1-clear field mask (ON:RW1C/RW1CS, OFF:other) */ uint32_t rw1c_mask; /* reg emulate field mask (ON:emu, OFF:passthrough) */ uint32_t emu_mask; xen_pt_conf_reg_init init; /* read/write function pointer * for double_word/word/byte size */ union { struct { xen_pt_conf_dword_write write; xen_pt_conf_dword_read read; } dw; struct { xen_pt_conf_word_write write; xen_pt_conf_word_read read; } w; struct { xen_pt_conf_byte_write write; xen_pt_conf_byte_read read; } b; } u; }; /* emulated register management */ struct XenPTReg { QLIST_ENTRY(XenPTReg) entries; XenPTRegInfo *reg; union { uint8_t *byte; uint16_t *half_word; uint32_t *word; } ptr; /* pointer to dev.config. */ }; typedef const struct XenPTRegGroupInfo XenPTRegGroupInfo; /* emul reg group size initialize method */ typedef int (*xen_pt_