summaryrefslogtreecommitdiffstats
path: root/libpdbg/adu.c
diff options
context:
space:
mode:
authorAlistair Popple <alistair@popple.id.au>2017-01-12 19:18:11 +1100
committerAlistair Popple <alistair@popple.id.au>2017-03-30 15:37:41 +1100
commit3c8aee3e1d38a470451929c9b3499b85928cb241 (patch)
treeef7a1fc1a5b6eaee3dc8d63e85bc02faf4d44294 /libpdbg/adu.c
parentf045f14437ef63e10f57580978dc9ca3e0256007 (diff)
downloadpdbg-3c8aee3e1d38a470451929c9b3499b85928cb241.tar.gz
pdbg-3c8aee3e1d38a470451929c9b3499b85928cb241.zip
Add support for power9 putmem/getmem
Signed-off-by: Alistair Popple <alistair@popple.id.au>
Diffstat (limited to 'libpdbg/adu.c')
-rw-r--r--libpdbg/adu.c406
1 files changed, 251 insertions, 155 deletions
diff --git a/libpdbg/adu.c b/libpdbg/adu.c
index 4f2e9cb..f2f6649 100644
--- a/libpdbg/adu.c
+++ b/libpdbg/adu.c
@@ -20,15 +20,19 @@
#include "operations.h"
#include "bitutils.h"
-enum adu_retcode {ADU_DONE, ADU_RETRY, ADU_ERR};
-
-/* ADU SCOM Register Definitions */
-#define ALTD_CONTROL_REG 0x0
-#define ALTD_CMD_REG 0x1
+/* P8 ADU SCOM Register Definitions */
+#define P8_ALTD_CONTROL_REG 0x0
+#define P8_ALTD_CMD_REG 0x1
#define P8_ALTD_STATUS_REG 0x2
#define P8_ALTD_DATA_REG 0x3
-/* ALTD_CMD_REG fields */
+/* P9 ADU SCOM Register Definitions */
+#define P9_ALTD_CONTROL_REG 0x0
+#define P9_ALTD_CMD_REG 0x1
+#define P9_ALTD_STATUS_REG 0x3
+#define P9_ALTD_DATA_REG 0x4
+
+/* Common ALTD_CMD_REG fields */
#define FBC_ALTD_START_OP PPC_BIT(2)
#define FBC_ALTD_CLEAR_STATUS PPC_BIT(3)
#define FBC_ALTD_RESET_AD_PCB PPC_BIT(4)
@@ -37,6 +41,15 @@ enum adu_retcode {ADU_DONE, ADU_RETRY, ADU_ERR};
#define FBC_ALTD_DROP_PRIORITY PPC_BITMASK(20, 21)
#define FBC_LOCKED PPC_BIT(11)
+/* P9_ALTD_CMD_REG fields */
+#define P9_TTYPE_TREAD PPC_BIT(5)
+#define P9_TTYPE_TWRITE 0
+#define P9_FBC_ALTD_TTYPE PPC_BITMASK(25, 31)
+#define P9_TTYPE_DMA_PARTIAL_READ 0b000110
+#define P9_TTYPE_DMA_PARTIAL_WRITE 0b100110
+#define P9_FBC_ALTD_TSIZE PPC_BITMASK(32, 39)
+#define P9_FBC_ALTD_ADDRESS PPC_BITMASK(8, 63)
+
#define DROP_PRIORITY_LOW 0ULL
#define DROP_PRIORITY_MEDIUM 1ULL
#define DROP_PRIORITY_HIGH 2ULL
@@ -46,36 +59,98 @@ enum adu_retcode {ADU_DONE, ADU_RETRY, ADU_ERR};
#define SCOPE_SYSTEM 2
#define SCOPE_REMOTE 3
-/* ALTD_CONTROL_REG fields */
-#define FBC_ALTD_TTYPE PPC_BITMASK(0, 5)
-#define TTYPE_TREAD PPC_BIT(6)
-#define TTYPE_TWRITE 0
-#define FBC_ALTD_TSIZE PPC_BITMASK(7, 13)
-#define FBC_ALTD_ADDRESS PPC_BITMASK(14, 63)
-
-#define TTYPE_CI_PARTIAL_WRITE 0b110111
-#define TTYPE_CI_PARTIAL_OOO_WRITE 0b110110
-#define TTYPE_DMA_PARTIAL_WRITE 0b100110
-#define TTYPE_CI_PARTIAL_READ 0b110100
-#define TTYPE_DMA_PARTIAL_READ 0b110101
-#define TTYPE_PBOPERATION 0b111111
-
-/* P8_ALTD_STATUS_REG fields */
+/* P8_ALTD_CONTROL_REG fields */
+#define P8_FBC_ALTD_TTYPE PPC_BITMASK(0, 5)
+#define P8_TTYPE_TREAD PPC_BIT(6)
+#define P8_TTYPE_TWRITE 0
+#define P8_FBC_ALTD_TSIZE PPC_BITMASK(7, 13)
+#define P8_FBC_ALTD_ADDRESS PPC_BITMASK(14, 63)
+
+#define P8_TTYPE_CI_PARTIAL_WRITE 0b110111
+#define P8_TTYPE_CI_PARTIAL_OOO_WRITE 0b110110
+#define P8_TTYPE_DMA_PARTIAL_WRITE 0b100110
+#define P8_TTYPE_CI_PARTIAL_READ 0b110100
+#define P8_TTYPE_DMA_PARTIAL_READ 0b110101
+#define P8_TTYPE_PBOPERATION 0b111111
+
+/* P8/P9_ALTD_STATUS_REG fields */
#define FBC_ALTD_ADDR_DONE PPC_BIT(2)
#define FBC_ALTD_DATA_DONE PPC_BIT(3)
#define FBC_ALTD_PBINIT_MISSING PPC_BIT(18)
+int adu_getmem(struct target *adu_target, uint64_t start_addr, uint8_t *output, uint64_t size)
+{
+ struct adu *adu;
+ int rc = 0;
+ uint64_t addr;
+
+ assert(!strcmp(adu_target->class, "adu"));
+ adu = target_to_adu(adu_target);
+
+ /* We read data in 8-byte aligned chunks */
+ for (addr = 8*(start_addr / 8); addr < start_addr + size; addr += 8) {
+ uint64_t data;
+
+ if (adu->getmem(adu, addr, &data))
+ return -1;
+
+ /* ADU returns data in big-endian form in the register */
+ data = __builtin_bswap64(data);
+
+ if (addr < start_addr) {
+ memcpy(output, ((uint8_t *) &data) + (start_addr - addr), 8 - (start_addr - addr));
+ output += 8 - (start_addr - addr);
+ } else if (addr + 8 > start_addr + size) {
+ memcpy(output, &data, start_addr + size - addr);
+ } else {
+ memcpy(output, &data, 8);
+ output += 8;
+ }
+ }
+
+ return rc;
+}
+
+int adu_putmem(struct target *adu_target, uint64_t start_addr, uint8_t *input, uint64_t size)
+{
+ struct adu *adu;
+ int rc = 0, tsize;
+ uint64_t addr, data, end_addr;
+
+ assert(!strcmp(adu_target->class, "adu"));
+ adu = target_to_adu(adu_target);
+ end_addr = start_addr + size;
+ for (addr = start_addr; addr < end_addr; addr += tsize, input += tsize) {
+ if ((addr % 8) || (addr + 8 > end_addr)) {
+ /* If the address is not 64-bit aligned we
+ * copy in a byte at a time until it is. */
+ tsize = 1;
+
+ /* Copy the input data in with correct alignment */
+ data = ((uint64_t) *input) << 8*(8 - (addr % 8) - 1);
+ } else {
+ tsize = 8;
+ memcpy(&data, input, sizeof(data));
+ data = __builtin_bswap64(data);
+ }
+
+ adu->putmem(adu, addr, data, tsize);
+ }
+
+ return rc;
+}
+
static int adu_lock(struct adu *adu)
{
uint64_t val;
- CHECK_ERR(pib_read(&adu->target, ALTD_CMD_REG, &val));
+ CHECK_ERR(pib_read(&adu->target, P8_ALTD_CMD_REG, &val));
if (val & FBC_LOCKED)
PR_INFO("ADU already locked! Ignoring.\n");
val |= FBC_LOCKED;
- CHECK_ERR(pib_write(&adu->target, ALTD_CMD_REG, val));
+ CHECK_ERR(pib_write(&adu->target, P8_ALTD_CMD_REG, val));
return 0;
}
@@ -84,7 +159,7 @@ static int adu_unlock(struct adu *adu)
{
uint64_t val;
- CHECK_ERR(pib_read(&adu->target, ALTD_CMD_REG, &val));
+ CHECK_ERR(pib_read(&adu->target, P8_ALTD_CMD_REG, &val));
if (!(val & FBC_LOCKED)) {
PR_INFO("ADU already unlocked!\n");
@@ -92,7 +167,7 @@ static int adu_unlock(struct adu *adu)
}
val &= ~FBC_LOCKED;
- CHECK_ERR(pib_write(&adu->target, ALTD_CMD_REG, val));
+ CHECK_ERR(pib_write(&adu->target, P8_ALTD_CMD_REG, val));
return 0;
}
@@ -101,33 +176,38 @@ static int adu_reset(struct adu *adu)
{
uint64_t val;
- CHECK_ERR(pib_read(&adu->target, ALTD_CMD_REG, &val));
+ CHECK_ERR(pib_read(&adu->target, P8_ALTD_CMD_REG, &val));
val |= FBC_ALTD_CLEAR_STATUS | FBC_ALTD_RESET_AD_PCB;
- CHECK_ERR(pib_write(&adu->target, ALTD_CMD_REG, val));
+ CHECK_ERR(pib_write(&adu->target, P8_ALTD_CMD_REG, val));
return 0;
}
-static uint64_t p8_get_ctrl_reg(uint64_t ctrl_reg, uint64_t addr)
+static int p8_adu_getmem(struct adu *adu, uint64_t addr, uint64_t *data)
{
- ctrl_reg |= TTYPE_TREAD;
- ctrl_reg = SETFIELD(FBC_ALTD_TTYPE, ctrl_reg, TTYPE_DMA_PARTIAL_READ);
- ctrl_reg = SETFIELD(FBC_ALTD_TSIZE, ctrl_reg, 8);
- ctrl_reg = SETFIELD(FBC_ALTD_ADDRESS, ctrl_reg, addr);
- return ctrl_reg;
-}
+ uint64_t ctrl_reg, cmd_reg, val;
-static uint64_t p8_get_cmd_reg(uint64_t cmd_reg, uint64_t addr)
-{
+ CHECK_ERR(adu_lock(adu));
+
+ ctrl_reg = P8_TTYPE_TREAD;
+ 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));
cmd_reg |= FBC_ALTD_START_OP;
cmd_reg = SETFIELD(FBC_ALTD_SCOPE, cmd_reg, SCOPE_SYSTEM);
cmd_reg = SETFIELD(FBC_ALTD_DROP_PRIORITY, cmd_reg, DROP_PRIORITY_MEDIUM);
- return cmd_reg;
-}
-static enum adu_retcode p8_wait_completion(struct adu *adu)
-{
- uint64_t val;
+retry:
+ /* Clear status bits */
+ CHECK_ERR(adu_reset(adu));
+
+ /* Set the address */
+ ctrl_reg = SETFIELD(P8_FBC_ALTD_ADDRESS, ctrl_reg, addr);
+ CHECK_ERR(pib_write(&adu->target, P8_ALTD_CONTROL_REG, ctrl_reg));
+
+ /* Start the command */
+ CHECK_ERR(pib_write(&adu->target, P8_ALTD_CMD_REG, cmd_reg));
/* Wait for completion */
do {
@@ -138,73 +218,67 @@ static enum adu_retcode p8_wait_completion(struct adu *adu)
!(val & FBC_ALTD_DATA_DONE)) {
/* PBINIT_MISSING is expected occasionally so just retry */
if (val & FBC_ALTD_PBINIT_MISSING)
- return ADU_RETRY;
+ goto retry;
else {
- PR_ERROR("ALTD_STATUS_REG = 0x%016llx\n", val);
- return ADU_ERR;
+ PR_ERROR("Unable to read memory. " \
+ "ALTD_STATUS_REG = 0x%016llx\n", val);
+ return -1;
}
}
- return ADU_DONE;
-}
+ /* Read data */
+ CHECK_ERR(pib_read(&adu->target, P8_ALTD_DATA_REG, data));
-static int p8_adu_getmem(struct adu *adu, uint64_t addr)
-{
+ adu_unlock(adu);
+
+ return 0;
}
-/* Return size bytes of memory in *output. *output must point to an
- * array large enough to hold size bytes. */
-static int _adu_getmem(struct adu *adu, uint64_t start_addr, uint8_t *output, uint64_t size)
+int p8_adu_putmem(struct adu *adu, uint64_t addr, uint64_t data, int size)
{
int rc = 0;
- uint64_t addr, ctrl_reg, cmd_reg, val;
+ uint64_t cmd_reg, ctrl_reg, val;
- /* We read data in 8-byte aligned chunks */
- for (addr = 8*(start_addr / 8); addr < start_addr + size; addr += 8) {
- uint64_t data;
+ CHECK_ERR(adu_lock(adu));
- retry:
- /* Clear status bits */
- CHECK_ERR(adu_reset(adu));
+ ctrl_reg = P8_TTYPE_TWRITE;
+ ctrl_reg = SETFIELD(P8_FBC_ALTD_TTYPE, ctrl_reg, P8_TTYPE_DMA_PARTIAL_WRITE);
+ ctrl_reg = SETFIELD(P8_FBC_ALTD_TSIZE, ctrl_reg, size);
- /* Set the address */
- ctrl_reg = adu->_get_ctrl_reg(ctrl_reg, addr);
- cmd_reg = adu->_get_cmd_reg(cmd_reg, addr);
+ CHECK_ERR(pib_read(&adu->target, P8_ALTD_CMD_REG, &cmd_reg));
+ cmd_reg |= FBC_ALTD_START_OP;
+ cmd_reg = SETFIELD(FBC_ALTD_SCOPE, cmd_reg, SCOPE_SYSTEM);
+ cmd_reg = SETFIELD(FBC_ALTD_DROP_PRIORITY, cmd_reg, DROP_PRIORITY_MEDIUM);
- CHECK_ERR(pib_write(&adu->target, ALTD_CONTROL_REG, ctrl_reg));
+ /* Clear status bits */
+ CHECK_ERR(adu_reset(adu));
- /* Start the command */
- CHECK_ERR(pib_write(&adu->target, ALTD_CMD_REG, cmd_reg));
+ /* Set the address */
+ ctrl_reg = SETFIELD(P8_FBC_ALTD_ADDRESS, ctrl_reg, addr);
- /* Wait for completion */
- switch (adu->_wait_completion(adu)) {
- case ADU_DONE:
- break;
- case ADU_RETRY:
- goto retry;
- break;
- case ADU_ERR:
- /* Fall through - other return codes also indicate error */
- default:
- PR_ERROR("Unable to read memory\n");
- rc = ADU_ERR;
- break;
- }
+retry:
+ CHECK_ERR(pib_write(&adu->target, P8_ALTD_CONTROL_REG, ctrl_reg));
- /* Read data */
- CHECK_ERR(pib_read(&adu->target, P8_ALTD_DATA_REG, &data));
+ /* Write the data */
+ CHECK_ERR(pib_write(&adu->target, P8_ALTD_DATA_REG, data));
- /* ADU returns data in big-endian form in the register */
- data = __builtin_bswap64(data);
+ /* Start the command */
+ CHECK_ERR(pib_write(&adu->target, P8_ALTD_CMD_REG, cmd_reg));
- if (addr < start_addr) {
- memcpy(output, ((uint8_t *) &data) + (start_addr - addr), 8 - (start_addr - addr));
- output += 8 - (start_addr - addr);
- } else if (addr + 8 > start_addr + size) {
- memcpy(output, &data, start_addr + size - addr);
- } else {
- memcpy(output, &data, 8);
- output += 8;
+ /* Wait for completion */
+ do {
+ CHECK_ERR(pib_read(&adu->target, P8_ALTD_STATUS_REG, &val));
+ } while (!val);
+
+ if( !(val & FBC_ALTD_ADDR_DONE) ||
+ !(val & FBC_ALTD_DATA_DONE)) {
+ /* PBINIT_MISSING is expected occasionally so just retry */
+ if (val & FBC_ALTD_PBINIT_MISSING)
+ goto retry;
+ else {
+ PR_ERROR("Unable to write memory. " \
+ "P8_ALTD_STATUS_REG = 0x%016llx\n", val);
+ rc = -1;
}
}
@@ -213,73 +287,100 @@ static int _adu_getmem(struct adu *adu, uint64_t start_addr, uint8_t *output, ui
return rc;
}
-int p8_adu_putmem(struct adu *adu, uint64_t start_addr, uint8_t *input, uint64_t size)
+static int p9_adu_getmem(struct adu *adu, uint64_t addr, uint64_t *data)
{
- int rc = 0, tsize;
- uint64_t addr, cmd_reg, ctrl_reg, val, data, end_addr;
+ uint64_t ctrl_reg, cmd_reg, val;
- CHECK_ERR(adu_lock(adu));
+ cmd_reg = P9_TTYPE_TREAD;
+ cmd_reg = SETFIELD(P9_FBC_ALTD_TTYPE, cmd_reg, P9_TTYPE_DMA_PARTIAL_READ);
- ctrl_reg = TTYPE_TWRITE;
- ctrl_reg = SETFIELD(FBC_ALTD_TTYPE, ctrl_reg, TTYPE_DMA_PARTIAL_WRITE);
+ /* For a read size is apparently always 0 */
+ cmd_reg = SETFIELD(P9_FBC_ALTD_TSIZE, cmd_reg, 0);
+ cmd_reg |= FBC_ALTD_START_OP;
+ cmd_reg = SETFIELD(FBC_ALTD_SCOPE, cmd_reg, SCOPE_REMOTE);
+ cmd_reg = SETFIELD(FBC_ALTD_DROP_PRIORITY, cmd_reg, DROP_PRIORITY_LOW);
- CHECK_ERR(pib_read(&adu->target, ALTD_CMD_REG, &cmd_reg));
- cmd_reg |= FBC_ALTD_START_OP;
- cmd_reg = SETFIELD(FBC_ALTD_SCOPE, cmd_reg, SCOPE_SYSTEM);
- cmd_reg = SETFIELD(FBC_ALTD_DROP_PRIORITY, cmd_reg, DROP_PRIORITY_MEDIUM);
+retry:
+ /* Clear status bits */
+ CHECK_ERR(adu_reset(adu));
- end_addr = start_addr + size;
- for (addr = start_addr; addr < end_addr; addr += tsize, input += tsize) {
- if ((addr % 8) || (addr + 8 > end_addr)) {
- /* If the address is not 64-bit aligned we
- * copy in a byte at a time until it is. */
- tsize = 1;
+ /* Set the address */
+ ctrl_reg = SETFIELD(P9_FBC_ALTD_ADDRESS, 0, addr);
+ CHECK_ERR(pib_write(&adu->target, P9_ALTD_CONTROL_REG, ctrl_reg));
- /* Copy the input data in with correct alignment */
- data = ((uint64_t) *input) << 8*(8 - (addr % 8) - 1);
- } else {
- tsize = 8;
- memcpy(&data, input, sizeof(data));
- data = __builtin_bswap64(data);
- }
- ctrl_reg = SETFIELD(FBC_ALTD_TSIZE, ctrl_reg, tsize);
-
- retry:
- /* Clear status bits */
- CHECK_ERR(adu_reset(adu));
-
- /* Set the address */
- ctrl_reg = SETFIELD(FBC_ALTD_ADDRESS, ctrl_reg, addr);
- CHECK_ERR(pib_write(&adu->target, ALTD_CONTROL_REG, ctrl_reg));
-
- /* Write the data */
- CHECK_ERR(pib_write(&adu->target, P8_ALTD_DATA_REG, data));
-
- /* Start the command */
- CHECK_ERR(pib_write(&adu->target, ALTD_CMD_REG, cmd_reg));
-
- /* Wait for completion */
- do {
- CHECK_ERR(pib_read(&adu->target, P8_ALTD_STATUS_REG, &val));
- } while (!val);
-
- if( !(val & FBC_ALTD_ADDR_DONE) ||
- !(val & FBC_ALTD_DATA_DONE)) {
- /* PBINIT_MISSING is expected occasionally so just retry */
- if (val & FBC_ALTD_PBINIT_MISSING)
- goto retry;
- else {
- PR_ERROR("Unable to write memory. " \
- "P8_ALTD_STATUS_REG = 0x%016llx\n", val);
- rc = -1;
- break;
- }
+ /* Start the command */
+ CHECK_ERR(pib_write(&adu->target, P9_ALTD_CMD_REG, cmd_reg));
+
+ /* Wait for completion */
+ do {
+ CHECK_ERR(pib_read(&adu->target, P9_ALTD_STATUS_REG, &val));
+ } while (!val);
+
+ if( !(val & FBC_ALTD_ADDR_DONE) ||
+ !(val & FBC_ALTD_DATA_DONE)) {
+ /* PBINIT_MISSING is expected occasionally so just retry */
+ if (val & FBC_ALTD_PBINIT_MISSING)
+ goto retry;
+ else {
+ PR_ERROR("Unable to read memory. " \
+ "ALTD_STATUS_REG = 0x%016llx\n", val);
+ return -1;
}
}
- adu_unlock(adu);
+ /* Read data */
+ CHECK_ERR(pib_read(&adu->target, P9_ALTD_DATA_REG, data));
- return rc;
+ return 0;
+}
+
+static int p9_adu_putmem(struct adu *adu, uint64_t addr, uint64_t data, int size)
+{
+ uint64_t ctrl_reg, cmd_reg, val;
+
+ /* Format to tsize. This is the "secondary encode" and is
+ shifted left on for writes. */
+ size <<= 1;
+
+ cmd_reg = P9_TTYPE_TWRITE;
+ 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);
+ cmd_reg = SETFIELD(FBC_ALTD_DROP_PRIORITY, cmd_reg, DROP_PRIORITY_LOW);
+
+ /* Clear status bits */
+ CHECK_ERR(adu_reset(adu));
+
+ /* Set the address */
+ ctrl_reg = SETFIELD(P9_FBC_ALTD_ADDRESS, 0, addr);
+retry:
+ CHECK_ERR(pib_write(&adu->target, P9_ALTD_CONTROL_REG, ctrl_reg));
+
+ /* Write the data */
+ CHECK_ERR(pib_write(&adu->target, P9_ALTD_DATA_REG, data));
+
+ /* Start the command */
+ CHECK_ERR(pib_write(&adu->target, P9_ALTD_CMD_REG, cmd_reg));
+
+ /* Wait for completion */
+ do {
+ CHECK_ERR(pib_read(&adu->target, P9_ALTD_STATUS_REG, &val));
+ } while (!val);
+
+ if( !(val & FBC_ALTD_ADDR_DONE) ||
+ !(val & FBC_ALTD_DATA_DONE)) {
+ /* PBINIT_MISSING is expected occasionally so just retry */
+ if (val & FBC_ALTD_PBINIT_MISSING)
+ goto retry;
+ else {
+ PR_ERROR("Unable to read memory. " \
+ "ALTD_STATUS_REG = 0x%016llx\n", val);
+ return -1;
+ }
+ }
+
+ return 0;
}
struct adu p8_adu = {
@@ -288,23 +389,18 @@ struct adu p8_adu = {
.compatible = "ibm,power8-adu",
.class = "adu",
},
- .getmem = _adu_getmem,
+ .getmem = p8_adu_getmem,
.putmem = p8_adu_putmem,
- ._get_ctrl_reg = p8_get_ctrl_reg,
- ._get_cmd_reg = p8_get_cmd_reg,
- ._wait_completion = p8_wait_completion,
};
DECLARE_HW_UNIT(p8_adu);
-
-
struct adu p9_adu = {
.target = {
.name = "POWER9 ADU",
.compatible = "ibm,power9-adu",
.class = "adu",
},
-// .getmem = p9_adu_getmem,
-// .putmem = p9_adu_putmem,
+ .getmem = p9_adu_getmem,
+ .putmem = p9_adu_putmem,
};
DECLARE_HW_UNIT(p9_adu);
OpenPOWER on IntegriCloud