Commit 61af6a68 authored by David Brownell's avatar David Brownell
Browse files

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: default avatarDavid Brownell <dbrownell@users.sourceforge.net>
parent 6881c1b6
...@@ -5051,9 +5051,11 @@ about what TAP is the current target, or about MMU configuration. ...@@ -5051,9 +5051,11 @@ about what TAP is the current target, or about MMU configuration.
Display contents of address @var{addr}, as Display contents of address @var{addr}, as
32-bit words (@command{mdw}), 16-bit halfwords (@command{mdh}), 32-bit words (@command{mdw}), 16-bit halfwords (@command{mdh}),
or 8-bit bytes (@command{mdb}). 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. 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, (If you want to manipulate the data instead of displaying it,
see the @code{mem2array} primitives.) see the @code{mem2array} primitives.)
@end deffn @end deffn
...@@ -5062,10 +5064,12 @@ see the @code{mem2array} primitives.) ...@@ -5062,10 +5064,12 @@ see the @code{mem2array} primitives.)
@deffnx Command mwh [phys] addr halfword @deffnx Command mwh [phys] addr halfword
@deffnx Command mwb [phys] addr byte @deffnx Command mwb [phys] addr byte
Writes the specified @var{word} (32 bits), 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}. at the specified address @var{addr}.
@var{phys} is an optional flag to indicate to use When the current target has an MMU which is present and active,
physical address and bypass MMU @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 @end deffn
......
...@@ -756,11 +756,12 @@ err_write_phys_memory(struct target_s *target, uint32_t address, ...@@ -756,11 +756,12 @@ err_write_phys_memory(struct target_s *target, uint32_t address,
int target_init(struct command_context_s *cmd_ctx) int target_init(struct command_context_s *cmd_ctx)
{ {
target_t *target = all_targets; struct target_s *target;
int retval; int retval;
while (target) for (target = all_targets; target; target = target->next) {
{ struct target_type_s *type = target->type;
target_reset_examined(target); target_reset_examined(target);
if (target->type->examine == NULL) if (target->type->examine == NULL)
{ {
...@@ -773,22 +774,6 @@ int target_init(struct command_context_s *cmd_ctx) ...@@ -773,22 +774,6 @@ int target_init(struct command_context_s *cmd_ctx)
return retval; 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 * @todo MCR/MRC are ARM-specific; don't require them in
* all targets, or for ARMs without coprocessors. * all targets, or for ARMs without coprocessors.
...@@ -833,11 +818,45 @@ int target_init(struct command_context_s *cmd_ctx) ...@@ -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_imp = target->type->run_algorithm;
target->type->run_algorithm = target_run_algorithm_imp; target->type->run_algorithm = target_run_algorithm_imp;
if (target->type->mmu == NULL) /* Sanity-check MMU support ... stub in what we must, to help
{ * implement it in stages, but warn if we need to do so.
target->type->mmu = no_mmu; */
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) if (all_targets)
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment