arm_cti: add cti command group

Extend the CTI abstraction to be accessible from TCL and
change the 'target' command to accept a cti 'object' instead of a
base address. This also allows accessing CTI instances that are not
related to a configured target.

Change-Id: Iac9ed0edca6f1be00fe93783a35c26077f6bc80a
Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com>
Reviewed-on: http://openocd.zylin.com/4031
Tested-by: jenkins
Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>
riscv-compliance-dev
Matthias Welwarsky 2017-04-10 22:53:27 +02:00 committed by Matthias Welwarsky
parent 1756f393e4
commit f444c57bf2
10 changed files with 578 additions and 45 deletions

View File

@ -4290,9 +4290,11 @@ access the target for debugging.
Use this option with systems where multiple, independent cores are connected Use this option with systems where multiple, independent cores are connected
to separate access ports of the same DAP. to separate access ports of the same DAP.
@item @code{-ctibase} @var{address} -- set base address of Cross-Trigger interface (CTI) connected @item @code{-cti} @var{cti_name} -- set Cross-Trigger Interface (CTI) connected
to the target. Currently, only the @code{aarch64} target makes use of this option, where it is to the target. Currently, only the @code{aarch64} target makes use of this option,
a mandatory configuration for the target run control. where it is a mandatory configuration for the target run control.
@xref{armcrosstrigger,,ARM Cross-Trigger Interface},
for instruction on how to declare and control a CTI instance.
@end itemize @end itemize
@end deffn @end deffn
@ -7781,6 +7783,50 @@ Reports whether the capture clock is locked or not.
@end deffn @end deffn
@end deffn @end deffn
@anchor{armcrosstrigger}
@section ARM Cross-Trigger Interface
@cindex CTI
The ARM Cross-Trigger Interface (CTI) is a generic CoreSight component
that connects event sources like tracing components or CPU cores with each
other through a common trigger matrix (CTM). For ARMv8 architecture, a
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
the @emph{cti} group of commands.
@deffn Command {cti create} @var{cti_name} -chain-position @var{tap_name} -ap-num @var{apn} -ctibase @var{base_address}
Creates a CTI object @var{cti_name} on the JTAG tap @var{tap_name} on MEM-AP
@var{apn} of the DAP reachable through @var{tap}. 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{@var{cti_name}}) which
is used for various purposes including additional configuration.
@end deffn
@deffn Command {$cti_name enable} @option{on|off}
Enable (@option{on}) or disable (@option{off}) the CTI.
@end deffn
@deffn Command {$cti_name dump}
Displays a register dump of the CTI.
@end deffn
@deffn Command {$cti_name write } @var{reg_name} @var{value}
Write @var{value} to the CTI register with the symbolic name @var{reg_name}.
@end deffn
@deffn Command {$cti_name read} @var{reg_name}
Print the value read from the CTI register with the symbolic name @var{reg_name}.
@end deffn
@deffn Command {$cti_name testmode} @option{on|off}
Enable (@option{on}) or disable (@option{off}) the integration test mode
of the CTI.
@end deffn
@deffn Command {cti names}
Prints a list of names of all CTI objects created. This command is mainly
useful in TCL scripting.
@end deffn
@section Generic ARM @section Generic ARM
@cindex ARM @cindex ARM

View File

@ -37,6 +37,7 @@
#include <flash/nand/core.h> #include <flash/nand/core.h>
#include <pld/pld.h> #include <pld/pld.h>
#include <flash/mflash.h> #include <flash/mflash.h>
#include <target/arm_cti.h>
#include <server/server.h> #include <server/server.h>
#include <server/gdb_server.h> #include <server/gdb_server.h>
@ -252,6 +253,7 @@ struct command_context *setup_command_handler(Jim_Interp *interp)
&nand_register_commands, &nand_register_commands,
&pld_register_commands, &pld_register_commands,
&mflash_register_commands, &mflash_register_commands,
&cti_register_commands,
NULL NULL
}; };
for (unsigned i = 0; NULL != command_registrants[i]; i++) { for (unsigned i = 0; NULL != command_registrants[i]; i++) {

View File

@ -40,6 +40,10 @@ enum halt_mode {
HALT_SYNC, HALT_SYNC,
}; };
struct aarch64_private_config {
struct arm_cti *cti;
};
static int aarch64_poll(struct target *target); static int aarch64_poll(struct target *target);
static int aarch64_debug_entry(struct target *target); static int aarch64_debug_entry(struct target *target);
static int aarch64_restore_context(struct target *target, bool bpwp); static int aarch64_restore_context(struct target *target, bool bpwp);
@ -2198,7 +2202,7 @@ static int aarch64_examine_first(struct target *target)
struct aarch64_common *aarch64 = target_to_aarch64(target); struct aarch64_common *aarch64 = target_to_aarch64(target);
struct armv8_common *armv8 = &aarch64->armv8_common; struct armv8_common *armv8 = &aarch64->armv8_common;
struct adiv5_dap *swjdp = armv8->arm.dap; struct adiv5_dap *swjdp = armv8->arm.dap;
uint32_t cti_base; struct aarch64_private_config *pc;
int i; int i;
int retval = ERROR_OK; int retval = ERROR_OK;
uint64_t debug, ttypr; uint64_t debug, ttypr;
@ -2289,17 +2293,15 @@ static int aarch64_examine_first(struct target *target)
LOG_DEBUG("ttypr = 0x%08" PRIx64, ttypr); LOG_DEBUG("ttypr = 0x%08" PRIx64, ttypr);
LOG_DEBUG("debug = 0x%08" PRIx64, debug); LOG_DEBUG("debug = 0x%08" PRIx64, debug);
if (target->ctibase == 0) { if (target->private_config == NULL)
/* assume a v8 rom table layout */
cti_base = armv8->debug_base + 0x10000;
LOG_INFO("Target ctibase is not set, assuming 0x%0" PRIx32, cti_base);
} else
cti_base = target->ctibase;
armv8->cti = arm_cti_create(armv8->debug_ap, cti_base);
if (armv8->cti == NULL)
return ERROR_FAIL; return ERROR_FAIL;
pc = (struct aarch64_private_config *)target->private_config;
if (pc->cti == NULL)
return ERROR_FAIL;
armv8->cti = pc->cti;
retval = aarch64_dpm_setup(aarch64, debug); retval = aarch64_dpm_setup(aarch64, debug);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -2405,6 +2407,63 @@ static int aarch64_virt2phys(struct target *target, target_addr_t virt,
return armv8_mmu_translate_va_pa(target, virt, phys, 1); return armv8_mmu_translate_va_pa(target, virt, phys, 1);
} }
static int aarch64_jim_configure(struct target *target, Jim_GetOptInfo *goi)
{
struct aarch64_private_config *pc;
const char *arg;
int e;
/* check if argv[0] is for us */
arg = Jim_GetString(goi->argv[0], NULL);
if (strcmp(arg, "-cti"))
return JIM_CONTINUE;
/* pop the argument from argv */
e = Jim_GetOpt_String(goi, &arg, NULL);
if (e != JIM_OK)
return e;
/* check if we have another option */
if (goi->argc == 0) {
Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-cti ?cti-name?");
return JIM_ERR;
}
pc = (struct aarch64_private_config *)target->private_config;
if (goi->isconfigure) {
Jim_Obj *o_cti;
struct arm_cti *cti;
e = Jim_GetOpt_Obj(goi, &o_cti);
if (e != JIM_OK)
return e;
cti = cti_instance_by_jim_obj(goi->interp, o_cti);
if (cti == NULL)
return JIM_ERR;
if (pc == NULL) {
pc = calloc(1, sizeof(struct aarch64_private_config));
target->private_config = pc;
}
pc->cti = cti;
} else {
if (goi->argc != 0) {
Jim_WrongNumArgs(goi->interp,
goi->argc, goi->argv,
"NO PARAMS");
return JIM_ERR;
}
if (pc == NULL || pc->cti == NULL) {
Jim_SetResultString(goi->interp, "CTI not configured", -1);
return JIM_ERR;
}
Jim_SetResultString(goi->interp, arm_cti_name(pc->cti), -1);
}
return JIM_OK;
}
COMMAND_HANDLER(aarch64_handle_cache_info_command) COMMAND_HANDLER(aarch64_handle_cache_info_command)
{ {
struct target *target = get_current_target(CMD_CTX); struct target *target = get_current_target(CMD_CTX);
@ -2570,6 +2629,7 @@ struct target_type aarch64_target = {
.commands = aarch64_command_handlers, .commands = aarch64_command_handlers,
.target_create = aarch64_target_create, .target_create = aarch64_target_create,
.target_jim_configure = aarch64_jim_configure,
.init_target = aarch64_init_target, .init_target = aarch64_init_target,
.examine = aarch64_examine, .examine = aarch64_examine,

View File

@ -27,21 +27,47 @@
#include "target/arm_cti.h" #include "target/arm_cti.h"
#include "target/target.h" #include "target/target.h"
#include "helper/time_support.h" #include "helper/time_support.h"
#include "helper/list.h"
#include "helper/command.h"
struct arm_cti { struct arm_cti {
uint32_t base; target_addr_t base;
struct adiv5_ap *ap; struct adiv5_ap *ap;
}; };
struct arm_cti *arm_cti_create(struct adiv5_ap *ap, uint32_t base) struct arm_cti_object {
{ struct list_head lh;
struct arm_cti *self = calloc(1, sizeof(struct arm_cti)); struct arm_cti cti;
if (!self) int ap_num;
return NULL; char *name;
};
self->base = base; static LIST_HEAD(all_cti);
self->ap = ap;
return self; const char *arm_cti_name(struct arm_cti *self)
{
struct arm_cti_object *obj = container_of(self, struct arm_cti_object, cti);
return obj->name;
}
struct arm_cti *cti_instance_by_jim_obj(Jim_Interp *interp, Jim_Obj *o)
{
struct arm_cti_object *obj = NULL;
const char *name;
bool found = false;
name = Jim_GetString(o, NULL);
list_for_each_entry(obj, &all_cti, lh) {
if (!strcmp(name, obj->name)) {
found = true;
break;
}
}
if (found)
return &obj->cti;
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)
@ -146,3 +172,404 @@ int arm_cti_clear_channel(struct arm_cti *self, uint32_t channel)
return arm_cti_write_reg(self, CTI_APPCLEAR, CTI_CHNL(channel)); return arm_cti_write_reg(self, CTI_APPCLEAR, CTI_CHNL(channel));
} }
static uint32_t cti_regs[26];
static const struct {
uint32_t offset;
const char *label;
uint32_t *p_val;
} cti_names[] = {
{ CTI_CTR, "CTR", &cti_regs[0] },
{ CTI_GATE, "GATE", &cti_regs[1] },
{ CTI_INEN0, "INEN0", &cti_regs[2] },
{ CTI_INEN1, "INEN1", &cti_regs[3] },
{ CTI_INEN2, "INEN2", &cti_regs[4] },
{ CTI_INEN3, "INEN3", &cti_regs[5] },
{ CTI_INEN4, "INEN4", &cti_regs[6] },
{ CTI_INEN5, "INEN5", &cti_regs[7] },
{ CTI_INEN6, "INEN6", &cti_regs[8] },
{ CTI_INEN7, "INEN7", &cti_regs[9] },
{ CTI_INEN8, "INEN8", &cti_regs[10] },
{ CTI_OUTEN0, "OUTEN0", &cti_regs[11] },
{ CTI_OUTEN1, "OUTEN1", &cti_regs[12] },
{ CTI_OUTEN2, "OUTEN2", &cti_regs[13] },
{ CTI_OUTEN3, "OUTEN3", &cti_regs[14] },
{ CTI_OUTEN4, "OUTEN4", &cti_regs[15] },
{ CTI_OUTEN5, "OUTEN5", &cti_regs[16] },
{ CTI_OUTEN6, "OUTEN6", &cti_regs[17] },
{ CTI_OUTEN7, "OUTEN7", &cti_regs[18] },
{ CTI_OUTEN8, "OUTEN8", &cti_regs[19] },
{ CTI_TRIN_STATUS, "TRIN", &cti_regs[20] },
{ CTI_TROUT_STATUS, "TROUT", &cti_regs[21] },
{ CTI_CHIN_STATUS, "CHIN", &cti_regs[22] },
{ CTI_CHOU_STATUS, "CHOUT", &cti_regs[23] },
{ CTI_APPSET, "APPSET", &cti_regs[24] },
{ CTI_APPCLEAR, "APPCLR", &cti_regs[25] },
};
static int cti_find_reg_offset(const char *name)
{
unsigned int i;
for (i = 0; i < ARRAY_SIZE(cti_names); i++) {
if (!strcmp(name, cti_names[i].label))
return cti_names[i].offset;
}
return -1;
}
COMMAND_HANDLER(handle_cti_dump)
{
struct arm_cti_object *obj = CMD_DATA;
struct arm_cti *cti = &obj->cti;
int retval = ERROR_OK;
for (int i = 0; (retval == ERROR_OK) && (i < (int)ARRAY_SIZE(cti_names)); i++)
retval = mem_ap_read_u32(cti->ap,
cti->base + cti_names[i].offset, cti_names[i].p_val);
if (retval == ERROR_OK)
retval = dap_run(cti->ap->dap);
if (retval != ERROR_OK)
return JIM_ERR;
for (int i = 0; i < (int)ARRAY_SIZE(cti_names); i++)
command_print(CMD_CTX, "%8.8s (0x%04"PRIx32") 0x%08"PRIx32,
cti_names[i].label, cti_names[i].offset, *cti_names[i].p_val);
return JIM_OK;
}
COMMAND_HANDLER(handle_cti_enable)
{
struct arm_cti_object *obj = CMD_DATA;
Jim_Interp *interp = CMD_CTX->interp;
struct arm_cti *cti = &obj->cti;
bool on_off;
if (CMD_ARGC != 1) {
Jim_SetResultString(interp, "wrong number of args", -1);
return ERROR_FAIL;
}
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], on_off);
return arm_cti_enable(cti, on_off);
}
COMMAND_HANDLER(handle_cti_testmode)
{
struct arm_cti_object *obj = CMD_DATA;
Jim_Interp *interp = CMD_CTX->interp;
struct arm_cti *cti = &obj->cti;
bool on_off;
if (CMD_ARGC != 1) {
Jim_SetResultString(interp, "wrong number of args", -1);
return ERROR_FAIL;
}
COMMAND_PARSE_ON_OFF(CMD_ARGV[0], on_off);
return arm_cti_write_reg(cti, 0xf00, on_off ? 0x1 : 0x0);
}
COMMAND_HANDLER(handle_cti_write)
{
struct arm_cti_object *obj = CMD_DATA;
Jim_Interp *interp = CMD_CTX->interp;
struct arm_cti *cti = &obj->cti;
int offset;
uint32_t value;
if (CMD_ARGC != 2) {
Jim_SetResultString(interp, "Wrong numer of args", -1);
return ERROR_FAIL;
}
offset = cti_find_reg_offset(CMD_ARGV[0]);
if (offset < 0)
return ERROR_FAIL;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
return arm_cti_write_reg(cti, offset, value);
}
COMMAND_HANDLER(handle_cti_read)
{
struct arm_cti_object *obj = CMD_DATA;
Jim_Interp *interp = CMD_CTX->interp;
struct arm_cti *cti = &obj->cti;
int offset;
int retval;
uint32_t value;
if (CMD_ARGC != 1) {
Jim_SetResultString(interp, "Wrong numer of args", -1);
return ERROR_FAIL;
}
offset = cti_find_reg_offset(CMD_ARGV[0]);
if (offset < 0)
return ERROR_FAIL;
retval = arm_cti_read_reg(cti, offset, &value);
if (retval != ERROR_OK)
return retval;
command_print(CMD_CTX, "0x%08"PRIx32, value);
return ERROR_OK;
}
static const struct command_registration cti_instance_command_handlers[] = {
{
.name = "dump",
.mode = COMMAND_EXEC,
.handler = handle_cti_dump,
.help = "dump CTI registers",
.usage = "",
},
{
.name = "enable",
.mode = COMMAND_EXEC,
.handler = handle_cti_enable,
.help = "enable or disable the CTI",
.usage = "'on'|'off'",
},
{
.name = "testmode",
.mode = COMMAND_EXEC,
.handler = handle_cti_testmode,
.help = "enable or disable integration test mode",
.usage = "'on'|'off'",
},
{
.name = "write",
.mode = COMMAND_EXEC,
.handler = handle_cti_write,
.help = "write to a CTI register",
.usage = "register_name value",
},
{
.name = "read",
.mode = COMMAND_EXEC,
.handler = handle_cti_read,
.help = "read a CTI register",
.usage = "register_name",
},
COMMAND_REGISTRATION_DONE
};
enum cti_cfg_param {
CFG_CHAIN_POSITION,
CFG_AP_NUM,
CFG_CTIBASE
};
static const Jim_Nvp nvp_config_opts[] = {
{ .name = "-chain-position", .value = CFG_CHAIN_POSITION },
{ .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 jtag_tap *tap = NULL;
struct adiv5_dap *dap;
Jim_Nvp *n;
jim_wide w;
int e;
/* parse config or cget options ... */
while (goi->argc > 0) {
Jim_SetEmptyResult(goi->interp);
e = Jim_GetOpt_Nvp(goi, nvp_config_opts, &n);
if (e != JIM_OK) {
Jim_GetOpt_NvpUnknown(goi, nvp_config_opts, 0);
return e;
}
switch (n->value) {
case CFG_CHAIN_POSITION: {
Jim_Obj *o_t;
e = Jim_GetOpt_Obj(goi, &o_t);
if (e != JIM_OK)
return e;
tap = jtag_tap_by_jim_obj(goi->interp, o_t);
if (tap == NULL) {
Jim_SetResultString(goi->interp, "-chain-position 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;
cti->ap_num = (uint32_t)w;
}
}
if (tap == NULL) {
Jim_SetResultString(goi->interp, "-chain-position required when creating CTI", -1);
return JIM_ERR;
}
if (tap->dap == NULL) {
dap = dap_init();
dap->tap = tap;
tap->dap = dap;
} else
dap = tap->dap;
cti->cti.ap = dap_ap(dap, cti->ap_num);
return JIM_OK;
}
static int cti_create(Jim_GetOptInfo *goi)
{
struct command_context *cmd_ctx;
static struct arm_cti_object *cti;
Jim_Obj *new_cmd;
Jim_Cmd *cmd;
const char *cp;
int e;
cmd_ctx = current_command_context(goi->interp);
assert(cmd_ctx != NULL);
if (goi->argc < 3) {
Jim_WrongNumArgs(goi->interp, 1, goi->argv, "?name? ..options...");
return JIM_ERR;
}
/* COMMAND */
Jim_GetOpt_Obj(goi, &new_cmd);
/* does this command exist? */
cmd = Jim_GetCommand(goi->interp, new_cmd, JIM_ERRMSG);
if (cmd) {
cp = Jim_GetString(new_cmd, NULL);
Jim_SetResultFormatted(goi->interp, "Command: %s Exists", cp);
return JIM_ERR;
}
/* Create it */
cti = calloc(1, sizeof(struct arm_cti_object));
if (cti == NULL)
return JIM_ERR;
e = cti_configure(goi, cti);
if (e != JIM_OK) {
free(cti);
return e;
}
cp = Jim_GetString(new_cmd, NULL);
cti->name = strdup(cp);
/* now - create the new cti name command */
const struct command_registration cti_subcommands[] = {
{
.chain = cti_instance_command_handlers,
},
COMMAND_REGISTRATION_DONE
};
const struct command_registration cti_commands[] = {
{
.name = cp,
.mode = COMMAND_ANY,
.help = "cti instance command group",
.usage = "",
.chain = cti_subcommands,
},
COMMAND_REGISTRATION_DONE
};
e = register_commands(cmd_ctx, NULL, cti_commands);
if (ERROR_OK != e)
return JIM_ERR;
struct command *c = command_find_in_context(cmd_ctx, cp);
assert(c);
command_set_handler_data(c, cti);
list_add_tail(&cti->lh, &all_cti);
return (ERROR_OK == e) ? JIM_OK : JIM_ERR;
}
static int jim_cti_create(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
Jim_GetOptInfo goi;
Jim_GetOpt_Setup(&goi, interp, argc - 1, argv + 1);
if (goi.argc < 2) {
Jim_WrongNumArgs(goi.interp, goi.argc, goi.argv,
"<name> [<cti_options> ...]");
return JIM_ERR;
}
return cti_create(&goi);
}
static int jim_cti_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
{
struct arm_cti_object *obj;
if (argc != 1) {
Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
return JIM_ERR;
}
Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0));
list_for_each_entry(obj, &all_cti, lh) {
Jim_ListAppendElement(interp, Jim_GetResult(interp),
Jim_NewStringObj(interp, obj->name, -1));
}
return JIM_OK;
}
static const struct command_registration cti_subcommand_handlers[] = {
{
.name = "create",
.mode = COMMAND_ANY,
.jim_handler = jim_cti_create,
.usage = "name '-chain-position' name [options ...]",
.help = "Creates a new CTI object",
},
{
.name = "names",
.mode = COMMAND_ANY,
.jim_handler = jim_cti_names,
.usage = "",
.help = "Lists all registered CTI objects by name",
},
COMMAND_REGISTRATION_DONE
};
static const struct command_registration cti_command_handlers[] = {
{
.name = "cti",
.mode = COMMAND_CONFIG,
.help = "CTI commands",
.chain = cti_subcommand_handlers,
},
COMMAND_REGISTRATION_DONE
};
int cti_register_commands(struct command_context *cmd_ctx)
{
return register_commands(cmd_ctx, NULL, cti_command_handlers);
}

View File

@ -34,6 +34,7 @@
#define CTI_INEN5 0x34 #define CTI_INEN5 0x34
#define CTI_INEN6 0x38 #define CTI_INEN6 0x38
#define CTI_INEN7 0x3C #define CTI_INEN7 0x3C
#define CTI_INEN8 0x40
#define CTI_INEN(n) (0x20 + 4 * n) #define CTI_INEN(n) (0x20 + 4 * n)
#define CTI_OUTEN0 0xA0 #define CTI_OUTEN0 0xA0
#define CTI_OUTEN1 0xA4 #define CTI_OUTEN1 0xA4
@ -43,6 +44,7 @@
#define CTI_OUTEN5 0xB4 #define CTI_OUTEN5 0xB4
#define CTI_OUTEN6 0xB8 #define CTI_OUTEN6 0xB8
#define CTI_OUTEN7 0xBC #define CTI_OUTEN7 0xBC
#define CTI_OUTEN8 0xC0
#define CTI_OUTEN(n) (0xA0 + 4 * n) #define CTI_OUTEN(n) (0xA0 + 4 * n)
#define CTI_TRIN_STATUS 0x130 #define CTI_TRIN_STATUS 0x130
#define CTI_TROUT_STATUS 0x134 #define CTI_TROUT_STATUS 0x134
@ -58,8 +60,10 @@
/* forward-declare arm_cti struct */ /* forward-declare arm_cti struct */
struct arm_cti; struct arm_cti;
struct adiv5_ap;
extern struct arm_cti *arm_cti_create(struct adiv5_ap *ap, uint32_t base); extern const char *arm_cti_name(struct arm_cti *self);
extern struct arm_cti *cti_instance_by_jim_obj(Jim_Interp *interp, Jim_Obj *o);
extern int arm_cti_enable(struct arm_cti *self, bool enable); extern int arm_cti_enable(struct arm_cti *self, bool enable);
extern int arm_cti_ack_events(struct arm_cti *self, uint32_t event); extern int arm_cti_ack_events(struct arm_cti *self, uint32_t event);
extern int arm_cti_gate_channel(struct arm_cti *self, uint32_t channel); extern int arm_cti_gate_channel(struct arm_cti *self, uint32_t channel);
@ -70,4 +74,6 @@ extern int arm_cti_pulse_channel(struct arm_cti *self, uint32_t channel);
extern int arm_cti_set_channel(struct arm_cti *self, uint32_t channel); extern int arm_cti_set_channel(struct arm_cti *self, uint32_t channel);
extern int arm_cti_clear_channel(struct arm_cti *self, uint32_t channel); extern int arm_cti_clear_channel(struct arm_cti *self, uint32_t channel);
extern int cti_register_commands(struct command_context *cmd_ctx);
#endif /* OPENOCD_TARGET_ARM_CTI_H */ #endif /* OPENOCD_TARGET_ARM_CTI_H */

View File

@ -54,6 +54,7 @@
#include "image.h" #include "image.h"
#include "rtos/rtos.h" #include "rtos/rtos.h"
#include "transport/transport.h" #include "transport/transport.h"
#include "arm_cti.h"
/* default halt wait timeout (ms) */ /* default halt wait timeout (ms) */
#define DEFAULT_HALT_TIMEOUT 5000 #define DEFAULT_HALT_TIMEOUT 5000
@ -4513,7 +4514,6 @@ enum target_cfg_param {
TCFG_COREID, TCFG_COREID,
TCFG_CHAIN_POSITION, TCFG_CHAIN_POSITION,
TCFG_DBGBASE, TCFG_DBGBASE,
TCFG_CTIBASE,
TCFG_RTOS, TCFG_RTOS,
TCFG_DEFER_EXAMINE, TCFG_DEFER_EXAMINE,
}; };
@ -4529,7 +4529,6 @@ static Jim_Nvp nvp_config_opts[] = {
{ .name = "-coreid", .value = TCFG_COREID }, { .name = "-coreid", .value = TCFG_COREID },
{ .name = "-chain-position", .value = TCFG_CHAIN_POSITION }, { .name = "-chain-position", .value = TCFG_CHAIN_POSITION },
{ .name = "-dbgbase", .value = TCFG_DBGBASE }, { .name = "-dbgbase", .value = TCFG_DBGBASE },
{ .name = "-ctibase", .value = TCFG_CTIBASE },
{ .name = "-rtos", .value = TCFG_RTOS }, { .name = "-rtos", .value = TCFG_RTOS },
{ .name = "-defer-examine", .value = TCFG_DEFER_EXAMINE }, { .name = "-defer-examine", .value = TCFG_DEFER_EXAMINE },
{ .name = NULL, .value = -1 } { .name = NULL, .value = -1 }
@ -4796,20 +4795,6 @@ no_params:
Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->dbgbase)); Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->dbgbase));
/* loop for more */ /* loop for more */
break; break;
case TCFG_CTIBASE:
if (goi->isconfigure) {
e = Jim_GetOpt_Wide(goi, &w);
if (e != JIM_OK)
return e;
target->ctibase = (uint32_t)w;
target->ctibase_set = true;
} else {
if (goi->argc != 0)
goto no_params;
}
Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->ctibase));
/* loop for more */
break;
case TCFG_RTOS: case TCFG_RTOS:
/* RTOS */ /* RTOS */
{ {

View File

@ -186,10 +186,6 @@ struct target {
* system in place to support target specific options * system in place to support target specific options
* currently. */ * currently. */
bool ctibase_set; /* By default the debug base is not set */
uint32_t ctibase; /* Really a Cortex-A specific option, but there is no
* system in place to support target specific options
* currently. */
struct rtos *rtos; /* Instance of Real Time Operating System support */ struct rtos *rtos; /* Instance of Real Time Operating System support */
bool rtos_auto_detect; /* A flag that indicates that the RTOS has been specified as "auto" bool rtos_auto_detect; /* A flag that indicates that the RTOS has been specified as "auto"
* and must be detected when symbols are offered */ * and must be detected when symbols are offered */

View File

@ -30,6 +30,8 @@ set $_TARGETNAME.cti(3) 0x80320000
set _cores 4 set _cores 4
for { set _core 0 } { $_core < $_cores } { incr _core 1 } { for { set _core 0 } { $_core < $_cores } { incr _core 1 } {
cti create cti$_core -dap $_CHIPNAME.dap -ctibase [set $_TARGETNAME.cti($_core)] -ap-num 0
set _command "target create ${_TARGETNAME}$_core aarch64 \ set _command "target create ${_TARGETNAME}$_core aarch64 \
-chain-position $_CHIPNAME.dap -coreid $_core -ctibase [set $_TARGETNAME.cti($_core)]" -chain-position $_CHIPNAME.dap -coreid $_core -ctibase [set $_TARGETNAME.cti($_core)]"

View File

@ -34,8 +34,10 @@ set $_TARGETNAME.cti(7) 0x801DB000
set _cores 8 set _cores 8
for { set _core 0 } { $_core < $_cores } { incr _core 1 } { for { set _core 0 } { $_core < $_cores } { incr _core 1 } {
cti create cti$_core -chain-position $_CHIPNAME.dap -ctibase [set $_TARGETNAME.cti($_core)] -ap-num 0
set _command "target create ${_TARGETNAME}$_core aarch64 \ set _command "target create ${_TARGETNAME}$_core aarch64 \
-chain-position $_CHIPNAME.dap -coreid $_core -ctibase [set $_TARGETNAME.cti($_core)]" -chain-position $_CHIPNAME.dap -coreid $_core -cti cti$_core"
if { $_core != 0 } { if { $_core != 0 } {
# non-boot core examination may fail # non-boot core examination may fail
@ -52,5 +54,10 @@ for { set _core 0 } { $_core < $_cores } { incr _core 1 } {
eval $_smp_command eval $_smp_command
cti create cti.sys -chain-position hi6220.dap -ap-num 0 -ctibase 0x80003000
# declare the auxiliary Cortex-M3 core on AP #2 (runs mcuimage.bin) # declare the auxiliary Cortex-M3 core on AP #2 (runs mcuimage.bin)
target create ${_TARGETNAME}.m3 cortex_m -chain-position $_CHIPNAME.dap -ap-num 2 -defer-examine target create ${_TARGETNAME}.m3 cortex_m -chain-position $_CHIPNAME.dap -ap-num 2 -defer-examine
# declare the auxiliary Cortex-A7 core
target create ${_TARGETNAME}.a7 cortex_a -chain-position $_CHIPNAME.dap -dbgbase 0x80210000 -defer-examine

View File

@ -43,9 +43,11 @@ set _smp_command ""
for { set _core 0 } { $_core < $_cores } { incr _core 1 } { for { set _core 0 } { $_core < $_cores } { incr _core 1 } {
cti create cti$_core -chain-position $_CHIPNAME.dap -ctibase [lindex $_ctis $_core] -ap-num 0
set _command "target create ${_TARGETNAME}$_core aarch64 \ set _command "target create ${_TARGETNAME}$_core aarch64 \
-chain-position $_CHIPNAME.dap -coreid $_core \ -chain-position $_CHIPNAME.dap -coreid $_core \
-ctibase [lindex $_ctis $_core]" -cti cti$_core"
if { $_core != 0 } { if { $_core != 0 } {
# non-boot core examination may fail # non-boot core examination may fail