aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlfredo Dal'Ava Junior <alfredo@FreeBSD.org>2021-03-29 23:28:32 +0000
committerAlfredo Dal'Ava Junior <alfredo@FreeBSD.org>2021-05-07 05:32:50 +0000
commit8d5898458818f9c0aaf203367c8ef1ac4d00fb71 (patch)
tree379dc3433eb6bb0bf1c2431de6b0342966d17638
parentaa21554a8b03196c4208a2a33527020f29073a00 (diff)
downloadsrc-8d589845881.tar.gz
src-8d589845881.zip
powerpc: implement bus_map_resource and bus_unmap_resource DEVMETHODs
Implements bus_map_resource and bus_unmap_resource DEVMETHODs to be used by powerpc targets. This is identical to the amd64 code. Required by virtio-modern. Reviewed by: bryanv Sponsored by: Eldorado Research Institute (eldorado.org.br) MFC after: 1 week Differential Revision: https://reviews.freebsd.org/D28012 (cherry picked from commit befb0817bd5e47588eb0254744daec02488acd72)
-rw-r--r--sys/powerpc/powerpc/nexus.c95
1 files changed, 95 insertions, 0 deletions
diff --git a/sys/powerpc/powerpc/nexus.c b/sys/powerpc/powerpc/nexus.c
index 34ec3c0fe0ab..b3fe5a3e1527 100644
--- a/sys/powerpc/powerpc/nexus.c
+++ b/sys/powerpc/powerpc/nexus.c
@@ -69,6 +69,13 @@ static bus_setup_intr_t nexus_setup_intr;
static bus_teardown_intr_t nexus_teardown_intr;
static bus_activate_resource_t nexus_activate_resource;
static bus_deactivate_resource_t nexus_deactivate_resource;
+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);
+static int nexus_unmap_resource(device_t bus, device_t child, int type,
+ struct resource *r, struct resource_map *map);
+
static bus_space_tag_t nexus_get_bus_tag(device_t, device_t);
static int nexus_get_cpus(device_t, device_t, enum cpu_sets, size_t,
cpuset_t *);
@@ -87,6 +94,8 @@ static device_method_t nexus_methods[] = {
DEVMETHOD(bus_add_child, bus_generic_add_child),
DEVMETHOD(bus_activate_resource, nexus_activate_resource),
DEVMETHOD(bus_deactivate_resource, nexus_deactivate_resource),
+ DEVMETHOD(bus_map_resource, nexus_map_resource),
+ DEVMETHOD(bus_unmap_resource, nexus_unmap_resource),
DEVMETHOD(bus_setup_intr, nexus_setup_intr),
DEVMETHOD(bus_teardown_intr, nexus_teardown_intr),
#ifdef SMP
@@ -268,3 +277,89 @@ nexus_deactivate_resource(device_t bus __unused, device_t child __unused,
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))
+ 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);
+
+ /*
+ * If this is a memory resource, map it into the kernel.
+ */
+ switch (type) {
+ case SYS_RES_IOPORT:
+ panic("%s:%d SYS_RES_IOPORT handling not implemented", __func__, __LINE__);
+ /* XXX: untested
+ map->r_bushandle = start;
+ map->r_bustag = nexus_get_bus_tag(NULL, NULL);
+ map->r_size = length;
+ map->r_vaddr = NULL;
+ */
+ break;
+ case SYS_RES_MEMORY:
+ map->r_vaddr = pmap_mapdev_attr(start, length, args.memattr);
+ map->r_bustag = nexus_get_bus_tag(NULL, NULL);
+ map->r_size = length;
+ map->r_bushandle = (bus_space_handle_t)map->r_vaddr;
+ break;
+ }
+
+ return (0);
+
+}
+
+static int
+nexus_unmap_resource(device_t bus, device_t child, int type, struct resource *r,
+ struct resource_map *map)
+{
+
+ /*
+ * If this is a memory resource, unmap it.
+ */
+ switch (type) {
+ case SYS_RES_MEMORY:
+ pmap_unmapdev((vm_offset_t)map->r_vaddr, map->r_size);
+ /* FALLTHROUGH */
+ case SYS_RES_IOPORT:
+ break;
+ default:
+ return (EINVAL);
+ }
+
+ return (0);
+
+}