Download raw body.
acpidmar(4): Store PCI domain in softc for segment mapping
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",
acpidmar(4): Store PCI domain in softc for segment mapping