Lines Matching +full:msi +full:- +full:x

1 /*-
2 * SPDX-License-Identifier: BSD-2-Clause
59 * If the MSI-X table is located in the middle of a BAR then that MMIO
60 * region gets split into two segments - one segment above the MSI-X table
61 * and the other segment below the MSI-X table - with a hole in place of
62 * the MSI-X table so accesses to it can be trapped and emulated.
68 MALLOC_DEFINE(M_PPTMSIX, "pptmsix", "Passthru MSI-X resources");
94 } msi;
133 * - be allowed by administrator to be used in this role
134 * - be an endpoint device
136 if ((dinfo->cfg.hdrtype & PCIM_HDRTYPE) != PCIM_HDRTYPE_NORMAL)
143 * SR-IOV infrastructure specified as "ppt" passthrough devices.
164 ppt->dev = dev;
179 if (ppt->vm != NULL)
181 num_pptdevs--;
209 dev = ppt->dev;
219 if (ppt->vm != vm) /* Make sure we own this device */
232 seg = &ppt->mmio[i];
233 if (seg->len == 0)
235 (void)vm_unmap_mmio(vm, seg->gpa, seg->len);
247 if (ppt->msi.num_msgs == 0)
250 for (i = 0; i < ppt->msi.num_msgs; i++) {
251 rid = ppt->msi.startrid + i;
252 res = ppt->msi.res[i];
253 cookie = ppt->msi.cookie[i];
256 bus_teardown_intr(ppt->dev, res, cookie);
259 bus_release_resource(ppt->dev, SYS_RES_IRQ, rid, res);
261 ppt->msi.res[i] = NULL;
262 ppt->msi.cookie[i] = NULL;
265 if (ppt->msi.startrid == 1)
266 pci_release_msi(ppt->dev);
268 ppt->msi.num_msgs = 0;
278 rid = ppt->msix.startrid + idx;
279 res = ppt->msix.res[idx];
280 cookie = ppt->msix.cookie[idx];
283 bus_teardown_intr(ppt->dev, res, cookie);
286 bus_release_resource(ppt->dev, SYS_RES_IRQ, rid, res);
288 ppt->msix.res[idx] = NULL;
289 ppt->msix.cookie[idx] = NULL;
297 if (ppt->msix.num_msgs == 0)
300 for (i = 0; i < ppt->msix.num_msgs; i++)
303 free(ppt->msix.res, M_PPTMSIX);
304 free(ppt->msix.cookie, M_PPTMSIX);
305 free(ppt->msix.arg, M_PPTMSIX);
307 pci_release_msi(ppt->dev);
309 if (ppt->msix.msix_table_res) {
310 bus_release_resource(ppt->dev, SYS_RES_MEMORY,
311 ppt->msix.msix_table_rid,
312 ppt->msix.msix_table_res);
313 ppt->msix.msix_table_res = NULL;
314 ppt->msix.msix_table_rid = 0;
316 if (ppt->msix.msix_pba_res) {
317 bus_release_resource(ppt->dev, SYS_RES_MEMORY,
318 ppt->msix.msix_pba_rid,
319 ppt->msix.msix_pba_res);
320 ppt->msix.msix_pba_res = NULL;
321 ppt->msix.msix_pba_rid = 0;
324 ppt->msix.num_msgs = 0;
342 if (ppt->vm == vm)
356 if (ppt->vm != vm)
360 seg = &ppt->mmio[i];
361 if (seg->len == 0)
363 if (gpa >= seg->gpa && gpa < seg->gpa + seg->len)
389 for (pm = pci_first_bar(ppt->dev); pm != NULL; pm = pci_next_bar(pm)) {
390 if (PCI_BAR_IO(pm->pm_value))
392 if (PCI_BAR_MEM(pm->pm_value))
410 pci_save_state(ppt->dev);
411 ppt_pci_reset(ppt->dev);
412 pci_restore_state(ppt->dev);
413 ppt->vm = vm;
414 iommu_add_device(vm_iommu_domain(vm), pci_get_rid(ppt->dev));
415 cmd = pci_read_config(ppt->dev, PCIR_COMMAND, 2);
417 pci_write_config(ppt->dev, PCIR_COMMAND, cmd, 2);
432 cmd = pci_read_config(ppt->dev, PCIR_COMMAND, 2);
434 pci_write_config(ppt->dev, PCIR_COMMAND, cmd, 2);
435 pci_save_state(ppt->dev);
436 ppt_pci_reset(ppt->dev);
437 pci_restore_state(ppt->dev);
441 iommu_remove_device(vm_iommu_domain(vm), pci_get_rid(ppt->dev));
442 ppt->vm = NULL;
454 if (ppt->vm == vm) {
455 dev = ppt->dev;
472 for (pm = pci_first_bar(ppt->dev); pm != NULL; pm = pci_next_bar(pm)) {
473 if (!PCI_BAR_MEM(pm->pm_value))
475 base = pm->pm_value & PCIM_BAR_MEM_BASE;
476 size = (pci_addr_t)1 << pm->pm_size;
503 seg = &ppt->mmio[i];
504 if (seg->len == 0) {
507 seg->gpa = gpa;
508 seg->len = len;
529 seg = &ppt->mmio[i];
530 if (seg->gpa == gpa && seg->len == len) {
531 error = vm_unmap_mmio(vm, seg->gpa, seg->len);
533 seg->gpa = 0;
534 seg->len = 0;
549 ppt = pptarg->pptdev;
551 if (ppt->vm != NULL)
552 lapic_intr_msi(ppt->vm, pptarg->addr, pptarg->msg_data);
556 * This is not expected to happen - panic?
564 if (ppt->msi.startrid == 0)
585 /* Reject attempts to enable MSI while MSI-X is active. */
586 if (ppt->msix.num_msgs != 0 && numvec != 0)
596 msi_count = pci_msi_count(ppt->dev);
602 startrid = 1; /* MSI */
612 * Make sure that we can allocate all the MSI vectors that are needed
617 error = pci_alloc_msi(ppt->dev, &tmp);
621 pci_release_msi(ppt->dev);
628 ppt->msi.startrid = startrid;
634 ppt->msi.num_msgs = i + 1;
635 ppt->msi.cookie[i] = NULL;
638 ppt->msi.res[i] = bus_alloc_resource_any(ppt->dev, SYS_RES_IRQ,
640 if (ppt->msi.res[i] == NULL)
643 ppt->msi.arg[i].pptdev = ppt;
644 ppt->msi.arg[i].addr = addr;
645 ppt->msi.arg[i].msg_data = msg + i;
647 error = bus_setup_intr(ppt->dev, ppt->msi.res[i],
649 pptintr, NULL, &ppt->msi.arg[i],
650 &ppt->msi.cookie[i]);
676 /* Reject attempts to enable MSI-X while MSI is active. */
677 if (ppt->msi.num_msgs != 0)
680 dinfo = device_get_ivars(ppt->dev);
685 * First-time configuration:
686 * Allocate the MSI-X table
688 * Set up some variables in ppt->msix
690 if (ppt->msix.num_msgs == 0) {
691 numvec = pci_msix_count(ppt->dev);
695 ppt->msix.startrid = 1;
696 ppt->msix.num_msgs = numvec;
698 res_size = numvec * sizeof(ppt->msix.res[0]);
699 cookie_size = numvec * sizeof(ppt->msix.cookie[0]);
700 arg_size = numvec * sizeof(ppt->msix.arg[0]);
702 ppt->msix.res = malloc(res_size, M_PPTMSIX, M_WAITOK | M_ZERO);
703 ppt->msix.cookie = malloc(cookie_size, M_PPTMSIX,
705 ppt->msix.arg = malloc(arg_size, M_PPTMSIX, M_WAITOK | M_ZERO);
707 rid = dinfo->cfg.msix.msix_table_bar;
708 ppt->msix.msix_table_res = bus_alloc_resource_any(ppt->dev,
711 if (ppt->msix.msix_table_res == NULL) {
715 ppt->msix.msix_table_rid = rid;
717 if (dinfo->cfg.msix.msix_table_bar !=
718 dinfo->cfg.msix.msix_pba_bar) {
719 rid = dinfo->cfg.msix.msix_pba_bar;
720 ppt->msix.msix_pba_res = bus_alloc_resource_any(
721 ppt->dev, SYS_RES_MEMORY, &rid, RF_ACTIVE);
723 if (ppt->msix.msix_pba_res == NULL) {
727 ppt->msix.msix_pba_rid = rid;
731 error = pci_alloc_msix(ppt->dev, &alloced);
743 ppt->msix.cookie[idx] = NULL;
744 rid = ppt->msix.startrid + idx;
745 ppt->msix.res[idx] = bus_alloc_resource_any(ppt->dev, SYS_RES_IRQ,
747 if (ppt->msix.res[idx] == NULL)
750 ppt->msix.arg[idx].pptdev = ppt;
751 ppt->msix.arg[idx].addr = addr;
752 ppt->msix.arg[idx].msg_data = msg;
754 /* Setup the MSI-X interrupt */
755 error = bus_setup_intr(ppt->dev, ppt->msix.res[idx],
757 pptintr, NULL, &ppt->msix.arg[idx],
758 &ppt->msix.cookie[idx]);
761 bus_release_resource(ppt->dev, SYS_RES_IRQ, rid, ppt->msix.res[idx]);
762 ppt->msix.cookie[idx] = NULL;
763 ppt->msix.res[idx] = NULL;