diff options
author | David Brownell <dbrownell@users.sourceforge.net> | 2009-11-10 11:58:31 -0800 |
---|---|---|
committer | David Brownell <dbrownell@users.sourceforge.net> | 2009-11-10 11:58:31 -0800 |
commit | 61af6a681671eae69256dcc5b9e853cf9b161387 (patch) | |
tree | 2a2d5a5cdcf577fee19093aeaec829e394be6114 /src | |
parent | 6881c1b6d686c91a8cd604bdcd6098ab62d4dcb9 (diff) | |
download | openocd+libswd-61af6a681671eae69256dcc5b9e853cf9b161387.tar.gz openocd+libswd-61af6a681671eae69256dcc5b9e853cf9b161387.tar.bz2 openocd+libswd-61af6a681671eae69256dcc5b9e853cf9b161387.tar.xz openocd+libswd-61af6a681671eae69256dcc5b9e853cf9b161387.zip |
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>
Diffstat (limited to 'src')
-rw-r--r-- | src/target/target.c | 65 |
1 files changed, 42 insertions, 23 deletions
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) |