From patchwork Wed Aug 21 06:08:16 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Amitay Isaacs X-Patchwork-Id: 1150582 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) (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 46Cy052Lplz9sML for ; Wed, 21 Aug 2019 16:08:37 +1000 (AEST) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=ozlabs.org Authentication-Results: ozlabs.org; dkim=fail reason="signature verification failed" (2048-bit key; secure) header.d=ozlabs.org header.i=@ozlabs.org header.b="YYvVe/7p"; dkim-atps=neutral Received: from bilbo.ozlabs.org (lists.ozlabs.org [IPv6:2401:3900:2:1::3]) by lists.ozlabs.org (Postfix) with ESMTP id 46Cy044lMwzDqVl for ; Wed, 21 Aug 2019 16:08:36 +1000 (AEST) X-Original-To: pdbg@lists.ozlabs.org Delivered-To: pdbg@lists.ozlabs.org Received: from ozlabs.org (bilbo.ozlabs.org [IPv6:2401:3900:2:1::2]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits)) (No client certificate requested) by lists.ozlabs.org (Postfix) with ESMTPS id 46Cxzq2pFQzDqcP for ; Wed, 21 Aug 2019 16:08:23 +1000 (AEST) Authentication-Results: lists.ozlabs.org; dmarc=pass (p=none dis=none) header.from=ozlabs.org Authentication-Results: lists.ozlabs.org; dkim=pass (2048-bit key; secure) header.d=ozlabs.org header.i=@ozlabs.org header.b="YYvVe/7p"; dkim-atps=neutral Received: from authenticated.ozlabs.org (localhost [127.0.0.1]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mail.ozlabs.org (Postfix) with ESMTPSA id 46Cxzp0Stpz9sN1; Wed, 21 Aug 2019 16:08:22 +1000 (AEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=ozlabs.org; s=201707; t=1566367702; bh=Pa+gX2yhAviBed8ilfdGli7mZczmmihC+hUyZcDxn48=; h=From:To:Cc:Subject:Date:In-Reply-To:References:From; b=YYvVe/7pj+D2iztz2SHKlF8FCL/kkNlz8NePK4WB6KkEOvJGV/3XoIDiSKxD1qeuG PruhJfQ8ijpD81391Gl0+ERmecJpJuJa9dpw8TigqGgMiCyNxFj+yFY6BI3oxWByyX iLhHACpfJkyZnFRpq3DxHs3f6Fftr1vZSp8ZOoFULk2intvqyK6maJ1zfx2HYLdIK0 +Zq+Xto9hibDqqaqLL0ZWTKpKryWzFwineEk2nhj1oZTq9IusnsnvmLHZpfpOWPban jrHep+CpJmgnIWE+qD9ftC/L7Wm6j7BqhEX7PUmrW0SHTf08X90WEUqrUCOCGIOack xyT9zXl4CemQg== From: Amitay Isaacs To: pdbg@lists.ozlabs.org Date: Wed, 21 Aug 2019 16:08:16 +1000 Message-Id: <20190821060817.31012-4-amitay@ozlabs.org> X-Mailer: git-send-email 2.21.0 In-Reply-To: <20190821060817.31012-1-amitay@ozlabs.org> References: <20190821060817.31012-1-amitay@ozlabs.org> MIME-Version: 1.0 Subject: [Pdbg] [PATCH v2 3/4] sbefifo: Switch to using libsbefifo api 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: Amitay Isaacs Errors-To: pdbg-bounces+incoming=patchwork.ozlabs.org@lists.ozlabs.org Sender: "Pdbg" Signed-off-by: Amitay Isaacs --- Makefile.am | 2 +- libpdbg/hwunit.h | 5 +- libpdbg/sbefifo.c | 324 ++++------------------------------------------ 3 files changed, 28 insertions(+), 303 deletions(-) diff --git a/Makefile.am b/Makefile.am index f850a29..f5e7ded 100644 --- a/Makefile.am +++ b/Makefile.am @@ -191,7 +191,7 @@ libpdbg_la_SOURCES = \ libpdbg/xbus.c libpdbg_la_CFLAGS = -Wall -Werror -libpdbg_la_LIBADD = libcronus.la +libpdbg_la_LIBADD = libcronus.la libsbefifo.la if BUILD_LIBFDT libpdbg_la_CFLAGS += -I$(top_srcdir)/libfdt diff --git a/libpdbg/hwunit.h b/libpdbg/hwunit.h index ad3795a..06e5fca 100644 --- a/libpdbg/hwunit.h +++ b/libpdbg/hwunit.h @@ -73,10 +73,7 @@ struct sbefifo { int (*thread_step)(struct sbefifo *, uint32_t core_id, uint32_t thread_id); int (*thread_sreset)(struct sbefifo *, uint32_t core_id, uint32_t thread_id); uint32_t (*ffdc_get)(struct sbefifo *, const uint8_t **, uint32_t *); - int fd; - uint32_t status; - uint8_t *ffdc; - uint32_t ffdc_len; + struct sbefifo_context *sf_ctx; }; #define target_to_sbefifo(x) container_of(x, struct sbefifo, target) diff --git a/libpdbg/sbefifo.c b/libpdbg/sbefifo.c index fb3203f..638e28c 100644 --- a/libpdbg/sbefifo.c +++ b/libpdbg/sbefifo.c @@ -20,239 +20,33 @@ #include #include +#include + #include "hwunit.h" #include "debug.h" -#define SBEFIFO_CMD_CLASS_CONTROL 0xA100 -#define SBEFIFO_CMD_EXECUTE_ISTEP 0x0001 - -#define SBEFIFO_CMD_CLASS_MEMORY 0xA400 -#define SBEFIFO_CMD_GET_MEMORY 0x0001 -#define SBEFIFO_CMD_PUT_MEMORY 0x0002 - -#define SBEFIFO_CMD_CLASS_INSTRUCTION 0xA700 -#define SBEFIFO_CMD_CONTROL_INSN 0x0001 - -#define SBEFIFO_MEMORY_FLAG_PROC 0x0001 -#define SBEFIFO_MEMORY_FLAG_PBA 0x0002 -#define SBEFIFO_MEMORY_FLAG_AUTO_INCR 0x0004 -#define SBEFIFO_MEMORY_FLAG_ECC_REQ 0x0008 -#define SBEFIFO_MEMORY_FLAG_TAG_REQ 0x0010 -#define SBEFIFO_MEMORY_FLAG_FAST_MODE 0x0020 -#define SBEFIFO_MEMORY_FLAG_LCO_MODE 0x0040 // only for putmem -#define SBEFIFO_MEMORY_FLAG_CI 0x0080 -#define SBEFIFO_MEMORY_FLAG_PASSTHRU 0x0100 -#define SBEFIFO_MEMORY_FLAG_CACHEINJECT 0x0200 // only for putmem - -#define SBEFIFO_INSN_OP_START 0x0 -#define SBEFIFO_INSN_OP_STOP 0x1 -#define SBEFIFO_INSN_OP_STEP 0x2 -#define SBEFIFO_INSN_OP_SRESET 0x3 - -static void sbefifo_op_dump(const char *prefix, uint8_t *buf, size_t buflen) -{ - int i; - - if (!prefix) - prefix = ""; - - for (i=0; i 0); - - n = read(sbefifo->fd, buf, *buflen); - if (n < 0) { - PR_ERROR("sbefifo: Failed to read, errno=%d\n", errno); - return -1; - } - *buflen = n; - - return 0; -} - -static int sbefifo_op_write(struct sbefifo *sbefifo, void *buf, size_t buflen) -{ - ssize_t n; - - n = write(sbefifo->fd, buf, buflen); - if (n < 0) { - PR_ERROR("sbefifo: Failed to write, errno=%d\n", errno); - return -1; - } - if (n != buflen) { - PR_ERROR("sbefifo: Short write %zi of %zi bytes\n", n, buflen); - return -1; - } - - return 0; -} - -static void sbefifo_ffdc_clear(struct sbefifo *sbefifo) +static uint32_t sbefifo_op_ffdc_get(struct sbefifo *sbefifo, const uint8_t **ffdc, uint32_t *ffdc_len) { - sbefifo->status = 0; - if (sbefifo->ffdc) { - free(sbefifo->ffdc); - sbefifo->ffdc = NULL; - sbefifo->ffdc_len = 0; - } -} - -static void sbefifo_ffdc_set(struct sbefifo *sbefifo, uint8_t *buf, uint32_t buflen, uint32_t status) -{ - sbefifo->status = status; - - sbefifo->ffdc = malloc(buflen); - if (!sbefifo->ffdc) { - PR_ERROR("sbefifo: Failed to store FFDC data\n"); - return; - } - - memcpy(sbefifo->ffdc, buf, buflen); - sbefifo->ffdc_len = buflen; -} - -static uint32_t sbefifo_ffdc_get(struct sbefifo *sbefifo, const uint8_t **ffdc, uint32_t *ffdc_len) -{ - *ffdc = sbefifo->ffdc; - *ffdc_len = sbefifo->ffdc_len; - - return sbefifo->status; -} - -static int sbefifo_op(struct sbefifo *sbefifo, - uint32_t *msg, uint32_t msg_len, uint16_t cmd, - uint8_t **out, uint32_t *out_len, uint32_t *status) -{ - uint8_t *buf; - uint32_t resp[2]; - size_t buflen; - uint32_t word_offset, offset; - uint16_t value; - int rc; - - sbefifo_ffdc_clear(sbefifo); - - assert(msg_len > 0); - - /* - * Allocate extra memory for FFDC (SBEFIFO_MAX_FFDC_SIZE = 0x2000) - * Use *out_len as a hint to expected reply length - */ - buflen = (*out_len + 0x2000 + 3) & (uint32_t)~3; - buf = malloc(buflen); - assert(buf); - - rc = sbefifo_op_write(sbefifo, msg, msg_len); - if (rc) - goto fail; - - rc = sbefifo_op_read(sbefifo, buf, &buflen); - if (rc) - goto fail; - - /* - * At least 3 words are expected in the response - * header word, status word, header offset word - */ - if (buflen < 3 * 4) { - PR_ERROR("sbefifo: Short read, got %zu\n", buflen); - sbefifo_op_dump("DATA:", buf, buflen); - goto fail; - } - - word_offset = be32toh(*(uint32_t *)(buf + buflen - 4)); - PR_INFO("sbefifo: status header word offset = %u\n", word_offset); - - offset = buflen - (word_offset * 4); - *out_len = offset; - - resp[0] = be32toh(*(uint32_t *)(buf + offset)); - offset += 4; - - resp[1] = be32toh(*(uint32_t *)(buf + offset)); - offset += 4; - - PR_INFO("sbefifo: response %08x %08x\n", resp[0], resp[1]); - - value = resp[0] >> 16; - if (value != 0xc0de) { - PR_ERROR("sbefifo: Expected magic 0xc0de, got 0x%04x\n", value); - goto fail; - } - - value = resp[0] & 0xffff; - if (value != cmd) { - PR_ERROR("sbefifo: Expected command 0x%04x, got 0x%04x\n", cmd, value); - goto fail; - } - - *status = resp[1]; - if (resp[1] != 0) { - PR_ERROR("sbefifo: Operation failed, response=0x%08x\n", resp[1]); - sbefifo_ffdc_set(sbefifo, buf + offset, buflen - offset - 4, resp[1]); - free(buf); - return 1; - } - - if (*out_len > 0) { - *out = malloc(*out_len); - assert(*out); - - memcpy(*out, buf, *out_len); - } else { - *out = NULL; - } - - free(buf); - return 0; - -fail: - free(buf); - return -1; + return sbefifo_ffdc_get(sbefifo->sf_ctx, ffdc, ffdc_len); } static int sbefifo_op_istep(struct sbefifo *sbefifo, uint32_t major, uint32_t minor) { - uint8_t *out; - uint32_t msg[3]; - uint32_t cmd, step, out_len, status; - int rc; - PR_NOTICE("sbefifo: istep %u.%u\n", major, minor); - cmd = SBEFIFO_CMD_CLASS_CONTROL | SBEFIFO_CMD_EXECUTE_ISTEP; - step = (major & 0xff) << 16 | (minor & 0xff); - - msg[0] = htobe32(3); // number of words - msg[1] = htobe32(cmd); - msg[2] = htobe32(step); - - out_len = 0; - rc = sbefifo_op(sbefifo, msg, sizeof(msg), cmd, &out, &out_len, &status); - if (rc) - return rc; - - return 0; + return sbefifo_istep_execute(sbefifo->sf_ctx, major & 0xff, minor & 0xff); } -static int sbefifo_op_getmem(struct mem *sbefifo, +static int sbefifo_op_getmem(struct mem *sbefifo_mem, uint64_t addr, uint8_t *data, uint64_t size, uint8_t block_size, bool ci) { + struct sbefifo *sbefifo = target_to_sbefifo(sbefifo_mem->target.parent); uint8_t *out; uint64_t start_addr, end_addr; - uint32_t align, offset, len, out_len, status; - uint32_t msg[6]; - uint32_t cmd, flags; + uint32_t align, offset, len; + uint16_t flags; int rc; align = ci ? 8 : 128; @@ -276,48 +70,31 @@ static int sbefifo_op_getmem(struct mem *sbefifo, PR_NOTICE("sbefifo: getmem addr=0x%016" PRIx64 ", len=%u\n", start_addr, len); - cmd = SBEFIFO_CMD_CLASS_MEMORY | SBEFIFO_CMD_GET_MEMORY; if (ci) flags = SBEFIFO_MEMORY_FLAG_PROC | SBEFIFO_MEMORY_FLAG_CI; else flags = SBEFIFO_MEMORY_FLAG_PBA; - msg[0] = htobe32(6); // number of words - msg[1] = htobe32(cmd); - msg[2] = htobe32(flags); - msg[3] = htobe32(start_addr >> 32); - msg[4] = htobe32(start_addr & 0xffffffff); - msg[5] = htobe32(len); + rc = sbefifo_mem_get(sbefifo->sf_ctx, start_addr, len, flags, &out); + + pdbg_progress_tick(len, len); - out_len = len + 4; - rc = sbefifo_op(target_to_sbefifo(sbefifo->target.parent), msg, sizeof(msg), cmd, - &out, &out_len, &status); if (rc) return rc; - pdbg_progress_tick(len + 4, out_len); - - if (out_len != size + 4) { - PR_ERROR("sbefifo: getmem error got %u, expected %"PRIu64"\n", out_len, size + 4); - if (out_len > 0) - free(out); - return -1; - } - memcpy(data, out+offset, size); free(out); return 0; } -static int sbefifo_op_putmem(struct mem *sbefifo, +static int sbefifo_op_putmem(struct mem *sbefifo_mem, uint64_t addr, uint8_t *data, uint64_t size, uint8_t block_size, bool ci) { - uint8_t *out; - uint32_t *msg; - uint32_t align, len, msg_len, out_len, status; - uint32_t cmd, flags, count; + struct sbefifo *sbefifo = target_to_sbefifo(sbefifo_mem->target.parent); + uint32_t align, len; + uint16_t flags; int rc; align = ci ? 8 : 128; @@ -343,60 +120,26 @@ static int sbefifo_op_putmem(struct mem *sbefifo, } len = size & 0xffffffff; - msg_len = 6 * 4 + len; - msg = (uint32_t *)malloc(msg_len); - assert(msg); PR_NOTICE("sbefifo: putmem addr=0x%016"PRIx64", len=%u\n", addr, len); - cmd = SBEFIFO_CMD_CLASS_MEMORY | SBEFIFO_CMD_PUT_MEMORY; if (ci) flags = SBEFIFO_MEMORY_FLAG_PROC | SBEFIFO_MEMORY_FLAG_CI; else flags = SBEFIFO_MEMORY_FLAG_PBA; - msg[0] = htobe32(msg_len/4); // number of words - msg[1] = htobe32(cmd); - msg[2] = htobe32(flags); - msg[3] = htobe32(addr >> 32); - msg[4] = htobe32(addr & 0xffffffff); - msg[5] = htobe32(len); - memcpy(&msg[6], data, len); - - out_len = 4; - rc = sbefifo_op(target_to_sbefifo(sbefifo->target.parent), msg, msg_len, cmd, - &out, &out_len, &status); - if (rc) - return rc; - - pdbg_progress_tick(4, out_len); + rc = sbefifo_mem_put(sbefifo->sf_ctx, addr, data, len, flags); - if (out_len != 4) { - PR_ERROR("sbefifo: putmem error got %u, expected 4\n", out_len); - if (out_len > 0) - free(out); - return -1; - } - - count = be32toh(*(uint32_t *)out); - free(out); - - if (count != len) { - PR_ERROR("sbefifo: putmem wrote %u bytes of %u\n", count, len); - return -1; - } + pdbg_progress_tick(len, len); - return 0; + return rc; } static int sbefifo_op_control(struct sbefifo *sbefifo, uint32_t core_id, uint32_t thread_id, uint32_t oper) { - uint8_t *out; - uint32_t msg[3]; - uint32_t cmd, op, out_len, status, mode = 0; - int rc; + uint8_t mode = 0; /* Enforce special-wakeup for thread stop and sreset */ if ((oper & 0xf) == SBEFIFO_INSN_OP_STOP || @@ -405,22 +148,7 @@ static int sbefifo_op_control(struct sbefifo *sbefifo, PR_NOTICE("sbefifo: control c:0x%x, t:0x%x, op:%u mode:%u\n", core_id, thread_id, oper, mode); - op = (mode << 16) | ((core_id & 0xff) << 8) | ((thread_id & 0x0f) << 4) | (oper & 0x0f); - cmd = SBEFIFO_CMD_CLASS_INSTRUCTION | SBEFIFO_CMD_CONTROL_INSN; - - msg[0] = htobe32(3); // number of words - msg[1] = htobe32(cmd); - msg[2] = htobe32(op); - - out_len = 0; - rc = sbefifo_op(sbefifo, msg, sizeof(msg), cmd, &out, &out_len, &status); - if (rc) - return rc; - - if (out_len > 0) - free(out); - - return 0; + return sbefifo_control_insn(sbefifo->sf_ctx, core_id & 0xff, thread_id & 0xff, oper & 0xff, mode); } static int sbefifo_op_thread_start(struct sbefifo *sbefifo, @@ -451,14 +179,15 @@ static int sbefifo_probe(struct pdbg_target *target) { struct sbefifo *sf = target_to_sbefifo(target); const char *sbefifo_path; + int rc; sbefifo_path = pdbg_target_property(target, "device-path", NULL); assert(sbefifo_path); - sf->fd = open(sbefifo_path, O_RDWR | O_SYNC); - if (sf->fd < 0) { + rc = sbefifo_connect(sbefifo_path, &sf->sf_ctx); + if (rc) { PR_ERROR("Unable to open sbefifo driver %s\n", sbefifo_path); - return -1; + return rc; } return 0; @@ -487,8 +216,7 @@ struct sbefifo kernel_sbefifo = { .thread_stop = sbefifo_op_thread_stop, .thread_step = sbefifo_op_thread_step, .thread_sreset = sbefifo_op_thread_sreset, - .ffdc_get = sbefifo_ffdc_get, - .fd = -1, + .ffdc_get = sbefifo_op_ffdc_get, }; DECLARE_HW_UNIT(kernel_sbefifo);