- 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-e2dbd0fdcd60tags/v0.1.0
@@ -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); | 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_BUS_WIDTH 4 | ||||
#define CFI_MAX_CHIP_WIDTH 4 | |||||
flash_driver_t cfi_flash = | 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; | 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)); | cfi_info = malloc(sizeof(cfi_flash_bank_t)); | ||||
bank->driver_priv = cfi_info; | bank->driver_priv = cfi_info; | ||||
@@ -138,6 +138,23 @@ int gdb_get_char(connection_t *connection, int* next_char) | |||||
return ERROR_OK; | 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 gdb_put_packet(connection_t *connection, char *buffer, int len) | ||||
{ | { | ||||
int i; | 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) | if ((retval = gdb_get_char(connection, &character)) != ERROR_OK) | ||||
return retval; | return retval; | ||||
DEBUG("character: '%c'", character); | |||||
switch (character) | switch (character) | ||||
{ | { | ||||
case '$': | case '$': | ||||
@@ -427,6 +446,9 @@ int gdb_new_connection(connection_t *connection) | |||||
if ((retval = gdb_get_char(connection, &initial_ack)) != ERROR_OK) | if ((retval = gdb_get_char(connection, &initial_ack)) != ERROR_OK) | ||||
return retval; | return retval; | ||||
if (initial_ack != '+') | |||||
gdb_putback_char(connection, initial_ack); | |||||
return ERROR_OK; | return ERROR_OK; | ||||
} | } | ||||
@@ -2,7 +2,8 @@ INCLUDES = -I$(top_srcdir)/src/gdb -I$(top_srcdir)/src/helper -I$(top_srcdir)/s | |||||
METASOURCES = AUTO | METASOURCES = AUTO | ||||
noinst_LIBRARIES = libtarget.a | noinst_LIBRARIES = libtarget.a | ||||
libtarget_a_SOURCES = target.c register.c breakpoints.c armv4_5.c embeddedice.c etm.c arm7tdmi.c arm9tdmi.c \ | 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 \ | 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_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 |
@@ -458,7 +458,7 @@ int arm720t_target_command(struct command_context_s *cmd_ctx, char *cmd, char ** | |||||
chain_pos = strtoul(args[3], NULL, 0); | chain_pos = strtoul(args[3], NULL, 0); | ||||
if (argc >= 5) | if (argc >= 5) | ||||
variant = strdup(args[4]); | |||||
variant = args[4]; | |||||
DEBUG("chain_pos: %i, variant: %s", chain_pos, variant); | 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); | 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 <opcode> [value]"); | register_command(cmd_ctx, arm720t_cmd, "cp15", arm720t_handle_cp15_command, COMMAND_EXEC, "display/modify cp15 register <opcode> [value]"); | ||||
register_command(cmd_ctx, arm720t_cmd, "virt2phys", arm720t_handle_virt2phys_command, COMMAND_EXEC, "translate va to pa <va>"); | register_command(cmd_ctx, arm720t_cmd, "virt2phys", arm720t_handle_virt2phys_command, COMMAND_EXEC, "translate va to pa <va>"); | ||||
@@ -1987,7 +1987,7 @@ int arm7_9_register_commands(struct command_context_s *cmd_ctx) | |||||
{ | { | ||||
command_t *arm7_9_cmd; | 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 <value> <not cpsr|spsr>"); | 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>"); | 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>"); | ||||
@@ -644,11 +644,11 @@ void arm7tdmi_build_reg_cache(target_t *target) | |||||
} | } | ||||
if (arch_info->has_monitor_mode) | 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 | 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; | |||||
} | } | ||||
@@ -716,7 +716,7 @@ int arm920t_target_command(struct command_context_s *cmd_ctx, char *cmd, char ** | |||||
chain_pos = strtoul(args[3], NULL, 0); | chain_pos = strtoul(args[3], NULL, 0); | ||||
if (argc >= 5) | if (argc >= 5) | ||||
variant = strdup(args[4]); | |||||
variant = args[4]; | |||||
DEBUG("chain_pos: %i, variant: %s", chain_pos, variant); | DEBUG("chain_pos: %i, variant: %s", chain_pos, variant); | ||||
@@ -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 <stdlib.h> | |||||
#include <string.h> | |||||
#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 <num> [value]"); | |||||
return ERROR_OK; | |||||
} |
@@ -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 */ |
@@ -719,11 +719,11 @@ void arm9tdmi_build_reg_cache(target_t *target) | |||||
arm7_9->eice_cache = (*cache_p)->next; | arm7_9->eice_cache = (*cache_p)->next; | ||||
if (arm9tdmi->has_monitor_mode) | if (arm9tdmi->has_monitor_mode) | ||||
(*cache_p)->next->reg_list[0].size = 6; | |||||
(*cache_p)->next->reg_list[EICE_DBG_CTRL].size = 6; | |||||
else | 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; | arm9tdmi->has_single_step = 1; | ||||
else if (strcmp(variant, "arm940t") == 0) | else if (strcmp(variant, "arm940t") == 0) | ||||
arm9tdmi->has_single_step = 1; | arm9tdmi->has_single_step = 1; | ||||
arm9tdmi->variant = strdup(variant); | |||||
} | } | ||||
else | |||||
arm9tdmi->variant = strdup(""); | |||||
arm7_9_init_arch_info(target, arm7_9); | 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); | chain_pos = strtoul(args[3], NULL, 0); | ||||
if (argc >= 5) | if (argc >= 5) | ||||
variant = strdup(args[4]); | |||||
variant = args[4]; | |||||
arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant); | arm9tdmi_init_arch_info(target, arm9tdmi, chain_pos, variant); | ||||
@@ -428,7 +428,7 @@ int armv4_5_register_commands(struct command_context_s *cmd_ctx) | |||||
{ | { | ||||
command_t *armv4_5_cmd; | 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, "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>"); | register_command(cmd_ctx, armv4_5_cmd, "core_state", handle_armv4_5_core_state_command, COMMAND_EXEC, "display/change ARM core state <arm|thumb>"); | ||||
@@ -46,6 +46,8 @@ enum | |||||
enum | enum | ||||
{ | { | ||||
EICE_DBG_CONTROL_ICEDIS = 5, | |||||
EICE_DBG_CONTROL_MONEN = 4, | |||||
EICE_DBG_CONTROL_INTDIS = 2, | EICE_DBG_CONTROL_INTDIS = 2, | ||||
EICE_DBG_CONTROL_DBGRQ = 1, | EICE_DBG_CONTROL_DBGRQ = 1, | ||||
EICE_DBG_CONTROL_DBGACK = 0, | EICE_DBG_CONTROL_DBGACK = 0, | ||||
@@ -73,6 +75,12 @@ enum | |||||
EICE_W_CTRL_nRW = 0x1 | EICE_W_CTRL_nRW = 0x1 | ||||
}; | }; | ||||
enum | |||||
{ | |||||
EICE_COMM_CTRL_WBIT = 1, | |||||
EICE_COMM_CTRL_RBIT = 0 | |||||
}; | |||||
typedef struct embeddedice_reg_s | typedef struct embeddedice_reg_s | ||||
{ | { | ||||
int addr; | int addr; | ||||
@@ -21,6 +21,7 @@ | |||||
#include "config.h" | #include "config.h" | ||||
#endif | #endif | ||||
#include "replacements.h" | |||||
#include "target.h" | #include "target.h" | ||||
#include "log.h" | #include "log.h" | ||||
@@ -74,6 +75,7 @@ extern target_type_t arm7tdmi_target; | |||||
extern target_type_t arm720t_target; | extern target_type_t arm720t_target; | ||||
extern target_type_t arm9tdmi_target; | extern target_type_t arm9tdmi_target; | ||||
extern target_type_t arm920t_target; | extern target_type_t arm920t_target; | ||||
extern target_type_t arm966e_target; | |||||
target_type_t *target_types[] = | target_type_t *target_types[] = | ||||
{ | { | ||||
@@ -81,6 +83,7 @@ target_type_t *target_types[] = | |||||
&arm9tdmi_target, | &arm9tdmi_target, | ||||
&arm920t_target, | &arm920t_target, | ||||
&arm720t_target, | &arm720t_target, | ||||
&arm966e_target, | |||||
NULL, | 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) | if ((retval = target->type->read_memory(target, address, 1, unaligned, buffer)) != ERROR_OK) | ||||
return retval; | return retval; | ||||
buffer += unaligned; | |||||
address += unaligned; | address += unaligned; | ||||
size -= 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) | if ((retval = target->type->read_memory(target, address, 4, aligned / 4, buffer)) != ERROR_OK) | ||||
return retval; | return retval; | ||||
buffer += aligned; | |||||
address += aligned; | address += aligned; | ||||
size -= aligned; | size -= aligned; | ||||
} | } | ||||