1fd8d34ceSJustin Hibbits /*
2fd8d34ceSJustin Hibbits * Copyright (c) 2026 Justin Hibbits
3*7a40b8a8SJustin Hibbits *
4*7a40b8a8SJustin Hibbits * SPDX-License-Identifier: BSD-2-Clause
5fd8d34ceSJustin Hibbits */
6fd8d34ceSJustin Hibbits
7fd8d34ceSJustin Hibbits #include <sys/param.h>
8fd8d34ceSJustin Hibbits #include <sys/systm.h>
9fd8d34ceSJustin Hibbits #include <vm/vm.h>
10fd8d34ceSJustin Hibbits #include <vm/pmap.h>
11fd8d34ceSJustin Hibbits
12fd8d34ceSJustin Hibbits #include <dev/fdt/fdt_common.h>
13fd8d34ceSJustin Hibbits #include <dev/ofw/ofw_bus.h>
14fd8d34ceSJustin Hibbits #include <dev/ofw/ofw_bus_subr.h>
15fd8d34ceSJustin Hibbits
16fd8d34ceSJustin Hibbits #include "dpaa_common.h"
17fd8d34ceSJustin Hibbits
18fd8d34ceSJustin Hibbits #define FDT_REG_CELLS 4
19fd8d34ceSJustin Hibbits int
dpaa_map_private_memory(device_t dev,int idx,const char * compat,vm_paddr_t * addrp,size_t * sizep)20fd8d34ceSJustin Hibbits dpaa_map_private_memory(device_t dev, int idx, const char *compat,
21fd8d34ceSJustin Hibbits vm_paddr_t *addrp, size_t *sizep)
22fd8d34ceSJustin Hibbits {
23fd8d34ceSJustin Hibbits phandle_t node;
24fd8d34ceSJustin Hibbits pcell_t cells[idx + 1];
25fd8d34ceSJustin Hibbits pcell_t *cell_alloc;
26fd8d34ceSJustin Hibbits int addr_cells, size_cells;
27fd8d34ceSJustin Hibbits uint64_t tmp;
28fd8d34ceSJustin Hibbits u_long align, base, size;
29fd8d34ceSJustin Hibbits vm_paddr_t alloc_base;
30fd8d34ceSJustin Hibbits vm_size_t alloc_range_size;
31fd8d34ceSJustin Hibbits ssize_t alloc_size;
32fd8d34ceSJustin Hibbits void *reserved;
33fd8d34ceSJustin Hibbits int rv;
34fd8d34ceSJustin Hibbits
35fd8d34ceSJustin Hibbits node = ofw_bus_get_node(dev);
36fd8d34ceSJustin Hibbits if (OF_getencprop(node, "memory-region", cells, sizeof(cells)) <= 0)
37fd8d34ceSJustin Hibbits return (ENXIO);
38fd8d34ceSJustin Hibbits
39fd8d34ceSJustin Hibbits node = OF_node_from_xref(cells[idx]);
40fd8d34ceSJustin Hibbits /* If the memory is already reserved, we just need to return it. */
41fd8d34ceSJustin Hibbits if (fdt_regsize(node, &base, &size) == 0)
42fd8d34ceSJustin Hibbits goto success;
43fd8d34ceSJustin Hibbits
44fd8d34ceSJustin Hibbits rv = fdt_addrsize_cells(OF_parent(node), &addr_cells, &size_cells);
45fd8d34ceSJustin Hibbits if (rv != 0)
46fd8d34ceSJustin Hibbits return (rv);
47fd8d34ceSJustin Hibbits
48fd8d34ceSJustin Hibbits if (OF_getprop(node, "alignment", &tmp, sizeof(tmp)) <= 0)
49fd8d34ceSJustin Hibbits return (ENXIO);
50fd8d34ceSJustin Hibbits
51fd8d34ceSJustin Hibbits align = fdt_data_get(&tmp, addr_cells);
52fd8d34ceSJustin Hibbits if (OF_getprop(node, "size", &tmp, sizeof(tmp)) <= 0)
53fd8d34ceSJustin Hibbits return (ENXIO);
54fd8d34ceSJustin Hibbits size = fdt_data_get(&tmp, size_cells);
55fd8d34ceSJustin Hibbits
56fd8d34ceSJustin Hibbits alloc_size =
57fd8d34ceSJustin Hibbits OF_getencprop_alloc(node, "alloc-ranges", (void **)&cell_alloc);
58fd8d34ceSJustin Hibbits if (alloc_size < 0)
59fd8d34ceSJustin Hibbits return (ENXIO);
60fd8d34ceSJustin Hibbits
61fd8d34ceSJustin Hibbits alloc_size /= sizeof(pcell_t);
62fd8d34ceSJustin Hibbits for (int i = 0; i < alloc_size; i += (addr_cells + size_cells)) {
63fd8d34ceSJustin Hibbits alloc_base = fdt_data_get(&cell_alloc[i], addr_cells);
64fd8d34ceSJustin Hibbits alloc_range_size =
65fd8d34ceSJustin Hibbits fdt_data_get(&cell_alloc[i + addr_cells], size_cells);
66fd8d34ceSJustin Hibbits reserved = contigmalloc(size, M_DEVBUF, M_NOWAIT | M_ZERO,
67fd8d34ceSJustin Hibbits alloc_base, alloc_base + alloc_range_size, align, 0);
68fd8d34ceSJustin Hibbits if (reserved != NULL)
69fd8d34ceSJustin Hibbits break;
70fd8d34ceSJustin Hibbits }
71fd8d34ceSJustin Hibbits if (reserved == NULL)
72fd8d34ceSJustin Hibbits return (ENOMEM);
73fd8d34ceSJustin Hibbits /* Flush the cache (zeroed memory) because it won't be touched later. */
74fd8d34ceSJustin Hibbits cpu_flush_dcache(reserved, size);
75fd8d34ceSJustin Hibbits base = pmap_kextract((vm_offset_t)reserved);
76fd8d34ceSJustin Hibbits
77fd8d34ceSJustin Hibbits success:
78fd8d34ceSJustin Hibbits *addrp = base;
79fd8d34ceSJustin Hibbits *sizep = size;
80fd8d34ceSJustin Hibbits
81fd8d34ceSJustin Hibbits return (0);
82fd8d34ceSJustin Hibbits }
83