* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+#ifdef HAVE_CONFIG_H
#include "config.h"
+#endif
+
+#include "replacements.h"
#include "arm_disassembler.h"
{
switch (mode)
{
- case 16: return 0; break;
- case 17: return 1; break;
- case 18: return 2; break;
- case 19: return 3; break;
- case 23: return 4; break;
- case 27: return 5; break;
- case 31: return 6; break;
- case -1: return 0; break; /* map MODE_ANY to user mode */
+ case ARMV4_5_MODE_USR: return 0; break;
+ case ARMV4_5_MODE_FIQ: return 1; break;
+ case ARMV4_5_MODE_IRQ: return 2; break;
+ case ARMV4_5_MODE_SVC: return 3; break;
+ case ARMV4_5_MODE_ABT: return 4; break;
+ case ARMV4_5_MODE_UND: return 5; break;
+ case ARMV4_5_MODE_SYS: return 6; break;
+ case ARMV4_5_MODE_ANY: return 0; break; /* map MODE_ANY to user mode */
default:
ERROR("invalid mode value encountered");
return -1;
return ERROR_TARGET_NOT_HALTED;
}
- //retval = armv4_5->armv4_5_common->full_context(target);
+ /* retval = armv4_5->armv4_5_common->full_context(target); */
retval = armv4_5->armv4_5_common->read_core_reg(target, armv4_5->num, armv4_5->mode);
return retval;
}
-int armv4_5_set_core_reg(reg_t *reg, u32 value)
+int armv4_5_set_core_reg(reg_t *reg, u8 *buf)
{
armv4_5_core_reg_t *armv4_5 = reg->arch_info;
target_t *target = armv4_5->target;
+ armv4_5_common_t *armv4_5_target = target->arch_info;
+ u32 value = buf_get_u32(buf, 0, 32);
if (target->state != TARGET_HALTED)
{
return ERROR_TARGET_NOT_HALTED;
}
+ if (reg == &armv4_5_target->core_cache->reg_list[ARMV4_5_CPSR])
+ {
+ if (value & 0x20)
+ {
+ /* T bit should be set */
+ if (armv4_5_target->core_state == ARMV4_5_STATE_ARM)
+ {
+ /* change state to Thumb */
+ DEBUG("changing to Thumb state");
+ armv4_5_target->core_state = ARMV4_5_STATE_THUMB;
+ }
+ }
+ else
+ {
+ /* T bit should be cleared */
+ if (armv4_5_target->core_state == ARMV4_5_STATE_THUMB)
+ {
+ /* change state to ARM */
+ DEBUG("changing to ARM state");
+ armv4_5_target->core_state = ARMV4_5_STATE_ARM;
+ }
+ }
+
+ if (armv4_5_target->core_mode != (value & 0x1f))
+ {
+ DEBUG("changing ARM core mode to '%s'", armv4_5_mode_strings[armv4_5_mode_to_number(value & 0x1f)]);
+ armv4_5_target->core_mode = value & 0x1f;
+ armv4_5_target->write_core_reg(target, 16, ARMV4_5_MODE_ANY, value);
+ }
+ }
+
buf_set_u32(reg->value, 0, 32, value);
reg->dirty = 1;
reg->valid = 1;
int num_regs = 37;
reg_cache_t *cache = malloc(sizeof(reg_cache_t));
reg_t *reg_list = malloc(sizeof(reg_t) * num_regs);
- armv4_5_core_reg_t *arch_info = malloc(sizeof(reg_t) * num_regs);
+ armv4_5_core_reg_t *arch_info = malloc(sizeof(armv4_5_core_reg_t) * num_regs);
int i;
cache->name = "arm v4/5 registers";
return cache;
}
-int armv4_5_arch_state(struct target_s *target, char *buf, int buf_size)
+int armv4_5_arch_state(struct target_s *target)
{
armv4_5_common_t *armv4_5 = target->arch_info;
exit(-1);
}
- snprintf(buf, buf_size,
- "target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8x pc: 0x%8.8x",
+ USER("target halted in %s state due to %s, current mode: %s\ncpsr: 0x%8.8x pc: 0x%8.8x",
armv4_5_state_strings[armv4_5->core_state],
target_debug_reason_strings[target->debug_reason],
armv4_5_mode_strings[armv4_5_mode_to_number(armv4_5->core_mode)],
int i;
arm_instruction_t cur_instruction;
u32 opcode;
- int thumb;
+ int thumb = 0;
if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC)
{
for (i = 0; i < count; i++)
{
- target->type->read_memory(target, address, 4, 1, (u8*)&opcode);
- evaluate_opcode(opcode, address, &cur_instruction);
+ target_read_u32(target, address, &opcode);
+ arm_evaluate_opcode(opcode, address, &cur_instruction);
command_print(cmd_ctx, "%s", cur_instruction.text);
address += (thumb) ? 2 : 4;
}
{
command_t *armv4_5_cmd;
- armv4_5_cmd = register_command(cmd_ctx, NULL, "armv4_5", NULL, COMMAND_ANY, NULL);
+ armv4_5_cmd = register_command(cmd_ctx, NULL, "armv4_5", NULL, COMMAND_ANY, "armv4/5 specific commands");
register_command(cmd_ctx, armv4_5_cmd, "reg", handle_armv4_5_reg_command, COMMAND_EXEC, "display ARM core registers");
register_command(cmd_ctx, armv4_5_cmd, "core_state", handle_armv4_5_core_state_command, COMMAND_EXEC, "display/change ARM core state <arm|thumb>");
armv4_5_common_t *armv4_5 = target->arch_info;
int i;
- if (target->state != TARGET_HALTED)
- {
- return ERROR_TARGET_NOT_HALTED;
- }
-
*reg_list_size = 26;
*reg_list = malloc(sizeof(reg_t*) * (*reg_list_size));
exit(-1);
}
- armv4_5_set_core_reg(reg, buf_get_u32(reg_params[i].value, 0, 32));
+ armv4_5_set_core_reg(reg, reg_params[i].value);
}
armv4_5->core_state = armv4_5_algorithm_info->core_state;
}
}
+ if ((retval != ERROR_TARGET_TIMEOUT) &&
+ (buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32) != exit_point))
+ {
+ WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4x",
+ buf_get_u32(armv4_5->core_cache->reg_list[15].value, 0, 32));
+ }
+
breakpoint_remove(target, exit_point);
for (i = 0; i < num_mem_params; i++)
for (i = 0; i <= 16; i++)
{
- DEBUG("restoring register %s with value 0x%8.8x", ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).name, buf_get_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32));
+ DEBUG("restoring register %s with value 0x%8.8x", ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).name, context[i]);
buf_set_u32(ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).value, 0, 32, context[i]);
ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).valid = 1;
ARMV4_5_CORE_REG_MODE(armv4_5->core_cache, armv4_5_algorithm_info->core_mode, i).dirty = 1;