summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--doc/openocd.texi14
-rw-r--r--src/target/target.c65
2 files changed, 51 insertions, 28 deletions
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 8223ee94..475482df 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -5051,9 +5051,11 @@ about what TAP is the current target, or about MMU configuration.
Display contents of address @var{addr}, as
32-bit words (@command{mdw}), 16-bit halfwords (@command{mdh}),
or 8-bit bytes (@command{mdb}).
+When the current target has an MMU which is present and active,
+@var{addr} is interpreted as a virtual address.
+Otherwise, or if the optional @var{phys} flag is specified,
+@var{addr} is interpreted as a physical address.
If @var{count} is specified, displays that many units.
-@var{phys} is an optional flag to indicate to use
-physical address and bypass MMU
(If you want to manipulate the data instead of displaying it,
see the @code{mem2array} primitives.)
@end deffn
@@ -5062,10 +5064,12 @@ see the @code{mem2array} primitives.)
@deffnx Command mwh [phys] addr halfword
@deffnx Command mwb [phys] addr byte
Writes the specified @var{word} (32 bits),
-@var{halfword} (16 bits), or @var{byte} (8-bit) pattern,
+@var{halfword} (16 bits), or @var{byte} (8-bit) value,
at the specified address @var{addr}.
-@var{phys} is an optional flag to indicate to use
-physical address and bypass MMU
+When the current target has an MMU which is present and active,
+@var{addr} is interpreted as a virtual address.
+Otherwise, or if the optional @var{phys} flag is specified,
+@var{addr} is interpreted as a physical address.
@end deffn
diff --git a/src/target/target.c b/src/target/target.c
index 5cdfa5dc..1bf680d1 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -756,11 +756,12 @@ err_write_phys_memory(struct target_s *target, uint32_t address,
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)
{
@@ -773,22 +774,6 @@ int target_init(struct command_context_s *cmd_ctx)
return retval;
}
- /* Set up default functions if none are provided by target */
- if (target->type->virt2phys == NULL)
- {
- target->type->virt2phys = identity_virt2phys;
- }
-
- if (target->type->read_phys_memory == NULL)
- {
- target->type->read_phys_memory = err_read_phys_memory;
- }
-
- if (target->type->write_phys_memory == NULL)
- {
- target->type->write_phys_memory = err_write_phys_memory;
- }
-
/**
* @todo MCR/MRC are ARM-specific; don't require them in
* all targets, or for ARMs without coprocessors.
@@ -833,11 +818,45 @@ int target_init(struct command_context_s *cmd_ctx)
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 = no_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)