The branch main has been updated by andrew:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=fe3822497726ab84a1e3753be41e43e4d51aab0b

commit fe3822497726ab84a1e3753be41e43e4d51aab0b
Author:     Andrew Turner <and...@freebsd.org>
AuthorDate: 2021-04-10 10:25:39 +0000
Commit:     Andrew Turner <and...@freebsd.org>
CommitDate: 2021-05-02 07:35:16 +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
---
 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 */
_______________________________________________
dev-commits-src-all@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/dev-commits-src-all
To unsubscribe, send any mail to "dev-commits-src-all-unsubscr...@freebsd.org"

Reply via email to