From patchwork Sun Sep 10 07:35:28 2017 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Benjamin Herrenschmidt X-Patchwork-Id: 812063 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [103.22.144.68]) (using TLSv1.2 with cipher ADH-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 3xqjZG3HWQz9s8J for ; Sun, 10 Sep 2017 17:37:26 +1000 (AEST) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 3xqjZG0wbxzDrp8 for ; Sun, 10 Sep 2017 17:37:26 +1000 (AEST) X-Original-To: skiboot@lists.ozlabs.org Delivered-To: skiboot@lists.ozlabs.org Authentication-Results: ozlabs.org; spf=permerror (mailfrom) smtp.mailfrom=kernel.crashing.org (client-ip=63.228.1.57; helo=gate.crashing.org; envelope-from=benh@kernel.crashing.org; receiver=) Received: from gate.crashing.org (gate.crashing.org [63.228.1.57]) (using TLSv1 with cipher DHE-RSA-AES256-SHA (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 3xqjXY6hlGzDrn0 for ; Sun, 10 Sep 2017 17:35:57 +1000 (AEST) Received: from pasglop.au.ibm.com (localhost.localdomain [127.0.0.1]) by gate.crashing.org (8.14.1/8.13.8) with ESMTP id v8A7ZahK032562; Sun, 10 Sep 2017 02:35:46 -0500 From: Benjamin Herrenschmidt To: skiboot@lists.ozlabs.org Date: Sun, 10 Sep 2017 17:35:28 +1000 Message-Id: <20170910073535.27226-6-benh@kernel.crashing.org> X-Mailer: git-send-email 2.13.5 In-Reply-To: <20170910073535.27226-1-benh@kernel.crashing.org> References: <20170910073535.27226-1-benh@kernel.crashing.org> Subject: [Skiboot] [PATCH v3 06/13] xive: Add exerciser for cache watch/scrub facility in DEBUG builds X-BeenThere: skiboot@lists.ozlabs.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: Mailing list for skiboot development List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , MIME-Version: 1.0 Errors-To: skiboot-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Skiboot" This runs 1000 iterations exercising the cache watch and scrub facilities on VPs and ENDs at boot. This exposes a HW bug with the scrub which will be worked around in a subsequent patch. Signed-off-by: Benjamin Herrenschmidt --- hw/xive.c | 141 ++++++++++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 96 insertions(+), 45 deletions(-) diff --git a/hw/xive.c b/hw/xive.c index 4f08e655..d8d51dee 100644 --- a/hw/xive.c +++ b/hw/xive.c @@ -44,10 +44,12 @@ #define XIVE_DEBUG_DUPLICATES #define XIVE_PERCPU_LOG #define XIVE_DEBUG_INIT_CACHE_UPDATES +#define XIVE_EXTRA_CHECK_INIT_CACHE #else #undef XIVE_DEBUG_DUPLICATES #undef XIVE_PERCPU_LOG #undef XIVE_DEBUG_INIT_CACHE_UPDATES +#undef XIVE_EXTRA_CHECK_INIT_CACHE #endif /* @@ -2870,6 +2872,95 @@ void xive_cpu_callin(struct cpu_thread *cpu) in_be64(xs->tm_ring1 + TM_QW3_HV_PHYS)); } +#ifdef XIVE_DEBUG_INIT_CACHE_UPDATES +static bool xive_check_eq_update(struct xive *x, uint32_t idx, struct xive_eq *eq) +{ + struct xive_eq *eq_p = xive_get_eq(x, idx); + struct xive_eq eq2; + + assert(eq_p); + eq2 = *eq_p; + if (memcmp(eq, &eq2, sizeof(eq)) != 0) { + xive_err(x, "EQ update mismatch idx %d\n", idx); + xive_err(x, "want: %08x %08x %08x %08x\n", + eq->w0, eq->w1, eq->w2, eq->w3); + xive_err(x, " %08x %08x %08x %08x\n", + eq->w4, eq->w5, eq->w6, eq->w7); + xive_err(x, "got : %08x %08x %08x %08x\n", + eq2.w0, eq2.w1, eq2.w2, eq2.w3); + xive_err(x, " %08x %08x %08x %08x\n", + eq2.w4, eq2.w5, eq2.w6, eq2.w7); + return false; + } + return true; +} + +static bool xive_check_vpc_update(struct xive *x, uint32_t idx, struct xive_vp *vp) +{ + struct xive_vp *vp_p = xive_get_vp(x, idx); + struct xive_vp vp2; + + assert(vp_p); + vp2 = *vp_p; + if (memcmp(vp, &vp2, sizeof(vp)) != 0) { + xive_err(x, "VP update mismatch idx %d\n", idx); + xive_err(x, "want: %08x %08x %08x %08x\n", + vp->w0, vp->w1, vp->w2, vp->w3); + xive_err(x, " %08x %08x %08x %08x\n", + vp->w4, vp->w5, vp->w6, vp->w7); + xive_err(x, "got : %08x %08x %08x %08x\n", + vp2.w0, vp2.w1, vp2.w2, vp2.w3); + xive_err(x, " %08x %08x %08x %08x\n", + vp2.w4, vp2.w5, vp2.w6, vp2.w7); + return false; + } + return true; +} +#else +static inline bool xive_check_eq_update(struct xive *x __unused, + uint32_t idx __unused, + struct xive_eq *eq __unused) +{ + return true; +} + +static inline bool xive_check_vpc_update(struct xive *x __unused, + uint32_t idx __unused, + struct xive_vp *vp __unused) +{ + return true; +} +#endif + +#ifdef XIVE_EXTRA_CHECK_INIT_CACHE +static void xive_special_cache_check(struct xive *x, uint32_t blk, uint32_t idx) +{ + struct xive_vp vp = {}; + uint32_t i; + + for (i = 0; i < 1000; i++) { + struct xive_vp *vp_m = xive_get_vp(x, idx); + + memset(vp_m, (~i) & 0xff, sizeof(*vp_m)); + sync(); + vp.w1 = (i << 16) | i; + xive_vpc_cache_update(x, blk, idx, + 0, 8, &vp, false, true); + if (!xive_check_vpc_update(x, idx, &vp)) { + xive_dbg(x, "Test failed at %d iterations\n", i); + return; + } + } + xive_dbg(x, "1000 iterations test success at %d/0x%x\n", blk, idx); +} +#else +static inline void xive_special_cache_check(struct xive *x __unused, + uint32_t blk __unused, + uint32_t idx __unused) +{ +} +#endif + static void xive_setup_hw_for_emu(struct xive_cpu_state *xs) { struct xive_eq eq; @@ -2897,58 +2988,18 @@ static void xive_setup_hw_for_emu(struct xive_cpu_state *xs) xive_eqc_cache_update(x_eq, xs->eq_blk, xs->eq_idx + XIVE_EMULATION_PRIO, 0, 4, &eq, false, true); + xive_check_eq_update(x_eq, xs->eq_idx + XIVE_EMULATION_PRIO, &eq); + + /* Extra testing of cache watch & scrub facilities */ + xive_special_cache_check(x_vp, xs->vp_blk, xs->vp_idx); -#ifdef XIVE_DEBUG_INIT_CACHE_UPDATES - if (1) { - struct xive_eq *eq_p = xive_get_eq(x_eq, - xs->eq_idx + - XIVE_EMULATION_PRIO); - struct xive_eq eq2; - - assert(eq_p); - eq2 = *eq_p; - if (memcmp(&eq, &eq2, sizeof(eq)) != 0) { - xive_err(x_eq, "EQ update mismatch idx %d\n", - xs->eq_idx); - xive_err(x_eq, "want: %08x %08x %08x %08x\n", - eq.w0, eq.w1, eq.w2, eq.w3); - xive_err(x_eq, " %08x %08x %08x %08x\n", - eq.w4, eq.w5, eq.w6, eq.w7); - xive_err(x_eq, "got : %08x %08x %08x %08x\n", - eq2.w0, eq2.w1, eq2.w2, eq2.w3); - xive_err(x_eq, " %08x %08x %08x %08x\n", - eq2.w4, eq2.w5, eq2.w6, eq2.w7); - } - } -#endif /* Initialize/enable the VP */ xive_init_default_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, true); - - /* Debug code */ -#ifdef XIVE_DEBUG_INIT_CACHE_UPDATES - if (1) { - struct xive_vp *vp_p = xive_get_vp(x_vp, xs->vp_idx); - struct xive_vp vp2; - - assert(vp_p); - vp2 = *vp_p; - if (memcmp(&vp, &vp2, sizeof(vp)) != 0) { - xive_err(x_vp, "VP update mismatch idx %d\n", xs->vp_idx); - xive_err(x_vp, "want: %08x %08x %08x %08x\n", - vp.w0, vp.w1, vp.w2, vp.w3); - xive_err(x_vp, " %08x %08x %08x %08x\n", - vp.w4, vp.w5, vp.w6, vp.w7); - xive_err(x_vp, "got : %08x %08x %08x %08x\n", - vp2.w0, vp2.w1, vp2.w2, vp2.w3); - xive_err(x_vp, " %08x %08x %08x %08x\n", - vp2.w4, vp2.w5, vp2.w6, vp2.w7); - } - } -#endif + xive_check_vpc_update(x_vp, xs->vp_idx, &vp); } static void xive_init_cpu_emulation(struct xive_cpu_state *xs,