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>
This commit is contained in:
David Brownell 2009-11-10 11:58:31 -08:00
parent 6881c1b6d6
commit 61af6a6816
2 changed files with 51 additions and 28 deletions

View File

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

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