forked from auracaster/openocd
target: restructure dap support
- add 'dap create' command to create dap instances - move all dap subcmmand into the dap instance commands - keep 'dap info' for convenience - change all armv7 and armv8 targets to take a dap instance instead of a jtag chain position - restructure tap/dap/target relations, jtag tap no longer references the dap, daps are now independently created and initialized. - clean up swd connect - re-initialize DAP also on JTAG errors (e.g. after reset, power cycle) - update documentation - update target files Change-Id: I322cf3969b5407c25d1d3962f9d9b9bc1df067d9 Signed-off-by: Matthias Welwarsky <matthias.welwarsky@sysgo.com> Reviewed-on: http://openocd.zylin.com/4468 Tested-by: jenkins Reviewed-by: Matthias Welwarsky <matthias@welwarsky.de>
This commit is contained in:
committed by
Matthias Welwarsky
parent
7274090456
commit
2231da8ec4
@@ -76,6 +76,7 @@
|
||||
#include <helper/jep106.h>
|
||||
#include <helper/time_support.h>
|
||||
#include <helper/list.h>
|
||||
#include <helper/jim-nvp.h>
|
||||
|
||||
/* ARM ADI Specification requires at least 10 bits used for TAR autoincrement */
|
||||
|
||||
@@ -614,33 +615,8 @@ int mem_ap_write_buf_noincr(struct adiv5_ap *ap,
|
||||
|
||||
#define DAP_POWER_DOMAIN_TIMEOUT (10)
|
||||
|
||||
/* FIXME don't import ... just initialize as
|
||||
* part of DAP transport setup
|
||||
*/
|
||||
extern const struct dap_ops jtag_dp_ops;
|
||||
|
||||
/*--------------------------------------------------------------------------*/
|
||||
|
||||
/**
|
||||
* Create a new DAP
|
||||
*/
|
||||
struct adiv5_dap *dap_init(void)
|
||||
{
|
||||
struct adiv5_dap *dap = calloc(1, sizeof(struct adiv5_dap));
|
||||
int i;
|
||||
/* Set up with safe defaults */
|
||||
for (i = 0; i <= 255; i++) {
|
||||
dap->ap[i].dap = dap;
|
||||
dap->ap[i].ap_num = i;
|
||||
/* memaccess_tck max is 255 */
|
||||
dap->ap[i].memaccess_tck = 255;
|
||||
/* Number of bits for tar autoincrement, impl. dep. at least 10 */
|
||||
dap->ap[i].tar_autoincr_block = (1<<10);
|
||||
}
|
||||
INIT_LIST_HEAD(&dap->cmd_journal);
|
||||
return dap;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invalidate cached DP select and cached TAR and CSW of all APs
|
||||
*/
|
||||
@@ -667,14 +643,7 @@ int dap_dp_init(struct adiv5_dap *dap)
|
||||
{
|
||||
int retval;
|
||||
|
||||
LOG_DEBUG(" ");
|
||||
/* JTAG-DP or SWJ-DP, in JTAG mode
|
||||
* ... for SWD mode this is patched as part
|
||||
* of link switchover
|
||||
* FIXME: This should already be setup by the respective transport specific DAP creation.
|
||||
*/
|
||||
if (!dap->ops)
|
||||
dap->ops = &jtag_dp_ops;
|
||||
LOG_DEBUG("%s", adiv5_dap_name(dap));
|
||||
|
||||
dap_invalidate_cache(dap);
|
||||
|
||||
@@ -1376,7 +1345,7 @@ static int dap_rom_display(struct command_context *cmd_ctx,
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static int dap_info_command(struct command_context *cmd_ctx,
|
||||
int dap_info_command(struct command_context *cmd_ctx,
|
||||
struct adiv5_ap *ap)
|
||||
{
|
||||
int retval;
|
||||
@@ -1434,46 +1403,131 @@ static int dap_info_command(struct command_context *cmd_ctx,
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
enum adiv5_cfg_param {
|
||||
CFG_DAP,
|
||||
CFG_AP_NUM
|
||||
};
|
||||
|
||||
static const Jim_Nvp nvp_config_opts[] = {
|
||||
{ .name = "-dap", .value = CFG_DAP },
|
||||
{ .name = "-ap-num", .value = CFG_AP_NUM },
|
||||
{ .name = NULL, .value = -1 }
|
||||
};
|
||||
|
||||
int adiv5_jim_configure(struct target *target, Jim_GetOptInfo *goi)
|
||||
{
|
||||
struct adiv5_private_config *pc;
|
||||
const char *arg;
|
||||
jim_wide ap_num;
|
||||
int e;
|
||||
|
||||
/* check if argv[0] is for us */
|
||||
arg = Jim_GetString(goi->argv[0], NULL);
|
||||
if (strcmp(arg, "-ap-num"))
|
||||
return JIM_CONTINUE;
|
||||
|
||||
e = Jim_GetOpt_String(goi, &arg, NULL);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
if (goi->argc == 0) {
|
||||
Jim_WrongNumArgs(goi->interp, goi->argc, goi->argv, "-ap-num ?ap-number? ...");
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
e = Jim_GetOpt_Wide(goi, &ap_num);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
if (target->private_config == NULL) {
|
||||
pc = (struct adiv5_private_config *)target->private_config;
|
||||
if (pc == NULL) {
|
||||
pc = calloc(1, sizeof(struct adiv5_private_config));
|
||||
pc->ap_num = -1;
|
||||
target->private_config = pc;
|
||||
pc->ap_num = ap_num;
|
||||
}
|
||||
|
||||
target->has_dap = true;
|
||||
|
||||
if (goi->argc > 0) {
|
||||
Jim_Nvp *n;
|
||||
|
||||
Jim_SetEmptyResult(goi->interp);
|
||||
|
||||
/* check first if topmost item is for us */
|
||||
e = Jim_Nvp_name2value_obj(goi->interp, nvp_config_opts,
|
||||
goi->argv[0], &n);
|
||||
if (e != JIM_OK)
|
||||
return JIM_CONTINUE;
|
||||
|
||||
e = Jim_GetOpt_Obj(goi, NULL);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
|
||||
switch (n->value) {
|
||||
case CFG_DAP:
|
||||
if (goi->isconfigure) {
|
||||
Jim_Obj *o_t;
|
||||
struct adiv5_dap *dap;
|
||||
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 name invalid!", -1);
|
||||
return JIM_ERR;
|
||||
}
|
||||
if (pc->dap != NULL && pc->dap != dap) {
|
||||
Jim_SetResultString(goi->interp,
|
||||
"DAP assignment cannot be changed after target was created!", -1);
|
||||
return JIM_ERR;
|
||||
}
|
||||
if (target->tap_configured) {
|
||||
Jim_SetResultString(goi->interp,
|
||||
"-chain-position and -dap configparams are mutually exclusive!", -1);
|
||||
return JIM_ERR;
|
||||
}
|
||||
pc->dap = dap;
|
||||
target->tap = dap->tap;
|
||||
target->dap_configured = true;
|
||||
} else {
|
||||
if (goi->argc != 0) {
|
||||
Jim_WrongNumArgs(goi->interp,
|
||||
goi->argc, goi->argv,
|
||||
"NO PARAMS");
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
if (pc->dap == NULL) {
|
||||
Jim_SetResultString(goi->interp, "DAP not configured", -1);
|
||||
return JIM_ERR;
|
||||
}
|
||||
Jim_SetResultString(goi->interp, adiv5_dap_name(pc->dap), -1);
|
||||
}
|
||||
break;
|
||||
|
||||
case CFG_AP_NUM:
|
||||
if (goi->isconfigure) {
|
||||
jim_wide ap_num;
|
||||
e = Jim_GetOpt_Wide(goi, &ap_num);
|
||||
if (e != JIM_OK)
|
||||
return e;
|
||||
pc->ap_num = ap_num;
|
||||
} else {
|
||||
if (goi->argc != 0) {
|
||||
Jim_WrongNumArgs(goi->interp,
|
||||
goi->argc, goi->argv,
|
||||
"NO PARAMS");
|
||||
return JIM_ERR;
|
||||
}
|
||||
|
||||
if (pc->ap_num < 0) {
|
||||
Jim_SetResultString(goi->interp, "AP number not configured", -1);
|
||||
return JIM_ERR;
|
||||
}
|
||||
Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, (int)pc->ap_num));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return JIM_OK;
|
||||
}
|
||||
|
||||
int adiv5_verify_config(struct adiv5_private_config *pc)
|
||||
{
|
||||
if (pc == NULL)
|
||||
return ERROR_FAIL;
|
||||
|
||||
if (pc->dap == NULL)
|
||||
return ERROR_FAIL;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
|
||||
uint32_t apsel;
|
||||
|
||||
switch (CMD_ARGC) {
|
||||
@@ -1494,10 +1548,7 @@ COMMAND_HANDLER(handle_dap_info_command)
|
||||
|
||||
COMMAND_HANDLER(dap_baseaddr_command)
|
||||
{
|
||||
struct target *target = get_current_target(CMD_CTX);
|
||||
struct arm *arm = target_to_arm(target);
|
||||
struct adiv5_dap *dap = arm->dap;
|
||||
|
||||
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
|
||||
uint32_t apsel, baseaddr;
|
||||
int retval;
|
||||
|
||||
@@ -1534,10 +1585,7 @@ COMMAND_HANDLER(dap_baseaddr_command)
|
||||
|
||||
COMMAND_HANDLER(dap_memaccess_command)
|
||||
{
|
||||
struct target *target = get_current_target(CMD_CTX);
|
||||
struct arm *arm = target_to_arm(target);
|
||||
struct adiv5_dap *dap = arm->dap;
|
||||
|
||||
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
|
||||
uint32_t memaccess_tck;
|
||||
|
||||
switch (CMD_ARGC) {
|
||||
@@ -1560,10 +1608,7 @@ COMMAND_HANDLER(dap_memaccess_command)
|
||||
|
||||
COMMAND_HANDLER(dap_apsel_command)
|
||||
{
|
||||
struct target *target = get_current_target(CMD_CTX);
|
||||
struct arm *arm = target_to_arm(target);
|
||||
struct adiv5_dap *dap = arm->dap;
|
||||
|
||||
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
|
||||
uint32_t apsel, apid;
|
||||
int retval;
|
||||
|
||||
@@ -1598,11 +1643,9 @@ COMMAND_HANDLER(dap_apsel_command)
|
||||
|
||||
COMMAND_HANDLER(dap_apcsw_command)
|
||||
{
|
||||
struct target *target = get_current_target(CMD_CTX);
|
||||
struct arm *arm = target_to_arm(target);
|
||||
struct adiv5_dap *dap = arm->dap;
|
||||
|
||||
uint32_t apcsw = dap->ap[dap->apsel].csw_default, sprot = 0;
|
||||
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
|
||||
uint32_t apcsw = dap->ap[dap->apsel].csw_default;
|
||||
uint32_t sprot = 0;
|
||||
|
||||
switch (CMD_ARGC) {
|
||||
case 0:
|
||||
@@ -1631,10 +1674,7 @@ COMMAND_HANDLER(dap_apcsw_command)
|
||||
|
||||
COMMAND_HANDLER(dap_apid_command)
|
||||
{
|
||||
struct target *target = get_current_target(CMD_CTX);
|
||||
struct arm *arm = target_to_arm(target);
|
||||
struct adiv5_dap *dap = arm->dap;
|
||||
|
||||
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
|
||||
uint32_t apsel, apid;
|
||||
int retval;
|
||||
|
||||
@@ -1666,10 +1706,7 @@ COMMAND_HANDLER(dap_apid_command)
|
||||
|
||||
COMMAND_HANDLER(dap_apreg_command)
|
||||
{
|
||||
struct target *target = get_current_target(CMD_CTX);
|
||||
struct arm *arm = target_to_arm(target);
|
||||
struct adiv5_dap *dap = arm->dap;
|
||||
|
||||
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
|
||||
uint32_t apsel, reg, value;
|
||||
int retval;
|
||||
|
||||
@@ -1705,10 +1742,7 @@ COMMAND_HANDLER(dap_apreg_command)
|
||||
|
||||
COMMAND_HANDLER(dap_ti_be_32_quirks_command)
|
||||
{
|
||||
struct target *target = get_current_target(CMD_CTX);
|
||||
struct arm *arm = target_to_arm(target);
|
||||
struct adiv5_dap *dap = arm->dap;
|
||||
|
||||
struct adiv5_dap *dap = adiv5_get_dap(CMD_DATA);
|
||||
uint32_t enable = dap->ti_be_32_quirks;
|
||||
|
||||
switch (CMD_ARGC) {
|
||||
@@ -1729,7 +1763,7 @@ COMMAND_HANDLER(dap_ti_be_32_quirks_command)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct command_registration dap_commands[] = {
|
||||
const struct command_registration dap_instance_commands[] = {
|
||||
{
|
||||
.name = "info",
|
||||
.handler = handle_dap_info_command,
|
||||
@@ -1795,14 +1829,3 @@ static const struct command_registration dap_commands[] = {
|
||||
},
|
||||
COMMAND_REGISTRATION_DONE
|
||||
};
|
||||
|
||||
const struct command_registration dap_command_handlers[] = {
|
||||
{
|
||||
.name = "dap",
|
||||
.mode = COMMAND_EXEC,
|
||||
.help = "DAP command group",
|
||||
.usage = "",
|
||||
.chain = dap_commands,
|
||||
},
|
||||
COMMAND_REGISTRATION_DONE
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user