From: David B. <dbr...@us...> - 2009-11-18 22:23:49
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Main OpenOCD repository". The branch, master has been updated via 8a6d4ced4c0d17626c3875d5f8819efa3ac0f155 (commit) via bbebfd9e134ec84a29dd68bc3661ead57435a4c3 (commit) from 9b1f9810b090958bb4a669034173a01683c6e3e9 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit 8a6d4ced4c0d17626c3875d5f8819efa3ac0f155 Author: David Brownell <dbr...@us...> Date: Wed Nov 18 13:23:00 2009 -0800 ARM: setup "secure monitor mode" shadow regs Teach the "armv4_5" register code to understand about the secure monitor mode: - Add the other three shadowed registers to the arrays - Support another internal mode number (sigh) in mappings - Catch malloc/calloc failures building that register cache This should kick in for Cortex-A8 and ARM1176. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 3e27ba4..562dc1f 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -38,7 +38,8 @@ static const char *armv4_5_core_reg_list[] = { - "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", "r9", "r10", "r11", "r12", "r13_usr", "lr_usr", "pc", + "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", + "r8", "r9", "r10", "r11", "r12", "r13_usr", "lr_usr", "pc", "r8_fiq", "r9_fiq", "r10_fiq", "r11_fiq", "r12_fiq", "r13_fiq", "lr_fiq", @@ -50,7 +51,9 @@ static const char *armv4_5_core_reg_list[] = "r13_und", "lr_und", - "cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und" + "cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und", + + "r13_mon", "lr_mon", "spsr_mon", }; static const struct { @@ -139,6 +142,8 @@ int armv4_5_mode_to_number(enum armv4_5_mode mode) return 5; case ARMV4_5_MODE_SYS: return 6; + case ARM_MODE_MON: + return 7; default: LOG_ERROR("invalid mode value encountered %d", mode); return -1; @@ -163,6 +168,8 @@ enum armv4_5_mode armv4_5_number_to_mode(int number) return ARMV4_5_MODE_UND; case 6: return ARMV4_5_MODE_SYS; + case 7: + return ARM_MODE_MON; default: LOG_ERROR("mode index out of bounds %d", number); return ARMV4_5_MODE_ANY; @@ -218,16 +225,20 @@ static const struct armv4_5_core_reg armv4_5_core_reg_list_arch_info[] = {16, ARMV4_5_MODE_IRQ, NULL, NULL}, {16, ARMV4_5_MODE_SVC, NULL, NULL}, {16, ARMV4_5_MODE_ABT, NULL, NULL}, - {16, ARMV4_5_MODE_UND, NULL, NULL} + {16, ARMV4_5_MODE_UND, NULL, NULL}, + + {13, ARM_MODE_MON, NULL, NULL}, + {14, ARM_MODE_MON, NULL, NULL}, + {16, ARM_MODE_MON, NULL, NULL}, }; /* map core mode (USR, FIQ, ...) and register number to indizes into the register cache */ -const int armv4_5_core_reg_map[7][17] = +const int armv4_5_core_reg_map[8][17] = { { /* USR */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31 }, - { /* FIQ */ + { /* FIQ (8 shadows of USR, vs normal 3) */ 0, 1, 2, 3, 4, 5, 6, 7, 16, 17, 18, 19, 20, 21, 22, 15, 32 }, { /* IRQ */ @@ -242,8 +253,11 @@ const int armv4_5_core_reg_map[7][17] = { /* UND */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 29, 30, 15, 36 }, - { /* SYS */ + { /* SYS (same registers as USR) */ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31 + }, + { /* MON */ + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 37, 38, 15, 39, } }; @@ -359,45 +373,62 @@ static const struct reg_arch_type arm_reg_type = { .set = armv4_5_set_core_reg, }; +/** Marks the contents of the register cache as invalid (and clean). */ int armv4_5_invalidate_core_regs(struct target *target) { struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target); - int i; + unsigned num_regs = armv4_5->core_cache->num_regs; + struct reg *reg = armv4_5->core_cache->reg_list; - for (i = 0; i < 37; i++) - { - armv4_5->core_cache->reg_list[i].valid = 0; - armv4_5->core_cache->reg_list[i].dirty = 0; + for (unsigned i = 0; i < num_regs; i++, reg++) { + reg->valid = 0; + reg->dirty = 0; } + /* FIXME don't bother returning a value then */ return ERROR_OK; } struct reg_cache* armv4_5_build_reg_cache(struct target *target, struct arm *armv4_5_common) { - int num_regs = 37; + int num_regs = ARRAY_SIZE(armv4_5_core_reg_list_arch_info); struct reg_cache *cache = malloc(sizeof(struct reg_cache)); - struct reg *reg_list = malloc(sizeof(struct reg) * num_regs); - struct armv4_5_core_reg *arch_info = malloc(sizeof(struct armv4_5_core_reg) * num_regs); + struct reg *reg_list = calloc(num_regs, sizeof(struct reg)); + struct armv4_5_core_reg *arch_info = calloc(num_regs, + sizeof(struct armv4_5_core_reg)); int i; - cache->name = "arm v4/5 registers"; + if (!cache || !reg_list || !arch_info) { + free(cache); + free(reg_list); + free(arch_info); + return NULL; + } + + cache->name = "ARM registers"; cache->next = NULL; cache->reg_list = reg_list; - cache->num_regs = num_regs; + cache->num_regs = 0; - for (i = 0; i < 37; i++) + for (i = 0; i < num_regs; i++) { + /* Skip registers this core doesn't expose */ + if (armv4_5_core_reg_list_arch_info[i].mode == ARM_MODE_MON + && armv4_5_common->core_type != ARM_MODE_MON) + continue; + + /* REVISIT handle Cortex-M, which only shadows R13/SP */ + arch_info[i] = armv4_5_core_reg_list_arch_info[i]; arch_info[i].target = target; arch_info[i].armv4_5_common = armv4_5_common; reg_list[i].name = (char *) armv4_5_core_reg_list[i]; reg_list[i].size = 32; reg_list[i].value = calloc(1, 4); - reg_list[i].dirty = 0; - reg_list[i].valid = 0; reg_list[i].type = &arm_reg_type; reg_list[i].arch_info = &arch_info[i]; + + cache->num_regs++; } return cache; diff --git a/src/target/armv4_5.h b/src/target/armv4_5.h index f9aa4ba..e3d053c 100644 --- a/src/target/armv4_5.h +++ b/src/target/armv4_5.h @@ -56,7 +56,7 @@ typedef enum armv4_5_state extern char* armv4_5_state_strings[]; -extern const int armv4_5_core_reg_map[7][17]; +extern const int armv4_5_core_reg_map[8][17]; #define ARMV4_5_CORE_REG_MODE(cache, mode, num) \ cache->reg_list[armv4_5_core_reg_map[armv4_5_mode_to_number(mode)][num]] @@ -69,7 +69,8 @@ enum ARMV4_5_SPSR_IRQ = 33, ARMV4_5_SPSR_SVC = 34, ARMV4_5_SPSR_ABT = 35, - ARMV4_5_SPSR_UND = 36 + ARMV4_5_SPSR_UND = 36, + ARM_SPSR_MON = 39, }; #define ARMV4_5_COMMON_MAGIC 0x0A450A45 commit bbebfd9e134ec84a29dd68bc3661ead57435a4c3 Author: David Brownell <dbr...@us...> Date: Wed Nov 18 13:22:27 2009 -0800 ARM: add "core_type" field to "struct arm" It's used to flag cores with the "TrustZone" extension, and is used in subsequent patches to set up support for the registers shadowed by its new secure monitor mode. The ARM1176 and Cortex-A8 both support this new mode. Signed-off-by: David Brownell <dbr...@us...> diff --git a/src/target/arm11.c b/src/target/arm11.c index 3a23585..6e007cf 100644 --- a/src/target/arm11.c +++ b/src/target/arm11.c @@ -1780,6 +1780,11 @@ static int arm11_init_target(struct command_context *cmd_ctx, struct target *target) { /* Initialize anything we can set up without talking to the target */ + + /* FIXME Switch to use the standard build_reg_cache() not custom + * code. Do it from examine(), after we check whether we're + * an arm1176 and thus support the Secure Monitor mode. + */ return arm11_build_reg_cache(target); } @@ -1787,7 +1792,7 @@ static int arm11_init_target(struct command_context *cmd_ctx, static int arm11_examine(struct target *target) { int retval; - + char *type; FNC_INFO; struct arm11_common *arm11 = target_to_arm11(target); @@ -1818,13 +1823,21 @@ static int arm11_examine(struct target *target) switch (arm11->device_id & 0x0FFFF000) { - case 0x07B36000: LOG_INFO("found ARM1136"); break; - case 0x07B56000: LOG_INFO("found ARM1156"); break; - case 0x07B76000: LOG_INFO("found ARM1176"); break; + case 0x07B36000: + type = "ARM1136"; + break; + case 0x07B56000: + type = "ARM1156"; + break; + case 0x07B76000: + arm11->arm.core_type = ARM_MODE_MON; + type = "ARM1176"; + break; default: LOG_ERROR("'target arm11' expects IDCODE 0x*7B*7****"); return ERROR_FAIL; } + LOG_INFO("found %s", type); arm11->debug_version = (arm11->didr >> 16) & 0x0F; diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index d22e0f3..3e27ba4 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -1015,5 +1015,8 @@ int armv4_5_init_arch_info(struct target *target, struct arm *armv4_5) armv4_5->core_state = ARMV4_5_STATE_ARM; armv4_5->core_mode = ARMV4_5_MODE_USR; + /* core_type may be overridden by subtype logic */ + armv4_5->core_type = ARMV4_5_MODE_ANY; + return ERROR_OK; } diff --git a/src/target/armv4_5.h b/src/target/armv4_5.h index 81eac47..f9aa4ba 100644 --- a/src/target/armv4_5.h +++ b/src/target/armv4_5.h @@ -89,7 +89,15 @@ struct arm int common_magic; struct reg_cache *core_cache; - int /* armv4_5_mode */ core_mode; + /** + * Indicates what registers are in the ARM state core register set. + * ARMV4_5_MODE_ANY indicates the standard set of 37 registers, + * seen on for example ARM7TDMI cores. ARM_MODE_MON indicates three + * more registers are shadowed, for "Secure Monitor" mode. + */ + enum armv4_5_mode core_type; + + enum armv4_5_mode core_mode; enum armv4_5_state core_state; /** Flag reporting unavailability of the BKPT instruction. */ diff --git a/src/target/cortex_a8.c b/src/target/cortex_a8.c index 04b3f87..f8ff392 100644 --- a/src/target/cortex_a8.c +++ b/src/target/cortex_a8.c @@ -1423,6 +1423,8 @@ static void cortex_a8_build_reg_cache(struct target *target) struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); struct armv4_5_common_s *armv4_5 = target_to_armv4_5(target); + armv4_5->core_type = ARM_MODE_MON; + (*cache_p) = armv4_5_build_reg_cache(target, armv4_5); armv4_5->core_cache = (*cache_p); } ----------------------------------------------------------------------- Summary of changes: src/target/arm11.c | 21 +++++++++++-- src/target/armv4_5.c | 72 +++++++++++++++++++++++++++++++++++------------ src/target/armv4_5.h | 15 ++++++++-- src/target/cortex_a8.c | 2 + 4 files changed, 84 insertions(+), 26 deletions(-) hooks/post-receive -- Main OpenOCD repository |