[Pdbg] [PATCH 14/17] libpdbg: Expand sbefifo data marshalling and calling chip-op
Amitay Isaacs
amitay at ozlabs.org
Thu Oct 31 17:34:25 AEDT 2019
This will allow to separate sbefifo transport layer to use something other
than sbefifo kernel device driver.
Signed-off-by: Amitay Isaacs <amitay at ozlabs.org>
---
libpdbg/sbefifo.c | 132 ++++++++++++++++++++++++++++------------------
1 file changed, 80 insertions(+), 52 deletions(-)
diff --git a/libpdbg/sbefifo.c b/libpdbg/sbefifo.c
index 030e6e9..9e3532b 100644
--- a/libpdbg/sbefifo.c
+++ b/libpdbg/sbefifo.c
@@ -30,12 +30,29 @@ static uint32_t sbefifo_op_ffdc_get(struct sbefifo *sbefifo, const uint8_t **ffd
return sbefifo_ffdc_get(sbefifo->sf_ctx, ffdc, ffdc_len);
}
-static int sbefifo_op_istep(struct sbefifo *sbefifo,
- uint32_t major, uint32_t minor)
+static int sbefifo_op_istep(struct sbefifo *sbefifo, uint32_t major, uint32_t minor)
{
+ uint8_t *msg, *out;
+ uint32_t msg_len, out_len;
+ int rc;
+
PR_NOTICE("sbefifo: istep %u.%u\n", major, minor);
- return sbefifo_istep_execute(sbefifo->sf_ctx, major & 0xff, minor & 0xff);
+ rc = sbefifo_istep_execute_push(major & 0xff, minor & 0xff, &msg, &msg_len);
+ if (rc)
+ return rc;
+
+ out_len = 0;
+ rc = sbefifo_operation(sbefifo->sf_ctx, msg, msg_len, &out, &out_len);
+ free(msg);
+ if (rc)
+ return rc;
+
+ rc = sbefifo_istep_execute_pull(out, out_len);
+ if (out)
+ free(out);
+
+ return rc;
}
static int sbefifo_op_getmem(struct mem *sbefifo_mem,
@@ -43,48 +60,45 @@ static int sbefifo_op_getmem(struct mem *sbefifo_mem,
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;
+ uint8_t *msg, *out;
+ uint32_t msg_len, out_len, len;
uint16_t flags;
int rc;
- align = 8;
-
- if (block_size && block_size != 8) {
- PR_ERROR("sbefifo: Only 8 byte block sizes are supported\n");
- return -1;
- };
-
- start_addr = addr & (~(uint64_t)(align-1));
- end_addr = (addr + size + (align-1)) & (~(uint64_t)(align-1));
-
- if (end_addr - start_addr > UINT32_MAX) {
- PR_ERROR("sbefifo: size too large\n");
- return -EINVAL;
+ if (size > UINT32_MAX) {
+ PR_ERROR("sbefifo: Invalid size for getmem\n");
+ return EINVAL;
}
- offset = addr - start_addr;
- len = end_addr - start_addr;
+ len = size & 0xffffffff;
- PR_NOTICE("sbefifo: getmem addr=0x%016" PRIx64 ", len=%u\n",
- start_addr, len);
+ PR_NOTICE("sbefifo: getmem addr=0x%016" PRIx64 ", len=%u\n", addr, len);
flags = SBEFIFO_MEMORY_FLAG_PROC;
if (ci)
flags |= SBEFIFO_MEMORY_FLAG_CI;
- rc = sbefifo_mem_get(sbefifo->sf_ctx, start_addr, len, flags, &out);
-
- pdbg_progress_tick(len, len);
+ rc = sbefifo_mem_get_push(addr, len, flags, &msg, &msg_len);
+ if (rc)
+ return rc;
+ out_len = len + 4;
+ rc = sbefifo_operation(sbefifo->sf_ctx, msg, msg_len, &out, &out_len);
+ free(msg);
if (rc)
return rc;
- memcpy(data, out+offset, size);
- free(out);
+ rc = sbefifo_mem_get_pull(out, out_len, addr, size, flags, &msg);
+ if (out)
+ free(out);
- return 0;
+ if (!rc) {
+ memcpy(data, msg, len);
+ free(msg);
+ pdbg_progress_tick(len, len);
+ }
+
+ return rc;
}
static int sbefifo_op_putmem(struct mem *sbefifo_mem,
@@ -92,30 +106,14 @@ static int sbefifo_op_putmem(struct mem *sbefifo_mem,
uint8_t block_size, bool ci)
{
struct sbefifo *sbefifo = target_to_sbefifo(sbefifo_mem->target.parent);
- uint32_t align, len;
+ uint8_t *msg, *out;
+ uint32_t msg_len, out_len, len;
uint16_t flags;
int rc;
- align = 8;
-
- if (block_size && block_size != 8) {
- PR_ERROR("sbefifo: Only 8 byte block sizes are supported\n");
- return -1;
- };
-
- if (addr & (align-1)) {
- PR_ERROR("sbefifo: Address must be aligned to %d bytes\n", align);
- return -1;
- }
-
- if (size & (align-1)) {
- PR_ERROR("sbefifo: Data must be multiple of %d bytes\n", align);
- return -1;
- }
-
if (size > UINT32_MAX) {
- PR_ERROR("sbefifo: size too large\n");
- return -1;
+ PR_ERROR("sbefifo: Invalid size for putmem\n");
+ return EINVAL;
}
len = size & 0xffffffff;
@@ -126,9 +124,22 @@ static int sbefifo_op_putmem(struct mem *sbefifo_mem,
if (ci)
flags |= SBEFIFO_MEMORY_FLAG_CI;
- rc = sbefifo_mem_put(sbefifo->sf_ctx, addr, data, len, flags);
+ rc = sbefifo_mem_put_push(addr, data, len, flags, &msg, &msg_len);
+ if (rc)
+ return rc;
+
+ out_len = 4;
+ rc = sbefifo_operation(sbefifo->sf_ctx, msg, msg_len, &out, &out_len);
+ free(msg);
+ if (rc)
+ return rc;
- pdbg_progress_tick(len, len);
+ rc = sbefifo_mem_put_pull(out, out_len);
+ if (out)
+ free(out);
+
+ if (!rc)
+ pdbg_progress_tick(len, len);
return rc;
}
@@ -137,6 +148,9 @@ static int sbefifo_op_control(struct sbefifo *sbefifo,
uint32_t core_id, uint32_t thread_id,
uint32_t oper)
{
+ uint8_t *msg, *out;
+ uint32_t msg_len, out_len;
+ int rc;
uint8_t mode = 0;
/* Enforce special-wakeup for thread stop and sreset */
@@ -146,7 +160,21 @@ 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);
- return sbefifo_control_insn(sbefifo->sf_ctx, core_id & 0xff, thread_id & 0xff, oper & 0xff, mode);
+ rc = sbefifo_control_insn_push(core_id & 0xff, thread_id & 0xff, oper & 0xff, mode, &msg, &msg_len);
+ if (rc)
+ return rc;
+
+ out_len = 0;
+ rc = sbefifo_operation(sbefifo->sf_ctx, msg, msg_len, &out, &out_len);
+ free(msg);
+ if (rc)
+ return rc;
+
+ rc = sbefifo_control_insn_pull(out, out_len);
+ if (out)
+ free(out);
+
+ return rc;
}
static int sbefifo_op_thread_start(struct sbefifo *sbefifo,
--
2.21.0
More information about the Pdbg
mailing list