ARM: add arm_mode_name()
Add and use arm_mode_name() to map from PSR bits to user meaningful names. It uses a new table which, later, can be used to hold other mode-coupled data. Add definitions for the "Secure Monitor" mode, as seen on some ARM11 cores (like ARM1176) and on Cortex-A8. The previous mode name scheme didn't understand that mode. Remove the old mechanism ... there were two copies, caused by Cortex-A8 needing to add "Secure Monitor" mode support. Signed-off-by: David Brownell <dbrownell@users.sourceforge.net>
This commit is contained in:
parent
d6c8945662
commit
ec93209f51
|
@ -239,7 +239,7 @@ static int arm720t_arch_state(struct target *target)
|
||||||
"MMU: %s, Cache: %s",
|
"MMU: %s, Cache: %s",
|
||||||
armv4_5_state_strings[armv4_5->core_state],
|
armv4_5_state_strings[armv4_5->core_state],
|
||||||
Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name ,
|
Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name ,
|
||||||
armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
|
arm_mode_name(armv4_5->core_mode),
|
||||||
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
|
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
|
||||||
buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
|
buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
|
||||||
state[arm720t->armv4_5_mmu.mmu_enabled],
|
state[arm720t->armv4_5_mmu.mmu_enabled],
|
||||||
|
|
|
@ -1420,7 +1420,8 @@ static int arm7_9_debug_entry(struct target *target)
|
||||||
return ERROR_TARGET_FAILURE;
|
return ERROR_TARGET_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
LOG_DEBUG("target entered debug state in %s mode", armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)]);
|
LOG_DEBUG("target entered debug state in %s mode",
|
||||||
|
arm_mode_name(armv4_5->core_mode));
|
||||||
|
|
||||||
if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
|
if (armv4_5->core_state == ARMV4_5_STATE_THUMB)
|
||||||
{
|
{
|
||||||
|
@ -1613,7 +1614,8 @@ int arm7_9_restore_context(struct target *target)
|
||||||
*/
|
*/
|
||||||
for (i = 0; i < 6; i++)
|
for (i = 0; i < 6; i++)
|
||||||
{
|
{
|
||||||
LOG_DEBUG("examining %s mode", armv4_5_mode_strings[i]);
|
LOG_DEBUG("examining %s mode",
|
||||||
|
arm_mode_name(armv4_5->core_mode));
|
||||||
dirty = 0;
|
dirty = 0;
|
||||||
mode_change = 0;
|
mode_change = 0;
|
||||||
/* check if there are dirty registers in the current mode
|
/* check if there are dirty registers in the current mode
|
||||||
|
@ -1675,7 +1677,10 @@ int arm7_9_restore_context(struct target *target)
|
||||||
num_regs++;
|
num_regs++;
|
||||||
reg->dirty = 0;
|
reg->dirty = 0;
|
||||||
reg->valid = 1;
|
reg->valid = 1;
|
||||||
LOG_DEBUG("writing register %i of mode %s with value 0x%8.8" PRIx32 "", j, armv4_5_mode_strings[i], regs[j]);
|
LOG_DEBUG("writing register %i mode %s "
|
||||||
|
"with value 0x%8.8" PRIx32, j,
|
||||||
|
arm_mode_name(armv4_5->core_mode),
|
||||||
|
regs[j]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -451,7 +451,7 @@ int arm920t_arch_state(struct target *target)
|
||||||
"MMU: %s, D-Cache: %s, I-Cache: %s",
|
"MMU: %s, D-Cache: %s, I-Cache: %s",
|
||||||
armv4_5_state_strings[armv4_5->core_state],
|
armv4_5_state_strings[armv4_5->core_state],
|
||||||
Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
|
Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
|
||||||
armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
|
arm_mode_name(armv4_5->core_mode),
|
||||||
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
|
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
|
||||||
buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
|
buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
|
||||||
state[arm920t->armv4_5_mmu.mmu_enabled],
|
state[arm920t->armv4_5_mmu.mmu_enabled],
|
||||||
|
|
|
@ -509,7 +509,7 @@ int arm926ejs_arch_state(struct target *target)
|
||||||
"MMU: %s, D-Cache: %s, I-Cache: %s",
|
"MMU: %s, D-Cache: %s, I-Cache: %s",
|
||||||
armv4_5_state_strings[armv4_5->core_state],
|
armv4_5_state_strings[armv4_5->core_state],
|
||||||
Jim_Nvp_value2name_simple(nvp_target_debug_reason,target->debug_reason)->name,
|
Jim_Nvp_value2name_simple(nvp_target_debug_reason,target->debug_reason)->name,
|
||||||
armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
|
arm_mode_name(armv4_5->core_mode),
|
||||||
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
|
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
|
||||||
buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
|
buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
|
||||||
state[arm926ejs->armv4_5_mmu.mmu_enabled],
|
state[arm926ejs->armv4_5_mmu.mmu_enabled],
|
||||||
|
|
|
@ -53,13 +53,63 @@ char* armv4_5_core_reg_list[] =
|
||||||
"cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und"
|
"cpsr", "spsr_fiq", "spsr_irq", "spsr_svc", "spsr_abt", "spsr_und"
|
||||||
};
|
};
|
||||||
|
|
||||||
static const char *armv4_5_mode_strings_list[] =
|
static const struct {
|
||||||
{
|
const char *name;
|
||||||
"Illegal mode value", "User", "FIQ", "IRQ", "Supervisor", "Abort", "Undefined", "System"
|
unsigned psr;
|
||||||
|
} arm_mode_data[] = {
|
||||||
|
/* Seven modes are standard from ARM7 on. "System" and "User" share
|
||||||
|
* the same registers; other modes shadow from 3 to 8 registers.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
.name = "User",
|
||||||
|
.psr = ARMV4_5_MODE_USR,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "FIQ",
|
||||||
|
.psr = ARMV4_5_MODE_FIQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "Supervisor",
|
||||||
|
.psr = ARMV4_5_MODE_SVC,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "Abort",
|
||||||
|
.psr = ARMV4_5_MODE_ABT,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "IRQ",
|
||||||
|
.psr = ARMV4_5_MODE_IRQ,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "Undefined" /* instruction */,
|
||||||
|
.psr = ARMV4_5_MODE_UND,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
.name = "System",
|
||||||
|
.psr = ARMV4_5_MODE_SYS,
|
||||||
|
},
|
||||||
|
/* TrustZone "Security Extensions" add a secure monitor mode.
|
||||||
|
* This is distinct from a "debug monitor" which can support
|
||||||
|
* non-halting debug, in conjunction with some debuggers.
|
||||||
|
*/
|
||||||
|
{
|
||||||
|
.name = "Secure Monitor",
|
||||||
|
.psr = ARM_MODE_MON,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Hack! Yuk! allow -1 index, which simplifies codepaths elsewhere in the code */
|
/** Map PSR mode bits to the name of an ARM processor operating mode. */
|
||||||
const char **armv4_5_mode_strings = armv4_5_mode_strings_list + 1;
|
const char *arm_mode_name(unsigned psr_mode)
|
||||||
|
{
|
||||||
|
unsigned i;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(arm_mode_data); i++) {
|
||||||
|
if (arm_mode_data[i].psr == psr_mode)
|
||||||
|
return arm_mode_data[i].name;
|
||||||
|
}
|
||||||
|
LOG_ERROR("unrecognized psr mode: %#02x", psr_mode);
|
||||||
|
return "UNRECOGNIZED";
|
||||||
|
}
|
||||||
|
|
||||||
/** Map PSR mode bits to linear number */
|
/** Map PSR mode bits to linear number */
|
||||||
int armv4_5_mode_to_number(enum armv4_5_mode mode)
|
int armv4_5_mode_to_number(enum armv4_5_mode mode)
|
||||||
|
@ -282,7 +332,8 @@ int armv4_5_set_core_reg(struct reg *reg, uint8_t *buf)
|
||||||
|
|
||||||
if (armv4_5_target->core_mode != (enum armv4_5_mode)(value & 0x1f))
|
if (armv4_5_target->core_mode != (enum armv4_5_mode)(value & 0x1f))
|
||||||
{
|
{
|
||||||
LOG_DEBUG("changing ARM core mode to '%s'", armv4_5_mode_strings[armv4_5_mode_to_number(value & 0x1f)]);
|
LOG_DEBUG("changing ARM core mode to '%s'",
|
||||||
|
arm_mode_name(value & 0x1f));
|
||||||
armv4_5_target->core_mode = value & 0x1f;
|
armv4_5_target->core_mode = value & 0x1f;
|
||||||
armv4_5_target->write_core_reg(target, 16, ARMV4_5_MODE_ANY, value);
|
armv4_5_target->write_core_reg(target, 16, ARMV4_5_MODE_ANY, value);
|
||||||
}
|
}
|
||||||
|
@ -357,7 +408,7 @@ int armv4_5_arch_state(struct target *target)
|
||||||
LOG_USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "",
|
LOG_USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "",
|
||||||
armv4_5_state_strings[armv4_5->core_state],
|
armv4_5_state_strings[armv4_5->core_state],
|
||||||
Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
|
Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name,
|
||||||
armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
|
arm_mode_name(armv4_5->core_mode),
|
||||||
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
|
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
|
||||||
buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
|
buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
|
||||||
|
|
||||||
|
|
|
@ -35,16 +35,16 @@ typedef enum armv4_5_mode
|
||||||
ARMV4_5_MODE_IRQ = 18,
|
ARMV4_5_MODE_IRQ = 18,
|
||||||
ARMV4_5_MODE_SVC = 19,
|
ARMV4_5_MODE_SVC = 19,
|
||||||
ARMV4_5_MODE_ABT = 23,
|
ARMV4_5_MODE_ABT = 23,
|
||||||
|
ARM_MODE_MON = 26,
|
||||||
ARMV4_5_MODE_UND = 27,
|
ARMV4_5_MODE_UND = 27,
|
||||||
ARMV4_5_MODE_SYS = 31,
|
ARMV4_5_MODE_SYS = 31,
|
||||||
ARMV4_5_MODE_ANY = -1
|
ARMV4_5_MODE_ANY = -1
|
||||||
} armv4_5_mode_t;
|
} armv4_5_mode_t;
|
||||||
|
|
||||||
|
const char *arm_mode_name(unsigned psr_mode);
|
||||||
int armv4_5_mode_to_number(enum armv4_5_mode mode);
|
int armv4_5_mode_to_number(enum armv4_5_mode mode);
|
||||||
enum armv4_5_mode armv4_5_number_to_mode(int number);
|
enum armv4_5_mode armv4_5_number_to_mode(int number);
|
||||||
|
|
||||||
extern const char **armv4_5_mode_strings;
|
|
||||||
|
|
||||||
typedef enum armv4_5_state
|
typedef enum armv4_5_state
|
||||||
{
|
{
|
||||||
ARMV4_5_STATE_ARM,
|
ARMV4_5_STATE_ARM,
|
||||||
|
|
|
@ -47,15 +47,6 @@ char* armv7a_core_reg_list[] =
|
||||||
"r13_mon", "lr_mon", "spsr_mon"
|
"r13_mon", "lr_mon", "spsr_mon"
|
||||||
};
|
};
|
||||||
|
|
||||||
char * armv7a_mode_strings_list[] =
|
|
||||||
{
|
|
||||||
"Illegal mode value", "User", "FIQ", "IRQ",
|
|
||||||
"Supervisor", "Abort", "Undefined", "System", "Monitor"
|
|
||||||
};
|
|
||||||
|
|
||||||
/* Hack! Yuk! allow -1 index, which simplifies codepaths elsewhere in the code */
|
|
||||||
char** armv7a_mode_strings = armv7a_mode_strings_list+1;
|
|
||||||
|
|
||||||
char* armv7a_state_strings[] =
|
char* armv7a_state_strings[] =
|
||||||
{
|
{
|
||||||
"ARM", "Thumb", "Jazelle", "ThumbEE"
|
"ARM", "Thumb", "Jazelle", "ThumbEE"
|
||||||
|
@ -183,8 +174,7 @@ int armv7a_arch_state(struct target *target)
|
||||||
armv7a_state_strings[armv7a->core_state],
|
armv7a_state_strings[armv7a->core_state],
|
||||||
Jim_Nvp_value2name_simple(nvp_target_debug_reason,
|
Jim_Nvp_value2name_simple(nvp_target_debug_reason,
|
||||||
target->debug_reason)->name,
|
target->debug_reason)->name,
|
||||||
armv7a_mode_strings[
|
arm_mode_name(armv4_5->core_mode),
|
||||||
armv7a_mode_to_number(armv4_5->core_mode)],
|
|
||||||
armv7a_core_reg_list[armv7a_core_reg_map[
|
armv7a_core_reg_list[armv7a_core_reg_map[
|
||||||
armv7a_mode_to_number(armv4_5->core_mode)][16]],
|
armv7a_mode_to_number(armv4_5->core_mode)][16]],
|
||||||
buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
|
buf_get_u32(ARMV7A_CORE_REG_MODE(armv4_5->core_cache,
|
||||||
|
|
|
@ -37,8 +37,6 @@ typedef enum armv7a_mode
|
||||||
ARMV7A_MODE_ANY = -1
|
ARMV7A_MODE_ANY = -1
|
||||||
} armv7a_t;
|
} armv7a_t;
|
||||||
|
|
||||||
extern char **armv7a_mode_strings;
|
|
||||||
|
|
||||||
typedef enum armv7a_state
|
typedef enum armv7a_state
|
||||||
{
|
{
|
||||||
ARMV7A_STATE_ARM,
|
ARMV7A_STATE_ARM,
|
||||||
|
|
|
@ -857,7 +857,7 @@ static int xscale_arch_state(struct target *target)
|
||||||
"%s",
|
"%s",
|
||||||
armv4_5_state_strings[armv4_5->core_state],
|
armv4_5_state_strings[armv4_5->core_state],
|
||||||
Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name ,
|
Jim_Nvp_value2name_simple(nvp_target_debug_reason, target->debug_reason)->name ,
|
||||||
armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
|
arm_mode_name(armv4_5->core_mode),
|
||||||
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
|
buf_get_u32(armv4_5->core_cache->reg_list[ARMV4_5_CPSR].value, 0, 32),
|
||||||
buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
|
buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32),
|
||||||
state[xscale->armv4_5_mmu.mmu_enabled],
|
state[xscale->armv4_5_mmu.mmu_enabled],
|
||||||
|
@ -960,7 +960,8 @@ static int xscale_debug_entry(struct target *target)
|
||||||
LOG_ERROR("cpsr contains invalid mode value - communication failure");
|
LOG_ERROR("cpsr contains invalid mode value - communication failure");
|
||||||
return ERROR_TARGET_FAILURE;
|
return ERROR_TARGET_FAILURE;
|
||||||
}
|
}
|
||||||
LOG_DEBUG("target entered debug state in %s mode", armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)]);
|
LOG_DEBUG("target entered debug state in %s mode",
|
||||||
|
arm_mode_name(armv4_5->core_mode));
|
||||||
|
|
||||||
if (buffer[9] & 0x20)
|
if (buffer[9] & 0x20)
|
||||||
armv4_5->core_state = ARMV4_5_STATE_THUMB;
|
armv4_5->core_state = ARMV4_5_STATE_THUMB;
|
||||||
|
|
Loading…
Reference in New Issue