aboutsummaryrefslogtreecommitdiff
path: root/sys/arm64/arm64/gic_v3.c
diff options
context:
space:
mode:
authorAndrew Turner <andrew@FreeBSD.org>2022-09-22 12:09:02 +0000
committerAndrew Turner <andrew@FreeBSD.org>2022-09-23 14:28:45 +0000
commit839374bbfe8bdbc766156bf0129bf54958dc2d8b (patch)
tree1aca843d7d4034c8659ba335eaf804fde20aa6d6 /sys/arm64/arm64/gic_v3.c
parentbdc9ece97b80c3a8b8c9161d95ef908172eb316a (diff)
downloadsrc-839374bbfe8bdbc766156bf0129bf54958dc2d8b.tar.gz
src-839374bbfe8bdbc766156bf0129bf54958dc2d8b.zip
Diffstat (limited to 'sys/arm64/arm64/gic_v3.c')
-rw-r--r--sys/arm64/arm64/gic_v3.c57
1 files changed, 57 insertions, 0 deletions
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)
{