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 /* 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
<= DP_APSEL_MAX
; 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);
58 /* default CSW value */
59 dap
->ap
[i
].csw_default
= CSW_AHB_DEFAULT
;
60 dap
->ap
[i
].cfg_reg
= MEM_AP_REG_CFG_INVALID
; /* mem_ap configuration reg (large physical addr, etc.) */
62 INIT_LIST_HEAD(&dap
->cmd_journal
);
63 INIT_LIST_HEAD(&dap
->cmd_pool
);
66 const char *adiv5_dap_name(struct adiv5_dap
*self
)
68 struct arm_dap_object
*obj
= container_of(self
, struct arm_dap_object
, dap
);
72 const struct swd_driver
*adiv5_dap_swd_driver(struct adiv5_dap
*self
)
74 struct arm_dap_object
*obj
= container_of(self
, struct arm_dap_object
, dap
);
78 struct adiv5_dap
*adiv5_get_dap(struct arm_dap_object
*obj
)
82 struct adiv5_dap
*dap_instance_by_jim_obj(Jim_Interp
*interp
, Jim_Obj
*o
)
84 struct arm_dap_object
*obj
= NULL
;
88 name
= Jim_GetString(o
, NULL
);
90 list_for_each_entry(obj
, &all_dap
, lh
) {
91 if (!strcmp(name
, obj
->name
)) {
102 static int dap_init_all(void)
104 struct arm_dap_object
*obj
;
107 LOG_DEBUG("Initializing all DAPs ...");
109 list_for_each_entry(obj
, &all_dap
, lh
) {
110 struct adiv5_dap
*dap
= &obj
->dap
;
112 /* with hla, dap is just a dummy */
113 if (transport_is_hla())
116 /* skip taps that are disabled */
117 if (!dap
->tap
->enabled
)
120 if (transport_is_swd()) {
121 dap
->ops
= &swd_dap_ops
;
122 obj
->swd
= adapter_driver
->swd_ops
;
123 } else if (transport_is_dapdirect_swd()) {
124 dap
->ops
= adapter_driver
->dap_swd_ops
;
125 } else if (transport_is_dapdirect_jtag()) {
126 dap
->ops
= adapter_driver
->dap_jtag_ops
;
128 dap
->ops
= &jtag_dp_ops
;
130 retval
= dap
->ops
->connect(dap
);
131 if (retval
!= ERROR_OK
)
138 int dap_cleanup_all(void)
140 struct arm_dap_object
*obj
, *tmp
;
141 struct adiv5_dap
*dap
;
143 list_for_each_entry_safe(obj
, tmp
, &all_dap
, lh
) {
145 if (dap
->ops
&& dap
->ops
->quit
)
157 CFG_IGNORE_SYSPWRUPACK
,
160 static const struct jim_nvp nvp_config_opts
[] = {
161 { .name
= "-chain-position", .value
= CFG_CHAIN_POSITION
},
162 { .name
= "-ignore-syspwrupack", .value
= CFG_IGNORE_SYSPWRUPACK
},
163 { .name
= NULL
, .value
= -1 }
166 static int dap_configure(struct jim_getopt_info
*goi
, struct arm_dap_object
*dap
)
168 struct jtag_tap
*tap
= NULL
;
172 /* parse config or cget options ... */
173 while (goi
->argc
> 0) {
174 Jim_SetEmptyResult(goi
->interp
);
176 e
= jim_getopt_nvp(goi
, nvp_config_opts
, &n
);
178 jim_getopt_nvp_unknown(goi
, nvp_config_opts
, 0);
182 case CFG_CHAIN_POSITION
: {
184 e
= jim_getopt_obj(goi
, &o_t
);
187 tap
= jtag_tap_by_jim_obj(goi
->interp
, o_t
);
189 Jim_SetResultString(goi
->interp
, "-chain-position is invalid", -1);
195 case CFG_IGNORE_SYSPWRUPACK
:
196 dap
->dap
.ignore_syspwrupack
= true;
204 Jim_SetResultString(goi
->interp
, "-chain-position required when creating DAP", -1);
208 dap_instance_init(&dap
->dap
);
214 static int dap_create(struct jim_getopt_info
*goi
)
216 struct command_context
*cmd_ctx
;
217 static struct arm_dap_object
*dap
;
223 cmd_ctx
= current_command_context(goi
->interp
);
227 Jim_WrongNumArgs(goi
->interp
, 1, goi
->argv
, "?name? ..options...");
231 jim_getopt_obj(goi
, &new_cmd
);
232 /* does this command exist? */
233 cmd
= Jim_GetCommand(goi
->interp
, new_cmd
, JIM_NONE
);
235 cp
= Jim_GetString(new_cmd
, NULL
);
236 Jim_SetResultFormatted(goi
->interp
, "Command: %s Exists", cp
);
241 dap
= calloc(1, sizeof(struct arm_dap_object
));
245 e
= dap_configure(goi
, dap
);
251 cp
= Jim_GetString(new_cmd
, NULL
);
252 dap
->name
= strdup(cp
);
254 struct command_registration dap_commands
[] = {
258 .help
= "dap instance command group",
260 .chain
= dap_instance_commands
,
262 COMMAND_REGISTRATION_DONE
265 /* don't expose the instance commands when using hla */
266 if (transport_is_hla())
267 dap_commands
[0].chain
= NULL
;
269 e
= register_commands_with_data(cmd_ctx
, NULL
, dap_commands
, dap
);
273 list_add_tail(&dap
->lh
, &all_dap
);
278 static int jim_dap_create(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
280 struct jim_getopt_info goi
;
281 jim_getopt_setup(&goi
, interp
, argc
- 1, argv
+ 1);
283 Jim_WrongNumArgs(goi
.interp
, goi
.argc
, goi
.argv
,
284 "<name> [<dap_options> ...]");
287 return dap_create(&goi
);
290 static int jim_dap_names(Jim_Interp
*interp
, int argc
, Jim_Obj
*const *argv
)
292 struct arm_dap_object
*obj
;
295 Jim_WrongNumArgs(interp
, 1, argv
, "Too many parameters");
298 Jim_SetResult(interp
, Jim_NewListObj(interp
, NULL
, 0));
299 list_for_each_entry(obj
, &all_dap
, lh
) {
300 Jim_ListAppendElement(interp
, Jim_GetResult(interp
),
301 Jim_NewStringObj(interp
, obj
->name
, -1));
306 COMMAND_HANDLER(handle_dap_init
)
308 return dap_init_all();
311 COMMAND_HANDLER(handle_dap_info_command
)
313 struct target
*target
= get_current_target(CMD_CTX
);
314 struct arm
*arm
= target_to_arm(target
);
315 struct adiv5_dap
*dap
= arm
->dap
;
319 LOG_ERROR("DAP instance not available. Probably a HLA target...");
320 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
328 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[0], apsel
);
329 if (apsel
> DP_APSEL_MAX
)
330 return ERROR_COMMAND_SYNTAX_ERROR
;
333 return ERROR_COMMAND_SYNTAX_ERROR
;
336 return dap_info_command(CMD
, &dap
->ap
[apsel
]);
339 static const struct command_registration dap_subcommand_handlers
[] = {
343 .jim_handler
= jim_dap_create
,
344 .usage
= "name '-chain-position' name",
345 .help
= "Creates a new DAP instance",
350 .jim_handler
= jim_dap_names
,
352 .help
= "Lists all registered DAP instances by name",
357 .handler
= handle_dap_init
,
359 .help
= "Initialize all registered DAP instances"
363 .handler
= handle_dap_info_command
,
364 .mode
= COMMAND_EXEC
,
365 .help
= "display ROM table for MEM-AP of current target "
366 "(default currently selected AP)",
369 COMMAND_REGISTRATION_DONE
372 static const struct command_registration dap_commands
[] = {
375 .mode
= COMMAND_CONFIG
,
376 .help
= "DAP commands",
377 .chain
= dap_subcommand_handlers
,
380 COMMAND_REGISTRATION_DONE
383 int dap_register_commands(struct command_context
*cmd_ctx
)
385 return register_commands(cmd_ctx
, NULL
, dap_commands
);