1 /***************************************************************************
2 * Copyright (C) 2016 by Matthias Welwarsky *
4 * This program is free software; you can redistribute it and/or modify *
5 * it under the terms of the GNU General Public License as published by *
6 * the Free Software Foundation; either version 2 of the License, or *
7 * (at your option) any later version. *
9 * This program is distributed in the hope that it will be useful, *
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
12 * GNU General Public License for more details. *
14 * You should have received a copy of the GNU General Public License *
15 * along with this program; if not, write to the *
16 * Free Software Foundation, Inc., *
18 ***************************************************************************/
26 #include "target/arm_adi_v5.h"
27 #include "target/arm.h"
28 #include "helper/list.h"
29 #include "helper/command.h"
30 #include "transport/transport.h"
31 #include "jtag/interface.h"
33 static LIST_HEAD(all_dap
);
35 extern const struct dap_ops swd_dap_ops
;
36 extern const struct dap_ops jtag_dp_ops
;
37 extern struct jtag_interface
*jtag_interface
;
39 /* DAP command support */
40 struct arm_dap_object
{
44 const struct swd_driver
*swd
;
47 static void dap_instance_init(struct adiv5_dap
*dap
)
50 /* Set up with safe defaults */
51 for (i
= 0; i
<= 255; i
++) {
53 dap
->ap
[i
].ap_num
= i
;
54 /* memaccess_tck max is 255 */
55 dap
->ap
[i
].memaccess_tck
= 255;
56 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
57 dap
->ap
[i
].tar_autoincr_block
= (1<<10);
59 INIT_LIST_HEAD(&dap
->cmd_journal
);
62 const char *adiv5_dap_name(struct adiv5_dap
*self
)
64 struct arm_dap_object
*obj
= container_of(self
, struct arm_dap_object
, dap
);
68 const struct swd_driver
*adiv5_dap_swd_driver(struct adiv5_dap
*self
)
70 struct arm_dap_object
*obj
= container_of(self
, struct arm_dap_object
, dap
);
74 struct adiv5_dap
*adiv5_get_dap(struct arm_dap_object
*obj
)
78 struct adiv5_dap
*dap_instance_by_jim_obj(Jim_Interp
*interp
, Jim_Obj
*o
)
80 struct arm_dap_object
*obj
= NULL
;
84 name
= Jim_GetString(o
, NULL
);
86 list_for_each_entry(obj
, &all_dap
, lh
) {
87 if (!strcmp(name
, obj
->name
)) {
98 static int dap_init_all(void)
100 struct arm_dap_object
*obj
;
103 LOG_DEBUG("Initializing all DAPs ...");
105 list_for_each_entry(obj
, &all_dap
, lh
) {
106 struct adiv5_dap
*dap
= &obj
->dap
;
108 /* with hla, dap is just a dummy */
109 if (transport_is_hla())
112 /* skip taps that are disabled */
113 if (!dap
->tap
->enabled
)
116 if (transport_is_swd()) {
117 dap
->ops
= &swd_dap_ops
;
118 obj
->swd
= jtag_interface
->swd
;
120 dap
->ops
= &jtag_dp_ops
;
122 retval
= dap
->ops
->connect(dap
);
123 if (retval
!= ERROR_OK
)
130 int dap_cleanup_all(void)
132 struct arm_dap_object
*obj
, *tmp
;
134 list_for_each_entry_safe(obj
, tmp
, &all_dap
, lh
) {
146 static const Jim_Nvp nvp_config_opts
[] = {
147 { .name
= "-chain-position", .value
= CFG_CHAIN_POSITION
},
148 { .name
= NULL
, .value
= -1 }
151 static int dap_configure(Jim_GetOptInfo
*goi
, struct arm_dap_object
*dap
)
153 struct jtag_tap
*tap
= NULL
;
157 /* parse config or cget options ... */
158 while (goi
->argc
> 0) {
159 Jim_SetEmptyResult(goi
->interp
);
161 e
= Jim_GetOpt_Nvp(goi
, nvp_config_opts
, &n
);
163 Jim_GetOpt_NvpUnknown(goi
, nvp_config_opts
, 0);
167 case CFG_CHAIN_POSITION
: {
169 e
= Jim_GetOpt_Obj(goi
, &o_t
);
172 tap
= jtag_tap_by_jim_obj(goi
->interp
, o_t
);
174 Jim_SetResultString(goi
->interp
, "-chain-position is invalid", -1);
186 Jim_SetResultString(goi
->interp
, "-chain-position required when creating DAP", -1);
190 dap_instance_init(&dap
->dap
);
196 static int dap_create(Jim_GetOptInfo
*goi
)
198 struct command_context
*cmd_ctx
;
199 static struct arm_dap_object
*dap
;
205 cmd_ctx
= current_command_context(goi
->interp
);
206 assert(cmd_ctx
!= NULL
);
209 Jim_WrongNumArgs(goi
->interp
, 1, goi
->argv
, "?name? ..options...");
213 Jim_GetOpt_Obj(goi
, &new_cmd
);
214 /* does this command exist? */
215 cmd
= Jim_GetCommand(goi
->interp
, new_cmd
, JIM_ERRMSG
);
217 cp
= Jim_GetString(new_cmd
, NULL
);
218 Jim_SetResultFormatted(goi
->interp
, "Command: %s Exists", cp
);
223 dap
= calloc(1, sizeof(struct arm_dap_object
));
227 e
= dap_configure(goi
, dap
);
233 cp
= Jim_GetString(new_cmd
, NULL
);
234 dap
->name
= strdup(cp
);
236 struct command_registration dap_commands
[] = {
240 .help
= "dap instance command group",
242 .chain
= dap_instance_commands
,
244 COMMAND_REGISTRATION_DONE
247 /* don't expose the instance commands when using hla */
248 if (transport_is_hla())
249 dap_commands
[0].chain
= NULL
;
251 e
= register_commands(cmd_ctx
, NULL
, dap_commands
);
255 struct command
*c
= command_find_in_context(cmd_ctx
, cp
);
257 command_set_handler_data(c
, dap
);
259 list_add_tail(&dap
->lh
, &all_dap
);
261 return (ERROR_OK
== e
) ? JIM_OK
: JIM_ERR
;
264 static int jim_dap_create(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
267 Jim_GetOpt_Setup(&goi
, interp
, argc
- 1, argv
+ 1);
269 Jim_WrongNumArgs(goi
.interp
, goi
.argc
, goi
.argv
,
270 "<name> [<dap_options> ...]");
273 return dap_create(&goi
);
276 static int jim_dap_names(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
278 struct arm_dap_object
*obj
;
281 Jim_WrongNumArgs(interp
, 1, argv
, "Too many parameters");
284 Jim_SetResult(interp
, Jim_NewListObj(interp
, NULL
, 0));
285 list_for_each_entry(obj
, &all_dap
, lh
) {
286 Jim_ListAppendElement(interp
, Jim_GetResult(interp
),
287 Jim_NewStringObj(interp
, obj
->name
, -1));
292 COMMAND_HANDLER(handle_dap_init
)
294 return dap_init_all();
297 COMMAND_HANDLER(handle_dap_info_command
)
299 struct target
*target
= get_current_target(CMD_CTX
);
300 struct arm
*arm
= target_to_arm(target
);
301 struct adiv5_dap
*dap
= arm
->dap
;
309 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], apsel
);
311 return ERROR_COMMAND_SYNTAX_ERROR
;
314 return ERROR_COMMAND_SYNTAX_ERROR
;
317 return dap_info_command(CMD_CTX
, &dap
->ap
[apsel
]);
320 static const struct command_registration dap_subcommand_handlers
[] = {
324 .jim_handler
= jim_dap_create
,
325 .usage
= "name '-chain-position' name",
326 .help
= "Creates a new DAP instance",
331 .jim_handler
= jim_dap_names
,
333 .help
= "Lists all registered DAP instances by name",
338 .handler
= handle_dap_init
,
340 .help
= "Initialize all registered DAP instances"
344 .handler
= handle_dap_info_command
,
345 .mode
= COMMAND_EXEC
,
346 .help
= "display ROM table for MEM-AP of current target "
347 "(default currently selected AP)",
350 COMMAND_REGISTRATION_DONE
353 static const struct command_registration dap_commands
[] = {
356 .mode
= COMMAND_CONFIG
,
357 .help
= "DAP commands",
358 .chain
= dap_subcommand_handlers
,
360 COMMAND_REGISTRATION_DONE
363 int dap_register_commands(struct command_context
*cmd_ctx
)
365 return register_commands(cmd_ctx
, NULL
, dap_commands
);