diff options
author | zwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2009-07-16 00:08:21 +0000 |
---|---|---|
committer | zwelch <zwelch@b42882b7-edfa-0310-969c-e2dbd0fdcd60> | 2009-07-16 00:08:21 +0000 |
commit | 16e17ab1b33c8d40cc28bf621fc7995366a28a8a (patch) | |
tree | 21f068ec71cc16f0b25616c3e4c642cb6a6a61b7 /src/target/cortex_m3.c | |
parent | 0c2ff267aadc8997e2a337d43eb3a3510f2bd2a1 (diff) |
Magnus Lundin <lundin@mlu.mine.nu>, Oyvind Harboe <oyvind.harboe@zylin.com>, David Brownell <david-b@pacbell.net>:
Some cleanup of the ARMv7-M support:
- Reference the relevant ARMv7-M ARM doc (DDI 0405C to non-Vendors), and
update the Cortex-M3 doc refs (DDI 0337C is no longer available).
- Those registers aren't actually general, and some are incorrect (per all
public docs anyway). Update comments and code accordingly.
* What the Core Debug facility exposes is *implementation-specific*
not architectural. These values aren't fully portable. They match
Cortex-M3 ... so no current implementation will make trouble, but
the next v7m implementation might.
* Four of the registers are actually not exposed that way. Before
Cortex-M3 r2p0 they are read/written through MRS/MSR instructions.
In that newest silicon, they are four bytes in one register, not
four separate registers.
- Update the CM3 code to report when that one register is available,
and not try to access it when it isn't. Also declare the register
numbers that an eventual MRS/MSR solution will need to be using.
- Stop line wrapping the exception labels.
So for parts before r2p0 OpenOCD behavior is effectively unchanged, and
still buggy; but for those newer parts a few things might now be correct.
Most current Cortex-M3 parts use r1p1 (or earlier); this seems to include
most LM3S parts and all STM32 parts. Parts using r2p0 are available, and
include fourth generation LM3S parts ("Tempest") plus AT91SAM3 and LPC17xx
parts which are now sampling.
git-svn-id: svn://svn.berlios.de/openocd/trunk@2543 b42882b7-edfa-0310-969c-e2dbd0fdcd60
Diffstat (limited to 'src/target/cortex_m3.c')
-rw-r--r-- | src/target/cortex_m3.c | 49 |
1 files changed, 31 insertions, 18 deletions
diff --git a/src/target/cortex_m3.c b/src/target/cortex_m3.c index 2e19cd67..8cb1bd4e 100644 --- a/src/target/cortex_m3.c +++ b/src/target/cortex_m3.c @@ -24,7 +24,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * * * * - * Cortex-M3(tm) TRM, ARM DDI 0337C * + * Cortex-M3(tm) TRM, ARM DDI 0337E (r1p1) and 0337G (r2p0) * * * ***************************************************************************/ #ifdef HAVE_CONFIG_H @@ -395,7 +395,7 @@ int cortex_m3_debug_entry(target_t *target) /* Examine target state and mode */ /* First load register acessible through core debug port*/ - for (i = 0; i < ARMV7M_PRIMASK; i++) + for (i = 0; i < ARMV7NUMCOREREGS; i++) { if (!armv7m->core_cache->reg_list[i].valid) armv7m->read_core_reg(target, i); @@ -418,22 +418,19 @@ int cortex_m3_debug_entry(target_t *target) cortex_m3_store_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 16, xPSR &~ 0xff); } - /* Now we can load SP core registers */ - for (i = ARMV7M_PRIMASK; i < ARMV7NUMCOREREGS; i++) - { - if (!armv7m->core_cache->reg_list[i].valid) - armv7m->read_core_reg(target, i); - } - /* Are we in an exception handler */ if (xPSR & 0x1FF) { armv7m->core_mode = ARMV7M_MODE_HANDLER; armv7m->exception_number = (xPSR & 0x1FF); } - else + else if (armv7m->has_spec20) { - armv7m->core_mode = buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_CONTROL].value, 0, 1); + /* NOTE: CONTROL is bits 31:24 of SPEC20 register, holding + * a two-bit field. Unavailable before r2p0... + */ + armv7m->core_mode = buf_get_u32( + armv7m->core_cache->reg_list[ARMV7M_SPEC20].value, 24, 2); armv7m->exception_number = 0; } @@ -636,16 +633,26 @@ int cortex_m3_resume(struct target_s *target, int current, uint32_t address, int if (debug_execution) { /* Disable interrupts */ - /* We disable interrupts in the PRIMASK register instead of masking with C_MASKINTS, + /* We disable interrupts in the PRIMASK register instead + * of masking with C_MASKINTS, * This is probably the same issue as Cortex-M3 Errata 377493: - * C_MASKINTS in parallel with disabled interrupts can cause local faults to not be taken. */ - buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_PRIMASK].value, 0, 32, 1); - armv7m->core_cache->reg_list[ARMV7M_PRIMASK].dirty = 1; - armv7m->core_cache->reg_list[ARMV7M_PRIMASK].valid = 1; + * C_MASKINTS in parallel with disabled interrupts can cause + * local faults to not be taken. (FIXED in r1p0 and later.) + * + * NOTE: PRIMASK is bits 7:0 of SPEC20 register, holding a + * one bit field. Available this way for r2p0 and later... + */ + if (armv7m->has_spec20) { + buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_SPEC20] + .value, 0, 1, 1); + armv7m->core_cache->reg_list[ARMV7M_SPEC20].dirty = 1; + armv7m->core_cache->reg_list[ARMV7M_SPEC20].valid = 1; + } /* Make sure we are in Thumb mode */ buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32, - buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32) | (1 << 24)); + buf_get_u32(armv7m->core_cache->reg_list[ARMV7M_xPSR].value, 0, 32) + | (1 << 24)); armv7m->core_cache->reg_list[ARMV7M_xPSR].dirty = 1; armv7m->core_cache->reg_list[ARMV7M_xPSR].valid = 1; } @@ -1467,8 +1474,14 @@ int cortex_m3_examine(struct target_s *target) if ((retval = target_read_u32(target, CPUID, &cpuid)) != ERROR_OK) return retval; - if (((cpuid >> 4) & 0xc3f) == 0xc23) + if (((cpuid >> 4) & 0xc3f) == 0xc23) { LOG_DEBUG("CORTEX-M3 processor detected"); + if (((cpuid >> 20) & 0xf) >= 2) { + armv7m->has_spec20 = true; + LOG_DEBUG("r2p0 or later detected"); + } + } else + LOG_WARNING("not a CORTEX-M3 processor?"); LOG_DEBUG("cpuid: 0x%8.8" PRIx32 "", cpuid); target_read_u32(target, NVIC_ICTR, &ictr); |