Rework/update ARM semihosting
[fw/openocd] / src / target / armv4_5.c
index 06994ca7b456c8eec18f70af4ae04a1b3f57e427..5ee8ead66f757ec6d95ad5ec3d710f0fb4a6453d 100644 (file)
@@ -8,6 +8,9 @@
  *   Copyright (C) 2008 by Oyvind Harboe                                   *
  *   oyvind.harboe@zylin.com                                               *
  *                                                                         *
+ *   Copyright (C) 2018 by Liviu Ionescu                                   *
+ *   <ilg@livius.net>                                                      *
+ *                                                                         *
  *   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     *
@@ -34,6 +37,7 @@
 #include <helper/binarybuffer.h>
 #include "algorithm.h"
 #include "register.h"
+#include "semihosting_common.h"
 
 /* offsets into armv4_5 core register cache */
 enum {
@@ -748,7 +752,7 @@ int arm_arch_state(struct target *target)
        }
 
        /* avoid filling log waiting for fileio reply */
-       if (arm->semihosting_hit_fileio)
+       if (target->semihosting->hit_fileio)
                return ERROR_OK;
 
        LOG_USER("target halted in %s state due to %s, current mode: %s\n"
@@ -758,8 +762,8 @@ int arm_arch_state(struct target *target)
                arm_mode_name(arm->core_mode),
                buf_get_u32(arm->cpsr->value, 0, 32),
                buf_get_u32(arm->pc->value, 0, 32),
-               arm->is_semihosting ? ", semihosting" : "",
-               arm->is_semihosting_fileio ? " fileio" : "");
+               target->semihosting->is_active ? ", semihosting" : "",
+               target->semihosting->is_fileio ? " fileio" : "");
 
        return ERROR_OK;
 }
@@ -1094,119 +1098,10 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
        return JIM_OK;
 }
 
-COMMAND_HANDLER(handle_arm_semihosting_command)
-{
-       struct target *target = get_current_target(CMD_CTX);
-
-       if (target == NULL) {
-               LOG_ERROR("No target selected");
-               return ERROR_FAIL;
-       }
-
-       struct arm *arm = target_to_arm(target);
-
-       if (!is_arm(arm)) {
-               command_print(CMD_CTX, "current target isn't an ARM");
-               return ERROR_FAIL;
-       }
-
-       if (!arm->setup_semihosting) {
-               command_print(CMD_CTX, "semihosting not supported for current target");
-               return ERROR_FAIL;
-       }
-
-       if (CMD_ARGC > 0) {
-               int semihosting;
-
-               COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting);
-
-               if (!target_was_examined(target)) {
-                       LOG_ERROR("Target not examined yet");
-                       return ERROR_FAIL;
-               }
-
-               if (arm->setup_semihosting(target, semihosting) != ERROR_OK) {
-                       LOG_ERROR("Failed to Configure semihosting");
-                       return ERROR_FAIL;
-               }
-
-               /* FIXME never let that "catch" be dropped! */
-               arm->is_semihosting = semihosting;
-       }
-
-       command_print(CMD_CTX, "semihosting is %s",
-               arm->is_semihosting
-               ? "enabled" : "disabled");
-
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_arm_semihosting_fileio_command)
-{
-       struct target *target = get_current_target(CMD_CTX);
-
-       if (target == NULL) {
-               LOG_ERROR("No target selected");
-               return ERROR_FAIL;
-       }
-
-       struct arm *arm = target_to_arm(target);
-
-       if (!is_arm(arm)) {
-               command_print(CMD_CTX, "current target isn't an ARM");
-               return ERROR_FAIL;
-       }
-
-       if (!arm->is_semihosting) {
-               command_print(CMD_CTX, "semihosting is not enabled");
-               return ERROR_FAIL;
-       }
-
-       if (CMD_ARGC > 0)
-               COMMAND_PARSE_ENABLE(CMD_ARGV[0], arm->is_semihosting_fileio);
-
-       command_print(CMD_CTX, "semihosting fileio is %s",
-               arm->is_semihosting_fileio
-               ? "enabled" : "disabled");
-
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(handle_arm_semihosting_cmdline)
-{
-       struct target *target = get_current_target(CMD_CTX);
-       unsigned int i;
-
-       if (target == NULL) {
-               LOG_ERROR("No target selected");
-               return ERROR_FAIL;
-       }
-
-       struct arm *arm = target_to_arm(target);
-
-       if (!is_arm(arm)) {
-               command_print(CMD_CTX, "current target isn't an ARM");
-               return ERROR_FAIL;
-       }
-
-       if (!arm->setup_semihosting) {
-               command_print(CMD_CTX, "semihosting not supported for current target");
-               return ERROR_FAIL;
-       }
-
-       free(arm->semihosting_cmdline);
-       arm->semihosting_cmdline = CMD_ARGC > 0 ? strdup(CMD_ARGV[0]) : NULL;
-
-       for (i = 1; i < CMD_ARGC; i++) {
-               char *cmdline = alloc_printf("%s %s", arm->semihosting_cmdline, CMD_ARGV[i]);
-               if (cmdline == NULL)
-                       break;
-               free(arm->semihosting_cmdline);
-               arm->semihosting_cmdline = cmdline;
-       }
-
-       return ERROR_OK;
-}
+extern __COMMAND_HANDLER(handle_common_semihosting_command);
+extern __COMMAND_HANDLER(handle_common_semihosting_fileio_command);
+extern __COMMAND_HANDLER(handle_common_semihosting_resumable_exit_command);
+extern __COMMAND_HANDLER(handle_common_semihosting_cmdline);
 
 static const struct command_registration arm_exec_command_handlers[] = {
        {
@@ -1245,26 +1140,32 @@ static const struct command_registration arm_exec_command_handlers[] = {
        },
        {
                "semihosting",
-               .handler = handle_arm_semihosting_command,
+               .handler = handle_common_semihosting_command,
                .mode = COMMAND_EXEC,
                .usage = "['enable'|'disable']",
                .help = "activate support for semihosting operations",
        },
        {
                "semihosting_cmdline",
-               .handler = handle_arm_semihosting_cmdline,
+               .handler = handle_common_semihosting_cmdline,
                .mode = COMMAND_EXEC,
                .usage = "arguments",
                .help = "command line arguments to be passed to program",
        },
        {
                "semihosting_fileio",
-               .handler = handle_arm_semihosting_fileio_command,
+               .handler = handle_common_semihosting_fileio_command,
                .mode = COMMAND_EXEC,
                .usage = "['enable'|'disable']",
                .help = "activate support for semihosting fileio operations",
        },
-
+       {
+               "semihosting_resexit",
+               .handler = handle_common_semihosting_resumable_exit_command,
+               .mode = COMMAND_EXEC,
+               .usage = "['enable'|'disable']",
+               .help = "activate support for semihosting resumable exit",
+       },
        COMMAND_REGISTRATION_DONE
 };
 const struct command_registration arm_command_handlers[] = {