This is an automated email from Gerrit.

Paul Fertser (fercer...@gmail.com) just uploaded a new patch set to Gerrit, 
which you can find at http://openocd.zylin.com/2540

-- gerrit

commit 92f08e4b1e4a8dae831ce86451a32de772ed4863
Author: Paul Fertser <fercer...@gmail.com>
Date:   Tue Feb 10 13:32:07 2015 +0300

    armv7m_trace, stlink: provide APIs to capture trace with an adapter
    
    ST-LINK works reasonably now. The speed seems to be still limited to
    2MHz even on V2-1:
    
    Info : STLINK v2 JTAG v20 API v2 SWIM v4 VID 0x0483 PID 0x374B
    
    I haven't tested properly this yet, and valgrind tells me I still have
    to debug an issue with calling unregistered target timer callback for
    whatever reason (reproduced with power-cycling the target).
    
    However, this is already working good enough to evaluate my proposal
    on the internal API.
    
    Change-Id: I9d193dd5af382912e4fe838bd4f612cffd11b295
    Signed-off-by: Paul Fertser <fercer...@gmail.com>

diff --git a/src/jtag/core.c b/src/jtag/core.c
index 8f3aa4d..514ed6c 100644
--- a/src/jtag/core.c
+++ b/src/jtag/core.c
@@ -1824,3 +1824,18 @@ void adapter_deassert_reset(void)
        else
                LOG_ERROR("transport is not selected");
 }
+
+int adapter_config_trace(bool enabled, enum tpio_pin_protocol pin_protocol,
+                        uint32_t port_size, unsigned int trace_freq,
+                        armv7m_trace_callback callback, struct target *target)
+{
+       if (jtag->config_trace)
+               return jtag->config_trace(enabled, pin_protocol, port_size,
+                                         trace_freq, callback, target);
+       else if (enabled) {
+               LOG_ERROR("The selected interface does not support tracing");
+               return ERROR_FAIL;
+       }
+
+       return ERROR_OK;
+}
diff --git a/src/jtag/drivers/stlink_usb.c b/src/jtag/drivers/stlink_usb.c
index 4988337..b521543 100644
--- a/src/jtag/drivers/stlink_usb.c
+++ b/src/jtag/drivers/stlink_usb.c
@@ -124,12 +124,12 @@ struct stlink_usb_handle_s {
        struct {
                /** whether SWO tracing is enabled or not */
                bool enabled;
-               /** trace data destination file */
-               FILE *output_f;
                /** trace module source clock (for prescaler) */
                uint32_t source_hz;
-               /** trace module clock prescaler */
-               uint32_t prescale;
+               /** trace received callback */
+               armv7m_trace_callback callback;
+               /** target for which the trace is taken */
+               struct target *target;
        } trace;
        /** reconnect is needed next time we try to query the
         * status */
@@ -894,11 +894,7 @@ static void stlink_usb_trace_read(void *handle)
 
                                res = stlink_usb_read_trace(handle, buf, size);
                                if (res == ERROR_OK) {
-                                       if (h->trace.output_f) {
-                                               /* Log retrieved trace output */
-                                               if (fwrite(buf, 1, size, 
h->trace.output_f) > 0)
-                                                       
fflush(h->trace.output_f);
-                                       }
+                                       h->trace.callback(h->trace.target, buf, 
size);
                                }
                        }
                }
@@ -975,25 +971,6 @@ static enum target_state stlink_usb_state(void *handle)
        return TARGET_UNKNOWN;
 }
 
-/** */
-static int stlink_usb_reset(void *handle)
-{
-       struct stlink_usb_handle_s *h = handle;
-
-       assert(handle != NULL);
-
-       stlink_usb_init_buffer(handle, h->rx_ep, 2);
-
-       h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;
-
-       if (h->jtag_api == STLINK_JTAG_API_V1)
-               h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_RESETSYS;
-       else
-               h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_RESETSYS;
-
-       return stlink_cmd_allow_retry(handle, h->databuf, 2);
-}
-
 static int stlink_usb_assert_srst(void *handle, int srst)
 {
        struct stlink_usb_handle_s *h = handle;
@@ -1013,62 +990,6 @@ static int stlink_usb_assert_srst(void *handle, int srst)
 }
 
 /** */
-static int stlink_configure_target_trace_port(void *handle)
-{
-       int res;
-       uint32_t reg;
-       struct stlink_usb_handle_s *h = handle;
-
-       assert(handle != NULL);
-
-       /* configure the TPI */
-
-       /* enable the trace subsystem */
-       res = stlink_usb_v2_read_debug_reg(handle, DCB_DEMCR, &reg);
-       if (res != ERROR_OK)
-               goto out;
-       res = stlink_usb_write_debug_reg(handle, DCB_DEMCR, TRCENA|reg);
-       if (res != ERROR_OK)
-               goto out;
-       /* set the TPI clock prescaler */
-       res = stlink_usb_write_debug_reg(handle, TPIU_ACPR, h->trace.prescale);
-       if (res != ERROR_OK)
-               goto out;
-       /* select the pin protocol.  The STLinkv2 only supports asynchronous
-        * UART emulation (NRZ) mode, so that's what we pick. */
-       res = stlink_usb_write_debug_reg(handle, TPIU_SPPR, 0x02);
-       if (res != ERROR_OK)
-               goto out;
-       /* disable continuous formatting */
-       res = stlink_usb_write_debug_reg(handle, TPIU_FFCR, (1<<8));
-       if (res != ERROR_OK)
-               goto out;
-
-       /* configure the ITM */
-
-       /* unlock access to the ITM registers */
-       res = stlink_usb_write_debug_reg(handle, ITM_LAR, 0xC5ACCE55);
-       if (res != ERROR_OK)
-               goto out;
-       /* enable trace with ATB ID 1 */
-       res = stlink_usb_write_debug_reg(handle, ITM_TCR, 
(1<<16)|(1<<0)|(1<<2));
-       if (res != ERROR_OK)
-               goto out;
-       /* trace privilege */
-       res = stlink_usb_write_debug_reg(handle, ITM_TPR, 1);
-       if (res != ERROR_OK)
-               goto out;
-       /* trace port enable (port 0) */
-       res = stlink_usb_write_debug_reg(handle, ITM_TER0, (1<<0));
-       if (res != ERROR_OK)
-               goto out;
-
-       res = ERROR_OK;
-out:
-       return res;
-}
-
-/** */
 static void stlink_usb_trace_disable(void *handle)
 {
        int res = ERROR_OK;
@@ -1101,30 +1022,20 @@ static int stlink_usb_trace_enable(void *handle)
        assert(handle != NULL);
 
        if (h->version.jtag >= STLINK_TRACE_MIN_VERSION) {
-               uint32_t trace_hz;
-
-               res = stlink_configure_target_trace_port(handle);
-               if (res != ERROR_OK)
-                       LOG_ERROR("Unable to configure tracing on target");
-
-               trace_hz = h->trace.prescale > 0 ?
-                       h->trace.source_hz / (h->trace.prescale + 1) :
-                       h->trace.source_hz;
-
                stlink_usb_init_buffer(handle, h->rx_ep, 10);
 
                h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;
                h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_START_TRACE_RX;
                h_u16_to_le(h->cmdbuf+h->cmdidx, (uint16_t)STLINK_TRACE_SIZE);
                h->cmdidx += 2;
-               h_u32_to_le(h->cmdbuf+h->cmdidx, trace_hz);
+               h_u32_to_le(h->cmdbuf+h->cmdidx, h->trace.source_hz);
                h->cmdidx += 4;
 
                res = stlink_usb_xfer(handle, h->databuf, 2);
 
                if (res == ERROR_OK)  {
                        h->trace.enabled = true;
-                       LOG_DEBUG("Tracing: recording at %" PRIu32 "Hz", 
trace_hz);
+                       LOG_DEBUG("Tracing: recording at %" PRIu32 "Hz", 
h->trace.source_hz);
                        /* We need the trace read function to be called at a
                         * high-enough frequency to ensure reasonable
                         * "timeliness" in processing ITM/DWT data.
@@ -1143,6 +1054,35 @@ static int stlink_usb_trace_enable(void *handle)
 }
 
 /** */
+static int stlink_usb_reset(void *handle)
+{
+       struct stlink_usb_handle_s *h = handle;
+       int retval;
+
+       assert(handle != NULL);
+
+       stlink_usb_init_buffer(handle, h->rx_ep, 2);
+
+       h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_COMMAND;
+
+       if (h->jtag_api == STLINK_JTAG_API_V1)
+               h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV1_RESETSYS;
+       else
+               h->cmdbuf[h->cmdidx++] = STLINK_DEBUG_APIV2_RESETSYS;
+
+       retval = stlink_cmd_allow_retry(handle, h->databuf, 2);
+       if (retval != ERROR_OK)
+               return retval;
+
+       if (h->trace.enabled) {
+               stlink_usb_trace_disable(h);
+               return stlink_usb_trace_enable(h);
+       }
+
+       return ERROR_OK;
+}
+
+/** */
 static int stlink_usb_run(void *handle)
 {
        int res;
@@ -1153,14 +1093,6 @@ static int stlink_usb_run(void *handle)
        if (h->jtag_api == STLINK_JTAG_API_V2) {
                res = stlink_usb_write_debug_reg(handle, DCB_DHCSR, 
DBGKEY|C_DEBUGEN);
 
-               /* Try to start tracing, if requested */
-               if (res == ERROR_OK && h->trace.source_hz && !h->trace.enabled) 
{
-                       if (stlink_usb_trace_enable(handle) == ERROR_OK)
-                               LOG_DEBUG("Tracing: enabled");
-                       else
-                               LOG_ERROR("Tracing: enable failed");
-               }
-
                return res;
        }
 
@@ -1183,9 +1115,6 @@ static int stlink_usb_halt(void *handle)
        if (h->jtag_api == STLINK_JTAG_API_V2) {
                res = stlink_usb_write_debug_reg(handle, DCB_DHCSR, 
DBGKEY|C_HALT|C_DEBUGEN);
 
-               if (res == ERROR_OK && h->trace.enabled)
-                       stlink_usb_trace_disable(handle);
-
                return res;
        }
 
@@ -1816,17 +1745,6 @@ static int stlink_usb_open(struct hl_interface_param_s 
*param, void **fd)
        /* set the used jtag api, this will default to the newest supported 
version */
        h->jtag_api = api;
 
-       if (h->jtag_api >= 2 && param->trace_source_hz > 0) {
-               uint32_t prescale;
-
-               prescale = param->trace_source_hz > STLINK_TRACE_MAX_HZ ?
-                       (param->trace_source_hz / STLINK_TRACE_MAX_HZ) - 1 : 0;
-
-               h->trace.output_f = param->trace_f;
-               h->trace.source_hz = param->trace_source_hz;
-               h->trace.prescale = prescale;
-       }
-
        /* initialize the debug hardware */
        err = stlink_usb_init_mode(h, param->connect_under_reset);
 
@@ -1872,6 +1790,31 @@ error_open:
        return ERROR_FAIL;
 }
 
+int stlink_config_trace(void *handle, bool enabled, enum tpio_pin_protocol 
pin_protocol,
+                       uint32_t port_size, unsigned int trace_freq,
+                       armv7m_trace_callback callback, struct target *target)
+{
+       struct stlink_usb_handle_s *h = handle;
+
+       if (enabled && (h->jtag_api < 2 || pin_protocol != ASYNC_UART)) {
+               LOG_ERROR("The attached ST-LINK version doesn't support this 
trace mode");
+               return ERROR_FAIL;
+       }
+
+       if (!enabled) {
+               stlink_usb_trace_disable(h);
+               return ERROR_OK;
+       }
+
+       stlink_usb_trace_disable(h);
+
+       h->trace.source_hz = trace_freq;
+       h->trace.callback = callback;
+       h->trace.target = target;
+
+       return stlink_usb_trace_enable(h);
+}
+
 /** */
 struct hl_layout_api_s stlink_usb_layout_api = {
        /** */
@@ -1908,4 +1851,6 @@ struct hl_layout_api_s stlink_usb_layout_api = {
        .override_target = stlink_usb_override_target,
        /** */
        .speed = stlink_speed,
+       /** */
+       .config_trace = stlink_config_trace,
 };
diff --git a/src/jtag/hla/hla_interface.c b/src/jtag/hla/hla_interface.c
index 21cd06f..a90bbe5 100644
--- a/src/jtag/hla/hla_interface.c
+++ b/src/jtag/hla/hla_interface.c
@@ -191,6 +191,23 @@ int hl_interface_override_target(const char **targetname)
        return ERROR_FAIL;
 }
 
+int hl_interface_config_trace(bool enabled, enum tpio_pin_protocol 
pin_protocol,
+                             uint32_t port_size, unsigned int trace_freq,
+                             armv7m_trace_callback callback, struct target 
*target)
+{
+       if (hl_if.layout->api->config_trace)
+               return hl_if.layout->api->config_trace(hl_if.handle, enabled, 
pin_protocol,
+                                                      port_size, trace_freq,
+                                                      callback, target);
+       else if (enabled) {
+               LOG_ERROR("The selected interface does not support tracing");
+               return ERROR_FAIL;
+       }
+
+       return ERROR_OK;
+}
+
+
 COMMAND_HANDLER(hl_interface_handle_device_desc_command)
 {
        LOG_DEBUG("hl_interface_handle_device_desc_command");
@@ -357,4 +374,5 @@ struct jtag_interface hl_interface = {
        .speed = &hl_interface_speed,
        .khz = &hl_interface_khz,
        .speed_div = &hl_interface_speed_div,
+       .config_trace = &hl_interface_config_trace,
 };
diff --git a/src/jtag/hla/hla_layout.h b/src/jtag/hla/hla_layout.h
index e989f66..9771362 100644
--- a/src/jtag/hla/hla_layout.h
+++ b/src/jtag/hla/hla_layout.h
@@ -24,6 +24,8 @@
 #ifndef _HL_LAYOUT_H
 #define _HL_LAYOUT_H
 
+#include <target/armv7m_trace.h>
+
 /** */
 struct hl_interface_s;
 struct hl_interface_param_s;
@@ -79,6 +81,15 @@ struct hl_layout_api_s {
        int (*custom_command) (void *handle, const char *command);
        /** */
        int (*speed)(void *handle, int khz, bool query);
+       /**
+        * Configure trace parameters for the adapter
+        *
+        * @param
+        * @returns ERROR_OK on success, an error code on failure.
+        */
+       int (*config_trace)(void *handle, bool enabled, enum tpio_pin_protocol 
pin_protocol,
+                           uint32_t port_size, unsigned int trace_freq,
+                           armv7m_trace_callback callback, struct target 
*target);
        /** */
        enum target_state (*state) (void *fd);
 };
diff --git a/src/jtag/interface.h b/src/jtag/interface.h
index c7130cc..df330fe 100644
--- a/src/jtag/interface.h
+++ b/src/jtag/interface.h
@@ -28,6 +28,7 @@
 #define OPENOCD_JTAG_INTERFACE_H
 
 #include <jtag/jtag.h>
+#include <target/armv7m_trace.h>
 
 /* @file
  * The "Cable Helper API" is what the cable drivers can use to help
@@ -298,11 +299,24 @@ struct jtag_interface {
         * @returns ERROR_OK on success, or an error code on failure.
         */
        int (*srst_asserted)(int *srst_asserted);
+
+       /**
+        * Configure trace parameters for the adapter
+        *
+        * @param
+        * @returns ERROR_OK on success, an error code on failure.
+        */
+       int (*config_trace)(bool enabled, enum tpio_pin_protocol pin_protocol,
+                           uint32_t port_size, unsigned int trace_freq,
+                           armv7m_trace_callback callback, struct target 
*target);
 };
 
 extern const char * const jtag_only[];
 
 void adapter_assert_reset(void);
 void adapter_deassert_reset(void);
+int adapter_config_trace(bool enabled, enum tpio_pin_protocol pin_protocol,
+                        uint32_t port_size, unsigned int trace_freq,
+                        armv7m_trace_callback callback, struct target *target);
 
 #endif /* OPENOCD_JTAG_INTERFACE_H */
diff --git a/src/target/armv7m_trace.c b/src/target/armv7m_trace.c
index e0ff192..0923a6b 100644
--- a/src/target/armv7m_trace.c
+++ b/src/target/armv7m_trace.c
@@ -17,10 +17,27 @@
 #include "config.h"
 #endif
 
-#include "target.h"
-#include "armv7m.h"
-#include "cortex_m.h"
-#include "armv7m_trace.h"
+#include <target/target.h>
+#include <target/armv7m.h>
+#include <target/cortex_m.h>
+#include <target/armv7m_trace.h>
+#include <jtag/interface.h>
+
+static int armv7m_trace_received(struct target *target, uint8_t *buf,
+                                        size_t size)
+{
+       struct armv7m_common *armv7m = target_to_armv7m(target);
+
+       if (fwrite(buf, 1, size, armv7m->trace_config.trace_file) == size)
+               fflush(armv7m->trace_config.trace_file);
+       else {
+               LOG_ERROR("Error writing to the trace destination file");
+               return ERROR_FAIL;
+       }
+
+       return ERROR_OK;
+}
+
 
 int armv7m_trace_tpiu_config(struct target *target)
 {
@@ -28,6 +45,15 @@ int armv7m_trace_tpiu_config(struct target *target)
        struct armv7m_trace_config *trace_config = &armv7m->trace_config;
        int retval;
 
+       retval = adapter_config_trace(trace_config->config_type == INTERNAL,
+                                     trace_config->pin_protocol,
+                                     trace_config->port_size,
+                                     trace_config->trace_freq,
+                                     armv7m_trace_received,
+                                     target);
+       if (retval != ERROR_OK)
+               return retval;
+
        retval = target_write_u32(target, TPIU_CSPSR, 1 << 
trace_config->port_size);
        if (retval != ERROR_OK)
                return retval;
@@ -101,6 +127,8 @@ COMMAND_HANDLER(handle_tpiu_config_command)
        } else if (!strcmp(CMD_ARGV[cmd_idx], "external") ||
                   !strcmp(CMD_ARGV[cmd_idx], "internal")) {
                if (!strcmp(CMD_ARGV[cmd_idx], "internal")) {
+                       armv7m->trace_config.config_type = INTERNAL;
+
                        cmd_idx++;
                        if (CMD_ARGC == cmd_idx)
                                return ERROR_COMMAND_SYNTAX_ERROR;
@@ -119,7 +147,8 @@ COMMAND_HANDLER(handle_tpiu_config_command)
                                LOG_ERROR("Can't open trace destination file");
                                return ERROR_FAIL;
                        }
-               }
+               } else
+                       armv7m->trace_config.config_type = EXTERNAL;
                cmd_idx++;
                if (CMD_ARGC == cmd_idx)
                        return ERROR_COMMAND_SYNTAX_ERROR;
diff --git a/src/target/armv7m_trace.h b/src/target/armv7m_trace.h
index f5632dd..18b4e40 100644
--- a/src/target/armv7m_trace.h
+++ b/src/target/armv7m_trace.h
@@ -16,7 +16,8 @@
 #ifndef ARMV7M_TRACE_H
 #define ARMV7M_TRACE_H
 
-#include "command.h"
+#include <target/target.h>
+#include <command.h>
 
 enum trace_config_type {
        NONE,
@@ -47,6 +48,9 @@ struct armv7m_trace_config {
 
 extern const struct command_registration armv7m_trace_command_handlers[];
 
+typedef int (*armv7m_trace_callback)(struct target *target, uint8_t *buf,
+                                    size_t size);
+
 int armv7m_trace_tpiu_config(struct target *target);
 int armv7m_trace_itm_config(struct target *target);
 

-- 

------------------------------------------------------------------------------
Dive into the World of Parallel Programming. The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net/
_______________________________________________
OpenOCD-devel mailing list
OpenOCD-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to