From patchwork Wed Apr 20 06:49:53 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1619346 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: bilbo.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=GlzK+mTl; dkim-atps=neutral Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=lists.ozlabs.org (client-ip=2404:9400:2:0:216:3eff:fee1:b9f1; helo=lists.ozlabs.org; envelope-from=pdbg-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org; receiver=) Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2404:9400:2:0:216:3eff:fee1:b9f1]) (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 bilbo.ozlabs.org (Postfix) with ESMTPS id 4KjrtB1714z9sG0 for ; Wed, 20 Apr 2022 16:51:14 +1000 (AEST) Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4KjrtB0Mxzz2ymb for ; Wed, 20 Apr 2022 16:51:14 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=GlzK+mTl; dkim-atps=neutral X-Original-To: pdbg@lists.ozlabs.org Delivered-To: pdbg@lists.ozlabs.org Authentication-Results: lists.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gmail.com (client-ip=2607:f8b0:4864:20::102e; helo=mail-pj1-x102e.google.com; envelope-from=npiggin@gmail.com; receiver=) Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.a=rsa-sha256 header.s=20210112 header.b=GlzK+mTl; dkim-atps=neutral Received: from mail-pj1-x102e.google.com (mail-pj1-x102e.google.com [IPv6:2607:f8b0:4864:20::102e]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 4Kjrt74k87z2xrv for ; Wed, 20 Apr 2022 16:51:11 +1000 (AEST) Received: by mail-pj1-x102e.google.com with SMTP id mm4-20020a17090b358400b001cb93d8b137so4151322pjb.2 for ; Tue, 19 Apr 2022 23:51:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20210112; h=from:to:cc:subject:date:message-id:in-reply-to:references :mime-version:content-transfer-encoding; bh=90Hn5oLAozidZZEUQR4uR0WOr8J/Hp6bwTzAiryuqmc=; b=GlzK+mTlYhj86R/F1TNr2Tx2Ou+dvhijQiq3SvxKgNbIHSAmUoOzsb5Hv+6wtZIQHU TK0pkzrif7C7eJCB/C5QfoUoEXkzAxjJ7/SyB9oE2ChkipRwJn81KqzhDU7QELRvTbd5 rzcSubIZkd1wO4kH+4+JhuXt5LLo4GNQ+TO3S3crWTfxmRySHRfiHoM1u7OZ9bVeXMS8 PwjzU0N5HQX9jqJhumeuZ3O5JQl3FHzoJpqWGrxIuRJG68pMs4XgsIR5npAFFyvJsE62 Cpa+rojZGkCgh/Ubq8CFYwnWYGDF0nxAMirdTOUe//eCEMXJ95zF4wByVoB02GEEYy6t +Xxg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20210112; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references:mime-version:content-transfer-encoding; bh=90Hn5oLAozidZZEUQR4uR0WOr8J/Hp6bwTzAiryuqmc=; b=lHpMm1nrC2bsEHKVvvHAspfk/5xzLHVsShw581RYDI5PXy0EkumzxzsBJHd1BrRN8O GQRKWrbm21aWGBfwct0xjBVCzmR4+4VDgzgfhlPwUlscYT+g4Pk1ym2lUA7L/eKMdh3E rwxcB3X71GTQeWFwTafcvD/NoSPT0t4PhRi1ex6M1VcijPLwH8R+YZY2Yf6sNukQAASF 9Ew5qnFII3YY+5vSIlygT8O6chQKR3tYCxku5wmkocVIBH86P5yRUGlcmp9+gWszWtXP eeHsZ1kz3ksFsRpOHZfr3xgz0GMF7IBKp0Z1AeB4PERbO/3jbobYXEH68QOiFeS4Z00+ JQeQ== X-Gm-Message-State: AOAM533gc8iMqM5Via2Baj7WD4A81ljGVeVZ4U/RA/f6dAQVSpJOYZuY 1UK9EGIRCxQQ/UMksaiTNAJS3Wyuer5VYA== X-Google-Smtp-Source: ABdhPJwjCHb98ROvBofvp9ED3BpahFSOSBb/tVUfFsKtvl7QffEuu5ORtTuJn72KNKm96nMFz+2teA== X-Received: by 2002:a17:902:d1cb:b0:158:a94b:965f with SMTP id g11-20020a170902d1cb00b00158a94b965fmr19044646plb.96.1650437469251; Tue, 19 Apr 2022 23:51:09 -0700 (PDT) Received: from bobo.ozlabs.ibm.com ([203.221.203.144]) by smtp.gmail.com with ESMTPSA id x20-20020aa79574000000b005061f4782c5sm18481235pfq.183.2022.04.19.23.51.07 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Apr 2022 23:51:08 -0700 (PDT) From: Nicholas Piggin To: pdbg@lists.ozlabs.org Date: Wed, 20 Apr 2022 16:49:53 +1000 Message-Id: <20220420065013.222816-20-npiggin@gmail.com> X-Mailer: git-send-email 2.35.1 In-Reply-To: <20220420065013.222816-1-npiggin@gmail.com> References: <20220420065013.222816-1-npiggin@gmail.com> MIME-Version: 1.0 Subject: [Pdbg] [PATCH v2 19/39] gdbserver: use read-modify-write for put_mem that is not 8-byte aligned 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" Not all targets have memory access that can support arbitrary byte writes. Use RMW for put_mem commands that are not 8-byte aligned. These helpers should possibly be moved into core code and this should really either be done in the target accessor, or at least an alignment capability should be exposed to the caller. But for now this will allow sbefifo mem ops to work to set breakpoints (which requires 4-byte writes). Signed-off-by: Nicholas Piggin Reviewed-by: Joel Stanley --- src/pdbgproxy.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/src/pdbgproxy.c b/src/pdbgproxy.c index 9729eaa1..4c7b4a82 100644 --- a/src/pdbgproxy.c +++ b/src/pdbgproxy.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -229,6 +230,86 @@ static uint64_t get_real_addr(uint64_t addr) return addr; } +/* + * TODO: Move write_memory and read_memory into libpdbg helper and advertise + * alignment requirement of a target, or have the back-ends use it directly + * (latter may have the problem that implicit R-M-W is undesirable at very low + * level operations if we only wanted to write). + */ + +/* WARNING: _a *MUST* be a power of two */ +#define ALIGN_UP(_v, _a) (((_v) + (_a) - 1) & ~((_a) - 1)) +#define ALIGN_DOWN(_v, _a) ((_v) & ~((_a) - 1)) + +static int write_memory(uint64_t addr, uint64_t len, void *buf, size_t align) +{ + uint64_t start_addr, end_addr; + void *tmpbuf = NULL; + void *src; + int err = 0; + + start_addr = ALIGN_DOWN(addr, align); + end_addr = ALIGN_UP(addr + len, align); + + if (addr != start_addr || (addr + len) != end_addr) { + tmpbuf = malloc(end_addr - start_addr); + if (mem_read(adu_target, start_addr, tmpbuf, end_addr - start_addr, 0, false)) { + PR_ERROR("Unable to read memory for RMW\n"); + err = -1; + goto out; + } + memcpy(tmpbuf + (addr - start_addr), buf, len); + src = tmpbuf; + } else { + src = buf; + } + + if (mem_write(adu_target, start_addr, src, end_addr - start_addr, 0, false)) { + PR_ERROR("Unable to write memory\n"); + err = -1; + } + +out: + if (tmpbuf) + free(tmpbuf); + + return err; +} + +static int read_memory(uint64_t addr, uint64_t len, void *buf, size_t align) +{ + uint64_t start_addr, end_addr; + void *tmpbuf = NULL; + void *dst; + int err = 0; + + start_addr = ALIGN_DOWN(addr, align); + end_addr = ALIGN_UP(addr + len, align); + + if (addr != start_addr || (addr + len) != end_addr) { + tmpbuf = malloc(end_addr - start_addr); + dst = tmpbuf; + } else { + dst = buf; + } + + if (mem_read(adu_target, start_addr, dst, end_addr - start_addr, 0, false)) { + PR_ERROR("Unable to read memory\n"); + err = -1; + goto out; + } + + if (addr != start_addr || (addr + len) != end_addr) + memcpy(buf, tmpbuf + (addr - start_addr), len); + +out: + if (tmpbuf) + free(tmpbuf); + + return err; +} + + static void get_mem(uint64_t *stack, void *priv) { uint64_t addr, len, linear_map; @@ -252,7 +333,7 @@ static void get_mem(uint64_t *stack, void *priv) linear_map = get_real_addr(addr); if (linear_map != -1UL) { - if (mem_read(adu_target, linear_map, (uint8_t *) data, len, 0, false)) { + if (read_memory(linear_map, len, data, 1)) { PR_ERROR("Unable to read memory\n"); err = 1; } @@ -320,7 +401,7 @@ static void put_mem(uint64_t *stack, void *priv) } } - if (mem_write(adu_target, addr, data, len, 0, false)) { + if (write_memory(addr, len, data, 8)) { PR_ERROR("Unable to write memory\n"); err = 3; }