[Pdbg] [PATCH v3 05/13] sbefifo: Drop FFDC parsing code

Amitay Isaacs amitay at ozlabs.org
Mon Jul 15 15:58:43 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