From: hshoexer Subject: acpidmar(4): Store PCI domain in softc for segment mapping To: tech@openbsd.org Date: Tue, 28 Jul 2026 15:39:46 +0200 Hi, with this change I store the PCI domain in the softc. Later I use that value when mapping domain to segment. Instead of counting. Also fall back to segment 0, when ACPI did not provide a segment. This actually enforces use of the IOMMU. While there: - tweak printf to use segment instead of PCI domain - use ACPI provided segment instead of hardcoded 0 in ivhd_showpage() ok? Take care, HJ. ----------------------------------------------------------------------------- diff --git a/sys/arch/amd64/pci/acpipci.c b/sys/arch/amd64/pci/acpipci.c index e3121987654..e5e861662d7 100644 --- a/sys/arch/amd64/pci/acpipci.c +++ b/sys/arch/amd64/pci/acpipci.c @@ -66,6 +66,7 @@ struct acpipci_softc { char sc_memex_name[32]; int sc_bus; uint32_t sc_seg; + int sc_domain; }; int acpipci_match(struct device *, void *, void *); @@ -97,15 +98,14 @@ int acpipci_domain_to_seg(int domain) { struct acpipci_softc *sc; - int i, d = 0; + int i; for (i = 0; i < acpipci_cd.cd_ndevs; i++) { sc = (struct acpipci_softc *)acpipci_cd.cd_devs[i]; if (sc == NULL) continue; - if (d == domain) + if (sc->sc_domain == domain) return sc->sc_seg; - d++; } return -1; @@ -147,6 +147,9 @@ acpipci_attach(struct device *parent, struct device *self, void *aux) aml_evalinteger(sc->sc_acpi, sc->sc_node, "_SEG", 0, NULL, &seg); sc->sc_seg = seg; + /* Assigned when the PCI bus attaches. */ + sc->sc_domain = -1; + if (aml_evalname(sc->sc_acpi, sc->sc_node, "_CRS", 0, NULL, &res)) { printf(": can't find resources\n"); @@ -210,6 +213,7 @@ acpipci_attach_bus(struct device *parent, struct acpipci_softc *sc) pba.pba_pmemex = sc->sc_memex; pba.pba_domain = pci_ndomains++; pba.pba_bus = sc->sc_bus; + sc->sc_domain = pba.pba_domain; /* Enable MSI in ACPI 2.0 and above, unless we're told not to. */ if (sc->sc_acpi->sc_fadt->hdr.revision >= 2 && diff --git a/sys/dev/acpi/acpidmar.c b/sys/dev/acpi/acpidmar.c index 57b90ddb193..cf18265fd09 100644 --- a/sys/dev/acpi/acpidmar.c +++ b/sys/dev/acpi/acpidmar.c @@ -2581,9 +2581,8 @@ acpidmar_pci_hook(pci_chipset_tag_t pc, struct pci_attach_args *pa) segment = acpipci_domain_to_seg(pa->pa_domain); if (segment < 0) { - DPRINTF(1, "acpidmar: no ACPI segment for pci domain %d\n", - pa->pa_domain); - return; + /* Fall back to segment 0. */ + segment = 0; } /* Record PCI-PCI bridge forwarding windows */ @@ -2608,7 +2607,7 @@ acpidmar_pci_hook(pci_chipset_tag_t pc, struct pci_attach_args *pa) PCI_SUBCLASS(reg) == PCI_SUBCLASS_BRIDGE_ISA) { /* For ISA Bridges, map 0-16Mb as 1:1 */ printf("dmar: %.4x:%.2x:%.2x.%x mapping ISA\n", - pa->pa_domain, bus, dev, fun); + segment, bus, dev, fun); domain_map_pthru(dom, 0x00, 16*1024*1024); /* Keep the identity mapped IOVA range out of the allocator */ @@ -2917,7 +2916,7 @@ ivhd_showpage(struct iommu_softc *iommu, int sid, paddr_t paddr) if (show > 10) return; show++; - dom = acpidmar_pci_attach(acpidmar_sc, 0, sid, 0); + dom = acpidmar_pci_attach(acpidmar_sc, iommu->segment, sid, 0); if (!dom) return; printf("DTE: %.8x %.8x %.8x %.8x %.8x %.8x %.8x %.8x\n",