Set the pl310 L2 cache driver to attach during the middle of BUS_PASS_CPU.
Because that's earlier than interrupts are available, set up deferred configuration of interrupts (which are used only for debugging).
This commit is contained in:
+49
-27
@@ -378,6 +378,44 @@ pl310_set_way_sizes(struct pl310_softc *sc)
|
|||||||
g_l2cache_size = g_way_size * g_ways_assoc;
|
g_l2cache_size = g_way_size * g_ways_assoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Setup interrupt handling. This is done only if the cache controller is
|
||||||
|
* disabled, for debugging. We set counters so when a cache event happens we'll
|
||||||
|
* get interrupted and be warned that something is wrong, because no cache
|
||||||
|
* events should happen if we're disabled.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
pl310_config_intr(void *arg)
|
||||||
|
{
|
||||||
|
struct pl310_softc * sc;
|
||||||
|
|
||||||
|
sc = arg;
|
||||||
|
|
||||||
|
/* activate the interrupt */
|
||||||
|
bus_setup_intr(sc->sc_dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
|
||||||
|
pl310_filter, NULL, sc, &sc->sc_irq_h);
|
||||||
|
|
||||||
|
/* Cache Line Eviction for Counter 0 */
|
||||||
|
pl310_write4(sc, PL310_EVENT_COUNTER0_CONF,
|
||||||
|
EVENT_COUNTER_CONF_INCR | EVENT_COUNTER_CONF_CO);
|
||||||
|
/* Data Read Request for Counter 1 */
|
||||||
|
pl310_write4(sc, PL310_EVENT_COUNTER1_CONF,
|
||||||
|
EVENT_COUNTER_CONF_INCR | EVENT_COUNTER_CONF_DRREQ);
|
||||||
|
|
||||||
|
/* Enable and clear pending interrupts */
|
||||||
|
pl310_write4(sc, PL310_INTR_CLEAR, INTR_MASK_ECNTR);
|
||||||
|
pl310_write4(sc, PL310_INTR_MASK, INTR_MASK_ALL);
|
||||||
|
|
||||||
|
/* Enable counters and reset C0 and C1 */
|
||||||
|
pl310_write4(sc, PL310_EVENT_COUNTER_CTRL,
|
||||||
|
EVENT_COUNTER_CTRL_ENABLED |
|
||||||
|
EVENT_COUNTER_CTRL_C0_RESET |
|
||||||
|
EVENT_COUNTER_CTRL_C1_RESET);
|
||||||
|
|
||||||
|
config_intrhook_disestablish(sc->sc_ich);
|
||||||
|
free(sc->sc_ich, M_DEVBUF);
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
pl310_probe(device_t dev)
|
pl310_probe(device_t dev)
|
||||||
{
|
{
|
||||||
@@ -416,10 +454,6 @@ pl310_attach(device_t dev)
|
|||||||
pl310_softc = sc;
|
pl310_softc = sc;
|
||||||
mtx_init(&sc->sc_mtx, "pl310lock", NULL, MTX_SPIN);
|
mtx_init(&sc->sc_mtx, "pl310lock", NULL, MTX_SPIN);
|
||||||
|
|
||||||
/* activate the interrupt */
|
|
||||||
bus_setup_intr(dev, sc->sc_irq_res, INTR_TYPE_MISC | INTR_MPSAFE,
|
|
||||||
pl310_filter, NULL, sc, &sc->sc_irq_h);
|
|
||||||
|
|
||||||
cache_id = pl310_read4(sc, PL310_CACHE_ID);
|
cache_id = pl310_read4(sc, PL310_CACHE_ID);
|
||||||
sc->sc_rtl_revision = (cache_id >> CACHE_ID_RELEASE_SHIFT) &
|
sc->sc_rtl_revision = (cache_id >> CACHE_ID_RELEASE_SHIFT) &
|
||||||
CACHE_ID_RELEASE_MASK;
|
CACHE_ID_RELEASE_MASK;
|
||||||
@@ -466,28 +500,14 @@ pl310_attach(device_t dev)
|
|||||||
if (bootverbose)
|
if (bootverbose)
|
||||||
pl310_print_config(sc);
|
pl310_print_config(sc);
|
||||||
} else {
|
} else {
|
||||||
/*
|
malloc(sizeof(*sc->sc_ich), M_DEVBUF, M_WAITOK);
|
||||||
* Set counters so when cache event happens we'll get interrupt
|
sc->sc_ich->ich_func = pl310_config_intr;
|
||||||
* and be warned that something is off.
|
sc->sc_ich->ich_arg = sc;
|
||||||
*/
|
if (config_intrhook_establish(sc->sc_ich) != 0) {
|
||||||
|
device_printf(dev,
|
||||||
/* Cache Line Eviction for Counter 0 */
|
"config_intrhook_establish failed\n");
|
||||||
pl310_write4(sc, PL310_EVENT_COUNTER0_CONF,
|
return(ENXIO);
|
||||||
EVENT_COUNTER_CONF_INCR | EVENT_COUNTER_CONF_CO);
|
}
|
||||||
/* Data Read Request for Counter 1 */
|
|
||||||
pl310_write4(sc, PL310_EVENT_COUNTER1_CONF,
|
|
||||||
EVENT_COUNTER_CONF_INCR | EVENT_COUNTER_CONF_DRREQ);
|
|
||||||
|
|
||||||
/* Enable and clear pending interrupts */
|
|
||||||
pl310_write4(sc, PL310_INTR_CLEAR, INTR_MASK_ECNTR);
|
|
||||||
pl310_write4(sc, PL310_INTR_MASK, INTR_MASK_ALL);
|
|
||||||
|
|
||||||
/* Enable counters and reset C0 and C1 */
|
|
||||||
pl310_write4(sc, PL310_EVENT_COUNTER_CTRL,
|
|
||||||
EVENT_COUNTER_CTRL_ENABLED |
|
|
||||||
EVENT_COUNTER_CTRL_C0_RESET |
|
|
||||||
EVENT_COUNTER_CTRL_C1_RESET);
|
|
||||||
|
|
||||||
device_printf(dev, "L2 Cache disabled\n");
|
device_printf(dev, "L2 Cache disabled\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -514,4 +534,6 @@ static driver_t pl310_driver = {
|
|||||||
};
|
};
|
||||||
static devclass_t pl310_devclass;
|
static devclass_t pl310_devclass;
|
||||||
|
|
||||||
DRIVER_MODULE(pl310, simplebus, pl310_driver, pl310_devclass, 0, 0);
|
EARLY_DRIVER_MODULE(pl310, simplebus, pl310_driver, pl310_devclass, 0, 0,
|
||||||
|
BUS_PASS_CPU + BUS_PASS_ORDER_MIDDLE);
|
||||||
|
|
||||||
|
|||||||
@@ -137,6 +137,8 @@
|
|||||||
#define POWER_CTRL_ENABLE_GATING (1 << 0)
|
#define POWER_CTRL_ENABLE_GATING (1 << 0)
|
||||||
#define POWER_CTRL_ENABLE_STANDBY (1 << 1)
|
#define POWER_CTRL_ENABLE_STANDBY (1 << 1)
|
||||||
|
|
||||||
|
struct intr_config_hook;
|
||||||
|
|
||||||
struct pl310_softc {
|
struct pl310_softc {
|
||||||
device_t sc_dev;
|
device_t sc_dev;
|
||||||
struct resource *sc_mem_res;
|
struct resource *sc_mem_res;
|
||||||
@@ -145,6 +147,7 @@ struct pl310_softc {
|
|||||||
int sc_enabled;
|
int sc_enabled;
|
||||||
struct mtx sc_mtx;
|
struct mtx sc_mtx;
|
||||||
u_int sc_rtl_revision;
|
u_int sc_rtl_revision;
|
||||||
|
struct intr_config_hook *sc_ich;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user