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 <borneo.antonio@gmail.com>
Reviewed-on: https://review.openocd.org/c/openocd/+/6461
Reviewed-by: Daniel Goehring <dgoehrin@os.amperecomputing.com>
Tested-by: jenkins
This commit is contained in:
Antonio Borneo 2021-08-14 23:56:12 +02:00
parent 72fb88613f
commit 3f4bc6ce7f
9 changed files with 156 additions and 73 deletions

View File

@ -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.

View File

@ -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;
}

View File

@ -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);

View File

@ -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;
};

View File

@ -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:

View File

@ -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;

View File

@ -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 */

View File

@ -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;
}

View File

@ -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)