change #include "jtag.h" to <jtag/jtag.h>
[fw/openocd] / src / target / target.c
index 3a84040c3bbd629c4be47f55d7b7490aa738cdb5..597046faa97b4cfc2fb8db9aaf543642924184d0 100644 (file)
 #include "target_type.h"
 #include "target_request.h"
 #include "breakpoints.h"
-#include "time_support.h"
+#include <helper/time_support.h>
 #include "register.h"
 #include "trace.h"
 #include "image.h"
-#include "jtag.h"
+#include <jtag/jtag.h>
 
 
-static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv);
-
 static int target_array2mem(Jim_Interp *interp, struct target *target, int argc, Jim_Obj *const *argv);
 static int target_mem2array(Jim_Interp *interp, struct target *target, int argc, Jim_Obj *const *argv);
 
@@ -449,12 +447,12 @@ int target_process_reset(struct command_context *cmd_ctx, enum target_reset_mode
        jtag_poll_set_enabled(false);
 
        sprintf(buf, "ocd_process_reset %s", n->name);
-       retval = Jim_Eval(interp, buf);
+       retval = Jim_Eval(cmd_ctx->interp, buf);
 
        jtag_poll_set_enabled(save_poll);
 
        if (retval != JIM_OK) {
-               Jim_PrintErrorMessage(interp);
+               Jim_PrintErrorMessage(cmd_ctx->interp);
                return ERROR_FAIL;
        }
 
@@ -665,222 +663,145 @@ static void target_reset_examined(struct target *target)
        target->examined = false;
 }
 
-
-
-static int default_mrc(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value)
+static int
+err_read_phys_memory(struct target *target, uint32_t address,
+               uint32_t size, uint32_t count, uint8_t *buffer)
 {
        LOG_ERROR("Not implemented: %s", __func__);
        return ERROR_FAIL;
 }
 
-static int default_mcr(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value)
+static int
+err_write_phys_memory(struct target *target, uint32_t address,
+               uint32_t size, uint32_t count, uint8_t *buffer)
 {
        LOG_ERROR("Not implemented: %s", __func__);
        return ERROR_FAIL;
 }
 
-static int arm_cp_check(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm)
+static int handle_target(void *priv);
+
+static int target_init_one(struct command_context *cmd_ctx,
+               struct target *target)
 {
-       /* basic check */
-       if (!target_was_examined(target))
-       {
-               LOG_ERROR("Target not examined yet");
-               return ERROR_FAIL;
-       }
+       target_reset_examined(target);
 
-       if ((cpnum <0) || (cpnum > 15))
-       {
-               LOG_ERROR("Illegal co-processor %d", cpnum);
-               return ERROR_FAIL;
-       }
+       struct target_type *type = target->type;
+       if (type->examine == NULL)
+               type->examine = default_examine;
 
-       if (op1 > 7)
+       int retval = type->init_target(cmd_ctx, target);
+       if (ERROR_OK != retval)
        {
-               LOG_ERROR("Illegal op1");
-               return ERROR_FAIL;
+               LOG_ERROR("target '%s' init failed", target_name(target));
+               return retval;
        }
 
-       if (op2 > 7)
-       {
-               LOG_ERROR("Illegal op2");
-               return ERROR_FAIL;
-       }
+       /**
+        * @todo get rid of those *memory_imp() methods, now that all
+        * callers are using target_*_memory() accessors ... and make
+        * sure the "physical" paths handle the same issues.
+        */
+       /* a non-invasive way(in terms of patches) to add some code that
+        * runs before the type->write/read_memory implementation
+        */
+       type->write_memory_imp = target->type->write_memory;
+       type->write_memory = target_write_memory_imp;
 
-       if (CRn > 15)
-       {
-               LOG_ERROR("Illegal CRn");
-               return ERROR_FAIL;
-       }
+       type->read_memory_imp = target->type->read_memory;
+       type->read_memory = target_read_memory_imp;
 
-       if (CRm > 15)
+       type->soft_reset_halt_imp = target->type->soft_reset_halt;
+       type->soft_reset_halt = target_soft_reset_halt_imp;
+
+       type->run_algorithm_imp = target->type->run_algorithm;
+       type->run_algorithm = target_run_algorithm_imp;
+
+       /* Sanity-check MMU support ... stub in what we must, to help
+        * implement it in stages, but warn if we need to do so.
+        */
+       if (type->mmu)
        {
-               LOG_ERROR("Illegal CRm");
-               return ERROR_FAIL;
+               if (type->write_phys_memory == NULL)
+               {
+                       LOG_ERROR("type '%s' is missing write_phys_memory",
+                                       type->name);
+                       type->write_phys_memory = err_write_phys_memory;
+               }
+               if (type->read_phys_memory == NULL)
+               {
+                       LOG_ERROR("type '%s' is missing read_phys_memory",
+                                       type->name);
+                       type->read_phys_memory = err_read_phys_memory;
+               }
+               if (type->virt2phys == NULL)
+               {
+                       LOG_ERROR("type '%s' is missing virt2phys", type->name);
+                       type->virt2phys = identity_virt2phys;
+               }
        }
+       else
+       {
+               /* Make sure no-MMU targets all behave the same:  make no
+                * distinction between physical and virtual addresses, and
+                * ensure that virt2phys() is always an identity mapping.
+                */
+               if (type->write_phys_memory || type->read_phys_memory
+                               || type->virt2phys)
+               {
+                       LOG_WARNING("type '%s' has bad MMU hooks", type->name);
+               }
 
+               type->mmu = no_mmu;
+               type->write_phys_memory = type->write_memory;
+               type->read_phys_memory = type->read_memory;
+               type->virt2phys = identity_virt2phys;
+       }
        return ERROR_OK;
 }
 
-int target_mrc(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value)
-{
-       int retval;
-
-       retval = arm_cp_check(target, cpnum, op1, op2, CRn, CRm);
-       if (retval != ERROR_OK)
-               return retval;
-
-       return target->type->mrc(target, cpnum, op1, op2, CRn, CRm, value);
-}
-
-int target_mcr(struct target *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value)
-{
-       int retval;
-
-       retval = arm_cp_check(target, cpnum, op1, op2, CRn, CRm);
-       if (retval != ERROR_OK)
-               return retval;
-
-       return target->type->mcr(target, cpnum, op1, op2, CRn, CRm, value);
-}
-
-static int
-err_read_phys_memory(struct target *target, uint32_t address,
-               uint32_t size, uint32_t count, uint8_t *buffer)
-{
-       LOG_ERROR("Not implemented: %s", __func__);
-       return ERROR_FAIL;
-}
-
-static int
-err_write_phys_memory(struct target *target, uint32_t address,
-               uint32_t size, uint32_t count, uint8_t *buffer)
-{
-       LOG_ERROR("Not implemented: %s", __func__);
-       return ERROR_FAIL;
-}
-
 int target_init(struct command_context *cmd_ctx)
 {
        struct target *target;
        int retval;
 
-       for (target = all_targets; target; target = target->next) {
-               struct target_type *type = target->type;
-
-               target_reset_examined(target);
-               if (target->type->examine == NULL)
-               {
-                       target->type->examine = default_examine;
-               }
-
-               if ((retval = target->type->init_target(cmd_ctx, target)) != ERROR_OK)
-               {
-                       LOG_ERROR("target '%s' init failed", target_name(target));
+       for (target = all_targets; target; target = target->next)
+       {
+               retval = target_init_one(cmd_ctx, target);
+               if (ERROR_OK != retval)
                        return retval;
-               }
-
-               /**
-                * @todo MCR/MRC are ARM-specific; don't require them in
-                * all targets, or for ARMs without coprocessors.
-                */
-               if (target->type->mcr == NULL)
-               {
-                       target->type->mcr = default_mcr;
-               } else
-               {
-                       const struct command_registration mcr_cmd = {
-                               .name = "mcr",
-                               .mode = COMMAND_EXEC,
-                               .jim_handler = &jim_mcrmrc,
-                               .help = "write coprocessor",
-                               .usage = "<cpnum> <op1> <op2> <CRn> <CRm> <value>",
-                       };
-                       register_command(cmd_ctx, NULL, &mcr_cmd);
-               }
+       }
 
-               if (target->type->mrc == NULL)
-               {
-                       target->type->mrc = default_mrc;
-               } else
-               {
-                       const struct command_registration mrc_cmd = {
-                               .name = "mrc",
-                               .jim_handler = &jim_mcrmrc,
-                               .help = "read coprocessor",
-                               .usage = "<cpnum> <op1> <op2> <CRn> <CRm>",
-                       };
-                       register_command(cmd_ctx, NULL, &mrc_cmd);
-               }
+       if (!all_targets)
+               return ERROR_OK;
 
+       retval = target_register_user_commands(cmd_ctx);
+       if (ERROR_OK != retval)
+               return retval;
 
-               /**
-                * @todo get rid of those *memory_imp() methods, now that all
-                * callers are using target_*_memory() accessors ... and make
-                * sure the "physical" paths handle the same issues.
-                */
+       retval = target_register_timer_callback(&handle_target,
+                       100, 1, cmd_ctx->interp);
+       if (ERROR_OK != retval)
+               return retval;
 
-               /* a non-invasive way(in terms of patches) to add some code that
-                * runs before the type->write/read_memory implementation
-                */
-               target->type->write_memory_imp = target->type->write_memory;
-               target->type->write_memory = target_write_memory_imp;
-               target->type->read_memory_imp = target->type->read_memory;
-               target->type->read_memory = target_read_memory_imp;
-               target->type->soft_reset_halt_imp = target->type->soft_reset_halt;
-               target->type->soft_reset_halt = target_soft_reset_halt_imp;
-               target->type->run_algorithm_imp = target->type->run_algorithm;
-               target->type->run_algorithm = target_run_algorithm_imp;
-
-               /* Sanity-check MMU support ... stub in what we must, to help
-                * implement it in stages, but warn if we need to do so.
-                */
-               if (type->mmu) {
-                       if (type->write_phys_memory == NULL) {
-                               LOG_ERROR("type '%s' is missing %s",
-                                               type->name,
-                                               "write_phys_memory");
-                               type->write_phys_memory = err_write_phys_memory;
-                       }
-                       if (type->read_phys_memory == NULL) {
-                               LOG_ERROR("type '%s' is missing %s",
-                                               type->name,
-                                               "read_phys_memory");
-                               type->read_phys_memory = err_read_phys_memory;
-                       }
-                       if (type->virt2phys == NULL) {
-                               LOG_ERROR("type '%s' is missing %s",
-                                               type->name,
-                                               "virt2phys");
-                               type->virt2phys = identity_virt2phys;
-                       }
+       return ERROR_OK;
+}
 
-               /* Make sure no-MMU targets all behave the same:  make no
-                * distinction between physical and virtual addresses, and
-                * ensure that virt2phys() is always an identity mapping.
-                */
-               } else {
-                       if (type->write_phys_memory
-                                       || type->read_phys_memory
-                                       || type->virt2phys)
-                               LOG_WARNING("type '%s' has broken MMU hooks",
-                                               type->name);
-
-                       type->mmu = no_mmu;
-                       type->write_phys_memory = type->write_memory;
-                       type->read_phys_memory = type->read_memory;
-                       type->virt2phys = identity_virt2phys;
-               }
-       }
+COMMAND_HANDLER(handle_target_init_command)
+{
+       if (CMD_ARGC != 0)
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       if (all_targets)
+       static bool target_initialized = false;
+       if (target_initialized)
        {
-               if ((retval = target_register_user_commands(cmd_ctx)) != ERROR_OK)
-                       return retval;
-               if ((retval = target_register_timer_callback(handle_target, 100, 1, NULL)) != ERROR_OK)
-                       return retval;
+               LOG_INFO("'target init' has already been called");
+               return ERROR_OK;
        }
+       target_initialized = true;
 
-       return ERROR_OK;
+       LOG_DEBUG("Initializing targets...");
+       return target_init(CMD_CTX);
 }
 
 int target_register_event_callback(int (*callback)(struct target *target, enum target_event event, void *priv), void *priv)
@@ -1796,8 +1717,9 @@ static void target_call_event_callbacks_all(enum target_event e) {
 }
 
 /* process target state changes */
-int handle_target(void *priv)
+static int handle_target(void *priv)
 {
+       Jim_Interp *interp = (Jim_Interp *)priv;
        int retval = ERROR_OK;
 
        /* we do not want to recurse here... */
@@ -3524,9 +3446,9 @@ void target_handle_event(struct target *target, enum target_event e)
                                           e,
                                           Jim_Nvp_value2name_simple(nvp_target_event, e)->name,
                                           Jim_GetString(teap->body, NULL));
-                       if (Jim_EvalObj(interp, teap->body) != JIM_OK)
+                       if (Jim_EvalObj(teap->interp, teap->body) != JIM_OK)
                        {
-                               Jim_PrintErrorMessage(interp);
+                               Jim_PrintErrorMessage(teap->interp);
                        }
                }
        }
@@ -3668,9 +3590,10 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target)
                                                replace = false;
                                        }
                                        teap->event = n->value;
+                                       teap->interp = goi->interp;
                                        Jim_GetOpt_Obj(goi, &o);
                                        if (teap->body) {
-                                               Jim_DecrRefCount(interp, teap->body);
+                                               Jim_DecrRefCount(teap->interp, teap->body);
                                        }
                                        teap->body  = Jim_DuplicateObj(goi->interp, o);
                                        /*
@@ -3718,7 +3641,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target)
                                        goto no_params;
                                }
                        }
-                       Jim_SetResult(interp, Jim_NewIntObj(goi->interp, target->working_area_virt));
+                       Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_virt));
                        /* loop for more */
                        break;
 
@@ -3736,7 +3659,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target)
                                        goto no_params;
                                }
                        }
-                       Jim_SetResult(interp, Jim_NewIntObj(goi->interp, target->working_area_phys));
+                       Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_phys));
                        /* loop for more */
                        break;
 
@@ -3753,7 +3676,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target)
                                        goto no_params;
                                }
                        }
-                       Jim_SetResult(interp, Jim_NewIntObj(goi->interp, target->working_area_size));
+                       Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->working_area_size));
                        /* loop for more */
                        break;
 
@@ -3771,7 +3694,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target)
                                        goto no_params;
                                }
                        }
-                       Jim_SetResult(interp, Jim_NewIntObj(goi->interp, target->backup_working_area));
+                       Jim_SetResult(goi->interp, Jim_NewIntObj(goi->interp, target->backup_working_area));
                        /* loop for more e*/
                        break;
 
@@ -3838,7 +3761,7 @@ static int target_configure(Jim_GetOptInfo *goi, struct target *target)
                                        goto no_params;
                                }
                        }
-                       Jim_SetResultString(interp, target->tap->dotted_name, -1);
+                       Jim_SetResultString(goi->interp, target->tap->dotted_name, -1);
                        /* loop for more e*/
                        break;
                }
@@ -4486,7 +4409,7 @@ static int target_create(Jim_GetOptInfo *goi)
 
        if (target->tap == NULL)
        {
-               Jim_SetResultString(interp, "-chain-position required when creating target", -1);
+               Jim_SetResultString(goi->interp, "-chain-position required when creating target", -1);
                e = JIM_ERR;
        }
 
@@ -4667,6 +4590,12 @@ static int jim_target_count(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 }
 
 static const struct command_registration target_subcommand_handlers[] = {
+       {
+               .name = "init",
+               .mode = COMMAND_CONFIG,
+               .handler = &handle_target_init_command,
+               .help = "initialize targets",
+       },
        {
                .name = "create",
                .mode = COMMAND_ANY,
@@ -4879,92 +4808,6 @@ COMMAND_HANDLER(handle_fast_load_command)
        return retval;
 }
 
-static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
-{
-       struct command_context *context;
-       struct target *target;
-       int retval;
-
-       context = Jim_GetAssocData(interp, "context");
-       if (context == NULL) {
-               LOG_ERROR("array2mem: no command context");
-               return JIM_ERR;
-       }
-       target = get_current_target(context);
-       if (target == NULL) {
-               LOG_ERROR("array2mem: no current target");
-               return JIM_ERR;
-       }
-
-       if ((argc < 6) || (argc > 7))
-       {
-               return JIM_ERR;
-       }
-
-       int cpnum;
-       uint32_t op1;
-       uint32_t op2;
-       uint32_t CRn;
-       uint32_t CRm;
-       uint32_t value;
-
-       int e;
-       long l;
-       e = Jim_GetLong(interp, argv[1], &l);
-       if (e != JIM_OK) {
-               return e;
-       }
-       cpnum = l;
-
-       e = Jim_GetLong(interp, argv[2], &l);
-       if (e != JIM_OK) {
-               return e;
-       }
-       op1 = l;
-
-       e = Jim_GetLong(interp, argv[3], &l);
-       if (e != JIM_OK) {
-               return e;
-       }
-       CRn = l;
-
-       e = Jim_GetLong(interp, argv[4], &l);
-       if (e != JIM_OK) {
-               return e;
-       }
-       CRm = l;
-
-       e = Jim_GetLong(interp, argv[5], &l);
-       if (e != JIM_OK) {
-               return e;
-       }
-       op2 = l;
-
-       value = 0;
-
-       if (argc == 7)
-       {
-               e = Jim_GetLong(interp, argv[6], &l);
-               if (e != JIM_OK) {
-                       return e;
-               }
-               value = l;
-
-               retval = target_mcr(target, cpnum, op1, op2, CRn, CRm, value);
-               if (retval != ERROR_OK)
-                       return JIM_ERR;
-       } else
-       {
-               retval = target_mrc(target, cpnum, op1, op2, CRn, CRm, &value);
-               if (retval != ERROR_OK)
-                       return JIM_ERR;
-
-               Jim_SetResult(interp, Jim_NewIntObj(interp, value));
-       }
-
-       return JIM_OK;
-}
-
 static const struct command_registration target_command_handlers[] = {
        {
                .name = "targets",