target/xtensa: avoid IHI for writes to non-executable memory
[openocd.git] / src / target / arm_tpiu_swo.c
index 387ad9e9e193ddc435e1a05dc679629438dc79fb..5cea682ec42b4c3fe6f405df291fad3c9d7f6e66 100644 (file)
@@ -1,4 +1,4 @@
-/* SPDX-License-Identifier: GPL-2.0-or-later */
+// SPDX-License-Identifier: GPL-2.0-or-later
 
 /**
  * @file
@@ -90,6 +90,7 @@ struct arm_tpiu_swo_event_action {
 struct arm_tpiu_swo_object {
        struct list_head lh;
        struct adiv5_mem_ap_spot spot;
+       struct adiv5_ap *ap;
        char *name;
        struct arm_tpiu_swo_event_action *event_action;
        /* record enable before init */
@@ -233,6 +234,9 @@ int arm_tpiu_swo_cleanup_all(void)
                        ea = next;
                }
 
+               if (obj->ap)
+                       dap_put_ap(obj->ap);
+
                free(obj->name);
                free(obj->out_filename);
                free(obj);
@@ -582,79 +586,90 @@ static int wrap_read_u32(struct target *target, struct adiv5_ap *tpiu_ap,
                return mem_ap_read_atomic_u32(tpiu_ap, address, value);
 }
 
-static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+static const struct service_driver arm_tpiu_swo_service_driver = {
+       .name = "tpiu_swo_trace",
+       .new_connection_during_keep_alive_handler = NULL,
+       .new_connection_handler = arm_tpiu_swo_service_new_connection,
+       .input_handler = arm_tpiu_swo_service_input,
+       .connection_closed_handler = arm_tpiu_swo_service_connection_closed,
+       .keep_client_alive_handler = NULL,
+};
+
+COMMAND_HANDLER(handle_arm_tpiu_swo_enable)
 {
-       struct command *c = jim_to_command(interp);
-       struct arm_tpiu_swo_object *obj = c->jim_handler_data;
-       struct command_context *cmd_ctx = current_command_context(interp);
-       struct adiv5_ap *tpiu_ap = dap_ap(obj->spot.dap, obj->spot.ap_num);
+       struct arm_tpiu_swo_object *obj = CMD_DATA;
        uint32_t value;
        int retval;
 
-       if (argc != 1) {
-               Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
-               return JIM_ERR;
-       }
+       if (CMD_ARGC != 0)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       if (cmd_ctx->mode == COMMAND_CONFIG) {
+       if (CMD_CTX->mode == COMMAND_CONFIG) {
                LOG_DEBUG("%s: enable deferred", obj->name);
                obj->deferred_enable = true;
-               return JIM_OK;
+               return ERROR_OK;
        }
 
        if (obj->enabled)
-               return JIM_OK;
+               return ERROR_OK;
 
-       if (transport_is_hla() && obj->spot.ap_num > 0) {
-               LOG_ERROR("Invalid access port %d. Only AP#0 allowed with hla transport", obj->spot.ap_num);
-               return JIM_ERR;
+       if (transport_is_hla() && obj->spot.ap_num != 0) {
+               command_print(CMD,
+                       "Invalid access port 0x%" PRIx64 ". Only AP#0 allowed with hla transport",
+                       obj->spot.ap_num);
+               return ERROR_FAIL;
        }
 
        if (!obj->traceclkin_freq) {
-               LOG_ERROR("Trace clock-in frequency not set");
-               return JIM_ERR;
+               command_print(CMD, "Trace clock-in frequency not set");
+               return ERROR_FAIL;
        }
 
        if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART)
-               if (!obj->swo_pin_freq) {
-                       LOG_ERROR("SWO pin frequency not set");
-                       return JIM_ERR;
-               }
+               if (!obj->swo_pin_freq)
+                       LOG_DEBUG("SWO pin frequency not set, will be autodetected by the adapter");
 
-       struct target *target = get_current_target(cmd_ctx);
+       struct target *target = get_current_target(CMD_CTX);
 
        /* START_DEPRECATED_TPIU */
        if (obj->recheck_ap_cur_target) {
                if (strcmp(target->type->name, "cortex_m") &&
                        strcmp(target->type->name, "hla_target")) {
                        LOG_ERROR(MSG "Current target is not a Cortex-M nor a HLA");
-                       return JIM_ERR;
+                       return ERROR_FAIL;
                }
                if (!target_was_examined(target)) {
                        LOG_ERROR(MSG "Current target not examined yet");
-                       return JIM_ERR;
+                       return ERROR_FAIL;
                }
                struct cortex_m_common *cm = target_to_cm(target);
                obj->recheck_ap_cur_target = false;
                obj->spot.ap_num = cm->armv7m.debug_ap->ap_num;
-               tpiu_ap = dap_ap(obj->spot.dap, obj->spot.ap_num);
                if (obj->spot.ap_num == 0)
                        LOG_INFO(MSG "Confirmed TPIU %s is on AP 0", obj->name);
                else
-                       LOG_INFO(MSG "Target %s is on AP %d. Revised command is "
-                               "\'tpiu create %s -dap %s -ap-num %d\'",
+                       LOG_INFO(MSG "Target %s is on AP#0x%" PRIx64 ". Revised command is "
+                               "\'tpiu create %s -dap %s -ap-num 0x%" PRIx64 "\'",
                                target_name(target), obj->spot.ap_num,
                                obj->name, adiv5_dap_name(obj->spot.dap), obj->spot.ap_num);
        }
        /* END_DEPRECATED_TPIU */
 
+       if (!obj->ap) {
+               obj->ap = dap_get_ap(obj->spot.dap, obj->spot.ap_num);
+               if (!obj->ap) {
+                       command_print(CMD, "Cannot get AP");
+                       return ERROR_FAIL;
+               }
+       }
+
        /* trigger the event before any attempt to R/W in the TPIU/SWO */
        arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_ENABLE);
 
-       retval = wrap_read_u32(target, tpiu_ap, obj->spot.base + TPIU_DEVID_OFFSET, &value);
+       retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_DEVID_OFFSET, &value);
        if (retval != ERROR_OK) {
-               LOG_ERROR("Unable to read %s", obj->name);
-               return JIM_ERR;
+               command_print(CMD, "Unable to read %s", obj->name);
+               return retval;
        }
        switch (obj->pin_protocol) {
        case TPIU_SPPR_PROTOCOL_SYNC:
@@ -670,21 +685,20 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const
                value = 0;
        }
        if (!value) {
-               struct jim_nvp *p;
-               jim_nvp_value2name(interp, nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol, &p);
-               LOG_ERROR("%s does not support protocol %s", obj->name, p->name);
-               return JIM_ERR;
+               struct jim_nvp *p = jim_nvp_value2name_simple(nvp_arm_tpiu_swo_protocol_opts, obj->pin_protocol);
+               command_print(CMD, "%s does not support protocol %s", obj->name, p->name);
+               return ERROR_FAIL;
        }
 
        if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_SYNC) {
-               retval = wrap_read_u32(target, tpiu_ap, obj->spot.base + TPIU_SSPSR_OFFSET, &value);
+               retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_SSPSR_OFFSET, &value);
                if (retval != ERROR_OK) {
-                       LOG_ERROR("Cannot read TPIU register SSPSR");
-                       return JIM_ERR;
+                       command_print(CMD, "Cannot read TPIU register SSPSR");
+                       return retval;
                }
                if (!(value & BIT(obj->port_width - 1))) {
-                       LOG_ERROR("TPIU does not support port-width of %d bits", obj->port_width);
-                       return JIM_ERR;
+                       command_print(CMD, "TPIU does not support port-width of %d bits", obj->port_width);
+                       return ERROR_FAIL;
                }
        }
 
@@ -696,34 +710,44 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const
                        struct arm_tpiu_swo_priv_connection *priv = malloc(sizeof(*priv));
                        if (!priv) {
                                LOG_ERROR("Out of memory");
-                               return JIM_ERR;
+                               return ERROR_FAIL;
                        }
                        priv->obj = obj;
                        LOG_INFO("starting trace server for %s on %s", obj->name, &obj->out_filename[1]);
-                       retval = add_service("tpiu_swo_trace", &obj->out_filename[1],
-                               CONNECTION_LIMIT_UNLIMITED, arm_tpiu_swo_service_new_connection,
-                               arm_tpiu_swo_service_input, arm_tpiu_swo_service_connection_closed,
-                               priv);
+                       retval = add_service(&arm_tpiu_swo_service_driver, &obj->out_filename[1],
+                               CONNECTION_LIMIT_UNLIMITED, priv);
                        if (retval != ERROR_OK) {
-                               LOG_ERROR("Can't configure trace TCP port %s", &obj->out_filename[1]);
-                               return JIM_ERR;
+                               command_print(CMD, "Can't configure trace TCP port %s", &obj->out_filename[1]);
+                               return retval;
                        }
                } else if (strcmp(obj->out_filename, "-")) {
                        obj->file = fopen(obj->out_filename, "ab");
                        if (!obj->file) {
-                               LOG_ERROR("Can't open trace destination file \"%s\"", obj->out_filename);
-                               return JIM_ERR;
+                               command_print(CMD, "Can't open trace destination file \"%s\"", obj->out_filename);
+                               return ERROR_FAIL;
                        }
                }
 
                retval = adapter_config_trace(true, obj->pin_protocol, obj->port_width,
                        &swo_pin_freq, obj->traceclkin_freq, &prescaler);
                if (retval != ERROR_OK) {
-                       LOG_ERROR("Failed to start adapter's trace");
+                       command_print(CMD, "Failed to start adapter's trace");
                        arm_tpiu_swo_close_output(obj);
-                       return JIM_ERR;
+                       return retval;
                }
 
+               if (obj->pin_protocol == TPIU_SPPR_PROTOCOL_MANCHESTER || obj->pin_protocol == TPIU_SPPR_PROTOCOL_UART)
+                       if (!swo_pin_freq) {
+                               if (obj->swo_pin_freq)
+                                       command_print(CMD, "Adapter rejected SWO pin frequency %d Hz", obj->swo_pin_freq);
+                               else
+                                       command_print(CMD,
+                                               "Adapter does not support auto-detection of SWO pin frequency nor a default value");
+
+                               arm_tpiu_swo_close_output(obj);
+                               return ERROR_FAIL;
+                       }
+
                if (obj->swo_pin_freq != swo_pin_freq)
                        LOG_INFO("SWO pin data rate adjusted by adapter to %d Hz", swo_pin_freq);
                obj->swo_pin_freq = swo_pin_freq;
@@ -743,26 +767,26 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const
                obj->swo_pin_freq = swo_pin_freq;
        }
 
-       retval = wrap_write_u32(target, tpiu_ap, obj->spot.base + TPIU_CSPSR_OFFSET, BIT(obj->port_width - 1));
+       retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_CSPSR_OFFSET, BIT(obj->port_width - 1));
        if (retval != ERROR_OK)
                goto error_exit;
 
-       retval = wrap_write_u32(target, tpiu_ap, obj->spot.base + TPIU_ACPR_OFFSET, prescaler - 1);
+       retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_ACPR_OFFSET, prescaler - 1);
        if (retval != ERROR_OK)
                goto error_exit;
 
-       retval = wrap_write_u32(target, tpiu_ap, obj->spot.base + TPIU_SPPR_OFFSET, obj->pin_protocol);
+       retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_SPPR_OFFSET, obj->pin_protocol);
        if (retval != ERROR_OK)
                goto error_exit;
 
-       retval = wrap_read_u32(target, tpiu_ap, obj->spot.base + TPIU_FFCR_OFFSET, &value);
+       retval = wrap_read_u32(target, obj->ap, obj->spot.base + TPIU_FFCR_OFFSET, &value);
        if (retval != ERROR_OK)
                goto error_exit;
        if (obj->en_formatter)
                value |= BIT(1);
        else
                value &= ~BIT(1);
-       retval = wrap_write_u32(target, tpiu_ap, obj->spot.base + TPIU_FFCR_OFFSET, value);
+       retval = wrap_write_u32(target, obj->ap, obj->spot.base + TPIU_FFCR_OFFSET, value);
        if (retval != ERROR_OK)
                goto error_exit;
 
@@ -773,10 +797,10 @@ static int jim_arm_tpiu_swo_enable(Jim_Interp *interp, int argc, Jim_Obj *const
        /* END_DEPRECATED_TPIU */
 
        obj->enabled = true;
-       return JIM_OK;
+       return ERROR_OK;
 
 error_exit:
-       LOG_ERROR("Error!");
+       command_print(CMD, "Error!");
 
        if (obj->en_capture) {
                obj->en_capture = false;
@@ -785,27 +809,22 @@ error_exit:
 
                target_unregister_timer_callback(arm_tpiu_swo_poll_trace, obj);
 
-               retval = adapter_config_trace(false, 0, 0, NULL, 0, NULL);
-               if (retval != ERROR_OK) {
-                       LOG_ERROR("Failed to stop adapter's trace");
-                       return JIM_ERR;
-               }
+               int retval1 = adapter_config_trace(false, 0, 0, NULL, 0, NULL);
+               if (retval1 != ERROR_OK)
+                       command_print(CMD, "Failed to stop adapter's trace");
        }
-       return JIM_ERR;
+       return retval;
 }
 
-static int jim_arm_tpiu_swo_disable(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+COMMAND_HANDLER(handle_arm_tpiu_swo_disable)
 {
-       struct command *c = jim_to_command(interp);
-       struct arm_tpiu_swo_object *obj = c->jim_handler_data;
+       struct arm_tpiu_swo_object *obj = CMD_DATA;
 
-       if (argc != 1) {
-               Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
-               return JIM_ERR;
-       }
+       if (CMD_ARGC != 0)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        if (!obj->enabled)
-               return JIM_OK;
+               return ERROR_OK;
        obj->enabled = false;
 
        arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_PRE_DISABLE);
@@ -819,20 +838,19 @@ static int jim_arm_tpiu_swo_disable(Jim_Interp *interp, int argc, Jim_Obj *const
 
                int retval = adapter_config_trace(false, 0, 0, NULL, 0, NULL);
                if (retval != ERROR_OK) {
-                       LOG_ERROR("Failed to stop adapter's trace");
-                       return JIM_ERR;
+                       command_print(CMD, "Failed to stop adapter's trace");
+                       return retval;
                }
        }
 
        arm_tpiu_swo_handle_event(obj, TPIU_SWO_EVENT_POST_DISABLE);
 
        /* START_DEPRECATED_TPIU */
-       struct command_context *cmd_ctx = current_command_context(interp);
-       struct target *target = get_current_target(cmd_ctx);
+       struct target *target = get_current_target(CMD_CTX);
        target_handle_event(target, TARGET_EVENT_TRACE_CONFIG);
        /* END_DEPRECATED_TPIU */
 
-       return JIM_OK;
+       return ERROR_OK;
 }
 
 static const struct command_registration arm_tpiu_swo_instance_command_handlers[] = {
@@ -860,14 +878,14 @@ static const struct command_registration arm_tpiu_swo_instance_command_handlers[
        {
                .name = "enable",
                .mode = COMMAND_ANY,
-               .jim_handler = jim_arm_tpiu_swo_enable,
+               .handler = handle_arm_tpiu_swo_enable,
                .usage = "",
                .help = "Enables the TPIU/SWO output",
        },
        {
                .name = "disable",
                .mode = COMMAND_EXEC,
-               .jim_handler = jim_arm_tpiu_swo_disable,
+               .handler = handle_arm_tpiu_swo_disable,
                .usage = "",
                .help = "Disables the TPIU/SWO output",
        },
@@ -916,7 +934,7 @@ static int jim_arm_tpiu_swo_create(Jim_Interp *interp, int argc, Jim_Obj *const
        struct jim_getopt_info goi;
        jim_getopt_setup(&goi, interp, argc - 1, argv + 1);
        if (goi.argc < 1) {
-               Jim_WrongNumArgs(goi.interp, 1, goi.argv, "?name? ..options...");
+               Jim_WrongNumArgs(interp, 1, argv, "name ?option option ...?");
                return JIM_ERR;
        }
 
@@ -963,39 +981,34 @@ err_exit:
        return JIM_ERR;
 }
 
-static int jim_arm_tpiu_swo_names(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+COMMAND_HANDLER(handle_arm_tpiu_swo_names)
 {
        struct arm_tpiu_swo_object *obj;
 
-       if (argc != 1) {
-               Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
-               return JIM_ERR;
-       }
-       Jim_SetResult(interp, Jim_NewListObj(interp, NULL, 0));
-       list_for_each_entry(obj, &all_tpiu_swo, lh) {
-               Jim_ListAppendElement(interp, Jim_GetResult(interp),
-                       Jim_NewStringObj(interp, obj->name, -1));
-       }
-       return JIM_OK;
+       if (CMD_ARGC != 0)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       list_for_each_entry(obj, &all_tpiu_swo, lh)
+               command_print(CMD, "%s", obj->name);
+
+       return ERROR_OK;
 }
 
-static int jim_arm_tpiu_swo_init(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
+COMMAND_HANDLER(handle_arm_tpiu_swo_init)
 {
-       struct command_context *cmd_ctx = current_command_context(interp);
        struct arm_tpiu_swo_object *obj;
-       int retval = JIM_OK;
+       int retval = ERROR_OK;
+
+       if (CMD_ARGC != 0)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       if (argc != 1) {
-               Jim_WrongNumArgs(interp, 1, argv, "Too many parameters");
-               return JIM_ERR;
-       }
        list_for_each_entry(obj, &all_tpiu_swo, lh) {
                if (!obj->deferred_enable)
                        continue;
                LOG_DEBUG("%s: running enable during init", obj->name);
-               int retval2 = command_run_linef(cmd_ctx, "%s enable", obj->name);
+               int retval2 = command_run_linef(CMD_CTX, "%s enable", obj->name);
                if (retval2 != ERROR_OK)
-                       retval = JIM_ERR;
+                       retval = retval2;
        }
        return retval;
 }
@@ -1021,7 +1034,7 @@ COMMAND_HANDLER(handle_tpiu_deprecated_config_command)
                struct cortex_m_common *cm = target_to_cm(target);
                struct adiv5_private_config *pc = target->private_config;
                struct adiv5_dap *dap = pc->dap;
-               int ap_num = pc->ap_num;
+               uint64_t ap_num = pc->ap_num;
                bool set_recheck_ap_cur_target = false;
 
                LOG_INFO(MSG "Adding a TPIU \'%s.tpiu\' in the configuration", target_name(target));
@@ -1039,10 +1052,10 @@ COMMAND_HANDLER(handle_tpiu_deprecated_config_command)
                        set_recheck_ap_cur_target = true;
                }
 
-               LOG_INFO(MSG "Running: \'tpiu create %s.tpiu -dap %s -ap-num %d\'",
+               LOG_INFO(MSG "Running: \'tpiu create %s.tpiu -dap %s -ap-num 0x%" PRIx64 "\'",
                        target_name(target), adiv5_dap_name(dap), ap_num);
 
-               retval = command_run_linef(CMD_CTX, "tpiu create %s.tpiu -dap %s -ap-num %d",
+               retval = command_run_linef(CMD_CTX, "tpiu create %s.tpiu -dap %s -ap-num 0x%" PRIx64,
                        target_name(target), adiv5_dap_name(dap), ap_num);
                if (retval != ERROR_OK)
                        return retval;
@@ -1161,20 +1174,20 @@ static const struct command_registration arm_tpiu_swo_subcommand_handlers[] = {
                .name = "create",
                .mode = COMMAND_ANY,
                .jim_handler = jim_arm_tpiu_swo_create,
-               .usage = "name [-dap dap] [-ap-num num] [-address baseaddr]",
+               .usage = "name [-dap dap] [-ap-num num] [-baseaddr baseaddr]",
                .help = "Creates a new TPIU or SWO object",
        },
        {
                .name = "names",
                .mode = COMMAND_ANY,
-               .jim_handler = jim_arm_tpiu_swo_names,
+               .handler = handle_arm_tpiu_swo_names,
                .usage = "",
                .help = "Lists all registered TPIU and SWO objects by name",
        },
        {
                .name = "init",
                .mode = COMMAND_EXEC,
-               .jim_handler = jim_arm_tpiu_swo_init,
+               .handler = handle_arm_tpiu_swo_init,
                .usage = "",
                .help = "Initialize TPIU and SWO",
        },

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)