From patchwork Tue Mar 29 15:49:11 2022 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Nicholas Piggin X-Patchwork-Id: 1610700 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=VIdZuw/e; 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 4KSYtR5V7Yz9sFk for ; Wed, 30 Mar 2022 02:50:23 +1100 (AEDT) Received: from boromir.ozlabs.org (localhost [IPv6:::1]) by lists.ozlabs.org (Postfix) with ESMTP id 4KSYtR4PrFz2xBK for ; Wed, 30 Mar 2022 02:50:23 +1100 (AEDT) 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=VIdZuw/e; 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::432; helo=mail-pf1-x432.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=VIdZuw/e; dkim-atps=neutral Received: from mail-pf1-x432.google.com (mail-pf1-x432.google.com [IPv6:2607:f8b0:4864:20::432]) (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 4KSYtP2VPHz2yPJ for ; Wed, 30 Mar 2022 02:50:21 +1100 (AEDT) Received: by mail-pf1-x432.google.com with SMTP id b15so16267652pfm.5 for ; Tue, 29 Mar 2022 08:50:21 -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=B+ATvcgUNhjnxkpyeg3VitPSeeh2st6s7fl7rjMIUdQ=; b=VIdZuw/ekDBkCijg8R37M7l2pYebvm/DS5bkDAH3oBUCDdd9lWxVwjBcJi4EXVuFxT XwBCErnZqp87FKghK3Mx8y9wKd6yCE9H1XIvzDH9i45u4WxrpRCHCI9sas/F4vdDDTBH Nb8XL7/x8xusDzFumchUvWMtTGGmAT0fL5bt0QBVFa87GcNnsgxxm9drxi8jsSSSNikc D12UQPh/cHkqaYvRp2/YQhl3g9U0CjGZPgG5qTRm9yBl8+c8P0rcntYQitUFVy3hvBLr BgFM0I+4m3uyhdrPdVPtug3t7TZLoP34J6U8nuvZqmCQWJopyVVvzHuhOB1cmyOnnvia Q4dQ== 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=B+ATvcgUNhjnxkpyeg3VitPSeeh2st6s7fl7rjMIUdQ=; b=WWwo/Y/5PhaDgVKnV9kbCjiBzcGEX/hufenGWAr60k34JcIiDRLUrfiOO0VcmZZ5V8 uzypAPS7N5IbDhHMetnK1ujkdOTP0U48RgWxsffxJHqF6PD81FiX0wePG+12ykT0las3 gYR7rcnp4KZM/IFYoDRrFdd6n88NEGHwAyNMAXIJwjFuVa78HlhnkITnS699dfXMsQ56 9ItDWqN9liVLrUf3Ee5wn4ROfh0GP6mvgLKk6WNYFJ0fjYkjvZX/Zp9WEdogRJEnlAiY 1r/AeJTodVUcVPLzOlbOgxQPRx/RI9k8o5CVqrtlX1gYNLPuFOJZYDXE8lk/loU3C5Re yNjg== X-Gm-Message-State: AOAM530dp/YMeonvTMVO+Y0LJBw4mMySGSPgPhP+Rhb9EmDWBs40RyFf Pefb8KkgA7WvendHgK2dZB56EYl18qU= X-Google-Smtp-Source: ABdhPJzZapc/7LhKgb8+ztQIxC4hBxQIyh0jM91Z0HkSeiLWCec+fRRbWu/T6bJfvX2k3ZHSNIXUsQ== X-Received: by 2002:a63:656:0:b0:385:f723:5245 with SMTP id 83-20020a630656000000b00385f7235245mr2479093pgg.496.1648569018736; Tue, 29 Mar 2022 08:50:18 -0700 (PDT) Received: from bobo.ibm.com (58-6-255-110.tpgi.com.au. [58.6.255.110]) by smtp.gmail.com with ESMTPSA id s35-20020a056a001c6300b004fb20b5d6c1sm14163564pfw.40.2022.03.29.08.50.17 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 29 Mar 2022 08:50:18 -0700 (PDT) From: Nicholas Piggin To: pdbg@lists.ozlabs.org Date: Wed, 30 Mar 2022 01:49:11 +1000 Message-Id: <20220329154931.493851-19-npiggin@gmail.com> X-Mailer: git-send-email 2.23.0 In-Reply-To: <20220329154931.493851-1-npiggin@gmail.com> References: <20220329154931.493851-1-npiggin@gmail.com> MIME-Version: 1.0 Subject: [Pdbg] [PATCH v2 18/38] 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 --- src/pdbgproxy.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 83 insertions(+), 2 deletions(-) diff --git a/src/pdbgproxy.c b/src/pdbgproxy.c index 99238df..c7cab28 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; }