Lines Matching +full:msi +full:- +full:base
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; member
133 * - be allowed by administrator to be used in this role in ppt_probe()
134 * - be an endpoint device in ppt_probe()
136 if ((dinfo->cfg.hdrtype & PCIM_HDRTYPE) != PCIM_HDRTYPE_NORMAL) in ppt_probe()
143 * SR-IOV infrastructure specified as "ppt" passthrough devices. in ppt_probe()
169 ppt->dev = dev; in ppt_attach()
185 if (ppt->vm != NULL) in ppt_detach()
195 num_pptdevs--; in ppt_detach()
220 dev = ppt->dev; in ppt_find()
230 if (ppt->vm != vm) /* Make sure we own this device */ in ppt_find()
243 seg = &ppt->mmio[i]; in ppt_unmap_all_mmio()
244 if (seg->len == 0) in ppt_unmap_all_mmio()
246 (void)vm_unmap_mmio(vm, seg->gpa, seg->len); in ppt_unmap_all_mmio()
258 if (ppt->msi.num_msgs == 0) in ppt_teardown_msi()
261 for (i = 0; i < ppt->msi.num_msgs; i++) { in ppt_teardown_msi()
262 rid = ppt->msi.startrid + i; in ppt_teardown_msi()
263 res = ppt->msi.res[i]; in ppt_teardown_msi()
264 cookie = ppt->msi.cookie[i]; in ppt_teardown_msi()
267 bus_teardown_intr(ppt->dev, res, cookie); in ppt_teardown_msi()
270 bus_release_resource(ppt->dev, SYS_RES_IRQ, rid, res); in ppt_teardown_msi()
272 ppt->msi.res[i] = NULL; in ppt_teardown_msi()
273 ppt->msi.cookie[i] = NULL; in ppt_teardown_msi()
276 if (ppt->msi.startrid == 1) in ppt_teardown_msi()
277 pci_release_msi(ppt->dev); in ppt_teardown_msi()
279 ppt->msi.num_msgs = 0; in ppt_teardown_msi()
289 rid = ppt->msix.startrid + idx; in ppt_teardown_msix_intr()
290 res = ppt->msix.res[idx]; in ppt_teardown_msix_intr()
291 cookie = ppt->msix.cookie[idx]; in ppt_teardown_msix_intr()
294 bus_teardown_intr(ppt->dev, res, cookie); in ppt_teardown_msix_intr()
297 bus_release_resource(ppt->dev, SYS_RES_IRQ, rid, res); in ppt_teardown_msix_intr()
299 ppt->msix.res[idx] = NULL; in ppt_teardown_msix_intr()
300 ppt->msix.cookie[idx] = NULL; in ppt_teardown_msix_intr()
308 if (ppt->msix.num_msgs == 0) in ppt_teardown_msix()
311 for (i = 0; i < ppt->msix.num_msgs; i++) in ppt_teardown_msix()
314 free(ppt->msix.res, M_PPTMSIX); in ppt_teardown_msix()
315 free(ppt->msix.cookie, M_PPTMSIX); in ppt_teardown_msix()
316 free(ppt->msix.arg, M_PPTMSIX); in ppt_teardown_msix()
318 pci_release_msi(ppt->dev); in ppt_teardown_msix()
320 if (ppt->msix.msix_table_res) { in ppt_teardown_msix()
321 bus_release_resource(ppt->dev, SYS_RES_MEMORY, in ppt_teardown_msix()
322 ppt->msix.msix_table_rid, in ppt_teardown_msix()
323 ppt->msix.msix_table_res); in ppt_teardown_msix()
324 ppt->msix.msix_table_res = NULL; in ppt_teardown_msix()
325 ppt->msix.msix_table_rid = 0; in ppt_teardown_msix()
327 if (ppt->msix.msix_pba_res) { in ppt_teardown_msix()
328 bus_release_resource(ppt->dev, SYS_RES_MEMORY, in ppt_teardown_msix()
329 ppt->msix.msix_pba_rid, in ppt_teardown_msix()
330 ppt->msix.msix_pba_res); in ppt_teardown_msix()
331 ppt->msix.msix_pba_res = NULL; in ppt_teardown_msix()
332 ppt->msix.msix_pba_rid = 0; in ppt_teardown_msix()
335 ppt->msix.num_msgs = 0; in ppt_teardown_msix()
346 if (ppt->vm == vm) in ppt_assigned_devices()
360 if (ppt->vm != vm) in ppt_is_mmio()
364 seg = &ppt->mmio[i]; in ppt_is_mmio()
365 if (seg->len == 0) in ppt_is_mmio()
367 if (gpa >= seg->gpa && gpa < seg->gpa + seg->len) in ppt_is_mmio()
393 for (pm = pci_first_bar(ppt->dev); pm != NULL; pm = pci_next_bar(pm)) { in ppt_bar_enables()
394 if (PCI_BAR_IO(pm->pm_value)) in ppt_bar_enables()
396 if (PCI_BAR_MEM(pm->pm_value)) in ppt_bar_enables()
414 pci_save_state(ppt->dev); in ppt_assign_device()
415 ppt_pci_reset(ppt->dev); in ppt_assign_device()
416 pci_restore_state(ppt->dev); in ppt_assign_device()
417 error = iommu_add_device(vm_iommu_domain(vm), ppt->dev, in ppt_assign_device()
418 pci_get_rid(ppt->dev)); in ppt_assign_device()
421 ppt->vm = vm; in ppt_assign_device()
422 cmd = pci_read_config(ppt->dev, PCIR_COMMAND, 2); in ppt_assign_device()
424 pci_write_config(ppt->dev, PCIR_COMMAND, cmd, 2); in ppt_assign_device()
439 cmd = pci_read_config(ppt->dev, PCIR_COMMAND, 2); in ppt_unassign_device()
441 pci_write_config(ppt->dev, PCIR_COMMAND, cmd, 2); in ppt_unassign_device()
442 pci_save_state(ppt->dev); in ppt_unassign_device()
443 ppt_pci_reset(ppt->dev); in ppt_unassign_device()
444 pci_restore_state(ppt->dev); in ppt_unassign_device()
448 error = iommu_remove_device(vm_iommu_domain(vm), ppt->dev, in ppt_unassign_device()
449 pci_get_rid(ppt->dev)); in ppt_unassign_device()
450 ppt->vm = NULL; in ppt_unassign_device()
462 if (ppt->vm == vm) { in ppt_unassign_all()
463 dev = ppt->dev; in ppt_unassign_all()
478 pci_addr_t base, size; in ppt_valid_bar_mapping() local
480 for (pm = pci_first_bar(ppt->dev); pm != NULL; pm = pci_next_bar(pm)) { in ppt_valid_bar_mapping()
481 if (!PCI_BAR_MEM(pm->pm_value)) in ppt_valid_bar_mapping()
483 base = pm->pm_value & PCIM_BAR_MEM_BASE; in ppt_valid_bar_mapping()
484 size = (pci_addr_t)1 << pm->pm_size; in ppt_valid_bar_mapping()
485 if (hpa >= base && hpa + len <= base + size) in ppt_valid_bar_mapping()
511 seg = &ppt->mmio[i]; in ppt_map_mmio()
512 if (seg->len == 0) { in ppt_map_mmio()
515 seg->gpa = gpa; in ppt_map_mmio()
516 seg->len = len; in ppt_map_mmio()
537 seg = &ppt->mmio[i]; in ppt_unmap_mmio()
538 if (seg->gpa == gpa && seg->len == len) { in ppt_unmap_mmio()
539 error = vm_unmap_mmio(vm, seg->gpa, seg->len); in ppt_unmap_mmio()
541 seg->gpa = 0; in ppt_unmap_mmio()
542 seg->len = 0; in ppt_unmap_mmio()
557 ppt = pptarg->pptdev; in pptintr()
559 if (ppt->vm != NULL) in pptintr()
560 lapic_intr_msi(ppt->vm, pptarg->addr, pptarg->msg_data); in pptintr()
564 * This is not expected to happen - panic? in pptintr()
572 if (ppt->msi.startrid == 0) in pptintr()
593 /* Reject attempts to enable MSI while MSI-X is active. */ in ppt_setup_msi()
594 if (ppt->msix.num_msgs != 0 && numvec != 0) in ppt_setup_msi()
604 msi_count = pci_msi_count(ppt->dev); in ppt_setup_msi()
610 startrid = 1; /* MSI */ in ppt_setup_msi()
620 * Make sure that we can allocate all the MSI vectors that are needed in ppt_setup_msi()
625 error = pci_alloc_msi(ppt->dev, &tmp); in ppt_setup_msi()
629 pci_release_msi(ppt->dev); in ppt_setup_msi()
636 ppt->msi.startrid = startrid; in ppt_setup_msi()
642 ppt->msi.num_msgs = i + 1; in ppt_setup_msi()
643 ppt->msi.cookie[i] = NULL; in ppt_setup_msi()
646 ppt->msi.res[i] = bus_alloc_resource_any(ppt->dev, SYS_RES_IRQ, in ppt_setup_msi()
648 if (ppt->msi.res[i] == NULL) in ppt_setup_msi()
651 ppt->msi.arg[i].pptdev = ppt; in ppt_setup_msi()
652 ppt->msi.arg[i].addr = addr; in ppt_setup_msi()
653 ppt->msi.arg[i].msg_data = msg + i; in ppt_setup_msi()
655 error = bus_setup_intr(ppt->dev, ppt->msi.res[i], in ppt_setup_msi()
657 pptintr, NULL, &ppt->msi.arg[i], in ppt_setup_msi()
658 &ppt->msi.cookie[i]); in ppt_setup_msi()
684 /* Reject attempts to enable MSI-X while MSI is active. */ in ppt_setup_msix()
685 if (ppt->msi.num_msgs != 0) in ppt_setup_msix()
688 dinfo = device_get_ivars(ppt->dev); in ppt_setup_msix()
693 * First-time configuration: in ppt_setup_msix()
694 * Allocate the MSI-X table in ppt_setup_msix()
696 * Set up some variables in ppt->msix in ppt_setup_msix()
698 if (ppt->msix.num_msgs == 0) { in ppt_setup_msix()
699 numvec = pci_msix_count(ppt->dev); in ppt_setup_msix()
703 ppt->msix.startrid = 1; in ppt_setup_msix()
704 ppt->msix.num_msgs = numvec; in ppt_setup_msix()
706 res_size = numvec * sizeof(ppt->msix.res[0]); in ppt_setup_msix()
707 cookie_size = numvec * sizeof(ppt->msix.cookie[0]); in ppt_setup_msix()
708 arg_size = numvec * sizeof(ppt->msix.arg[0]); in ppt_setup_msix()
710 ppt->msix.res = malloc(res_size, M_PPTMSIX, M_WAITOK | M_ZERO); in ppt_setup_msix()
711 ppt->msix.cookie = malloc(cookie_size, M_PPTMSIX, in ppt_setup_msix()
713 ppt->msix.arg = malloc(arg_size, M_PPTMSIX, M_WAITOK | M_ZERO); in ppt_setup_msix()
715 rid = dinfo->cfg.msix.msix_table_bar; in ppt_setup_msix()
716 ppt->msix.msix_table_res = bus_alloc_resource_any(ppt->dev, in ppt_setup_msix()
719 if (ppt->msix.msix_table_res == NULL) { in ppt_setup_msix()
723 ppt->msix.msix_table_rid = rid; in ppt_setup_msix()
725 if (dinfo->cfg.msix.msix_table_bar != in ppt_setup_msix()
726 dinfo->cfg.msix.msix_pba_bar) { in ppt_setup_msix()
727 rid = dinfo->cfg.msix.msix_pba_bar; in ppt_setup_msix()
728 ppt->msix.msix_pba_res = bus_alloc_resource_any( in ppt_setup_msix()
729 ppt->dev, SYS_RES_MEMORY, &rid, RF_ACTIVE); in ppt_setup_msix()
731 if (ppt->msix.msix_pba_res == NULL) { in ppt_setup_msix()
735 ppt->msix.msix_pba_rid = rid; in ppt_setup_msix()
739 error = pci_alloc_msix(ppt->dev, &alloced); in ppt_setup_msix()
746 if (idx >= ppt->msix.num_msgs) in ppt_setup_msix()
754 ppt->msix.cookie[idx] = NULL; in ppt_setup_msix()
755 rid = ppt->msix.startrid + idx; in ppt_setup_msix()
756 ppt->msix.res[idx] = bus_alloc_resource_any(ppt->dev, SYS_RES_IRQ, in ppt_setup_msix()
758 if (ppt->msix.res[idx] == NULL) in ppt_setup_msix()
761 ppt->msix.arg[idx].pptdev = ppt; in ppt_setup_msix()
762 ppt->msix.arg[idx].addr = addr; in ppt_setup_msix()
763 ppt->msix.arg[idx].msg_data = msg; in ppt_setup_msix()
765 /* Setup the MSI-X interrupt */ in ppt_setup_msix()
766 error = bus_setup_intr(ppt->dev, ppt->msix.res[idx], in ppt_setup_msix()
768 pptintr, NULL, &ppt->msix.arg[idx], in ppt_setup_msix()
769 &ppt->msix.cookie[idx]); in ppt_setup_msix()
772 bus_release_resource(ppt->dev, SYS_RES_IRQ, rid, ppt->msix.res[idx]); in ppt_setup_msix()
773 ppt->msix.cookie[idx] = NULL; in ppt_setup_msix()
774 ppt->msix.res[idx] = NULL; in ppt_setup_msix()