forked from auracaster/openocd
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:
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user