Page MenuHomeFreeBSD

D26764.id78181.diff
No OneTemporary

D26764.id78181.diff

Index: sys/arm64/arm64/gic_v3.c
===================================================================
--- sys/arm64/arm64/gic_v3.c
+++ sys/arm64/arm64/gic_v3.c
@@ -154,7 +154,8 @@
/* Helper routines starting with gic_v3_ */
static int gic_v3_dist_init(struct gic_v3_softc *);
static int gic_v3_redist_alloc(struct gic_v3_softc *);
-static int gic_v3_redist_find(struct gic_v3_softc *);
+static int gic_v3_redist_find_all(struct gic_v3_softc *);
+static int gic_v3_redist_find(struct gic_v3_softc *, u_int cpuid);
static int gic_v3_redist_init(struct gic_v3_softc *);
static int gic_v3_cpu_init(struct gic_v3_softc *);
static void gic_v3_wait_for_rwp(struct gic_v3_softc *, enum gic_v3_xdist);
@@ -165,6 +166,7 @@
static gic_v3_initseq_t gic_v3_primary_init[] = {
gic_v3_dist_init,
gic_v3_redist_alloc,
+ gic_v3_redist_find_all,
gic_v3_redist_init,
gic_v3_cpu_init,
NULL
@@ -192,12 +194,19 @@
uint64_t
gic_r_read_8(device_t dev, bus_size_t offset)
+{
+
+ return (gic_r_read_nth_8(dev, PCPU_GET(cpuid), offset));
+}
+
+uint64_t
+gic_r_read_nth_8(device_t dev, int which, bus_size_t offset)
{
struct gic_v3_softc *sc;
struct resource *rdist;
sc = device_get_softc(dev);
- rdist = &sc->gic_redists.pcpu[PCPU_GET(cpuid)]->res;
+ rdist = &sc->gic_redists.pcpu[which]->res;
return (bus_read_8(rdist, offset));
}
@@ -393,6 +402,9 @@
case GICV3_IVAR_REDIST:
*result = (uintptr_t)sc->gic_redists.pcpu[PCPU_GET(cpuid)];
return (0);
+ case GICV3_IVAR_REDISTS:
+ *result = (uintptr_t)sc->gic_redists.pcpu;
+ return (0);
case GIC_IVAR_HW_REV:
KASSERT(
GICR_PIDR2_ARCH(sc->gic_pidr2) == GICR_PIDR2_ARCH_GICv3 ||
@@ -1136,18 +1148,15 @@
}
static int
-gic_v3_redist_find(struct gic_v3_softc *sc)
+gic_v3_redist_find(struct gic_v3_softc *sc, u_int cpuid)
{
struct resource r_res;
bus_space_handle_t r_bsh;
uint64_t aff;
uint64_t typer;
uint32_t pidr2;
- u_int cpuid;
size_t i;
- cpuid = PCPU_GET(cpuid);
-
aff = CPU_AFFINITY(cpuid);
/* Affinity in format for comparison with typer */
aff = (CPU_AFF3(aff) << 24) | (CPU_AFF2(aff) << 16) |
@@ -1204,6 +1213,19 @@
return (ENXIO);
}
+static int
+gic_v3_redist_find_all(struct gic_v3_softc *sc)
+{
+ int i, err;
+
+ CPU_FOREACH(i) {
+ err = gic_v3_redist_find(sc, i);
+ if (err != 0)
+ return err;
+ }
+ return (0);
+}
+
static int
gic_v3_redist_wake(struct gic_v3_softc *sc)
{
@@ -1240,10 +1262,6 @@
int err;
size_t i;
- err = gic_v3_redist_find(sc);
- if (err != 0)
- return (err);
-
err = gic_v3_redist_wake(sc);
if (err != 0)
return (err);
Index: sys/arm64/arm64/gic_v3_var.h
===================================================================
--- sys/arm64/arm64/gic_v3_var.h
+++ sys/arm64/arm64/gic_v3_var.h
@@ -95,9 +95,11 @@
#define GICV3_IVAR_NIRQS 1000
/* 1001 was GICV3_IVAR_REDIST_VADDR */
#define GICV3_IVAR_REDIST 1002
+#define GICV3_IVAR_REDISTS 1003
__BUS_ACCESSOR(gicv3, nirqs, GICV3, NIRQS, u_int);
__BUS_ACCESSOR(gicv3, redist, GICV3, REDIST, void *);
+__BUS_ACCESSOR(gicv3, redists, GICV3, REDISTS, struct redist_pcpu **);
/* Device methods */
int gic_v3_attach(device_t dev);
@@ -106,6 +108,7 @@
uint32_t gic_r_read_4(device_t, bus_size_t);
uint64_t gic_r_read_8(device_t, bus_size_t);
+uint64_t gic_r_read_nth_8(device_t, int, bus_size_t);
void gic_r_write_4(device_t, bus_size_t, uint32_t var);
void gic_r_write_8(device_t, bus_size_t, uint64_t var);
Index: sys/arm64/arm64/gicv3_its.c
===================================================================
--- sys/arm64/arm64/gicv3_its.c
+++ sys/arm64/arm64/gicv3_its.c
@@ -680,7 +680,6 @@
its_init_cpu(device_t dev, struct gicv3_its_softc *sc)
{
device_t gicv3;
- vm_paddr_t target;
u_int cpuid;
struct redist_pcpu *rpcpu;
@@ -701,20 +700,42 @@
rpcpu->lpi_enabled = true;
}
- if ((gic_its_read_8(sc, GITS_TYPER) & GITS_TYPER_PTA) != 0) {
- /* This ITS wants the redistributor physical address */
- target = vtophys(rman_get_virtual(&rpcpu->res));
- } else {
- /* This ITS wants the unique processor number */
- target = GICR_TYPER_CPUNUM(gic_r_read_8(gicv3, GICR_TYPER)) <<
- CMD_TARGET_SHIFT;
- }
+ return (0);
+}
- sc->sc_its_cols[cpuid]->col_target = target;
- sc->sc_its_cols[cpuid]->col_id = cpuid;
+static int
+its_init_collections(device_t dev, struct gicv3_its_softc *sc)
+{
+ device_t gicv3;
+ struct redist_pcpu **rpcpus;
+ uint64_t gicr_typer;
+ vm_paddr_t target;
+ int i;
+ bool gits_typer_pta;
- its_cmd_mapc(dev, sc->sc_its_cols[cpuid], 1);
- its_cmd_invall(dev, sc->sc_its_cols[cpuid]);
+ gicv3 = device_get_parent(dev);
+ rpcpus = gicv3_get_redists(dev);
+ gits_typer_pta = (gic_its_read_8(sc, GITS_TYPER) & GITS_TYPER_PTA) != 0;
+ CPU_FOREACH(i) {
+ if (CPU_ISSET(i, &sc->sc_cpus) == 0)
+ continue;
+
+ if (gits_typer_pta) {
+ /* This ITS wants the redistributor physical address */
+ target = vtophys(rman_get_virtual(&rpcpus[i]->res));
+ } else {
+ /* This ITS wants the unique processor number */
+ gicr_typer = gic_r_read_nth_8(gicv3, i, GICR_TYPER);
+ target = GICR_TYPER_CPUNUM(gicr_typer) <<
+ CMD_TARGET_SHIFT;
+ }
+
+ sc->sc_its_cols[i]->col_target = target;
+ sc->sc_its_cols[i]->col_id = i;
+
+ its_cmd_mapc(dev, sc->sc_its_cols[i], 1);
+ its_cmd_invall(dev, sc->sc_its_cols[i]);
+ }
return (0);
}
@@ -876,6 +897,8 @@
/* Enable LPIs on this CPU */
its_init_cpu(dev, sc);
+ its_init_collections(dev, sc);
+
TAILQ_INIT(&sc->sc_its_dev_list);
TAILQ_INIT(&sc->sc_free_irqs);

File Metadata

Mime Type
text/plain
Expires
Sat, Oct 18, 8:59 AM (2 h, 32 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
23860881
Default Alt Text
D26764.id78181.diff (5 KB)

Event Timeline