Browse Source

target: MMU-aware init for memory read/write

Start switching MMU handling over to a more sensible scheme.
Having an mmu() method enables MMU-aware behaviors.  Not having
one kicks in simpler ones, with no distinction between virtual
and physical addresses.

Currently only a handful of targets have methods to read/write
physical memory:  just arm720, arm920, and arm926.  They should
all initialize OK now, but the arm*20 parts don't do the "extra"
stuff arm926 does (which should arguably be target-generic).

Also simplify how target_init() loops over all targets by making
it be a normal "for" loop, instead of scattering its three parts
to the four winds.

Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
tags/v0.4.0-rc1
David Brownell 14 years ago
parent
commit
61af6a6816
2 changed files with 51 additions and 28 deletions
  1. +9
    -5
      doc/openocd.texi
  2. +42
    -23
      src/target/target.c

+ 9
- 5
doc/openocd.texi View File

@@ -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




+ 42
- 23
src/target/target.c View File

@@ -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)


Loading…
Cancel
Save