openocd: fix SPDX tag format for files .c
[fw/openocd] / src / jtag / core.c
index 14062383f3327ed837397441f52e5454cfaec1ca..57480118758bc56e3226ae2a1102f7f0cf7fc7b1 100644 (file)
@@ -1,3 +1,5 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
 /***************************************************************************
  *   Copyright (C) 2009 Zachary T Welch                                    *
  *   zw@superlucidity.net                                                  *
  *                                                                         *
  *   Copyright (C) 2005 by Dominic Rath                                    *
  *   Dominic.Rath@gmx.de                                                   *
- *                                                                         *
- *   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/>. *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
+#include "adapter.h"
 #include "jtag.h"
 #include "swd.h"
 #include "interface.h"
@@ -123,16 +113,6 @@ struct jtag_event_callback {
 /* callbacks to inform high-level handlers about JTAG state changes */
 static struct jtag_event_callback *jtag_event_callbacks;
 
-/* speed in kHz*/
-static int speed_khz;
-/* speed to fallback to when RCLK is requested but not supported */
-static int rclk_fallback_speed_khz;
-static enum {CLOCK_MODE_UNSELECTED, CLOCK_MODE_KHZ, CLOCK_MODE_RCLK} clock_mode;
-static int jtag_speed;
-
-/* FIXME: change name to this variable, it is not anymore JTAG only */
-static struct adapter_driver *jtag;
-
 extern struct adapter_driver *adapter_driver;
 
 void jtag_set_flush_queue_sleep(int ms)
@@ -156,14 +136,19 @@ int jtag_error_clear(void)
 
 /************/
 
-static bool jtag_poll = 1;
+static bool jtag_poll = true;
+static bool jtag_poll_en = true;
 
 bool is_jtag_poll_safe(void)
 {
        /* Polling can be disabled explicitly with set_enabled(false).
+        * It can also be masked with mask().
         * It is also implicitly disabled while TRST is active and
         * while SRST is gating the JTAG clock.
         */
+       if (!jtag_poll_en)
+               return false;
+
        if (!transport_is_jtag())
                return jtag_poll;
 
@@ -182,6 +167,18 @@ void jtag_poll_set_enabled(bool value)
        jtag_poll = value;
 }
 
+bool jtag_poll_mask(void)
+{
+       bool retval = jtag_poll_en;
+       jtag_poll_en = false;
+       return retval;
+}
+
+void jtag_poll_unmask(bool saved)
+{
+       jtag_poll_en = saved;
+}
+
 /************/
 
 struct jtag_tap *jtag_all_taps(void)
@@ -243,7 +240,7 @@ struct jtag_tap *jtag_tap_by_string(const char *s)
        struct jtag_tap *t = jtag_all_taps();
 
        while (t) {
-               if (0 == strcmp(t->dotted_name, s))
+               if (strcmp(t->dotted_name, s) == 0)
                        return t;
                t = t->next_tap;
        }
@@ -506,7 +503,7 @@ int jtag_add_tms_seq(unsigned nbits, const uint8_t *seq, enum tap_state state)
 {
        int retval;
 
-       if (!(jtag->jtag_ops->supported & DEBUG_CAP_TMS_SEQ))
+       if (!(adapter_driver->jtag_ops->supported & DEBUG_CAP_TMS_SEQ))
                return ERROR_JTAG_NOT_IMPLEMENTED;
 
        jtag_checks();
@@ -628,7 +625,7 @@ static int adapter_system_reset(int req_srst)
 
        /* Maybe change SRST signal state */
        if (jtag_srst != req_srst) {
-               retval = jtag->reset(0, req_srst);
+               retval = adapter_driver->reset(0, req_srst);
                if (retval != ERROR_OK) {
                        LOG_ERROR("SRST error");
                        return ERROR_FAIL;
@@ -765,7 +762,7 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst)
        int new_srst = 0;
        int new_trst = 0;
 
-       if (!jtag->reset) {
+       if (!adapter_driver->reset) {
                legacy_jtag_add_reset(req_tlr_or_trst, req_srst);
                return;
        }
@@ -814,7 +811,7 @@ void jtag_add_reset(int req_tlr_or_trst, int req_srst)
                /* guarantee jtag queue empty before changing reset status */
                jtag_execute_queue();
 
-               retval = jtag->reset(new_trst, new_srst);
+               retval = adapter_driver->reset(new_trst, new_srst);
                if (retval != ERROR_OK) {
                        jtag_set_error(retval);
                        LOG_ERROR("TRST/SRST error");
@@ -934,7 +931,7 @@ void jtag_check_value_mask(struct scan_field *field, uint8_t *value, uint8_t *ma
 
 int default_interface_jtag_execute_queue(void)
 {
-       if (!jtag) {
+       if (!is_adapter_initialized()) {
                LOG_ERROR("No JTAG interface configured yet.  "
                        "Issue 'init' command in startup scripts "
                        "before communicating with targets.");
@@ -950,11 +947,11 @@ int default_interface_jtag_execute_queue(void)
                 * The fix can be applied immediately after next release (v0.11.0 ?)
                 */
                LOG_ERROR("JTAG API jtag_execute_queue() called on non JTAG interface");
-               if (!jtag->jtag_ops || !jtag->jtag_ops->execute_queue)
+               if (!adapter_driver->jtag_ops || !adapter_driver->jtag_ops->execute_queue)
                        return ERROR_OK;
        }
 
-       int result = jtag->jtag_ops->execute_queue();
+       int result = adapter_driver->jtag_ops->execute_queue();
 
        struct jtag_command *cmd = jtag_command_queue;
        while (debug_level >= LOG_LVL_DEBUG_IO && cmd) {
@@ -1072,8 +1069,6 @@ void jtag_sleep(uint32_t us)
 
 #define JTAG_MAX_AUTO_TAPS 20
 
-#define EXTRACT_JEP106_BANK(X) (((X) & 0xf00) >> 8)
-#define EXTRACT_JEP106_ID(X)   (((X) & 0xfe) >> 1)
 #define EXTRACT_MFG(X)  (((X) & 0xffe) >> 1)
 #define EXTRACT_PART(X) (((X) & 0xffff000) >> 12)
 #define EXTRACT_VER(X)  (((X) & 0xf0000000) >> 28)
@@ -1141,7 +1136,7 @@ static void jtag_examine_chain_display(enum log_levels level, const char *msg,
                name, msg,
                (unsigned int)idcode,
                (unsigned int)EXTRACT_MFG(idcode),
-               jep106_manufacturer(EXTRACT_JEP106_BANK(idcode), EXTRACT_JEP106_ID(idcode)),
+               jep106_manufacturer(EXTRACT_MFG(idcode)),
                (unsigned int)EXTRACT_PART(idcode),
                (unsigned int)EXTRACT_VER(idcode));
 }
@@ -1197,7 +1192,7 @@ static bool jtag_examine_chain_match_tap(const struct jtag_tap *tap)
                        return true;
 
                /* treat "-expected-id 0" as a "don't-warn" wildcard */
-               if (0 == tap->expected_ids[ii])
+               if (tap->expected_ids[ii] == 0)
                        return true;
        }
 
@@ -1284,7 +1279,7 @@ static int jtag_examine_chain(void)
                        jtag_tap_init(tap);
                }
 
-               if ((idcode & 1) == 0) {
+               if ((idcode & 1) == 0 && !tap->ignore_bypass) {
                        /* Zero for LSB indicates a device in bypass */
                        LOG_INFO("TAP %s does not have valid IDCODE (idcode=0x%" PRIx32 ")",
                                        tap->dotted_name, idcode);
@@ -1338,7 +1333,6 @@ static int jtag_validate_ircapture(void)
        struct jtag_tap *tap;
        uint8_t *ir_test = NULL;
        struct scan_field field;
-       uint64_t val;
        int chain_pos = 0;
        int retval;
 
@@ -1398,7 +1392,7 @@ static int jtag_validate_ircapture(void)
                 */
                if (tap->ir_length == 0) {
                        tap->ir_length = 2;
-                       while ((val = buf_get_u64(ir_test, chain_pos, tap->ir_length + 1)) == 1
+                       while (buf_get_u64(ir_test, chain_pos, tap->ir_length + 1) == 1
                                        && tap->ir_length < JTAG_IRLEN_MAX) {
                                tap->ir_length++;
                        }
@@ -1414,7 +1408,7 @@ static int jtag_validate_ircapture(void)
                 * this part of the JTAG spec, so their capture mask/value
                 * attributes might disable this test.
                 */
-               val = buf_get_u64(ir_test, chain_pos, tap->ir_length);
+               uint64_t val = buf_get_u64(ir_test, chain_pos, tap->ir_length);
                if ((val & tap->ir_capture_mask) != tap->ir_capture_value) {
                        LOG_ERROR("%s: IR capture error; saw 0x%0*" PRIx64 " not 0x%0*" PRIx32,
                                jtag_tap_name(tap),
@@ -1430,7 +1424,7 @@ static int jtag_validate_ircapture(void)
        }
 
        /* verify the '11' sentinel we wrote is returned at the end */
-       val = buf_get_u64(ir_test, chain_pos, 2);
+       uint64_t val = buf_get_u64(ir_test, chain_pos, 2);
        if (val != 0x3) {
                char *cbuf = buf_to_hex_str(ir_test, total_ir_length);
 
@@ -1506,65 +1500,6 @@ void jtag_tap_free(struct jtag_tap *tap)
        free(tap);
 }
 
-/**
- * Do low-level setup like initializing registers, output signals,
- * and clocking.
- */
-int adapter_init(struct command_context *cmd_ctx)
-{
-       if (jtag)
-               return ERROR_OK;
-
-       if (!adapter_driver) {
-               /* nothing was previously specified by "adapter driver" command */
-               LOG_ERROR("Debug Adapter has to be specified, "
-                       "see \"adapter driver\" command");
-               return ERROR_JTAG_INVALID_INTERFACE;
-       }
-
-       int retval;
-       retval = adapter_driver->init();
-       if (retval != ERROR_OK)
-               return retval;
-       jtag = adapter_driver;
-
-       if (!jtag->speed) {
-               LOG_INFO("This adapter doesn't support configurable speed");
-               return ERROR_OK;
-       }
-
-       if (clock_mode == CLOCK_MODE_UNSELECTED) {
-               LOG_ERROR("An adapter speed is not selected in the init script."
-                       " Insert a call to \"adapter speed\" or \"jtag_rclk\" to proceed.");
-               return ERROR_JTAG_INIT_FAILED;
-       }
-
-       int requested_khz = jtag_get_speed_khz();
-       int actual_khz = requested_khz;
-       int jtag_speed_var = 0;
-       retval = jtag_get_speed(&jtag_speed_var);
-       if (retval != ERROR_OK)
-               return retval;
-       retval = jtag->speed(jtag_speed_var);
-       if (retval != ERROR_OK)
-               return retval;
-       retval = jtag_get_speed_readable(&actual_khz);
-       if (retval != ERROR_OK)
-               LOG_INFO("adapter-specific clock speed value %d", jtag_speed_var);
-       else if (actual_khz) {
-               /* Adaptive clocking -- JTAG-specific */
-               if ((clock_mode == CLOCK_MODE_RCLK)
-                               || ((clock_mode == CLOCK_MODE_KHZ) && !requested_khz)) {
-                       LOG_INFO("RCLK (adaptive clock speed) not supported - fallback to %d kHz"
-                       , actual_khz);
-               } else
-                       LOG_INFO("clock speed %d kHz", actual_khz);
-       } else
-               LOG_INFO("RCLK (adaptive clock speed)");
-
-       return ERROR_OK;
-}
-
 int jtag_init_inner(struct command_context *cmd_ctx)
 {
        struct jtag_tap *tap;
@@ -1645,25 +1580,6 @@ int jtag_init_inner(struct command_context *cmd_ctx)
        return ERROR_OK;
 }
 
-int adapter_quit(void)
-{
-       if (jtag && jtag->quit) {
-               /* close the JTAG interface */
-               int result = jtag->quit();
-               if (result != ERROR_OK)
-                       LOG_ERROR("failed: %d", result);
-       }
-
-       struct jtag_tap *t = jtag_all_taps();
-       while (t) {
-               struct jtag_tap *n = t->next_tap;
-               jtag_tap_free(t);
-               t = n;
-       }
-
-       return ERROR_OK;
-}
-
 int swd_init_reset(struct command_context *cmd_ctx)
 {
        int retval, retval1;
@@ -1771,98 +1687,6 @@ int jtag_init(struct command_context *cmd_ctx)
        return ERROR_OK;
 }
 
-unsigned jtag_get_speed_khz(void)
-{
-       return speed_khz;
-}
-
-static int adapter_khz_to_speed(unsigned khz, int *speed)
-{
-       LOG_DEBUG("convert khz to interface specific speed value");
-       speed_khz = khz;
-       if (!jtag)
-               return ERROR_OK;
-       LOG_DEBUG("have interface set up");
-       if (!jtag->khz) {
-               LOG_ERROR("Translation from khz to jtag_speed not implemented");
-               return ERROR_FAIL;
-       }
-       int speed_div1;
-       int retval = jtag->khz(jtag_get_speed_khz(), &speed_div1);
-       if (retval != ERROR_OK)
-               return retval;
-       *speed = speed_div1;
-       return ERROR_OK;
-}
-
-static int jtag_rclk_to_speed(unsigned fallback_speed_khz, int *speed)
-{
-       int retval = adapter_khz_to_speed(0, speed);
-       if ((retval != ERROR_OK) && fallback_speed_khz) {
-               LOG_DEBUG("trying fallback speed...");
-               retval = adapter_khz_to_speed(fallback_speed_khz, speed);
-       }
-       return retval;
-}
-
-static int jtag_set_speed(int speed)
-{
-       jtag_speed = speed;
-       /* this command can be called during CONFIG,
-        * in which case jtag isn't initialized */
-       return jtag ? jtag->speed(speed) : ERROR_OK;
-}
-
-int jtag_config_khz(unsigned khz)
-{
-       LOG_DEBUG("handle jtag khz");
-       clock_mode = CLOCK_MODE_KHZ;
-       int speed = 0;
-       int retval = adapter_khz_to_speed(khz, &speed);
-       return (retval != ERROR_OK) ? retval : jtag_set_speed(speed);
-}
-
-int jtag_config_rclk(unsigned fallback_speed_khz)
-{
-       LOG_DEBUG("handle jtag rclk");
-       clock_mode = CLOCK_MODE_RCLK;
-       rclk_fallback_speed_khz = fallback_speed_khz;
-       int speed = 0;
-       int retval = jtag_rclk_to_speed(fallback_speed_khz, &speed);
-       return (retval != ERROR_OK) ? retval : jtag_set_speed(speed);
-}
-
-int jtag_get_speed(int *speed)
-{
-       switch (clock_mode) {
-               case CLOCK_MODE_KHZ:
-                       adapter_khz_to_speed(jtag_get_speed_khz(), speed);
-                       break;
-               case CLOCK_MODE_RCLK:
-                       jtag_rclk_to_speed(rclk_fallback_speed_khz, speed);
-                       break;
-               default:
-                       LOG_ERROR("BUG: unknown jtag clock mode");
-                       return ERROR_FAIL;
-       }
-       return ERROR_OK;
-}
-
-int jtag_get_speed_readable(int *khz)
-{
-       int jtag_speed_var = 0;
-       int retval = jtag_get_speed(&jtag_speed_var);
-       if (retval != ERROR_OK)
-               return retval;
-       if (!jtag)
-               return ERROR_OK;
-       if (!jtag->speed_div) {
-               LOG_ERROR("Translation from jtag_speed to khz not implemented");
-               return ERROR_FAIL;
-       }
-       return jtag->speed_div(jtag_speed_var, khz);
-}
-
 void jtag_set_verify(bool enable)
 {
        jtag_verify = enable;
@@ -1885,14 +1709,14 @@ bool jtag_will_verify_capture_ir(void)
 
 int jtag_power_dropout(int *dropout)
 {
-       if (!jtag) {
+       if (!is_adapter_initialized()) {
                /* TODO: as the jtag interface is not valid all
                 * we can do at the moment is exit OpenOCD */
                LOG_ERROR("No Valid JTAG Interface Configured.");
                exit(-1);
        }
-       if (jtag->power_dropout)
-               return jtag->power_dropout(dropout);
+       if (adapter_driver->power_dropout)
+               return adapter_driver->power_dropout(dropout);
 
        *dropout = 0; /* by default we can't detect power dropout */
        return ERROR_OK;
@@ -1900,8 +1724,8 @@ int jtag_power_dropout(int *dropout)
 
 int jtag_srst_asserted(int *srst_asserted)
 {
-       if (jtag->srst_asserted)
-               return jtag->srst_asserted(srst_asserted);
+       if (adapter_driver->srst_asserted)
+               return adapter_driver->srst_asserted(srst_asserted);
 
        *srst_asserted = 0; /* by default we can't detect srst asserted */
        return ERROR_OK;
@@ -2094,8 +1918,8 @@ int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,
                uint32_t port_size, unsigned int *trace_freq,
                unsigned int traceclkin_freq, uint16_t *prescaler)
 {
-       if (jtag->config_trace) {
-               return jtag->config_trace(enabled, pin_protocol, port_size, trace_freq,
+       if (adapter_driver->config_trace) {
+               return adapter_driver->config_trace(enabled, pin_protocol, port_size, trace_freq,
                        traceclkin_freq, prescaler);
        } else if (enabled) {
                LOG_ERROR("The selected interface does not support tracing");
@@ -2107,8 +1931,8 @@ int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol,
 
 int adapter_poll_trace(uint8_t *buf, size_t *size)
 {
-       if (jtag->poll_trace)
-               return jtag->poll_trace(buf, size);
+       if (adapter_driver->poll_trace)
+               return adapter_driver->poll_trace(buf, size);
 
        return ERROR_FAIL;
 }