#include "embeddedice.h"
#include "target.h"
+#include "target_request.h"
#include "armv4_5.h"
#include "arm_jtag.h"
#include "jtag.h"
/* restore original instruction (kept in target endianness) */
if (breakpoint->length == 4)
{
- target->type->write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
+ u32 current_instr;
+ /* check that user program as not modified breakpoint instruction */
+ target->type->read_memory(target, breakpoint->address, 4, 1, (u8*)¤t_instr);
+ if (current_instr==arm7_9->arm_bkpt)
+ target->type->write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
}
else
{
- target->type->write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
+ u16 current_instr;
+ /* check that user program as not modified breakpoint instruction */
+ target->type->read_memory(target, breakpoint->address, 2, 1, (u8*)¤t_instr);
+ if (current_instr==arm7_9->thumb_bkpt)
+ target->type->write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
}
breakpoint->set = 0;
}
int arm7_9_execute_fast_sys_speed(struct target_s *target)
{
- u8 check_value[4], check_mask[4];
+ static int set=0;
+ static u8 check_value[4], check_mask[4];
armv4_5_common_t *armv4_5 = target->arch_info;
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
jtag_add_end_state(TAP_RTI);
arm_jtag_set_instr(jtag_info, 0x4, NULL);
- /* check for DBGACK and SYSCOMP set (others don't care) */
- buf_set_u32(check_value, 0, 32, 0x9);
- buf_set_u32(check_mask, 0, 32, 0x9);
+ if (!set)
+ {
+ /* check for DBGACK and SYSCOMP set (others don't care) */
+
+ /* NB! These are constants that must be available until after next jtag_execute() and
+ we evaluate the values upon first execution in lieu of setting up these constants
+ during early setup.
+ */
+ buf_set_u32(check_value, 0, 32, 0x9);
+ buf_set_u32(check_mask, 0, 32, 0x9);
+ set=1;
+ }
/* read debug status register */
embeddedice_read_reg_w_check(dbg_stat, check_value, check_value);
return ERROR_OK;
}
+int arm7_9_target_request_data(target_t *target, u32 size, u8 *buffer)
+{
+ armv4_5_common_t *armv4_5 = target->arch_info;
+ arm7_9_common_t *arm7_9 = armv4_5->arch_info;
+ arm_jtag_t *jtag_info = &arm7_9->jtag_info;
+ u32 *data;
+ int i;
+
+ data = malloc(size * (sizeof(u32)));
+
+ embeddedice_receive(jtag_info, data, size);
+
+ for (i = 0; i < size; i++)
+ {
+ h_u32_to_le(buffer + (i * 4), data[i]);
+ }
+
+ free(data);
+
+ return ERROR_OK;
+}
+
+int arm7_9_handle_target_request(void *priv)
+{
+ target_t *target = priv;
+ armv4_5_common_t *armv4_5 = target->arch_info;
+ arm7_9_common_t *arm7_9 = armv4_5->arch_info;
+ arm_jtag_t *jtag_info = &arm7_9->jtag_info;
+ reg_t *dcc_control = &arm7_9->eice_cache->reg_list[EICE_COMMS_CTRL];
+
+ if (!target->dbg_msg_enabled)
+ return ERROR_OK;
+
+ if (target->state == TARGET_RUNNING)
+ {
+ /* read DCC control register */
+ embeddedice_read_reg(dcc_control);
+ jtag_execute_queue();
+
+ /* check W bit */
+ if (buf_get_u32(dcc_control->value, 1, 1) == 1)
+ {
+ u32 request;
+
+ embeddedice_receive(jtag_info, &request, 1);
+ target_request(target, request);
+ }
+ }
+
+ return ERROR_OK;
+}
+
enum target_state arm7_9_poll(target_t *target)
{
int retval;
armv4_5_common_t *armv4_5 = target->arch_info;
arm7_9_common_t *arm7_9 = armv4_5->arch_info;
+ /* poll the target, and resume if it was currently halted */
+ arm7_9_poll(target);
+ if (target->state == TARGET_HALTED)
+ {
+ arm7_9_resume(target, 1, 0x0, 0, 1);
+ }
+
if (arm7_9->has_vector_catch)
{
/* program vector catch register to catch reset vector */
return ERROR_OK;
}
+int arm7_9_checksum_memory(struct target_s *target, u32 address, u32 count, u32* checksum)
+{
+ working_area_t *crc_algorithm;
+ armv4_5_algorithm_t armv4_5_info;
+ reg_param_t reg_params[2];
+ int retval;
+
+ u32 arm7_9_crc_code[] = {
+ 0xE1A02000, /* mov r2, r0 */
+ 0xE3E00000, /* mov r0, #0xffffffff */
+ 0xE1A03001, /* mov r3, r1 */
+ 0xE3A04000, /* mov r4, #0 */
+ 0xEA00000B, /* b ncomp */
+ /* nbyte: */
+ 0xE7D21004, /* ldrb r1, [r2, r4] */
+ 0xE59F7030, /* ldr r7, CRC32XOR */
+ 0xE0200C01, /* eor r0, r0, r1, asl 24 */
+ 0xE3A05000, /* mov r5, #0 */
+ /* loop: */
+ 0xE3500000, /* cmp r0, #0 */
+ 0xE1A06080, /* mov r6, r0, asl #1 */
+ 0xE2855001, /* add r5, r5, #1 */
+ 0xE1A00006, /* mov r0, r6 */
+ 0xB0260007, /* eorlt r0, r6, r7 */
+ 0xE3550008, /* cmp r5, #8 */
+ 0x1AFFFFF8, /* bne loop */
+ 0xE2844001, /* add r4, r4, #1 */
+ /* ncomp: */
+ 0xE1540003, /* cmp r4, r3 */
+ 0x1AFFFFF1, /* bne nbyte */
+ /* end: */
+ 0xEAFFFFFE, /* b end */
+ 0x04C11DB7 /* CRC32XOR: .word 0x04C11DB7 */
+ };
+
+ int i;
+
+ if (target_alloc_working_area(target, sizeof(arm7_9_crc_code), &crc_algorithm) != ERROR_OK)
+ {
+ return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+ }
+
+ /* convert flash writing code into a buffer in target endianness */
+ for (i = 0; i < (sizeof(arm7_9_crc_code)/sizeof(u32)); i++)
+ target_write_u32(target, crc_algorithm->address + i*sizeof(u32), arm7_9_crc_code[i]);
+
+ armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
+ armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
+ armv4_5_info.core_state = ARMV4_5_STATE_ARM;
+
+ init_reg_param(®_params[0], "r0", 32, PARAM_IN_OUT);
+ init_reg_param(®_params[1], "r1", 32, PARAM_OUT);
+
+ buf_set_u32(reg_params[0].value, 0, 32, address);
+ buf_set_u32(reg_params[1].value, 0, 32, count);
+
+ if ((retval = target->type->run_algorithm(target, 0, NULL, 2, reg_params,
+ crc_algorithm->address, crc_algorithm->address + (sizeof(arm7_9_crc_code) - 8), 20000, &armv4_5_info)) != ERROR_OK)
+ {
+ ERROR("error executing arm7_9 crc algorithm");
+ destroy_reg_param(®_params[0]);
+ destroy_reg_param(®_params[1]);
+ target_free_working_area(target, crc_algorithm);
+ return retval;
+ }
+
+ *checksum = buf_get_u32(reg_params[0].value, 0, 32);
+
+ destroy_reg_param(®_params[0]);
+ destroy_reg_param(®_params[1]);
+
+ target_free_working_area(target, crc_algorithm);
+
+ return ERROR_OK;
+}
+
int arm7_9_register_commands(struct command_context_s *cmd_ctx)
{
command_t *arm7_9_cmd;
arm7_9_cmd = register_command(cmd_ctx, NULL, "arm7_9", NULL, COMMAND_ANY, "arm7/9 specific commands");
- register_command(cmd_ctx, arm7_9_cmd, "etm", handle_arm7_9_etm_command, COMMAND_CONFIG, NULL);
-
register_command(cmd_ctx, arm7_9_cmd, "write_xpsr", handle_arm7_9_write_xpsr_command, COMMAND_EXEC, "write program status register <value> <not cpsr|spsr>");
register_command(cmd_ctx, arm7_9_cmd, "write_xpsr_im8", handle_arm7_9_write_xpsr_im8_command, COMMAND_EXEC, "write program status register <8bit immediate> <rotate> <not cpsr|spsr>");
COMMAND_ANY, "use DCC downloads for larger memory writes <enable|disable>");
armv4_5_register_commands(cmd_ctx);
- etb_register_commands(cmd_ctx, arm7_9_cmd);
+
+ etm_register_commands(cmd_ctx);
return ERROR_OK;
}
return ERROR_OK;
}
-int handle_arm7_9_etm_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
- target_t *target;
- armv4_5_common_t *armv4_5;
- arm7_9_common_t *arm7_9;
-
- if (argc != 1)
- {
- ERROR("incomplete 'arm7_9 etm <target>' command");
- exit(-1);
- }
-
- target = get_target_by_num(strtoul(args[0], NULL, 0));
-
- if (!target)
- {
- ERROR("target number '%s' not defined", args[0]);
- exit(-1);
- }
-
- if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
- {
- command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
- return ERROR_OK;
- }
-
- arm7_9->has_etm = 1;
-
- return ERROR_OK;
-}
-
-int handle_arm7_9_etb_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
-{
- target_t *target;
- jtag_device_t *jtag_device;
- armv4_5_common_t *armv4_5;
- arm7_9_common_t *arm7_9;
-
- if (argc != 2)
- {
- ERROR("incomplete 'arm7_9 etb <target> <chain_pos>' command");
- exit(-1);
- }
-
- target = get_target_by_num(strtoul(args[0], NULL, 0));
-
- if (!target)
- {
- ERROR("target number '%s' not defined", args[0]);
- exit(-1);
- }
-
- if (arm7_9_get_arch_pointers(target, &armv4_5, &arm7_9) != ERROR_OK)
- {
- command_print(cmd_ctx, "current target isn't an ARM7/ARM9 target");
- return ERROR_OK;
- }
-
- jtag_device = jtag_get_device(strtoul(args[1], NULL, 0));
-
- if (!jtag_device)
- {
- ERROR("jtag device number '%s' not defined", args[1]);
- exit(-1);
- }
-
- arm7_9->etb = malloc(sizeof(etb_t));
-
- arm7_9->etb->chain_pos = strtoul(args[1], NULL, 0);
- arm7_9->etb->cur_scan_chain = -1;
- arm7_9->etb->reg_cache = NULL;
- arm7_9->etb->RAM_width = 0;
- arm7_9->etb->RAM_depth = 0;
-
- return ERROR_OK;
-}
-
int arm7_9_init_arch_info(target_t *target, arm7_9_common_t *arm7_9)
{
armv4_5_common_t *armv4_5 = &arm7_9->armv4_5_common;
arm7_9->force_hw_bkpts = 0;
arm7_9->use_dbgrq = 0;
- arm7_9->has_etm = 0;
- arm7_9->etb = NULL;
+ arm7_9->etm_ctx = NULL;
arm7_9->has_single_step = 0;
arm7_9->has_monitor_mode = 0;
arm7_9->has_vector_catch = 0;
armv4_5_init_arch_info(target, armv4_5);
+ target_register_timer_callback(arm7_9_handle_target_request, 1, 1, target);
+
return ERROR_OK;
}