#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 target_array2mem(Jim_Interp *interp, struct target *target, int argc, Jim_Obj *const *argv);
static int handle_target(void *priv);
-int target_init(struct command_context *cmd_ctx)
+static int target_init_one(struct command_context *cmd_ctx,
+ struct target *target)
{
- struct target *target;
- int retval;
+ target_reset_examined(target);
- for (target = all_targets; target; target = target->next) {
- struct target_type *type = target->type;
+ struct target_type *type = target->type;
+ if (type->examine == NULL)
+ type->examine = default_examine;
- target_reset_examined(target);
- if (target->type->examine == NULL)
- {
- target->type->examine = default_examine;
- }
+ int retval = type->init_target(cmd_ctx, target);
+ if (ERROR_OK != retval)
+ {
+ LOG_ERROR("target '%s' init failed", target_name(target));
+ return retval;
+ }
- if ((retval = target->type->init_target(cmd_ctx, target)) != ERROR_OK)
- {
- LOG_ERROR("target '%s' init failed", target_name(target));
- 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.
+ */
+ /* 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;
+ type->read_memory_imp = target->type->read_memory;
+ type->read_memory = target_read_memory_imp;
- /**
- * @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.
- */
+ type->soft_reset_halt_imp = target->type->soft_reset_halt;
+ type->soft_reset_halt = target_soft_reset_halt_imp;
- /* 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;
- }
+ 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)
+ {
+ 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.
*/
- } 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;
+ 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;
+}
- if (all_targets)
+int target_init(struct command_context *cmd_ctx)
+{
+ struct target *target;
+ int retval;
+
+ for (target = all_targets; target; target = target->next)
{
- if ((retval = target_register_user_commands(cmd_ctx)) != ERROR_OK)
- return retval;
- if ((retval = target_register_timer_callback(&handle_target, 100, 1, cmd_ctx->interp)) != ERROR_OK)
+ retval = target_init_one(cmd_ctx, target);
+ if (ERROR_OK != retval)
return retval;
}
+ if (!all_targets)
+ return ERROR_OK;
+
+ retval = target_register_user_commands(cmd_ctx);
+ if (ERROR_OK != retval)
+ return retval;
+
+ retval = target_register_timer_callback(&handle_target,
+ 100, 1, cmd_ctx->interp);
+ if (ERROR_OK != retval)
+ return retval;
+
return ERROR_OK;
}
+COMMAND_HANDLER(handle_target_init_command)
+{
+ if (CMD_ARGC != 0)
+ return ERROR_COMMAND_SYNTAX_ERROR;
+
+ static bool target_initialized = false;
+ if (target_initialized)
+ {
+ LOG_INFO("'target init' has already been called");
+ return ERROR_OK;
+ }
+ target_initialized = true;
+
+ 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)
{
struct target_event_callback **callbacks_p = &target_event_callbacks;
}
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,