[Pdbg] [PATCH 2/3] libpdg: Add option to write to / read from cache inhibited memory

Rashmica Gupta rashmica.g at gmail.com
Tue May 15 13:43:17 AEST 2018


Using P9_TTYPE_CI_PARTIAL_WRITE instead of P9_TTYPE_CI_PARTIAL_OOO_WRITE
because that is what cronus does.

Signed-off-by: Rashmica Gupta <rashmica.g at gmail.com>
---
 libpdbg/adu.c        | 45 ++++++++++++++++++++++++++++++++-------------
 libpdbg/libpdbg.h    |  4 ++--
 libpdbg/operations.h |  4 ++--
 libpdbg/target.h     |  4 ++--
 src/mem.c            | 29 ++++++++++++++++++-----------
 5 files changed, 56 insertions(+), 30 deletions(-)

diff --git a/libpdbg/adu.c b/libpdbg/adu.c
index 2a0b8d5..b03e4c5 100644
--- a/libpdbg/adu.c
+++ b/libpdbg/adu.c
@@ -46,6 +46,10 @@
 #define P9_TTYPE_TREAD 	       		PPC_BIT(5)
 #define P9_TTYPE_TWRITE 		0
 #define P9_FBC_ALTD_TTYPE		PPC_BITMASK(25, 31)
+
+#define P9_TTYPE_CI_PARTIAL_WRITE	0b110111
+#define P9_TTYPE_CI_PARTIAL_OOO_WRITE	0b110110
+#define P9_TTYPE_CI_PARTIAL_READ 	0b110100
 #define P9_TTYPE_DMA_PARTIAL_READ	0b000110
 #define P9_TTYPE_DMA_PARTIAL_WRITE	0b100110
 #define P9_FBC_ALTD_TSIZE		PPC_BITMASK(32, 39)
@@ -79,7 +83,7 @@
 #define FBC_ALTD_DATA_DONE	PPC_BIT(3)
 #define FBC_ALTD_PBINIT_MISSING PPC_BIT(18)
 
-int adu_getmem(struct pdbg_target *adu_target, uint64_t start_addr, uint8_t *output, uint64_t size)
+int adu_getmem(struct pdbg_target *adu_target, uint64_t start_addr, uint8_t *output, uint64_t size, int ci)
 {
 	struct adu *adu;
 	int rc = 0;
@@ -92,7 +96,7 @@ int adu_getmem(struct pdbg_target *adu_target, uint64_t start_addr, uint8_t *out
 	for (addr = 8*(start_addr / 8); addr < start_addr + size; addr += 8) {
 		uint64_t data;
 
-		if (adu->getmem(adu, addr, &data))
+		if (adu->getmem(adu, addr, &data, ci))
 			return -1;
 
 		/* ADU returns data in big-endian form in the register */
@@ -112,7 +116,7 @@ int adu_getmem(struct pdbg_target *adu_target, uint64_t start_addr, uint8_t *out
 	return rc;
 }
 
-int adu_putmem(struct pdbg_target *adu_target, uint64_t start_addr, uint8_t *input, uint64_t size)
+int adu_putmem(struct pdbg_target *adu_target, uint64_t start_addr, uint8_t *input, uint64_t size, int ci)
 {
 	struct adu *adu;
 	int rc = 0, tsize;
@@ -135,7 +139,7 @@ int adu_putmem(struct pdbg_target *adu_target, uint64_t start_addr, uint8_t *inp
 			data = __builtin_bswap64(data);
 		}
 
-		adu->putmem(adu, addr, data, tsize);
+		adu->putmem(adu, addr, data, tsize, ci);
 	}
 
 	return rc;
@@ -184,14 +188,18 @@ static int adu_reset(struct adu *adu)
 	return 0;
 }
 
-static int p8_adu_getmem(struct adu *adu, uint64_t addr, uint64_t *data)
+static int p8_adu_getmem(struct adu *adu, uint64_t addr, uint64_t *data, int ci)
 {
 	uint64_t ctrl_reg, cmd_reg, val;
 
 	CHECK_ERR(adu_lock(adu));
 
 	ctrl_reg = P8_TTYPE_TREAD;
-	ctrl_reg = SETFIELD(P8_FBC_ALTD_TTYPE, ctrl_reg, P8_TTYPE_DMA_PARTIAL_READ);
+	if (ci)
+		/* Do cache inhibited access */
+		ctrl_reg = SETFIELD(P8_FBC_ALTD_TTYPE, ctrl_reg, P8_TTYPE_CI_PARTIAL_READ);
+	else
+		ctrl_reg = SETFIELD(P8_FBC_ALTD_TTYPE, ctrl_reg, P8_TTYPE_DMA_PARTIAL_READ);
 	ctrl_reg = SETFIELD(P8_FBC_ALTD_TSIZE, ctrl_reg, 8);
 
 	CHECK_ERR(pib_read(&adu->target, P8_ALTD_CMD_REG, &cmd_reg));
@@ -235,15 +243,18 @@ retry:
 	return 0;
 }
 
-int p8_adu_putmem(struct adu *adu, uint64_t addr, uint64_t data, int size)
+int p8_adu_putmem(struct adu *adu, uint64_t addr, uint64_t data, int size, int ci)
 {
 	int rc = 0;
 	uint64_t cmd_reg, ctrl_reg, val;
-
 	CHECK_ERR(adu_lock(adu));
 
 	ctrl_reg = P8_TTYPE_TWRITE;
-	ctrl_reg = SETFIELD(P8_FBC_ALTD_TTYPE, ctrl_reg, P8_TTYPE_DMA_PARTIAL_WRITE);
+	if (ci)
+		/* Do cache inhibited access */
+		ctrl_reg = SETFIELD(P8_FBC_ALTD_TTYPE, ctrl_reg, P8_TTYPE_CI_PARTIAL_WRITE);
+	else
+		ctrl_reg = SETFIELD(P8_FBC_ALTD_TTYPE, ctrl_reg, P8_TTYPE_DMA_PARTIAL_WRITE);
 	ctrl_reg = SETFIELD(P8_FBC_ALTD_TSIZE, ctrl_reg, size);
 
 	CHECK_ERR(pib_read(&adu->target, P8_ALTD_CMD_REG, &cmd_reg));
@@ -288,12 +299,16 @@ retry:
 	return rc;
 }
 
-static int p9_adu_getmem(struct adu *adu, uint64_t addr, uint64_t *data)
+static int p9_adu_getmem(struct adu *adu, uint64_t addr, uint64_t *data, int ci)
 {
 	uint64_t ctrl_reg, cmd_reg, val;
 
 	cmd_reg = P9_TTYPE_TREAD;
-	cmd_reg = SETFIELD(P9_FBC_ALTD_TTYPE, cmd_reg, P9_TTYPE_DMA_PARTIAL_READ);
+	if (ci)
+		/* Do cache inhibited access */
+		cmd_reg = SETFIELD(P9_FBC_ALTD_TTYPE, cmd_reg, P9_TTYPE_CI_PARTIAL_READ);
+	else
+		cmd_reg = SETFIELD(P9_FBC_ALTD_TTYPE, cmd_reg, P9_TTYPE_DMA_PARTIAL_READ);
 
 	/* For a read size is apparently always 0 */
 	cmd_reg = SETFIELD(P9_FBC_ALTD_TSIZE, cmd_reg, 0);
@@ -335,7 +350,7 @@ retry:
 	return 0;
 }
 
-static int p9_adu_putmem(struct adu *adu, uint64_t addr, uint64_t data, int size)
+static int p9_adu_putmem(struct adu *adu, uint64_t addr, uint64_t data, int size, int ci)
 {
 	uint64_t ctrl_reg, cmd_reg, val;
 
@@ -344,7 +359,11 @@ static int p9_adu_putmem(struct adu *adu, uint64_t addr, uint64_t data, int size
 	size <<= 1;
 
 	cmd_reg = P9_TTYPE_TWRITE;
-	cmd_reg = SETFIELD(P9_FBC_ALTD_TTYPE, cmd_reg, P9_TTYPE_DMA_PARTIAL_WRITE);
+	if (ci)
+		/* Do cache inhibited access */
+		cmd_reg = SETFIELD(P9_FBC_ALTD_TTYPE, cmd_reg, P9_TTYPE_CI_PARTIAL_WRITE);
+	else
+		cmd_reg = SETFIELD(P9_FBC_ALTD_TTYPE, cmd_reg, P9_TTYPE_DMA_PARTIAL_WRITE);
 	cmd_reg = SETFIELD(P9_FBC_ALTD_TSIZE, cmd_reg, size);
  	cmd_reg |= FBC_ALTD_START_OP;
 	cmd_reg = SETFIELD(FBC_ALTD_SCOPE, cmd_reg, SCOPE_REMOTE);
diff --git a/libpdbg/libpdbg.h b/libpdbg/libpdbg.h
index f2b5de7..8601361 100644
--- a/libpdbg/libpdbg.h
+++ b/libpdbg/libpdbg.h
@@ -120,8 +120,8 @@ int htm_status(struct pdbg_target *target);
 int htm_reset(struct pdbg_target *target, uint64_t *base, uint64_t *size);
 int htm_dump(struct pdbg_target *target, uint64_t size, const char *filename);
 
-int adu_getmem(struct pdbg_target *target, uint64_t addr, uint8_t *ouput, uint64_t size);
-int adu_putmem(struct pdbg_target *target, uint64_t addr, uint8_t *input, uint64_t size);
+int adu_getmem(struct pdbg_target *target, uint64_t addr, uint8_t *ouput, uint64_t size, int ci);
+int adu_putmem(struct pdbg_target *target, uint64_t addr, uint8_t *input, uint64_t size, int ci);
 
 int opb_read(struct pdbg_target *target, uint32_t addr, uint32_t *data);
 int opb_write(struct pdbg_target *target, uint32_t addr, uint32_t data);
diff --git a/libpdbg/operations.h b/libpdbg/operations.h
index d6c947f..7ee4cb2 100644
--- a/libpdbg/operations.h
+++ b/libpdbg/operations.h
@@ -32,8 +32,8 @@
 #define FSI2PIB_BASE	0x1000
 
 /* Alter display unit functions */
-int adu_getmem(struct pdbg_target *target, uint64_t addr, uint8_t *output, uint64_t size);
-int adu_putmem(struct pdbg_target *target, uint64_t start_addr, uint8_t *input, uint64_t size);
+int adu_getmem(struct pdbg_target *target, uint64_t addr, uint8_t *output, uint64_t size, int ci);
+int adu_putmem(struct pdbg_target *target, uint64_t start_addr, uint8_t *input, uint64_t size, int ci);
 
 /* Functions to ram instructions */
 #define THREAD_STATUS_DISABLED  PPC_BIT(0)
diff --git a/libpdbg/target.h b/libpdbg/target.h
index eba26cb..d60c586 100644
--- a/libpdbg/target.h
+++ b/libpdbg/target.h
@@ -103,8 +103,8 @@ struct htm {
 
 struct adu {
 	struct pdbg_target target;
-	int (*getmem)(struct adu *, uint64_t, uint64_t *);
-	int (*putmem)(struct adu *, uint64_t, uint64_t, int);
+	int (*getmem)(struct adu *, uint64_t, uint64_t *, int);
+	int (*putmem)(struct adu *, uint64_t, uint64_t, int, int);
 };
 #define target_to_adu(x) container_of(x, struct adu, target)
 
diff --git a/src/mem.c b/src/mem.c
index 815c1c7..be45434 100644
--- a/src/mem.c
+++ b/src/mem.c
@@ -26,7 +26,7 @@
 #include "main.h"
 
 #define PUTMEM_BUF_SIZE 1024
-static int getmem(uint64_t addr, uint64_t size)
+static int getmem(uint64_t addr, uint64_t size, int ci)
 {
 	struct pdbg_target *target;
 	uint8_t *buf;
@@ -37,7 +37,7 @@ static int getmem(uint64_t addr, uint64_t size)
 		if (pdbg_target_probe(target) != PDBG_TARGET_ENABLED)
 			continue;
 
-		if (!adu_getmem(target, addr, buf, size)) {
+		if (!adu_getmem(target, addr, buf, size, ci)) {
 			if (write(STDOUT_FILENO, buf, size) < 0)
 				PR_ERROR("Unable to write stdout.\n");
 			else
@@ -51,7 +51,7 @@ static int getmem(uint64_t addr, uint64_t size)
 	return rc;
 
 }
-static int putmem(uint64_t addr)
+static int putmem(uint64_t addr, int ci)
 {
 	uint8_t *buf;
 	int read_size, rc = 0;
@@ -67,7 +67,7 @@ static int putmem(uint64_t addr)
 	assert(buf);
 	do {
 		read_size = read(STDIN_FILENO, buf, PUTMEM_BUF_SIZE);
-		if (adu_putmem(adu_target, addr, buf, read_size)) {
+		if (adu_putmem(adu_target, addr, buf, read_size, ci)) {
 			rc = 0;
 			printf("Unable to write memory.\n");
 			break;
@@ -84,6 +84,7 @@ int handle_mem(int optind, int argc, char *argv[])
 {
 	uint64_t addr;
 	char *endptr;
+	int ci = 0;
 
 	if (optind + 1 >= argc) {
 		printf("%s: command '%s' requires an address\n", argv[0], argv[optind]);
@@ -91,31 +92,37 @@ int handle_mem(int optind, int argc, char *argv[])
 	}
 
 	errno = 0;
-	addr = strtoull(argv[optind + 1], &endptr, 0);
+
+	if (strcmp(argv[optind +1], "-ci") == 0) {
+		/* Set cache-inhibited flag */
+		ci = 1;
+	}
+
+	addr = strtoull(argv[optind + 1 + ci], &endptr, 0);
 	if (errno || *endptr != '\0') {
 		printf("%s: command '%s' couldn't parse address '%s'\n",
-				argv[0], argv[optind], argv[optind + 1]);
+				argv[0], argv[optind], argv[optind + 1 + ci]);
 		return -1;
 	}
 
 	if (strcmp(argv[optind], "getmem") == 0) {
 		uint64_t size;
 
-		if (optind + 2 >= argc) {
+		if (optind + 2 + ci >= argc) {
 			printf("%s: command '%s' requires data\n", argv[0], argv[optind]);
 			return -1;
 		}
 
 		errno = 0;
-		size = strtoull(argv[optind + 2], &endptr, 0);
+		size = strtoull(argv[optind + 2 + ci], &endptr, 0);
 		if (errno || *endptr != '\0') {
 			printf("%s: command '%s' couldn't parse data '%s'\n",
-				argv[0], argv[optind], argv[optind + 1]);
+				argv[0], argv[optind], argv[optind + 1 + ci]);
 			return -1;
 		}
 
-		return getmem(addr, size);
+		return getmem(addr, size, ci);
 	}
 
-	return putmem(addr);
+	return putmem(addr, ci);
 }
-- 
2.14.3



More information about the Pdbg mailing list