size_t nbytes = size * count;
const uint32_t csw_addrincr = addrinc ? CSW_ADDRINC_SINGLE : CSW_ADDRINC_OFF;
uint32_t csw_size;
+ uint32_t addr_xor;
int retval;
- if (size == 4)
+ /* TI BE-32 Quirks mode:
+ * Writes on big-endian TMS570 behave very strangely. Observed behavior:
+ * size write address bytes written in order
+ * 4 TAR ^ 0 (val >> 24), (val >> 16), (val >> 8), (val)
+ * 2 TAR ^ 2 (val >> 8), (val)
+ * 1 TAR ^ 3 (val)
+ * For example, if you attempt to write a single byte to address 0, the processor
+ * will actually write a byte to address 3.
+ *
+ * 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. */
+
+ if (size == 4) {
csw_size = CSW_32BIT;
- else if (size == 2)
+ addr_xor = 0;
+ } else if (size == 2) {
csw_size = CSW_16BIT;
- else if (size == 1)
+ addr_xor = dap->ti_be_32_quirks ? 2 : 0;
+ } else if (size == 1) {
csw_size = CSW_8BIT;
- else
+ addr_xor = dap->ti_be_32_quirks ? 3 : 0;
+ } else {
return ERROR_TARGET_UNALIGNED_ACCESS;
+ }
- retval = dap_setup_accessport_tar(dap, address);
+ if (dap->unaligned_access_bad && (address % size != 0))
+ return ERROR_TARGET_UNALIGNED_ACCESS;
+
+ retval = dap_setup_accessport_tar(dap, address ^ addr_xor);
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;
- switch (this_size) {
- case 4:
- outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
- outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
- case 2:
- outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
- case 1:
- outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
+ if (dap->ti_be_32_quirks) {
+ switch (this_size) {
+ case 4:
+ outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor);
+ outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor);
+ outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor);
+ outvalue |= (uint32_t)*buffer++ << 8 * (3 ^ (address++ & 3) ^ addr_xor);
+ break;
+ case 2:
+ outvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (address++ & 3) ^ addr_xor);
+ outvalue |= (uint32_t)*buffer++ << 8 * (1 ^ (address++ & 3) ^ addr_xor);
+ break;
+ case 1:
+ outvalue |= (uint32_t)*buffer++ << 8 * (0 ^ (address++ & 3) ^ addr_xor);
+ break;
+ }
+ } else {
+ switch (this_size) {
+ case 4:
+ outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
+ outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
+ case 2:
+ outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
+ case 1:
+ outvalue |= (uint32_t)*buffer++ << 8 * (address++ & 3);
+ }
}
nbytes -= this_size;
if (retval != ERROR_OK)
break;
- /* Rewrite TAR if it wrapped */
- if (addrinc && address % dap->tar_autoincr_block < size && nbytes > 0) {
- retval = dap_setup_accessport_tar(dap, address);
+ /* Rewrite TAR if it wrapped or we're xoring addresses */
+ if (addrinc && (addr_xor || (address % dap->tar_autoincr_block < size && nbytes > 0))) {
+ retval = dap_setup_accessport_tar(dap, address ^ addr_xor);
if (retval != ERROR_OK)
break;
}
uint32_t address = adr;
int retval;
+ /* TI BE-32 Quirks mode:
+ * Reads on big-endian TMS570 behave strangely differently than writes.
+ * They read from the physical address requested, but with DRW byte-reversed.
+ * For example, a byte read from address 0 will place the result in the high bytes of DRW.
+ * Also, packed 8-bit and 16-bit transfers seem to sometimes return garbage in some bytes,
+ * so avoid them. */
+
if (size == 4)
csw_size = CSW_32BIT;
else if (size == 2)
else
return ERROR_TARGET_UNALIGNED_ACCESS;
+ if (dap->unaligned_access_bad && (adr % size != 0))
+ return ERROR_TARGET_UNALIGNED_ACCESS;
+
/* 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. */
}
retval = dap_setup_accessport_tar(dap, address);
- if (retval != ERROR_OK)
+ if (retval != ERROR_OK) {
+ free(read_buf);
return retval;
+ }
/* Queue up all reads. Each read will store the entire DRW word in the read buffer. How many
* useful bytes it contains, and their location in the word, depends on the type of transfer
this_size = 4;
}
- switch (this_size) {
- case 4:
- *buffer++ = *read_ptr >> 8 * (address++ & 3);
- *buffer++ = *read_ptr >> 8 * (address++ & 3);
- case 2:
- *buffer++ = *read_ptr >> 8 * (address++ & 3);
- case 1:
- *buffer++ = *read_ptr >> 8 * (address++ & 3);
+ if (dap->ti_be_32_quirks) {
+ switch (this_size) {
+ case 4:
+ *buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
+ *buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
+ case 2:
+ *buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
+ case 1:
+ *buffer++ = *read_ptr >> 8 * (3 - (address++ & 3));
+ }
+ } else {
+ switch (this_size) {
+ case 4:
+ *buffer++ = *read_ptr >> 8 * (address++ & 3);
+ *buffer++ = *read_ptr >> 8 * (address++ & 3);
+ case 2:
+ *buffer++ = *read_ptr >> 8 * (address++ & 3);
+ case 1:
+ *buffer++ = *read_ptr >> 8 * (address++ & 3);
+ }
}
read_ptr++;
dap_syssec(dap);
/* check that we support packed transfers */
- uint32_t csw;
+ uint32_t csw, cfg;
retval = dap_setup_accessport(dap, CSW_8BIT | CSW_ADDRINC_PACKED, 0);
if (retval != ERROR_OK)
if (retval != ERROR_OK)
return retval;
+ retval = dap_queue_ap_read(dap, AP_REG_CFG, &cfg);
+ if (retval != ERROR_OK)
+ return retval;
+
retval = dap_run(dap);
if (retval != ERROR_OK)
return retval;
else
dap->packed_transfers = false;
+ /* Packed transfers on TI BE-32 processors do not work correctly in
+ * many cases. */
+ if (dap->ti_be_32_quirks)
+ dap->packed_transfers = false;
+
LOG_DEBUG("MEM_AP Packed Transfers: %s",
dap->packed_transfers ? "enabled" : "disabled");
+ /* The ARM ADI spec leaves implementation-defined whether unaligned
+ * memory accesses work, only work partially, or cause a sticky error.
+ * On TI BE-32 processors, reads seem to return garbage in some bytes
+ * and unaligned writes seem to cause a sticky error.
+ * TODO: it would be nice to have a way to detect whether unaligned
+ * operations are supported on other processors. */
+ dap->unaligned_access_bad = dap->ti_be_32_quirks;
+
+ LOG_DEBUG("MEM_AP CFG: large data %d, long address %d, big-endian %d",
+ !!(cfg & 0x04), !!(cfg & 0x02), !!(cfg & 0x01));
+
return ERROR_OK;
}
return retval;
}
+static int dap_rom_display(struct command_context *cmd_ctx,
+ struct adiv5_dap *dap, int ap, uint32_t dbgbase, int depth)
+{
+ int retval;
+ uint32_t cid0, cid1, cid2, cid3, memtype, romentry;
+ uint16_t entry_offset;
+ char tabs[7] = "";
+
+ if (depth > 16) {
+ command_print(cmd_ctx, "\tTables too deep");
+ return ERROR_FAIL;
+ }
+
+ if (depth)
+ snprintf(tabs, sizeof(tabs), "[L%02d] ", depth);
+
+ /* bit 16 of apid indicates a memory access port */
+ if (dbgbase & 0x02)
+ command_print(cmd_ctx, "\t%sValid ROM table present", tabs);
+ else
+ 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_read_u32(dap, (dbgbase&0xFFFFF000) | 0xFF0, &cid0);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = mem_ap_read_u32(dap, (dbgbase&0xFFFFF000) | 0xFF4, &cid1);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = mem_ap_read_u32(dap, (dbgbase&0xFFFFF000) | 0xFF8, &cid2);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = mem_ap_read_u32(dap, (dbgbase&0xFFFFF000) | 0xFFC, &cid3);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = mem_ap_read_u32(dap, (dbgbase&0xFFFFF000) | 0xFCC, &memtype);
+ if (retval != ERROR_OK)
+ return retval;
+ retval = dap_run(dap);
+ if (retval != ERROR_OK)
+ return retval;
+
+ if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
+ command_print(cmd_ctx, "\t%sCID3 0x%02x"
+ ", CID2 0x%02x"
+ ", CID1 0x%02x"
+ ", CID0 0x%02x",
+ tabs,
+ (unsigned)cid3, (unsigned)cid2,
+ (unsigned)cid1, (unsigned)cid0);
+ if (memtype & 0x01)
+ command_print(cmd_ctx, "\t%sMEMTYPE system memory present on bus", tabs);
+ else
+ command_print(cmd_ctx, "\t%sMEMTYPE system memory not present: dedicated debug bus", tabs);
+
+ /* Now we read ROM table entries from dbgbase&0xFFFFF000) | 0x000 until we get 0x00000000 */
+ for (entry_offset = 0; ; entry_offset += 4) {
+ retval = mem_ap_read_atomic_u32(dap, (dbgbase&0xFFFFF000) | entry_offset, &romentry);
+ if (retval != ERROR_OK)
+ return retval;
+ command_print(cmd_ctx, "\t%sROMTABLE[0x%x] = 0x%" PRIx32 "",
+ tabs, entry_offset, romentry);
+ if (romentry & 0x01) {
+ uint32_t c_cid0, c_cid1, c_cid2, c_cid3;
+ uint32_t c_pid0, c_pid1, c_pid2, c_pid3, c_pid4;
+ uint32_t component_base;
+ unsigned part_num;
+ char *type, *full;
+
+ component_base = (dbgbase & 0xFFFFF000) + (romentry & 0xFFFFF000);
+
+ /* IDs are in last 4K section */
+ retval = mem_ap_read_atomic_u32(dap, 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_read_atomic_u32(dap, component_base + 0xFE4, &c_pid1);
+ if (retval != ERROR_OK)
+ return retval;
+ c_pid1 &= 0xff;
+ retval = mem_ap_read_atomic_u32(dap, component_base + 0xFE8, &c_pid2);
+ if (retval != ERROR_OK)
+ return retval;
+ c_pid2 &= 0xff;
+ retval = mem_ap_read_atomic_u32(dap, component_base + 0xFEC, &c_pid3);
+ if (retval != ERROR_OK)
+ return retval;
+ c_pid3 &= 0xff;
+ retval = mem_ap_read_atomic_u32(dap, component_base + 0xFD0, &c_pid4);
+ if (retval != ERROR_OK)
+ return retval;
+ c_pid4 &= 0xff;
+
+ retval = mem_ap_read_atomic_u32(dap, component_base + 0xFF0, &c_cid0);
+ if (retval != ERROR_OK)
+ return retval;
+ c_cid0 &= 0xff;
+ retval = mem_ap_read_atomic_u32(dap, component_base + 0xFF4, &c_cid1);
+ if (retval != ERROR_OK)
+ return retval;
+ c_cid1 &= 0xff;
+ retval = mem_ap_read_atomic_u32(dap, component_base + 0xFF8, &c_cid2);
+ if (retval != ERROR_OK)
+ return retval;
+ c_cid2 &= 0xff;
+ retval = mem_ap_read_atomic_u32(dap, component_base + 0xFFC, &c_cid3);
+ if (retval != ERROR_OK)
+ return retval;
+ c_cid3 &= 0xff;
+
+ command_print(cmd_ctx, "\t\tComponent base address 0x%" PRIx32 ", "
+ "start address 0x%" PRIx32, component_base,
+ /* component may take multiple 4K pages */
+ (uint32_t)(component_base - 0x1000*(c_pid4 >> 4)));
+ command_print(cmd_ctx, "\t\tComponent class is 0x%" PRIx8 ", %s",
+ (uint8_t)((c_cid1 >> 4) & 0xf),
+ /* See ARM IHI 0029B Table 3-3 */
+ class_description[(c_cid1 >> 4) & 0xf]);
+
+ /* CoreSight component? */
+ if (((c_cid1 >> 4) & 0x0f) == 9) {
+ uint32_t devtype;
+ unsigned minor;
+ char *major = "Reserved", *subtype = "Reserved";
+
+ retval = mem_ap_read_atomic_u32(dap,
+ (component_base & 0xfffff000) | 0xfcc,
+ &devtype);
+ if (retval != ERROR_OK)
+ return retval;
+ minor = (devtype >> 4) & 0x0f;
+ switch (devtype & 0x0f) {
+ case 0:
+ major = "Miscellaneous";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 4:
+ subtype = "Validation component";
+ break;
+ }
+ break;
+ case 1:
+ major = "Trace Sink";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Port";
+ break;
+ case 2:
+ subtype = "Buffer";
+ break;
+ }
+ break;
+ case 2:
+ major = "Trace Link";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Funnel, router";
+ break;
+ case 2:
+ subtype = "Filter";
+ break;
+ case 3:
+ subtype = "FIFO, buffer";
+ break;
+ }
+ break;
+ case 3:
+ major = "Trace Source";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Processor";
+ break;
+ case 2:
+ subtype = "DSP";
+ break;
+ case 3:
+ subtype = "Engine/Coprocessor";
+ break;
+ case 4:
+ subtype = "Bus";
+ break;
+ }
+ break;
+ case 4:
+ major = "Debug Control";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Trigger Matrix";
+ break;
+ case 2:
+ subtype = "Debug Auth";
+ break;
+ }
+ break;
+ case 5:
+ major = "Debug Logic";
+ switch (minor) {
+ case 0:
+ subtype = "other";
+ break;
+ case 1:
+ subtype = "Processor";
+ break;
+ case 2:
+ subtype = "DSP";
+ break;
+ case 3:
+ subtype = "Engine/Coprocessor";
+ break;
+ }
+ break;
+ }
+ command_print(cmd_ctx, "\t\tType is 0x%02" PRIx8 ", %s, %s",
+ (uint8_t)(devtype & 0xff),
+ major, subtype);
+ /* REVISIT also show 0xfc8 DevId */
+ }
+
+ if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
+ command_print(cmd_ctx,
+ "\t\tCID3 0%02x"
+ ", CID2 0%02x"
+ ", CID1 0%02x"
+ ", CID0 0%02x",
+ (int)c_cid3,
+ (int)c_cid2,
+ (int)c_cid1,
+ (int)c_cid0);
+ command_print(cmd_ctx,
+ "\t\tPeripheral ID[4..0] = hex "
+ "%02x %02x %02x %02x %02x",
+ (int)c_pid4, (int)c_pid3, (int)c_pid2,
+ (int)c_pid1, (int)c_pid0);
+
+ /* Part number interpretations are from Cortex
+ * core specs, the CoreSight components TRM
+ * (ARM DDI 0314H), CoreSight System Design
+ * Guide (ARM DGI 0012D) and ETM specs; also
+ * from chip observation (e.g. TI SDTI).
+ */
+ part_num = (c_pid0 & 0xff);
+ part_num |= (c_pid1 & 0x0f) << 8;
+ switch (part_num) {
+ case 0x000:
+ type = "Cortex-M3 NVIC";
+ full = "(Interrupt Controller)";
+ break;
+ case 0x001:
+ type = "Cortex-M3 ITM";
+ full = "(Instrumentation Trace Module)";
+ break;
+ case 0x002:
+ type = "Cortex-M3 DWT";
+ full = "(Data Watchpoint and Trace)";
+ break;
+ case 0x003:
+ type = "Cortex-M3 FBP";
+ full = "(Flash Patch and Breakpoint)";
+ break;
+ case 0x00c:
+ type = "Cortex-M4 SCS";
+ full = "(System Control Space)";
+ break;
+ case 0x00d:
+ type = "CoreSight ETM11";
+ full = "(Embedded Trace)";
+ break;
+ /* case 0x113: what? */
+ case 0x120: /* from OMAP3 memmap */
+ type = "TI SDTI";
+ full = "(System Debug Trace Interface)";
+ break;
+ case 0x343: /* from OMAP3 memmap */
+ type = "TI DAPCTL";
+ full = "";
+ break;
+ case 0x906:
+ type = "Coresight CTI";
+ full = "(Cross Trigger)";
+ break;
+ case 0x907:
+ type = "Coresight ETB";
+ full = "(Trace Buffer)";
+ break;
+ case 0x908:
+ type = "Coresight CSTF";
+ full = "(Trace Funnel)";
+ break;
+ case 0x910:
+ type = "CoreSight ETM9";
+ full = "(Embedded Trace)";
+ break;
+ case 0x912:
+ type = "Coresight TPIU";
+ full = "(Trace Port Interface Unit)";
+ break;
+ case 0x913:
+ type = "Coresight ITM";
+ full = "(Instrumentation Trace Macrocell)";
+ break;
+ case 0x921:
+ type = "Cortex-A8 ETM";
+ full = "(Embedded Trace)";
+ break;
+ case 0x922:
+ type = "Cortex-A8 CTI";
+ full = "(Cross Trigger)";
+ break;
+ case 0x923:
+ type = "Cortex-M3 TPIU";
+ full = "(Trace Port Interface Unit)";
+ break;
+ case 0x924:
+ type = "Cortex-M3 ETM";
+ full = "(Embedded Trace)";
+ break;
+ case 0x925:
+ type = "Cortex-M4 ETM";
+ full = "(Embedded Trace)";
+ break;
+ case 0x930:
+ type = "Cortex-R4 ETM";
+ full = "(Embedded Trace)";
+ break;
+ case 0x950:
+ type = "CoreSight Component";
+ full = "(unidentified Cortex-A9 component)";
+ break;
+ case 0x9a0:
+ type = "CoreSight PMU";
+ full = "(Performance Monitoring Unit)";
+ break;
+ case 0x9a1:
+ type = "Cortex-M4 TPUI";
+ full = "(Trace Port Interface Unit)";
+ break;
+ case 0xc08:
+ type = "Cortex-A8 Debug";
+ full = "(Debug Unit)";
+ break;
+ case 0xc09:
+ type = "Cortex-A9 Debug";
+ full = "(Debug Unit)";
+ break;
+ default:
+ type = "-*- unrecognized -*-";
+ full = "";
+ break;
+ }
+ command_print(cmd_ctx, "\t\tPart is %s %s",
+ type, full);
+
+ /* ROM Table? */
+ if (((c_cid1 >> 4) & 0x0f) == 1) {
+ retval = dap_rom_display(cmd_ctx, dap, ap, component_base, depth + 1);
+ if (retval != ERROR_OK)
+ return retval;
+ }
+ } else {
+ if (romentry)
+ command_print(cmd_ctx, "\t\tComponent not present");
+ else
+ break;
+ }
+ }
+ command_print(cmd_ctx, "\t%s\tEnd of ROM table", tabs);
+ return ERROR_OK;
+}
+
static int dap_info_command(struct command_context *cmd_ctx,
struct adiv5_dap *dap, int ap)
{
romtable_present = ((mem_ap) && (dbgbase != 0xFFFFFFFF));
if (romtable_present) {
- uint32_t cid0, cid1, cid2, cid3, memtype, romentry;
- uint16_t entry_offset;
-
- /* bit 16 of apid indicates a memory access port */
- if (dbgbase & 0x02)
- command_print(cmd_ctx, "\tValid ROM table present");
- else
- command_print(cmd_ctx, "\tROM table in legacy format");
-
- /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */
- retval = mem_ap_read_u32(dap, (dbgbase&0xFFFFF000) | 0xFF0, &cid0);
- if (retval != ERROR_OK)
- return retval;
- retval = mem_ap_read_u32(dap, (dbgbase&0xFFFFF000) | 0xFF4, &cid1);
- if (retval != ERROR_OK)
- return retval;
- retval = mem_ap_read_u32(dap, (dbgbase&0xFFFFF000) | 0xFF8, &cid2);
- if (retval != ERROR_OK)
- return retval;
- retval = mem_ap_read_u32(dap, (dbgbase&0xFFFFF000) | 0xFFC, &cid3);
- if (retval != ERROR_OK)
- return retval;
- retval = mem_ap_read_u32(dap, (dbgbase&0xFFFFF000) | 0xFCC, &memtype);
- if (retval != ERROR_OK)
- return retval;
- retval = dap_run(dap);
- if (retval != ERROR_OK)
- return retval;
-
- if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
- command_print(cmd_ctx, "\tCID3 0x%2.2x"
- ", CID2 0x%2.2x"
- ", CID1 0x%2.2x"
- ", CID0 0x%2.2x",
- (unsigned) cid3, (unsigned)cid2,
- (unsigned) cid1, (unsigned) cid0);
- if (memtype & 0x01)
- command_print(cmd_ctx, "\tMEMTYPE system memory present on bus");
- else
- command_print(cmd_ctx, "\tMEMTYPE System memory not present. "
- "Dedicated debug bus.");
-
- /* Now we read ROM table entries from dbgbase&0xFFFFF000) | 0x000 until we get 0x00000000 */
- entry_offset = 0;
- do {
- retval = mem_ap_read_atomic_u32(dap, (dbgbase&0xFFFFF000) | entry_offset, &romentry);
- if (retval != ERROR_OK)
- return retval;
- command_print(cmd_ctx, "\tROMTABLE[0x%x] = 0x%" PRIx32 "", entry_offset, romentry);
- if (romentry & 0x01) {
- uint32_t c_cid0, c_cid1, c_cid2, c_cid3;
- uint32_t c_pid0, c_pid1, c_pid2, c_pid3, c_pid4;
- uint32_t component_base;
- unsigned part_num;
- char *type, *full;
-
- component_base = (dbgbase & 0xFFFFF000) + (romentry & 0xFFFFF000);
-
- /* IDs are in last 4K section */
- retval = mem_ap_read_atomic_u32(dap, component_base + 0xFE0, &c_pid0);
- if (retval != ERROR_OK)
- return retval;
- c_pid0 &= 0xff;
- retval = mem_ap_read_atomic_u32(dap, component_base + 0xFE4, &c_pid1);
- if (retval != ERROR_OK)
- return retval;
- c_pid1 &= 0xff;
- retval = mem_ap_read_atomic_u32(dap, component_base + 0xFE8, &c_pid2);
- if (retval != ERROR_OK)
- return retval;
- c_pid2 &= 0xff;
- retval = mem_ap_read_atomic_u32(dap, component_base + 0xFEC, &c_pid3);
- if (retval != ERROR_OK)
- return retval;
- c_pid3 &= 0xff;
- retval = mem_ap_read_atomic_u32(dap, component_base + 0xFD0, &c_pid4);
- if (retval != ERROR_OK)
- return retval;
- c_pid4 &= 0xff;
-
- retval = mem_ap_read_atomic_u32(dap, component_base + 0xFF0, &c_cid0);
- if (retval != ERROR_OK)
- return retval;
- c_cid0 &= 0xff;
- retval = mem_ap_read_atomic_u32(dap, component_base + 0xFF4, &c_cid1);
- if (retval != ERROR_OK)
- return retval;
- c_cid1 &= 0xff;
- retval = mem_ap_read_atomic_u32(dap, component_base + 0xFF8, &c_cid2);
- if (retval != ERROR_OK)
- return retval;
- c_cid2 &= 0xff;
- retval = mem_ap_read_atomic_u32(dap, component_base + 0xFFC, &c_cid3);
- if (retval != ERROR_OK)
- return retval;
- c_cid3 &= 0xff;
-
- command_print(cmd_ctx, "\t\tComponent base address 0x%" PRIx32 ","
- "start address 0x%" PRIx32, component_base,
- /* component may take multiple 4K pages */
- component_base - 0x1000*(c_pid4 >> 4));
- command_print(cmd_ctx, "\t\tComponent class is 0x%x, %s",
- (int) (c_cid1 >> 4) & 0xf,
- /* See ARM IHI 0029B Table 3-3 */
- class_description[(c_cid1 >> 4) & 0xf]);
-
- /* CoreSight component? */
- if (((c_cid1 >> 4) & 0x0f) == 9) {
- uint32_t devtype;
- unsigned minor;
- char *major = "Reserved", *subtype = "Reserved";
-
- retval = mem_ap_read_atomic_u32(dap,
- (component_base & 0xfffff000) | 0xfcc,
- &devtype);
- if (retval != ERROR_OK)
- return retval;
- minor = (devtype >> 4) & 0x0f;
- switch (devtype & 0x0f) {
- case 0:
- major = "Miscellaneous";
- switch (minor) {
- case 0:
- subtype = "other";
- break;
- case 4:
- subtype = "Validation component";
- break;
- }
- break;
- case 1:
- major = "Trace Sink";
- switch (minor) {
- case 0:
- subtype = "other";
- break;
- case 1:
- subtype = "Port";
- break;
- case 2:
- subtype = "Buffer";
- break;
- }
- break;
- case 2:
- major = "Trace Link";
- switch (minor) {
- case 0:
- subtype = "other";
- break;
- case 1:
- subtype = "Funnel, router";
- break;
- case 2:
- subtype = "Filter";
- break;
- case 3:
- subtype = "FIFO, buffer";
- break;
- }
- break;
- case 3:
- major = "Trace Source";
- switch (minor) {
- case 0:
- subtype = "other";
- break;
- case 1:
- subtype = "Processor";
- break;
- case 2:
- subtype = "DSP";
- break;
- case 3:
- subtype = "Engine/Coprocessor";
- break;
- case 4:
- subtype = "Bus";
- break;
- }
- break;
- case 4:
- major = "Debug Control";
- switch (minor) {
- case 0:
- subtype = "other";
- break;
- case 1:
- subtype = "Trigger Matrix";
- break;
- case 2:
- subtype = "Debug Auth";
- break;
- }
- break;
- case 5:
- major = "Debug Logic";
- switch (minor) {
- case 0:
- subtype = "other";
- break;
- case 1:
- subtype = "Processor";
- break;
- case 2:
- subtype = "DSP";
- break;
- case 3:
- subtype = "Engine/Coprocessor";
- break;
- }
- break;
- }
- command_print(cmd_ctx, "\t\tType is 0x%2.2x, %s, %s",
- (unsigned) (devtype & 0xff),
- major, subtype);
- /* REVISIT also show 0xfc8 DevId */
- }
-
- if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
- command_print(cmd_ctx,
- "\t\tCID3 0%2.2x"
- ", CID2 0%2.2x"
- ", CID1 0%2.2x"
- ", CID0 0%2.2x",
- (int) c_cid3,
- (int) c_cid2,
- (int)c_cid1,
- (int)c_cid0);
- command_print(cmd_ctx,
- "\t\tPeripheral ID[4..0] = hex "
- "%2.2x %2.2x %2.2x %2.2x %2.2x",
- (int) c_pid4, (int) c_pid3, (int) c_pid2,
- (int) c_pid1, (int) c_pid0);
-
- /* Part number interpretations are from Cortex
- * core specs, the CoreSight components TRM
- * (ARM DDI 0314H), CoreSight System Design
- * Guide (ARM DGI 0012D) and ETM specs; also
- * from chip observation (e.g. TI SDTI).
- */
- part_num = (c_pid0 & 0xff);
- part_num |= (c_pid1 & 0x0f) << 8;
- switch (part_num) {
- case 0x000:
- type = "Cortex-M3 NVIC";
- full = "(Interrupt Controller)";
- break;
- case 0x001:
- type = "Cortex-M3 ITM";
- full = "(Instrumentation Trace Module)";
- break;
- case 0x002:
- type = "Cortex-M3 DWT";
- full = "(Data Watchpoint and Trace)";
- break;
- case 0x003:
- type = "Cortex-M3 FBP";
- full = "(Flash Patch and Breakpoint)";
- break;
- case 0x00c:
- type = "Cortex-M4 SCS";
- full = "(System Control Space)";
- break;
- case 0x00d:
- type = "CoreSight ETM11";
- full = "(Embedded Trace)";
- break;
- /* case 0x113: what? */
- case 0x120: /* from OMAP3 memmap */
- type = "TI SDTI";
- full = "(System Debug Trace Interface)";
- break;
- case 0x343: /* from OMAP3 memmap */
- type = "TI DAPCTL";
- full = "";
- break;
- case 0x906:
- type = "Coresight CTI";
- full = "(Cross Trigger)";
- break;
- case 0x907:
- type = "Coresight ETB";
- full = "(Trace Buffer)";
- break;
- case 0x908:
- type = "Coresight CSTF";
- full = "(Trace Funnel)";
- break;
- case 0x910:
- type = "CoreSight ETM9";
- full = "(Embedded Trace)";
- break;
- case 0x912:
- type = "Coresight TPIU";
- full = "(Trace Port Interface Unit)";
- break;
- case 0x921:
- type = "Cortex-A8 ETM";
- full = "(Embedded Trace)";
- break;
- case 0x922:
- type = "Cortex-A8 CTI";
- full = "(Cross Trigger)";
- break;
- case 0x923:
- type = "Cortex-M3 TPIU";
- full = "(Trace Port Interface Unit)";
- break;
- case 0x924:
- type = "Cortex-M3 ETM";
- full = "(Embedded Trace)";
- break;
- case 0x925:
- type = "Cortex-M4 ETM";
- full = "(Embedded Trace)";
- break;
- case 0x930:
- type = "Cortex-R4 ETM";
- full = "(Embedded Trace)";
- break;
- case 0x9a1:
- type = "Cortex-M4 TPUI";
- full = "(Trace Port Interface Unit)";
- break;
- case 0xc08:
- type = "Cortex-A8 Debug";
- full = "(Debug Unit)";
- break;
- default:
- type = "-*- unrecognized -*-";
- full = "";
- break;
- }
- command_print(cmd_ctx, "\t\tPart is %s %s",
- type, full);
- } else {
- if (romentry)
- command_print(cmd_ctx, "\t\tComponent not present");
- else
- command_print(cmd_ctx, "\t\tEnd of ROM table");
- }
- entry_offset += 4;
- } while (romentry > 0);
+ dap_rom_display(cmd_ctx, dap, ap, dbgbase, 0);
} else
command_print(cmd_ctx, "\tNo ROM table present");
dap_ap_select(dap, ap_old);
return retval;
}
+COMMAND_HANDLER(dap_ti_be_32_quirks_command)
+{
+ struct target *target = get_current_target(CMD_CTX);
+ struct arm *arm = target_to_arm(target);
+ struct adiv5_dap *dap = arm->dap;
+
+ uint32_t enable = dap->ti_be_32_quirks;
+
+ switch (CMD_ARGC) {
+ case 0:
+ break;
+ case 1:
+ COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], enable);
+ if (enable > 1)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ break;
+ default:
+ return ERROR_COMMAND_SYNTAX_ERROR;
+ }
+ dap->ti_be_32_quirks = enable;
+ command_print(CMD_CTX, "TI BE-32 quirks mode %s",
+ enable ? "enabled" : "disabled");
+
+ return 0;
+}
+
static const struct command_registration dap_commands[] = {
{
.name = "info",
"bus access [0-255]",
.usage = "[cycles]",
},
+ {
+ .name = "ti_be_32_quirks",
+ .handler = dap_ti_be_32_quirks_command,
+ .mode = COMMAND_CONFIG,
+ .help = "set/get quirks mode for TI TMS450/TMS570 processors",
+ .usage = "[enable]",
+ },
COMMAND_REGISTRATION_DONE
};