return retval;
}
-static int default_virt2phys(struct target_s *target, uint32_t virtual, uint32_t *physical)
+static int identity_virt2phys(struct target_s *target,
+ uint32_t virtual, uint32_t *physical)
{
*physical = virtual;
return ERROR_OK;
}
-static int default_mmu(struct target_s *target, int *enabled)
+static int no_mmu(struct target_s *target, int *enabled)
{
*enabled = 0;
return ERROR_OK;
static int default_mrc(struct target_s *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value)
{
- LOG_ERROR("Not implemented");
+ LOG_ERROR("Not implemented: %s", __func__);
return ERROR_FAIL;
}
static int default_mcr(struct target_s *target, int cpnum, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value)
{
- LOG_ERROR("Not implemented");
+ LOG_ERROR("Not implemented: %s", __func__);
return ERROR_FAIL;
}
return target->type->mcr(target, cpnum, op1, op2, CRn, CRm, value);
}
-static int default_read_phys_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+static int
+err_read_phys_memory(struct target_s *target, uint32_t address,
+ uint32_t size, uint32_t count, uint8_t *buffer)
{
- LOG_ERROR("Not implemented");
+ LOG_ERROR("Not implemented: %s", __func__);
return ERROR_FAIL;
}
-static int default_write_phys_memory(struct target_s *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer)
+static int
+err_write_phys_memory(struct target_s *target, uint32_t address,
+ uint32_t size, uint32_t count, uint8_t *buffer)
{
- LOG_ERROR("Not implemented");
+ LOG_ERROR("Not implemented: %s", __func__);
return ERROR_FAIL;
}
-
int target_init(struct command_context_s *cmd_ctx)
{
- target_t *target = all_targets;
+ struct target_s *target;
int retval;
- while (target)
- {
+ for (target = all_targets; target; target = target->next) {
+ struct target_type_s *type = target->type;
+
target_reset_examined(target);
if (target->type->examine == NULL)
{
return retval;
}
- /* Set up default functions if none are provided by target */
- if (target->type->virt2phys == NULL)
- {
- target->type->virt2phys = default_virt2phys;
- }
-
- if (target->type->read_phys_memory == NULL)
- {
- target->type->read_phys_memory = default_read_phys_memory;
- }
-
- if (target->type->write_phys_memory == NULL)
- {
- target->type->write_phys_memory = default_write_phys_memory;
- }
-
+ /**
+ * @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;
}
+ /**
+ * @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
*/
target->type->run_algorithm_imp = target->type->run_algorithm;
target->type->run_algorithm = target_run_algorithm_imp;
- if (target->type->mmu == NULL)
- {
- target->type->mmu = default_mmu;
+ /* 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;
+ }
+
+ /* 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;
}
- target = target->next;
}
if (all_targets)
}
/* Dump a gmon.out histogram file. */
-static void writeGmon(uint32_t *samples, uint32_t sampleNum, char *filename)
+static void writeGmon(uint32_t *samples, uint32_t sampleNum, const char *filename)
{
uint32_t i;
FILE *f = fopen(filename, "w");
"loads active fast load image to current target "
"- mainly for profiling purposes");
-
+ /** @todo don't register virt2phys() unless target supports it */
register_command(cmd_ctx, NULL, "virt2phys",
handle_virt2phys_command, COMMAND_ANY,
"translate a virtual address into a physical address");
+
register_command(cmd_ctx, NULL, "reg",
handle_reg_command, COMMAND_EXEC,
"display or set a register");