git: ae84491a3594 - main - gicv3: Only set the redistributor base if we're not prealloced
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Wed, 28 Feb 2024 14:10:44 UTC
The branch main has been updated by imp:
URL: https://cgit.FreeBSD.org/src/commit/?id=ae84491a3594c542f2aedc9340581cbb30386c1e
commit ae84491a3594c542f2aedc9340581cbb30386c1e
Author: Warner Losh <imp@FreeBSD.org>
AuthorDate: 2024-02-28 14:08:39 +0000
Commit: Warner Losh <imp@FreeBSD.org>
CommitDate: 2024-02-28 14:09:42 +0000
gicv3: Only set the redistributor base if we're not prealloced
Only set the redistributor base if we're not reallocated. If we are
preallocated, leave it all alone.
Sponsored by: Netflix
Reviewed by: andrew
Differential Revision: https://reviews.freebsd.org/D44035
---
sys/arm64/arm64/gicv3_its.c | 134 +++++++++++++++++++++++---------------------
1 file changed, 71 insertions(+), 63 deletions(-)
diff --git a/sys/arm64/arm64/gicv3_its.c b/sys/arm64/arm64/gicv3_its.c
index c7e9ef7a3733..74d6f617bbba 100644
--- a/sys/arm64/arm64/gicv3_its.c
+++ b/sys/arm64/arm64/gicv3_its.c
@@ -745,81 +745,89 @@ static void
its_init_cpu_lpi(device_t dev, struct gicv3_its_softc *sc)
{
device_t gicv3;
- uint64_t xbaser, tmp;
+ uint64_t xbaser, tmp, size;
uint32_t ctlr;
u_int cpuid;
gicv3 = device_get_parent(dev);
cpuid = PCPU_GET(cpuid);
- /* Disable LPIs */
- ctlr = gic_r_read_4(gicv3, GICR_CTLR);
- ctlr &= ~GICR_CTLR_LPI_ENABLE;
- gic_r_write_4(gicv3, GICR_CTLR, ctlr);
-
- /* Make sure changes are observable my the GIC */
- dsb(sy);
-
/*
- * Set the redistributor base
+ * Set the redistributor base. If we're reusing what we found on boot
+ * since the gic was already running, then don't touch it here. We also
+ * don't need to disable / enable LPI if we're not changing PROPBASER,
+ * so only do that if we're not prealloced.
*/
- xbaser = vtophys(sc->sc_conf_base) |
- (GICR_PROPBASER_SHARE_IS << GICR_PROPBASER_SHARE_SHIFT) |
- (GICR_PROPBASER_CACHE_NIWAWB << GICR_PROPBASER_CACHE_SHIFT) |
- (flsl(LPI_CONFTAB_SIZE | GIC_FIRST_LPI) - 1);
- gic_r_write_8(gicv3, GICR_PROPBASER, xbaser);
-
- /* Check the cache attributes we set */
- tmp = gic_r_read_8(gicv3, GICR_PROPBASER);
-
- if ((tmp & GICR_PROPBASER_SHARE_MASK) !=
- (xbaser & GICR_PROPBASER_SHARE_MASK)) {
- if ((tmp & GICR_PROPBASER_SHARE_MASK) ==
- (GICR_PROPBASER_SHARE_NS << GICR_PROPBASER_SHARE_SHIFT)) {
- /* We need to mark as non-cacheable */
- xbaser &= ~(GICR_PROPBASER_SHARE_MASK |
- GICR_PROPBASER_CACHE_MASK);
- /* Non-cacheable */
- xbaser |= GICR_PROPBASER_CACHE_NIN <<
- GICR_PROPBASER_CACHE_SHIFT;
- /* Non-shareable */
- xbaser |= GICR_PROPBASER_SHARE_NS <<
- GICR_PROPBASER_SHARE_SHIFT;
- gic_r_write_8(gicv3, GICR_PROPBASER, xbaser);
+ if ((sc->sc_its_flags & ITS_FLAGS_LPI_PREALLOC) == 0) {
+ /* Disable LPIs */
+ ctlr = gic_r_read_4(gicv3, GICR_CTLR);
+ ctlr &= ~GICR_CTLR_LPI_ENABLE;
+ gic_r_write_4(gicv3, GICR_CTLR, ctlr);
+
+ /* Make sure changes are observable my the GIC */
+ dsb(sy);
+
+ size = (flsl(LPI_CONFTAB_SIZE | GIC_FIRST_LPI) - 1);
+
+ xbaser = vtophys(sc->sc_conf_base) |
+ (GICR_PROPBASER_SHARE_IS << GICR_PROPBASER_SHARE_SHIFT) |
+ (GICR_PROPBASER_CACHE_NIWAWB << GICR_PROPBASER_CACHE_SHIFT) |
+ size;
+
+ gic_r_write_8(gicv3, GICR_PROPBASER, xbaser);
+
+ /* Check the cache attributes we set */
+ tmp = gic_r_read_8(gicv3, GICR_PROPBASER);
+
+ if ((tmp & GICR_PROPBASER_SHARE_MASK) !=
+ (xbaser & GICR_PROPBASER_SHARE_MASK)) {
+ if ((tmp & GICR_PROPBASER_SHARE_MASK) ==
+ (GICR_PROPBASER_SHARE_NS << GICR_PROPBASER_SHARE_SHIFT)) {
+ /* We need to mark as non-cacheable */
+ xbaser &= ~(GICR_PROPBASER_SHARE_MASK |
+ GICR_PROPBASER_CACHE_MASK);
+ /* Non-cacheable */
+ xbaser |= GICR_PROPBASER_CACHE_NIN <<
+ GICR_PROPBASER_CACHE_SHIFT;
+ /* Non-shareable */
+ xbaser |= GICR_PROPBASER_SHARE_NS <<
+ GICR_PROPBASER_SHARE_SHIFT;
+ gic_r_write_8(gicv3, GICR_PROPBASER, xbaser);
+ }
+ sc->sc_its_flags |= ITS_FLAGS_LPI_CONF_FLUSH;
}
- sc->sc_its_flags |= ITS_FLAGS_LPI_CONF_FLUSH;
- }
- /*
- * Set the LPI pending table base
- */
- xbaser = vtophys(sc->sc_pend_base[cpuid]) |
- (GICR_PENDBASER_CACHE_NIWAWB << GICR_PENDBASER_CACHE_SHIFT) |
- (GICR_PENDBASER_SHARE_IS << GICR_PENDBASER_SHARE_SHIFT);
-
- gic_r_write_8(gicv3, GICR_PENDBASER, xbaser);
-
- tmp = gic_r_read_8(gicv3, GICR_PENDBASER);
-
- if ((tmp & GICR_PENDBASER_SHARE_MASK) ==
- (GICR_PENDBASER_SHARE_NS << GICR_PENDBASER_SHARE_SHIFT)) {
- /* Clear the cahce and shareability bits */
- xbaser &= ~(GICR_PENDBASER_CACHE_MASK |
- GICR_PENDBASER_SHARE_MASK);
- /* Mark as non-shareable */
- xbaser |= GICR_PENDBASER_SHARE_NS << GICR_PENDBASER_SHARE_SHIFT;
- /* And non-cacheable */
- xbaser |= GICR_PENDBASER_CACHE_NIN <<
- GICR_PENDBASER_CACHE_SHIFT;
- }
+ /*
+ * Set the LPI pending table base
+ */
+ xbaser = vtophys(sc->sc_pend_base[cpuid]) |
+ (GICR_PENDBASER_CACHE_NIWAWB << GICR_PENDBASER_CACHE_SHIFT) |
+ (GICR_PENDBASER_SHARE_IS << GICR_PENDBASER_SHARE_SHIFT);
+
+ gic_r_write_8(gicv3, GICR_PENDBASER, xbaser);
+
+ tmp = gic_r_read_8(gicv3, GICR_PENDBASER);
+
+ if ((tmp & GICR_PENDBASER_SHARE_MASK) ==
+ (GICR_PENDBASER_SHARE_NS << GICR_PENDBASER_SHARE_SHIFT)) {
+ /* Clear the cahce and shareability bits */
+ xbaser &= ~(GICR_PENDBASER_CACHE_MASK |
+ GICR_PENDBASER_SHARE_MASK);
+ /* Mark as non-shareable */
+ xbaser |= GICR_PENDBASER_SHARE_NS << GICR_PENDBASER_SHARE_SHIFT;
+ /* And non-cacheable */
+ xbaser |= GICR_PENDBASER_CACHE_NIN <<
+ GICR_PENDBASER_CACHE_SHIFT;
+ }
- /* Enable LPIs */
- ctlr = gic_r_read_4(gicv3, GICR_CTLR);
- ctlr |= GICR_CTLR_LPI_ENABLE;
- gic_r_write_4(gicv3, GICR_CTLR, ctlr);
+ /* Enable LPIs */
+ ctlr = gic_r_read_4(gicv3, GICR_CTLR);
+ ctlr |= GICR_CTLR_LPI_ENABLE;
+ gic_r_write_4(gicv3, GICR_CTLR, ctlr);
- /* Make sure the GIC has seen everything */
- dsb(sy);
+ /* Make sure the GIC has seen everything */
+ dsb(sy);
+ }
}
static int