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 adapter_driver
*adapter_driver
;
39 #define ADI_BAD_CFG 0xBAD00000
41 /* DAP command support */
42 struct arm_dap_object
{
46 const struct swd_driver
*swd
;
49 static void dap_instance_init(struct adiv5_dap
*dap
)
52 /* Set up with safe defaults */
53 for (i
= 0; i
<= DP_APSEL_MAX
; i
++) {
55 dap
->ap
[i
].ap_num
= i
;
56 /* memaccess_tck max is 255 */
57 dap
->ap
[i
].memaccess_tck
= 255;
58 /* Number of bits for tar autoincrement, impl. dep. at least 10 */
59 dap
->ap
[i
].tar_autoincr_block
= (1<<10);
60 /* default CSW value */
61 dap
->ap
[i
].csw_default
= CSW_AHB_DEFAULT
;
62 dap
->ap
[i
].cfg_reg
= ADI_BAD_CFG
; /* mem_ap configuration reg (large physical addr, etc.) */
64 INIT_LIST_HEAD(&dap
->cmd_journal
);
65 INIT_LIST_HEAD(&dap
->cmd_pool
);
68 const char *adiv5_dap_name(struct adiv5_dap
*self
)
70 struct arm_dap_object
*obj
= container_of(self
, struct arm_dap_object
, dap
);
74 const struct swd_driver
*adiv5_dap_swd_driver(struct adiv5_dap
*self
)
76 struct arm_dap_object
*obj
= container_of(self
, struct arm_dap_object
, dap
);
80 struct adiv5_dap
*adiv5_get_dap(struct arm_dap_object
*obj
)
84 struct adiv5_dap
*dap_instance_by_jim_obj(Jim_Interp
*interp
, Jim_Obj
*o
)
86 struct arm_dap_object
*obj
= NULL
;
90 name
= Jim_GetString(o
, NULL
);
92 list_for_each_entry(obj
, &all_dap
, lh
) {
93 if (!strcmp(name
, obj
->name
)) {
104 static int dap_init_all(void)
106 struct arm_dap_object
*obj
;
109 LOG_DEBUG("Initializing all DAPs ...");
111 list_for_each_entry(obj
, &all_dap
, lh
) {
112 struct adiv5_dap
*dap
= &obj
->dap
;
114 /* with hla, dap is just a dummy */
115 if (transport_is_hla())
118 /* skip taps that are disabled */
119 if (!dap
->tap
->enabled
)
122 if (transport_is_swd()) {
123 dap
->ops
= &swd_dap_ops
;
124 obj
->swd
= adapter_driver
->swd_ops
;
125 } else if (transport_is_dapdirect_swd()) {
126 dap
->ops
= adapter_driver
->dap_swd_ops
;
127 } else if (transport_is_dapdirect_jtag()) {
128 dap
->ops
= adapter_driver
->dap_jtag_ops
;
130 dap
->ops
= &jtag_dp_ops
;
132 retval
= dap
->ops
->connect(dap
);
133 if (retval
!= ERROR_OK
)
140 int dap_cleanup_all(void)
142 struct arm_dap_object
*obj
, *tmp
;
143 struct adiv5_dap
*dap
;
145 list_for_each_entry_safe(obj
, tmp
, &all_dap
, lh
) {
147 if (dap
->ops
&& dap
->ops
->quit
)
159 CFG_IGNORE_SYSPWRUPACK
,
162 static const struct jim_nvp nvp_config_opts
[] = {
163 { .name
= "-chain-position", .value
= CFG_CHAIN_POSITION
},
164 { .name
= "-ignore-syspwrupack", .value
= CFG_IGNORE_SYSPWRUPACK
},
165 { .name
= NULL
, .value
= -1 }
168 static int dap_configure(struct jim_getopt_info
*goi
, struct arm_dap_object
*dap
)
170 struct jtag_tap
*tap
= NULL
;
174 /* parse config or cget options ... */
175 while (goi
->argc
> 0) {
176 Jim_SetEmptyResult(goi
->interp
);
178 e
= jim_getopt_nvp(goi
, nvp_config_opts
, &n
);
180 jim_getopt_nvp_unknown(goi
, nvp_config_opts
, 0);
184 case CFG_CHAIN_POSITION
: {
186 e
= jim_getopt_obj(goi
, &o_t
);
189 tap
= jtag_tap_by_jim_obj(goi
->interp
, o_t
);
191 Jim_SetResultString(goi
->interp
, "-chain-position is invalid", -1);
197 case CFG_IGNORE_SYSPWRUPACK
:
198 dap
->dap
.ignore_syspwrupack
= true;
206 Jim_SetResultString(goi
->interp
, "-chain-position required when creating DAP", -1);
210 dap_instance_init(&dap
->dap
);
216 static int dap_create(struct jim_getopt_info
*goi
)
218 struct command_context
*cmd_ctx
;
219 static struct arm_dap_object
*dap
;
225 cmd_ctx
= current_command_context(goi
->interp
);
226 assert(cmd_ctx
!= NULL
);
229 Jim_WrongNumArgs(goi
->interp
, 1, goi
->argv
, "?name? ..options...");
233 jim_getopt_obj(goi
, &new_cmd
);
234 /* does this command exist? */
235 cmd
= Jim_GetCommand(goi
->interp
, new_cmd
, JIM_ERRMSG
);
237 cp
= Jim_GetString(new_cmd
, NULL
);
238 Jim_SetResultFormatted(goi
->interp
, "Command: %s Exists", cp
);
243 dap
= calloc(1, sizeof(struct arm_dap_object
));
247 e
= dap_configure(goi
, dap
);
253 cp
= Jim_GetString(new_cmd
, NULL
);
254 dap
->name
= strdup(cp
);
256 struct command_registration dap_commands
[] = {
260 .help
= "dap instance command group",
262 .chain
= dap_instance_commands
,
264 COMMAND_REGISTRATION_DONE
267 /* don't expose the instance commands when using hla */
268 if (transport_is_hla())
269 dap_commands
[0].chain
= NULL
;
271 e
= register_commands_with_data(cmd_ctx
, NULL
, dap_commands
, dap
);
275 list_add_tail(&dap
->lh
, &all_dap
);
280 static int jim_dap_create(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
282 struct jim_getopt_info goi
;
283 jim_getopt_setup(&goi
, interp
, argc
- 1, argv
+ 1);
285 Jim_WrongNumArgs(goi
.interp
, goi
.argc
, goi
.argv
,
286 "<name> [<dap_options> ...]");
289 return dap_create(&goi
);
292 static int jim_dap_names(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
294 struct arm_dap_object
*obj
;
297 Jim_WrongNumArgs(interp
, 1, argv
, "Too many parameters");
300 Jim_SetResult(interp
, Jim_NewListObj(interp
, NULL
, 0));
301 list_for_each_entry(obj
, &all_dap
, lh
) {
302 Jim_ListAppendElement(interp
, Jim_GetResult(interp
),
303 Jim_NewStringObj(interp
, obj
->name
, -1));
308 COMMAND_HANDLER(handle_dap_init
)
310 return dap_init_all();
313 COMMAND_HANDLER(handle_dap_info_command
)
315 struct target
*target
= get_current_target(CMD_CTX
);
316 struct arm
*arm
= target_to_arm(target
);
317 struct adiv5_dap
*dap
= arm
->dap
;
321 LOG_ERROR("DAP instance not available. Probably a HLA target...");
322 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
330 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], apsel
);
331 if (apsel
> DP_APSEL_MAX
)
332 return ERROR_COMMAND_SYNTAX_ERROR
;
335 return ERROR_COMMAND_SYNTAX_ERROR
;
338 return dap_info_command(CMD
, &dap
->ap
[apsel
]);
341 static const struct command_registration dap_subcommand_handlers
[] = {
345 .jim_handler
= jim_dap_create
,
346 .usage
= "name '-chain-position' name",
347 .help
= "Creates a new DAP instance",
352 .jim_handler
= jim_dap_names
,
354 .help
= "Lists all registered DAP instances by name",
359 .handler
= handle_dap_init
,
361 .help
= "Initialize all registered DAP instances"
365 .handler
= handle_dap_info_command
,
366 .mode
= COMMAND_EXEC
,
367 .help
= "display ROM table for MEM-AP of current target "
368 "(default currently selected AP)",
371 COMMAND_REGISTRATION_DONE
374 static const struct command_registration dap_commands
[] = {
377 .mode
= COMMAND_CONFIG
,
378 .help
= "DAP commands",
379 .chain
= dap_subcommand_handlers
,
382 COMMAND_REGISTRATION_DONE
385 int dap_register_commands(struct command_context
*cmd_ctx
)
387 return register_commands(cmd_ctx
, NULL
, dap_commands
);