[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