From fbf5bec7f3ea9f4a9584099a12e71681cb55ce35 Mon Sep 17 00:00:00 2001 From: drath Date: Sun, 6 Aug 2006 11:20:42 +0000 Subject: [PATCH] - fixed a minor problem with the GDB server that could drop the first packet (non-fatal) - fixed some small memory leaks (thanks to Spencer Oliver) - verify chip- and buswidth of cfi flash configurations - added support for ARM966E based systems (tested only with ST micro STR9, thanks to Spencer Oliver) git-svn-id: svn://svn.berlios.de/openocd/trunk@81 b42882b7-edfa-0310-969c-e2dbd0fdcd60 --- src/flash/cfi.c | 8 + src/server/gdb_server.c | 22 ++ src/target/Makefile.am | 5 +- src/target/arm720t.c | 4 +- src/target/arm7_9_common.c | 2 +- src/target/arm7tdmi.c | 6 +- src/target/arm920t.c | 2 +- src/target/arm966e.c | 461 +++++++++++++++++++++++++++++++++++++ src/target/arm966e.h | 39 ++++ src/target/arm9tdmi.c | 11 +- src/target/armv4_5.c | 2 +- src/target/embeddedice.h | 8 + src/target/target.c | 5 + 13 files changed, 561 insertions(+), 14 deletions(-) create mode 100644 src/target/arm966e.c create mode 100644 src/target/arm966e.h diff --git a/src/flash/cfi.c b/src/flash/cfi.c index 3dc7885c0..fb3d4cc88 100644 --- a/src/flash/cfi.c +++ b/src/flash/cfi.c @@ -50,6 +50,7 @@ int cfi_info(struct flash_bank_s *bank, char *buf, int buf_size); int cfi_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc); #define CFI_MAX_BUS_WIDTH 4 +#define CFI_MAX_CHIP_WIDTH 4 flash_driver_t cfi_flash = { @@ -335,6 +336,13 @@ int cfi_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char ** return ERROR_FLASH_BANK_INVALID; } + if ((strtoul(args[4], NULL, 0) > CFI_MAX_CHIP_WIDTH) + || (strtoul(args[3], NULL, 0) > CFI_MAX_BUS_WIDTH)) + { + ERROR("chip and bus width have to specified in byte"); + return ERROR_FLASH_BANK_INVALID; + } + cfi_info = malloc(sizeof(cfi_flash_bank_t)); bank->driver_priv = cfi_info; diff --git a/src/server/gdb_server.c b/src/server/gdb_server.c index 4b99922cc..c0a2fe84b 100644 --- a/src/server/gdb_server.c +++ b/src/server/gdb_server.c @@ -138,6 +138,23 @@ int gdb_get_char(connection_t *connection, int* next_char) return ERROR_OK; } +int gdb_putback_char(connection_t *connection, int last_char) +{ + gdb_connection_t *gdb_con = connection->priv; + + if (gdb_con->buf_p > gdb_con->buffer) + { + *(--gdb_con->buf_p) = last_char; + gdb_con->buf_cnt++; + } + else + { + ERROR("BUG: couldn't put character back"); + } + + return ERROR_OK; +} + int gdb_put_packet(connection_t *connection, char *buffer, int len) { int i; @@ -219,6 +236,8 @@ int gdb_get_packet(connection_t *connection, char *buffer, int *len) if ((retval = gdb_get_char(connection, &character)) != ERROR_OK) return retval; + DEBUG("character: '%c'", character); + switch (character) { case '$': @@ -427,6 +446,9 @@ int gdb_new_connection(connection_t *connection) if ((retval = gdb_get_char(connection, &initial_ack)) != ERROR_OK) return retval; + if (initial_ack != '+') + gdb_putback_char(connection, initial_ack); + return ERROR_OK; } diff --git a/src/target/Makefile.am b/src/target/Makefile.am index 2192469c3..2936967a4 100644 --- a/src/target/Makefile.am +++ b/src/target/Makefile.am @@ -2,7 +2,8 @@ INCLUDES = -I$(top_srcdir)/src/gdb -I$(top_srcdir)/src/helper -I$(top_srcdir)/s METASOURCES = AUTO noinst_LIBRARIES = libtarget.a libtarget_a_SOURCES = target.c register.c breakpoints.c armv4_5.c embeddedice.c etm.c arm7tdmi.c arm9tdmi.c \ - arm_jtag.c arm7_9_common.c algorithm.c arm920t.c arm720t.c armv4_5_mmu.c armv4_5_cache.c arm_disassembler.c + arm_jtag.c arm7_9_common.c algorithm.c arm920t.c arm720t.c armv4_5_mmu.c armv4_5_cache.c arm_disassembler.c \ + arm966e.c noinst_HEADERS = target.h register.h armv4_5.h embeddedice.h etm.h arm7tdmi.h arm9tdmi.h \ arm_jtag.h arm7_9_common.h arm920t.h arm720t.h armv4_5_mmu.h armv4_5_cache.h breakpoints.h algorithm.h \ - arm_disassembler.h + arm_disassembler.h arm966e.h diff --git a/src/target/arm720t.c b/src/target/arm720t.c index 31428a272..677aa4587 100644 --- a/src/target/arm720t.c +++ b/src/target/arm720t.c @@ -458,7 +458,7 @@ int arm720t_target_command(struct command_context_s *cmd_ctx, char *cmd, char ** chain_pos = strtoul(args[3], NULL, 0); if (argc >= 5) - variant = strdup(args[4]); + variant = args[4]; DEBUG("chain_pos: %i, variant: %s", chain_pos, variant); @@ -475,7 +475,7 @@ int arm720t_register_commands(struct command_context_s *cmd_ctx) retval = arm7tdmi_register_commands(cmd_ctx); - arm720t_cmd = register_command(cmd_ctx, NULL, "arm720t", NULL, COMMAND_ANY, NULL); + arm720t_cmd = register_command(cmd_ctx, NULL, "arm720t", NULL, COMMAND_ANY, "arm720t specific commands"); register_command(cmd_ctx, arm720t_cmd, "cp15", arm720t_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register [value]"); register_command(cmd_ctx, arm720t_cmd, "virt2phys", arm720t_handle_virt2phys_command, COMMAND_EXEC, "translate va to pa "); diff --git a/src/target/arm7_9_common.c b/src/target/arm7_9_common.c index 6bb801254..904d0ca0f 100644 --- a/src/target/arm7_9_common.c +++ b/src/target/arm7_9_common.c @@ -1987,7 +1987,7 @@ 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, NULL); + arm7_9_cmd = register_command(cmd_ctx, NULL, "arm7_9", NULL, COMMAND_ANY, "arm7/9 specific commands"); register_command(cmd_ctx, arm7_9_cmd, "write_xpsr", handle_arm7_9_write_xpsr_command, COMMAND_EXEC, "write program status register "); 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> "); diff --git a/src/target/arm7tdmi.c b/src/target/arm7tdmi.c index f6f0cef71..5f16f71ff 100644 --- a/src/target/arm7tdmi.c +++ b/src/target/arm7tdmi.c @@ -644,11 +644,11 @@ void arm7tdmi_build_reg_cache(target_t *target) } if (arch_info->has_monitor_mode) - (*cache_p)->next->reg_list[0].size = 6; + (*cache_p)->next->reg_list[EICE_DBG_CTRL].size = 6; else - (*cache_p)->next->reg_list[0].size = 3; + (*cache_p)->next->reg_list[EICE_DBG_CTRL].size = 3; - (*cache_p)->next->reg_list[1].size = 5; + (*cache_p)->next->reg_list[EICE_DBG_STAT].size = 5; } diff --git a/src/target/arm920t.c b/src/target/arm920t.c index ac0b6a6ad..d68ca2e44 100644 --- a/src/target/arm920t.c +++ b/src/target/arm920t.c @@ -716,7 +716,7 @@ int arm920t_target_command(struct command_context_s *cmd_ctx, char *cmd, char ** chain_pos = strtoul(args[3], NULL, 0); if (argc >= 5) - variant = strdup(args[4]); + variant = args[4]; DEBUG("chain_pos: %i, variant: %s", chain_pos, variant); diff --git a/src/target/arm966e.c b/src/target/arm966e.c new file mode 100644 index 000000000..b7cfea805 --- /dev/null +++ b/src/target/arm966e.c @@ -0,0 +1,461 @@ +/*************************************************************************** + * Copyright (C) 2005 by Dominic Rath * + * Dominic.Rath@gmx.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "arm966e.h" + +#include "arm7_9_common.h" +#include "register.h" +#include "target.h" +#include "armv4_5.h" +#include "embeddedice.h" +#include "log.h" +#include "jtag.h" +#include "arm_jtag.h" + +#include +#include + +#if 0 +#define _DEBUG_INSTRUCTION_EXECUTION_ +#endif + +/* cli handling */ +int arm966e_register_commands(struct command_context_s *cmd_ctx); + +/* forward declarations */ +int arm966e_deassert_reset(target_t *target); +int arm966e_assert_reset(target_t *target); +int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target); +int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target); +int arm966e_quit(void); + +target_type_t arm966e_target = +{ + .name = "arm966e", + + .poll = arm7_9_poll, + .arch_state = armv4_5_arch_state, + + .halt = arm7_9_halt, + .resume = arm7_9_resume, + .step = arm7_9_step, + + .assert_reset = arm966e_assert_reset, + .deassert_reset = arm966e_deassert_reset, + .soft_reset_halt = arm7_9_soft_reset_halt, + + .get_gdb_reg_list = armv4_5_get_gdb_reg_list, + + .read_memory = arm7_9_read_memory, + .write_memory = arm7_9_write_memory, + .bulk_write_memory = arm7_9_bulk_write_memory, + + .add_breakpoint = arm7_9_add_breakpoint, + .remove_breakpoint = arm7_9_remove_breakpoint, + .add_watchpoint = arm7_9_add_watchpoint, + .remove_watchpoint = arm7_9_remove_watchpoint, + + .register_commands = arm966e_register_commands, + .target_command = arm966e_target_command, + .init_target = arm966e_init_target, + .quit = arm966e_quit, +}; + +int arm966e_assert_reset(target_t *target) +{ + armv4_5_common_t *armv4_5 = target->arch_info; + arm7_9_common_t *arm7_9 = armv4_5->arch_info; + arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info; + arm966e_common_t *arm966e = arm9tdmi->arch_info; + reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; + int retval; + int trst_asserted_with_srt = 0; + + arm966e->monitor_mode_set = 1; + + DEBUG("target->state: %s", target_state_strings[target->state]); + + if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN) + { + /* assert SRST and TRST */ + /* system would get ouf sync if we didn't reset test-logic, too */ + if ((retval = jtag_add_reset(1, 1)) != ERROR_OK) + { + if (retval == ERROR_JTAG_RESET_CANT_SRST) + { + WARNING("can't assert srst"); + return retval; + } + else + { + ERROR("unknown error"); + exit(-1); + } + } + jtag_add_sleep(5000); + if ((retval = jtag_add_reset(0, 1)) != ERROR_OK) + { + if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST) + { + WARNING("srst resets test logic, too"); + retval = jtag_add_reset(1, 1); + trst_asserted_with_srt = 1; + } + } + } + else + { + if ((retval = jtag_add_reset(0, 1)) != ERROR_OK) + { + if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST) + { + WARNING("srst resets test logic, too"); + retval = jtag_add_reset(1, 1); + trst_asserted_with_srt = 1; + } + + if (retval == ERROR_JTAG_RESET_CANT_SRST) + { + WARNING("can't assert srst"); + return retval; + } + else if (retval != ERROR_OK) + { + ERROR("unknown error"); + exit(-1); + } + } + } + + target->state = TARGET_RESET; + jtag_add_sleep(50000); + + armv4_5_invalidate_core_regs(target); + + if( trst_asserted_with_srt == 0 ) + { + DEBUG("monitor mode needs clearing"); + + /* arm9e monitor mode enabled at reset */ + embeddedice_read_reg(dbg_ctrl); + jtag_execute_queue(); + + if(buf_get_u32(dbg_ctrl->value, EICE_DBG_CONTROL_MONEN, 1)) + { + buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_MONEN, 1, 0); + embeddedice_store_reg(dbg_ctrl); + DEBUG("monitor mode disabled"); + } + arm966e->monitor_mode_set = 0; + } + + return ERROR_OK; +} + +int arm966e_deassert_reset(target_t *target) +{ + armv4_5_common_t *armv4_5 = target->arch_info; + arm7_9_common_t *arm7_9 = armv4_5->arch_info; + arm9tdmi_common_t *arm9tdmi = arm7_9->arch_info; + arm966e_common_t *arm966e = arm9tdmi->arch_info; + reg_t *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; + + arm7_9_deassert_reset( target ); + + if( arm966e->monitor_mode_set == 1 ) + { + DEBUG("monitor mode needs clearing"); + + /* arm9e monitor mode enabled at reset */ + embeddedice_read_reg(dbg_ctrl); + jtag_execute_queue(); + + if(buf_get_u32(dbg_ctrl->value, EICE_DBG_CONTROL_MONEN, 1)) + { + buf_set_u32(dbg_ctrl->value, EICE_DBG_CONTROL_MONEN, 1, 0); + embeddedice_store_reg(dbg_ctrl); + arm966e->monitor_mode_set = 0; + DEBUG("monitor mode disabled"); + } + } + + return ERROR_OK; +} + +int arm966e_init_target(struct command_context_s *cmd_ctx, struct target_s *target) +{ + arm9tdmi_init_target(cmd_ctx, target); + + return ERROR_OK; +} + +int arm966e_quit(void) +{ + + return ERROR_OK; +} + +int arm966e_init_arch_info(target_t *target, arm966e_common_t *arm966e, int chain_pos, char *variant) +{ + arm9tdmi_common_t *arm9tdmi = &arm966e->arm9tdmi_common; + + arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant); + + arm9tdmi->arch_info = arm966e; + arm966e->common_magic = ARM966E_COMMON_MAGIC; + + arm9tdmi->has_single_step = 0; + arm9tdmi->has_monitor_mode = 1; + + return ERROR_OK; +} + +int arm966e_target_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct target_s *target) +{ + int chain_pos; + char *variant = NULL; + arm966e_common_t *arm966e = malloc(sizeof(arm966e_common_t)); + + if (argc < 4) + { + ERROR("'target arm966e' requires at least one additional argument"); + exit(-1); + } + + chain_pos = strtoul(args[3], NULL, 0); + + if (argc >= 5) + variant = args[4]; + + DEBUG("chain_pos: %i, variant: %s", chain_pos, variant); + + arm966e_init_arch_info(target, arm966e, chain_pos, variant); + + return ERROR_OK; +} + +int arm966e_get_arch_pointers(target_t *target, armv4_5_common_t **armv4_5_p, arm7_9_common_t **arm7_9_p, arm9tdmi_common_t **arm9tdmi_p, arm966e_common_t **arm966e_p) +{ + armv4_5_common_t *armv4_5 = target->arch_info; + arm7_9_common_t *arm7_9; + arm9tdmi_common_t *arm9tdmi; + arm966e_common_t *arm966e; + + if (armv4_5->common_magic != ARMV4_5_COMMON_MAGIC) + { + return -1; + } + + arm7_9 = armv4_5->arch_info; + if (arm7_9->common_magic != ARM7_9_COMMON_MAGIC) + { + return -1; + } + + arm9tdmi = arm7_9->arch_info; + if (arm9tdmi->common_magic != ARM9TDMI_COMMON_MAGIC) + { + return -1; + } + + arm966e = arm9tdmi->arch_info; + if (arm966e->common_magic != ARM966E_COMMON_MAGIC) + { + return -1; + } + + *armv4_5_p = armv4_5; + *arm7_9_p = arm7_9; + *arm9tdmi_p = arm9tdmi; + *arm966e_p = arm966e; + + return ERROR_OK; +} + +int arm966e_read_cp15(target_t *target, int reg_addr, u32 *value) +{ + 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; + scan_field_t fields[3]; + u8 reg_addr_buf = reg_addr & 0x3f; + u8 nr_w_buf = 0; + + jtag_add_end_state(TAP_RTI); + arm_jtag_scann(jtag_info, 0xf); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); + + fields[0].device = jtag_info->chain_pos; + fields[0].num_bits = 32; + fields[0].out_value = NULL; + fields[0].out_mask = NULL; + fields[0].in_value = NULL; + fields[0].in_check_value = NULL; + fields[0].in_check_mask = NULL; + fields[0].in_handler = NULL; + fields[0].in_handler_priv = NULL; + + fields[1].device = jtag_info->chain_pos; + fields[1].num_bits = 6; + fields[1].out_value = ®_addr_buf; + fields[1].out_mask = NULL; + fields[1].in_value = NULL; + fields[1].in_check_value = NULL; + fields[1].in_check_mask = NULL; + fields[1].in_handler = NULL; + fields[1].in_handler_priv = NULL; + + fields[2].device = jtag_info->chain_pos; + fields[2].num_bits = 1; + fields[2].out_value = &nr_w_buf; + fields[2].out_mask = NULL; + fields[2].in_value = NULL; + fields[2].in_check_value = NULL; + fields[2].in_check_mask = NULL; + fields[2].in_handler = NULL; + fields[2].in_handler_priv = NULL; + + jtag_add_dr_scan(3, fields, -1); + + fields[0].in_value = (u8*)value; + + jtag_add_dr_scan(3, fields, -1); + + return ERROR_OK; +} + +int arm966e_write_cp15(target_t *target, int reg_addr, u32 value) +{ + 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; + scan_field_t fields[3]; + u8 reg_addr_buf = reg_addr & 0x3f; + u8 nr_w_buf = 1; + + jtag_add_end_state(TAP_RTI); + arm_jtag_scann(jtag_info, 0xf); + arm_jtag_set_instr(jtag_info, jtag_info->intest_instr); + + fields[0].device = jtag_info->chain_pos; + fields[0].num_bits = 32; + fields[0].out_value = (u8*)&value; + fields[0].out_mask = NULL; + fields[0].in_value = NULL; + fields[0].in_check_value = NULL; + fields[0].in_check_mask = NULL; + fields[0].in_handler = NULL; + fields[0].in_handler_priv = NULL; + + fields[1].device = jtag_info->chain_pos; + fields[1].num_bits = 6; + fields[1].out_value = ®_addr_buf; + fields[1].out_mask = NULL; + fields[1].in_value = NULL; + fields[1].in_check_value = NULL; + fields[1].in_check_mask = NULL; + fields[1].in_handler = NULL; + fields[1].in_handler_priv = NULL; + + fields[2].device = jtag_info->chain_pos; + fields[2].num_bits = 1; + fields[2].out_value = &nr_w_buf; + fields[2].out_mask = NULL; + fields[2].in_value = NULL; + fields[2].in_check_value = NULL; + fields[2].in_check_mask = NULL; + fields[2].in_handler = NULL; + fields[2].in_handler_priv = NULL; + + jtag_add_dr_scan(3, fields, -1); + + return ERROR_OK; +} + +int arm966e_handle_cp15_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc) +{ + int retval; + target_t *target = get_current_target(cmd_ctx); + armv4_5_common_t *armv4_5; + arm7_9_common_t *arm7_9; + arm9tdmi_common_t *arm9tdmi; + arm966e_common_t *arm966e; + arm_jtag_t *jtag_info; + + if (arm966e_get_arch_pointers(target, &armv4_5, &arm7_9, &arm9tdmi, &arm966e) != ERROR_OK) + { + command_print(cmd_ctx, "current target isn't an ARM966e target"); + return ERROR_OK; + } + + jtag_info = &arm7_9->jtag_info; + + if (target->state != TARGET_HALTED) + { + command_print(cmd_ctx, "target must be stopped for \"%s\" command", cmd); + return ERROR_OK; + } + + /* one or more argument, access a single register (write if second argument is given */ + if (argc >= 1) + { + int address = strtoul(args[0], NULL, 0); + + if (argc == 1) + { + u32 value; + if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK) + { + command_print(cmd_ctx, "couldn't access reg %i", address); + return ERROR_OK; + } + jtag_execute_queue(); + + command_print(cmd_ctx, "%i: %8.8x", address, value); + } + else if (argc == 2) + { + u32 value = strtoul(args[1], NULL, 0); + if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK) + { + command_print(cmd_ctx, "couldn't access reg %i", address); + return ERROR_OK; + } + command_print(cmd_ctx, "%i: %8.8x", address, value); + } + } + + return ERROR_OK; +} + +int arm966e_register_commands(struct command_context_s *cmd_ctx) +{ + int retval; + command_t *arm966e_cmd; + + retval = arm7_9_register_commands(cmd_ctx); + arm966e_cmd = register_command(cmd_ctx, NULL, "arm966e", NULL, COMMAND_ANY, "arm966e specific commands"); + register_command(cmd_ctx, arm966e_cmd, "cp15", arm966e_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register [value]"); + + return ERROR_OK; +} diff --git a/src/target/arm966e.h b/src/target/arm966e.h new file mode 100644 index 000000000..dee067652 --- /dev/null +++ b/src/target/arm966e.h @@ -0,0 +1,39 @@ +/*************************************************************************** + * Copyright (C) 2005 by Dominic Rath * + * Dominic.Rath@gmx.de * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifndef ARM966E_H +#define ARM966E_H + +#include "target.h" +#include "register.h" +#include "embeddedice.h" +#include "arm_jtag.h" +#include "arm9tdmi.h" + +#define ARM966E_COMMON_MAGIC 0x20f920f9 + +typedef struct arm966e_common_s +{ + int common_magic; + arm9tdmi_common_t arm9tdmi_common; + u32 cp15_control_reg; + int monitor_mode_set; +} arm966e_common_t; + +#endif /* ARM966E_H */ diff --git a/src/target/arm9tdmi.c b/src/target/arm9tdmi.c index 04ea676ba..be01dd604 100644 --- a/src/target/arm9tdmi.c +++ b/src/target/arm9tdmi.c @@ -719,11 +719,11 @@ void arm9tdmi_build_reg_cache(target_t *target) arm7_9->eice_cache = (*cache_p)->next; if (arm9tdmi->has_monitor_mode) - (*cache_p)->next->reg_list[0].size = 6; + (*cache_p)->next->reg_list[EICE_DBG_CTRL].size = 6; else - (*cache_p)->next->reg_list[0].size = 4; + (*cache_p)->next->reg_list[EICE_DBG_CTRL].size = 4; - (*cache_p)->next->reg_list[1].size = 5; + (*cache_p)->next->reg_list[EICE_DBG_STAT].size = 5; } @@ -808,7 +808,10 @@ int arm9tdmi_init_arch_info(target_t *target, arm9tdmi_common_t *arm9tdmi, int c arm9tdmi->has_single_step = 1; else if (strcmp(variant, "arm940t") == 0) arm9tdmi->has_single_step = 1; + arm9tdmi->variant = strdup(variant); } + else + arm9tdmi->variant = strdup(""); arm7_9_init_arch_info(target, arm7_9); @@ -831,7 +834,7 @@ int arm9tdmi_target_command(struct command_context_s *cmd_ctx, char *cmd, char * chain_pos = strtoul(args[3], NULL, 0); if (argc >= 5) - variant = strdup(args[4]); + variant = args[4]; arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant); diff --git a/src/target/armv4_5.c b/src/target/armv4_5.c index 2ee34e29c..9ee0577d6 100644 --- a/src/target/armv4_5.c +++ b/src/target/armv4_5.c @@ -428,7 +428,7 @@ int armv4_5_register_commands(struct command_context_s *cmd_ctx) { 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 "); diff --git a/src/target/embeddedice.h b/src/target/embeddedice.h index 0062153f1..e038f92d0 100644 --- a/src/target/embeddedice.h +++ b/src/target/embeddedice.h @@ -46,6 +46,8 @@ enum enum { + EICE_DBG_CONTROL_ICEDIS = 5, + EICE_DBG_CONTROL_MONEN = 4, EICE_DBG_CONTROL_INTDIS = 2, EICE_DBG_CONTROL_DBGRQ = 1, EICE_DBG_CONTROL_DBGACK = 0, @@ -73,6 +75,12 @@ enum EICE_W_CTRL_nRW = 0x1 }; +enum +{ + EICE_COMM_CTRL_WBIT = 1, + EICE_COMM_CTRL_RBIT = 0 +}; + typedef struct embeddedice_reg_s { int addr; diff --git a/src/target/target.c b/src/target/target.c index 8b9939af7..e88fb1967 100644 --- a/src/target/target.c +++ b/src/target/target.c @@ -21,6 +21,7 @@ #include "config.h" #endif +#include "replacements.h" #include "target.h" #include "log.h" @@ -74,6 +75,7 @@ extern target_type_t arm7tdmi_target; extern target_type_t arm720t_target; extern target_type_t arm9tdmi_target; extern target_type_t arm920t_target; +extern target_type_t arm966e_target; target_type_t *target_types[] = { @@ -81,6 +83,7 @@ target_type_t *target_types[] = &arm9tdmi_target, &arm920t_target, &arm720t_target, + &arm966e_target, NULL, }; @@ -692,6 +695,7 @@ int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffe if ((retval = target->type->read_memory(target, address, 1, unaligned, buffer)) != ERROR_OK) return retval; + buffer += unaligned; address += unaligned; size -= unaligned; } @@ -704,6 +708,7 @@ int target_read_buffer(struct target_s *target, u32 address, u32 size, u8 *buffe if ((retval = target->type->read_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK) return retval; + buffer += aligned; address += aligned; size -= aligned; }