From nobody Sat May 7 10:20:31 2022 X-Original-To: dev-commits-src-all@mlmmj.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mlmmj.nyi.freebsd.org (Postfix) with ESMTP id E4D181AC5CE8; Sat, 7 May 2022 10:20:31 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from mxrelay.nyi.freebsd.org (mxrelay.nyi.freebsd.org [IPv6:2610:1c1:1:606c::19:3]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256 client-signature RSA-PSS (4096 bits) client-digest SHA256) (Client CN "mxrelay.nyi.freebsd.org", Issuer "R3" (verified OK)) by mx1.freebsd.org (Postfix) with ESMTPS id 4KwNjq5SYtz4nQ8; Sat, 7 May 2022 10:20:31 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1651918831; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Tp1pud98Qf0aHFnhVRThlmO67KsavcuvB+0BgA8lXN4=; b=OlDDtK1qlZE+AjNbhc+w51zmgDQN8AOHIP3ukIrexvlVK+nb8LbC8qI7mc8bQTDmI2XfGz /fCawba8iCZ2/iRdZxjJQuQrkXMwrE7409L7CIvUoceD5GZpMw2770nhSALjXQ3WDd5VDE YBTaJoNrHSJ3bj23h3TElY2yK/rBZfTZsZg9xlk4CRXUZNVj0zJzbfjca8aZ1ih4XoHozt 6aIOGhgcXaubGY/9icYnTTozc8l4EkSeRyS3L01erBCvZ1qPPSJjn0Qvla3xct78cfSQYx PDkq8kC+Sy46YJ2WyIfJ+PfwTRF0ZhcBlVpetL/g2sI370uhDyfvrlicpaFRBQ== Received: from gitrepo.freebsd.org (gitrepo.freebsd.org [IPv6:2610:1c1:1:6068::e6a:5]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (Client did not present a certificate) by mxrelay.nyi.freebsd.org (Postfix) with ESMTPS id 9B4496C22; Sat, 7 May 2022 10:20:31 +0000 (UTC) (envelope-from git@FreeBSD.org) Received: from gitrepo.freebsd.org ([127.0.1.44]) by gitrepo.freebsd.org (8.16.1/8.16.1) with ESMTP id 247AKVlE064636; Sat, 7 May 2022 10:20:31 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 247AKV0B064635; Sat, 7 May 2022 10:20:31 GMT (envelope-from git) Date: Sat, 7 May 2022 10:20:31 GMT Message-Id: <202205071020.247AKV0B064635@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Ruslan Bukin Subject: git: a5ec261a7c57 - main - Add FDT attachment driver for ARM System MMU v3.2 controller. List-Id: Commit messages for all branches of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-all List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-all@freebsd.org X-BeenThere: dev-commits-src-all@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: br X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: a5ec261a7c57758e9b77c1c3af0bdbb5165b3e3c Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1651918831; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=Tp1pud98Qf0aHFnhVRThlmO67KsavcuvB+0BgA8lXN4=; b=DMA8grw3WOfROu0rmsRTG5dpY0JVnOfp8iVxXIPn2k/KRjakhXVkBQiFL8UK9uwS7JLOI1 7zAWwrcoGlq+YmFgIbfnGY8UpchmKK4W0qqGAIC2tskPR6piNA20JgLbtijrD1Zr6BvYEQ RyFJMjzrrnBiTMQ/14K+PbLVCCGBJqSkOFOhhSnJJxRbGYUcELFQIRj30p0tczw/97Nw2J EEaOEspG+ufJefo54MkdzIFyS8DegI08P12JT+18SerAi+WsN+NXq8V5iuNSj80b/5ey3G 8/JmdzBy264/JKt6L7+eZVjnUrJ2eLkKwjjvVsfin+qQrnu57HiKu62QkEnt9w== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1651918831; a=rsa-sha256; cv=none; b=ZOHLswj6UKA/CfeOsj7xbT/41nsj2MTqIuY8h0aXdJfug0/SR3V2dp2KVs6cNpqIzjKY8k Cgsa0LqaP1usTgPW6wO8x9DP9hHjewtQAbLdp1E5GVvPZ7lv6ctkvd9zTVM2gsiBm7siDA RinYe00e/r5JI6gxAgnmbBG/jBptzbBjrCqmF5Zx/fo21CNm8geasuwC30nHjtIROm+muR GgXEmvqwjWZAxZulOsPf0YCN2VNMK1x8VsGhNMKgGe882NOk/S/kP9w6KMKh6iAZvUQ/Bl zP/7OAXstRYDAE/ZeUMbza3cZl92nU6Yh0ErTMu3uD/V5MSzuhSh4nrT2MUQLw== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by br: URL: https://cgit.FreeBSD.org/src/commit/?id=a5ec261a7c57758e9b77c1c3af0bdbb5165b3e3c commit a5ec261a7c57758e9b77c1c3af0bdbb5165b3e3c Author: Ruslan Bukin AuthorDate: 2022-05-07 10:13:46 +0000 Commit: Ruslan Bukin CommitDate: 2022-05-07 10:18:35 +0000 Add FDT attachment driver for ARM System MMU v3.2 controller. Tested on ARM Morello Board. Sponsored by: UKRI --- sys/arm64/iommu/smmu.c | 63 ++++++++++++++++---- sys/arm64/iommu/smmu_acpi.c | 4 +- sys/arm64/iommu/smmu_fdt.c | 138 ++++++++++++++++++++++++++++++++++++++++++++ sys/arm64/iommu/smmuvar.h | 2 +- sys/conf/files.arm64 | 3 +- 5 files changed, 195 insertions(+), 15 deletions(-) diff --git a/sys/arm64/iommu/smmu.c b/sys/arm64/iommu/smmu.c index 1f2d7283be72..74b68ce1d07a 100644 --- a/sys/arm64/iommu/smmu.c +++ b/sys/arm64/iommu/smmu.c @@ -98,13 +98,15 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include +#include #include #include #include #include -#if DEV_ACPI +#ifdef DEV_ACPI #include #include #endif @@ -113,6 +115,14 @@ __FBSDID("$FreeBSD$"); #include #include +#include + +#ifdef FDT +#include +#include +#include +#endif + #include "iommu.h" #include "iommu_if.h" @@ -144,6 +154,7 @@ static struct resource_spec smmu_spec[] = { { SYS_RES_IRQ, 0, RF_ACTIVE }, { SYS_RES_IRQ, 1, RF_ACTIVE }, { SYS_RES_IRQ, 2, RF_ACTIVE }, + { SYS_RES_IRQ, 3, RF_ACTIVE }, RESOURCE_SPEC_END }; @@ -1129,7 +1140,7 @@ smmu_enable_interrupts(struct smmu_softc *sc) return (0); } -#if DEV_ACPI +#ifdef DEV_ACPI static void smmu_configure_intr(struct smmu_softc *sc, struct resource *res) { @@ -1155,14 +1166,15 @@ smmu_setup_interrupts(struct smmu_softc *sc) dev = sc->dev; -#if DEV_ACPI +#ifdef DEV_ACPI /* * Configure SMMU interrupts as EDGE triggered manually * as ACPI tables carries no information for that. */ smmu_configure_intr(sc, sc->res[1]); - smmu_configure_intr(sc, sc->res[2]); + /* PRIQ is not in use. */ smmu_configure_intr(sc, sc->res[3]); + smmu_configure_intr(sc, sc->res[4]); #endif error = bus_setup_intr(dev, sc->res[1], INTR_TYPE_MISC, @@ -1172,7 +1184,7 @@ smmu_setup_interrupts(struct smmu_softc *sc) return (ENXIO); } - error = bus_setup_intr(dev, sc->res[3], INTR_TYPE_MISC, + error = bus_setup_intr(dev, sc->res[4], INTR_TYPE_MISC, smmu_gerr_intr, NULL, sc, &sc->intr_cookie[2]); if (error) { device_printf(dev, "Couldn't setup Gerr interrupt handler\n"); @@ -1761,18 +1773,28 @@ smmu_ctx_alloc(device_t dev, struct iommu_domain *iodom, device_t child, struct smmu_domain *domain; struct smmu_softc *sc; struct smmu_ctx *ctx; +#ifdef DEV_ACPI uint16_t rid; - u_int xref, sid; + u_int xref; int seg; +#else + struct pci_id_ofw_iommu pi; +#endif + u_int sid; int err; sc = device_get_softc(dev); domain = (struct smmu_domain *)iodom; +#ifdef DEV_ACPI seg = pci_get_domain(child); rid = pci_get_rid(child); err = acpi_iort_map_pci_smmuv3(seg, rid, &xref, &sid); - if (err) +#else + err = pci_get_id(child, PCI_ID_OFW_IOMMU, (uintptr_t *)&pi); + sid = pi.id; +#endif + if (err != 0) return (NULL); if (sc->features & SMMU_FEATURE_2_LVL_STREAM_TABLE) { @@ -1852,7 +1874,7 @@ smmu_ctx_lookup_by_sid(device_t dev, u_int sid) static struct iommu_ctx * smmu_ctx_lookup(device_t dev, device_t child) { - struct iommu_unit *iommu; + struct iommu_unit *iommu __unused; struct smmu_softc *sc; struct smmu_domain *domain; struct smmu_unit *unit; @@ -1883,15 +1905,24 @@ static int smmu_find(device_t dev, device_t child) { struct smmu_softc *sc; - u_int xref, sid; - uint16_t rid; + u_int xref; int error; +#ifdef DEV_ACPI + uint16_t rid; int seg; + u_int sid; +#else + phandle_t node; + uint64_t base, size; + struct pci_id_ofw_iommu pi; +#endif sc = device_get_softc(dev); +#ifdef DEV_ACPI rid = pci_get_rid(child); seg = pci_get_domain(child); +#endif /* * Find an xref of an IOMMU controller that serves traffic for dev. @@ -1903,8 +1934,16 @@ smmu_find(device_t dev, device_t child) return (ENOENT); } #else - /* TODO: add FDT support. */ - return (ENXIO); + error = pci_get_id(child, PCI_ID_OFW_IOMMU, (uintptr_t *)&pi); + if (error) { + /* Could not find reference to an SMMU device. */ + return (ENOENT); + } + + /* Our xref is memory base address. */ + node = OF_node_from_xref(pi.xref); + fdt_regsize(node, &base, &size); + xref = base; #endif /* Check if xref is ours. */ diff --git a/sys/arm64/iommu/smmu_acpi.c b/sys/arm64/iommu/smmu_acpi.c index d7a2c0444fdf..6ddbb0138c87 100644 --- a/sys/arm64/iommu/smmu_acpi.c +++ b/sys/arm64/iommu/smmu_acpi.c @@ -146,8 +146,10 @@ smmu_acpi_identify(driver_t *driver, device_t parent) BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 0, iort_data.smmu[i]->EventGsiv, 1); BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 1, - iort_data.smmu[i]->SyncGsiv, 1); + iort_data.smmu[i]->PriGsiv, 1); BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 2, + iort_data.smmu[i]->SyncGsiv, 1); + BUS_SET_RESOURCE(parent, dev, SYS_RES_IRQ, 3, iort_data.smmu[i]->GerrGsiv, 1); BUS_SET_RESOURCE(parent, dev, SYS_RES_MEMORY, 0, iort_data.smmu[i]->BaseAddress, MEMORY_RESOURCE_SIZE); diff --git a/sys/arm64/iommu/smmu_fdt.c b/sys/arm64/iommu/smmu_fdt.c new file mode 100644 index 000000000000..86cf0f9fd0cf --- /dev/null +++ b/sys/arm64/iommu/smmu_fdt.c @@ -0,0 +1,138 @@ +/*- + * SPDX-License-Identifier: BSD-2-Clause + * + * Copyright (c) 2022 Ruslan Bukin + * + * This work was supported by Innovate UK project 105694, "Digital Security + * by Design (DSbD) Technology Platform Prototype". + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#include +__FBSDID("$FreeBSD$"); + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +#include + +#include + +#include "smmuvar.h" + +static struct ofw_compat_data compat_data[] = { + { "arm,smmu-v3", 1 }, + { NULL, 0 } +}; + +static int +smmu_fdt_probe(device_t dev) +{ + if (!ofw_bus_status_okay(dev)) + return (ENXIO); + + if (ofw_bus_search_compatible(dev, compat_data)->ocd_data == 0) + return (ENXIO); + + device_set_desc(dev, "ARM System MMU (SMMU) v3"); + + return (BUS_PROBE_DEFAULT); +} + +static int +smmu_fdt_attach(device_t dev) +{ + struct smmu_softc *sc; + struct smmu_unit *unit; + struct iommu_unit *iommu; + int err; + + sc = device_get_softc(dev); + sc->dev = dev; + + err = smmu_attach(dev); + if (err != 0) + goto error; + + unit = &sc->unit; + unit->dev = dev; + + iommu = &unit->iommu; + iommu->dev = dev; + + LIST_INIT(&unit->domain_list); + + /* Use memory start address as an xref. */ + sc->xref = bus_get_resource_start(dev, SYS_RES_MEMORY, 0); + + err = iommu_register(iommu); + if (err) { + device_printf(dev, "Failed to register SMMU.\n"); + return (ENXIO); + } + + return (0); + +error: + if (bootverbose) { + device_printf(dev, + "Failed to attach. Error %d\n", err); + } + + /* Failure so free resources. */ + smmu_detach(dev); + + return (err); +} + +static device_method_t smmu_fdt_methods[] = { + /* Device interface */ + DEVMETHOD(device_probe, smmu_fdt_probe), + DEVMETHOD(device_attach, smmu_fdt_attach), + DEVMETHOD_END +}; + +DEFINE_CLASS_1(smmu, smmu_fdt_driver, smmu_fdt_methods, + sizeof(struct smmu_softc), smmu_driver); + +static devclass_t smmu_fdt_devclass; + +EARLY_DRIVER_MODULE(smmu, simplebus, smmu_fdt_driver, smmu_fdt_devclass, + 0, 0, BUS_PASS_INTERRUPT + BUS_PASS_ORDER_MIDDLE); diff --git a/sys/arm64/iommu/smmuvar.h b/sys/arm64/iommu/smmuvar.h index 3a1e5a269c01..76d4f238002d 100644 --- a/sys/arm64/iommu/smmuvar.h +++ b/sys/arm64/iommu/smmuvar.h @@ -136,7 +136,7 @@ struct smmu_strtab { struct smmu_softc { device_t dev; - struct resource *res[4]; + struct resource *res[5]; void *intr_cookie[3]; uint32_t ias; /* Intermediate Physical Address */ uint32_t oas; /* Physical Address */ diff --git a/sys/conf/files.arm64 b/sys/conf/files.arm64 index 5ee973a7b514..30358a5d67d1 100644 --- a/sys/conf/files.arm64 +++ b/sys/conf/files.arm64 @@ -106,7 +106,8 @@ arm64/iommu/iommu.c optional iommu arm64/iommu/iommu_if.m optional iommu arm64/iommu/iommu_pmap.c optional iommu arm64/iommu/smmu.c optional iommu -arm64/iommu/smmu_acpi.c optional acpi iommu +arm64/iommu/smmu_acpi.c optional iommu acpi +arm64/iommu/smmu_fdt.c optional iommu fdt arm64/iommu/smmu_quirks.c optional iommu dev/iommu/busdma_iommu.c optional iommu dev/iommu/iommu_gas.c optional iommu