[Skiboot] [PATCH 23/60] xive: Split xive_provision_cpu() and use cache watch for VP

Benjamin Herrenschmidt benh at kernel.crashing.org
Thu Dec 22 14:16:31 AEDT 2016


This splits xive_provision_cpu() into one function that actually
provisions the CPU by allocating the EQs and EQ page and will only
be called once at boot, and a function that configures the default
EQs and VPs and can be called potentially multiple times (such as
from xive_reset).

We also make the VP update use the cache watch rather than writing
to the structure directly.

Signed-off-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
---
 hw/xive.c | 79 +++++++++++++++++++++++++++++++++++++++++++++------------------
 1 file changed, 57 insertions(+), 22 deletions(-)

diff --git a/hw/xive.c b/hw/xive.c
index a2db96d..07a0c26 100644
--- a/hw/xive.c
+++ b/hw/xive.c
@@ -252,6 +252,7 @@ struct xive_cpu_state {
 	uint32_t	vp_idx;
 	uint32_t	eq_blk;
 	uint32_t	eq_idx; /* Base eq index of a block of 8 */
+	void		*eq_page;
 
 	/* Pre-allocated IPI */
 	uint32_t	ipi_irq;
@@ -904,6 +905,16 @@ static int64_t xive_eqc_cache_update(struct xive *x, uint64_t block,
 				  new_data, light_watch);
 }
 
+static int64_t xive_vpc_cache_update(struct xive *x, uint64_t block,
+				     uint64_t idx, uint32_t start_dword,
+				     uint32_t dword_count, void *new_data,
+				     bool light_watch)
+{
+	return __xive_cache_watch(x, xive_cache_vpc, block, idx,
+				  start_dword, dword_count,
+				  new_data, light_watch);
+}
+
 static bool xive_set_vsd(struct xive *x, uint32_t tbl, uint32_t idx, uint64_t v)
 {
 	/* Set VC version */
@@ -2131,10 +2142,44 @@ void xive_cpu_callin(struct cpu_thread *cpu)
 	xive_ipi_init(x, cpu);
 }
 
-static void xive_provision_cpu(struct xive_cpu_state *xs, struct cpu_thread *c)
+static void xive_init_cpu_defaults(struct xive_cpu_state *xs)
 {
-	struct xive_vp *vp;
 	struct xive_eq eq;
+	struct xive_vp vp;
+	struct xive *x_eq, *x_vp;
+
+	/* Grab the XIVE where the VP resides. It could be different from
+	 * the local chip XIVE if not using block group mode
+	 */
+	x_vp = xive_from_pc_blk(xs->vp_blk);
+	assert(x_vp);
+
+	/* Grab the XIVE where the EQ resides. It will be the same as the
+	 * VP one with the current provisioning but I prefer not making
+	 * this code depend on it.
+	 */
+	x_eq = xive_from_vc_blk(xs->eq_blk);
+	assert(x_eq);
+
+	/* Initialize the structure */
+	xive_init_eq(xs->vp_blk, xs->vp_idx, &eq,
+		     xs->eq_page, XIVE_EMULATION_PRIO);
+
+	/* Use the cache watch to write it out */
+	xive_eqc_cache_update(x_eq, xs->eq_blk,
+			      xs->eq_idx + XIVE_EMULATION_PRIO,
+			      0, 4, &eq, false);
+
+	/* Initialize/enable the VP */
+	xive_init_vp(x_vp, &vp, xs->eq_blk, xs->eq_idx);
+
+	/* Use the cache watch to write it out */
+	xive_vpc_cache_update(x_vp, xs->vp_blk, xs->vp_idx,
+			      0, 8, &vp, false);
+}
+
+static void xive_provision_cpu(struct xive_cpu_state *xs, struct cpu_thread *c)
+{
 	struct xive *x;
 	void *p;
 
@@ -2142,21 +2187,17 @@ static void xive_provision_cpu(struct xive_cpu_state *xs, struct cpu_thread *c)
 	xs->vp_blk = PIR2VP_BLK(c->pir);
 	xs->vp_idx = PIR2VP_IDX(c->pir);
 
-	/* Grab the XIVE where the VP resides. It could be different from
-	 * the local chip XIVE if not using block group mode
-	 */
-	x = xive_from_pc_blk(xs->vp_blk);
-	assert(x);
-
-	/* Grab VP pointer */
-	vp = xive_get_vp(x, xs->vp_idx);
-	assert(vp);
-
 	/* For now we use identical block IDs for VC and PC but that might
 	 * change. We allocate the EQs on the same XIVE as the VP.
 	 */
 	xs->eq_blk = xs->vp_blk;
 
+	/* Grab the XIVE where the EQ resides. It could be different from
+	 * the local chip XIVE if not using block group mode
+	 */
+	x = xive_from_vc_blk(xs->eq_blk);
+	assert(x);
+
 	/* Allocate a set of EQs for that VP */
 	xs->eq_idx = xive_alloc_eq_set(x, true);
 	assert(!XIVE_ALLOC_IS_ERR(xs->eq_idx));
@@ -2169,16 +2210,7 @@ static void xive_provision_cpu(struct xive_cpu_state *xs, struct cpu_thread *c)
 		xive_err(x, "Failed to allocate EQ backing store\n");
 		assert(false);
 	}
-
-	/* Initialize the structure */
-	xive_init_eq(xs->vp_blk, xs->vp_idx, &eq, p, XIVE_EMULATION_PRIO);
-
-	/* Use the cache watch to write it out */
-	xive_eqc_cache_update(x, xs->vp_blk, xs->eq_idx + XIVE_EMULATION_PRIO,
-			      0, 4, &eq, false);
-
-	/* Initialize/enable the VP */
-	xive_init_vp(x, vp, xs->eq_blk, xs->eq_idx);
+	xs->eq_page = p;
 }
 
 static void xive_init_xics_emulation(struct xive_cpu_state *xs)
@@ -2248,6 +2280,9 @@ static void xive_init_cpu(struct cpu_thread *c)
 	/* Provision a VP and some EQDs for a physical CPU */
 	xive_provision_cpu(xs, c);
 
+	/* Configure the default EQ/VP */
+	xive_init_cpu_defaults(xs);
+
 	/* Initialize the XICS emulation related fields */
 	xive_init_xics_emulation(xs);
 }
-- 
2.9.3



More information about the Skiboot mailing list