This is an automated email from Gerrit. simon qian ([email protected]) just uploaded a new patch set to Gerrit, which you can find at http://openocd.zylin.com/565
-- gerrit commit d3499f645cdbd85a1409c5e7b1ce98cb64347cbc Author: Simon Qian <[email protected]> Date: Thu Apr 12 00:25:32 2012 +0800 topic: add mem_ap_read_buf_u32_swd add mem_ap_read_buf_u32_swd, called by mem_ap_read_buf in swd mode. Change-Id: Ieed2f56dc6a6b75b2c3bcb1511364d879e4af103 Signed-off-by: Simon Qian <[email protected]> diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index 9a98f61..c1832c2 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -541,14 +541,14 @@ extern int adi_jtag_dp_scan(struct adiv5_dap *dap, uint8_t *outvalue, uint8_t *invalue, uint8_t *ack); /** - * Synchronously read a block of 32-bit words into a buffer + * Synchronously read a block of 32-bit words into a buffer via JTAG * @param dap The DAP connected to the MEM-AP. * @param buffer where the words will be stored (in host byte order). * @param count How many words to read. * @param address Memory address from which to read words; all the * words must be readable by the currently selected MEM-AP. */ -int mem_ap_read_buf_u32(struct adiv5_dap *dap, uint8_t *buffer, +static int mem_ap_read_buf_u32_jtag(struct adiv5_dap *dap, uint8_t *buffer, int count, uint32_t address) { int wcount, blocksize, readcount, errorcount = 0, retval = ERROR_OK; @@ -644,6 +644,120 @@ int mem_ap_read_buf_u32(struct adiv5_dap *dap, uint8_t *buffer, return retval; } +/** + * Synchronously read a block of 32-bit words into a buffer via SWD + * @param dap The DAP connected to the MEM-AP. + * @param buffer where the words will be stored (in host byte order). + * @param count How many words to read. + * @param address Memory address from which to read words; all the + * words must be readable by the currently selected MEM-AP. + */ +static int mem_ap_read_buf_u32_swd(struct adiv5_dap *dap, uint8_t *buffer, + int count, uint32_t address) +{ + int wcount, blocksize, readcount, errorcount = 0, retval = ERROR_OK; + uint32_t adr = address; + uint8_t *pBuffer = buffer; + + count >>= 2; + wcount = count; + + while (wcount > 0) { + /* Adjust to read blocks within boundaries aligned to the + * TAR autoincrement size (at least 2^10). Autoincrement + * mode avoids an extra per-word roundtrip to update TAR. + */ + blocksize = max_tar_block_size(dap->tar_autoincr_block, + address); + if (wcount < blocksize) + blocksize = wcount; + + /* handle unaligned data at 4k boundary */ + if (blocksize == 0) + blocksize = 1; + + retval = dap_setup_accessport(dap, CSW_32BIT | CSW_ADDRINC_SINGLE, + address); + if (retval != ERROR_OK) + return retval; + + /* FIXME remove these three calls to adi_jtag_dp_scan(), + * so this routine becomes transport-neutral. Be careful + * not to cause performance problems with JTAG; would it + * suffice to loop over dap_queue_ap_read(), or would that + * be slower when JTAG is the chosen transport? + */ + + /* Scan out first read */ + retval = dap_queue_ap_read(dap, AP_REG_DRW, NULL); + if (retval != ERROR_OK) + return retval; + for (readcount = 0; readcount < blocksize - 1; readcount++) { + /* Scan out next read; scan in posted value for the + * previous one. Assumes read is acked "OK/FAULT", + * and CTRL_STAT says that meant "OK". + */ + retval = dap_queue_ap_read(dap, AP_REG_DRW, + (uint32_t *)(buffer + 4 * readcount)); + if (retval != ERROR_OK) + return retval; + } + + /* Scan in last posted value; RDBUFF has no other effect, + * assuming ack is OK/FAULT and CTRL_STAT says "OK". + */ + retval = dap_queue_dp_read(dap, DP_RDBUFF, + (uint32_t *)(buffer + 4 * readcount)); + if (retval != ERROR_OK) + return retval; + + retval = dap_run(dap); + if (retval != ERROR_OK) { + errorcount++; + if (errorcount <= 1) { + /* try again */ + continue; + } + LOG_WARNING("Block read error address 0x%" PRIx32, address); + return retval; + } + wcount = wcount - blocksize; + address += 4 * blocksize; + buffer += 4 * blocksize; + } + + /* if we have an unaligned access - reorder data */ + if (adr & 0x3u) { + for (readcount = 0; readcount < count; readcount++) { + int i; + uint32_t data; + memcpy(&data, pBuffer, sizeof(uint32_t)); + + for (i = 0; i < 4; i++) { + *((uint8_t *)pBuffer) = + (data >> 8 * (adr & 0x3)); + pBuffer++; + adr++; + } + } + } + + return retval; +} + +int mem_ap_read_buf_u32(struct adiv5_dap *dap, uint8_t *buffer, + int count, uint32_t address) +{ + if (transport_is_swd()) { + return mem_ap_read_buf_u32_swd(dap, buffer, count, address); + } else if (transport_is_jtag()) { + return mem_ap_read_buf_u32_jtag(dap, buffer, count, address); + } else { + LOG_ERROR("unsupported transport!"); + return ERROR_FAIL; + } +} + static int mem_ap_read_buf_packed_u16(struct adiv5_dap *dap, uint8_t *buffer, int count, uint32_t address) { -- ------------------------------------------------------------------------------ Better than sec? Nothing is better than sec when it comes to monitoring Big Data applications. Try Boundary one-second resolution app monitoring today. Free. http://p.sf.net/sfu/Boundary-dev2dev _______________________________________________ OpenOCD-devel mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/openocd-devel
