From 3f4bc6ce7f5c5a619590c3cc05a74d6bff6a124f Mon Sep 17 00:00:00 2001 From: Antonio Borneo Date: Sat, 14 Aug 2021 23:56:12 +0200 Subject: [PATCH] adiv6: use struct adiv5_ap->ap_num to contain the AP base address ADIv5 DAP can only have 256 AP, while ADIv6 can provide till 2**40 (1,099,511,627,776) AP per DAP. Reuse the field ap_num in struct adiv5_ap, currently used on ADIv5 to hold the ADIv5 AP number (apsel), to contain the ADIv6 AP base address. Convert struct adiv5_ap->ap_num to 64 bit and initialize it to DP_APSEL_INVALID for unused AP. Restrict dap_find_get_ap() to ADIv5 only. To be enhanced. On ADIv6, let dap_get_ap() return an already allocated AP, or allocate and return an unused AP. Add function is_ap_num_valid() and use it. Change-Id: Ib2fe8c7ec0d08393cd91c29fdac5d632dfc1e438 Signed-off-by: Antonio Borneo Reviewed-on: https://review.openocd.org/c/openocd/+/6461 Reviewed-by: Daniel Goehring Tested-by: jenkins --- doc/openocd.texi | 27 +++++-- src/jtag/drivers/stlink_usb.c | 11 +-- src/target/arm_adi_v5.c | 136 ++++++++++++++++++++++++---------- src/target/arm_adi_v5.h | 27 ++++--- src/target/arm_dap.c | 8 +- src/target/arm_tpiu_swo.c | 14 ++-- src/target/cortex_m.h | 2 +- src/target/hla_target.c | 2 +- src/target/mem_ap.c | 2 +- 9 files changed, 156 insertions(+), 73 deletions(-) diff --git a/doc/openocd.texi b/doc/openocd.texi index e8535b7a14..0398e2fb4e 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -4680,6 +4680,8 @@ for TCL scripting. @deffn {Command} {dap info} [num] Displays the ROM table for MEM-AP @var{num}, defaulting to the currently selected AP of the currently selected target. +On ADIv5 DAP @var{num} is the numeric index of the AP. +On ADIv6 DAP @var{num} is the base address of the AP. @end deffn @deffn {Command} {dap init} @@ -4693,21 +4695,29 @@ The following commands exist as subcommands of DAP instances: @deffn {Command} {$dap_name info} [num] Displays the ROM table for MEM-AP @var{num}, defaulting to the currently selected AP. +On ADIv5 DAP @var{num} is the numeric index of the AP. +On ADIv6 DAP @var{num} is the base address of the AP. @end deffn @deffn {Command} {$dap_name apid} [num] Displays ID register from AP @var{num}, defaulting to the currently selected AP. +On ADIv5 DAP @var{num} is the numeric index of the AP. +On ADIv6 DAP @var{num} is the base address of the AP. @end deffn @anchor{DAP subcommand apreg} @deffn {Command} {$dap_name apreg} ap_num reg [value] Displays content of a register @var{reg} from AP @var{ap_num} or set a new value @var{value}. +On ADIv5 DAP @var{ap_num} is the numeric index of the AP. +On ADIv6 DAP @var{ap_num} is the base address of the AP. @var{reg} is byte address of a word register, 0, 4, 8 ... 0xfc. @end deffn @deffn {Command} {$dap_name apsel} [num] Select AP @var{num}, defaulting to 0. +On ADIv5 DAP @var{num} is the numeric index of the AP. +On ADIv6 DAP @var{num} is the base address of the AP. @end deffn @deffn {Command} {$dap_name dpreg} reg [value] @@ -4725,6 +4735,8 @@ background activity by OpenOCD while you are operating at such low-level. @deffn {Command} {$dap_name baseaddr} [num] Displays debug base address from MEM-AP @var{num}, defaulting to the currently selected AP. +On ADIv5 DAP @var{num} is the numeric index of the AP. +On ADIv6 DAP @var{num} is the base address of the AP. @end deffn @deffn {Command} {$dap_name memaccess} [value] @@ -5098,8 +5110,9 @@ The value should normally correspond to a static mapping for the scan and after a reset. A manual call to arp_examine is required to access the target for debugging. -@item @code{-ap-num} @var{ap_number} -- set DAP access port for target, -@var{ap_number} is the numeric index of the DAP AP the target is connected to. +@item @code{-ap-num} @var{ap_number} -- set DAP access port for target. +On ADIv5 DAP @var{ap_number} is the numeric index of the DAP AP the target is connected to. +On ADIv6 DAP @var{ap_number} is the base address of the DAP AP the target is connected to. Use this option with systems where multiple, independent cores are connected to separate access ports of the same DAP. @@ -9449,7 +9462,10 @@ the @emph{cti} group of commands. @deffn {Command} {cti create} cti_name @option{-dap} dap_name @option{-ap-num} apn @option{-baseaddr} base_address Creates a CTI instance @var{cti_name} on the DAP instance @var{dap_name} on MEM-AP -@var{apn}. The @var{base_address} must match the base address of the CTI +@var{apn}. +On ADIv5 DAP @var{apn} is the numeric index of the DAP AP the CTI is connected to. +On ADIv6 DAP @var{apn} is the base address of the DAP AP the CTI is connected to. +The @var{base_address} must match the base address of the CTI on the respective MEM-AP. All arguments are mandatory. This creates a new command @command{$cti_name} which is used for various purposes including additional configuration. @@ -10114,8 +10130,9 @@ using the @command{$tpiu_name cget} command. @item @code{-dap} @var{dap_name} -- names the DAP used to access this TPIU. @xref{dapdeclaration,,DAP declaration}, on how to create and manage DAP instances. -@item @code{-ap-num} @var{ap_number} -- sets DAP access port for TPIU, -@var{ap_number} is the numeric index of the DAP AP the TPIU is connected to. +@item @code{-ap-num} @var{ap_number} -- sets DAP access port for TPIU. +On ADIv5 DAP @var{ap_number} is the numeric index of the DAP AP the TPIU is connected to. +On ADIv6 DAP @var{ap_number} is the base address of the DAP AP the TPIU is connected to. @item @code{-baseaddr} @var{base_address} -- sets the TPIU @var{base_address} where to access the TPIU in the DAP AP memory space. diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c index 8a9028bd1e..046d29776f 100644 --- a/src/jtag/drivers/stlink_usb.c +++ b/src/jtag/drivers/stlink_usb.c @@ -4152,7 +4152,7 @@ static int stlink_dap_reinit_interface(void) stlink_dap_handle->reconnect_pending = false; /* on new FW, calling mode-leave closes all the opened AP; reopen them! */ if (stlink_dap_handle->version.flags & STLINK_F_HAS_AP_INIT) - for (int apsel = 0; apsel <= DP_APSEL_MAX; apsel++) + for (unsigned int apsel = 0; apsel <= DP_APSEL_MAX; apsel++) if (test_bit(apsel, opened_ap)) { clear_bit(apsel, opened_ap); stlink_dap_open_ap(apsel); @@ -4348,7 +4348,7 @@ static int stlink_usb_misc_rw_segment(void *handle, const struct dap_queue *q, u LOG_DEBUG("Queue: %u commands in %u items", len, items); - int ap_num = DP_APSEL_INVALID; + uint32_t ap_num = DP_APSEL_INVALID; unsigned int cmd_index = 0; unsigned int val_index = ALIGN_UP(items, 4); for (unsigned int i = 0; i < len; i++) { @@ -4497,7 +4497,7 @@ static int stlink_usb_count_misc_rw_queue(void *handle, const struct dap_queue * { struct stlink_usb_handle_s *h = handle; unsigned int i, items = 0; - int ap_num = DP_APSEL_INVALID; + uint32_t ap_num = DP_APSEL_INVALID; unsigned int misc_max_items = (h->version.stlink == 2) ? STLINK_V2_RW_MISC_SIZE : STLINK_V3_RW_MISC_SIZE; if (!(h->version.flags & STLINK_F_HAS_RW_MISC)) @@ -4864,9 +4864,10 @@ static int stlink_dap_op_queue_ap_write(struct adiv5_ap *ap, unsigned int reg, q->ap_w.reg = reg; q->ap_w.ap = ap; q->ap_w.data = data; - if (reg == ADIV5_MEM_AP_REG_CSW && ap->csw_default != last_csw_default[ap->ap_num]) { + uint8_t ap_num = ap->ap_num; + if (reg == ADIV5_MEM_AP_REG_CSW && ap->csw_default != last_csw_default[ap_num]) { q->ap_w.changes_csw_default = true; - last_csw_default[ap->ap_num] = ap->csw_default; + last_csw_default[ap_num] = ap->csw_default; } else { q->ap_w.changes_csw_default = false; } diff --git a/src/target/arm_adi_v5.c b/src/target/arm_adi_v5.c index a74e47f794..79f9b8d2bf 100644 --- a/src/target/arm_adi_v5.c +++ b/src/target/arm_adi_v5.c @@ -966,16 +966,45 @@ static const char *ap_type_to_description(enum ap_type type) return "Unknown"; } +bool is_ap_num_valid(struct adiv5_dap *dap, uint64_t ap_num) +{ + if (!dap) + return false; + + /* no autodetection, by now, so uninitialized is equivalent to ADIv5 for + * backward compatibility */ + if (!is_adiv6(dap)) { + if (ap_num > DP_APSEL_MAX) + return false; + return true; + } + + if (is_adiv6(dap)) { + if (ap_num & 0x0fffULL) + return false; + if (dap->asize != 0) + if (ap_num & ((~0ULL) << dap->asize)) + return false; + return true; + } + + return false; +} + /* * This function checks the ID for each access port to find the requested Access Port type * It also calls dap_get_ap() to increment the AP refcount */ int dap_find_get_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_ap **ap_out) { - int ap_num; + if (is_adiv6(dap)) { + /* TODO: scan the ROM table and detect the AP available */ + LOG_DEBUG("On ADIv6 we cannot scan all the possible AP"); + return ERROR_FAIL; + } /* Maximum AP number is 255 since the SELECT register is 8 bits */ - for (ap_num = 0; ap_num <= DP_APSEL_MAX; ap_num++) { + for (unsigned int ap_num = 0; ap_num <= DP_APSEL_MAX; ap_num++) { struct adiv5_ap *ap = dap_get_ap(dap, ap_num); if (!ap) continue; @@ -1014,33 +1043,55 @@ static inline bool is_ap_in_use(struct adiv5_ap *ap) return ap->refcount > 0 || ap->config_ap_never_release; } -static struct adiv5_ap *_dap_get_ap(struct adiv5_dap *dap, unsigned int ap_num) +static struct adiv5_ap *_dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num) { - if (ap_num > DP_APSEL_MAX) { - LOG_ERROR("Invalid AP#%u", ap_num); + if (!is_ap_num_valid(dap, ap_num)) { + LOG_ERROR("Invalid AP#0x%" PRIx64, ap_num); return NULL; } + if (is_adiv6(dap)) { + for (unsigned int i = 0; i <= DP_APSEL_MAX; i++) { + struct adiv5_ap *ap = &dap->ap[i]; + if (is_ap_in_use(ap) && ap->ap_num == ap_num) { + ++ap->refcount; + return ap; + } + } + for (unsigned int i = 0; i <= DP_APSEL_MAX; i++) { + struct adiv5_ap *ap = &dap->ap[i]; + if (!is_ap_in_use(ap)) { + ap->ap_num = ap_num; + ++ap->refcount; + return ap; + } + } + LOG_ERROR("No more AP available!"); + return NULL; + } + + /* ADIv5 */ struct adiv5_ap *ap = &dap->ap[ap_num]; + ap->ap_num = ap_num; ++ap->refcount; return ap; } /* Return AP with specified ap_num. Increment AP refcount */ -struct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, unsigned int ap_num) +struct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num) { struct adiv5_ap *ap = _dap_get_ap(dap, ap_num); if (ap) - LOG_DEBUG("refcount AP#%u get %u", ap_num, ap->refcount); + LOG_DEBUG("refcount AP#0x%" PRIx64 " get %u", ap_num, ap->refcount); return ap; } /* Return AP with specified ap_num. Increment AP refcount and keep it non-zero */ -struct adiv5_ap *dap_get_config_ap(struct adiv5_dap *dap, unsigned int ap_num) +struct adiv5_ap *dap_get_config_ap(struct adiv5_dap *dap, uint64_t ap_num) { struct adiv5_ap *ap = _dap_get_ap(dap, ap_num); if (ap) { ap->config_ap_never_release = true; - LOG_DEBUG("refcount AP#%u get_config %u", ap_num, ap->refcount); + LOG_DEBUG("refcount AP#0x%" PRIx64 " get_config %u", ap_num, ap->refcount); } return ap; } @@ -1049,15 +1100,16 @@ struct adiv5_ap *dap_get_config_ap(struct adiv5_dap *dap, unsigned int ap_num) int dap_put_ap(struct adiv5_ap *ap) { if (ap->refcount == 0) { - LOG_ERROR("BUG: refcount AP#%" PRIu8 " put underflow", ap->ap_num); + LOG_ERROR("BUG: refcount AP#0x%" PRIx64 " put underflow", ap->ap_num); return ERROR_FAIL; } --ap->refcount; - LOG_DEBUG("refcount AP#%" PRIu8 " put %u", ap->ap_num, ap->refcount); + LOG_DEBUG("refcount AP#0x%" PRIx64 " put %u", ap->ap_num, ap->refcount); if (!is_ap_in_use(ap)) { /* defaults from dap_instance_init() */ + ap->ap_num = DP_APSEL_INVALID; ap->memaccess_tck = 255; ap->tar_autoincr_block = (1 << 10); ap->csw_default = CSW_AHB_DEFAULT; @@ -1756,7 +1808,7 @@ static int dap_info_mem_ap_header(int retval, struct adiv5_ap *ap, command_print(cmd, "AP ID register 0x%8.8" PRIx32, apid); if (apid == 0) { - command_print(cmd, "No AP found at this ap 0x%x", ap->ap_num); + command_print(cmd, "No AP found at this AP#0x%" PRIx64, ap->ap_num); return ERROR_FAIL; } @@ -2000,7 +2052,7 @@ static const struct jim_nvp nvp_config_opts[] = { }; static int adiv5_jim_spot_configure(struct jim_getopt_info *goi, - struct adiv5_dap **dap_p, int *ap_num_p, uint32_t *base_p) + struct adiv5_dap **dap_p, uint64_t *ap_num_p, uint32_t *base_p) { assert(dap_p && ap_num_p); @@ -2055,11 +2107,13 @@ static int adiv5_jim_spot_configure(struct jim_getopt_info *goi, case CFG_AP_NUM: if (goi->isconfigure) { + /* jim_wide is a signed 64 bits int, ap_num is unsigned with max 52 bits */ jim_wide ap_num; e = jim_getopt_wide(goi, &ap_num); if (e != JIM_OK) return e; - if (ap_num < 0 || ap_num > DP_APSEL_MAX) { + /* we still don't know dap->adi_version */ + if (ap_num < 0 || (ap_num > DP_APSEL_MAX && (ap_num & 0xfff))) { Jim_SetResultString(goi->interp, "Invalid AP number!", -1); return JIM_ERR; } @@ -2164,15 +2218,15 @@ int adiv5_mem_ap_spot_init(struct adiv5_mem_ap_spot *p) COMMAND_HANDLER(handle_dap_info_command) { struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); - uint32_t apsel; + uint64_t apsel; switch (CMD_ARGC) { case 0: apsel = dap->apsel; break; case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - if (apsel > DP_APSEL_MAX) { + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel); + if (!is_ap_num_valid(dap, apsel)) { command_print(CMD, "Invalid AP number"); return ERROR_COMMAND_ARGUMENT_INVALID; } @@ -2195,7 +2249,8 @@ COMMAND_HANDLER(handle_dap_info_command) COMMAND_HANDLER(dap_baseaddr_command) { struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); - uint32_t apsel, baseaddr_lower, baseaddr_upper; + uint64_t apsel; + uint32_t baseaddr_lower, baseaddr_upper; struct adiv5_ap *ap; target_addr_t baseaddr; int retval; @@ -2207,9 +2262,8 @@ COMMAND_HANDLER(dap_baseaddr_command) apsel = dap->apsel; break; case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel > DP_APSEL_MAX) { + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel); + if (!is_ap_num_valid(dap, apsel)) { command_print(CMD, "Invalid AP number"); return ERROR_COMMAND_ARGUMENT_INVALID; } @@ -2294,16 +2348,15 @@ COMMAND_HANDLER(dap_memaccess_command) COMMAND_HANDLER(dap_apsel_command) { struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); - uint32_t apsel; + uint64_t apsel; switch (CMD_ARGC) { case 0: - command_print(CMD, "%" PRIu32, dap->apsel); + command_print(CMD, "0x%" PRIx64, dap->apsel); return ERROR_OK; case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel > DP_APSEL_MAX) { + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel); + if (!is_ap_num_valid(dap, apsel)) { command_print(CMD, "Invalid AP number"); return ERROR_COMMAND_ARGUMENT_INVALID; } @@ -2329,7 +2382,7 @@ COMMAND_HANDLER(dap_apcsw_command) command_print(CMD, "Cannot get AP"); return ERROR_FAIL; } - command_print(CMD, "ap %" PRIu32 " selected, csw 0x%8.8" PRIx32, + command_print(CMD, "AP#0x%" PRIx64 " selected, csw 0x%8.8" PRIx32, dap->apsel, ap->csw_default); break; case 1: @@ -2376,7 +2429,8 @@ COMMAND_HANDLER(dap_apcsw_command) COMMAND_HANDLER(dap_apid_command) { struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); - uint32_t apsel, apid; + uint64_t apsel; + uint32_t apid; int retval; switch (CMD_ARGC) { @@ -2384,9 +2438,8 @@ COMMAND_HANDLER(dap_apid_command) apsel = dap->apsel; break; case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel > DP_APSEL_MAX) { + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel); + if (!is_ap_num_valid(dap, apsel)) { command_print(CMD, "Invalid AP number"); return ERROR_COMMAND_ARGUMENT_INVALID; } @@ -2418,23 +2471,30 @@ COMMAND_HANDLER(dap_apid_command) COMMAND_HANDLER(dap_apreg_command) { struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA); - uint32_t apsel, reg, value; + uint64_t apsel; + uint32_t reg, value; int retval; if (CMD_ARGC < 2 || CMD_ARGC > 3) return ERROR_COMMAND_SYNTAX_ERROR; - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - /* AP address is in bits 31:24 of DP_SELECT */ - if (apsel > DP_APSEL_MAX) { + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel); + if (!is_ap_num_valid(dap, apsel)) { command_print(CMD, "Invalid AP number"); return ERROR_COMMAND_ARGUMENT_INVALID; } COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], reg); - if (reg >= 256 || (reg & 3)) { - command_print(CMD, "Invalid reg value (should be less than 256 and 4 bytes aligned)"); - return ERROR_COMMAND_ARGUMENT_INVALID; + if (is_adiv6(dap)) { + if (reg >= 4096 || (reg & 3)) { + command_print(CMD, "Invalid reg value (should be less than 4096 and 4 bytes aligned)"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } + } else { /* ADI version 5 */ + if (reg >= 256 || (reg & 3)) { + command_print(CMD, "Invalid reg value (should be less than 256 and 4 bytes aligned)"); + return ERROR_COMMAND_ARGUMENT_INVALID; + } } struct adiv5_ap *ap = dap_get_ap(dap, apsel); diff --git a/src/target/arm_adi_v5.h b/src/target/arm_adi_v5.h index 4eab35d6ea..534dd3b737 100644 --- a/src/target/arm_adi_v5.h +++ b/src/target/arm_adi_v5.h @@ -110,8 +110,8 @@ #define DP_SELECT_DPBANK 0x0000000F #define DP_SELECT_INVALID 0x00FFFF00 /* Reserved bits one */ -#define DP_APSEL_MAX (255) -#define DP_APSEL_INVALID (-1) +#define DP_APSEL_MAX (255) /* for ADIv5 only */ +#define DP_APSEL_INVALID 0xF00 /* more than DP_APSEL_MAX and not ADIv6 aligned 4k */ #define DP_TARGETSEL_INVALID 0xFFFFFFFFU #define DP_TARGETSEL_DPID_MASK 0x0FFFFFFFU @@ -255,9 +255,11 @@ struct adiv5_ap { struct adiv5_dap *dap; /** - * Number of this AP. + * ADIv5: Number of this AP (0~255) + * ADIv6: Base address of this AP (4k aligned) + * TODO: to be more coherent, it should be renamed apsel */ - uint8_t ap_num; + uint64_t ap_num; /** * Default value for (MEM-AP) AP_REG_CSW register. @@ -342,7 +344,7 @@ struct adiv5_dap { struct adiv5_ap ap[DP_APSEL_MAX + 1]; /* The current manually selected AP by the "dap apsel" command */ - uint32_t apsel; + uint64_t apsel; /** * Cache for DP_SELECT register. A value of DP_SELECT_INVALID @@ -551,7 +553,7 @@ static inline int dap_queue_ap_read(struct adiv5_ap *ap, assert(ap->dap->ops); if (ap->refcount == 0) { ap->refcount = 1; - LOG_ERROR("BUG: refcount AP#%" PRIu8 " used without get", ap->ap_num); + LOG_ERROR("BUG: refcount AP#0x%" PRIx64 " used without get", ap->ap_num); } return ap->dap->ops->queue_ap_read(ap, reg, data); } @@ -571,7 +573,7 @@ static inline int dap_queue_ap_write(struct adiv5_ap *ap, assert(ap->dap->ops); if (ap->refcount == 0) { ap->refcount = 1; - LOG_ERROR("BUG: refcount AP#%" PRIu8 " used without get", ap->ap_num); + LOG_ERROR("BUG: refcount AP#0x%" PRIx64 " used without get", ap->ap_num); } return ap->dap->ops->queue_ap_write(ap, reg, data); } @@ -690,16 +692,19 @@ int mem_ap_init(struct adiv5_ap *ap); /* Invalidate cached DP select and cached TAR and CSW of all APs */ void dap_invalidate_cache(struct adiv5_dap *dap); +/* test if ap_num is valid, based on current knowledge of dap */ +bool is_ap_num_valid(struct adiv5_dap *dap, uint64_t ap_num); + /* Probe Access Ports to find a particular type. Increment AP refcount */ int dap_find_get_ap(struct adiv5_dap *dap, enum ap_type type_to_find, struct adiv5_ap **ap_out); /* Return AP with specified ap_num. Increment AP refcount */ -struct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, unsigned int ap_num); +struct adiv5_ap *dap_get_ap(struct adiv5_dap *dap, uint64_t ap_num); /* Return AP with specified ap_num. Increment AP refcount and keep it non-zero */ -struct adiv5_ap *dap_get_config_ap(struct adiv5_dap *dap, unsigned int ap_num); +struct adiv5_ap *dap_get_config_ap(struct adiv5_dap *dap, uint64_t ap_num); /* Decrement AP refcount and release the AP when refcount reaches zero */ int dap_put_ap(struct adiv5_ap *ap); @@ -735,7 +740,7 @@ extern const struct swd_driver *adiv5_dap_swd_driver(struct adiv5_dap *self); extern int dap_cleanup_all(void); struct adiv5_private_config { - int ap_num; + uint64_t ap_num; struct adiv5_dap *dap; }; @@ -744,7 +749,7 @@ extern int adiv5_jim_configure(struct target *target, struct jim_getopt_info *go struct adiv5_mem_ap_spot { struct adiv5_dap *dap; - int ap_num; + uint64_t ap_num; uint32_t base; }; diff --git a/src/target/arm_dap.c b/src/target/arm_dap.c index d2e3f99972..cfd14de936 100644 --- a/src/target/arm_dap.c +++ b/src/target/arm_dap.c @@ -50,7 +50,7 @@ static void dap_instance_init(struct adiv5_dap *dap) /* Set up with safe defaults */ for (i = 0; i <= DP_APSEL_MAX; i++) { dap->ap[i].dap = dap; - dap->ap[i].ap_num = i; + dap->ap[i].ap_num = DP_APSEL_INVALID; /* memaccess_tck max is 255 */ dap->ap[i].memaccess_tck = 255; /* Number of bits for tar autoincrement, impl. dep. at least 10 */ @@ -459,7 +459,7 @@ COMMAND_HANDLER(handle_dap_info_command) struct target *target = get_current_target(CMD_CTX); struct arm *arm = target_to_arm(target); struct adiv5_dap *dap = arm->dap; - uint32_t apsel; + uint64_t apsel; if (!dap) { LOG_ERROR("DAP instance not available. Probably a HLA target..."); @@ -471,8 +471,8 @@ COMMAND_HANDLER(handle_dap_info_command) apsel = dap->apsel; break; case 1: - COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], apsel); - if (apsel > DP_APSEL_MAX) + COMMAND_PARSE_NUMBER(u64, CMD_ARGV[0], apsel); + if (!is_ap_num_valid(dap, apsel)) return ERROR_COMMAND_SYNTAX_ERROR; break; default: diff --git a/src/target/arm_tpiu_swo.c b/src/target/arm_tpiu_swo.c index 5cbd89b86b..a9f558e124 100644 --- a/src/target/arm_tpiu_swo.c +++ b/src/target/arm_tpiu_swo.c @@ -617,8 +617,8 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const if (obj->enabled) return JIM_OK; - if (transport_is_hla() && obj->spot.ap_num > 0) { - LOG_ERROR("Invalid access port %d. Only AP#0 allowed with hla transport", obj->spot.ap_num); + if (transport_is_hla() && obj->spot.ap_num != 0) { + LOG_ERROR("Invalid access port 0x%" PRIx64 ". Only AP#0 allowed with hla transport", obj->spot.ap_num); return JIM_ERR; } @@ -650,8 +650,8 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const if (obj->spot.ap_num == 0) LOG_INFO(MSG "Confirmed TPIU %s is on AP 0", obj->name); else - LOG_INFO(MSG "Target %s is on AP %d. Revised command is " - "\'tpiu create %s -dap %s -ap-num %d\'", + LOG_INFO(MSG "Target %s is on AP#0x%" PRIx64 ". Revised command is " + "\'tpiu create %s -dap %s -ap-num 0x%" PRIx64 "\'", target_name(target), obj->spot.ap_num, obj->name, adiv5_dap_name(obj->spot.dap), obj->spot.ap_num); } @@ -1047,7 +1047,7 @@ COMMAND_HANDLER(handle_tpiu_deprecated_config_command) struct cortex_m_common *cm = target_to_cm(target); struct adiv5_private_config *pc = target->private_config; struct adiv5_dap *dap = pc->dap; - int ap_num = pc->ap_num; + uint64_t ap_num = pc->ap_num; bool set_recheck_ap_cur_target = false; LOG_INFO(MSG "Adding a TPIU \'%s.tpiu\' in the configuration", target_name(target)); @@ -1065,10 +1065,10 @@ COMMAND_HANDLER(handle_tpiu_deprecated_config_command) set_recheck_ap_cur_target = true; } - LOG_INFO(MSG "Running: \'tpiu create %s.tpiu -dap %s -ap-num %d\'", + LOG_INFO(MSG "Running: \'tpiu create %s.tpiu -dap %s -ap-num 0x%" PRIx64 "\'", target_name(target), adiv5_dap_name(dap), ap_num); - retval = command_run_linef(CMD_CTX, "tpiu create %s.tpiu -dap %s -ap-num %d", + retval = command_run_linef(CMD_CTX, "tpiu create %s.tpiu -dap %s -ap-num 0x%" PRIx64, target_name(target), adiv5_dap_name(dap), ap_num); if (retval != ERROR_OK) return retval; diff --git a/src/target/cortex_m.h b/src/target/cortex_m.h index 5554014162..1fab871e12 100644 --- a/src/target/cortex_m.h +++ b/src/target/cortex_m.h @@ -241,7 +241,7 @@ struct cortex_m_common { bool slow_register_read; /* A register has not been ready, poll S_REGRDY */ - int apsel; + uint64_t apsel; /* Whether this target has the erratum that makes C_MASKINTS not apply to * already pending interrupts */ diff --git a/src/target/hla_target.c b/src/target/hla_target.c index 3e359b950e..487ffe7c99 100644 --- a/src/target/hla_target.c +++ b/src/target/hla_target.c @@ -203,7 +203,7 @@ static int adapter_target_create(struct target *target, { LOG_DEBUG("%s", __func__); struct adiv5_private_config *pc = target->private_config; - if (pc && pc->ap_num > 0) { + if (pc && pc->ap_num != DP_APSEL_INVALID && pc->ap_num != 0) { LOG_ERROR("hla_target: invalid parameter -ap-num (> 0)"); return ERROR_COMMAND_SYNTAX_ERROR; } diff --git a/src/target/mem_ap.c b/src/target/mem_ap.c index 86bb29f212..cf5aa54497 100644 --- a/src/target/mem_ap.c +++ b/src/target/mem_ap.c @@ -29,7 +29,7 @@ struct mem_ap { int common_magic; struct adiv5_dap *dap; struct adiv5_ap *ap; - int ap_num; + uint64_t ap_num; }; static int mem_ap_target_create(struct target *target, Jim_Interp *interp) -- 2.30.2