armv7a: forward error value in armv7a_cache_auto_flush_all_data
[fw/openocd] / src / target / armv7m_trace.c
index b1bbb31c5ad75fa13811f658dc7c8e09738f2384..c1e4f5baac33d7f2b8a5c282c7c56f605bddfc59 100644 (file)
@@ -10,6 +10,9 @@
  *   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 <target/armv7m.h>
 #include <target/cortex_m.h>
 #include <target/armv7m_trace.h>
+#include <jtag/interface.h>
+
+#define TRACE_BUF_SIZE 4096
+
+static int armv7m_poll_trace(void *target)
+{
+       struct armv7m_common *armv7m = target_to_armv7m(target);
+       uint8_t buf[TRACE_BUF_SIZE];
+       size_t size = sizeof(buf);
+       int retval;
+
+       retval = adapter_poll_trace(buf, &size);
+       if (retval != ERROR_OK || !size)
+               return retval;
+
+       target_call_trace_callbacks(target, size, buf);
+
+       if (armv7m->trace_config.trace_file != NULL) {
+               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,19 +59,38 @@ int armv7m_trace_tpiu_config(struct target *target)
        int prescaler;
        int retval;
 
+       target_unregister_timer_callback(armv7m_poll_trace, target);
+
+
+       retval = adapter_config_trace(trace_config->config_type == INTERNAL,
+                                     trace_config->pin_protocol,
+                                     trace_config->port_size,
+                                     &trace_config->trace_freq);
+       if (retval != ERROR_OK)
+               return retval;
+
        if (!trace_config->trace_freq) {
                LOG_ERROR("Trace port frequency is 0, can't enable TPIU");
                return ERROR_FAIL;
        }
 
+       prescaler = trace_config->traceclkin_freq / trace_config->trace_freq;
+
        if (trace_config->traceclkin_freq % trace_config->trace_freq) {
-               LOG_ERROR("Can not calculate an integer divisor to get %u trace port frequency from %u TRACECLKIN frequency",
-                         trace_config->trace_freq, trace_config->traceclkin_freq);
-               return ERROR_FAIL;
+               prescaler++;
+               int trace_freq = trace_config->traceclkin_freq / prescaler;
+               LOG_INFO("Can not obtain %u trace port frequency from %u TRACECLKIN frequency, using %u instead",
+                         trace_config->trace_freq, trace_config->traceclkin_freq,
+                         trace_freq);
+               trace_config->trace_freq = trace_freq;
+               retval = adapter_config_trace(trace_config->config_type == INTERNAL,
+                                             trace_config->pin_protocol,
+                                             trace_config->port_size,
+                                             &trace_config->trace_freq);
+               if (retval != ERROR_OK)
+                       return retval;
        }
 
-       prescaler = trace_config->traceclkin_freq / trace_config->trace_freq;
-
        retval = target_write_u32(target, TPIU_CSPSR, 1 << trace_config->port_size);
        if (retval != ERROR_OK)
                return retval;
@@ -65,6 +115,9 @@ int armv7m_trace_tpiu_config(struct target *target)
        if (retval != ERROR_OK)
                return retval;
 
+       if (trace_config->config_type == INTERNAL)
+               target_register_timer_callback(armv7m_poll_trace, 1, 1, target);
+
        target_call_event_callbacks(target, TARGET_EVENT_TRACE_CONFIG);
 
        return ERROR_OK;
@@ -137,10 +190,13 @@ COMMAND_HANDLER(handle_tpiu_config_command)
                                return ERROR_COMMAND_SYNTAX_ERROR;
 
                        armv7m->trace_config.config_type = INTERNAL;
-                       armv7m->trace_config.trace_file = fopen(CMD_ARGV[cmd_idx], "ab");
-                       if (!armv7m->trace_config.trace_file) {
-                               LOG_ERROR("Can't open trace destination file");
-                               return ERROR_FAIL;
+
+                       if (strcmp(CMD_ARGV[cmd_idx], "-") != 0) {
+                               armv7m->trace_config.trace_file = fopen(CMD_ARGV[cmd_idx], "ab");
+                               if (!armv7m->trace_config.trace_file) {
+                                       LOG_ERROR("Can't open trace destination file");
+                                       return ERROR_FAIL;
+                               }
                        }
                }
                cmd_idx++;