[Pdbg] [PATCH v2 3/4] sbefifo: Switch to using libsbefifo api
Amitay Isaacs
amitay at ozlabs.org
Fri Sep 20 15:16:31 AEST 2019
Signed-off-by: Amitay Isaacs <amitay at ozlabs.org>
---
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 <inttypes.h>
#include <fcntl.h>
+#include <libsbefifo/libsbefifo.h>
+
#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<buflen/4; i++) {
- PR_ERROR(" %s 0x%02x%02x%02x%02x\n", prefix,
- buf[i*4], buf[i*4+1], buf[i*4+2], buf[i*4+3]);
- }
-}
-
-static int sbefifo_op_read(struct sbefifo *sbefifo, void *buf, size_t *buflen)
-{
- ssize_t n;
-
- assert(*buflen > 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);
--
2.21.0
More information about the Pdbg
mailing list