Lines Matching +full:reg +full:- +full:data
6 * the COPYING file in the top-level directory.
20 #include "hw/xen/xen-legacy-backend.h"
22 #define XEN_PT_MERGE_VALUE(value, data, val_mask) \ argument
23 (((value) & (val_mask)) | ((data) & ~(val_mask)))
29 static int xen_pt_ptr_reg_init(XenPCIPassthroughState *s, XenPTRegInfo *reg,
30 uint32_t real_offset, uint32_t *data);
53 if (d->vendor_id == PCI_VENDOR_ID_INTEL && in xen_pt_hide_dev_cap()
54 d->device_id == PCI_DEVICE_ID_INTEL_82599_SFP_VF) { in xen_pt_hide_dev_cap()
68 QLIST_FOREACH(entry, &s->reg_grps, entries) { in xen_pt_find_reg_grp()
70 if ((entry->base_offset <= address) in xen_pt_find_reg_grp()
71 && ((entry->base_offset + entry->size) > address)) { in xen_pt_find_reg_grp()
84 XenPTRegInfo *reg = NULL; in xen_pt_find_reg() local
88 QLIST_FOREACH(reg_entry, ®_grp->reg_tbl_list, entries) { in xen_pt_find_reg()
89 reg = reg_entry->reg; in xen_pt_find_reg()
90 real_offset = reg_grp->base_offset + reg->offset; in xen_pt_find_reg()
93 && ((real_offset + reg->size) > address)) { in xen_pt_find_reg()
102 XenPTRegInfo *reg, uint32_t valid_mask) in get_throughable_mask() argument
104 uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask); in get_throughable_mask()
106 if (!s->permissive) { in get_throughable_mask()
107 throughable_mask &= ~reg->res_mask; in get_throughable_mask()
120 XenPTRegInfo *reg, uint32_t real_offset, in xen_pt_common_reg_init() argument
121 uint32_t *data) in xen_pt_common_reg_init() argument
123 *data = reg->init_val; in xen_pt_common_reg_init()
132 XenPTRegInfo *reg = cfg_entry->reg; in xen_pt_byte_reg_read() local
134 uint8_t *data = cfg_entry->ptr.byte; in xen_pt_byte_reg_read() local
137 valid_emu_mask = reg->emu_mask & valid_mask; in xen_pt_byte_reg_read()
138 *value = XEN_PT_MERGE_VALUE(*value, *data, ~valid_emu_mask); in xen_pt_byte_reg_read()
145 XenPTRegInfo *reg = cfg_entry->reg; in xen_pt_word_reg_read() local
147 uint16_t *data = cfg_entry->ptr.half_word; in xen_pt_word_reg_read() local
150 valid_emu_mask = reg->emu_mask & valid_mask; in xen_pt_word_reg_read()
151 *value = XEN_PT_MERGE_VALUE(*value, *data, ~valid_emu_mask); in xen_pt_word_reg_read()
158 XenPTRegInfo *reg = cfg_entry->reg; in xen_pt_long_reg_read() local
160 uint32_t *data = cfg_entry->ptr.word; in xen_pt_long_reg_read() local
163 valid_emu_mask = reg->emu_mask & valid_mask; in xen_pt_long_reg_read()
164 *value = XEN_PT_MERGE_VALUE(*value, *data, ~valid_emu_mask); in xen_pt_long_reg_read()
175 XenPTRegInfo *reg = cfg_entry->reg; in xen_pt_byte_reg_write() local
177 uint8_t throughable_mask = get_throughable_mask(s, reg, valid_mask); in xen_pt_byte_reg_write()
178 uint8_t *data = cfg_entry->ptr.byte; in xen_pt_byte_reg_write() local
181 writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; in xen_pt_byte_reg_write()
182 *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask); in xen_pt_byte_reg_write()
185 *val = XEN_PT_MERGE_VALUE(*val, dev_value & ~reg->rw1c_mask, in xen_pt_byte_reg_write()
194 XenPTRegInfo *reg = cfg_entry->reg; in xen_pt_word_reg_write() local
196 uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); in xen_pt_word_reg_write()
197 uint16_t *data = cfg_entry->ptr.half_word; in xen_pt_word_reg_write() local
200 writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; in xen_pt_word_reg_write()
201 *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask); in xen_pt_word_reg_write()
204 *val = XEN_PT_MERGE_VALUE(*val, dev_value & ~reg->rw1c_mask, in xen_pt_word_reg_write()
213 XenPTRegInfo *reg = cfg_entry->reg; in xen_pt_long_reg_write() local
215 uint32_t throughable_mask = get_throughable_mask(s, reg, valid_mask); in xen_pt_long_reg_write()
216 uint32_t *data = cfg_entry->ptr.word; in xen_pt_long_reg_write() local
219 writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; in xen_pt_long_reg_write()
220 *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask); in xen_pt_long_reg_write()
223 *val = XEN_PT_MERGE_VALUE(*val, dev_value & ~reg->rw1c_mask, in xen_pt_long_reg_write()
231 * - only for emulated register (either a part or whole bit).
232 * - for passthrough register that need special behavior (like interacting with
234 * - do NOT use ALL F for init_val, otherwise the tbl will not be registered.
242 XenPTRegInfo *reg, uint32_t real_offset, in xen_pt_vendor_reg_init() argument
243 uint32_t *data) in xen_pt_vendor_reg_init() argument
245 *data = s->real_device.vendor_id; in xen_pt_vendor_reg_init()
249 XenPTRegInfo *reg, uint32_t real_offset, in xen_pt_device_reg_init() argument
250 uint32_t *data) in xen_pt_device_reg_init() argument
252 *data = s->real_device.device_id; in xen_pt_device_reg_init()
256 XenPTRegInfo *reg, uint32_t real_offset, in xen_pt_status_reg_init() argument
257 uint32_t *data) in xen_pt_status_reg_init() argument
270 if (*reg_entry->ptr.half_word) { in xen_pt_status_reg_init()
279 return -1; in xen_pt_status_reg_init()
284 return -1; in xen_pt_status_reg_init()
287 *data = reg_field; in xen_pt_status_reg_init()
291 XenPTRegInfo *reg, uint32_t real_offset, in xen_pt_header_type_reg_init() argument
292 uint32_t *data) in xen_pt_header_type_reg_init() argument
295 *data = reg->init_val; in xen_pt_header_type_reg_init()
296 if ((PCI_DEVICE(s)->cap_present & QEMU_PCI_CAP_MULTIFUNCTION)) { in xen_pt_header_type_reg_init()
297 *data |= PCI_HEADER_TYPE_MULTI_FUNCTION; in xen_pt_header_type_reg_init()
304 XenPTRegInfo *reg, uint32_t real_offset, in xen_pt_irqpin_reg_init() argument
305 uint32_t *data) in xen_pt_irqpin_reg_init() argument
307 if (s->real_device.irq) { in xen_pt_irqpin_reg_init()
308 *data = xen_pt_pci_read_intx(s); in xen_pt_irqpin_reg_init()
318 XenPTRegInfo *reg = cfg_entry->reg; in xen_pt_cmd_reg_write() local
320 uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); in xen_pt_cmd_reg_write()
321 uint16_t *data = cfg_entry->ptr.half_word; in xen_pt_cmd_reg_write() local
324 writable_mask = ~reg->ro_mask & valid_mask; in xen_pt_cmd_reg_write()
325 *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask); in xen_pt_cmd_reg_write()
331 if (s->machine_irq) { in xen_pt_cmd_reg_write()
349 return !!(r->type & PCI_BASE_ADDRESS_MEM_TYPE_64); in is_64bit_bar()
356 size64 = (r + 1)->size; in xen_pt_get_bar_size()
358 size64 += r->size; in xen_pt_get_bar_size()
361 return r->size; in xen_pt_get_bar_size()
373 int type = s->real_device.io_regions[index - 1].type; in xen_pt_bar_reg_parse()
377 region = &s->bases[index - 1]; in xen_pt_bar_reg_parse()
378 if (region->bar_flag != XEN_PT_BAR_FLAG_UPPER) { in xen_pt_bar_reg_parse()
385 r = &d->io_regions[index]; in xen_pt_bar_reg_parse()
396 if (s->real_device.io_regions[index].type & XEN_HOST_PCI_REGION_TYPE_IO) { in xen_pt_bar_reg_parse()
405 if (hr->type & XEN_HOST_PCI_REGION_TYPE_IO) { in base_address_with_flags()
406 return hr->base_addr | (hr->bus_flags & ~PCI_BASE_ADDRESS_IO_MASK); in base_address_with_flags()
408 return hr->base_addr | (hr->bus_flags & ~PCI_BASE_ADDRESS_MEM_MASK); in base_address_with_flags()
412 static int xen_pt_bar_reg_init(XenPCIPassthroughState *s, XenPTRegInfo *reg, in xen_pt_bar_reg_init() argument
413 uint32_t real_offset, uint32_t *data) in xen_pt_bar_reg_init() argument
418 index = xen_pt_bar_offset_to_index(reg->offset); in xen_pt_bar_reg_init()
420 XEN_PT_ERR(&s->dev, "Internal error: Invalid BAR index [%d].\n", index); in xen_pt_bar_reg_init()
421 return -1; in xen_pt_bar_reg_init()
425 s->bases[index].bar_flag = xen_pt_bar_reg_parse(s, index); in xen_pt_bar_reg_init()
426 if (s->bases[index].bar_flag == XEN_PT_BAR_FLAG_UNUSED) { in xen_pt_bar_reg_init()
430 *data = reg_field; in xen_pt_bar_reg_init()
436 XenPTRegInfo *reg = cfg_entry->reg; in xen_pt_bar_reg_read() local
442 index = xen_pt_bar_offset_to_index(reg->offset); in xen_pt_bar_reg_read()
443 if (index < 0 || index >= PCI_NUM_REGIONS - 1) { in xen_pt_bar_reg_read()
444 XEN_PT_ERR(&s->dev, "Internal error: Invalid BAR index [%d].\n", index); in xen_pt_bar_reg_read()
445 return -1; in xen_pt_bar_reg_read()
448 /* use fixed-up value from kernel sysfs */ in xen_pt_bar_reg_read()
449 *value = base_address_with_flags(&s->real_device.io_regions[index]); in xen_pt_bar_reg_read()
452 switch (s->bases[index].bar_flag) { in xen_pt_bar_reg_read()
468 *value = XEN_PT_MERGE_VALUE(*value, *cfg_entry->ptr.word, ~valid_emu_mask); in xen_pt_bar_reg_read()
476 XenPTRegInfo *reg = cfg_entry->reg; in xen_pt_bar_reg_write() local
485 uint32_t *data = cfg_entry->ptr.word; in xen_pt_bar_reg_write() local
487 index = xen_pt_bar_offset_to_index(reg->offset); in xen_pt_bar_reg_write()
490 return -1; in xen_pt_bar_reg_write()
493 r = &d->io_regions[index]; in xen_pt_bar_reg_write()
494 base = &s->bases[index]; in xen_pt_bar_reg_write()
495 r_size = xen_pt_get_emul_size(base->bar_flag, r->size); in xen_pt_bar_reg_write()
497 /* set emulate mask and read-only mask values depend on the BAR flag */ in xen_pt_bar_reg_write()
498 switch (s->bases[index].bar_flag) { in xen_pt_bar_reg_write()
505 bar_ro_mask = XEN_PT_BAR_MEM_RO_MASK | (r_size - 1); in xen_pt_bar_reg_write()
510 bar_ro_mask = XEN_PT_BAR_IO_RO_MASK | (r_size - 1); in xen_pt_bar_reg_write()
514 r_size = d->io_regions[index - 1].size >> 32; in xen_pt_bar_reg_write()
516 bar_ro_mask = r_size ? r_size - 1 : 0; in xen_pt_bar_reg_write()
524 *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask); in xen_pt_bar_reg_write()
527 switch (s->bases[index].bar_flag) { in xen_pt_bar_reg_write()
550 XenPTRegInfo *reg = cfg_entry->reg; in xen_pt_exp_rom_bar_reg_write() local
554 uint32_t throughable_mask = get_throughable_mask(s, reg, valid_mask); in xen_pt_exp_rom_bar_reg_write()
557 uint32_t *data = cfg_entry->ptr.word; in xen_pt_exp_rom_bar_reg_write() local
559 r_size = d->io_regions[PCI_ROM_SLOT].size; in xen_pt_exp_rom_bar_reg_write()
560 base = &s->bases[PCI_ROM_SLOT]; in xen_pt_exp_rom_bar_reg_write()
562 r_size = xen_pt_get_emul_size(base->bar_flag, r_size); in xen_pt_exp_rom_bar_reg_write()
564 /* set emulate mask and read-only mask */ in xen_pt_exp_rom_bar_reg_write()
565 bar_ro_mask = (reg->ro_mask | (r_size - 1)) & ~PCI_ROM_ADDRESS_ENABLE; in xen_pt_exp_rom_bar_reg_write()
569 *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask); in xen_pt_exp_rom_bar_reg_write()
593 /* Header Type0 reg static information table */
595 /* Vendor ID reg */
606 /* Device ID reg */
617 /* Command reg */
628 /* Capabilities Pointer reg */
639 /* Status reg */
641 * so need to be declared after Cap Ptr reg
655 /* Cache Line Size reg */
666 /* Latency Timer reg */
677 /* Header Type reg */
688 /* Interrupt Line reg */
699 /* Interrupt Pin reg */
710 /* BAR 0 reg */
720 /* BAR 1 reg */
729 /* BAR 2 reg */
738 /* BAR 3 reg */
747 /* BAR 4 reg */
756 /* BAR 5 reg */
765 /* Expansion ROM BAR reg */
783 * Vital Product Data Capability
786 /* Vital Product Data Capability Structure reg static information table */
817 /* Vendor Specific Capability Structure reg static information table */
843 if (xen_host_pci_get_byte(&s->real_device, offset + PCI_EXP_FLAGS, &flag)) { in get_capability_version()
853 if (xen_host_pci_get_byte(&s->real_device, offset + PCI_EXP_FLAGS, &flag)) { in get_device_type()
861 XenPTRegInfo *reg, uint32_t real_offset, in xen_pt_linkctrl_reg_init() argument
862 uint32_t *data) in xen_pt_linkctrl_reg_init() argument
864 uint8_t cap_ver = get_capability_version(s, real_offset - reg->offset); in xen_pt_linkctrl_reg_init()
865 uint8_t dev_type = get_device_type(s, real_offset - reg->offset); in xen_pt_linkctrl_reg_init()
871 *data = XEN_PT_INVALID_REG; in xen_pt_linkctrl_reg_init()
874 *data = reg->init_val; in xen_pt_linkctrl_reg_init()
879 XenPTRegInfo *reg, uint32_t real_offset, in xen_pt_devctrl2_reg_init() argument
880 uint32_t *data) in xen_pt_devctrl2_reg_init() argument
882 uint8_t cap_ver = get_capability_version(s, real_offset - reg->offset); in xen_pt_devctrl2_reg_init()
886 *data = XEN_PT_INVALID_REG; in xen_pt_devctrl2_reg_init()
889 *data = reg->init_val; in xen_pt_devctrl2_reg_init()
894 XenPTRegInfo *reg, uint32_t real_offset, in xen_pt_linkctrl2_reg_init() argument
895 uint32_t *data) in xen_pt_linkctrl2_reg_init() argument
897 uint8_t cap_ver = get_capability_version(s, real_offset - reg->offset); in xen_pt_linkctrl2_reg_init()
907 rc = xen_host_pci_get_byte(&s->real_device, in xen_pt_linkctrl2_reg_init()
908 real_offset - reg->offset + PCI_EXP_LNKCAP, in xen_pt_linkctrl2_reg_init()
916 *data = reg_field; in xen_pt_linkctrl2_reg_init()
920 /* PCI Express Capability Structure reg static information table */
922 /* Next Pointer reg */
933 /* Device Capabilities reg */
944 /* Device Control reg */
955 /* Device Status reg */
966 /* Link Control reg */
977 /* Link Status reg */
987 /* Device Control 2 reg */
998 /* Link Control 2 reg */
1019 /* Power Management Capability reg static information table */
1021 /* Next Pointer reg */
1032 /* Power Management Capabilities reg */
1043 /* PCI Power Management Control/Status reg */
1073 XenPTRegInfo *reg, uint32_t real_offset, in xen_pt_msgctrl_reg_init() argument
1074 uint32_t *data) in xen_pt_msgctrl_reg_init() argument
1076 XenPTMSI *msi = s->msi; in xen_pt_msgctrl_reg_init()
1081 rc = xen_host_pci_get_word(&s->real_device, real_offset, ®_field); in xen_pt_msgctrl_reg_init()
1086 XEN_PT_LOG(&s->dev, "MSI already enabled, disabling it first\n"); in xen_pt_msgctrl_reg_init()
1087 xen_host_pci_set_word(&s->real_device, real_offset, in xen_pt_msgctrl_reg_init()
1090 msi->flags |= reg_field; in xen_pt_msgctrl_reg_init()
1091 msi->ctrl_offset = real_offset; in xen_pt_msgctrl_reg_init()
1092 msi->initialized = false; in xen_pt_msgctrl_reg_init()
1093 msi->mapped = false; in xen_pt_msgctrl_reg_init()
1095 *data = reg->init_val; in xen_pt_msgctrl_reg_init()
1102 XenPTRegInfo *reg = cfg_entry->reg; in xen_pt_msgctrl_reg_write() local
1103 XenPTMSI *msi = s->msi; in xen_pt_msgctrl_reg_write()
1105 uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); in xen_pt_msgctrl_reg_write()
1106 uint16_t *data = cfg_entry->ptr.half_word; in xen_pt_msgctrl_reg_write() local
1108 /* Currently no support for multi-vector */ in xen_pt_msgctrl_reg_write()
1110 XEN_PT_WARN(&s->dev, "Tries to set more than 1 vector ctrl %x\n", *val); in xen_pt_msgctrl_reg_write()
1114 writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; in xen_pt_msgctrl_reg_write()
1115 *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask); in xen_pt_msgctrl_reg_write()
1116 msi->flags |= *data & ~PCI_MSI_FLAGS_ENABLE; in xen_pt_msgctrl_reg_write()
1124 if (!msi->initialized) { in xen_pt_msgctrl_reg_write()
1126 XEN_PT_LOG(&s->dev, "setup MSI (register: %x).\n", *val); in xen_pt_msgctrl_reg_write()
1134 XEN_PT_WARN(&s->dev, "Can not map MSI (register: %x)!\n", *val); in xen_pt_msgctrl_reg_write()
1139 XEN_PT_WARN(&s->dev, "Can not bind MSI (register: %x)!\n", *val); in xen_pt_msgctrl_reg_write()
1142 msi->initialized = true; in xen_pt_msgctrl_reg_write()
1143 msi->mapped = true; in xen_pt_msgctrl_reg_write()
1145 msi->flags |= PCI_MSI_FLAGS_ENABLE; in xen_pt_msgctrl_reg_write()
1146 } else if (msi->mapped) { in xen_pt_msgctrl_reg_write()
1155 XenPTRegInfo *reg, uint32_t real_offset, in xen_pt_msgaddr64_reg_init() argument
1156 uint32_t *data) in xen_pt_msgaddr64_reg_init() argument
1159 if (!(s->msi->flags & PCI_MSI_FLAGS_64BIT)) { in xen_pt_msgaddr64_reg_init()
1160 *data = XEN_PT_INVALID_REG; in xen_pt_msgaddr64_reg_init()
1162 *data = reg->init_val; in xen_pt_msgaddr64_reg_init()
1168 /* initialize Message Data register */
1170 XenPTRegInfo *reg, uint32_t real_offset, in xen_pt_msgdata_reg_init() argument
1171 uint32_t *data) in xen_pt_msgdata_reg_init() argument
1173 uint32_t flags = s->msi->flags; in xen_pt_msgdata_reg_init()
1174 uint32_t offset = reg->offset; in xen_pt_msgdata_reg_init()
1177 if (xen_pt_msi_check_type(offset, flags, DATA)) { in xen_pt_msgdata_reg_init()
1178 *data = reg->init_val; in xen_pt_msgdata_reg_init()
1180 *data = XEN_PT_INVALID_REG; in xen_pt_msgdata_reg_init()
1188 XenPTRegInfo *reg, uint32_t real_offset, in xen_pt_mask_reg_init() argument
1189 uint32_t *data) in xen_pt_mask_reg_init() argument
1191 uint32_t flags = s->msi->flags; in xen_pt_mask_reg_init()
1195 *data = XEN_PT_INVALID_REG; in xen_pt_mask_reg_init()
1196 } else if (xen_pt_msi_check_type(reg->offset, flags, MASK)) { in xen_pt_mask_reg_init()
1197 *data = reg->init_val; in xen_pt_mask_reg_init()
1199 *data = XEN_PT_INVALID_REG; in xen_pt_mask_reg_init()
1207 XenPTRegInfo *reg, uint32_t real_offset, in xen_pt_pending_reg_init() argument
1208 uint32_t *data) in xen_pt_pending_reg_init() argument
1210 uint32_t flags = s->msi->flags; in xen_pt_pending_reg_init()
1214 *data = XEN_PT_INVALID_REG; in xen_pt_pending_reg_init()
1215 } else if (xen_pt_msi_check_type(reg->offset, flags, PENDING)) { in xen_pt_pending_reg_init()
1216 *data = reg->init_val; in xen_pt_pending_reg_init()
1218 *data = XEN_PT_INVALID_REG; in xen_pt_pending_reg_init()
1228 XenPTRegInfo *reg = cfg_entry->reg; in xen_pt_msgaddr32_reg_write() local
1230 uint32_t old_addr = *cfg_entry->ptr.word; in xen_pt_msgaddr32_reg_write()
1231 uint32_t *data = cfg_entry->ptr.word; in xen_pt_msgaddr32_reg_write() local
1234 writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; in xen_pt_msgaddr32_reg_write()
1235 *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask); in xen_pt_msgaddr32_reg_write()
1236 s->msi->addr_lo = *data; in xen_pt_msgaddr32_reg_write()
1242 if (*data != old_addr) { in xen_pt_msgaddr32_reg_write()
1243 if (s->msi->mapped) { in xen_pt_msgaddr32_reg_write()
1255 XenPTRegInfo *reg = cfg_entry->reg; in xen_pt_msgaddr64_reg_write() local
1257 uint32_t old_addr = *cfg_entry->ptr.word; in xen_pt_msgaddr64_reg_write()
1258 uint32_t *data = cfg_entry->ptr.word; in xen_pt_msgaddr64_reg_write() local
1261 if (!(s->msi->flags & PCI_MSI_FLAGS_64BIT)) { in xen_pt_msgaddr64_reg_write()
1262 XEN_PT_ERR(&s->dev, in xen_pt_msgaddr64_reg_write()
1264 return -1; in xen_pt_msgaddr64_reg_write()
1268 writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; in xen_pt_msgaddr64_reg_write()
1269 *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask); in xen_pt_msgaddr64_reg_write()
1271 s->msi->addr_hi = *data; in xen_pt_msgaddr64_reg_write()
1277 if (*data != old_addr) { in xen_pt_msgaddr64_reg_write()
1278 if (s->msi->mapped) { in xen_pt_msgaddr64_reg_write()
1288 /* write Message Data register */
1293 XenPTRegInfo *reg = cfg_entry->reg; in xen_pt_msgdata_reg_write() local
1294 XenPTMSI *msi = s->msi; in xen_pt_msgdata_reg_write()
1296 uint16_t old_data = *cfg_entry->ptr.half_word; in xen_pt_msgdata_reg_write()
1297 uint32_t offset = reg->offset; in xen_pt_msgdata_reg_write()
1298 uint16_t *data = cfg_entry->ptr.half_word; in xen_pt_msgdata_reg_write() local
1301 if (!xen_pt_msi_check_type(offset, msi->flags, DATA)) { in xen_pt_msgdata_reg_write()
1303 XEN_PT_ERR(&s->dev, "the offset does not match the 32/64 bit type!\n"); in xen_pt_msgdata_reg_write()
1304 return -1; in xen_pt_msgdata_reg_write()
1308 writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; in xen_pt_msgdata_reg_write()
1309 *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask); in xen_pt_msgdata_reg_write()
1311 msi->data = *data; in xen_pt_msgdata_reg_write()
1317 if (*data != old_data) { in xen_pt_msgdata_reg_write()
1318 if (msi->mapped) { in xen_pt_msgdata_reg_write()
1337 s->msi->mask = *val; in xen_pt_mask_reg_write()
1342 /* MSI Capability Structure reg static information table */
1344 /* Next Pointer reg */
1355 /* Message Control reg */
1367 /* Message Address reg */
1378 /* Message Upper Address reg (if PCI_MSI_FLAGS_64BIT set) */
1389 /* Message Data reg (16 bits of data for 32-bit devices) */
1400 /* Message Data reg (16 bits of data for 64-bit devices) */
1411 /* Mask reg (if PCI_MSI_FLAGS_MASKBIT set, for 32-bit devices) */
1422 /* Mask reg (if PCI_MSI_FLAGS_MASKBIT set, for 64-bit devices) */
1433 /* Pending reg (if PCI_MSI_FLAGS_MASKBIT set, for 32-bit devices) */
1444 /* Pending reg (if PCI_MSI_FLAGS_MASKBIT set, for 64-bit devices) */
1462 * MSI-X Capability
1465 /* Message Control register for MSI-X */
1467 XenPTRegInfo *reg, uint32_t real_offset, in xen_pt_msixctrl_reg_init() argument
1468 uint32_t *data) in xen_pt_msixctrl_reg_init() argument
1474 rc = xen_host_pci_get_word(&s->real_device, real_offset, ®_field); in xen_pt_msixctrl_reg_init()
1479 XEN_PT_LOG(&s->dev, "MSIX already enabled, disabling it first\n"); in xen_pt_msixctrl_reg_init()
1480 xen_host_pci_set_word(&s->real_device, real_offset, in xen_pt_msixctrl_reg_init()
1484 s->msix->ctrl_offset = real_offset; in xen_pt_msixctrl_reg_init()
1486 *data = reg->init_val; in xen_pt_msixctrl_reg_init()
1493 XenPTRegInfo *reg = cfg_entry->reg; in xen_pt_msixctrl_reg_write() local
1495 uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); in xen_pt_msixctrl_reg_write()
1497 uint16_t *data = cfg_entry->ptr.half_word; in xen_pt_msixctrl_reg_write() local
1500 writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; in xen_pt_msixctrl_reg_write()
1501 *data = XEN_PT_MERGE_VALUE(*val, *data, writable_mask); in xen_pt_msixctrl_reg_write()
1506 /* update MSI-X */ in xen_pt_msixctrl_reg_write()
1510 } else if (!(*val & PCI_MSIX_FLAGS_ENABLE) && s->msix->enabled) { in xen_pt_msixctrl_reg_write()
1514 s->msix->maskall = *val & PCI_MSIX_FLAGS_MASKALL; in xen_pt_msixctrl_reg_write()
1516 debug_msix_enabled_old = s->msix->enabled; in xen_pt_msixctrl_reg_write()
1517 s->msix->enabled = !!(*val & PCI_MSIX_FLAGS_ENABLE); in xen_pt_msixctrl_reg_write()
1518 if (s->msix->enabled != debug_msix_enabled_old) { in xen_pt_msixctrl_reg_write()
1519 XEN_PT_LOG(&s->dev, "%s MSI-X\n", in xen_pt_msixctrl_reg_write()
1520 s->msix->enabled ? "enable" : "disable"); in xen_pt_msixctrl_reg_write()
1526 /* MSI-X Capability Structure reg static information table */
1528 /* Next Pointer reg */
1539 /* Message Control reg */
1557 /* Intel IGFX OpRegion reg */
1581 *size = grp_reg->grp_size; in xen_pt_reg_grp_size_init()
1589 return xen_host_pci_get_byte(&s->real_device, base_offset + 0x02, size); in xen_pt_vendor_size_init()
1630 return -1; in xen_pt_pcie_size_init()
1653 return -1; in xen_pt_pcie_size_init()
1657 return -1; in xen_pt_pcie_size_init()
1672 rc = xen_host_pci_get_word(&s->real_device, base_offset + PCI_MSI_FLAGS, in xen_pt_msi_size_init()
1677 /* check if 64-bit address is capable of per-vector masking */ in xen_pt_msi_size_init()
1685 s->msi = g_new0(XenPTMSI, 1); in xen_pt_msi_size_init()
1686 s->msi->pirq = XEN_PT_UNASSIGNED_PIRQ; in xen_pt_msi_size_init()
1691 /* get MSI-X Capability Structure register group size */
1701 XEN_PT_ERR(&s->dev, "Internal error: Invalid xen_pt_msix_init.\n"); in xen_pt_msix_size_init()
1705 *size = grp_reg->grp_size; in xen_pt_msix_size_init()
1711 /* Header Type0 reg group */
1719 /* PCI PowerManagement Capability reg group */
1727 /* AGP Capability Structure reg group */
1734 /* Vital Product Data Capability Structure reg group */
1742 /* Slot Identification reg group */
1749 /* MSI Capability Structure reg group */
1757 /* PCI-X Capabilities List Item reg group */
1764 /* Vendor Specific Capability Structure reg group */
1772 /* SHPC Capability List Item reg group */
1779 /* Subsystem ID and Subsystem Vendor ID Capability List Item reg group */
1786 /* AGP 8x Capability Structure reg group */
1793 /* PCI Express Capability Structure reg group */
1801 /* MSI-X Capability Structure reg group */
1824 XenPTRegInfo *reg, uint32_t real_offset, in xen_pt_ptr_reg_init() argument
1825 uint32_t *data) in xen_pt_ptr_reg_init() argument
1831 rc = xen_host_pci_get_byte(&s->real_device, real_offset, ®_field); in xen_pt_ptr_reg_init()
1838 if (xen_pt_hide_dev_cap(&s->real_device, in xen_pt_ptr_reg_init()
1843 rc = xen_host_pci_get_byte(&s->real_device, in xen_pt_ptr_reg_init()
1846 XEN_PT_ERR(&s->dev, "Failed to read capability @0x%x (rc:%d)\n", in xen_pt_ptr_reg_init()
1860 rc = xen_host_pci_get_byte(&s->real_device, in xen_pt_ptr_reg_init()
1868 *data = reg_field; in xen_pt_ptr_reg_init()
1884 if (xen_host_pci_get_byte(&s->real_device, PCI_STATUS, &status)) { in find_cap_offset()
1891 while (max_cap--) { in find_cap_offset()
1892 if (xen_host_pci_get_byte(&s->real_device, pos, &pos)) { in find_cap_offset()
1900 if (xen_host_pci_get_byte(&s->real_device, in find_cap_offset()
1918 XenPTRegGroup *reg_grp, XenPTRegInfo *reg, in xen_pt_config_reg_init() argument
1922 uint32_t data = 0; in xen_pt_config_reg_init() local
1926 reg_entry->reg = reg; in xen_pt_config_reg_init()
1928 if (reg->init) { in xen_pt_config_reg_init()
1934 rc = reg->init(s, reg_entry->reg, in xen_pt_config_reg_init()
1935 reg_grp->base_offset + reg->offset, &data); in xen_pt_config_reg_init()
1941 if (data == XEN_PT_INVALID_REG) { in xen_pt_config_reg_init()
1946 /* Sync up the data to dev.config */ in xen_pt_config_reg_init()
1947 offset = reg_grp->base_offset + reg->offset; in xen_pt_config_reg_init()
1948 size_mask = 0xFFFFFFFF >> ((4 - reg->size) << 3); in xen_pt_config_reg_init()
1950 switch (reg->size) { in xen_pt_config_reg_init()
1951 case 1: rc = xen_host_pci_get_byte(&s->real_device, offset, (uint8_t *)&val); in xen_pt_config_reg_init()
1953 case 2: rc = xen_host_pci_get_word(&s->real_device, offset, (uint16_t *)&val); in xen_pt_config_reg_init()
1955 case 4: rc = xen_host_pci_get_long(&s->real_device, offset, &val); in xen_pt_config_reg_init()
1966 * contain the emulated view of the guest - therefore we flip the mask in xen_pt_config_reg_init()
1968 host_mask = size_mask & ~reg->emu_mask; in xen_pt_config_reg_init()
1970 if ((data & host_mask) != (val & host_mask)) { in xen_pt_config_reg_init()
1973 * Merge the emulated bits (data) with the host bits (val) in xen_pt_config_reg_init()
1977 new_val = XEN_PT_MERGE_VALUE(val, data, host_mask) & size_mask; in xen_pt_config_reg_init()
1978 /* Leave intact host and emulated values past the size - even though in xen_pt_config_reg_init()
1979 * we do not care as we write per reg->size granularity, but for the in xen_pt_config_reg_init()
1981 new_val |= ((val | data)) & ~size_mask; in xen_pt_config_reg_init()
1982 … XEN_PT_LOG(&s->dev,"Offset 0x%04x mismatch! Emulated=0x%04x, host=0x%04x, syncing to 0x%04x.\n", in xen_pt_config_reg_init()
1983 offset, data, val, new_val); in xen_pt_config_reg_init()
1986 val = data; in xen_pt_config_reg_init()
1990 " register size (%d)", offset, val, reg->size); in xen_pt_config_reg_init()
1995 * past reg->size, but in case this routine is run in parallel or the in xen_pt_config_reg_init()
1996 * init value is larger, we do not want to over-write registers. */ in xen_pt_config_reg_init()
1997 switch (reg->size) { in xen_pt_config_reg_init()
1998 case 1: pci_set_byte(s->dev.config + offset, (uint8_t)val); in xen_pt_config_reg_init()
2000 case 2: pci_set_word(s->dev.config + offset, (uint16_t)val); in xen_pt_config_reg_init()
2002 case 4: pci_set_long(s->dev.config + offset, val); in xen_pt_config_reg_init()
2006 /* set register value pointer to the data. */ in xen_pt_config_reg_init()
2007 reg_entry->ptr.byte = s->dev.config + offset; in xen_pt_config_reg_init()
2011 QLIST_INSERT_HEAD(®_grp->reg_tbl_list, reg_entry, entries); in xen_pt_config_reg_init()
2019 QLIST_INIT(&s->reg_grps); in xen_pt_config_init()
2027 if (xen_pt_hide_dev_cap(&s->real_device, in xen_pt_config_init()
2040 if (!is_igd_vga_passthrough(&s->real_device) || in xen_pt_config_init()
2041 s->real_device.vendor_id != PCI_VENDOR_ID_INTEL) { in xen_pt_config_init()
2053 QLIST_INIT(®_grp_entry->reg_tbl_list); in xen_pt_config_init()
2054 QLIST_INSERT_HEAD(&s->reg_grps, reg_grp_entry, entries); in xen_pt_config_init()
2056 reg_grp_entry->base_offset = reg_grp_offset; in xen_pt_config_init()
2057 reg_grp_entry->reg_grp = xen_pt_emu_reg_grps + i; in xen_pt_config_init()
2060 rc = xen_pt_emu_reg_grps[i].size_init(s, reg_grp_entry->reg_grp, in xen_pt_config_init()
2062 ®_grp_entry->size); in xen_pt_config_init()
2078 for (j = 0; regs->size != 0; j++, regs++) { in xen_pt_config_init()
2084 regs->offset, in xen_pt_config_init()
2100 struct XenPTReg *reg, *next_reg; in xen_pt_config_delete() local
2102 /* free MSI/MSI-X info table */ in xen_pt_config_delete()
2103 if (s->msix) { in xen_pt_config_delete()
2106 g_free(s->msi); in xen_pt_config_delete()
2109 QLIST_FOREACH_SAFE(reg_group, &s->reg_grps, entries, next_grp) { in xen_pt_config_delete()
2111 QLIST_FOREACH_SAFE(reg, ®_group->reg_tbl_list, entries, next_reg) { in xen_pt_config_delete()
2112 QLIST_REMOVE(reg, entries); in xen_pt_config_delete()
2113 g_free(reg); in xen_pt_config_delete()