aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTomas Vanek <vanekt@fbl.cz>2023-04-02 17:23:46 +0200
committerAntonio Borneo <borneo.antonio@gmail.com>2024-01-06 13:56:43 +0000
commitadcc8ef87bc1ed47c95f1f2d23072b2b916e1555 (patch)
tree9e9558b7b46ca15a0c1ce79b35ee1b3b52424842 /src
parentffdcec938fb6bd2d6f7f1f4aed7b41c627934a24 (diff)
downloadriscv-openocd-adcc8ef87bc1ed47c95f1f2d23072b2b916e1555.zip
riscv-openocd-adcc8ef87bc1ed47c95f1f2d23072b2b916e1555.tar.gz
riscv-openocd-adcc8ef87bc1ed47c95f1f2d23072b2b916e1555.tar.bz2
target/adiv5: probe MEM-AP supported transfer sizes including large data
Based on Daniel Goehring's [1] and Peter Collingbourne's [2] work. Probe for support of 8, 16 bit and if the large data extension is available also probe for 64, 128 and 256 bit operations. Probe for the ability of packing 8 and 16 bit data (formerly probed in mem_ap_init()). The probe is integrated to mem_ap_read/write() routines and takes place just before the first memory access of the specific size. Add 64, 128 and 256 bit MEM-AP read/writes. Introduce specific error codes for unsupported transfer size and for unsupported packing. Change-Id: I180c4ef17d2fc3189e8e2f14bafd22d857f29608 Link: 7191: target/adiv5: add MEM-AP 64-bit access support | https://review.openocd.org/c/openocd/+/7191 Link: 7436: arm_adi_v5: Support reads wider than 32 bits | https://review.openocd.org/c/openocd/+/7436 Signed-off-by: Tomas Vanek <vanekt@fbl.cz> Reviewed-on: https://review.openocd.org/c/openocd/+/7576 Reviewed-by: Antonio Borneo <borneo.antonio@gmail.com> Tested-by: jenkins
Diffstat (limited to 'src')
-rw-r--r--src/target/arm_adi_v5.c366
-rw-r--r--src/target/arm_adi_v5.h26
-rw-r--r--src/target/target.h2
3 files changed, 268 insertions, 126 deletions
diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c
index 0f1e648..ff12658 100644
--- a/src/target/arm_adi_v5.c
+++ b/src/target/arm_adi_v5.c
@@ -50,7 +50,8 @@
/*
* Relevant specifications from ARM include:
*
- * ARM(tm) Debug Interface v5 Architecture Specification ARM IHI 0031E
+ * ARM(tm) Debug Interface v5 Architecture Specification ARM IHI 0031F
+ * ARM(tm) Debug Interface v6 Architecture Specification ARM IHI 0074C
* CoreSight(tm) v1.0 Architecture Specification ARM IHI 0029B
*
* CoreSight(tm) DAP-Lite TRM, ARM DDI 0316D
@@ -164,6 +165,12 @@ static uint32_t mem_ap_get_tar_increment(struct adiv5_ap *ap)
return 2;
case CSW_32BIT:
return 4;
+ case CSW_64BIT:
+ return 8;
+ case CSW_128BIT:
+ return 16;
+ case CSW_256BIT:
+ return 32;
default:
return 0;
}
@@ -320,11 +327,144 @@ int mem_ap_write_atomic_u32(struct adiv5_ap *ap, target_addr_t address,
}
/**
+ * Queue transactions setting up transfer parameters for the
+ * currently selected MEM-AP. If transfer size or packing
+ * has not been probed, run the queue, read back CSW and check if the requested
+ * transfer mode is supported.
+ *
+ * @param ap The MEM-AP.
+ * @param size Transfer width in bytes. Corresponding CSW.Size will be set.
+ * @param address Transfer address, MEM-AP TAR will be set to this value.
+ * @param addrinc TAR will be autoincremented.
+ * @param pack Try to setup packed transfer.
+ * @param this_size Points to a variable set to the size of single transfer
+ * or to 4 when transferring packed bytes or halfwords
+ *
+ * @return ERROR_OK if the transaction was properly queued, else a fault code.
+ */
+static int mem_ap_setup_transfer_verify_size_packing(struct adiv5_ap *ap,
+ unsigned int size, target_addr_t address,
+ bool addrinc, bool pack, unsigned int *this_size)
+{
+ int retval;
+ uint32_t csw_size;
+
+ switch (size) {
+ case 1:
+ csw_size = CSW_8BIT;
+ break;
+ case 2:
+ csw_size = CSW_16BIT;
+ break;
+ case 4:
+ csw_size = CSW_32BIT;
+ break;
+ case 8:
+ csw_size = CSW_64BIT;
+ break;
+ case 16:
+ csw_size = CSW_128BIT;
+ break;
+ case 32:
+ csw_size = CSW_256BIT;
+ break;
+ default:
+ LOG_ERROR("Size %u not supported", size);
+ return ERROR_TARGET_SIZE_NOT_SUPPORTED;
+ }
+
+ if (!addrinc || size >= 4
+ || (ap->packed_transfers_probed && !ap->packed_transfers_supported)
+ || max_tar_block_size(ap->tar_autoincr_block, address) < 4)
+ pack = false;
+
+ uint32_t csw_addrinc = pack ? CSW_ADDRINC_PACKED :
+ addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF;
+ retval = mem_ap_setup_csw(ap, csw_size | csw_addrinc);
+ if (retval != ERROR_OK)
+ return retval;
+
+ bool do_probe = !(ap->csw_size_probed_mask & size)
+ || (pack && !ap->packed_transfers_probed);
+ if (do_probe) {
+ uint32_t csw_readback;
+ retval = dap_queue_ap_read(ap, MEM_AP_REG_CSW(ap->dap), &csw_readback);
+ if (retval != ERROR_OK)
+ return retval;
+
+ retval = dap_run(ap->dap);
+ if (retval != ERROR_OK)
+ return retval;
+
+ bool size_supported = ((csw_readback & CSW_SIZE_MASK) == csw_size);
+ LOG_DEBUG("AP#0x%" PRIx64 " probed size %u: %s", ap->ap_num, size,
+ size_supported ? "supported" : "not supported");
+ ap->csw_size_probed_mask |= size;
+ if (size_supported) {
+ ap->csw_size_supported_mask |= size;
+ if (pack && !ap->packed_transfers_probed) {
+ ap->packed_transfers_probed = true;
+ ap->packed_transfers_supported =
+ ((csw_readback & CSW_ADDRINC_MASK) == csw_addrinc);
+ LOG_DEBUG("probed packing: %s",
+ ap->packed_transfers_supported ? "supported" : "not supported");
+ }
+ }
+ }
+
+ if (!(ap->csw_size_supported_mask & size)) {
+ LOG_ERROR("Size %u not supported", size);
+ return ERROR_TARGET_SIZE_NOT_SUPPORTED;
+ }
+
+ if (pack && !ap->packed_transfers_supported)
+ return ERROR_TARGET_PACKING_NOT_SUPPORTED;
+
+ *this_size = pack ? 4 : size;
+
+ return mem_ap_setup_tar(ap, address);
+}
+
+/**
+ * Queue transactions setting up transfer parameters for the
+ * currently selected MEM-AP. If transfer size or packing
+ * has not been probed, run the queue, read back CSW and check if the requested
+ * transfer mode is supported.
+ * If packing is not supported fallback and prepare CSW for unpacked transfer.
+ *
+ * @param ap The MEM-AP.
+ * @param size Transfer width in bytes. Corresponding CSW.Size will be set.
+ * @param address Transfer address, MEM-AP TAR will be set to this value.
+ * @param addrinc TAR will be autoincremented.
+ * @param pack Try to setup packed transfer.
+ * @param this_size Points to a variable set to the size of single transfer
+ * or to 4 when transferring packed bytes or halfwords
+ *
+ * @return ERROR_OK if the transaction was properly queued, else a fault code.
+ */
+static int mem_ap_setup_transfer_verify_size_packing_fallback(struct adiv5_ap *ap,
+ unsigned int size, target_addr_t address,
+ bool addrinc, bool pack, unsigned int *this_size)
+{
+ int retval = mem_ap_setup_transfer_verify_size_packing(ap,
+ size, address,
+ addrinc, pack, this_size);
+ if (retval == ERROR_TARGET_PACKING_NOT_SUPPORTED) {
+ /* Retry without packing */
+ retval = mem_ap_setup_transfer_verify_size_packing(ap,
+ size, address,
+ addrinc, false, this_size);
+ }
+ return retval;
+}
+
+/**
* Synchronous write of a block of memory, using a specific access size.
*
* @param ap The MEM-AP to access.
* @param buffer The data buffer to write. No particular alignment is assumed.
- * @param size Which access size to use, in bytes. 1, 2 or 4.
+ * @param size Which access size to use, in bytes. 1, 2, or 4.
+ * If large data extension is available also accepts sizes 8, 16, 32.
* @param count The number of writes to do (in size units, not bytes).
* @param address Address to be written; it must be writable by the currently selected MEM-AP.
* @param addrinc Whether the target address should be increased for each write or not. This
@@ -336,8 +476,6 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t siz
{
struct adiv5_dap *dap = ap->dap;
size_t nbytes = size * count;
- const uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF;
- uint32_t csw_size;
int retval = ERROR_OK;
/* TI BE-32 Quirks mode:
@@ -352,93 +490,85 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t siz
* To make writes of size < 4 work as expected, we xor a value with the address before
* setting the TAP, and we set the TAP after every transfer rather then relying on
* address increment. */
-
- target_addr_t ti_be_lane_xor = dap->ti_be_32_quirks ? 3 : 0;
- target_addr_t ti_be_addr_xor;
- if (size == 4) {
- csw_size = CSW_32BIT;
- ti_be_addr_xor = 0;
- } else if (size == 2) {
- csw_size = CSW_16BIT;
- ti_be_addr_xor = dap->ti_be_32_quirks ? 2 : 0;
- } else if (size == 1) {
- csw_size = CSW_8BIT;
- ti_be_addr_xor = dap->ti_be_32_quirks ? 3 : 0;
- } else {
- return ERROR_TARGET_UNALIGNED_ACCESS;
+ target_addr_t ti_be_addr_xor = 0;
+ target_addr_t ti_be_lane_xor = 0;
+ if (dap->ti_be_32_quirks) {
+ ti_be_lane_xor = 3;
+ switch (size) {
+ case 1:
+ ti_be_addr_xor = 3;
+ break;
+ case 2:
+ ti_be_addr_xor = 2;
+ break;
+ case 4:
+ break;
+ default:
+ LOG_ERROR("Write more than 32 bits not supported with ti_be_32_quirks");
+ return ERROR_TARGET_SIZE_NOT_SUPPORTED;
+ }
}
if (ap->unaligned_access_bad && (address % size != 0))
return ERROR_TARGET_UNALIGNED_ACCESS;
- while (nbytes > 0) {
- uint32_t this_size = size;
+ /* Nuvoton NPCX quirks prevent packed writes */
+ bool pack = !dap->nu_npcx_quirks;
- /* Select packed transfer if possible */
- if (addrinc && ap->packed_transfers && nbytes >= 4
- && !dap->nu_npcx_quirks
- && max_tar_block_size(ap->tar_autoincr_block, address) >= 4) {
- this_size = 4;
- retval = mem_ap_setup_csw(ap, csw_size | CSW_ADDRINC_PACKED);
- } else {
- retval = mem_ap_setup_csw(ap, csw_size | csw_addrincr);
- }
-
- if (retval != ERROR_OK)
- break;
-
- retval = mem_ap_setup_tar(ap, address ^ ti_be_addr_xor);
+ while (nbytes > 0) {
+ unsigned int this_size;
+ retval = mem_ap_setup_transfer_verify_size_packing_fallback(ap,
+ size, address ^ ti_be_addr_xor,
+ addrinc, pack && nbytes >= 4, &this_size);
if (retval != ERROR_OK)
return retval;
/* How many source bytes each transfer will consume, and their location in the DRW,
* depends on the type of transfer and alignment. See ARM document IHI0031C. */
- uint32_t outvalue = 0;
uint32_t drw_byte_idx = address;
- if (dap->nu_npcx_quirks && this_size <= 2) {
- switch (this_size) {
- case 2:
- {
- /* Alternate low and high byte to all byte lanes */
- uint32_t low = *buffer++;
- uint32_t high = *buffer++;
- outvalue |= low << 8 * (drw_byte_idx++ & 3);
- outvalue |= high << 8 * (drw_byte_idx++ & 3);
- outvalue |= low << 8 * (drw_byte_idx++ & 3);
- outvalue |= high << 8 * (drw_byte_idx & 3);
- }
- break;
- case 1:
- {
- /* Mirror output byte to all byte lanes */
- uint32_t data = *buffer++;
- outvalue |= data;
- outvalue |= data << 8;
- outvalue |= data << 16;
- outvalue |= data << 24;
+ unsigned int drw_ops = DIV_ROUND_UP(this_size, 4);
+
+ while (drw_ops--) {
+ uint32_t outvalue = 0;
+ if (dap->nu_npcx_quirks && this_size <= 2) {
+ switch (this_size) {
+ case 2:
+ {
+ /* Alternate low and high byte to all byte lanes */
+ uint32_t low = *buffer++;
+ uint32_t high = *buffer++;
+ outvalue |= low << 8 * (drw_byte_idx++ & 3);
+ outvalue |= high << 8 * (drw_byte_idx++ & 3);
+ outvalue |= low << 8 * (drw_byte_idx++ & 3);
+ outvalue |= high << 8 * (drw_byte_idx & 3);
+ }
+ break;
+ case 1:
+ {
+ /* Mirror output byte to all byte lanes */
+ uint32_t data = *buffer++;
+ outvalue |= data;
+ outvalue |= data << 8;
+ outvalue |= data << 16;
+ outvalue |= data << 24;
+ }
}
+ } else {
+ unsigned int drw_bytes = MIN(this_size, 4);
+ while (drw_bytes--)
+ outvalue |= (uint32_t)*buffer++ <<
+ 8 * ((drw_byte_idx++ & 3) ^ ti_be_lane_xor);
}
- } else {
- switch (this_size) {
- case 4:
- outvalue |= (uint32_t)*buffer++ << 8 * ((drw_byte_idx++ & 3) ^ ti_be_lane_xor);
- outvalue |= (uint32_t)*buffer++ << 8 * ((drw_byte_idx++ & 3) ^ ti_be_lane_xor);
- /* fallthrough */
- case 2:
- outvalue |= (uint32_t)*buffer++ << 8 * ((drw_byte_idx++ & 3) ^ ti_be_lane_xor);
- /* fallthrough */
- case 1:
- outvalue |= (uint32_t)*buffer++ << 8 * ((drw_byte_idx & 3) ^ ti_be_lane_xor);
- }
- }
- nbytes -= this_size;
-
- retval = dap_queue_ap_write(ap, MEM_AP_REG_DRW(dap), outvalue);
+ retval = dap_queue_ap_write(ap, MEM_AP_REG_DRW(dap), outvalue);
+ if (retval != ERROR_OK)
+ break;
+ }
if (retval != ERROR_OK)
break;
mem_ap_update_tar_cache(ap);
+ nbytes -= this_size;
if (addrinc)
address += this_size;
}
@@ -463,7 +593,8 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t siz
*
* @param ap The MEM-AP to access.
* @param buffer The data buffer to receive the data. No particular alignment is assumed.
- * @param size Which access size to use, in bytes. 1, 2 or 4.
+ * @param size Which access size to use, in bytes. 1, 2, or 4.
+ * If large data extension is available also accepts sizes 8, 16, 32.
* @param count The number of reads to do (in size units, not bytes).
* @param adr Address to be read; it must be readable by the currently selected MEM-AP.
* @param addrinc Whether the target address should be increased after each read or not. This
@@ -475,8 +606,6 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint
{
struct adiv5_dap *dap = ap->dap;
size_t nbytes = size * count;
- const uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF;
- uint32_t csw_size;
target_addr_t address = adr;
int retval = ERROR_OK;
@@ -487,14 +616,10 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint
* Also, packed 8-bit and 16-bit transfers seem to sometimes return garbage in some bytes,
* so avoid them (ap->packed_transfers is forced to false in mem_ap_init). */
- if (size == 4)
- csw_size = CSW_32BIT;
- else if (size == 2)
- csw_size = CSW_16BIT;
- else if (size == 1)
- csw_size = CSW_8BIT;
- else
- return ERROR_TARGET_UNALIGNED_ACCESS;
+ if (dap->ti_be_32_quirks && size > 4) {
+ LOG_ERROR("Read more than 32 bits not supported with ti_be_32_quirks");
+ return ERROR_TARGET_SIZE_NOT_SUPPORTED;
+ }
if (ap->unaligned_access_bad && (adr % size != 0))
return ERROR_TARGET_UNALIGNED_ACCESS;
@@ -502,7 +627,8 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint
/* Allocate buffer to hold the sequence of DRW reads that will be made. This is a significant
* over-allocation if packed transfers are going to be used, but determining the real need at
* this point would be messy. */
- uint32_t *read_buf = calloc(count, sizeof(uint32_t));
+ uint32_t *read_buf = calloc(count, MAX(sizeof(uint32_t), size));
+
/* Multiplication count * sizeof(uint32_t) may overflow, calloc() is safe */
uint32_t *read_ptr = read_buf;
if (!read_buf) {
@@ -514,26 +640,20 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint
* useful bytes it contains, and their location in the word, depends on the type of transfer
* and alignment. */
while (nbytes > 0) {
- uint32_t this_size = size;
-
- /* Select packed transfer if possible */
- if (addrinc && ap->packed_transfers && nbytes >= 4
- && max_tar_block_size(ap->tar_autoincr_block, address) >= 4) {
- this_size = 4;
- retval = mem_ap_setup_csw(ap, csw_size | CSW_ADDRINC_PACKED);
- } else {
- retval = mem_ap_setup_csw(ap, csw_size | csw_addrincr);
- }
+ unsigned int this_size;
+ retval = mem_ap_setup_transfer_verify_size_packing_fallback(ap,
+ size, address,
+ addrinc, nbytes >= 4, &this_size);
if (retval != ERROR_OK)
break;
- retval = mem_ap_setup_tar(ap, address);
- if (retval != ERROR_OK)
- break;
- retval = dap_queue_ap_read(ap, MEM_AP_REG_DRW(dap), read_ptr++);
- if (retval != ERROR_OK)
- break;
+ unsigned int drw_ops = DIV_ROUND_UP(this_size, 4);
+ while (drw_ops--) {
+ retval = dap_queue_ap_read(ap, MEM_AP_REG_DRW(dap), read_ptr++);
+ if (retval != ERROR_OK)
+ break;
+ }
nbytes -= this_size;
if (addrinc)
@@ -552,7 +672,9 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint
/* If something failed, read TAR to find out how much data was successfully read, so we can
* at least give the caller what we have. */
- if (retval != ERROR_OK) {
+ if (retval == ERROR_TARGET_SIZE_NOT_SUPPORTED) {
+ nbytes = 0;
+ } else if (retval != ERROR_OK) {
target_addr_t tar;
if (mem_ap_read_tar(ap, &tar) == ERROR_OK) {
/* TAR is incremented after failed transfer on some devices (eg Cortex-M4) */
@@ -569,11 +691,12 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint
/* Replay loop to populate caller's buffer from the correct word and byte lane */
while (nbytes > 0) {
- uint32_t this_size = size;
+ /* Convert transfers longer than 32-bit on word-at-a-time basis */
+ unsigned int this_size = MIN(size, 4);
- if (addrinc && ap->packed_transfers && nbytes >= 4
+ if (size < 4 && addrinc && ap->packed_transfers_supported && nbytes >= 4
&& max_tar_block_size(ap->tar_autoincr_block, address) >= 4) {
- this_size = 4;
+ this_size = 4; /* Packed read of 4 bytes or 2 halfwords */
}
switch (this_size) {
@@ -764,7 +887,7 @@ int dap_dp_init_or_reconnect(struct adiv5_dap *dap)
int mem_ap_init(struct adiv5_ap *ap)
{
/* check that we support packed transfers */
- uint32_t csw, cfg;
+ uint32_t cfg;
int retval;
struct adiv5_dap *dap = ap->dap;
@@ -781,30 +904,23 @@ int mem_ap_init(struct adiv5_ap *ap)
ap->cfg_reg = cfg;
ap->tar_valid = false;
ap->csw_value = 0; /* force csw and tar write */
- retval = mem_ap_setup_transfer(ap, CSW_8BIT | CSW_ADDRINC_PACKED, 0);
- if (retval != ERROR_OK)
- return retval;
- retval = dap_queue_ap_read(ap, MEM_AP_REG_CSW(dap), &csw);
- if (retval != ERROR_OK)
- return retval;
+ /* CSW 32-bit size must be supported (IHI 0031F and 0074D). */
+ ap->csw_size_supported_mask = BIT(CSW_32BIT);
+ ap->csw_size_probed_mask = BIT(CSW_32BIT);
- retval = dap_run(dap);
- if (retval != ERROR_OK)
- return retval;
+ /* Suppress probing sizes longer than 32 bit if AP has no large data extension */
+ if (!(cfg & MEM_AP_REG_CFG_LD))
+ ap->csw_size_probed_mask |= BIT(CSW_64BIT) | BIT(CSW_128BIT) | BIT(CSW_256BIT);
- if (csw & CSW_ADDRINC_PACKED)
- ap->packed_transfers = true;
- else
- ap->packed_transfers = false;
-
- /* Packed transfers on TI BE-32 processors do not work correctly in
+ /* Both IHI 0031F and 0074D state: Implementations that support transfers
+ * smaller than a word must support packed transfers. Unfortunately at least
+ * Cortex-M0 and Cortex-M0+ do not comply with this rule.
+ * Probe for packed transfers except we know they are broken.
+ * Packed transfers on TI BE-32 processors do not work correctly in
* many cases. */
- if (dap->ti_be_32_quirks)
- ap->packed_transfers = false;
-
- LOG_DEBUG("MEM_AP Packed Transfers: %s",
- ap->packed_transfers ? "enabled" : "disabled");
+ ap->packed_transfers_supported = false;
+ ap->packed_transfers_probed = dap->ti_be_32_quirks ? true : false;
/* The ARM ADI spec leaves implementation-defined whether unaligned
* memory accesses work, only work partially, or cause a sticky error.
diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h
index fc7fdaf..60c161f 100644
--- a/src/target/arm_adi_v5.h
+++ b/src/target/arm_adi_v5.h
@@ -165,6 +165,9 @@
#define CSW_8BIT 0
#define CSW_16BIT 1
#define CSW_32BIT 2
+#define CSW_64BIT 3
+#define CSW_128BIT 4
+#define CSW_256BIT 5
#define CSW_ADDRINC_MASK (3UL << 4)
#define CSW_ADDRINC_OFF 0UL
#define CSW_ADDRINC_SINGLE (1UL << 4)
@@ -270,6 +273,26 @@ struct adiv5_ap {
uint32_t csw_value;
/**
+ * Save the supported CSW.Size data types for the MEM-AP.
+ * Each bit corresponds to a data type.
+ * 0b1 = Supported data size. 0b0 = Not supported.
+ * Bit 0 = Byte (8-bits)
+ * Bit 1 = Halfword (16-bits)
+ * Bit 2 = Word (32-bits) - always supported by spec.
+ * Bit 3 = Doubleword (64-bits)
+ * Bit 4 = 128-bits
+ * Bit 5 = 256-bits
+ */
+ uint32_t csw_size_supported_mask;
+ /**
+ * Probed CSW.Size data types for the MEM-AP.
+ * Each bit corresponds to a data type.
+ * 0b1 = Data size has been probed. 0b0 = Not yet probed.
+ * Bits assigned to sizes same way as above.
+ */
+ uint32_t csw_size_probed_mask;
+
+ /**
* Cache for (MEM-AP) AP_REG_TAR register value This is written to
* configure the address being read or written
* "-1" indicates no cached value.
@@ -286,7 +309,8 @@ struct adiv5_ap {
uint32_t tar_autoincr_block;
/* true if packed transfers are supported by the MEM-AP */
- bool packed_transfers;
+ bool packed_transfers_supported;
+ bool packed_transfers_probed;
/* true if unaligned memory access is not supported by the MEM-AP */
bool unaligned_access_bad;
diff --git a/src/target/target.h b/src/target/target.h
index 6caf598..f69ee77 100644
--- a/src/target/target.h
+++ b/src/target/target.h
@@ -796,6 +796,8 @@ int target_profiling_default(struct target *target, uint32_t *samples, uint32_t
#define ERROR_TARGET_NOT_EXAMINED (-311)
#define ERROR_TARGET_DUPLICATE_BREAKPOINT (-312)
#define ERROR_TARGET_ALGO_EXIT (-313)
+#define ERROR_TARGET_SIZE_NOT_SUPPORTED (-314)
+#define ERROR_TARGET_PACKING_NOT_SUPPORTED (-315)
extern bool get_target_reset_nag(void);