Lines Matching +full:rom +full:- +full:addr

6  * the COPYING file in the top-level directory.
22 * - Set real Interrupt Disable bit to '1'.
23 * - Set machine_irq and assigned_device->machine_irq to '0'.
28 * - Set real Interrupt Disable bit to '1'.
29 * - Unmap INTx.
30 * - Decrement xen_pt_mapped_machine_irq[machine_irq]
31 * - Set assigned_device->machine_irq to '0'.
35 * - Set real bit to '0' if assigned_device->machine_irq isn't '0'.
38 * - Set real bit to '1'.
44 * - Unmap MSI.
45 * - Set dev->msi->pirq to '-1'.
47 * MSI-X interrupt:
48 * Initialize MSI-X register(xen_pt_msix_update_one)
49 * Bind MSI-X(xc_domain_update_msi_irq)
51 * - Unmap MSI-X.
52 * - Set entry->pirq to '-1'.
60 #include "hw/qdev-properties.h"
61 #include "hw/qdev-properties-system.h"
65 #include "hw/xen/xen-legacy-backend.h"
90 PCI_SLOT(d->devfn), PCI_FUNC(d->devfn)); in xen_pt_log()
98 static int xen_pt_pci_config_access_check(PCIDevice *d, uint32_t addr, int len) in xen_pt_pci_config_access_check() argument
101 if (addr > 0xFF) { in xen_pt_pci_config_access_check()
103 "(addr: 0x%02x, len: %d)\n", addr, len); in xen_pt_pci_config_access_check()
104 return -1; in xen_pt_pci_config_access_check()
110 "(addr: 0x%02x, len: %d)\n", addr, len); in xen_pt_pci_config_access_check()
111 return -1; in xen_pt_pci_config_access_check()
115 if (addr & (len - 1)) { in xen_pt_pci_config_access_check()
117 "alignment. (addr: 0x%02x, len: %d)\n", addr, len); in xen_pt_pci_config_access_check()
118 return -1; in xen_pt_pci_config_access_check()
128 /* check Exp ROM BAR */ in xen_pt_bar_offset_to_index()
134 index = (offset - PCI_BASE_ADDRESS_0) >> 2; in xen_pt_bar_offset_to_index()
136 return -1; in xen_pt_bar_offset_to_index()
142 static uint32_t xen_pt_pci_read_config(PCIDevice *d, uint32_t addr, int len) in xen_pt_pci_read_config() argument
150 uint32_t find_addr = addr; in xen_pt_pci_read_config()
152 if (xen_pt_pci_config_access_check(d, addr, len)) { in xen_pt_pci_read_config()
157 reg_grp_entry = xen_pt_find_reg_grp(s, addr); in xen_pt_pci_read_config()
159 /* check 0-Hardwired register group */ in xen_pt_pci_read_config()
160 if (reg_grp_entry->reg_grp->grp_type == XEN_PT_GRP_TYPE_HARDWIRED) { in xen_pt_pci_read_config()
168 rc = xen_host_pci_get_block(&s->real_device, addr, (uint8_t *)&val, len); in xen_pt_pci_read_config()
180 /* adjust the read value to appropriate CFC-CFF window */ in xen_pt_pci_read_config()
181 val <<= (addr & 3) << 3; in xen_pt_pci_read_config()
189 XenPTRegInfo *reg = reg_entry->reg; in xen_pt_pci_read_config()
190 uint32_t real_offset = reg_grp_entry->base_offset + reg->offset; in xen_pt_pci_read_config()
191 uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3); in xen_pt_pci_read_config()
194 valid_mask <<= (find_addr - real_offset) << 3; in xen_pt_pci_read_config()
198 switch (reg->size) { in xen_pt_pci_read_config()
200 if (reg->u.b.read) { in xen_pt_pci_read_config()
201 rc = reg->u.b.read(s, reg_entry, ptr_val, valid_mask); in xen_pt_pci_read_config()
205 if (reg->u.w.read) { in xen_pt_pci_read_config()
206 rc = reg->u.w.read(s, reg_entry, in xen_pt_pci_read_config()
211 if (reg->u.dw.read) { in xen_pt_pci_read_config()
212 rc = reg->u.dw.read(s, reg_entry, in xen_pt_pci_read_config()
226 emul_len -= reg->size; in xen_pt_pci_read_config()
228 find_addr = real_offset + reg->size; in xen_pt_pci_read_config()
233 emul_len--; in xen_pt_pci_read_config()
239 val >>= ((addr & 3) << 3); in xen_pt_pci_read_config()
242 XEN_PT_LOG_CONFIG(d, addr, val, len); in xen_pt_pci_read_config()
246 static void xen_pt_pci_write_config(PCIDevice *d, uint32_t addr, in xen_pt_pci_write_config() argument
256 uint32_t find_addr = addr; in xen_pt_pci_write_config()
260 if (xen_pt_pci_config_access_check(d, addr, len)) { in xen_pt_pci_write_config()
264 XEN_PT_LOG_CONFIG(d, addr, val, len); in xen_pt_pci_write_config()
267 index = xen_pt_bar_offset_to_index(addr); in xen_pt_pci_write_config()
275 (s->bases[index].bar_flag == XEN_PT_BAR_FLAG_UNUSED)) { in xen_pt_pci_write_config()
277 "Base Address Register. (addr: 0x%02x, len: %d)\n", in xen_pt_pci_write_config()
278 addr, len); in xen_pt_pci_write_config()
283 reg_grp_entry = xen_pt_find_reg_grp(s, addr); in xen_pt_pci_write_config()
285 /* check 0-Hardwired register group */ in xen_pt_pci_write_config()
286 if (reg_grp_entry->reg_grp->grp_type == XEN_PT_GRP_TYPE_HARDWIRED) { in xen_pt_pci_write_config()
288 XEN_PT_WARN(d, "Access to 0-Hardwired register. " in xen_pt_pci_write_config()
289 "(addr: 0x%02x, len: %d)\n", addr, len); in xen_pt_pci_write_config()
294 rc = xen_host_pci_get_block(&s->real_device, addr, in xen_pt_pci_write_config()
301 wb_mask = 0xFFFFFFFF >> ((4 - len) << 3); in xen_pt_pci_write_config()
306 if (!s->permissive) { in xen_pt_pci_write_config()
314 pci_default_write_config(d, addr, val, len); in xen_pt_pci_write_config()
316 /* adjust the read and write value to appropriate CFC-CFF window */ in xen_pt_pci_write_config()
317 read_val <<= (addr & 3) << 3; in xen_pt_pci_write_config()
318 val <<= (addr & 3) << 3; in xen_pt_pci_write_config()
326 reg = reg_entry->reg; in xen_pt_pci_write_config()
327 uint32_t real_offset = reg_grp_entry->base_offset + reg->offset; in xen_pt_pci_write_config()
328 uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3); in xen_pt_pci_write_config()
330 uint32_t wp_mask = reg->emu_mask | reg->ro_mask; in xen_pt_pci_write_config()
332 valid_mask <<= (find_addr - real_offset) << 3; in xen_pt_pci_write_config()
334 if (!s->permissive) { in xen_pt_pci_write_config()
335 wp_mask |= reg->res_mask; in xen_pt_pci_write_config()
337 if (wp_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) { in xen_pt_pci_write_config()
338 wb_mask &= ~((wp_mask >> ((find_addr - real_offset) << 3)) in xen_pt_pci_write_config()
339 << ((len - emul_len) << 3)); in xen_pt_pci_write_config()
343 switch (reg->size) { in xen_pt_pci_write_config()
345 if (reg->u.b.write) { in xen_pt_pci_write_config()
346 rc = reg->u.b.write(s, reg_entry, ptr_val, in xen_pt_pci_write_config()
352 if (reg->u.w.write) { in xen_pt_pci_write_config()
353 rc = reg->u.w.write(s, reg_entry, (uint16_t *)ptr_val, in xen_pt_pci_write_config()
359 if (reg->u.dw.write) { in xen_pt_pci_write_config()
360 rc = reg->u.dw.write(s, reg_entry, (uint32_t *)ptr_val, in xen_pt_pci_write_config()
375 emul_len -= reg->size; in xen_pt_pci_write_config()
377 find_addr = real_offset + reg->size; in xen_pt_pci_write_config()
382 if (!s->permissive) { in xen_pt_pci_write_config()
383 wb_mask &= ~(0xff << ((len - emul_len) << 3)); in xen_pt_pci_write_config()
392 emul_len--; in xen_pt_pci_write_config()
398 val >>= (addr & 3) << 3; in xen_pt_pci_write_config()
403 if (wp_flag && !s->permissive_warned) { in xen_pt_pci_write_config()
404 s->permissive_warned = true; in xen_pt_pci_write_config()
405 xen_pt_log(d, "Write-back to unknown field 0x%02x (partially) inhibited (0x%0*x)\n", in xen_pt_pci_write_config()
406 addr, len * 2, wb_mask); in xen_pt_pci_write_config()
408 xen_pt_log(d, "(unsafe) and if it helps report the problem to xen-devel\n"); in xen_pt_pci_write_config()
421 rc = xen_host_pci_set_block(&s->real_device, addr + index, in xen_pt_pci_write_config()
432 static uint64_t xen_pt_bar_read(void *o, hwaddr addr, in xen_pt_bar_read() argument
439 addr); in xen_pt_bar_read()
442 static void xen_pt_bar_write(void *o, hwaddr addr, uint64_t val, in xen_pt_bar_write() argument
448 addr); in xen_pt_bar_write()
460 XenHostPCIDevice *d = &s->real_device; in xen_pt_register_regions()
464 XenHostPCIIORegion *r = &d->io_regions[i]; in xen_pt_register_regions()
467 if (r->base_addr == 0 || r->size == 0) { in xen_pt_register_regions()
471 s->bases[i].access.u = r->base_addr; in xen_pt_register_regions()
473 if (r->type & XEN_HOST_PCI_REGION_TYPE_IO) { in xen_pt_register_regions()
478 if (r->type & XEN_HOST_PCI_REGION_TYPE_PREFETCH) { in xen_pt_register_regions()
481 if (r->type & XEN_HOST_PCI_REGION_TYPE_MEM_64) { in xen_pt_register_regions()
487 memory_region_init_io(&s->bar[i], OBJECT(s), &ops, &s->dev, in xen_pt_register_regions()
488 "xen-pci-pt-bar", r->size); in xen_pt_register_regions()
489 pci_register_bar(&s->dev, i, type, &s->bar[i]); in xen_pt_register_regions()
491 XEN_PT_LOG(&s->dev, "IO region %i registered (size=0x%08"PRIx64 in xen_pt_register_regions()
493 i, r->size, r->base_addr, type); in xen_pt_register_regions()
496 /* Register expansion ROM address */ in xen_pt_register_regions()
497 if (d->rom.base_addr && d->rom.size) { in xen_pt_register_regions()
500 /* Re-set BAR reported by OS, otherwise ROM can't be read. */ in xen_pt_register_regions()
505 bar_data |= d->rom.base_addr & PCI_ROM_ADDRESS_MASK; in xen_pt_register_regions()
509 s->bases[PCI_ROM_SLOT].access.maddr = d->rom.base_addr; in xen_pt_register_regions()
511 memory_region_init_io(&s->rom, OBJECT(s), &ops, &s->dev, in xen_pt_register_regions()
512 "xen-pci-pt-rom", d->rom.size); in xen_pt_register_regions()
513 pci_register_bar(&s->dev, PCI_ROM_SLOT, PCI_BASE_ADDRESS_MEM_PREFETCH, in xen_pt_register_regions()
514 &s->rom); in xen_pt_register_regions()
516 XEN_PT_LOG(&s->dev, "Expansion ROM registered (size=0x%08"PRIx64 in xen_pt_register_regions()
518 d->rom.size, d->rom.base_addr); in xen_pt_register_regions()
531 for (i = 0; i < PCI_NUM_REGIONS - 1; i++) { in xen_pt_bar_from_region()
532 if (mr == &s->bar[i]) { in xen_pt_bar_from_region()
536 if (mr == &s->rom) { in xen_pt_bar_from_region()
539 return -1; in xen_pt_bar_from_region()
544 * device. The io_region to check is provided with (addr, size and type)
550 pcibus_t addr; member
558 XenPCIPassthroughState *s = arg->s; in xen_pt_check_bar_overlap()
559 uint8_t type = arg->type; in xen_pt_check_bar_overlap()
562 if (d->devfn == s->dev.devfn) { in xen_pt_check_bar_overlap()
568 const PCIIORegion *r = &d->io_regions[i]; in xen_pt_check_bar_overlap()
570 if (!r->size) { in xen_pt_check_bar_overlap()
574 != (r->type & PCI_BASE_ADDRESS_SPACE_IO)) { in xen_pt_check_bar_overlap()
578 if (ranges_overlap(arg->addr, arg->size, r->addr, r->size)) { in xen_pt_check_bar_overlap()
579 XEN_PT_WARN(&s->dev, in xen_pt_check_bar_overlap()
581 " (addr: 0x%"FMT_PCIBUS", len: 0x%"FMT_PCIBUS")\n", in xen_pt_check_bar_overlap()
582 pci_bus_num(bus), PCI_SLOT(d->devfn), in xen_pt_check_bar_overlap()
583 PCI_FUNC(d->devfn), i, r->addr, r->size); in xen_pt_check_bar_overlap()
584 arg->rc = true; in xen_pt_check_bar_overlap()
592 PCIDevice *d = &s->dev; in xen_pt_region_update()
593 MemoryRegion *mr = sec->mr; in xen_pt_region_update()
594 int bar = -1; in xen_pt_region_update()
599 .addr = sec->offset_within_address_space, in xen_pt_region_update()
600 .size = int128_get64(sec->size), in xen_pt_region_update()
605 if (bar == -1 && (!s->msix || &s->msix->mmio != mr)) { in xen_pt_region_update()
609 if (s->msix && &s->msix->mmio == mr) { in xen_pt_region_update()
611 s->msix->mmio_base_addr = sec->offset_within_address_space; in xen_pt_region_update()
612 rc = xen_pt_msix_update_remap(s, s->msix->bar_index); in xen_pt_region_update()
617 args.type = d->io_regions[bar].type; in xen_pt_region_update()
621 XEN_PT_WARN(d, "Region: %d (addr: 0x%"FMT_PCIBUS in xen_pt_region_update()
623 bar, sec->offset_within_address_space, in xen_pt_region_update()
624 int128_get64(sec->size)); in xen_pt_region_update()
627 if (d->io_regions[bar].type & PCI_BASE_ADDRESS_SPACE_IO) { in xen_pt_region_update()
628 uint32_t guest_port = sec->offset_within_address_space; in xen_pt_region_update()
629 uint32_t machine_port = s->bases[bar].access.pio_base; in xen_pt_region_update()
630 uint32_t size = int128_get64(sec->size); in xen_pt_region_update()
639 pcibus_t guest_addr = sec->offset_within_address_space; in xen_pt_region_update()
640 pcibus_t machine_addr = s->bases[bar].access.maddr in xen_pt_region_update()
641 + sec->offset_within_region; in xen_pt_region_update()
642 pcibus_t size = int128_get64(sec->size); in xen_pt_region_update()
644 XEN_PFN(guest_addr + XC_PAGE_SIZE - 1), in xen_pt_region_update()
645 XEN_PFN(machine_addr + XC_PAGE_SIZE - 1), in xen_pt_region_update()
646 XEN_PFN(size + XC_PAGE_SIZE - 1), in xen_pt_region_update()
660 memory_region_ref(sec->mr); in xen_pt_region_add()
670 memory_region_unref(sec->mr); in xen_pt_region_del()
678 memory_region_ref(sec->mr); in xen_pt_io_region_add()
688 memory_region_unref(sec->mr); in xen_pt_io_region_del()
692 .name = "xen-pt-mem",
699 .name = "xen-pt-io",
709 XenHostPCIDevice *host_dev = &s->real_device; in xen_pt_destroy()
710 uint8_t machine_irq = s->machine_irq; in xen_pt_destroy()
719 PCI_SLOT(s->dev.devfn), in xen_pt_destroy()
731 if (s->msi) { in xen_pt_destroy()
734 if (s->msix) { in xen_pt_destroy()
739 xen_pt_mapped_machine_irq[machine_irq]--; in xen_pt_destroy()
750 s->machine_irq = 0; in xen_pt_destroy()
758 if (s->listener_set) { in xen_pt_destroy()
759 memory_listener_unregister(&s->memory_listener); in xen_pt_destroy()
760 memory_listener_unregister(&s->io_listener); in xen_pt_destroy()
761 s->listener_set = false; in xen_pt_destroy()
790 type[len - 1] = '\0'; in xen_pt_need_gsi()
808 PCI_SBDF(s->real_device.domain, in xen_pt_map_pirq_for_gsi()
809 s->real_device.bus, in xen_pt_map_pirq_for_gsi()
810 s->real_device.dev, in xen_pt_map_pirq_for_gsi()
811 s->real_device.func)); in xen_pt_map_pirq_for_gsi()
832 s->hostaddr.bus, s->hostaddr.slot, s->hostaddr.function, in xen_pt_realize()
833 s->dev.devfn); in xen_pt_realize()
835 s->is_virtfn = s->real_device.is_virtfn; in xen_pt_realize()
836 if (s->is_virtfn) { in xen_pt_realize()
837 XEN_PT_LOG(d, "%04x:%02x:%02x.%d is a SR-IOV Virtual Function\n", in xen_pt_realize()
838 s->real_device.domain, s->real_device.bus, in xen_pt_realize()
839 s->real_device.dev, s->real_device.func); in xen_pt_realize()
843 memset(d->config, 0, PCI_CONFIG_SPACE_SIZE); in xen_pt_realize()
845 s->memory_listener = xen_pt_memory_listener; in xen_pt_realize()
846 s->io_listener = xen_pt_io_listener; in xen_pt_realize()
849 if ((s->real_device.domain == XEN_PCI_IGD_DOMAIN) && in xen_pt_realize()
850 (s->real_device.bus == XEN_PCI_IGD_BUS) && in xen_pt_realize()
851 (s->real_device.dev == XEN_PCI_IGD_DEV) && in xen_pt_realize()
852 (s->real_device.func == XEN_PCI_IGD_FN)) { in xen_pt_realize()
853 if (!is_igd_vga_passthrough(&s->real_device)) { in xen_pt_realize()
854 error_setg(errp, "Need to enable igd-passthru if you're trying" in xen_pt_realize()
856 xen_host_pci_device_put(&s->real_device); in xen_pt_realize()
860 xen_pt_setup_vga(s, &s->real_device, errp); in xen_pt_realize()
864 xen_host_pci_device_put(&s->real_device); in xen_pt_realize()
869 xen_igd_passthrough_isa_bridge_create(s, &s->real_device); in xen_pt_realize()
879 rc = -1; in xen_pt_realize()
884 rc = xen_host_pci_get_byte(&s->real_device, PCI_INTERRUPT_PIN, &scratch); in xen_pt_realize()
894 machine_irq = s->real_device.irq; in xen_pt_realize()
918 s->machine_irq = 0; in xen_pt_realize()
921 s->machine_irq = pirq; in xen_pt_realize()
931 PCI_SLOT(d->devfn), in xen_pt_realize()
939 xen_pt_mapped_machine_irq[machine_irq]--; in xen_pt_realize()
947 s->machine_irq = 0; in xen_pt_realize()
955 rc = xen_host_pci_get_word(&s->real_device, PCI_COMMAND, &val); in xen_pt_realize()
961 rc = xen_host_pci_set_word(&s->real_device, PCI_COMMAND, val); in xen_pt_realize()
970 memory_listener_register(&s->memory_listener, &address_space_memory); in xen_pt_realize()
971 memory_listener_register(&s->io_listener, &address_space_io); in xen_pt_realize()
972 s->listener_set = true; in xen_pt_realize()
975 s->hostaddr.bus, s->hostaddr.slot, s->hostaddr.function); in xen_pt_realize()
981 object_unparent(OBJECT(&s->bar[i])); in xen_pt_realize()
983 object_unparent(OBJECT(&s->rom)); in xen_pt_realize()
1003 PCI_DEVICE(obj)->cap_present |= QEMU_PCI_CAP_EXPRESS; in xen_pci_passthrough_instance_init()
1024 xen_host_pci_device_get(&s->real_device, in xen_igd_clear_slot()
1025 s->hostaddr.domain, s->hostaddr.bus, in xen_igd_clear_slot()
1026 s->hostaddr.slot, s->hostaddr.function, in xen_igd_clear_slot()
1034 xpdc->pci_qdev_realize(qdev, errp); in xen_igd_clear_slot()
1038 if (is_igd_vga_passthrough(&s->real_device) && in xen_igd_clear_slot()
1039 s->real_device.domain == XEN_PCI_IGD_DOMAIN && in xen_igd_clear_slot()
1040 s->real_device.bus == XEN_PCI_IGD_BUS && in xen_igd_clear_slot()
1041 s->real_device.dev == XEN_PCI_IGD_DEV && in xen_igd_clear_slot()
1042 s->real_device.func == XEN_PCI_IGD_FN && in xen_igd_clear_slot()
1043 s->real_device.vendor_id == PCI_VENDOR_ID_INTEL) { in xen_igd_clear_slot()
1047 xpdc->pci_qdev_realize(qdev, errp); in xen_igd_clear_slot()
1056 xpdc->pci_qdev_realize = dc->realize; in xen_pci_passthrough_class_init()
1057 dc->realize = xen_igd_clear_slot; in xen_pci_passthrough_class_init()
1058 k->realize = xen_pt_realize; in xen_pci_passthrough_class_init()
1059 k->exit = xen_pt_unregister_device; in xen_pci_passthrough_class_init()
1060 k->config_read = xen_pt_pci_read_config; in xen_pci_passthrough_class_init()
1061 k->config_write = xen_pt_pci_write_config; in xen_pci_passthrough_class_init()
1062 set_bit(DEVICE_CATEGORY_MISC, dc->categories); in xen_pci_passthrough_class_init()
1063 dc->desc = "Assign an host PCI device with Xen"; in xen_pci_passthrough_class_init()