target/arm_cti: use adiv5_jim_mem_ap_spot_configure()

To avoid code duplication, reorganize the code to replace
cti_configure() with adiv5_jim_mem_ap_spot_configure().

Reorganize 'struct arm_cti_object' and its sub-'struct arm_cti'
moving DAP and mem-AP info in a 'struct adiv5_mem_ap_spot'.
Replace cti_configure() with adiv5_jim_mem_ap_spot_configure().
Deprecate the use of '-ctibase' in favor of '-baseaddr'.

Change-Id: I43740a37c80de67c0f5e4dc79c3400b91a12e9e8
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: http://openocd.zylin.com/5869
Tested-by: jenkins
This commit is contained in:
Antonio Borneo 2020-10-17 16:27:13 +02:00
parent 080fab2ecd
commit ec0c23a3ab
3 changed files with 48 additions and 102 deletions

View File

@ -8593,7 +8593,7 @@ CTI is mandatory for core run control and each core has an individual
CTI instance attached to it. OpenOCD has limited support for CTI using CTI instance attached to it. OpenOCD has limited support for CTI using
the @emph{cti} group of commands. the @emph{cti} group of commands.
@deffn Command {cti create} cti_name @option{-dap} dap_name @option{-ap-num} apn @option{-ctibase} base_address @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 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}. The @var{base_address} must match the base address of the CTI
on the respective MEM-AP. All arguments are mandatory. This creates a on the respective MEM-AP. All arguments are mandatory. This creates a

View File

@ -1481,12 +1481,14 @@ enum adiv5_cfg_param {
CFG_DAP, CFG_DAP,
CFG_AP_NUM, CFG_AP_NUM,
CFG_BASEADDR, CFG_BASEADDR,
CFG_CTIBASE, /* DEPRECATED */
}; };
static const Jim_Nvp nvp_config_opts[] = { static const Jim_Nvp nvp_config_opts[] = {
{ .name = "-dap", .value = CFG_DAP }, { .name = "-dap", .value = CFG_DAP },
{ .name = "-ap-num", .value = CFG_AP_NUM }, { .name = "-ap-num", .value = CFG_AP_NUM },
{ .name = "-baseaddr", .value = CFG_BASEADDR }, { .name = "-baseaddr", .value = CFG_BASEADDR },
{ .name = "-ctibase", .value = CFG_CTIBASE }, /* DEPRECATED */
{ .name = NULL, .value = -1 } { .name = NULL, .value = -1 }
}; };
@ -1505,7 +1507,7 @@ static int adiv5_jim_spot_configure(Jim_GetOptInfo *goi,
return JIM_CONTINUE; return JIM_CONTINUE;
/* base_p can be NULL, then '-baseaddr' option is treated as unknown */ /* base_p can be NULL, then '-baseaddr' option is treated as unknown */
if (!base_p && n->value == CFG_BASEADDR) if (!base_p && (n->value == CFG_BASEADDR || n->value == CFG_CTIBASE))
return JIM_CONTINUE; return JIM_CONTINUE;
e = Jim_GetOpt_Obj(goi, NULL); e = Jim_GetOpt_Obj(goi, NULL);
@ -1564,6 +1566,9 @@ static int adiv5_jim_spot_configure(Jim_GetOptInfo *goi,
} }
break; break;
case CFG_CTIBASE:
LOG_WARNING("DEPRECATED! use \'-baseaddr' not \'-ctibase\'");
/* fall through */
case CFG_BASEADDR: case CFG_BASEADDR:
if (goi->isconfigure) { if (goi->isconfigure) {
jim_wide base; jim_wide base;

View File

@ -31,28 +31,21 @@
#include "helper/command.h" #include "helper/command.h"
struct arm_cti { struct arm_cti {
target_addr_t base;
struct adiv5_ap *ap;
};
struct arm_cti_object {
struct list_head lh; struct list_head lh;
struct arm_cti cti;
int ap_num;
char *name; char *name;
struct adiv5_mem_ap_spot spot;
}; };
static LIST_HEAD(all_cti); static LIST_HEAD(all_cti);
const char *arm_cti_name(struct arm_cti *self) const char *arm_cti_name(struct arm_cti *self)
{ {
struct arm_cti_object *obj = container_of(self, struct arm_cti_object, cti); return self->name;
return obj->name;
} }
struct arm_cti *cti_instance_by_jim_obj(Jim_Interp *interp, Jim_Obj *o) struct arm_cti *cti_instance_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
{ {
struct arm_cti_object *obj = NULL; struct arm_cti *obj = NULL;
const char *name; const char *name;
bool found = false; bool found = false;
@ -66,16 +59,17 @@ struct arm_cti *cti_instance_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
} }
if (found) if (found)
return &obj->cti; return obj;
return NULL; return NULL;
} }
static int arm_cti_mod_reg_bits(struct arm_cti *self, unsigned int reg, uint32_t mask, uint32_t value) static int arm_cti_mod_reg_bits(struct arm_cti *self, unsigned int reg, uint32_t mask, uint32_t value)
{ {
struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
uint32_t tmp; uint32_t tmp;
/* Read register */ /* Read register */
int retval = mem_ap_read_atomic_u32(self->ap, self->base + reg, &tmp); int retval = mem_ap_read_atomic_u32(ap, self->spot.base + reg, &tmp);
if (ERROR_OK != retval) if (ERROR_OK != retval)
return retval; return retval;
@ -85,26 +79,28 @@ static int arm_cti_mod_reg_bits(struct arm_cti *self, unsigned int reg, uint32_t
tmp |= value & mask; tmp |= value & mask;
/* write new value */ /* write new value */
return mem_ap_write_atomic_u32(self->ap, self->base + reg, tmp); return mem_ap_write_atomic_u32(ap, self->spot.base + reg, tmp);
} }
int arm_cti_enable(struct arm_cti *self, bool enable) int arm_cti_enable(struct arm_cti *self, bool enable)
{ {
struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
uint32_t val = enable ? 1 : 0; uint32_t val = enable ? 1 : 0;
return mem_ap_write_atomic_u32(self->ap, self->base + CTI_CTR, val); return mem_ap_write_atomic_u32(ap, self->spot.base + CTI_CTR, val);
} }
int arm_cti_ack_events(struct arm_cti *self, uint32_t event) int arm_cti_ack_events(struct arm_cti *self, uint32_t event)
{ {
struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
int retval; int retval;
uint32_t tmp; uint32_t tmp;
retval = mem_ap_write_atomic_u32(self->ap, self->base + CTI_INACK, event); retval = mem_ap_write_atomic_u32(ap, self->spot.base + CTI_INACK, event);
if (retval == ERROR_OK) { if (retval == ERROR_OK) {
int64_t then = timeval_ms(); int64_t then = timeval_ms();
for (;;) { for (;;) {
retval = mem_ap_read_atomic_u32(self->ap, self->base + CTI_TROUT_STATUS, &tmp); retval = mem_ap_read_atomic_u32(ap, self->spot.base + CTI_TROUT_STATUS, &tmp);
if (retval != ERROR_OK) if (retval != ERROR_OK)
break; break;
if ((tmp & event) == 0) if ((tmp & event) == 0)
@ -138,15 +134,19 @@ int arm_cti_ungate_channel(struct arm_cti *self, uint32_t channel)
int arm_cti_write_reg(struct arm_cti *self, unsigned int reg, uint32_t value) int arm_cti_write_reg(struct arm_cti *self, unsigned int reg, uint32_t value)
{ {
return mem_ap_write_atomic_u32(self->ap, self->base + reg, value); struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
return mem_ap_write_atomic_u32(ap, self->spot.base + reg, value);
} }
int arm_cti_read_reg(struct arm_cti *self, unsigned int reg, uint32_t *p_value) int arm_cti_read_reg(struct arm_cti *self, unsigned int reg, uint32_t *p_value)
{ {
struct adiv5_ap *ap = dap_ap(self->spot.dap, self->spot.ap_num);
if (p_value == NULL) if (p_value == NULL)
return ERROR_COMMAND_ARGUMENT_INVALID; return ERROR_COMMAND_ARGUMENT_INVALID;
return mem_ap_read_atomic_u32(self->ap, self->base + reg, p_value); return mem_ap_read_atomic_u32(ap, self->spot.base + reg, p_value);
} }
int arm_cti_pulse_channel(struct arm_cti *self, uint32_t channel) int arm_cti_pulse_channel(struct arm_cti *self, uint32_t channel)
@ -225,7 +225,7 @@ static int cti_find_reg_offset(const char *name)
int arm_cti_cleanup_all(void) int arm_cti_cleanup_all(void)
{ {
struct arm_cti_object *obj, *tmp; struct arm_cti *obj, *tmp;
list_for_each_entry_safe(obj, tmp, &all_cti, lh) { list_for_each_entry_safe(obj, tmp, &all_cti, lh) {
free(obj->name); free(obj->name);
@ -237,16 +237,16 @@ int arm_cti_cleanup_all(void)
COMMAND_HANDLER(handle_cti_dump) COMMAND_HANDLER(handle_cti_dump)
{ {
struct arm_cti_object *obj = CMD_DATA; struct arm_cti *cti = CMD_DATA;
struct arm_cti *cti = &obj->cti; struct adiv5_ap *ap = dap_ap(cti->spot.dap, cti->spot.ap_num);
int retval = ERROR_OK; int retval = ERROR_OK;
for (int i = 0; (retval == ERROR_OK) && (i < (int)ARRAY_SIZE(cti_names)); i++) for (int i = 0; (retval == ERROR_OK) && (i < (int)ARRAY_SIZE(cti_names)); i++)
retval = mem_ap_read_u32(cti->ap, retval = mem_ap_read_u32(ap,
cti->base + cti_names[i].offset, cti_names[i].p_val); cti->spot.base + cti_names[i].offset, cti_names[i].p_val);
if (retval == ERROR_OK) if (retval == ERROR_OK)
retval = dap_run(cti->ap->dap); retval = dap_run(ap->dap);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return JIM_ERR; return JIM_ERR;
@ -260,8 +260,7 @@ COMMAND_HANDLER(handle_cti_dump)
COMMAND_HANDLER(handle_cti_enable) COMMAND_HANDLER(handle_cti_enable)
{ {
struct arm_cti_object *obj = CMD_DATA; struct arm_cti *cti = CMD_DATA;
struct arm_cti *cti = &obj->cti;
bool on_off; bool on_off;
if (CMD_ARGC != 1) if (CMD_ARGC != 1)
@ -274,8 +273,7 @@ COMMAND_HANDLER(handle_cti_enable)
COMMAND_HANDLER(handle_cti_testmode) COMMAND_HANDLER(handle_cti_testmode)
{ {
struct arm_cti_object *obj = CMD_DATA; struct arm_cti *cti = CMD_DATA;
struct arm_cti *cti = &obj->cti;
bool on_off; bool on_off;
if (CMD_ARGC != 1) if (CMD_ARGC != 1)
@ -288,8 +286,7 @@ COMMAND_HANDLER(handle_cti_testmode)
COMMAND_HANDLER(handle_cti_write) COMMAND_HANDLER(handle_cti_write)
{ {
struct arm_cti_object *obj = CMD_DATA; struct arm_cti *cti = CMD_DATA;
struct arm_cti *cti = &obj->cti;
int offset; int offset;
uint32_t value; uint32_t value;
@ -307,8 +304,7 @@ COMMAND_HANDLER(handle_cti_write)
COMMAND_HANDLER(handle_cti_read) COMMAND_HANDLER(handle_cti_read)
{ {
struct arm_cti_object *obj = CMD_DATA; struct arm_cti *cti = CMD_DATA;
struct arm_cti *cti = &obj->cti;
int offset; int offset;
int retval; int retval;
uint32_t value; uint32_t value;
@ -331,8 +327,7 @@ COMMAND_HANDLER(handle_cti_read)
COMMAND_HANDLER(handle_cti_ack) COMMAND_HANDLER(handle_cti_ack)
{ {
struct arm_cti_object *obj = CMD_DATA; struct arm_cti *cti = CMD_DATA;
struct arm_cti *cti = &obj->cti;
uint32_t event; uint32_t event;
if (CMD_ARGC != 1) if (CMD_ARGC != 1)
@ -351,8 +346,7 @@ COMMAND_HANDLER(handle_cti_ack)
COMMAND_HANDLER(handle_cti_channel) COMMAND_HANDLER(handle_cti_channel)
{ {
struct arm_cti_object *obj = CMD_DATA; struct arm_cti *cti = CMD_DATA;
struct arm_cti *cti = &obj->cti;
int retval = ERROR_OK; int retval = ERROR_OK;
uint32_t ch_num; uint32_t ch_num;
@ -436,83 +430,26 @@ static const struct command_registration cti_instance_command_handlers[] = {
COMMAND_REGISTRATION_DONE COMMAND_REGISTRATION_DONE
}; };
enum cti_cfg_param { static int cti_configure(Jim_GetOptInfo *goi, struct arm_cti *cti)
CFG_DAP,
CFG_AP_NUM,
CFG_CTIBASE
};
static const Jim_Nvp nvp_config_opts[] = {
{ .name = "-dap", .value = CFG_DAP },
{ .name = "-ctibase", .value = CFG_CTIBASE },
{ .name = "-ap-num", .value = CFG_AP_NUM },
{ .name = NULL, .value = -1 }
};
static int cti_configure(Jim_GetOptInfo *goi, struct arm_cti_object *cti)
{ {
struct adiv5_dap *dap = NULL;
Jim_Nvp *n;
jim_wide w;
int e;
/* parse config or cget options ... */ /* parse config or cget options ... */
while (goi->argc > 0) { while (goi->argc > 0) {
Jim_SetEmptyResult(goi->interp); int e = adiv5_jim_mem_ap_spot_configure(&cti->spot, goi);
if (e != JIM_OK)
e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n);
if (e != JIM_OK) {
Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0);
return e; return e;
}
switch (n->value) {
case CFG_DAP: {
Jim_Obj *o_t;
e = Jim_GetOpt_Obj(goi, &o_t);
if (e != JIM_OK)
return e;
dap = dap_instance_by_jim_obj(goi->interp, o_t);
if (dap == NULL) {
Jim_SetResultString(goi->interp, "-dap is invalid", -1);
return JIM_ERR;
}
/* loop for more */
break;
}
case CFG_CTIBASE:
e = Jim_GetOpt_Wide(goi, &w);
if (e != JIM_OK)
return e;
cti->cti.base = (uint32_t)w;
/* loop for more */
break;
case CFG_AP_NUM:
e = Jim_GetOpt_Wide(goi, &w);
if (e != JIM_OK)
return e;
if (w < 0 || w > DP_APSEL_MAX) {
Jim_SetResultString(goi->interp, "-ap-num is invalid", -1);
return JIM_ERR;
}
cti->ap_num = (uint32_t)w;
}
} }
if (dap == NULL) { if (!cti->spot.dap) {
Jim_SetResultString(goi->interp, "-dap required when creating CTI", -1); Jim_SetResultString(goi->interp, "-dap required when creating CTI", -1);
return JIM_ERR; return JIM_ERR;
} }
cti->cti.ap = dap_ap(dap, cti->ap_num);
return JIM_OK; return JIM_OK;
} }
static int cti_create(Jim_GetOptInfo *goi) static int cti_create(Jim_GetOptInfo *goi)
{ {
struct command_context *cmd_ctx; struct command_context *cmd_ctx;
static struct arm_cti_object *cti; static struct arm_cti *cti;
Jim_Obj *new_cmd; Jim_Obj *new_cmd;
Jim_Cmd *cmd; Jim_Cmd *cmd;
const char *cp; const char *cp;
@ -536,10 +473,14 @@ static int cti_create(Jim_GetOptInfo *goi)
} }
/* Create it */ /* Create it */
cti = calloc(1, sizeof(struct arm_cti_object)); cti = calloc(1, sizeof(*cti));
if (cti == NULL) if (cti == NULL)
return JIM_ERR; return JIM_ERR;
adiv5_mem_ap_spot_init(&cti->spot);
/* Do the rest as "configure" options */
goi->isconfigure = 1;
e = cti_configure(goi, cti); e = cti_configure(goi, cti);
if (e != JIM_OK) { if (e != JIM_OK) {
free(cti); free(cti);
@ -593,7 +534,7 @@ static int jim_cti_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
static int jim_cti_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int jim_cti_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{ {
struct arm_cti_object *obj; struct arm_cti *obj;
if (argc != 1) { if (argc != 1) {
Jim_WrongNumArgs(interp, 1, argv, "Too many parameters"); Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");