diff options
Diffstat (limited to 'sys/arm64/arm64/gic_v3.c')
-rw-r--r-- | sys/arm64/arm64/gic_v3.c | 57 |
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) { |