Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/arm64/gic_v3.c
Show First 20 Lines • Show All 93 Lines • ▼ Show 20 Lines | |||||
#endif | #endif | ||||
static u_int gic_irq_cpu; | static u_int gic_irq_cpu; | ||||
#ifdef SMP | #ifdef SMP | ||||
static u_int sgi_to_ipi[GIC_LAST_SGI - GIC_FIRST_SGI + 1]; | static u_int sgi_to_ipi[GIC_LAST_SGI - GIC_FIRST_SGI + 1]; | ||||
static u_int sgi_first_unused = GIC_FIRST_SGI; | static u_int sgi_first_unused = GIC_FIRST_SGI; | ||||
#endif | #endif | ||||
static struct resource *maint_res; | |||||
static device_t gic_dev; | |||||
static int maint_rid; | |||||
static void *maint_cookie; | |||||
static device_method_t gic_v3_methods[] = { | static device_method_t gic_v3_methods[] = { | ||||
/* Device interface */ | /* Device interface */ | ||||
DEVMETHOD(device_detach, gic_v3_detach), | DEVMETHOD(device_detach, gic_v3_detach), | ||||
/* Bus interface */ | /* Bus interface */ | ||||
DEVMETHOD(bus_get_domain, gic_v3_get_domain), | DEVMETHOD(bus_get_domain, gic_v3_get_domain), | ||||
DEVMETHOD(bus_read_ivar, gic_v3_read_ivar), | DEVMETHOD(bus_read_ivar, gic_v3_read_ivar), | ||||
▲ Show 20 Lines • Show All 251 Lines • ▼ Show 20 Lines | for (i = 0; i <= mp_maxid; i++) | ||||
free(sc->gic_redists.pcpu[i], M_GIC_V3); | free(sc->gic_redists.pcpu[i], M_GIC_V3); | ||||
free(sc->gic_res, M_GIC_V3); | free(sc->gic_res, M_GIC_V3); | ||||
free(sc->gic_redists.regions, M_GIC_V3); | free(sc->gic_redists.regions, M_GIC_V3); | ||||
return (0); | return (0); | ||||
} | } | ||||
void | |||||
gic_v3_alloc_maint_res(device_t dev) | |||||
{ | |||||
gic_dev = dev; | |||||
maint_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &maint_rid, | |||||
RF_ACTIVE); | |||||
if (!maint_res) | |||||
device_printf(dev, | |||||
"Could not allocate resource for maintenance interrupt\n"); | |||||
} | |||||
int | |||||
gic_v3_setup_maint_intr(driver_filter_t filter, driver_intr_t handler, | |||||
void *arg) | |||||
{ | |||||
int flags; | |||||
if (!maint_res) | |||||
return (EINVAL); | |||||
flags = INTR_TYPE_MISC | INTR_MPSAFE; | |||||
return (bus_setup_intr(gic_dev, maint_res, flags, filter, handler, | |||||
arg, &maint_cookie)); | |||||
} | |||||
int | |||||
gic_v3_teardown_maint_intr(void) | |||||
{ | |||||
if (!maint_res) | |||||
return (EINVAL); | |||||
return (bus_teardown_intr(gic_dev, maint_res, maint_cookie)); | |||||
} | |||||
static int | static int | ||||
gic_v3_get_domain(device_t dev, device_t child, int *domain) | gic_v3_get_domain(device_t dev, device_t child, int *domain) | ||||
{ | { | ||||
struct gic_v3_devinfo *di; | struct gic_v3_devinfo *di; | ||||
di = device_get_ivars(child); | di = device_get_ivars(child); | ||||
if (di == NULL) | |||||
return (0); | |||||
if (di->gic_domain < 0) | if (di->gic_domain < 0) | ||||
return (ENOENT); | return (ENOENT); | ||||
*domain = di->gic_domain; | *domain = di->gic_domain; | ||||
return (0); | return (0); | ||||
} | } | ||||
static int | static int | ||||
▲ Show 20 Lines • Show All 590 Lines • ▼ Show 20 Lines | |||||
* Helper routines | * Helper routines | ||||
*/ | */ | ||||
static void | static void | ||||
gic_v3_wait_for_rwp(struct gic_v3_softc *sc, enum gic_v3_xdist xdist) | gic_v3_wait_for_rwp(struct gic_v3_softc *sc, enum gic_v3_xdist xdist) | ||||
{ | { | ||||
struct resource *res; | struct resource *res; | ||||
u_int cpuid; | u_int cpuid; | ||||
size_t us_left = 1000000; | size_t us_left = 1000000; | ||||
uint32_t rwp; | |||||
cpuid = PCPU_GET(cpuid); | cpuid = PCPU_GET(cpuid); | ||||
switch (xdist) { | switch (xdist) { | ||||
case DIST: | case DIST: | ||||
res = sc->gic_dist; | res = sc->gic_dist; | ||||
rwp = GICD_CTLR_RWP; | |||||
break; | break; | ||||
case REDIST: | case REDIST: | ||||
res = &sc->gic_redists.pcpu[cpuid]->res; | res = &sc->gic_redists.pcpu[cpuid]->res; | ||||
rwp = GICR_CTLR_RWP; | |||||
break; | break; | ||||
default: | default: | ||||
KASSERT(0, ("%s: Attempt to wait for unknown RWP", __func__)); | KASSERT(0, ("%s: Attempt to wait for unknown RWP", __func__)); | ||||
return; | return; | ||||
} | } | ||||
while ((bus_read_4(res, GICD_CTLR) & GICD_CTLR_RWP) != 0) { | while ((bus_read_4(res, GICD_CTLR) & rwp) != 0) { | ||||
DELAY(1); | DELAY(1); | ||||
if (us_left-- == 0) | if (us_left-- == 0) | ||||
panic("GICD Register write pending for too long"); | panic("GICD Register write pending for too long"); | ||||
} | } | ||||
} | } | ||||
/* CPU interface. */ | /* CPU interface. */ | ||||
static __inline void | static __inline void | ||||
▲ Show 20 Lines • Show All 267 Lines • Show Last 20 Lines |