X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Farm_adi_v5.c;h=6efc0af13fdfb762fe6b3813d1e5ef0a02adb5bf;hp=a28bc154485e568fb5eadb8b9c938e73e9732f4d;hb=2f131d3c3004658e891b674e9a8ac93bae5246b0;hpb=e7d165f3dbff0fbe11f458becdccbb3d4fa8ccc4 diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index a28bc15448..6efc0af13f 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -94,28 +94,6 @@ static uint32_t max_tar_block_size(uint32_t tar_autoincr_block, uint32_t address * * ***************************************************************************/ -/** - * 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 | @@ -123,7 +101,7 @@ static int mem_ap_setup_csw(struct adiv5_ap *ap, uint32_t csw) 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; @@ -136,7 +114,7 @@ static int mem_ap_setup_tar(struct adiv5_ap *ap, uint32_t tar) 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; @@ -189,8 +167,6 @@ int mem_ap_read_u32(struct adiv5_ap *ap, uint32_t address, { int retval; - dap_ap_select(ap->dap, ap->ap_num); - /* Use banked addressing (REG_BDx) to avoid some link traffic * (updating TAR) when reading several consecutive addresses. */ @@ -199,7 +175,7 @@ int mem_ap_read_u32(struct adiv5_ap *ap, uint32_t address, 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); } /** @@ -242,8 +218,6 @@ int mem_ap_write_u32(struct adiv5_ap *ap, uint32_t address, { int retval; - dap_ap_select(ap->dap, ap->ap_num); - /* Use banked addressing (REG_BDx) to avoid some link traffic * (updating TAR) when writing several consecutive addresses. */ @@ -252,7 +226,7 @@ int mem_ap_write_u32(struct adiv5_ap *ap, uint32_t address, 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); } @@ -329,8 +303,6 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t siz if (ap->unaligned_access_bad && (address % size != 0)) return ERROR_TARGET_UNALIGNED_ACCESS; - dap_ap_select(ap->dap, ap->ap_num); - retval = mem_ap_setup_tar(ap, address ^ addr_xor); if (retval != ERROR_OK) return retval; @@ -383,7 +355,7 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t siz 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; @@ -401,7 +373,7 @@ static int mem_ap_write(struct adiv5_ap *ap, const uint8_t *buffer, uint32_t siz 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 @@ -462,8 +434,6 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint return ERROR_FAIL; } - dap_ap_select(ap->dap, ap->ap_num); - retval = mem_ap_setup_tar(ap, address); if (retval != ERROR_OK) { free(read_buf); @@ -487,7 +457,7 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint 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; @@ -514,7 +484,7 @@ static int mem_ap_read(struct adiv5_ap *ap, uint8_t *buffer, uint32_t size, uint * 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) @@ -616,9 +586,6 @@ struct adiv5_dap *dap_init(void) /* 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; } @@ -641,15 +608,12 @@ int dap_dp_init(struct adiv5_dap *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; @@ -719,17 +683,15 @@ int mem_ap_init(struct adiv5_ap *ap) 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; @@ -793,9 +755,8 @@ int dap_find_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_a /* 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; @@ -844,12 +805,10 @@ int dap_get_debugbase(struct adiv5_ap *ap, struct adiv5_dap *dap = ap->dap; int retval; - 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); @@ -915,6 +874,86 @@ int dap_lookup_cs_component(struct adiv5_ap *ap, return ERROR_OK; } +/* The designer identity code is encoded as: + * bits 11:8 : JEP106 Bank (number of continuation codes), only valid when bit 7 is 1. + * bit 7 : Set when bits 6:0 represent a JEP106 ID and cleared when bits 6:0 represent + * a legacy ASCII Identity Code. + * bits 6:0 : JEP106 Identity Code (without parity) or legacy ASCII code according to bit 7. + * JEP106 is a standard available from jedec.org + */ + +/* 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). + */ + +/* The legacy code only used the part number field to identify CoreSight peripherals. + * This meant that the same part number from two different manufacturers looked the same. + * It is desirable for all future additions to identify with both part number and JEP106. + * "ANY_ID" is a wildcard (any JEP106) only to preserve legacy behavior for legacy entries. + */ + +#define ANY_ID 0x1000 + +#define ARM_ID 0x4BB + +static const struct { + uint16_t designer_id; + uint16_t part_num; + const char *type; + const char *full; +} dap_partnums[] = { + { ARM_ID, 0x000, "Cortex-M3 SCS", "(System Control Space)", }, + { ARM_ID, 0x001, "Cortex-M3 ITM", "(Instrumentation Trace Module)", }, + { ARM_ID, 0x002, "Cortex-M3 DWT", "(Data Watchpoint and Trace)", }, + { ARM_ID, 0x003, "Cortex-M3 FBP", "(Flash Patch and Breakpoint)", }, + { ARM_ID, 0x008, "Cortex-M0 SCS", "(System Control Space)", }, + { ARM_ID, 0x00a, "Cortex-M0 DWT", "(Data Watchpoint and Trace)", }, + { ARM_ID, 0x00b, "Cortex-M0 BPU", "(Breakpoint Unit)", }, + { ARM_ID, 0x00c, "Cortex-M4 SCS", "(System Control Space)", }, + { ARM_ID, 0x00d, "CoreSight ETM11", "(Embedded Trace)", }, + { ARM_ID, 0x490, "Cortex-A15 GIC", "(Generic Interrupt Controller)", }, + { ARM_ID, 0x4c7, "Cortex-M7 PPB", "(Private Peripheral Bus ROM Table)", }, + { ARM_ID, 0x906, "CoreSight CTI", "(Cross Trigger)", }, + { ARM_ID, 0x907, "CoreSight ETB", "(Trace Buffer)", }, + { ARM_ID, 0x908, "CoreSight CSTF", "(Trace Funnel)", }, + { ARM_ID, 0x910, "CoreSight ETM9", "(Embedded Trace)", }, + { ARM_ID, 0x912, "CoreSight TPIU", "(Trace Port Interface Unit)", }, + { ARM_ID, 0x913, "CoreSight ITM", "(Instrumentation Trace Macrocell)", }, + { ARM_ID, 0x914, "CoreSight SWO", "(Single Wire Output)", }, + { ARM_ID, 0x917, "CoreSight HTM", "(AHB Trace Macrocell)", }, + { ARM_ID, 0x920, "CoreSight ETM11", "(Embedded Trace)", }, + { ARM_ID, 0x921, "Cortex-A8 ETM", "(Embedded Trace)", }, + { ARM_ID, 0x922, "Cortex-A8 CTI", "(Cross Trigger)", }, + { ARM_ID, 0x923, "Cortex-M3 TPIU", "(Trace Port Interface Unit)", }, + { ARM_ID, 0x924, "Cortex-M3 ETM", "(Embedded Trace)", }, + { ARM_ID, 0x925, "Cortex-M4 ETM", "(Embedded Trace)", }, + { ARM_ID, 0x930, "Cortex-R4 ETM", "(Embedded Trace)", }, + { ARM_ID, 0x941, "CoreSight TPIU-Lite", "(Trace Port Interface Unit)", }, + { ARM_ID, 0x950, "CoreSight Component", "(unidentified Cortex-A9 component)", }, + { ARM_ID, 0x955, "CoreSight Component", "(unidentified Cortex-A5 component)", }, + { ARM_ID, 0x95f, "Cortex-A15 PTM", "(Program Trace Macrocell)", }, + { ARM_ID, 0x961, "CoreSight TMC", "(Trace Memory Controller)", }, + { ARM_ID, 0x962, "CoreSight STM", "(System Trace Macrocell)", }, + { ARM_ID, 0x9a0, "CoreSight PMU", "(Performance Monitoring Unit)", }, + { ARM_ID, 0x9a1, "Cortex-M4 TPIU", "(Trace Port Interface Unit)", }, + { ARM_ID, 0x9a5, "Cortex-A5 ETM", "(Embedded Trace)", }, + { ARM_ID, 0x9a7, "Cortex-A7 PMU", "(Performance Monitor Unit)", }, + { ARM_ID, 0x9af, "Cortex-A15 PMU", "(Performance Monitor Unit)", }, + { ARM_ID, 0xc05, "Cortex-A5 Debug", "(Debug Unit)", }, + { ARM_ID, 0xc07, "Cortex-A7 Debug", "(Debug Unit)", }, + { ARM_ID, 0xc08, "Cortex-A8 Debug", "(Debug Unit)", }, + { ARM_ID, 0xc09, "Cortex-A9 Debug", "(Debug Unit)", }, + { ARM_ID, 0xc0f, "Cortex-A15 Debug", "(Debug Unit)", }, + { ARM_ID, 0xc14, "Cortex-R4 Debug", "(Debug Unit)", }, + { 0x0E5, 0x000, "SHARC+/Blackfin+", "", }, + /* legacy comment: 0x113: what? */ + { ANY_ID, 0x120, "TI SDTI", "(System Debug Trace Interface)", }, /* from OMAP3 memmap */ + { ANY_ID, 0x343, "TI DAPCTL", "", }, /* from OMAP3 memmap */ +}; + static int dap_rom_display(struct command_context *cmd_ctx, struct adiv5_ap *ap, uint32_t dbgbase, int depth) { @@ -982,7 +1021,7 @@ static int dap_rom_display(struct command_context *cmd_ctx, 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; - uint32_t part_num; + uint16_t part_num, designer_id; const char *type, *full; component_base = (dbgbase & 0xFFFFF000) + (romentry & 0xFFFFF000); @@ -1205,168 +1244,42 @@ static int dap_rom_display(struct command_context *cmd_ctx, (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 0x008: - type = "Cortex-M0 SCS"; - full = "(System Control Space)"; - break; - case 0x00a: - type = "Cortex-M0 DWT"; - full = "(Data Watchpoint and Trace)"; - break; - case 0x00b: - type = "Cortex-M0 BPU"; - full = "(Breakpoint Unit)"; - 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 0x914: - type = "Coresight SWO"; - full = "(Single Wire Output)"; - break; - case 0x917: - type = "Coresight HTM"; - full = "(AHB Trace Macrocell)"; - break; - case 0x920: - type = "CoreSight ETM11"; - full = "(Embedded Trace)"; - 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 0x961: - type = "CoreSight TMC"; - full = "(Trace Memory Controller)"; - break; - case 0x962: - type = "CoreSight STM"; - full = "(System Trace Macrocell)"; - break; - case 0x9a0: - type = "CoreSight PMU"; - full = "(Performance Monitoring Unit)"; - break; - case 0x9a1: - type = "Cortex-M4 TPUI"; - full = "(Trace Port Interface Unit)"; - break; - case 0x9a5: - type = "Cortex-A5 ETM"; - full = "(Embedded Trace)"; - break; - case 0xc05: - type = "Cortex-A5 Debug"; - full = "(Debug Unit)"; - break; - case 0xc08: - type = "Cortex-A8 Debug"; - full = "(Debug Unit)"; - break; - case 0xc09: - type = "Cortex-A9 Debug"; - full = "(Debug Unit)"; - break; - case 0x4af: - type = "Cortex-A15 Debug"; - full = "(Debug Unit)"; - break; - default: - LOG_DEBUG("Unrecognized Part number 0x%" PRIx32, part_num); - type = "-*- unrecognized -*-"; - full = ""; + designer_id = (c_pid1 & 0xf0) >> 4; + designer_id |= (c_pid2 & 0x0f) << 4; + designer_id |= (c_pid4 & 0x0f) << 8; + if ((designer_id & 0x80) == 0) { + /* Legacy ASCII ID, clear invalid bits */ + designer_id &= 0x7f; + } + + /* default values to be overwritten upon finding a match */ + type = NULL; + full = ""; + + /* search dap_partnums[] array for a match */ + unsigned entry; + for (entry = 0; entry < ARRAY_SIZE(dap_partnums); entry++) { + + if ((dap_partnums[entry].designer_id != designer_id) && (dap_partnums[entry].designer_id != ANY_ID)) + continue; + + if (dap_partnums[entry].part_num != part_num) + continue; + + type = dap_partnums[entry].type; + full = dap_partnums[entry].full; break; } - command_print(cmd_ctx, "\t\tPart is %s %s", - type, full); + + if (type) { + command_print(cmd_ctx, "\t\tPart is %s %s", + type, full); + } else { + command_print(cmd_ctx, "\t\tUnrecognized (Part 0x%" PRIx16 ", designer 0x%" PRIx16 ")", + part_num, designer_id); + } /* ROM Table? */ if (((c_cid1 >> 4) & 0x0f) == 1) { @@ -1485,14 +1398,12 @@ COMMAND_HANDLER(dap_baseaddr_command) 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); @@ -1541,7 +1452,7 @@ COMMAND_HANDLER(dap_apsel_command) switch (CMD_ARGC) { case 0: - apsel = 0; + apsel = dap->apsel; break; case 1: COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); @@ -1554,9 +1465,8 @@ COMMAND_HANDLER(dap_apsel_command) } 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); @@ -1625,9 +1535,7 @@ COMMAND_HANDLER(dap_apid_command) 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);