[Pdbg] [PATCH 06/10] sbefifo: Return only the response data from sbefifo_op
Amitay Isaacs
amitay at ozlabs.org
Wed Jul 3 13:46:15 AEST 2019
Instead of returning the entire response buffer, extract the response
data and status.
To differentiate between the chip-op failure and other failures,
return 1 from sbefifo_op() if chip-op completes but does not succeed.
Signed-off-by: Amitay Isaacs <amitay at ozlabs.org>
---
libpdbg/sbefifo.c | 74 ++++++++++++++++++++++++++++-------------------
1 file changed, 45 insertions(+), 29 deletions(-)
diff --git a/libpdbg/sbefifo.c b/libpdbg/sbefifo.c
index 9ca92f7..54dc90d 100644
--- a/libpdbg/sbefifo.c
+++ b/libpdbg/sbefifo.c
@@ -199,8 +199,8 @@ static void sbefifo_ffdc_dump(struct sbefifo *sbefifo)
}
static int sbefifo_op(struct sbefifo *sbefifo,
- uint32_t *msg, size_t msg_len, uint16_t cmd,
- size_t out_len, uint8_t **out)
+ 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];
@@ -214,7 +214,7 @@ static int sbefifo_op(struct sbefifo *sbefifo,
assert(msg_len > 0);
/* Allocate extra memory for FFDC (SBEFIFO_MAX_FFDC_SIZE = 0x2000) */
- buflen = out_len + 0x2000;
+ buflen = 0x2000;
buf = malloc(buflen);
assert(buf);
@@ -231,8 +231,7 @@ static int sbefifo_op(struct sbefifo *sbefifo,
* header word, status word, header offset word
*/
if (buflen < 3 * 4) {
- PR_ERROR("sbefifo: Short read, expected %zu, got %zu\n",
- out_len + 3 * 4, buflen);
+ PR_ERROR("sbefifo: Short read, got %zu\n", buflen);
sbefifo_op_dump("DATA:", buf, buflen);
goto fail;
}
@@ -241,6 +240,7 @@ static int sbefifo_op(struct sbefifo *sbefifo,
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;
@@ -262,14 +262,26 @@ static int sbefifo_op(struct sbefifo *sbefifo,
goto fail;
}
- if (resp[1] == 0) {
- *out = buf;
- return 0;
- } else {
+ *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;
@@ -280,7 +292,7 @@ static int sbefifo_op_istep(struct sbefifo *sbefifo,
{
uint8_t *out;
uint32_t msg[3];
- uint32_t cmd, step;
+ uint32_t cmd, step, out_len, status;
int rc;
PR_NOTICE("sbefifo: istep %u.%u\n", major, minor);
@@ -292,12 +304,10 @@ static int sbefifo_op_istep(struct sbefifo *sbefifo,
msg[1] = htobe32(cmd);
msg[2] = htobe32(step);
- /* Return - data read + length of data read */
- rc = sbefifo_op(sbefifo, msg, sizeof(msg), cmd, 0, &out);
+ rc = sbefifo_op(sbefifo, msg, sizeof(msg), cmd, &out, &out_len, &status);
if (rc)
return rc;
- free(out);
return 0;
}
@@ -307,9 +317,9 @@ static int sbefifo_op_getmem(struct sbefifo *sbefifo,
{
uint8_t *out;
uint64_t start_addr, end_addr;
- uint32_t align, offset, len;
+ uint32_t align, offset, len, out_len, status;
uint32_t msg[6];
- uint32_t cmd, flags, count;
+ uint32_t cmd, flags;
int rc;
align = ci ? 8 : 128;
@@ -338,22 +348,22 @@ static int sbefifo_op_getmem(struct sbefifo *sbefifo,
msg[4] = htobe32(start_addr & 0xffffffff);
msg[5] = htobe32(len);
- /* Return - data read + length of data read */
- rc = sbefifo_op(sbefifo, msg, sizeof(msg), cmd, len+4, &out);
+ rc = sbefifo_op(sbefifo, msg, sizeof(msg), cmd, &out, &out_len, &status);
if (rc)
return rc;
- memcpy(data, out+offset, size);
- count = htobe32(*(uint32_t *)&out[len]);
- free(out);
-
- pdbg_progress_tick(count, len);
+ pdbg_progress_tick(len + 4, out_len);
- if (count != len) {
- PR_ERROR("sbefifo: getmem read %u bytes of %u\n", count, 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;
}
@@ -363,7 +373,7 @@ static int sbefifo_op_putmem(struct sbefifo *sbefifo,
{
uint8_t *out;
uint32_t *msg;
- uint32_t align, len, msg_len;
+ uint32_t align, len, msg_len, out_len, status;
uint32_t cmd, flags, count;
int rc;
@@ -402,16 +412,22 @@ static int sbefifo_op_putmem(struct sbefifo *sbefifo,
msg[5] = htobe32(len);
memcpy(&msg[6], data, len);
- /* Return - length of data written */
- rc = sbefifo_op(sbefifo, msg, msg_len, cmd, 0, &out);
+ rc = sbefifo_op(sbefifo, msg, msg_len, cmd, &out, &out_len, &status);
if (rc)
return rc;
+ pdbg_progress_tick(len + 4, out_len);
+
+ 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);
- pdbg_progress_tick(count, len);
-
if (count != len) {
PR_ERROR("sbefifo: putmem wrote %u bytes of %u\n", count, len);
return -1;
--
2.21.0
More information about the Pdbg
mailing list