* *
***************************************************************************/
-/**
- * Select one of the APs connected to the specified DAP. The
- * selection is implicitly used with future AP transactions.
- * This is a NOP if the specified AP is already selected.
- *
- * @param dap The DAP
- * @param apsel Number of the AP to (implicitly) use with further
- * transactions. This normally identifies a MEM-AP.
- */
-void dap_ap_select(struct adiv5_dap *dap, uint8_t ap)
-{
- uint32_t new_ap = (ap << 24) & 0xFF000000;
-
- if (new_ap != dap->ap_current) {
- dap->ap_current = new_ap;
- /* Switching AP invalidates cached values.
- * Values MUST BE UPDATED BEFORE AP ACCESS.
- */
- dap->ap_bank_value = -1;
- }
-}
-
static int mem_ap_setup_csw(struct adiv5_ap *ap, uint32_t csw)
{
csw = csw | CSW_DBGSWENABLE | CSW_MASTER_DEBUG | CSW_HPROT |
if (csw != ap->csw_value) {
/* LOG_DEBUG("DAP: Set CSW %x",csw); */
- int retval = dap_queue_ap_write(ap->dap, MEM_AP_REG_CSW, csw);
+ int retval = dap_queue_ap_write(ap, MEM_AP_REG_CSW, csw);
if (retval != ERROR_OK)
return retval;
ap->csw_value = csw;
if (tar != ap->tar_value ||
(ap->csw_value & CSW_ADDRINC_MASK)) {
/* LOG_DEBUG("DAP: Set TAR %x",tar); */
- int retval = dap_queue_ap_write(ap->dap, MEM_AP_REG_TAR, tar);
+ int retval = dap_queue_ap_write(ap, MEM_AP_REG_TAR, tar);
if (retval != ERROR_OK)
return retval;
ap->tar_value = tar;
/**
* Asynchronous (queued) read of a word from memory or a system register.
*
- * @param dap The DAP connected to the MEM-AP performing the read.
+ * @param ap The MEM-AP to access.
* @param address Address of the 32-bit word to read; it must be
* readable by the currently selected MEM-AP.
* @param value points to where the word will be stored when the
*
* @return ERROR_OK for success. Otherwise a fault code.
*/
-static int mem_ap_read_u32(struct adiv5_ap *ap, uint32_t address,
+int mem_ap_read_u32(struct adiv5_ap *ap, uint32_t address,
uint32_t *value)
{
int retval;
if (retval != ERROR_OK)
return retval;
- return dap_queue_ap_read(ap->dap, MEM_AP_REG_BD0 | (address & 0xC), value);
+ return dap_queue_ap_read(ap, MEM_AP_REG_BD0 | (address & 0xC), value);
}
/**
* Synchronous read of a word from memory or a system register.
* As a side effect, this flushes any queued transactions.
*
- * @param dap The DAP connected to the MEM-AP performing the read.
+ * @param ap The MEM-AP to access.
* @param address Address of the 32-bit word to read; it must be
* readable by the currently selected MEM-AP.
* @param value points to where the result will be stored.
* @return ERROR_OK for success; *value holds the result.
* Otherwise a fault code.
*/
-static int mem_ap_read_atomic_u32(struct adiv5_ap *ap, uint32_t address,
+int mem_ap_read_atomic_u32(struct adiv5_ap *ap, uint32_t address,
uint32_t *value)
{
int retval;
/**
* Asynchronous (queued) write of a word to memory or a system register.
*
- * @param dap The DAP connected to the MEM-AP.
+ * @param ap The MEM-AP to access.
* @param address Address to be written; it must be writable by
* the currently selected MEM-AP.
* @param value Word that will be written to the address when transaction
*
* @return ERROR_OK for success. Otherwise a fault code.
*/
-static int mem_ap_write_u32(struct adiv5_ap *ap, uint32_t address,
+int mem_ap_write_u32(struct adiv5_ap *ap, uint32_t address,
uint32_t value)
{
int retval;
if (retval != ERROR_OK)
return retval;
- return dap_queue_ap_write(ap->dap, MEM_AP_REG_BD0 | (address & 0xC),
+ return dap_queue_ap_write(ap, MEM_AP_REG_BD0 | (address & 0xC),
value);
}
* Synchronous write of a word to memory or a system register.
* As a side effect, this flushes any queued transactions.
*
- * @param dap The DAP connected to the MEM-AP.
+ * @param ap The MEM-AP to access.
* @param address Address to be written; it must be writable by
* the currently selected MEM-AP.
* @param value Word that will be written.
*
* @return ERROR_OK for success; the data was written. Otherwise a fault code.
*/
-static int mem_ap_write_atomic_u32(struct adiv5_ap *ap, uint32_t address,
+int mem_ap_write_atomic_u32(struct adiv5_ap *ap, uint32_t address,
uint32_t value)
{
int retval = mem_ap_write_u32(ap, address, value);
/**
* Synchronous write of a block of memory, using a specific access size.
*
- * @param dap The DAP connected to the MEM-AP.
+ * @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 count The number of writes to do (in size units, not bytes).
nbytes -= this_size;
- retval = dap_queue_ap_write(dap, MEM_AP_REG_DRW, outvalue);
+ retval = dap_queue_ap_write(ap, MEM_AP_REG_DRW, outvalue);
if (retval != ERROR_OK)
break;
if (retval != ERROR_OK) {
uint32_t tar;
- if (dap_queue_ap_read(dap, MEM_AP_REG_TAR, &tar) == ERROR_OK
+ if (dap_queue_ap_read(ap, MEM_AP_REG_TAR, &tar) == ERROR_OK
&& dap_run(dap) == ERROR_OK)
LOG_ERROR("Failed to write memory at 0x%08"PRIx32, tar);
else
/**
* Synchronous read of a block of memory, using a specific access size.
*
- * @param dap The DAP connected to the MEM-AP.
+ * @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 count The number of reads to do (in size units, not bytes).
if (retval != ERROR_OK)
break;
- retval = dap_queue_ap_read(dap, MEM_AP_REG_DRW, read_ptr++);
+ retval = dap_queue_ap_read(ap, MEM_AP_REG_DRW, read_ptr++);
if (retval != ERROR_OK)
break;
* at least give the caller what we have. */
if (retval != ERROR_OK) {
uint32_t tar;
- if (dap_queue_ap_read(dap, MEM_AP_REG_TAR, &tar) == ERROR_OK
+ if (dap_queue_ap_read(ap, MEM_AP_REG_TAR, &tar) == ERROR_OK
&& dap_run(dap) == ERROR_OK) {
LOG_ERROR("Failed to read memory at 0x%08"PRIx32, tar);
if (nbytes > tar - address)
return retval;
}
-/*--------------------------------------------------------------------*/
-/* Wrapping function with selection of AP */
-/*--------------------------------------------------------------------*/
-int mem_ap_sel_read_u32(struct adiv5_ap *ap,
- uint32_t address, uint32_t *value)
-{
- dap_ap_select(ap->dap, ap->ap_num);
- return mem_ap_read_u32(ap, address, value);
-}
-
-int mem_ap_sel_write_u32(struct adiv5_ap *ap,
- uint32_t address, uint32_t value)
-{
- dap_ap_select(ap->dap, ap->ap_num);
- return mem_ap_write_u32(ap, address, value);
-}
-
-int mem_ap_sel_read_atomic_u32(struct adiv5_ap *ap,
- uint32_t address, uint32_t *value)
-{
- dap_ap_select(ap->dap, ap->ap_num);
- return mem_ap_read_atomic_u32(ap, address, value);
-}
-
-int mem_ap_sel_write_atomic_u32(struct adiv5_ap *ap,
- uint32_t address, uint32_t value)
-{
- dap_ap_select(ap->dap, ap->ap_num);
- return mem_ap_write_atomic_u32(ap, address, value);
-}
-
-int mem_ap_sel_read_buf(struct adiv5_ap *ap,
+int mem_ap_read_buf(struct adiv5_ap *ap,
uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address)
{
- dap_ap_select(ap->dap, ap->ap_num);
return mem_ap_read(ap, buffer, size, count, address, true);
}
-int mem_ap_sel_write_buf(struct adiv5_ap *ap,
+int mem_ap_write_buf(struct adiv5_ap *ap,
const uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address)
{
- dap_ap_select(ap->dap, ap->ap_num);
return mem_ap_write(ap, buffer, size, count, address, true);
}
-int mem_ap_sel_read_buf_noincr(struct adiv5_ap *ap,
+int mem_ap_read_buf_noincr(struct adiv5_ap *ap,
uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address)
{
- dap_ap_select(ap->dap, ap->ap_num);
return mem_ap_read(ap, buffer, size, count, address, false);
}
-int mem_ap_sel_write_buf_noincr(struct adiv5_ap *ap,
+int mem_ap_write_buf_noincr(struct adiv5_ap *ap,
const uint8_t *buffer, uint32_t size, uint32_t count, uint32_t address)
{
- dap_ap_select(ap->dap, ap->ap_num);
return mem_ap_write(ap, buffer, size, count, address, false);
}
/* Number of bits for tar autoincrement, impl. dep. at least 10 */
dap->ap[i].tar_autoincr_block = (1<<10);
}
- dap->ap_current = -1;
- dap->ap_bank_value = -1;
- dap->dp_bank_value = -1;
return dap;
}
if (!dap->ops)
dap->ops = &jtag_dp_ops;
- dap->ap_current = -1;
- dap->ap_bank_value = -1;
+ dap->select = DP_SELECT_INVALID;
dap->last_read = NULL;
for (size_t i = 0; i < 10; i++) {
/* DP initialization */
- dap->dp_bank_value = 0;
-
retval = dap_queue_dp_read(dap, DP_CTRL_STAT, NULL);
if (retval != ERROR_OK)
continue;
int retval;
struct adiv5_dap *dap = ap->dap;
- dap_ap_select(dap, ap->ap_num);
-
retval = mem_ap_setup_transfer(ap, CSW_8BIT | CSW_ADDRINC_PACKED, 0);
if (retval != ERROR_OK)
return retval;
- retval = dap_queue_ap_read(dap, MEM_AP_REG_CSW, &csw);
+ retval = dap_queue_ap_read(ap, MEM_AP_REG_CSW, &csw);
if (retval != ERROR_OK)
return retval;
- retval = dap_queue_ap_read(dap, MEM_AP_REG_CFG, &cfg);
+ retval = dap_queue_ap_read(ap, MEM_AP_REG_CFG, &cfg);
if (retval != ERROR_OK)
return retval;
/* read the IDR register of the Access Port */
uint32_t id_val = 0;
- dap_ap_select(dap, ap_num);
- int retval = dap_queue_ap_read(dap, AP_REG_IDR, &id_val);
+ int retval = dap_queue_ap_read(dap_ap(dap, ap_num), AP_REG_IDR, &id_val);
if (retval != ERROR_OK)
return retval;
uint32_t *dbgbase, uint32_t *apid)
{
struct adiv5_dap *dap = ap->dap;
- uint32_t ap_old;
int retval;
- ap_old = dap_ap_get_select(dap);
- dap_ap_select(dap, ap->ap_num);
-
- retval = dap_queue_ap_read(dap, MEM_AP_REG_BASE, dbgbase);
+ retval = dap_queue_ap_read(ap, MEM_AP_REG_BASE, dbgbase);
if (retval != ERROR_OK)
return retval;
- retval = dap_queue_ap_read(dap, AP_REG_IDR, apid);
+ retval = dap_queue_ap_read(ap, AP_REG_IDR, apid);
if (retval != ERROR_OK)
return retval;
retval = dap_run(dap);
if (retval != ERROR_OK)
return retval;
- dap_ap_select(dap, ap_old);
-
return ERROR_OK;
}
int dap_lookup_cs_component(struct adiv5_ap *ap,
uint32_t dbgbase, uint8_t type, uint32_t *addr, int32_t *idx)
{
- struct adiv5_dap *dap = ap->dap;
- uint32_t ap_old;
uint32_t romentry, entry_offset = 0, component_base, devtype;
int retval;
*addr = 0;
- ap_old = dap_ap_get_select(dap);
do {
- retval = mem_ap_sel_read_atomic_u32(ap, (dbgbase&0xFFFFF000) |
+ retval = mem_ap_read_atomic_u32(ap, (dbgbase&0xFFFFF000) |
entry_offset, &romentry);
if (retval != ERROR_OK)
return retval;
if (romentry & 0x1) {
uint32_t c_cid1;
- retval = mem_ap_sel_read_atomic_u32(ap, component_base | 0xff4, &c_cid1);
+ retval = mem_ap_read_atomic_u32(ap, component_base | 0xff4, &c_cid1);
if (retval != ERROR_OK) {
LOG_ERROR("Can't read component with base address 0x%" PRIx32
", the corresponding core might be turned off", component_base);
return retval;
}
- retval = mem_ap_sel_read_atomic_u32(ap,
+ retval = mem_ap_read_atomic_u32(ap,
(component_base & 0xfffff000) | 0xfcc,
&devtype);
if (retval != ERROR_OK)
entry_offset += 4;
} while (romentry > 0);
- dap_ap_select(dap, ap_old);
-
if (!*addr)
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
command_print(cmd_ctx, "\t%sROM table in legacy format", tabs);
/* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */
- retval = mem_ap_sel_read_u32(ap, (dbgbase&0xFFFFF000) | 0xFF0, &cid0);
+ retval = mem_ap_read_u32(ap, (dbgbase&0xFFFFF000) | 0xFF0, &cid0);
if (retval != ERROR_OK)
return retval;
- retval = mem_ap_sel_read_u32(ap, (dbgbase&0xFFFFF000) | 0xFF4, &cid1);
+ retval = mem_ap_read_u32(ap, (dbgbase&0xFFFFF000) | 0xFF4, &cid1);
if (retval != ERROR_OK)
return retval;
- retval = mem_ap_sel_read_u32(ap, (dbgbase&0xFFFFF000) | 0xFF8, &cid2);
+ retval = mem_ap_read_u32(ap, (dbgbase&0xFFFFF000) | 0xFF8, &cid2);
if (retval != ERROR_OK)
return retval;
- retval = mem_ap_sel_read_u32(ap, (dbgbase&0xFFFFF000) | 0xFFC, &cid3);
+ retval = mem_ap_read_u32(ap, (dbgbase&0xFFFFF000) | 0xFFC, &cid3);
if (retval != ERROR_OK)
return retval;
- retval = mem_ap_sel_read_u32(ap, (dbgbase&0xFFFFF000) | 0xFCC, &memtype);
+ retval = mem_ap_read_u32(ap, (dbgbase&0xFFFFF000) | 0xFCC, &memtype);
if (retval != ERROR_OK)
return retval;
retval = dap_run(dap);
/* Now we read ROM table entries from dbgbase&0xFFFFF000) | 0x000 until we get 0x00000000 */
for (entry_offset = 0; ; entry_offset += 4) {
- retval = mem_ap_sel_read_atomic_u32(ap, (dbgbase&0xFFFFF000) | entry_offset, &romentry);
+ retval = mem_ap_read_atomic_u32(ap, (dbgbase&0xFFFFF000) | entry_offset, &romentry);
if (retval != ERROR_OK)
return retval;
command_print(cmd_ctx, "\t%sROMTABLE[0x%x] = 0x%" PRIx32 "",
component_base = (dbgbase & 0xFFFFF000) + (romentry & 0xFFFFF000);
/* IDs are in last 4K section */
- retval = mem_ap_sel_read_atomic_u32(ap, component_base + 0xFE0, &c_pid0);
+ retval = mem_ap_read_atomic_u32(ap, component_base + 0xFE0, &c_pid0);
if (retval != ERROR_OK) {
command_print(cmd_ctx, "\t%s\tCan't read component with base address 0x%" PRIx32
", the corresponding core might be turned off", tabs, component_base);
continue;
}
c_pid0 &= 0xff;
- retval = mem_ap_sel_read_atomic_u32(ap, component_base + 0xFE4, &c_pid1);
+ retval = mem_ap_read_atomic_u32(ap, component_base + 0xFE4, &c_pid1);
if (retval != ERROR_OK)
return retval;
c_pid1 &= 0xff;
- retval = mem_ap_sel_read_atomic_u32(ap, component_base + 0xFE8, &c_pid2);
+ retval = mem_ap_read_atomic_u32(ap, component_base + 0xFE8, &c_pid2);
if (retval != ERROR_OK)
return retval;
c_pid2 &= 0xff;
- retval = mem_ap_sel_read_atomic_u32(ap, component_base + 0xFEC, &c_pid3);
+ retval = mem_ap_read_atomic_u32(ap, component_base + 0xFEC, &c_pid3);
if (retval != ERROR_OK)
return retval;
c_pid3 &= 0xff;
- retval = mem_ap_sel_read_atomic_u32(ap, component_base + 0xFD0, &c_pid4);
+ retval = mem_ap_read_atomic_u32(ap, component_base + 0xFD0, &c_pid4);
if (retval != ERROR_OK)
return retval;
c_pid4 &= 0xff;
- retval = mem_ap_sel_read_atomic_u32(ap, component_base + 0xFF0, &c_cid0);
+ retval = mem_ap_read_atomic_u32(ap, component_base + 0xFF0, &c_cid0);
if (retval != ERROR_OK)
return retval;
c_cid0 &= 0xff;
- retval = mem_ap_sel_read_atomic_u32(ap, component_base + 0xFF4, &c_cid1);
+ retval = mem_ap_read_atomic_u32(ap, component_base + 0xFF4, &c_cid1);
if (retval != ERROR_OK)
return retval;
c_cid1 &= 0xff;
- retval = mem_ap_sel_read_atomic_u32(ap, component_base + 0xFF8, &c_cid2);
+ retval = mem_ap_read_atomic_u32(ap, component_base + 0xFF8, &c_cid2);
if (retval != ERROR_OK)
return retval;
c_cid2 &= 0xff;
- retval = mem_ap_sel_read_atomic_u32(ap, component_base + 0xFFC, &c_cid3);
+ retval = mem_ap_read_atomic_u32(ap, component_base + 0xFFC, &c_cid3);
if (retval != ERROR_OK)
return retval;
c_cid3 &= 0xff;
unsigned minor;
const char *major = "Reserved", *subtype = "Reserved";
- retval = mem_ap_sel_read_atomic_u32(ap,
+ retval = mem_ap_read_atomic_u32(ap,
(component_base & 0xfffff000) | 0xfcc,
&devtype);
if (retval != ERROR_OK)
return ERROR_COMMAND_SYNTAX_ERROR;
}
- dap_ap_select(dap, apsel);
-
/* NOTE: assumes we're talking to a MEM-AP, which
* has a base address. There are other kinds of AP,
* though they're not common for now. This should
* use the ID register to verify it's a MEM-AP.
*/
- retval = dap_queue_ap_read(dap, MEM_AP_REG_BASE, &baseaddr);
+ retval = dap_queue_ap_read(dap_ap(dap, apsel), MEM_AP_REG_BASE, &baseaddr);
if (retval != ERROR_OK)
return retval;
retval = dap_run(dap);
switch (CMD_ARGC) {
case 0:
- apsel = 0;
+ apsel = dap->apsel;
break;
case 1:
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel);
}
dap->apsel = apsel;
- dap_ap_select(dap, apsel);
- retval = dap_queue_ap_read(dap, AP_REG_IDR, &apid);
+ retval = dap_queue_ap_read(dap_ap(dap, apsel), AP_REG_IDR, &apid);
if (retval != ERROR_OK)
return retval;
retval = dap_run(dap);
return ERROR_COMMAND_SYNTAX_ERROR;
}
- dap_ap_select(dap, apsel);
-
- retval = dap_queue_ap_read(dap, AP_REG_IDR, &apid);
+ retval = dap_queue_ap_read(dap_ap(dap, apsel), AP_REG_IDR, &apid);
if (retval != ERROR_OK)
return retval;
retval = dap_run(dap);