[Pdbg] [PATCH v4 05/13] sbefifo: Drop FFDC parsing code
Amitay Isaacs
amitay at ozlabs.org
Wed Jul 17 14:08:44 AEST 2019
Instead of dumping ffdc data, store it so an application can query it in
case of chip-op failures.
FFDC data is stored only for the last chip-op.
Signed-off-by: Amitay Isaacs <amitay at ozlabs.org>
---
libpdbg/hwunit.h | 3 ++
libpdbg/sbefifo.c | 72 +++++++++++------------------------------------
2 files changed, 20 insertions(+), 55 deletions(-)
diff --git a/libpdbg/hwunit.h b/libpdbg/hwunit.h
index b816ae3..0b0c62b 100644
--- a/libpdbg/hwunit.h
+++ b/libpdbg/hwunit.h
@@ -71,6 +71,9 @@ struct sbefifo {
int (*mem_read)(struct sbefifo *, uint64_t, uint8_t *, uint64_t, bool);
int (*mem_write)(struct sbefifo *, uint64_t, uint8_t *, uint64_t, bool);
int fd;
+ uint32_t status;
+ uint8_t *ffdc;
+ uint32_t ffdc_len;
};
#define target_to_sbefifo(x) container_of(x, struct sbefifo, target)
diff --git a/libpdbg/sbefifo.c b/libpdbg/sbefifo.c
index 80a4e67..35c4e54 100644
--- a/libpdbg/sbefifo.c
+++ b/libpdbg/sbefifo.c
@@ -87,68 +87,28 @@ static int sbefifo_op_write(struct sbefifo *sbefifo, void *buf, size_t buflen)
return 0;
}
-static int sbefifo_op_ffdc_read(uint8_t *buf, uint32_t buflen)
+static void sbefifo_ffdc_clear(struct sbefifo *sbefifo)
{
- int offset = 0;
- uint32_t header, value;
- uint16_t magic, len_words;
- int i;
-
- if (buflen < 4)
- return -1;
-
- /* End of ffdc data */
- if (buflen == 4)
- return 0;
-
- header = be32toh(*(uint32_t *)(buf + offset));
- offset += 4;
-
- magic = header >> 16;
- if (magic != 0xffdc) {
- PR_ERROR("sbefifo: ffdc expected 0xffdc, got 0x%04x\n", magic);
- return -1;
- }
-
- len_words = header & 0xffff;
- if (offset + len_words * 4 > buflen)
- return -1;
-
- value = be32toh(*(uint32_t *)(buf + offset));
- offset += 4;
-
- PR_ERROR("FFDC: Sequence = %u\n", value >> 16);
- PR_ERROR("FFDC: Command = 0x%08x\n", value & 0xffff);
-
- value = be32toh(*(uint32_t *)(buf + offset));
- offset += 4;
-
- PR_ERROR("FFDC: RC = 0x%08x\n", value);
-
- for (i=0; i<len_words-3; i++) {
- value = be32toh(*(uint32_t *)(buf + offset));
- offset += 4;
-
- PR_ERROR("FFDC: Data: 0x%08x\n", value);
+ sbefifo->status = 0;
+ if (sbefifo->ffdc) {
+ free(sbefifo->ffdc);
+ sbefifo->ffdc = NULL;
+ sbefifo->ffdc_len = 0;
}
-
- return offset;
}
-static int sbefifo_op_ffdc(uint8_t *buf, uint32_t buflen)
+static void sbefifo_ffdc_set(struct sbefifo *sbefifo, uint8_t *buf, uint32_t buflen, uint32_t status)
{
- uint32_t offset = 0;
- int rc;
-
- while (1) {
- rc = sbefifo_op_ffdc_read(buf + offset, buflen - offset);
- if (rc <= 0)
- break;
+ sbefifo->status = status;
- offset += rc;
+ sbefifo->ffdc = malloc(buflen);
+ if (!sbefifo->ffdc) {
+ PR_ERROR("sbefifo: Failed to store FFDC data\n");
+ return;
}
- return rc;
+ memcpy(sbefifo->ffdc, buf, buflen);
+ sbefifo->ffdc_len = buflen;
}
static int sbefifo_op(struct sbefifo *sbefifo,
@@ -162,6 +122,8 @@ static int sbefifo_op(struct sbefifo *sbefifo,
uint16_t value;
int rc;
+ sbefifo_ffdc_clear(sbefifo);
+
assert(msg_len > 0);
/* Allocate extra memory for FFDC (SBEFIFO_MAX_FFDC_SIZE = 0x2000) */
@@ -218,7 +180,7 @@ static int sbefifo_op(struct sbefifo *sbefifo,
return 0;
} else {
PR_ERROR("sbefifo: Operation failed, response=0x%08x\n", resp[1]);
- sbefifo_op_ffdc(buf + offset, buflen - offset);
+ sbefifo_ffdc_set(sbefifo, buf + offset, buflen - offset - 4, resp[1]);
}
fail:
--
2.21.0
More information about the Pdbg
mailing list