adi_v5_dapdirect: add support for adapter drivers that provide DAP API 03/4903/8
authorAntonio Borneo <borneo.antonio@gmail.com>
Wed, 23 Jan 2019 09:52:28 +0000 (10:52 +0100)
committerTomas Vanek <vanekt@fbl.cz>
Tue, 14 Jan 2020 11:40:25 +0000 (11:40 +0000)
Some high level adapters, like STLINK-V3 and new firmware for
ST-Link/V2, provide API to directly access the DAP registers
hiding the details of the physical transport JTAG or SWD.
OpenOCD has already the intermediate API in struct dap_ops that
are suitable for such adapters, but are not exposed to the
adapter drivers.

Add in struct adapter_driver two independent struct dap_ops for
the cases of physical JTAG and SWD transport.
Add new transport names "dapdirect_jtag" and "dapdirect_swd", to
be used by the drivers that provide one or both DAP API.
Add the necessarily glue in target/adi_v5_dapdirect.c

Change-Id: I2bb8e3a80fba750f2c218d877cfa5888428e3c28
Signed-off-by: Antonio Borneo <borneo.antonio@gmail.com>
Reviewed-on: http://openocd.zylin.com/4903
Tested-by: jenkins
Reviewed-by: Tomas Vanek <vanekt@fbl.cz>
src/jtag/core.c
src/jtag/interface.h
src/target/Makefile.am
src/target/adi_v5_dapdirect.c [new file with mode: 0644]
src/target/arm_dap.c
src/transport/transport.h

index 6239573d105ebf881cbefa3b1d7e059a6c235f85..111b122d95ef70f9cb94ca5c0e6754ef23110d5c 100644 (file)
@@ -2052,7 +2052,8 @@ int adapter_assert_reset(void)
                else
                        jtag_add_reset(0, 1);
                return ERROR_OK;
-       } else if (transport_is_swd() || transport_is_hla())
+       } else if (transport_is_swd() || transport_is_hla() ||
+                          transport_is_dapdirect_jtag() || transport_is_dapdirect_swd())
                return adapter_system_reset(1);
        else if (get_current_transport() != NULL)
                LOG_ERROR("reset is not supported on %s",
@@ -2067,7 +2068,8 @@ int adapter_deassert_reset(void)
        if (transport_is_jtag()) {
                jtag_add_reset(0, 0);
                return ERROR_OK;
-       } else if (transport_is_swd() || transport_is_hla())
+       } else if (transport_is_swd() || transport_is_hla() ||
+                        transport_is_dapdirect_jtag() || transport_is_dapdirect_swd())
                return adapter_system_reset(0);
        else if (get_current_transport() != NULL)
                LOG_ERROR("reset is not supported on %s",
index feda35699e92a5c998c5e9dbc256d97396e34cf6..f4c6a98ba70b68c9a36703fc4c3003d2daf27aa1 100644 (file)
@@ -351,6 +351,12 @@ struct adapter_driver {
 
        /** Low-level SWD APIs */
        const struct swd_driver *swd_ops;
+
+       /* DAP APIs over JTAG transport */
+       const struct dap_ops *dap_jtag_ops;
+
+       /* DAP APIs over SWD transport */
+       const struct dap_ops *dap_swd_ops;
 };
 
 extern const char * const jtag_only[];
index 08a4b961f1f58bf23fda84ce764f4cb4b6ab7619..5a16def55bcc923005c05f49b326ed2c092ad60f 100644 (file)
@@ -98,6 +98,7 @@ ARM_DEBUG_SRC = \
        %D%/arm_dap.c \
        %D%/armv7a_cache.c \
        %D%/armv7a_cache_l2x.c \
+       %D%/adi_v5_dapdirect.c \
        %D%/adi_v5_jtag.c \
        %D%/adi_v5_swd.c \
        %D%/embeddedice.c \
diff --git a/src/target/adi_v5_dapdirect.c b/src/target/adi_v5_dapdirect.c
new file mode 100644 (file)
index 0000000..f120151
--- /dev/null
@@ -0,0 +1,223 @@
+/*
+ * Copyright (C) 2019, STMicroelectronics - All Rights Reserved
+ * Author(s): Antonio Borneo <borneo.antonio@gmail.com> for STMicroelectronics
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+/**
+ * @file
+ * Utilities to support in-circuit debuggers that provide APIs to access
+ * directly ARM DAP, hiding the access to the underlining transport used
+ * for the physical connection (either JTAG or SWD).
+ * E.g. STMicroelectronics ST-Link/V2 (from version V2J24) and STLINK-V3.
+ *
+ * Single-DAP support only.
+ *
+ * For details, see "ARM IHI 0031A"
+ * ARM Debug Interface v5 Architecture Specification
+ *
+ * FIXME: in JTAG mode, trst is not managed
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <jtag/interface.h>
+#include <jtag/tcl.h>
+#include <transport/transport.h>
+
+COMMAND_HANDLER(dapdirect_jtag_empty_command)
+{
+       LOG_DEBUG("dapdirect_jtag_empty_command(\"%s\")", CMD_NAME);
+
+       return ERROR_OK;
+}
+
+COMMAND_HANDLER(dapdirect_jtag_reset_command)
+{
+       enum reset_types jtag_reset_config = jtag_get_reset_config();
+
+       /*
+        * in case the adapter has not already handled asserting srst
+        * we will attempt it again
+        */
+       if (jtag_reset_config & RESET_CNCT_UNDER_SRST) {
+               if (jtag_reset_config & RESET_SRST_NO_GATING) {
+                       adapter_assert_reset();
+                       return ERROR_OK;
+               }
+               LOG_WARNING("\'srst_nogate\' reset_config option is required");
+       }
+       adapter_deassert_reset();
+       return ERROR_OK;
+}
+
+static const struct command_registration dapdirect_jtag_subcommand_handlers[] = {
+       {
+               .name = "newtap",
+               .mode = COMMAND_CONFIG,
+               .jim_handler = jim_jtag_newtap,
+               .help = "declare a new TAP"
+       },
+       {
+               .name = "init",
+               .mode = COMMAND_ANY,
+               .handler = dapdirect_jtag_empty_command,
+               .usage = ""
+       },
+       {
+               .name = "arp_init",
+               .mode = COMMAND_ANY,
+               .handler = dapdirect_jtag_empty_command,
+               .usage = ""
+       },
+       {
+               .name = "arp_init-reset",
+               .mode = COMMAND_ANY,
+               .handler = dapdirect_jtag_reset_command,
+               .usage = ""
+       },
+       {
+               .name = "tapisenabled",
+               .mode = COMMAND_EXEC,
+               .jim_handler = jim_jtag_tap_enabler,
+       },
+       {
+               .name = "tapenable",
+               .mode = COMMAND_EXEC,
+               .jim_handler = jim_jtag_tap_enabler,
+       },
+       {
+               .name = "tapdisable",
+               .mode = COMMAND_EXEC,
+               .handler = dapdirect_jtag_empty_command,
+               .usage = "",
+       },
+       {
+               .name = "configure",
+               .mode = COMMAND_ANY,
+               .handler = dapdirect_jtag_empty_command,
+               .usage = "",
+       },
+       {
+               .name = "cget",
+               .mode = COMMAND_EXEC,
+               .jim_handler = jim_jtag_configure,
+       },
+       {
+               .name = "names",
+               .mode = COMMAND_ANY,
+               .handler = dapdirect_jtag_empty_command,
+               .usage = "",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration dapdirect_jtag_handlers[] = {
+       {
+               .name = "jtag",
+               .mode = COMMAND_ANY,
+               .chain = dapdirect_jtag_subcommand_handlers,
+               .usage = "",
+       },
+       {
+               .name = "jtag_ntrst_delay",
+               .mode = COMMAND_ANY,
+               .handler = dapdirect_jtag_empty_command,
+               .usage = "",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration dapdirect_swd_subcommand_handlers[] = {
+       {
+               .name = "newdap",
+               .mode = COMMAND_CONFIG,
+               .jim_handler = jim_jtag_newtap,
+               .help = "declare a new SWD DAP",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+static const struct command_registration dapdirect_swd_handlers[] = {
+       {
+               .name = "swd",
+               .mode = COMMAND_ANY,
+               .help = "SWD command group",
+               .usage = "",
+               .chain = dapdirect_swd_subcommand_handlers,
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+static int dapdirect_jtag_select(struct command_context *ctx)
+{
+       LOG_DEBUG("dapdirect_jtag_select()");
+
+       return register_commands(ctx, NULL, dapdirect_jtag_handlers);
+}
+
+static int dapdirect_swd_select(struct command_context *ctx)
+{
+       LOG_DEBUG("dapdirect_swd_select()");
+
+       return register_commands(ctx, NULL, dapdirect_swd_handlers);
+}
+
+static int dapdirect_init(struct command_context *ctx)
+{
+       LOG_DEBUG("dapdirect_init()");
+
+       adapter_deassert_reset();
+       return ERROR_OK;
+}
+
+static struct transport dapdirect_jtag_transport = {
+       .name = "dapdirect_jtag",
+       .select = dapdirect_jtag_select,
+       .init = dapdirect_init,
+};
+
+static struct transport dapdirect_swd_transport = {
+       .name = "dapdirect_swd",
+       .select = dapdirect_swd_select,
+       .init = dapdirect_init,
+};
+
+static void dapdirect_constructor(void) __attribute__((constructor));
+static void dapdirect_constructor(void)
+{
+       transport_register(&dapdirect_jtag_transport);
+       transport_register(&dapdirect_swd_transport);
+}
+
+/**
+ * Returns true if the current debug session
+ * is using JTAG as its transport.
+ */
+bool transport_is_dapdirect_jtag(void)
+{
+       return get_current_transport() == &dapdirect_jtag_transport;
+}
+
+/**
+ * Returns true if the current debug session
+ * is using SWD as its transport.
+ */
+bool transport_is_dapdirect_swd(void)
+{
+       return get_current_transport() == &dapdirect_swd_transport;
+}
index 4be94b41bd2abaaf03fc3832da848196161df0f9..56442f1835269f589caad87009c6368cdef1dbf5 100644 (file)
@@ -119,6 +119,10 @@ static int dap_init_all(void)
                if (transport_is_swd()) {
                        dap->ops = &swd_dap_ops;
                        obj->swd = adapter_driver->swd_ops;
+               } else if (transport_is_dapdirect_swd()) {
+                       dap->ops = adapter_driver->dap_swd_ops;
+               } else if (transport_is_dapdirect_jtag()) {
+                       dap->ops = adapter_driver->dap_jtag_ops;
                } else
                        dap->ops = &jtag_dp_ops;
 
index 140ef503d7e0f2e3e6ec0b98fed62ef6ae9e23ec..4effca5d5e2f1254d08076ef2d7de9d6dad93e29 100644 (file)
@@ -96,6 +96,8 @@ bool transports_are_declared(void);
 
 bool transport_is_jtag(void);
 bool transport_is_swd(void);
+bool transport_is_dapdirect_jtag(void);
+bool transport_is_dapdirect_swd(void);
 
 #if BUILD_HLADAPTER
 bool transport_is_hla(void);

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)