From nobody Fri Sep 23 14:47:11 2022 X-Original-To: dev-commits-src-main@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 4MYw3M6X09z4d9bj; Fri, 23 Sep 2022 14:47:11 +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 4MYw3M66W4z4CVn; Fri, 23 Sep 2022 14:47:11 +0000 (UTC) (envelope-from git@FreeBSD.org) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1663944431; 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=2UgjlxvTfy6P2EM0LIPXML/fJdQTFHS1b76KXpQl0LY=; b=tPkfY/9i/5xpuDlu9v7o7VNMiITHTivajducs/qw98GUAzBqJe5gbqBm1IcpmfXW9VvjrY 0yv9/M4Uq06Ei8RotHhdyGvw2zOnGNVXIt18OjTyUugjxsTUF+wGBWQ9drV+8nAEGz3wHN iYGnaTklPVbO1KVKoA3XrtpsulomEA9rP1GyJaHC6J4NCKX4cs/YMvkguoL1VvI2CnriM8 5tzNMOXP5ivqr/yYgkZsYoFQbTUcAYBF1V08krITnaxa2QmxoS9VS4jLyGQNrbYWe788WL Pae6U5i5VR9UlSI9vD+u7rHgp6FRzL5Ci7FxPaSuukf/2naK/w+5qjvpD6Y6qw== 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 4MYw3M4y3xzmSY; Fri, 23 Sep 2022 14:47:11 +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 28NElB5D022465; Fri, 23 Sep 2022 14:47:11 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 28NElB0B022464; Fri, 23 Sep 2022 14:47:11 GMT (envelope-from git) Date: Fri, 23 Sep 2022 14:47:11 GMT Message-Id: <202209231447.28NElB0B022464@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org From: Andrew Turner Subject: git: 839374bbfe8b - main - Teach the GICv3 driver to translate memory ranges List-Id: Commit messages for the main branch of the src repository List-Archive: https://lists.freebsd.org/archives/dev-commits-src-main List-Help: List-Post: List-Subscribe: List-Unsubscribe: Sender: owner-dev-commits-src-main@freebsd.org X-BeenThere: dev-commits-src-main@freebsd.org MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: 8bit X-Git-Committer: andrew X-Git-Repository: src X-Git-Refname: refs/heads/main X-Git-Reftype: branch X-Git-Commit: 839374bbfe8bdbc766156bf0129bf54958dc2d8b Auto-Submitted: auto-generated ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=freebsd.org; s=dkim; t=1663944431; 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=2UgjlxvTfy6P2EM0LIPXML/fJdQTFHS1b76KXpQl0LY=; b=pd/iV7R4QE6sfxTWGNvZOu8LuNvYrA0vmV7q63J4g//kTRHhYErtXbzsgWMt2RUdGh+xWy 1ZZsk1h/5O06RP/5rFPNv+SCkh7tCGfLUmH7P/gIwLKgzfcli0xzSkHWEgKrqI+Vtp502f 00Jsmuy2gAty+HuMUfNnOjBVlv2qxx37O4yJ2M56Lld3rMlXS5XPg2HuBMRkSzxz0KGQjC ns+HSBkHA9amY7ZfSySqK0P1u8PZ7fMentCyk85fKZKwLlkbQ5klDhf4/y7iPeRxjvqcMF xbqcLpXw6zRYcoowTCB0FrRAKucPhp+CORRy4P6D6J6GbOlZSOx8K7NshBoQEw== ARC-Seal: i=1; s=dkim; d=freebsd.org; t=1663944431; a=rsa-sha256; cv=none; b=tjWsBW98p1oiP5jhmfjtzm4p1WlPulfvdmWhvg+HZWaVXC1BG/1DmMF3uoZo9abx6tqewO t59c9qj2ghlsc4ZUAgtdWna3QGZUjBtMr2mTzm8hteoeOQVhXRXtvHSfIaT1fKvQszTj90 a6z+os88lkhVzdkgPttLPPoEYs+Vgv3QEUBGtNFmZL4BxXOcn1wwO35ed67Mo5/1R9HI7B mhW7vjSdSLgJqr4GRE3kb8K0D6F5xoz/E18LACDeM5EBtacI5ommCpeqq6X78AnZeREOCH 9dg+B5bECBzmTPFEzJBgu2si9WtOWXQyZWqXeyf6HZwZ0D6TR4d9LUaX9OMOGA== ARC-Authentication-Results: i=1; mx1.freebsd.org; none X-ThisMailContainsUnwantedMimeParts: N The branch main has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=839374bbfe8bdbc766156bf0129bf54958dc2d8b commit 839374bbfe8bdbc766156bf0129bf54958dc2d8b Author: Andrew Turner AuthorDate: 2022-09-22 12:09:02 +0000 Commit: Andrew Turner CommitDate: 2022-09-23 14:28:45 +0000 Teach the GICv3 driver to translate memory ranges As with the GICv1/2 driver teach the GICv3 driver to translate memory ranges of children. This allows us to create a common bus_alloc_resource implementation for bot hACPI and FDT attachments. Sponsored by: The FreeBSD Foundation --- sys/arm/arm/gic.h | 6 --- sys/arm/arm/gic_common.h | 6 +++ sys/arm64/arm64/gic_v3.c | 57 ++++++++++++++++++++++ sys/arm64/arm64/gic_v3_acpi.c | 33 ------------- sys/arm64/arm64/gic_v3_fdt.c | 111 +++++++++++++++++++++++------------------- sys/arm64/arm64/gic_v3_var.h | 3 ++ 6 files changed, 126 insertions(+), 90 deletions(-) diff --git a/sys/arm/arm/gic.h b/sys/arm/arm/gic.h index ce0c8a6187e1..5db11a16a4e2 100644 --- a/sys/arm/arm/gic.h +++ b/sys/arm/arm/gic.h @@ -39,12 +39,6 @@ #ifndef _ARM_GIC_H_ #define _ARM_GIC_H_ -struct arm_gic_range { - uint64_t bus; - uint64_t host; - uint64_t size; -}; - struct arm_gic_softc { device_t gic_dev; void * gic_intrhand; diff --git a/sys/arm/arm/gic_common.h b/sys/arm/arm/gic_common.h index 42ec44bb7fab..9487bcb2be8d 100644 --- a/sys/arm/arm/gic_common.h +++ b/sys/arm/arm/gic_common.h @@ -31,6 +31,12 @@ #ifndef _GIC_COMMON_H_ #define _GIC_COMMON_H_ +struct arm_gic_range { + uint64_t bus; + uint64_t host; + uint64_t size; +}; + #define GIC_IVAR_HW_REV 500 #define GIC_IVAR_BUS 501 #define GIC_IVAR_VGIC 502 diff --git a/sys/arm64/arm64/gic_v3.c b/sys/arm64/arm64/gic_v3.c index 759d50f0941e..c26158e4035c 100644 --- a/sys/arm64/arm64/gic_v3.c +++ b/sys/arm64/arm64/gic_v3.c @@ -81,6 +81,7 @@ static bus_print_child_t gic_v3_print_child; static bus_get_domain_t gic_v3_get_domain; static bus_read_ivar_t gic_v3_read_ivar; static bus_write_ivar_t gic_v3_write_ivar; +static bus_alloc_resource_t gic_v3_alloc_resource; static pic_disable_intr_t gic_v3_disable_intr; static pic_enable_intr_t gic_v3_enable_intr; @@ -124,6 +125,8 @@ static device_method_t gic_v3_methods[] = { DEVMETHOD(bus_get_domain, gic_v3_get_domain), DEVMETHOD(bus_read_ivar, gic_v3_read_ivar), DEVMETHOD(bus_write_ivar, gic_v3_write_ivar), + DEVMETHOD(bus_alloc_resource, gic_v3_alloc_resource), + DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), /* Interrupt controller interface */ DEVMETHOD(pic_disable_intr, gic_v3_disable_intr), @@ -435,6 +438,7 @@ gic_v3_detach(device_t dev) for (i = 0; i <= mp_maxid; i++) free(sc->gic_redists.pcpu[i], M_GIC_V3); + free(sc->ranges, M_GIC_V3); free(sc->gic_res, M_GIC_V3); free(sc->gic_redists.regions, M_GIC_V3); @@ -524,6 +528,59 @@ gic_v3_write_ivar(device_t dev, device_t child, int which, uintptr_t value) return (ENOENT); } +static struct resource * +gic_v3_alloc_resource(device_t bus, device_t child, int type, int *rid, + rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) +{ + struct gic_v3_softc *sc; + struct resource_list_entry *rle; + struct resource_list *rl; + int j; + + /* We only allocate memory */ + if (type != SYS_RES_MEMORY) + return (NULL); + + sc = device_get_softc(bus); + + if (RMAN_IS_DEFAULT_RANGE(start, end)) { + rl = BUS_GET_RESOURCE_LIST(bus, child); + if (rl == NULL) + return (NULL); + + /* Find defaults for this rid */ + rle = resource_list_find(rl, type, *rid); + if (rle == NULL) + return (NULL); + + start = rle->start; + end = rle->end; + count = rle->count; + } + + /* Remap through ranges property */ + for (j = 0; j < sc->nranges; j++) { + if (start >= sc->ranges[j].bus && end < + sc->ranges[j].bus + sc->ranges[j].size) { + start -= sc->ranges[j].bus; + start += sc->ranges[j].host; + end -= sc->ranges[j].bus; + end += sc->ranges[j].host; + break; + } + } + if (j == sc->nranges && sc->nranges != 0) { + if (bootverbose) + device_printf(bus, "Could not map resource " + "%#jx-%#jx\n", (uintmax_t)start, (uintmax_t)end); + + return (NULL); + } + + return (bus_generic_alloc_resource(bus, child, type, rid, start, end, + count, flags)); +} + int arm_gic_v3_intr(void *arg) { diff --git a/sys/arm64/arm64/gic_v3_acpi.c b/sys/arm64/arm64/gic_v3_acpi.c index f24662750da7..3d3cd3ba9ccd 100644 --- a/sys/arm64/arm64/gic_v3_acpi.c +++ b/sys/arm64/arm64/gic_v3_acpi.c @@ -59,7 +59,6 @@ struct gic_v3_acpi_devinfo { static device_identify_t gic_v3_acpi_identify; static device_probe_t gic_v3_acpi_probe; static device_attach_t gic_v3_acpi_attach; -static bus_alloc_resource_t gic_v3_acpi_bus_alloc_res; static bus_get_resource_list_t gic_v3_acpi_get_resource_list; static void gic_v3_acpi_bus_attach(device_t); @@ -71,8 +70,6 @@ static device_method_t gic_v3_acpi_methods[] = { DEVMETHOD(device_attach, gic_v3_acpi_attach), /* Bus interface */ - DEVMETHOD(bus_alloc_resource, gic_v3_acpi_bus_alloc_res), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), DEVMETHOD(bus_get_resource_list, gic_v3_acpi_get_resource_list), /* End */ @@ -445,36 +442,6 @@ gic_v3_acpi_bus_attach(device_t dev) bus_generic_attach(dev); } -static struct resource * -gic_v3_acpi_bus_alloc_res(device_t bus, device_t child, int type, int *rid, - rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) -{ - struct resource_list_entry *rle; - struct resource_list *rl; - - /* We only allocate memory */ - if (type != SYS_RES_MEMORY) - return (NULL); - - if (RMAN_IS_DEFAULT_RANGE(start, end)) { - rl = BUS_GET_RESOURCE_LIST(bus, child); - if (rl == NULL) - return (NULL); - - /* Find defaults for this rid */ - rle = resource_list_find(rl, type, *rid); - if (rle == NULL) - return (NULL); - - start = rle->start; - end = rle->end; - count = rle->count; - } - - return (bus_generic_alloc_resource(bus, child, type, rid, start, end, - count, flags)); -} - static struct resource_list * gic_v3_acpi_get_resource_list(device_t bus, device_t child) { diff --git a/sys/arm64/arm64/gic_v3_fdt.c b/sys/arm64/arm64/gic_v3_fdt.c index dc1445340943..2efdba68eae2 100644 --- a/sys/arm64/arm64/gic_v3_fdt.c +++ b/sys/arm64/arm64/gic_v3_fdt.c @@ -54,8 +54,6 @@ __FBSDID("$FreeBSD$"); static int gic_v3_fdt_probe(device_t); static int gic_v3_fdt_attach(device_t); -static struct resource *gic_v3_ofw_bus_alloc_res(device_t, device_t, int, int *, - rman_res_t, rman_res_t, rman_res_t, u_int); static const struct ofw_bus_devinfo *gic_v3_ofw_get_devinfo(device_t, device_t); static bus_get_resource_list_t gic_v3_fdt_get_resource_list; @@ -65,8 +63,6 @@ static device_method_t gic_v3_fdt_methods[] = { DEVMETHOD(device_attach, gic_v3_fdt_attach), /* Bus interface */ - DEVMETHOD(bus_alloc_resource, gic_v3_ofw_bus_alloc_res), - DEVMETHOD(bus_activate_resource, bus_generic_activate_resource), DEVMETHOD(bus_get_resource_list, gic_v3_fdt_get_resource_list), /* ofw_bus interface */ @@ -219,51 +215,64 @@ gic_v3_ofw_get_devinfo(device_t bus __unused, device_t child) return (&di->di_dinfo); } -static struct resource * -gic_v3_ofw_bus_alloc_res(device_t bus, device_t child, int type, int *rid, - rman_res_t start, rman_res_t end, rman_res_t count, u_int flags) +/* Helper functions */ +static int +gic_v3_ofw_fill_ranges(phandle_t parent, struct gic_v3_softc *sc, + pcell_t *addr_cellsp, pcell_t *size_cellsp) { - struct resource_list_entry *rle; - struct resource_list *rl; - int ranges_len; - - /* We only allocate memory */ - if (type != SYS_RES_MEMORY) - return (NULL); - - if (RMAN_IS_DEFAULT_RANGE(start, end)) { - rl = BUS_GET_RESOURCE_LIST(bus, child); - if (rl == NULL) - return (NULL); - - /* Find defaults for this rid */ - rle = resource_list_find(rl, type, *rid); - if (rle == NULL) - return (NULL); - - start = rle->start; - end = rle->end; - count = rle->count; - } - /* - * XXX: No ranges remap! - * Absolute address is expected. - */ - if (ofw_bus_has_prop(bus, "ranges")) { - ranges_len = OF_getproplen(ofw_bus_get_node(bus), "ranges"); - if (ranges_len != 0) { - if (bootverbose) { - device_printf(child, - "Ranges remap not supported\n"); - } - return (NULL); + pcell_t addr_cells, host_cells, size_cells; + cell_t *base_ranges; + ssize_t nbase_ranges; + int i, j, k; + + host_cells = 1; + OF_getencprop(OF_parent(parent), "#address-cells", &host_cells, + sizeof(host_cells)); + addr_cells = 2; + OF_getencprop(parent, "#address-cells", &addr_cells, + sizeof(addr_cells)); + size_cells = 2; + OF_getencprop(parent, "#size-cells", &size_cells, + sizeof(size_cells)); + + *addr_cellsp = addr_cells; + *size_cellsp = size_cells; + + nbase_ranges = OF_getproplen(parent, "ranges"); + if (nbase_ranges < 0) + return (EINVAL); + + sc->nranges = nbase_ranges / sizeof(cell_t) / + (addr_cells + host_cells + size_cells); + if (sc->nranges == 0) + return (0); + + sc->ranges = malloc(sc->nranges * sizeof(sc->ranges[0]), M_GIC_V3, + M_WAITOK); + base_ranges = malloc(nbase_ranges, M_DEVBUF, M_WAITOK); + OF_getencprop(parent, "ranges", base_ranges, nbase_ranges); + + for (i = 0, j = 0; i < sc->nranges; i++) { + sc->ranges[i].bus = 0; + for (k = 0; k < addr_cells; k++) { + sc->ranges[i].bus <<= 32; + sc->ranges[i].bus |= base_ranges[j++]; + } + sc->ranges[i].host = 0; + for (k = 0; k < host_cells; k++) { + sc->ranges[i].host <<= 32; + sc->ranges[i].host |= base_ranges[j++]; + } + sc->ranges[i].size = 0; + for (k = 0; k < size_cells; k++) { + sc->ranges[i].size <<= 32; + sc->ranges[i].size |= base_ranges[j++]; } } - return (bus_generic_alloc_resource(bus, child, type, rid, start, end, - count, flags)); -} -/* Helper functions */ + free(base_ranges, M_DEVBUF); + return (0); +} /* * Bus capability support for GICv3. @@ -278,16 +287,16 @@ gic_v3_ofw_bus_attach(device_t dev) device_t child; phandle_t parent, node; pcell_t addr_cells, size_cells; + int rv; sc = device_get_softc(dev); parent = ofw_bus_get_node(dev); if (parent > 0) { - addr_cells = 2; - OF_getencprop(parent, "#address-cells", &addr_cells, - sizeof(addr_cells)); - size_cells = 2; - OF_getencprop(parent, "#size-cells", &size_cells, - sizeof(size_cells)); + rv = gic_v3_ofw_fill_ranges(parent, sc, &addr_cells, + &size_cells); + if (rv != 0) + return (rv); + /* Iterate through all GIC subordinates */ for (node = OF_child(parent); node > 0; node = OF_peer(node)) { /* diff --git a/sys/arm64/arm64/gic_v3_var.h b/sys/arm64/arm64/gic_v3_var.h index b66fe6c57bb2..61c3ff0b61ae 100644 --- a/sys/arm64/arm64/gic_v3_var.h +++ b/sys/arm64/arm64/gic_v3_var.h @@ -84,6 +84,9 @@ struct gic_v3_softc { device_t *gic_children; struct intr_pic *gic_pic; struct gic_v3_irqsrc *gic_irqs; + + int nranges; + struct arm_gic_range * ranges; }; struct gic_v3_devinfo {