From patchwork Tue Mar 12 01:49:20 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1055025 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [203.11.71.2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 44JHwZ3F2sz9s9T for ; Tue, 12 Mar 2019 12:50:06 +1100 (AEDT) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="c7AY2uH5"; dkim-atps=neutral Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 44JHwZ1b77zDqFp for ; Tue, 12 Mar 2019 12:50:06 +1100 (AEDT) X-Original-To: pdbg@lists.ozlabs.org Delivered-To: pdbg@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::52b; helo=mail-pg1-x52b.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=gmail.com Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="c7AY2uH5"; dkim-atps=neutral Received: from mail-pg1-x52b.google.com (mail-pg1-x52b.google.com [IPv6:2607:f8b0:4864:20::52b]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 44JHwH5zQLzDqFG for ; Tue, 12 Mar 2019 12:49:51 +1100 (AEDT) Received: by mail-pg1-x52b.google.com with SMTP id k11so529768pgb.8 for ; Mon, 11 Mar 2019 18:49:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=uTU02tlkz//c0VVZNB6UpacZb/8i6Cz007ks3Tu/bow=; b=c7AY2uH5CA3N6nY++oQ8lN0NBejZV3hBGArU9OqTaWxIOPG0Q8ndzXIuGXioE/pZ+L dIjfyDw55wpm9rtlwmz2IyGzq99Hieq1W+7Ua0265PJrgd1bNvOSdQDQW4HHjYhasEia FNmDVggCa4ogOZESORgLUs86k7y/IP+cBIvvNHtF6CL0CPC1Ysd8wJFFHA3sSG7TIAo2 t2iyeWEkR8CMWBT1+FITKqFga95EXzVrhYRGdFoi3t9N2v/hD8em+N/y8hYokc5pTlaN pM2zinBLkCeuQ/Acaz1nT+7t+H+ddcGSxZnkhsQU2VuxEElunx3T5hskpnEZnP2sqJdx 9amA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=uTU02tlkz//c0VVZNB6UpacZb/8i6Cz007ks3Tu/bow=; b=nNtMNU9a9sYow5uA7scNP6LUxJkZ4aS1iI/bXbC319wb42zrlyr9YKartm9rfVTNng wZsMpzQYGCl3GJeCzZPN8C9bPOVvJSN8QYlu90qsT4rITVIGkL8msGfB4/VUJbyg0rZh xm28wCM7zb6Vlz09wL/JomurPY9bidhGQh/NBi9BijKv5y6QUANA1LCtdhImJuURTVQI DMai43eyQ83VKkLnyPbUBghg0ckIA7aCp5UlQXDwn80wx0ZdhVS4XvM4CzyQKZXZvXtR mKB1sOHcqFHaVOSjngG1uV7sjLvakaU1Y3+Q4hUKyUBd7ESTadcm8A8TSsyhy+3T28Nz 9ekQ== X-Gm-Message-State: APjAAAVrwk25W/PMVbLTHTcreinIgFpquJLpc2Xgtxbr8GOXRKOKxf2r 5e28tb0SSPWp/zYsbHHi3nhj3RF9DB8= X-Google-Smtp-Source: APXvYqzQCnkurxpIoPvXVJ3PRxgUePpj0GI/giMMLznDpQhoceG6HU9lSSXjzc0R6Ba0rRlYGNTByA== X-Received: by 2002:a17:902:501:: with SMTP id 1mr36445309plf.72.1552355389357; Mon, 11 Mar 2019 18:49:49 -0700 (PDT) Received: from bobo.ibm.com ([1.132.158.219]) by smtp.gmail.com with ESMTPSA id m9sm10592891pfi.31.2019.03.11.18.49.47 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Mon, 11 Mar 2019 18:49:48 -0700 (PDT) From: Nicholas Piggin To: pdbg@lists.ozlabs.org Date: Tue, 12 Mar 2019 11:49:20 +1000 Message-Id: <20190312014920.25368-8-npiggin@gmail.com> X-Mailer: git-send-email 2.20.1 In-Reply-To: <20190312014920.25368-1-npiggin@gmail.com> References: <20190312014920.25368-1-npiggin@gmail.com> MIME-Version: 1.0 Subject: [Pdbg] [PATCH v2 7/7] libpdbg/p8chip.c: Emulate sreset using ramming for active threads X-BeenThere: pdbg@lists.ozlabs.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: "mailing list for https://github.com/open-power/pdbg development" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Nicholas Piggin Errors-To: pdbg-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Pdbg" Based on patch from Alistair, some fixes and changes: - account HILE bit, set/clear MSR_LE - clear MSR_PR - don't use raw ramming (clearer this way, not perf critical) At the moment, must manually stop all threads in the core, and manually restart them. Can change behaviour depending on what exactly we want (e.g., sreset all threads may be good for debugging). Tested-by: Stewart Smith --- libpdbg/p8chip.c | 131 +++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 128 insertions(+), 3 deletions(-) diff --git a/libpdbg/p8chip.c b/libpdbg/p8chip.c index cd4a50b..ff21d6b 100644 --- a/libpdbg/p8chip.c +++ b/libpdbg/p8chip.c @@ -29,6 +29,7 @@ #define RAS_STATUS_TIMEOUT 100 #define DIRECT_CONTROLS_REG 0x0 +#define DIRECT_CONTROL_SP_SRESET PPC_BIT(60) #define DIRECT_CONTROL_SP_STEP PPC_BIT(61) #define DIRECT_CONTROL_SP_START PPC_BIT(62) #define DIRECT_CONTROL_SP_STOP PPC_BIT(63) @@ -314,10 +315,60 @@ static int p8_thread_start(struct thread *thread) return 0; } -static int p8_thread_sreset(struct thread *thread) +static void p8_ram_unquiesce_siblings(struct thread *thread) +{ + struct pdbg_target *target; + struct core *chip = target_to_core( + pdbg_target_require_parent("core", &thread->target)); + + pdbg_for_each_compatible(&chip->target, target, "ibm,power8-thread") { + struct thread *tmp; + + if (pdbg_target_probe(target) != PDBG_TARGET_ENABLED) + continue; + + tmp = target_to_thread(target); + if (!tmp->status.quiesced) + continue; + + if (!tmp->ram_did_quiesce) + continue; + + p8_thread_start(tmp); + + tmp->ram_did_quiesce = false; + } +} + +static int p8_ram_quiesce_siblings(struct thread *thread) { - /* Broken on p8 */ - return 1; + struct pdbg_target *target; + struct core *chip = target_to_core( + pdbg_target_require_parent("core", &thread->target)); + int rc = 0; + + pdbg_for_each_compatible(&chip->target, target, "ibm,power8-thread") { + struct thread *tmp; + + if (pdbg_target_probe(target) != PDBG_TARGET_ENABLED) + continue; + + tmp = target_to_thread(target); + if (tmp->status.quiesced) + continue; + + rc = p8_thread_stop(tmp); + if (rc) + break; + tmp->ram_did_quiesce = true; + } + + if (!rc) + return 0; + + p8_ram_unquiesce_siblings(thread); + + return rc; } static int p8_ram_setup(struct thread *thread) @@ -458,6 +509,80 @@ static int p8_ram_putxer(struct pdbg_target *thread, uint64_t value) return 0; } +#define SPR_SRR0 0x01a +#define SPR_SRR1 0x01b + +#define HID0_HILE PPC_BIT(19) + +#define MSR_HV PPC_BIT(3) /* Hypervisor mode */ +#define MSR_EE PPC_BIT(48) /* External Int. Enable */ +#define MSR_PR PPC_BIT(49) /* Problem State */ +#define MSR_FE0 PPC_BIT(52) /* FP Exception 0 */ +#define MSR_FE1 PPC_BIT(55) /* FP Exception 1 */ +#define MSR_IR PPC_BIT(58) /* Instructions reloc */ +#define MSR_DR PPC_BIT(59) /* Data reloc */ +#define MSR_RI PPC_BIT(62) /* Recoverable Interrupt */ +#define MSR_LE PPC_BIT(63) /* Little Endian */ + +static int p8_get_hid0(struct pdbg_target *chip, uint64_t *value); +static int emulate_sreset(struct thread *thread) +{ + struct pdbg_target *chip = pdbg_target_parent("core", &thread->target); + uint64_t hid0; + uint64_t old_nia, old_msr; + uint64_t new_nia, new_msr; + + printf("emulate sreset begin\n"); + CHECK_ERR(p8_get_hid0(chip, &hid0)); + printf("emulate sreset HILE=%d\n", !!(hid0 & HID0_HILE)); + CHECK_ERR(ram_getnia(&thread->target, &old_nia)); + CHECK_ERR(ram_getmsr(&thread->target, &old_msr)); + new_nia = 0x100; + new_msr = (old_msr & ~(MSR_PR | MSR_IR | MSR_DR | MSR_FE0 | MSR_FE1 | MSR_EE | MSR_RI)) | MSR_HV; + if (hid0 & HID0_HILE) + new_msr |= MSR_LE; + else + new_msr &= ~MSR_LE; + printf("emulate sreset old NIA:%llx MSR:%llx\n", old_nia, old_msr); + printf("emulate sreset new NIA:%llx MSR:%llx\n", new_nia, new_msr); + CHECK_ERR(ram_putspr(&thread->target, SPR_SRR0, old_nia)); + CHECK_ERR(ram_putspr(&thread->target, SPR_SRR1, old_msr)); + CHECK_ERR(ram_putnia(&thread->target, new_nia)); + CHECK_ERR(ram_putmsr(&thread->target, new_msr)); + printf("emulate sreset done\n"); + + return 0; +} + +static int p8_thread_sreset(struct thread *thread) +{ + int rc; + + if (!(thread->status.active)) { + CHECK_ERR(pib_write(&thread->target, DIRECT_CONTROLS_REG, DIRECT_CONTROL_SP_SRESET)); + thread->status = get_thread_status(thread); + + return 0; + } + + rc = p8_ram_quiesce_siblings(thread); + if (rc) + return rc; + + /* Thread was active, emulate the sreset */ + rc = p8_ram_setup(thread); + if (rc) { + p8_ram_unquiesce_siblings(thread); + return rc; + } + rc = emulate_sreset(thread); + p8_ram_destroy(thread); + p8_ram_unquiesce_siblings(thread); + if (rc) + return rc; + return p8_thread_start(thread); +} + /* * Initialise all viable threads for ramming on the given core. */