From owner-dev-commits-src-branches@freebsd.org Sat Jun 12 14:01:06 2021 Return-Path: Delivered-To: dev-commits-src-branches@mailman.nyi.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2610:1c1:1:606c::19:1]) by mailman.nyi.freebsd.org (Postfix) with ESMTP id D8F7964C10F; Sat, 12 Jun 2021 14:01:06 +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 4G2KBB5fcFz4q81; Sat, 12 Jun 2021 14:01:06 +0000 (UTC) (envelope-from git@FreeBSD.org) 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 A74427884; Sat, 12 Jun 2021 14:01:06 +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 15CE16aE022233; Sat, 12 Jun 2021 14:01:06 GMT (envelope-from git@gitrepo.freebsd.org) Received: (from git@localhost) by gitrepo.freebsd.org (8.16.1/8.16.1/Submit) id 15CE16Nv022232; Sat, 12 Jun 2021 14:01:06 GMT (envelope-from git) Date: Sat, 12 Jun 2021 14:01:06 GMT Message-Id: <202106121401.15CE16Nv022232@gitrepo.freebsd.org> To: src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-branches@FreeBSD.org From: Andrew Turner Subject: git: 48e4430ea5a1 - stable/13 - Implement bus_map_resource on arm64 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/stable/13 X-Git-Reftype: branch X-Git-Commit: 48e4430ea5a1e82121a8fe486eb09986b9b62f0f Auto-Submitted: auto-generated X-BeenThere: dev-commits-src-branches@freebsd.org X-Mailman-Version: 2.1.34 Precedence: list List-Id: Commits to the stable branches of the FreeBSD src repository List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 12 Jun 2021 14:01:07 -0000 The branch stable/13 has been updated by andrew: URL: https://cgit.FreeBSD.org/src/commit/?id=48e4430ea5a1e82121a8fe486eb09986b9b62f0f commit 48e4430ea5a1e82121a8fe486eb09986b9b62f0f Author: Andrew Turner AuthorDate: 2021-04-10 10:25:39 +0000 Commit: Andrew Turner CommitDate: 2021-06-12 01:21:54 +0000 Implement bus_map_resource on arm64 This will allow us to allocate an unmapped memory resource, then later map it with a specific memory attribute. This is also needed for virtio with the modern PCI attachment. Reviewed by: kib (via D29723) Sponsored by: Innovate UK Differential Revision: https://reviews.freebsd.org/D29694 (cherry picked from commit fe3822497726ab84a1e3753be41e43e4d51aab0b) --- sys/arm64/arm64/nexus.c | 77 ++++++++++++++++++++++++++++++++++++++++--------- 1 file changed, 63 insertions(+), 14 deletions(-) diff --git a/sys/arm64/arm64/nexus.c b/sys/arm64/arm64/nexus.c index 924496ec7f52..cc28d87f002b 100644 --- a/sys/arm64/arm64/nexus.c +++ b/sys/arm64/arm64/nexus.c @@ -106,6 +106,8 @@ static struct resource *nexus_alloc_resource(device_t, device_t, int, int *, rman_res_t, rman_res_t, rman_res_t, u_int); static int nexus_activate_resource(device_t, device_t, int, int, struct resource *); +static int nexus_map_resource(device_t, device_t, int, struct resource *, + struct resource_map_request *, struct resource_map *); static int nexus_config_intr(device_t dev, int irq, enum intr_trigger trig, enum intr_polarity pol); static struct resource_list *nexus_get_reslist(device_t, device_t); @@ -135,6 +137,7 @@ static device_method_t nexus_methods[] = { DEVMETHOD(bus_add_child, nexus_add_child), DEVMETHOD(bus_alloc_resource, nexus_alloc_resource), DEVMETHOD(bus_activate_resource, nexus_activate_resource), + DEVMETHOD(bus_map_resource, nexus_map_resource), DEVMETHOD(bus_config_intr, nexus_config_intr), DEVMETHOD(bus_get_resource_list, nexus_get_reslist), DEVMETHOD(bus_set_resource, nexus_set_resource), @@ -344,10 +347,8 @@ static int nexus_activate_resource(device_t bus, device_t child, int type, int rid, struct resource *r) { + struct resource_map map; int err; - bus_addr_t paddr; - bus_size_t psize; - bus_space_handle_t vaddr; if ((err = rman_activate_resource(r)) != 0) return (err); @@ -355,18 +356,21 @@ nexus_activate_resource(device_t bus, device_t child, int type, int rid, /* * If this is a memory resource, map it into the kernel. */ - if (type == SYS_RES_MEMORY || type == SYS_RES_IOPORT) { - paddr = (bus_addr_t)rman_get_start(r); - psize = (bus_size_t)rman_get_size(r); - err = bus_space_map(&memmap_bus, paddr, psize, 0, &vaddr); - if (err != 0) { - rman_deactivate_resource(r); - return (err); + switch (type) { + case SYS_RES_IOPORT: + case SYS_RES_MEMORY: + if ((rman_get_flags(r) & RF_UNMAPPED) == 0) { + err = nexus_map_resource(bus, child, type, r, NULL, + &map); + if (err != 0) { + rman_deactivate_resource(r); + return (err); + } + + rman_set_mapping(r, &map); } - rman_set_bustag(r, &memmap_bus); - rman_set_virtual(r, (void *)vaddr); - rman_set_bushandle(r, vaddr); - } else if (type == SYS_RES_IRQ) { + break; + case SYS_RES_IRQ: err = intr_activate_irq(child, r); if (err != 0) { rman_deactivate_resource(r); @@ -420,6 +424,51 @@ nexus_deactivate_resource(device_t bus, device_t child, int type, int rid, return (rman_deactivate_resource(r)); } +static int +nexus_map_resource(device_t bus, device_t child, int type, struct resource *r, + struct resource_map_request *argsp, struct resource_map *map) +{ + struct resource_map_request args; + rman_res_t end, length, start; + + /* Resources must be active to be mapped. */ + if ((rman_get_flags(r) & RF_ACTIVE) == 0) + return (ENXIO); + + /* Mappings are only supported on I/O and memory resources. */ + switch (type) { + case SYS_RES_IOPORT: + case SYS_RES_MEMORY: + break; + default: + return (EINVAL); + } + + resource_init_map_request(&args); + if (argsp != NULL) + bcopy(argsp, &args, imin(argsp->size, args.size)); + start = rman_get_start(r) + args.offset; + if (args.length == 0) + length = rman_get_size(r); + else + length = args.length; + end = start + length - 1; + if (start > rman_get_end(r) || start < rman_get_start(r)) + return (EINVAL); + if (end > rman_get_end(r) || end < start) + return (EINVAL); + + map->r_vaddr = pmap_mapdev_attr(start, length, args.memattr); + map->r_bustag = &memmap_bus; + map->r_size = length; + + /* + * The handle is the virtual address. + */ + map->r_bushandle = (bus_space_handle_t)map->r_vaddr; + return (0); +} + #ifdef FDT static device_method_t nexus_fdt_methods[] = { /* Device interface */