xen_pt.h 10 KB

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