build: cleanup src/target directory

Change-Id: Ia055b6d2b5f6449a38afd0539a8c66e7d7e0c059
Signed-off-by: Spencer Oliver <spen@spen-soft.co.uk>
Reviewed-on: http://openocd.zylin.com/430
Tested-by: jenkins
This commit is contained in:
Spencer Oliver 2012-02-05 12:03:04 +00:00
parent de0130a0aa
commit 374127301e
107 changed files with 9577 additions and 11917 deletions

View File

@ -40,7 +40,6 @@
#include "arm_adi_v5.h" #include "arm_adi_v5.h"
#include <helper/time_support.h> #include <helper/time_support.h>
/* JTAG instructions/registers for JTAG-DP and SWJ-DP */ /* JTAG instructions/registers for JTAG-DP and SWJ-DP */
#define JTAG_DP_ABORT 0x8 #define JTAG_DP_ABORT 0x8
#define JTAG_DP_DPACC 0xA #define JTAG_DP_DPACC 0xA
@ -223,22 +222,19 @@ static int jtagdp_transaction_endcheck(struct adiv5_dap *dap)
DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
if (retval != ERROR_OK)
return retval; return retval;
dap->ack = dap->ack & 0x7; dap->ack = dap->ack & 0x7;
/* common code path avoids calling timeval_ms() */ /* common code path avoids calling timeval_ms() */
if (dap->ack != JTAG_ACK_OK_FAULT) if (dap->ack != JTAG_ACK_OK_FAULT) {
{
long long then = timeval_ms(); long long then = timeval_ms();
while (dap->ack != JTAG_ACK_OK_FAULT) while (dap->ack != JTAG_ACK_OK_FAULT) {
{ if (dap->ack == JTAG_ACK_WAIT) {
if (dap->ack == JTAG_ACK_WAIT) if ((timeval_ms()-then) > 1000) {
{
if ((timeval_ms()-then) > 1000)
{
/* NOTE: this would be a good spot /* NOTE: this would be a good spot
* to use JTAG_DP_ABORT. * to use JTAG_DP_ABORT.
*/ */
@ -247,9 +243,7 @@ static int jtagdp_transaction_endcheck(struct adiv5_dap *dap)
"in JTAG-DP transaction"); "in JTAG-DP transaction");
return ERROR_JTAG_DEVICE_ERROR; return ERROR_JTAG_DEVICE_ERROR;
} }
} } else {
else
{
LOG_WARNING("Invalid ACK %#x " LOG_WARNING("Invalid ACK %#x "
"in JTAG-DP transaction", "in JTAG-DP transaction",
dap->ack); dap->ack);
@ -260,7 +254,8 @@ static int jtagdp_transaction_endcheck(struct adiv5_dap *dap)
DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if ((retval = dap_run(dap)) != ERROR_OK) retval = dap_run(dap);
if (retval != ERROR_OK)
return retval; return retval;
dap->ack = dap->ack & 0x7; dap->ack = dap->ack & 0x7;
} }
@ -269,18 +264,14 @@ static int jtagdp_transaction_endcheck(struct adiv5_dap *dap)
/* REVISIT also STICKYCMP, for pushed comparisons (nyet used) */ /* REVISIT also STICKYCMP, for pushed comparisons (nyet used) */
/* Check for STICKYERR and STICKYORUN */ /* Check for STICKYERR and STICKYORUN */
if (ctrlstat & (SSTICKYORUN | SSTICKYERR)) if (ctrlstat & (SSTICKYORUN | SSTICKYERR)) {
{
LOG_DEBUG("jtag-dp: CTRL/STAT error, 0x%" PRIx32, ctrlstat); LOG_DEBUG("jtag-dp: CTRL/STAT error, 0x%" PRIx32, ctrlstat);
/* Check power to debug regions */ /* Check power to debug regions */
if ((ctrlstat & 0xf0000000) != 0xf0000000) if ((ctrlstat & 0xf0000000) != 0xf0000000) {
{
retval = ahbap_debugport_init(dap); retval = ahbap_debugport_init(dap);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
} } else {
else
{
uint32_t mem_ap_csw, mem_ap_tar; uint32_t mem_ap_csw, mem_ap_tar;
/* Maybe print information about last intended /* Maybe print information about last intended
@ -314,7 +305,8 @@ static int jtagdp_transaction_endcheck(struct adiv5_dap *dap)
DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if ((retval = dap_run(dap)) != ERROR_OK) retval = dap_run(dap);
if (retval != ERROR_OK)
return retval; return retval;
LOG_DEBUG("jtag-dp: CTRL/STAT 0x%" PRIx32, ctrlstat); LOG_DEBUG("jtag-dp: CTRL/STAT 0x%" PRIx32, ctrlstat);
@ -329,13 +321,15 @@ static int jtagdp_transaction_endcheck(struct adiv5_dap *dap)
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if ((retval = dap_run(dap)) != ERROR_OK) retval = dap_run(dap);
if (retval != ERROR_OK)
return retval; return retval;
LOG_ERROR("MEM_AP_CSW 0x%" PRIx32 ", MEM_AP_TAR 0x%" LOG_ERROR("MEM_AP_CSW 0x%" PRIx32 ", MEM_AP_TAR 0x%"
PRIx32, mem_ap_csw, mem_ap_tar); PRIx32, mem_ap_csw, mem_ap_tar);
} }
if ((retval = dap_run(dap)) != ERROR_OK) retval = dap_run(dap);
if (retval != ERROR_OK)
return retval; return retval;
return ERROR_JTAG_DEVICE_ERROR; return ERROR_JTAG_DEVICE_ERROR;
} }

View File

@ -55,12 +55,10 @@
#include <jtag/swd.h> #include <jtag/swd.h>
static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned reg, static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned reg,
uint32_t *data) uint32_t *data)
{ {
// REVISIT status return vs ack ... /* REVISIT status return vs ack ... */
return swd->read_reg(swd_cmd(true, false, reg), data); return swd->read_reg(swd_cmd(true, false, reg), data);
} }
@ -71,14 +69,14 @@ static int swd_queue_idcode_read(struct adiv5_dap *dap,
if (status < 0) if (status < 0)
return status; return status;
*ack = status; *ack = status;
// ?? /* ?? */
return ERROR_OK; return ERROR_OK;
} }
static int (swd_queue_dp_write)(struct adiv5_dap *dap, unsigned reg, static int (swd_queue_dp_write)(struct adiv5_dap *dap, unsigned reg,
uint32_t data) uint32_t data)
{ {
// REVISIT status return vs ack ... /* REVISIT status return vs ack ... */
return swd->write_reg(swd_cmd(false, false, reg), data); return swd->write_reg(swd_cmd(false, false, reg), data);
} }
@ -86,16 +84,16 @@ static int (swd_queue_dp_write)(struct adiv5_dap *dap, unsigned reg,
static int (swd_queue_ap_read)(struct adiv5_dap *dap, unsigned reg, static int (swd_queue_ap_read)(struct adiv5_dap *dap, unsigned reg,
uint32_t *data) uint32_t *data)
{ {
// REVISIT APSEL ... /* REVISIT APSEL ... */
// REVISIT status return ... /* REVISIT status return ... */
return swd->read_reg(swd_cmd(true, true, reg), data); return swd->read_reg(swd_cmd(true, true, reg), data);
} }
static int (swd_queue_ap_write)(struct adiv5_dap *dap, unsigned reg, static int (swd_queue_ap_write)(struct adiv5_dap *dap, unsigned reg,
uint32_t data) uint32_t data)
{ {
// REVISIT APSEL ... /* REVISIT APSEL ... */
// REVISIT status return ... /* REVISIT status return ... */
return swd->write_reg(swd_cmd(false, true, reg), data); return swd->write_reg(swd_cmd(false, true, reg), data);
} }
@ -194,15 +192,14 @@ COMMAND_HANDLER(handle_swd_wcr)
int retval; int retval;
struct target *target = get_current_target(CMD_CTX); struct target *target = get_current_target(CMD_CTX);
struct arm *arm = target_to_arm(target); struct arm *arm = target_to_arm(target);
struct adiv5_dap *dap = arm->dap; struct adiv5_dap *dap = arm->dap;
uint32_t wcr; uint32_t wcr;
unsigned trn, scale = 0; unsigned trn, scale = 0;
switch (CMD_ARGC) { switch (CMD_ARGC) {
/* no-args: just dump state */ /* no-args: just dump state */
case 0: case 0:
//retval = swd_queue_dp_read(dap, DP_WCR, &wcr); /*retval = swd_queue_dp_read(dap, DP_WCR, &wcr); */
retval = dap_queue_dp_read(dap, DP_WCR, &wcr); retval = dap_queue_dp_read(dap, DP_WCR, &wcr);
if (retval == ERROR_OK) if (retval == ERROR_OK)
dap->ops->run(dap); dap->ops->run(dap);
@ -315,11 +312,10 @@ static int swd_init(struct command_context *ctx)
{ {
struct target *target = get_current_target(ctx); struct target *target = get_current_target(ctx);
struct arm *arm = target_to_arm(target); struct arm *arm = target_to_arm(target);
struct adiv5_dap *dap = arm->dap; struct adiv5_dap *dap = arm->dap;
uint32_t idcode; uint32_t idcode;
int status; int status;
/* FIXME validate transport config ... is the /* FIXME validate transport config ... is the
* configured DAP present (check IDCODE)? * configured DAP present (check IDCODE)?
* Is *only* one DAP configured? * Is *only* one DAP configured?

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -24,7 +25,6 @@
#include "algorithm.h" #include "algorithm.h"
#include <helper/binarybuffer.h> #include <helper/binarybuffer.h>
void init_mem_param(struct mem_param *param, uint32_t address, uint32_t size, enum param_direction direction) void init_mem_param(struct mem_param *param, uint32_t address, uint32_t size, enum param_direction direction)
{ {
param->address = address; param->address = address;

View File

@ -17,26 +17,24 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ALGORITHM_H #ifndef ALGORITHM_H
#define ALGORITHM_H #define ALGORITHM_H
enum param_direction enum param_direction {
{
PARAM_IN, PARAM_IN,
PARAM_OUT, PARAM_OUT,
PARAM_IN_OUT PARAM_IN_OUT
}; };
struct mem_param struct mem_param {
{
uint32_t address; uint32_t address;
uint32_t size; uint32_t size;
uint8_t *value; uint8_t *value;
enum param_direction direction; enum param_direction direction;
}; };
struct reg_param struct reg_param {
{
const char *reg_name; const char *reg_name;
uint32_t size; uint32_t size;
uint8_t *value; uint8_t *value;

View File

@ -23,6 +23,7 @@
* Free Software Foundation, Inc., * Free Software Foundation, Inc.,
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/ */
#ifndef ARM_H #ifndef ARM_H
#define ARM_H #define ARM_H

File diff suppressed because it is too large Load Diff

View File

@ -26,38 +26,36 @@
#include "arm.h" #include "arm.h"
#include "arm_dpm.h" #include "arm_dpm.h"
#define ARM11_TAP_DEFAULT TAP_INVALID #define ARM11_TAP_DEFAULT TAP_INVALID
#define CHECK_RETVAL(action) \ #define CHECK_RETVAL(action) \
do { \ do { \
int __retval = (action); \ int __retval = (action); \
if (__retval != ERROR_OK) { \ if (__retval != ERROR_OK) { \
LOG_DEBUG("error while calling \"%s\"", \ LOG_DEBUG("error while calling \"%s\"", \
# action ); \ # action); \
return __retval; \ return __retval; \
} \ } \
} while (0) } while (0)
/* bits from ARMv7 DIDR */ /* bits from ARMv7 DIDR */
enum arm11_debug_version enum arm11_debug_version {
{ ARM11_DEBUG_V6 = 0x01,
ARM11_DEBUG_V6 = 0x01, ARM11_DEBUG_V61 = 0x02,
ARM11_DEBUG_V61 = 0x02, ARM11_DEBUG_V7 = 0x03,
ARM11_DEBUG_V7 = 0x03, ARM11_DEBUG_V7_CP14 = 0x04,
ARM11_DEBUG_V7_CP14 = 0x04,
}; };
struct arm11_common struct arm11_common {
{ struct arm arm;
struct arm arm;
/** Debug module state. */ /** Debug module state. */
struct arm_dpm dpm; struct arm_dpm dpm;
struct arm11_sc7_action *bpwp_actions; struct arm11_sc7_action *bpwp_actions;
unsigned bpwp_n; unsigned bpwp_n;
size_t brp; /**< Number of Breakpoint Register Pairs from DIDR */ size_t brp; /**< Number of Breakpoint Register Pairs from DIDR */
size_t free_brps; /**< Number of breakpoints allocated */ size_t free_brps; /**< Number of breakpoints allocated */
uint32_t dscr; /**< Last retrieved DSCR value. */ uint32_t dscr; /**< Last retrieved DSCR value. */
@ -67,7 +65,7 @@ struct arm11_common
bool is_rdtr_saved; bool is_rdtr_saved;
bool is_wdtr_saved; bool is_wdtr_saved;
bool simulate_reset_on_next_halt; /**< Perform cleanups of the ARM state on next halt */ bool simulate_reset_on_next_halt; /**< Perform cleanups of the ARM state on next halt **/
/* Per-core configurable options. /* Per-core configurable options.
* NOTE that several of these boolean options should not exist * NOTE that several of these boolean options should not exist
@ -86,8 +84,7 @@ struct arm11_common
static inline struct arm11_common *target_to_arm11(struct target *target) static inline struct arm11_common *target_to_arm11(struct target *target)
{ {
return container_of(target->arch_info, struct arm11_common, return container_of(target->arch_info, struct arm11_common, arm);
arm);
} }
/** /**
@ -95,27 +92,25 @@ static inline struct arm11_common *target_to_arm11(struct target *target)
* *
* http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301f/I1006229.html * http://infocenter.arm.com/help/topic/com.arm.doc.ddi0301f/I1006229.html
*/ */
enum arm11_instructions enum arm11_instructions {
{
ARM11_EXTEST = 0x00, ARM11_EXTEST = 0x00,
ARM11_SCAN_N = 0x02, ARM11_SCAN_N = 0x02,
ARM11_RESTART = 0x04, ARM11_RESTART = 0x04,
ARM11_HALT = 0x08, ARM11_HALT = 0x08,
ARM11_INTEST = 0x0C, ARM11_INTEST = 0x0C,
ARM11_ITRSEL = 0x1D, ARM11_ITRSEL = 0x1D,
ARM11_IDCODE = 0x1E, ARM11_IDCODE = 0x1E,
ARM11_BYPASS = 0x1F, ARM11_BYPASS = 0x1F,
}; };
enum arm11_sc7 enum arm11_sc7 {
{ ARM11_SC7_NULL = 0,
ARM11_SC7_NULL = 0, ARM11_SC7_VCR = 7,
ARM11_SC7_VCR = 7, ARM11_SC7_PC = 8,
ARM11_SC7_PC = 8, ARM11_SC7_BVR0 = 64,
ARM11_SC7_BVR0 = 64, ARM11_SC7_BCR0 = 80,
ARM11_SC7_BCR0 = 80, ARM11_SC7_WVR0 = 96,
ARM11_SC7_WVR0 = 96, ARM11_SC7_WCR0 = 112,
ARM11_SC7_WCR0 = 112,
}; };
#endif /* ARM11_H */ #endif /* ARM11_H */

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,25 @@
/***************************************************************************
* Copyright (C) 2008 digenius technology GmbH. *
* Michael Bruck *
* *
* Copyright (C) 2008,2009 Oyvind Harboe oyvind.harboe@zylin.com *
* *
* 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 ARM11_DBGTAP_H #ifndef ARM11_DBGTAP_H
#define ARM11_DBGTAP_H #define ARM11_DBGTAP_H
@ -37,10 +59,9 @@ void arm11_add_dr_scan_vc(struct jtag_tap *tap, int num_fields, struct scan_fiel
* Used with arm11_sc7_run to make a list of read/write commands for * Used with arm11_sc7_run to make a list of read/write commands for
* scan chain 7 * scan chain 7
*/ */
struct arm11_sc7_action struct arm11_sc7_action {
{ bool write; /**< Access mode: true for write, false for read. */
bool write; /**< Access mode: true for write, false for read. */ uint8_t address;/**< Register address mode. Use enum #arm11_sc7 */
uint8_t address; /**< Register address mode. Use enum #arm11_sc7 */
/** /**
* If write then set this to value to be written. In read mode * If write then set this to value to be written. In read mode
* this receives the read value when the function returns. * this receives the read value when the function returns.
@ -61,4 +82,4 @@ int arm11_read_memory_word(struct arm11_common *arm11,
int arm11_dpm_init(struct arm11_common *arm11, uint32_t didr); int arm11_dpm_init(struct arm11_common *arm11, uint32_t didr);
int arm11_bpwp_flush(struct arm11_common *arm11); int arm11_bpwp_flush(struct arm11_common *arm11);
#endif // ARM11_DBGTAP_H #endif /* ARM11_DBGTAP_H */

View File

@ -20,6 +20,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -54,14 +55,12 @@ static int arm720t_scan_cp15(struct target *target,
buf_set_u32(out_buf, 0, 32, flip_u32(out, 32)); buf_set_u32(out_buf, 0, 32, flip_u32(out, 32));
if ((retval = arm_jtag_scann(jtag_info, 0xf, TAP_DRPAUSE)) != ERROR_OK) retval = arm_jtag_scann(jtag_info, 0xf, TAP_DRPAUSE);
{ if (retval != ERROR_OK)
return retval; return retval;
} retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
if ((retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE)) != ERROR_OK) if (retval != ERROR_OK)
{
return retval; return retval;
}
fields[0].num_bits = 1; fields[0].num_bits = 1;
fields[0].out_value = &instruction_buf; fields[0].out_value = &instruction_buf;
@ -71,24 +70,20 @@ static int arm720t_scan_cp15(struct target *target,
fields[1].out_value = out_buf; fields[1].out_value = out_buf;
fields[1].in_value = NULL; fields[1].in_value = NULL;
if (in) if (in) {
{
fields[1].in_value = (uint8_t *)in; fields[1].in_value = (uint8_t *)in;
jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE); jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE);
jtag_add_callback(arm7flip32, (jtag_callback_data_t)in); jtag_add_callback(arm7flip32, (jtag_callback_data_t)in);
} else } else
{
jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE); jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE);
}
if (clock_arg) if (clock_arg)
jtag_add_runtest(0, TAP_DRPAUSE); jtag_add_runtest(0, TAP_DRPAUSE);
#ifdef _DEBUG_INSTRUCTION_EXECUTION_ #ifdef _DEBUG_INSTRUCTION_EXECUTION_
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
if (in) if (in)
LOG_DEBUG("out: %8.8x, in: %8.8x, instruction: %i, clock: %i", out, *in, instruction, clock); LOG_DEBUG("out: %8.8x, in: %8.8x, instruction: %i, clock: %i", out, *in, instruction, clock);
@ -254,8 +249,7 @@ static int arm720t_arch_state(struct target *target)
{ {
struct arm720t_common *arm720t = target_to_arm720(target); struct arm720t_common *arm720t = target_to_arm720(target);
static const char *state[] = static const char *state[] = {
{
"disabled", "enabled" "disabled", "enabled"
}; };
@ -300,16 +294,14 @@ static int arm720t_read_memory(struct target *target,
struct arm720t_common *arm720t = target_to_arm720(target); struct arm720t_common *arm720t = target_to_arm720(target);
/* disable cache, but leave MMU enabled */ /* disable cache, but leave MMU enabled */
if (arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) if (arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) {
{
retval = arm720t_disable_mmu_caches(target, 0, 1, 0); retval = arm720t_disable_mmu_caches(target, 0, 1, 0);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
} }
retval = arm7_9_read_memory(target, address, size, count, buffer); retval = arm7_9_read_memory(target, address, size, count, buffer);
if (arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) if (arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) {
{
retval = arm720t_enable_mmu_caches(target, 0, 1, 0); retval = arm720t_enable_mmu_caches(target, 0, 1, 0);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -342,36 +334,26 @@ static int arm720t_soft_reset_halt(struct target *target)
.eice_cache->reg_list[EICE_DBG_STAT]; .eice_cache->reg_list[EICE_DBG_STAT];
struct arm *arm = &arm720t->arm7_9_common.arm; struct arm *arm = &arm720t->arm7_9_common.arm;
if ((retval = target_halt(target)) != ERROR_OK) retval = target_halt(target);
{ if (retval != ERROR_OK)
return retval; return retval;
}
long long then = timeval_ms(); long long then = timeval_ms();
int timeout; int timeout;
while (!(timeout = ((timeval_ms()-then) > 1000))) while (!(timeout = ((timeval_ms()-then) > 1000))) {
{ if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0) {
if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0)
{
embeddedice_read_reg(dbg_stat); embeddedice_read_reg(dbg_stat);
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
} else } else
{
break; break;
}
if (debug_level >= 3) if (debug_level >= 3)
{
alive_sleep(100); alive_sleep(100);
} else else
{
keep_alive(); keep_alive();
}
} }
if (timeout) if (timeout) {
{
LOG_ERROR("Failed to halt CPU after 1 sec"); LOG_ERROR("Failed to halt CPU after 1 sec");
return ERROR_TARGET_TIMEOUT; return ERROR_TARGET_TIMEOUT;
} }
@ -399,10 +381,9 @@ static int arm720t_soft_reset_halt(struct target *target)
arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0; arm720t->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled = 0;
arm720t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0; arm720t->armv4_5_mmu.armv4_5_cache.i_cache_enabled = 0;
if ((retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED)) != ERROR_OK) retval = target_call_event_callbacks(target, TARGET_EVENT_HALTED);
{ if (retval != ERROR_OK)
return retval; return retval;
}
return ERROR_OK; return ERROR_OK;
} }
@ -467,42 +448,35 @@ COMMAND_HANDLER(arm720t_handle_cp15_command)
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if (target->state != TARGET_HALTED) {
if (target->state != TARGET_HALTED)
{
command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
return ERROR_OK; return ERROR_OK;
} }
/* one or more argument, access a single register (write if second argument is given */ /* one or more argument, access a single register (write if second argument is given */
if (CMD_ARGC >= 1) if (CMD_ARGC >= 1) {
{
uint32_t opcode; uint32_t opcode;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], opcode); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], opcode);
if (CMD_ARGC == 1) if (CMD_ARGC == 1) {
{
uint32_t value; uint32_t value;
if ((retval = arm720t_read_cp15(target, opcode, &value)) != ERROR_OK) retval = arm720t_read_cp15(target, opcode, &value);
{ if (retval != ERROR_OK) {
command_print(CMD_CTX, "couldn't access cp15 with opcode 0x%8.8" PRIx32 "", opcode); command_print(CMD_CTX, "couldn't access cp15 with opcode 0x%8.8" PRIx32 "", opcode);
return ERROR_OK; return ERROR_OK;
} }
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
command_print(CMD_CTX, "0x%8.8" PRIx32 ": 0x%8.8" PRIx32 "", opcode, value); command_print(CMD_CTX, "0x%8.8" PRIx32 ": 0x%8.8" PRIx32 "", opcode, value);
} } else if (CMD_ARGC == 2) {
else if (CMD_ARGC == 2)
{
uint32_t value; uint32_t value;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
if ((retval = arm720t_write_cp15(target, opcode, value)) != ERROR_OK) retval = arm720t_write_cp15(target, opcode, value);
{ if (retval != ERROR_OK) {
command_print(CMD_CTX, "couldn't access cp15 with opcode 0x%8.8" PRIx32 "", opcode); command_print(CMD_CTX, "couldn't access cp15 with opcode 0x%8.8" PRIx32 "", opcode);
return ERROR_OK; return ERROR_OK;
} }
@ -518,8 +492,7 @@ static int arm720t_mrc(struct target *target, int cpnum,
uint32_t CRn, uint32_t CRm, uint32_t CRn, uint32_t CRm,
uint32_t *value) uint32_t *value)
{ {
if (cpnum!=15) if (cpnum != 15) {
{
LOG_ERROR("Only cp15 is supported"); LOG_ERROR("Only cp15 is supported");
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -536,8 +509,7 @@ static int arm720t_mcr(struct target *target, int cpnum,
uint32_t CRn, uint32_t CRm, uint32_t CRn, uint32_t CRm,
uint32_t value) uint32_t value)
{ {
if (cpnum!=15) if (cpnum != 15) {
{
LOG_ERROR("Only cp15 is supported"); LOG_ERROR("Only cp15 is supported");
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -576,8 +548,7 @@ static const struct command_registration arm720t_command_handlers[] = {
}; };
/** Holds methods for ARM720 targets. */ /** Holds methods for ARM720 targets. */
struct target_type arm720t_target = struct target_type arm720t_target = {
{
.name = "arm720t", .name = "arm720t",
.poll = arm7_9_poll, .poll = arm7_9_poll,

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARM720T_H #ifndef ARM720T_H
#define ARM720T_H #define ARM720T_H
@ -25,8 +26,7 @@
#define ARM720T_COMMON_MAGIC 0xa720a720 #define ARM720T_COMMON_MAGIC 0xa720a720
struct arm720t_common struct arm720t_common {
{
struct arm7_9_common arm7_9_common; struct arm7_9_common arm7_9_common;
uint32_t common_magic; uint32_t common_magic;
struct armv4_5_mmu_common armv4_5_mmu; struct armv4_5_mmu_common armv4_5_mmu;
@ -35,11 +35,9 @@ struct arm720t_common
uint32_t far_reg; uint32_t far_reg;
}; };
static inline struct arm720t_common * static inline struct arm720t_common *target_to_arm720(struct target *target)
target_to_arm720(struct target *target)
{ {
return container_of(target->arch_info, struct arm720t_common, return container_of(target->arch_info, struct arm720t_common, arm7_9_common.arm);
arm7_9_common.arm);
} }
#endif /* ARM720T_H */ #endif /* ARM720T_H */

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARM7_9_COMMON_H #ifndef ARM7_9_COMMON_H
#define ARM7_9_COMMON_H #define ARM7_9_COMMON_H
@ -37,8 +38,7 @@
/** /**
* Structure for items that are common between both ARM7 and ARM9 targets. * Structure for items that are common between both ARM7 and ARM9 targets.
*/ */
struct arm7_9_common struct arm7_9_common {
{
struct arm arm; struct arm arm;
uint32_t common_magic; uint32_t common_magic;
@ -71,16 +71,26 @@ struct arm7_9_common
struct working_area *dcc_working_area; struct working_area *dcc_working_area;
int (*examine_debug_reason)(struct target *target); /**< Function for determining why debug state was entered */ int (*examine_debug_reason)(struct target *target);
/**< Function for determining why debug state was entered */
void (*change_to_arm)(struct target *target, uint32_t *r0, uint32_t *pc); /**< Function for changing from Thumb to ARM mode */ void (*change_to_arm)(struct target *target, uint32_t *r0, uint32_t *pc);
/**< Function for changing from Thumb to ARM mode */
void (*read_core_regs)(struct target *target, uint32_t mask, uint32_t *core_regs[16]); /**< Function for reading the core registers */ void (*read_core_regs)(struct target *target, uint32_t mask, uint32_t *core_regs[16]);
void (*read_core_regs_target_buffer)(struct target *target, uint32_t mask, void *buffer, int size); /**< Function for reading the core registers */
void (*read_xpsr)(struct target *target, uint32_t *xpsr, int spsr); /**< Function for reading CPSR or SPSR */
void (*read_core_regs_target_buffer)(struct target *target, uint32_t mask,
void *buffer, int size);
void (*read_xpsr)(struct target *target, uint32_t *xpsr, int spsr);
/**< Function for reading CPSR or SPSR */
void (*write_xpsr)(struct target *target, uint32_t xpsr, int spsr);
/**< Function for writing to CPSR or SPSR */
void (*write_xpsr_im8)(struct target *target, uint8_t xpsr_im, int rot, int spsr);
/**< Function for writing an immediate value to CPSR or SPSR */
void (*write_xpsr)(struct target *target, uint32_t xpsr, int spsr); /**< Function for writing to CPSR or SPSR */
void (*write_xpsr_im8)(struct target *target, uint8_t xpsr_im, int rot, int spsr); /**< Function for writing an immediate value to CPSR or SPSR */
void (*write_core_regs)(struct target *target, uint32_t mask, uint32_t core_regs[16]); void (*write_core_regs)(struct target *target, uint32_t mask, uint32_t core_regs[16]);
void (*load_word_regs)(struct target *target, uint32_t mask); void (*load_word_regs)(struct target *target, uint32_t mask);
@ -91,25 +101,28 @@ struct arm7_9_common
void (*store_hword_reg)(struct target *target, int num); void (*store_hword_reg)(struct target *target, int num);
void (*store_byte_reg)(struct target *target, int num); void (*store_byte_reg)(struct target *target, int num);
void (*write_pc)(struct target *target, uint32_t pc); /**< Function for writing to the program counter */ void (*write_pc)(struct target *target, uint32_t pc);
/**< Function for writing to the program counter */
void (*branch_resume)(struct target *target); void (*branch_resume)(struct target *target);
void (*branch_resume_thumb)(struct target *target); void (*branch_resume_thumb)(struct target *target);
void (*enable_single_step)(struct target *target, uint32_t next_pc); void (*enable_single_step)(struct target *target, uint32_t next_pc);
void (*disable_single_step)(struct target *target); void (*disable_single_step)(struct target *target);
void (*set_special_dbgrq)(struct target *target); /**< Function for setting DBGRQ if the normal way won't work */ void (*set_special_dbgrq)(struct target *target);
/**< Function for setting DBGRQ if the normal way won't work */
int (*post_debug_entry)(struct target *target); /**< Callback function called after entering debug mode */ int (*post_debug_entry)(struct target *target);
/**< Callback function called after entering debug mode */
void (*pre_restore_context)(struct target *target); /**< Callback function called before restoring the processor context */ void (*pre_restore_context)(struct target *target);
/**< Callback function called before restoring the processor context */
}; };
static inline struct arm7_9_common * static inline struct arm7_9_common *target_to_arm7_9(struct target *target)
target_to_arm7_9(struct target *target)
{ {
return container_of(target->arch_info, struct arm7_9_common, return container_of(target->arch_info, struct arm7_9_common, arm);
arm);
} }
static inline bool is_arm7_9(struct arm7_9_common *arm7_9) static inline bool is_arm7_9(struct arm7_9_common *arm7_9)
@ -131,13 +144,20 @@ int arm7_9_soft_reset_halt(struct target *target);
int arm7_9_prepare_reset_halt(struct target *target); int arm7_9_prepare_reset_halt(struct target *target);
int arm7_9_halt(struct target *target); int arm7_9_halt(struct target *target);
int arm7_9_resume(struct target *target, int current, uint32_t address, int handle_breakpoints, int debug_execution); int arm7_9_resume(struct target *target, int current, uint32_t address,
int arm7_9_step(struct target *target, int current, uint32_t address, int handle_breakpoints); int handle_breakpoints, int debug_execution);
int arm7_9_read_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer); int arm7_9_step(struct target *target, int current, uint32_t address,
int arm7_9_write_memory(struct target *target, uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer); int handle_breakpoints);
int arm7_9_bulk_write_memory(struct target *target, uint32_t address, uint32_t count, const uint8_t *buffer); int arm7_9_read_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, uint8_t *buffer);
int arm7_9_write_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, const uint8_t *buffer);
int arm7_9_bulk_write_memory(struct target *target, uint32_t address,
uint32_t count, const uint8_t *buffer);
int arm7_9_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_prams, struct reg_param *reg_param, uint32_t entry_point, void *arch_info); int arm7_9_run_algorithm(struct target *target, int num_mem_params,
struct mem_param *mem_params, int num_reg_prams,
struct reg_param *reg_param, uint32_t entry_point, void *arch_info);
int arm7_9_add_breakpoint(struct target *target, struct breakpoint *breakpoint); int arm7_9_add_breakpoint(struct target *target, struct breakpoint *breakpoint);
int arm7_9_remove_breakpoint(struct target *target, struct breakpoint *breakpoint); int arm7_9_remove_breakpoint(struct target *target, struct breakpoint *breakpoint);

View File

@ -23,6 +23,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -32,7 +33,6 @@
#include "register.h" #include "register.h"
#include "arm_opcodes.h" #include "arm_opcodes.h"
/* /*
* For information about ARM7TDMI, see ARM DDI 0210C (r4p1) * For information about ARM7TDMI, see ARM DDI 0210C (r4p1)
* or ARM DDI 0029G (r3). "Debug In Depth", Appendix B, * or ARM DDI 0029G (r3). "Debug In Depth", Appendix B,
@ -50,8 +50,7 @@ static int arm7tdmi_examine_debug_reason(struct target *target)
/* only check the debug reason if we don't know it already */ /* only check the debug reason if we don't know it already */
if ((target->debug_reason != DBG_REASON_DBGRQ) if ((target->debug_reason != DBG_REASON_DBGRQ)
&& (target->debug_reason != DBG_REASON_SINGLESTEP)) && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
{
struct scan_field fields[2]; struct scan_field fields[2];
uint8_t databus[4]; uint8_t databus[4];
uint8_t breakpoint; uint8_t breakpoint;
@ -64,19 +63,17 @@ static int arm7tdmi_examine_debug_reason(struct target *target)
fields[1].out_value = NULL; fields[1].out_value = NULL;
fields[1].in_value = databus; fields[1].in_value = databus;
if ((retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1, TAP_DRPAUSE)) != ERROR_OK) retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1, TAP_DRPAUSE);
{ if (retval != ERROR_OK)
return retval; return retval;
}
retval = arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL, TAP_DRPAUSE); retval = arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL, TAP_DRPAUSE);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
jtag_add_dr_scan(arm7_9->jtag_info.tap, 2, fields, TAP_DRPAUSE); jtag_add_dr_scan(arm7_9->jtag_info.tap, 2, fields, TAP_DRPAUSE);
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
fields[0].in_value = NULL; fields[0].in_value = NULL;
fields[0].out_value = &breakpoint; fields[0].out_value = &breakpoint;
@ -96,9 +93,9 @@ static int arm7tdmi_examine_debug_reason(struct target *target)
static const int arm7tdmi_num_bits[] = {1, 32}; static const int arm7tdmi_num_bits[] = {1, 32};
static __inline int arm7tdmi_clock_out_inner(struct arm_jtag *jtag_info, uint32_t out, int breakpoint) static inline int arm7tdmi_clock_out_inner(struct arm_jtag *jtag_info, uint32_t out, int breakpoint)
{ {
uint32_t values[2]={breakpoint, flip_u32(out, 32)}; uint32_t values[2] = {breakpoint, flip_u32(out, 32)};
jtag_add_dr_out(jtag_info->tap, jtag_add_dr_out(jtag_info->tap,
2, 2,
@ -116,7 +113,7 @@ static __inline int arm7tdmi_clock_out_inner(struct arm_jtag *jtag_info, uint32_
* *
* FIXME remove the unused "deprecated" parameter * FIXME remove the unused "deprecated" parameter
*/ */
static __inline int arm7tdmi_clock_out(struct arm_jtag *jtag_info, static inline int arm7tdmi_clock_out(struct arm_jtag *jtag_info,
uint32_t out, uint32_t *deprecated, int breakpoint) uint32_t out, uint32_t *deprecated, int breakpoint)
{ {
int retval; int retval;
@ -136,10 +133,9 @@ static int arm7tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in)
int retval = ERROR_OK; int retval = ERROR_OK;
struct scan_field fields[2]; struct scan_field fields[2];
if ((retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE)) != ERROR_OK) retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);
{ if (retval != ERROR_OK)
return retval; return retval;
}
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE); retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -159,7 +155,8 @@ static int arm7tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in)
jtag_add_runtest(0, TAP_DRPAUSE); jtag_add_runtest(0, TAP_DRPAUSE);
#ifdef _DEBUG_INSTRUCTION_EXECUTION_ #ifdef _DEBUG_INSTRUCTION_EXECUTION_
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
if (retval != ERROR_OK)
return retval; return retval;
if (in) if (in)
@ -176,28 +173,21 @@ void arm_endianness(uint8_t *tmp, void *in, int size, int be, int flip)
uint32_t readback = le_to_h_u32(tmp); uint32_t readback = le_to_h_u32(tmp);
if (flip) if (flip)
readback = flip_u32(readback, 32); readback = flip_u32(readback, 32);
switch (size) switch (size) {
{
case 4: case 4:
if (be) if (be)
{ h_u32_to_be(((uint8_t *)in), readback);
h_u32_to_be(((uint8_t*)in), readback); else
} else h_u32_to_le(((uint8_t *)in), readback);
{
h_u32_to_le(((uint8_t*)in), readback);
}
break; break;
case 2: case 2:
if (be) if (be)
{ h_u16_to_be(((uint8_t *)in), readback & 0xffff);
h_u16_to_be(((uint8_t*)in), readback & 0xffff); else
} else h_u16_to_le(((uint8_t *)in), readback & 0xffff);
{
h_u16_to_le(((uint8_t*)in), readback & 0xffff);
}
break; break;
case 1: case 1:
*((uint8_t *)in)= readback & 0xff; *((uint8_t *)in) = readback & 0xff;
break; break;
} }
} }
@ -222,10 +212,9 @@ static int arm7tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info,
int retval = ERROR_OK; int retval = ERROR_OK;
struct scan_field fields[2]; struct scan_field fields[2];
if ((retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE)) != ERROR_OK) retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);
{ if (retval != ERROR_OK)
return retval; return retval;
}
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE); retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -250,19 +239,14 @@ static int arm7tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info,
#ifdef _DEBUG_INSTRUCTION_EXECUTION_ #ifdef _DEBUG_INSTRUCTION_EXECUTION_
{ {
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
if (in) if (in)
{ LOG_DEBUG("in: 0x%8.8x", *(uint32_t *)in);
LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in);
}
else else
{
LOG_ERROR("BUG: called with in == NULL"); LOG_ERROR("BUG: called with in == NULL");
}
} }
#endif #endif
@ -318,7 +302,6 @@ static void arm7tdmi_change_to_arm(struct target *target,
*pc -= 0xa; *pc -= 0xa;
} }
/* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many /* FIX!!! is this a potential performance bottleneck w.r.t. requiring too many
* roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s? * roundtrips when jtag_execute_queue() has a large overhead(e.g. for USB)s?
* *
@ -326,7 +309,7 @@ static void arm7tdmi_change_to_arm(struct target *target,
* and convert data afterwards. * and convert data afterwards.
*/ */
static void arm7tdmi_read_core_regs(struct target *target, static void arm7tdmi_read_core_regs(struct target *target,
uint32_t mask, uint32_t* core_regs[16]) uint32_t mask, uint32_t *core_regs[16])
{ {
int i; int i;
struct arm7_9_common *arm7_9 = target_to_arm7_9(target); struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
@ -342,8 +325,7 @@ static void arm7tdmi_read_core_regs(struct target *target,
/* fetch NOP, STM in EXECUTE stage (1st cycle) */ /* fetch NOP, STM in EXECUTE stage (1st cycle) */
arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
for (i = 0; i <= 15; i++) for (i = 0; i <= 15; i++) {
{
if (mask & (1 << i)) if (mask & (1 << i))
/* nothing fetched, STM still in EXECUTE (1 + i cycle) */ /* nothing fetched, STM still in EXECUTE (1 + i cycle) */
arm7tdmi_clock_data_in(jtag_info, core_regs[i]); arm7tdmi_clock_data_in(jtag_info, core_regs[i]);
@ -351,7 +333,7 @@ static void arm7tdmi_read_core_regs(struct target *target,
} }
static void arm7tdmi_read_core_regs_target_buffer(struct target *target, static void arm7tdmi_read_core_regs_target_buffer(struct target *target,
uint32_t mask, void* buffer, int size) uint32_t mask, void *buffer, int size)
{ {
int i; int i;
struct arm7_9_common *arm7_9 = target_to_arm7_9(target); struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
@ -371,13 +353,10 @@ static void arm7tdmi_read_core_regs_target_buffer(struct target *target,
/* fetch NOP, STM in EXECUTE stage (1st cycle) */ /* fetch NOP, STM in EXECUTE stage (1st cycle) */
arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0); arm7tdmi_clock_out(jtag_info, ARMV4_5_NOP, NULL, 0);
for (i = 0; i <= 15; i++) for (i = 0; i <= 15; i++) {
{
/* nothing fetched, STM still in EXECUTE (1 + i cycle), read databus */ /* nothing fetched, STM still in EXECUTE (1 + i cycle), read databus */
if (mask & (1 << i)) if (mask & (1 << i)) {
{ switch (size) {
switch (size)
{
case 4: case 4:
arm7tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be); arm7tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
break; break;
@ -474,8 +453,7 @@ static void arm7tdmi_write_core_regs(struct target *target,
/* fetch NOP, LDM in EXECUTE stage (1st cycle) */ /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0); arm7tdmi_clock_out_inner(jtag_info, ARMV4_5_NOP, 0);
for (i = 0; i <= 15; i++) for (i = 0; i <= 15; i++) {
{
if (mask & (1 << i)) if (mask & (1 << i))
/* nothing fetched, LDM still in EXECUTE (1 + i cycle) */ /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
arm7tdmi_clock_out_inner(jtag_info, core_regs[i], 0); arm7tdmi_clock_out_inner(jtag_info, core_regs[i], 0);
@ -711,7 +689,7 @@ static int arm7tdmi_target_create(struct target *target, Jim_Interp *interp)
{ {
struct arm7_9_common *arm7_9; struct arm7_9_common *arm7_9;
arm7_9 = calloc(1,sizeof(struct arm7_9_common)); arm7_9 = calloc(1, sizeof(struct arm7_9_common));
arm7tdmi_init_arch_info(target, arm7_9, target->tap); arm7tdmi_init_arch_info(target, arm7_9, target->tap);
arm7_9->arm.is_armv4 = true; arm7_9->arm.is_armv4 = true;
@ -719,8 +697,7 @@ static int arm7tdmi_target_create(struct target *target, Jim_Interp *interp)
} }
/** Holds methods for ARM7TDMI targets. */ /** Holds methods for ARM7TDMI targets. */
struct target_type arm7tdmi_target = struct target_type arm7tdmi_target = {
{
.name = "arm7tdmi", .name = "arm7tdmi",
.poll = arm7_9_poll, .poll = arm7_9_poll,

View File

@ -20,6 +20,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARM7TDMI_H #ifndef ARM7TDMI_H
#define ARM7TDMI_H #define ARM7TDMI_H

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARM920T_H #ifndef ARM920T_H
#define ARM920T_H #define ARM920T_H
@ -25,8 +26,7 @@
#define ARM920T_COMMON_MAGIC 0xa920a920 #define ARM920T_COMMON_MAGIC 0xa920a920
struct arm920t_common struct arm920t_common {
{
struct arm7_9_common arm7_9_common; struct arm7_9_common arm7_9_common;
uint32_t common_magic; uint32_t common_magic;
struct armv4_5_mmu_common armv4_5_mmu; struct armv4_5_mmu_common armv4_5_mmu;
@ -38,21 +38,17 @@ struct arm920t_common
int preserve_cache; int preserve_cache;
}; };
static inline struct arm920t_common * static inline struct arm920t_common *target_to_arm920(struct target *target)
target_to_arm920(struct target *target)
{ {
return container_of(target->arch_info, struct arm920t_common, return container_of(target->arch_info, struct arm920t_common, arm7_9_common.arm);
arm7_9_common.arm);
} }
struct arm920t_cache_line struct arm920t_cache_line {
{
uint32_t cam; uint32_t cam;
uint32_t data[8]; uint32_t data[8];
}; };
struct arm920t_tlb_entry struct arm920t_tlb_entry {
{
uint32_t cam; uint32_t cam;
uint32_t ram1; uint32_t ram1;
uint32_t ram2; uint32_t ram2;

View File

@ -20,6 +20,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -63,10 +64,9 @@ static int arm926ejs_cp15_read(struct target *target, uint32_t op1, uint32_t op2
buf_set_u32(address_buf, 0, 14, address); buf_set_u32(address_buf, 0, 14, address);
if ((retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE)) != ERROR_OK) retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
{ if (retval != ERROR_OK)
return retval; return retval;
}
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE); retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -91,8 +91,7 @@ static int arm926ejs_cp15_read(struct target *target, uint32_t op1, uint32_t op2
long long then = timeval_ms(); long long then = timeval_ms();
for (;;) for (;;) {
{
/* rescan with NOP, to wait for the access to complete */ /* rescan with NOP, to wait for the access to complete */
access_t = 0; access_t = 0;
nr_w_buf = 0; nr_w_buf = 0;
@ -100,19 +99,15 @@ static int arm926ejs_cp15_read(struct target *target, uint32_t op1, uint32_t op2
jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value); jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)value);
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
if (buf_get_u32(&access_t, 0, 1) == 1) if (buf_get_u32(&access_t, 0, 1) == 1)
{
break; break;
}
/* 10ms timeout */ /* 10ms timeout */
if ((timeval_ms()-then)>10) if ((timeval_ms()-then) > 10) {
{
LOG_ERROR("cp15 read operation timed out"); LOG_ERROR("cp15 read operation timed out");
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -155,10 +150,9 @@ static int arm926ejs_cp15_write(struct target *target, uint32_t op1, uint32_t op
buf_set_u32(address_buf, 0, 14, address); buf_set_u32(address_buf, 0, 14, address);
buf_set_u32(value_buf, 0, 32, value); buf_set_u32(value_buf, 0, 32, value);
if ((retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE)) != ERROR_OK) retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
{ if (retval != ERROR_OK)
return retval; return retval;
}
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE); retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -183,25 +177,20 @@ static int arm926ejs_cp15_write(struct target *target, uint32_t op1, uint32_t op
long long then = timeval_ms(); long long then = timeval_ms();
for (;;) for (;;) {
{
/* rescan with NOP, to wait for the access to complete */ /* rescan with NOP, to wait for the access to complete */
access_t = 0; access_t = 0;
nr_w_buf = 0; nr_w_buf = 0;
jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE); jtag_add_dr_scan(jtag_info->tap, 4, fields, TAP_IDLE);
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
if (buf_get_u32(&access_t, 0, 1) == 1) if (buf_get_u32(&access_t, 0, 1) == 1)
{
break; break;
}
/* 10ms timeout */ /* 10ms timeout */
if ((timeval_ms()-then)>10) if ((timeval_ms()-then) > 10) {
{
LOG_ERROR("cp15 write operation timed out"); LOG_ERROR("cp15 write operation timed out");
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -236,14 +225,14 @@ static int arm926ejs_examine_debug_reason(struct target *target)
int retval; int retval;
embeddedice_read_reg(dbg_stat); embeddedice_read_reg(dbg_stat);
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
if (retval != ERROR_OK)
return retval; return retval;
/* Method-Of-Entry (MOE) field */ /* Method-Of-Entry (MOE) field */
debug_reason = buf_get_u32(dbg_stat->value, 6, 4); debug_reason = buf_get_u32(dbg_stat->value, 6, 4);
switch (debug_reason) switch (debug_reason) {
{
case 0: case 0:
LOG_DEBUG("no *NEW* debug entry (?missed one?)"); LOG_DEBUG("no *NEW* debug entry (?missed one?)");
/* ... since last restart or debug reset ... */ /* ... since last restart or debug reset ... */
@ -337,7 +326,8 @@ static int arm926ejs_get_ttb(struct target *target, uint32_t *result)
int retval; int retval;
uint32_t ttb = 0x0; uint32_t ttb = 0x0;
if ((retval = arm926ejs->read_cp15(target, 0, 0, 2, 0, &ttb)) != ERROR_OK) retval = arm926ejs->read_cp15(target, 0, 0, 2, 0, &ttb);
if (retval != ERROR_OK)
return retval; return retval;
*result = ttb; *result = ttb;
@ -360,8 +350,7 @@ static int arm926ejs_disable_mmu_caches(struct target *target, int mmu,
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if (mmu) if (mmu) {
{
/* invalidate TLB */ /* invalidate TLB */
retval = arm926ejs->write_cp15(target, 0, 0, 8, 7, 0x0); retval = arm926ejs->write_cp15(target, 0, 0, 8, 7, 0x0);
if (retval != ERROR_OK) if (retval != ERROR_OK)
@ -370,8 +359,7 @@ static int arm926ejs_disable_mmu_caches(struct target *target, int mmu,
cp15_control &= ~0x1U; cp15_control &= ~0x1U;
} }
if (d_u_cache) if (d_u_cache) {
{
uint32_t debug_override; uint32_t debug_override;
/* read-modify-write CP15 debug override register /* read-modify-write CP15 debug override register
* to enable "test and clean all" */ * to enable "test and clean all" */
@ -398,8 +386,7 @@ static int arm926ejs_disable_mmu_caches(struct target *target, int mmu,
cp15_control &= ~0x4U; cp15_control &= ~0x4U;
} }
if (i_cache) if (i_cache) {
{
/* invalidate ICache */ /* invalidate ICache */
retval = arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0); retval = arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0);
if (retval != ERROR_OK) if (retval != ERROR_OK)
@ -454,8 +441,7 @@ static int arm926ejs_post_debug_entry(struct target *target)
return retval; return retval;
LOG_DEBUG("cp15_control_reg: %8.8" PRIx32 "", arm926ejs->cp15_control_reg); LOG_DEBUG("cp15_control_reg: %8.8" PRIx32 "", arm926ejs->cp15_control_reg);
if (arm926ejs->armv4_5_mmu.armv4_5_cache.ctype == -1) if (arm926ejs->armv4_5_mmu.armv4_5_cache.ctype == -1) {
{
uint32_t cache_type_reg; uint32_t cache_type_reg;
/* identify caches */ /* identify caches */
retval = arm926ejs->read_cp15(target, 0, 1, 0, 0, &cache_type_reg); retval = arm926ejs->read_cp15(target, 0, 1, 0, 0, &cache_type_reg);
@ -530,15 +516,13 @@ static int arm926ejs_verify_pointer(struct command_context *cmd_ctx,
/** Logs summary of ARM926 state for a halted target. */ /** Logs summary of ARM926 state for a halted target. */
int arm926ejs_arch_state(struct target *target) int arm926ejs_arch_state(struct target *target)
{ {
static const char *state[] = static const char *state[] = {
{
"disabled", "enabled" "disabled", "enabled"
}; };
struct arm926ejs_common *arm926ejs = target_to_arm926(target); struct arm926ejs_common *arm926ejs = target_to_arm926(target);
if (arm926ejs->common_magic != ARM926EJS_COMMON_MAGIC) if (arm926ejs->common_magic != ARM926EJS_COMMON_MAGIC) {
{
LOG_ERROR("BUG: %s", arm926_not); LOG_ERROR("BUG: %s", arm926_not);
return ERROR_TARGET_INVALID; return ERROR_TARGET_INVALID;
} }
@ -560,37 +544,27 @@ int arm926ejs_soft_reset_halt(struct target *target)
struct arm *arm = &arm7_9->arm; struct arm *arm = &arm7_9->arm;
struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT]; struct reg *dbg_stat = &arm7_9->eice_cache->reg_list[EICE_DBG_STAT];
if ((retval = target_halt(target)) != ERROR_OK) retval = target_halt(target);
{ if (retval != ERROR_OK)
return retval; return retval;
}
long long then = timeval_ms(); long long then = timeval_ms();
int timeout; int timeout;
while (!(timeout = ((timeval_ms()-then) > 1000))) while (!(timeout = ((timeval_ms()-then) > 1000))) {
{ if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0) {
if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0)
{
embeddedice_read_reg(dbg_stat); embeddedice_read_reg(dbg_stat);
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
} } else
} else
{
break; break;
} if (debug_level >= 1) {
if (debug_level >= 1)
{
/* do not eat all CPU, time out after 1 se*/ /* do not eat all CPU, time out after 1 se*/
alive_sleep(100); alive_sleep(100);
} else } else
{
keep_alive(); keep_alive();
}
} }
if (timeout) if (timeout) {
{
LOG_ERROR("Failed to halt CPU after 1 sec"); LOG_ERROR("Failed to halt CPU after 1 sec");
return ERROR_TARGET_TIMEOUT; return ERROR_TARGET_TIMEOUT;
} }
@ -636,13 +610,11 @@ int arm926ejs_write_memory(struct target *target, uint32_t address,
* Also it should be moved to the callbacks that handle breakpoints * Also it should be moved to the callbacks that handle breakpoints
* specifically and not the generic memory write fn's. See XScale code. * specifically and not the generic memory write fn's. See XScale code.
**/ **/
if (arm926ejs->armv4_5_mmu.mmu_enabled && (count == 1) && ((size==2) || (size==4))) if (arm926ejs->armv4_5_mmu.mmu_enabled && (count == 1) && ((size == 2) || (size == 4))) {
{
/* special case the handling of single word writes to bypass MMU /* special case the handling of single word writes to bypass MMU
* to allow implementation of breakpoints in memory marked read only * to allow implementation of breakpoints in memory marked read only
* by MMU */ * by MMU */
if (arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) if (arm926ejs->armv4_5_mmu.armv4_5_cache.d_u_cache_enabled) {
{
/* flush and invalidate data cache /* flush and invalidate data cache
* *
* MCR p15,0,p,c7,c10,1 - clean cache line using virtual address * MCR p15,0,p,c7,c10,1 - clean cache line using virtual address
@ -662,24 +634,20 @@ int arm926ejs_write_memory(struct target *target, uint32_t address,
retval = armv4_5_mmu_write_physical(target, &arm926ejs->armv4_5_mmu, pa, size, count, buffer); retval = armv4_5_mmu_write_physical(target, &arm926ejs->armv4_5_mmu, pa, size, count, buffer);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
} else } else {
{ retval = arm7_9_write_memory(target, address, size, count, buffer);
if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
} }
/* If ICache is enabled, we have to invalidate affected ICache lines /* If ICache is enabled, we have to invalidate affected ICache lines
* the DCache is forced to write-through, so we don't have to clean it here * the DCache is forced to write-through, so we don't have to clean it here
*/ */
if (arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled) if (arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled) {
{ if (count <= 1) {
if (count <= 1)
{
/* invalidate ICache single entry with MVA */ /* invalidate ICache single entry with MVA */
arm926ejs->write_cp15(target, 0, 1, 7, 5, address); arm926ejs->write_cp15(target, 0, 1, 7, 5, address);
} } else {
else
{
/* invalidate ICache */ /* invalidate ICache */
arm926ejs->write_cp15(target, 0, 0, 7, 5, address); arm926ejs->write_cp15(target, 0, 0, 7, 5, address);
} }
@ -748,7 +716,7 @@ int arm926ejs_init_arch_info(struct target *target, struct arm926ejs_common *arm
static int arm926ejs_target_create(struct target *target, Jim_Interp *interp) static int arm926ejs_target_create(struct target *target, Jim_Interp *interp)
{ {
struct arm926ejs_common *arm926ejs = calloc(1,sizeof(struct arm926ejs_common)); struct arm926ejs_common *arm926ejs = calloc(1, sizeof(struct arm926ejs_common));
/* ARM9EJ-S core always reports 0x1 in Capture-IR */ /* ARM9EJ-S core always reports 0x1 in Capture-IR */
target->tap->ir_capture_mask = 0x0f; target->tap->ir_capture_mask = 0x0f;
@ -787,8 +755,7 @@ static int arm926ejs_mmu(struct target *target, int *enabled)
{ {
struct arm926ejs_common *arm926ejs = target_to_arm926(target); struct arm926ejs_common *arm926ejs = target_to_arm926(target);
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
LOG_ERROR("Target not halted"); LOG_ERROR("Target not halted");
return ERROR_TARGET_INVALID; return ERROR_TARGET_INVALID;
} }
@ -822,8 +789,7 @@ const struct command_registration arm926ejs_command_handlers[] = {
}; };
/** Holds methods for ARM926 targets. */ /** Holds methods for ARM926 targets. */
struct target_type arm926ejs_target = struct target_type arm926ejs_target = {
{
.name = "arm926ejs", .name = "arm926ejs",
.poll = arm7_9_poll, .poll = arm7_9_poll,

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARM926EJS_H #ifndef ARM926EJS_H
#define ARM926EJS_H #define ARM926EJS_H
@ -25,27 +26,25 @@
#define ARM926EJS_COMMON_MAGIC 0xa926a926 #define ARM926EJS_COMMON_MAGIC 0xa926a926
struct arm926ejs_common struct arm926ejs_common {
{
struct arm7_9_common arm7_9_common; struct arm7_9_common arm7_9_common;
uint32_t common_magic; uint32_t common_magic;
struct armv4_5_mmu_common armv4_5_mmu; struct armv4_5_mmu_common armv4_5_mmu;
int (*read_cp15)(struct target *target, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t *value); int (*read_cp15)(struct target *target, uint32_t op1, uint32_t op2,
int (*write_cp15)(struct target *target, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t value); uint32_t CRn, uint32_t CRm, uint32_t *value);
int (*write_cp15)(struct target *target, uint32_t op1, uint32_t op2,
uint32_t CRn, uint32_t CRm, uint32_t value);
uint32_t cp15_control_reg; uint32_t cp15_control_reg;
uint32_t d_fsr; uint32_t d_fsr;
uint32_t i_fsr; uint32_t i_fsr;
uint32_t d_far; uint32_t d_far;
}; };
static inline struct arm926ejs_common * static inline struct arm926ejs_common *target_to_arm926(struct target *target)
target_to_arm926(struct target *target)
{ {
return container_of(target->arch_info, struct arm926ejs_common, return container_of(target->arch_info, struct arm926ejs_common, arm7_9_common.arm);
arm7_9_common.arm);
} }
int arm926ejs_init_arch_info(struct target *target, int arm926ejs_init_arch_info(struct target *target,
struct arm926ejs_common *arm926ejs, struct jtag_tap *tap); struct arm926ejs_common *arm926ejs, struct jtag_tap *tap);
int arm926ejs_arch_state(struct target *target); int arm926ejs_arch_state(struct target *target);

View File

@ -23,6 +23,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -39,8 +40,8 @@
#define NB_CACHE_WAYS 4 #define NB_CACHE_WAYS 4
static uint32_t dc = 0x0; static uint32_t dc;
static uint32_t ic = 0x0; static uint32_t ic;
/** /**
* flag to give info about cache manipulation during debug : * flag to give info about cache manipulation during debug :
@ -55,8 +56,9 @@ int arm946e_post_debug_entry(struct target *target);
void arm946e_pre_restore_context(struct target *target); void arm946e_pre_restore_context(struct target *target);
static int arm946e_read_cp15(struct target *target, int reg_addr, uint32_t *value); static int arm946e_read_cp15(struct target *target, int reg_addr, uint32_t *value);
int arm946e_init_arch_info(struct target *target,
int arm946e_init_arch_info(struct target *target, struct arm946e_common *arm946e, struct jtag_tap *tap) struct arm946e_common *arm946e,
struct jtag_tap *tap)
{ {
struct arm7_9_common *arm7_9 = &arm946e->arm7_9_common; struct arm7_9_common *arm7_9 = &arm946e->arm7_9_common;
@ -84,14 +86,14 @@ int arm946e_init_arch_info(struct target *target, struct arm946e_common *arm946e
arm946e_preserve_cache = 0; arm946e_preserve_cache = 0;
/* override hw single-step capability from ARM9TDMI */ /* override hw single-step capability from ARM9TDMI */
//arm7_9->has_single_step = 1; /* arm7_9->has_single_step = 1; */
return ERROR_OK; return ERROR_OK;
} }
static int arm946e_target_create(struct target *target, Jim_Interp *interp) static int arm946e_target_create(struct target *target, Jim_Interp *interp)
{ {
struct arm946e_common *arm946e = calloc(1,sizeof(struct arm946e_common)); struct arm946e_common *arm946e = calloc(1, sizeof(struct arm946e_common));
arm946e_init_arch_info(target, arm946e, target->tap); arm946e_init_arch_info(target, arm946e, target->tap);
@ -99,7 +101,7 @@ static int arm946e_target_create(struct target *target, Jim_Interp *interp)
} }
static int arm946e_verify_pointer(struct command_context *cmd_ctx, static int arm946e_verify_pointer(struct command_context *cmd_ctx,
struct arm946e_common *arm946e) struct arm946e_common *arm946e)
{ {
if (arm946e->common_magic != ARM946E_COMMON_MAGIC) { if (arm946e->common_magic != ARM946E_COMMON_MAGIC) {
command_print(cmd_ctx, "target is not an ARM946"); command_print(cmd_ctx, "target is not an ARM946");
@ -123,10 +125,9 @@ static int arm946e_read_cp15(struct target *target, int reg_addr, uint32_t *valu
uint8_t reg_addr_buf = reg_addr & 0x3f; uint8_t reg_addr_buf = reg_addr & 0x3f;
uint8_t nr_w_buf = 0; uint8_t nr_w_buf = 0;
if ((retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE)) != ERROR_OK) retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
{ if (retval != ERROR_OK)
return retval; return retval;
}
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE); retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -157,10 +158,9 @@ static int arm946e_read_cp15(struct target *target, int reg_addr, uint32_t *valu
LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value); LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
#endif #endif
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
return ERROR_OK; return ERROR_OK;
} }
@ -177,10 +177,9 @@ int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value)
buf_set_u32(value_buf, 0, 32, value); buf_set_u32(value_buf, 0, 32, value);
if ((retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE)) != ERROR_OK) retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
{ if (retval != ERROR_OK)
return retval; return retval;
}
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE); retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -203,10 +202,9 @@ int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value)
LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value); LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, value);
#endif #endif
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
return ERROR_OK; return ERROR_OK;
} }
@ -214,21 +212,21 @@ int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value)
uint32_t arm946e_invalidate_whole_dcache(struct target *target) uint32_t arm946e_invalidate_whole_dcache(struct target *target)
{ {
uint32_t csize = 0; uint32_t csize = 0;
uint32_t shift = 0; uint32_t shift = 0;
uint32_t cp15_idx, seg, dtag; uint32_t cp15_idx, seg, dtag;
int nb_idx, idx = 0; int nb_idx, idx = 0;
int retval; int retval;
/* Get cache type */ /* Get cache type */
arm946e_read_cp15(target, 0x01, (uint32_t *) &csize); arm946e_read_cp15(target, 0x01, (uint32_t *) &csize);
csize = (csize >> 18) & 0x0F; csize = (csize >> 18) & 0x0F;
if (csize == 0) if (csize == 0)
shift = 0; shift = 0;
else else
shift = csize - 0x3; /* Now 0 = 4KB, 1 = 8KB, ... */ shift = csize - 0x3; /* Now 0 = 4KB, 1 = 8KB, ... */
/* Cache size, given in bytes */ /* Cache size, given in bytes */
csize = 1 << (12 + shift); csize = 1 << (12 + shift);
@ -236,16 +234,13 @@ uint32_t arm946e_invalidate_whole_dcache(struct target *target)
nb_idx = (csize / 32); /* gives nb of lines (indexes) in the cache */ nb_idx = (csize / 32); /* gives nb of lines (indexes) in the cache */
/* Loop for all segmentde (i.e. ways) */ /* Loop for all segmentde (i.e. ways) */
for( seg=0; seg < NB_CACHE_WAYS; seg++) for (seg = 0; seg < NB_CACHE_WAYS; seg++) {
{
/* Loop for all indexes */ /* Loop for all indexes */
for(idx=0; idx < nb_idx; idx++) for (idx = 0; idx < nb_idx; idx++) {
{
/* Form and write cp15 index (segment + line idx) */ /* Form and write cp15 index (segment + line idx) */
cp15_idx = seg << 30 | idx << 5; cp15_idx = seg << 30 | idx << 5;
retval = arm946e_write_cp15(target, 0x3a, cp15_idx); retval = arm946e_write_cp15(target, 0x3a, cp15_idx);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
LOG_DEBUG("ERROR writing index"); LOG_DEBUG("ERROR writing index");
return retval; return retval;
} }
@ -254,21 +249,19 @@ uint32_t arm946e_invalidate_whole_dcache(struct target *target)
arm946e_read_cp15(target, 0x16, (uint32_t *) &dtag); arm946e_read_cp15(target, 0x16, (uint32_t *) &dtag);
/* Check cache line VALID bit */ /* Check cache line VALID bit */
if ( !(dtag >> 4 & 0x1) ) if (!(dtag >> 4 & 0x1))
continue; continue;
/* Clean data cache line */ /* Clean data cache line */
retval = arm946e_write_cp15(target, 0x35, 0x1); retval = arm946e_write_cp15(target, 0x35, 0x1);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
LOG_DEBUG("ERROR cleaning cache line"); LOG_DEBUG("ERROR cleaning cache line");
return retval; return retval;
} }
/* Flush data cache line */ /* Flush data cache line */
retval = arm946e_write_cp15(target, 0x1a, 0x1); retval = arm946e_write_cp15(target, 0x1a, 0x1);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
LOG_DEBUG("ERROR flushing cache line"); LOG_DEBUG("ERROR flushing cache line");
return retval; return retval;
} }
@ -289,8 +282,7 @@ uint32_t arm946e_invalidate_whole_icache(struct target *target)
* mcr 15, 0, r0, cr7, cr5, {0} * mcr 15, 0, r0, cr7, cr5, {0}
*/ */
retval = arm946e_write_cp15(target, 0x0f, 0x1); retval = arm946e_write_cp15(target, 0x0f, 0x1);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
LOG_DEBUG("ERROR flushing I$"); LOG_DEBUG("ERROR flushing I$");
return retval; return retval;
} }
@ -309,10 +301,8 @@ int arm946e_post_debug_entry(struct target *target)
dc = (ctr_reg >> 2) & 0x01; dc = (ctr_reg >> 2) & 0x01;
ic = (ctr_reg >> 12) & 0x01; ic = (ctr_reg >> 12) & 0x01;
if (arm946e_preserve_cache) if (arm946e_preserve_cache) {
{ if (dc == 1) {
if (dc == 1)
{
/* Clean and flush D$ */ /* Clean and flush D$ */
arm946e_invalidate_whole_dcache(target); arm946e_invalidate_whole_dcache(target);
@ -320,8 +310,7 @@ int arm946e_post_debug_entry(struct target *target)
ctr_reg &= ~(1 << 2); ctr_reg &= ~(1 << 2);
} }
if (ic == 1) if (ic == 1) {
{
/* Flush I$ */ /* Flush I$ */
arm946e_invalidate_whole_icache(target); arm946e_invalidate_whole_icache(target);
@ -331,12 +320,11 @@ int arm946e_post_debug_entry(struct target *target)
/* Write the new configuration */ /* Write the new configuration */
retval = arm946e_write_cp15(target, 0x02, ctr_reg); retval = arm946e_write_cp15(target, 0x02, ctr_reg);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
LOG_DEBUG("ERROR disabling cache"); LOG_DEBUG("ERROR disabling cache");
return retval; return retval;
} }
} /* if preserve_cache */ } /* if preserve_cache */
return ERROR_OK; return ERROR_OK;
} }
@ -346,8 +334,7 @@ void arm946e_pre_restore_context(struct target *target)
uint32_t ctr_reg = 0x0; uint32_t ctr_reg = 0x0;
uint32_t retval; uint32_t retval;
if (arm946e_preserve_cache) if (arm946e_preserve_cache) {
{
/* Get the contents of the CTR reg */ /* Get the contents of the CTR reg */
arm946e_read_cp15(target, 0x02, (uint32_t *) &ctr_reg); arm946e_read_cp15(target, 0x02, (uint32_t *) &ctr_reg);
@ -355,14 +342,12 @@ void arm946e_pre_restore_context(struct target *target)
* Read-modify-write CP15 test state register * Read-modify-write CP15 test state register
* to reenable I/D-cache linefills * to reenable I/D-cache linefills
*/ */
if (dc == 1) if (dc == 1) {
{
/* Enable D$ */ /* Enable D$ */
ctr_reg |= 1 << 2; ctr_reg |= 1 << 2;
} }
if (ic == 1) if (ic == 1) {
{
/* Enable I$ */ /* Enable I$ */
ctr_reg |= 1 << 12; ctr_reg |= 1 << 12;
} }
@ -370,14 +355,12 @@ void arm946e_pre_restore_context(struct target *target)
/* Write the new configuration */ /* Write the new configuration */
retval = arm946e_write_cp15(target, 0x02, ctr_reg); retval = arm946e_write_cp15(target, 0x02, ctr_reg);
if (retval != ERROR_OK) if (retval != ERROR_OK)
{
LOG_DEBUG("ERROR enabling cache"); LOG_DEBUG("ERROR enabling cache");
} } /* if preserve_cache */
} /* if preserve_cache */
} }
uint32_t arm946e_invalidate_dcache(struct target *target, uint32_t address, uint32_t arm946e_invalidate_dcache(struct target *target, uint32_t address,
uint32_t size, uint32_t count) uint32_t size, uint32_t count)
{ {
uint32_t csize = 0x0; uint32_t csize = 0x0;
uint32_t shift = 0; uint32_t shift = 0;
@ -386,8 +369,7 @@ uint32_t arm946e_invalidate_dcache(struct target *target, uint32_t address,
uint32_t i = 0; uint32_t i = 0;
int retval; int retval;
for(i = 0; i < count*size; i++) for (i = 0; i < count*size; i++) {
{
cur_addr = address + i; cur_addr = address + i;
/* Get cache type */ /* Get cache type */
@ -399,14 +381,13 @@ uint32_t arm946e_invalidate_dcache(struct target *target, uint32_t address,
if (csize == 0) if (csize == 0)
shift = 0; shift = 0;
else else
shift = csize - 0x3; /* Now 0 = 4KB, 1 = 8KB, ... */ shift = csize - 0x3; /* Now 0 = 4KB, 1 = 8KB, ... */
csize = 1 << (12 + shift); csize = 1 << (12 + shift);
set = (cur_addr >> 5) & 0xff; /* set field is 8 bits long */ set = (cur_addr >> 5) & 0xff; /* set field is 8 bits long */
for (way = 0; way < NB_CACHE_WAYS; way++) for (way = 0; way < NB_CACHE_WAYS; way++) {
{
/** /**
* Find if the affected address is kept in the cache. * Find if the affected address is kept in the cache.
* Because JTAG Scan Chain 15 offers limited approach, * Because JTAG Scan Chain 15 offers limited approach,
@ -417,8 +398,7 @@ uint32_t arm946e_invalidate_dcache(struct target *target, uint32_t address,
/* Form and write cp15 index (segment + line idx) */ /* Form and write cp15 index (segment + line idx) */
cp15_idx = way << 30 | set << 5; cp15_idx = way << 30 | set << 5;
retval = arm946e_write_cp15(target, 0x3a, cp15_idx); retval = arm946e_write_cp15(target, 0x3a, cp15_idx);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
LOG_DEBUG("ERROR writing index"); LOG_DEBUG("ERROR writing index");
return retval; return retval;
} }
@ -427,57 +407,51 @@ uint32_t arm946e_invalidate_dcache(struct target *target, uint32_t address,
arm946e_read_cp15(target, 0x16, (uint32_t *) &dtag); arm946e_read_cp15(target, 0x16, (uint32_t *) &dtag);
/* Check cache line VALID bit */ /* Check cache line VALID bit */
if ( !(dtag >> 4 & 0x1) ) if (!(dtag >> 4 & 0x1))
continue; continue;
/* If line is valid and corresponds to affected address - invalidate it */ /* If line is valid and corresponds to affected address - invalidate it */
if (dtag >> 5 == cur_addr >> 5) if (dtag >> 5 == cur_addr >> 5) {
{
/* Clean data cache line */ /* Clean data cache line */
retval = arm946e_write_cp15(target, 0x35, 0x1); retval = arm946e_write_cp15(target, 0x35, 0x1);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
LOG_DEBUG("ERROR cleaning cache line"); LOG_DEBUG("ERROR cleaning cache line");
return retval; return retval;
} }
/* Flush data cache line */ /* Flush data cache line */
retval = arm946e_write_cp15(target, 0x1c, 0x1); retval = arm946e_write_cp15(target, 0x1c, 0x1);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
LOG_DEBUG("ERROR flushing cache line"); LOG_DEBUG("ERROR flushing cache line");
return retval; return retval;
} }
break; break;
} }
} /* loop through all 4 ways */ } /* loop through all 4 ways */
} /* loop through all addresses */ } /* loop through all addresses */
return ERROR_OK; return ERROR_OK;
} }
uint32_t arm946e_invalidate_icache(struct target *target, uint32_t address, uint32_t arm946e_invalidate_icache(struct target *target, uint32_t address,
uint32_t size, uint32_t count) uint32_t size, uint32_t count)
{ {
uint32_t cur_addr = 0x0; uint32_t cur_addr = 0x0;
uint32_t cp15_idx, set, way, itag; uint32_t cp15_idx, set, way, itag;
uint32_t i = 0; uint32_t i = 0;
int retval; int retval;
for(i = 0; i < count*size; i++) for (i = 0; i < count*size; i++) {
{
cur_addr = address + i; cur_addr = address + i;
set = (cur_addr >> 5) & 0xff; /* set field is 8 bits long */ set = (cur_addr >> 5) & 0xff; /* set field is 8 bits long */
for (way = 0; way < NB_CACHE_WAYS; way++) for (way = 0; way < NB_CACHE_WAYS; way++) {
{
/* Form and write cp15 index (segment + line idx) */ /* Form and write cp15 index (segment + line idx) */
cp15_idx = way << 30 | set << 5; cp15_idx = way << 30 | set << 5;
retval = arm946e_write_cp15(target, 0x3a, cp15_idx); retval = arm946e_write_cp15(target, 0x3a, cp15_idx);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
LOG_DEBUG("ERROR writing index"); LOG_DEBUG("ERROR writing index");
return retval; return retval;
} }
@ -486,31 +460,29 @@ uint32_t arm946e_invalidate_icache(struct target *target, uint32_t address,
arm946e_read_cp15(target, 0x17, (uint32_t *) &itag); arm946e_read_cp15(target, 0x17, (uint32_t *) &itag);
/* Check cache line VALID bit */ /* Check cache line VALID bit */
if ( !(itag >> 4 & 0x1) ) if (!(itag >> 4 & 0x1))
continue; continue;
/* If line is valid and corresponds to affected address - invalidate it */ /* If line is valid and corresponds to affected address - invalidate it */
if (itag >> 5 == cur_addr >> 5) if (itag >> 5 == cur_addr >> 5) {
{
/* Flush I$ line */ /* Flush I$ line */
retval = arm946e_write_cp15(target, 0x1d, 0x0); retval = arm946e_write_cp15(target, 0x1d, 0x0);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
LOG_DEBUG("ERROR flushing cache line"); LOG_DEBUG("ERROR flushing cache line");
return retval; return retval;
} }
break; break;
} }
} /* way loop */ } /* way loop */
} /* addr loop */ } /* addr loop */
return ERROR_OK; return ERROR_OK;
} }
/** Writes a buffer, in the specified word size, with current MMU settings. */ /** Writes a buffer, in the specified word size, with current MMU settings. */
int arm946e_write_memory(struct target *target, uint32_t address, int arm946e_write_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, const uint8_t *buffer) uint32_t size, uint32_t count, const uint8_t *buffer)
{ {
int retval; int retval;
@ -518,18 +490,14 @@ int arm946e_write_memory(struct target *target, uint32_t address,
/* Invalidate D$ if it is ON */ /* Invalidate D$ if it is ON */
if (!arm946e_preserve_cache && dc == 1) if (!arm946e_preserve_cache && dc == 1)
{
arm946e_invalidate_dcache(target, address, size, count); arm946e_invalidate_dcache(target, address, size, count);
}
/** /**
* Write memory * Write memory
*/ */
if ( ( retval = arm7_9_write_memory(target, address, retval = arm7_9_write_memory(target, address, size, count, buffer);
size, count, buffer) ) != ERROR_OK ) if (retval != ERROR_OK)
{
return retval; return retval;
}
/* * /* *
* Invalidate I$ if it is ON. * Invalidate I$ if it is ON.
@ -554,26 +522,22 @@ int arm946e_write_memory(struct target *target, uint32_t address,
* If the data is not in the cache, the controller writes to main memory only. * If the data is not in the cache, the controller writes to main memory only.
*/ */
if (!arm946e_preserve_cache && ic == 1) if (!arm946e_preserve_cache && ic == 1)
{
arm946e_invalidate_icache(target, address, size, count); arm946e_invalidate_icache(target, address, size, count);
}
return ERROR_OK; return ERROR_OK;
} }
int arm946e_read_memory(struct target *target, uint32_t address, int arm946e_read_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, uint8_t *buffer) uint32_t size, uint32_t count, uint8_t *buffer)
{ {
int retval; int retval;
LOG_DEBUG("-"); LOG_DEBUG("-");
if ( ( retval = arm7_9_read_memory(target, address, retval = arm7_9_read_memory(target, address, size, count, buffer);
size, count, buffer) ) != ERROR_OK ) if (retval != ERROR_OK)
{
return retval; return retval;
}
return ERROR_OK; return ERROR_OK;
} }
@ -589,49 +553,37 @@ COMMAND_HANDLER(arm946e_handle_cp15_command)
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
return ERROR_OK; return ERROR_OK;
} }
/* one or more argument, access a single register (write if second argument is given */ /* one or more argument, access a single register (write if second argument is given */
if (CMD_ARGC >= 1) if (CMD_ARGC >= 1) {
{
uint32_t address; uint32_t address;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
if (CMD_ARGC == 1) if (CMD_ARGC == 1) {
{
uint32_t value; uint32_t value;
if ((retval = arm946e_read_cp15(target, address, &value)) != ERROR_OK) retval = arm946e_read_cp15(target, address, &value);
{ if (retval != ERROR_OK) {
command_print(CMD_CTX, command_print(CMD_CTX, "couldn't access reg %" PRIi32, address);
"couldn't access reg %" PRIi32,
address);
return ERROR_OK; return ERROR_OK;
} }
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
command_print(CMD_CTX, "%" PRIi32 ": %8.8" PRIx32, command_print(CMD_CTX, "%" PRIi32 ": %8.8" PRIx32, address, value);
address, value); } else if (CMD_ARGC == 2) {
}
else if (CMD_ARGC == 2)
{
uint32_t value; uint32_t value;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
if ((retval = arm946e_write_cp15(target, address, value)) != ERROR_OK) retval = arm946e_write_cp15(target, address, value);
{ if (retval != ERROR_OK) {
command_print(CMD_CTX, command_print(CMD_CTX, "couldn't access reg %" PRIi32, address);
"couldn't access reg %" PRIi32,
address);
return ERROR_OK; return ERROR_OK;
} }
command_print(CMD_CTX, "%" PRIi32 ": %8.8" PRIx32, command_print(CMD_CTX, "%" PRIi32 ": %8.8" PRIx32, address, value);
address, value);
} }
} }
@ -664,8 +616,7 @@ const struct command_registration arm946e_command_handlers[] = {
}; };
/** Holds methods for ARM946 targets. */ /** Holds methods for ARM946 targets. */
struct target_type arm946e_target = struct target_type arm946e_target = {
{
.name = "arm946e", .name = "arm946e",
.poll = arm7_9_poll, .poll = arm7_9_poll,
@ -683,8 +634,8 @@ struct target_type arm946e_target =
.get_gdb_reg_list = arm_get_gdb_reg_list, .get_gdb_reg_list = arm_get_gdb_reg_list,
//.read_memory = arm7_9_read_memory, /* .read_memory = arm7_9_read_memory, */
//.write_memory = arm7_9_write_memory, /* .write_memory = arm7_9_write_memory, */
.read_memory = arm946e_read_memory, .read_memory = arm946e_read_memory,
.write_memory = arm946e_write_memory, .write_memory = arm946e_write_memory,
@ -697,8 +648,8 @@ struct target_type arm946e_target =
.add_breakpoint = arm7_9_add_breakpoint, .add_breakpoint = arm7_9_add_breakpoint,
.remove_breakpoint = arm7_9_remove_breakpoint, .remove_breakpoint = arm7_9_remove_breakpoint,
//.add_breakpoint = arm946e_add_breakpoint, /* .add_breakpoint = arm946e_add_breakpoint, */
//.remove_breakpoint = arm946e_remove_breakpoint, /* .remove_breakpoint = arm946e_remove_breakpoint, */
.add_watchpoint = arm7_9_add_watchpoint, .add_watchpoint = arm7_9_add_watchpoint,
.remove_watchpoint = arm7_9_remove_watchpoint, .remove_watchpoint = arm7_9_remove_watchpoint,

View File

@ -23,31 +23,30 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARM946E_H #ifndef ARM946E_H
#define ARM946E_H #define ARM946E_H
#include "arm9tdmi.h" #include "arm9tdmi.h"
#define ARM946E_COMMON_MAGIC 0x20f920f9 #define ARM946E_COMMON_MAGIC 0x20f920f9
struct arm946e_common struct arm946e_common {
{
struct arm7_9_common arm7_9_common; struct arm7_9_common arm7_9_common;
int common_magic; int common_magic;
uint32_t cp15_control_reg; uint32_t cp15_control_reg;
}; };
static inline struct arm946e_common * static inline struct arm946e_common *target_to_arm946(struct target *target)
target_to_arm946(struct target *target)
{ {
return container_of(target->arch_info, struct arm946e_common, return container_of(target->arch_info, struct arm946e_common,
arm7_9_common.arm); arm7_9_common.arm);
} }
int arm946e_init_arch_info(struct target *target, int arm946e_init_arch_info(struct target *target,
struct arm946e_common *arm946e, struct jtag_tap *tap); struct arm946e_common *arm946e, struct jtag_tap *tap);
int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value); int arm946e_write_cp15(struct target *target, int reg_addr, uint32_t value);
extern const struct command_registration arm946e_command_handlers[]; extern const struct command_registration arm946e_command_handlers[];
#endif /* ARM946E_H */ #endif /* ARM946E_H */

View File

@ -20,6 +20,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -28,7 +29,6 @@
#include "target_type.h" #include "target_type.h"
#include "arm_opcodes.h" #include "arm_opcodes.h"
#if 0 #if 0
#define _DEBUG_INSTRUCTION_EXECUTION_ #define _DEBUG_INSTRUCTION_EXECUTION_
#endif #endif
@ -53,7 +53,7 @@ int arm966e_init_arch_info(struct target *target, struct arm966e_common *arm966e
static int arm966e_target_create(struct target *target, Jim_Interp *interp) static int arm966e_target_create(struct target *target, Jim_Interp *interp)
{ {
struct arm966e_common *arm966e = calloc(1,sizeof(struct arm966e_common)); struct arm966e_common *arm966e = calloc(1, sizeof(struct arm966e_common));
return arm966e_init_arch_info(target, arm966e, target->tap); return arm966e_init_arch_info(target, arm966e, target->tap);
} }
@ -84,10 +84,9 @@ static int arm966e_read_cp15(struct target *target, int reg_addr, uint32_t *valu
uint8_t reg_addr_buf = reg_addr & 0x3f; uint8_t reg_addr_buf = reg_addr & 0x3f;
uint8_t nr_w_buf = 0; uint8_t nr_w_buf = 0;
if ((retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE)) != ERROR_OK) retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
{ if (retval != ERROR_OK)
return retval; return retval;
}
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE); retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -117,17 +116,16 @@ static int arm966e_read_cp15(struct target *target, int reg_addr, uint32_t *valu
#ifdef _DEBUG_INSTRUCTION_EXECUTION_ #ifdef _DEBUG_INSTRUCTION_EXECUTION_
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value); LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value);
#endif #endif
return ERROR_OK; return ERROR_OK;
} }
// EXPORTED to str9x (flash) /* EXPORTED to str9x (flash) */
int arm966e_write_cp15(struct target *target, int reg_addr, uint32_t value) int arm966e_write_cp15(struct target *target, int reg_addr, uint32_t value)
{ {
int retval = ERROR_OK; int retval = ERROR_OK;
@ -140,10 +138,9 @@ int arm966e_write_cp15(struct target *target, int reg_addr, uint32_t value)
buf_set_u32(value_buf, 0, 32, value); buf_set_u32(value_buf, 0, 32, value);
if ((retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE)) != ERROR_OK) retval = arm_jtag_scann(jtag_info, 0xf, TAP_IDLE);
{ if (retval != ERROR_OK)
return retval; return retval;
}
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE); retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -179,42 +176,36 @@ COMMAND_HANDLER(arm966e_handle_cp15_command)
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
return ERROR_OK; return ERROR_OK;
} }
/* one or more argument, access a single register (write if second argument is given */ /* one or more argument, access a single register (write if second argument is given */
if (CMD_ARGC >= 1) if (CMD_ARGC >= 1) {
{
uint32_t address; uint32_t address;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
if (CMD_ARGC == 1) if (CMD_ARGC == 1) {
{
uint32_t value; uint32_t value;
if ((retval = arm966e_read_cp15(target, address, &value)) != ERROR_OK) retval = arm966e_read_cp15(target, address, &value);
{ if (retval != ERROR_OK) {
command_print(CMD_CTX, command_print(CMD_CTX,
"couldn't access reg %" PRIi32, "couldn't access reg %" PRIi32,
address); address);
return ERROR_OK; return ERROR_OK;
} }
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
command_print(CMD_CTX, "%" PRIi32 ": %8.8" PRIx32, command_print(CMD_CTX, "%" PRIi32 ": %8.8" PRIx32,
address, value); address, value);
} } else if (CMD_ARGC == 2) {
else if (CMD_ARGC == 2)
{
uint32_t value; uint32_t value;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
if ((retval = arm966e_write_cp15(target, address, value)) != ERROR_OK) retval = arm966e_write_cp15(target, address, value);
{ if (retval != ERROR_OK) {
command_print(CMD_CTX, command_print(CMD_CTX,
"couldn't access reg %" PRIi32, "couldn't access reg %" PRIi32,
address); address);
@ -254,8 +245,7 @@ const struct command_registration arm966e_command_handlers[] = {
}; };
/** Holds methods for ARM966 targets. */ /** Holds methods for ARM966 targets. */
struct target_type arm966e_target = struct target_type arm966e_target = {
{
.name = "arm966e", .name = "arm966e",
.poll = arm7_9_poll, .poll = arm7_9_poll,

View File

@ -20,6 +20,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARM966E_H #ifndef ARM966E_H
#define ARM966E_H #define ARM966E_H
@ -27,8 +28,7 @@
#define ARM966E_COMMON_MAGIC 0x20f920f9 #define ARM966E_COMMON_MAGIC 0x20f920f9
struct arm966e_common struct arm966e_common {
{
struct arm7_9_common arm7_9_common; struct arm7_9_common arm7_9_common;
int common_magic; int common_magic;
uint32_t cp15_control_reg; uint32_t cp15_control_reg;

View File

@ -23,6 +23,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -32,7 +33,6 @@
#include "register.h" #include "register.h"
#include "arm_opcodes.h" #include "arm_opcodes.h"
/* /*
* NOTE: this holds code that's used with multiple ARM9 processors: * NOTE: this holds code that's used with multiple ARM9 processors:
* - ARM9TDMI (ARMv4T) ... in ARM920, ARM922, and ARM940 cores * - ARM9TDMI (ARMv4T) ... in ARM920, ARM922, and ARM940 cores
@ -47,8 +47,7 @@
#define _DEBUG_INSTRUCTION_EXECUTION_ #define _DEBUG_INSTRUCTION_EXECUTION_
#endif #endif
enum arm9tdmi_vector_bit enum arm9tdmi_vector_bit {
{
ARM9TDMI_RESET_VECTOR = 0x01, ARM9TDMI_RESET_VECTOR = 0x01,
ARM9TDMI_UNDEF_VECTOR = 0x02, ARM9TDMI_UNDEF_VECTOR = 0x02,
ARM9TDMI_SWI_VECTOR = 0x04, ARM9TDMI_SWI_VECTOR = 0x04,
@ -80,8 +79,7 @@ int arm9tdmi_examine_debug_reason(struct target *target)
/* only check the debug reason if we don't know it already */ /* only check the debug reason if we don't know it already */
if ((target->debug_reason != DBG_REASON_DBGRQ) if ((target->debug_reason != DBG_REASON_DBGRQ)
&& (target->debug_reason != DBG_REASON_SINGLESTEP)) && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
{
struct scan_field fields[3]; struct scan_field fields[3];
uint8_t databus[4]; uint8_t databus[4];
uint8_t instructionbus[4]; uint8_t instructionbus[4];
@ -99,19 +97,17 @@ int arm9tdmi_examine_debug_reason(struct target *target)
fields[2].out_value = NULL; fields[2].out_value = NULL;
fields[2].in_value = instructionbus; fields[2].in_value = instructionbus;
if ((retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1, TAP_DRPAUSE)) != ERROR_OK) retval = arm_jtag_scann(&arm7_9->jtag_info, 0x1, TAP_DRPAUSE);
{ if (retval != ERROR_OK)
return retval; return retval;
}
retval = arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL, TAP_DRPAUSE); retval = arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL, TAP_DRPAUSE);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
jtag_add_dr_scan(arm7_9->jtag_info.tap, 3, fields, TAP_DRPAUSE); jtag_add_dr_scan(arm7_9->jtag_info.tap, 3, fields, TAP_DRPAUSE);
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
fields[0].in_value = NULL; fields[0].in_value = NULL;
fields[0].out_value = databus; fields[0].out_value = databus;
@ -154,10 +150,9 @@ int arm9tdmi_clock_out(struct arm_jtag *jtag_info, uint32_t instr,
if (sysspeed) if (sysspeed)
buf_set_u32(&sysspeed_buf, 2, 1, 1); buf_set_u32(&sysspeed_buf, 2, 1, 1);
if ((retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE)) != ERROR_OK) retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);
{ if (retval != ERROR_OK)
return retval; return retval;
}
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE); retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
if (retval != ERROR_OK) if (retval != ERROR_OK)
@ -175,31 +170,24 @@ int arm9tdmi_clock_out(struct arm_jtag *jtag_info, uint32_t instr,
fields[2].out_value = instr_buf; fields[2].out_value = instr_buf;
fields[2].in_value = NULL; fields[2].in_value = NULL;
if (in) if (in) {
{
fields[0].in_value = (uint8_t *)in; fields[0].in_value = (uint8_t *)in;
jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE); jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE);
jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)in); jtag_add_callback(arm_le_to_h_u32, (jtag_callback_data_t)in);
} } else
else
{
jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE); jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE);
}
jtag_add_runtest(0, TAP_DRPAUSE); jtag_add_runtest(0, TAP_DRPAUSE);
#ifdef _DEBUG_INSTRUCTION_EXECUTION_ #ifdef _DEBUG_INSTRUCTION_EXECUTION_
{ {
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
if (in) if (in)
{
LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr, out, *in); LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr, out, *in);
}
else else
LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr, out); LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x", instr, out);
} }
@ -211,13 +199,12 @@ int arm9tdmi_clock_out(struct arm_jtag *jtag_info, uint32_t instr,
/* just read data (instruction and data-out = don't care) */ /* just read data (instruction and data-out = don't care) */
int arm9tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in) int arm9tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in)
{ {
int retval = ERROR_OK;; int retval = ERROR_OK;
struct scan_field fields[3]; struct scan_field fields[3];
if ((retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE)) != ERROR_OK) retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);
{ if (retval != ERROR_OK)
return retval; return retval;
}
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE); retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
if (retval != ERROR_OK) if (retval != ERROR_OK)
@ -243,19 +230,14 @@ int arm9tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in)
#ifdef _DEBUG_INSTRUCTION_EXECUTION_ #ifdef _DEBUG_INSTRUCTION_EXECUTION_
{ {
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
if (in) if (in)
{
LOG_DEBUG("in: 0x%8.8x", *in); LOG_DEBUG("in: 0x%8.8x", *in);
}
else else
{
LOG_ERROR("BUG: called with in == NULL"); LOG_ERROR("BUG: called with in == NULL");
}
} }
#endif #endif
@ -282,10 +264,9 @@ int arm9tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info,
int retval = ERROR_OK; int retval = ERROR_OK;
struct scan_field fields[3]; struct scan_field fields[3];
if ((retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE)) != ERROR_OK) retval = arm_jtag_scann(jtag_info, 0x1, TAP_DRPAUSE);
{ if (retval != ERROR_OK)
return retval; return retval;
}
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE); retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE);
if (retval != ERROR_OK) if (retval != ERROR_OK)
@ -315,19 +296,14 @@ int arm9tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info,
#ifdef _DEBUG_INSTRUCTION_EXECUTION_ #ifdef _DEBUG_INSTRUCTION_EXECUTION_
{ {
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
if (in) if (in)
{ LOG_DEBUG("in: 0x%8.8x", *(uint32_t *)in);
LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in);
}
else else
{
LOG_ERROR("BUG: called with in == NULL"); LOG_ERROR("BUG: called with in == NULL");
}
} }
#endif #endif
@ -376,10 +352,9 @@ static void arm9tdmi_change_to_arm(struct target *target,
/* NOP fetched, BX in Execute (1) */ /* NOP fetched, BX in Execute (1) */
arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_T_NOP, 0, NULL, 0);
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return; return;
}
/* fix program counter: /* fix program counter:
* MOV r0, r15 was the 5th instruction (+8) * MOV r0, r15 was the 5th instruction (+8)
@ -389,7 +364,7 @@ static void arm9tdmi_change_to_arm(struct target *target,
} }
void arm9tdmi_read_core_regs(struct target *target, void arm9tdmi_read_core_regs(struct target *target,
uint32_t mask, uint32_t* core_regs[16]) uint32_t mask, uint32_t *core_regs[16])
{ {
int i; int i;
struct arm7_9_common *arm7_9 = target_to_arm7_9(target); struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
@ -405,8 +380,7 @@ void arm9tdmi_read_core_regs(struct target *target,
/* fetch NOP, STM in EXECUTE stage (1st cycle) */ /* fetch NOP, STM in EXECUTE stage (1st cycle) */
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
for (i = 0; i <= 15; i++) for (i = 0; i <= 15; i++) {
{
if (mask & (1 << i)) if (mask & (1 << i))
/* nothing fetched, STM in MEMORY (i'th cycle) */ /* nothing fetched, STM in MEMORY (i'th cycle) */
arm9tdmi_clock_data_in(jtag_info, core_regs[i]); arm9tdmi_clock_data_in(jtag_info, core_regs[i]);
@ -414,7 +388,7 @@ void arm9tdmi_read_core_regs(struct target *target,
} }
static void arm9tdmi_read_core_regs_target_buffer(struct target *target, static void arm9tdmi_read_core_regs_target_buffer(struct target *target,
uint32_t mask, void* buffer, int size) uint32_t mask, void *buffer, int size)
{ {
int i; int i;
struct arm7_9_common *arm7_9 = target_to_arm7_9(target); struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
@ -434,12 +408,10 @@ static void arm9tdmi_read_core_regs_target_buffer(struct target *target,
/* fetch NOP, STM in EXECUTE stage (1st cycle) */ /* fetch NOP, STM in EXECUTE stage (1st cycle) */
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
for (i = 0; i <= 15; i++) for (i = 0; i <= 15; i++) {
{
if (mask & (1 << i)) if (mask & (1 << i))
/* nothing fetched, STM in MEMORY (i'th cycle) */ /* nothing fetched, STM in MEMORY (i'th cycle) */
switch (size) switch (size) {
{
case 4: case 4:
arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be); arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
break; break;
@ -525,8 +497,7 @@ static void arm9tdmi_write_xpsr_im8(struct target *target,
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
/* rot == 4 writes flags, which takes only one cycle */ /* rot == 4 writes flags, which takes only one cycle */
if (rot != 4) if (rot != 4) {
{
/* nothing fetched, MSR in EXECUTE (2) */ /* nothing fetched, MSR in EXECUTE (2) */
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
/* nothing fetched, MSR in EXECUTE (3) */ /* nothing fetched, MSR in EXECUTE (3) */
@ -551,8 +522,7 @@ void arm9tdmi_write_core_regs(struct target *target,
/* fetch NOP, LDM in EXECUTE stage (1st cycle) */ /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
for (i = 0; i <= 15; i++) for (i = 0; i <= 15; i++) {
{
if (mask & (1 << i)) if (mask & (1 << i))
/* nothing fetched, LDM still in EXECUTE (1 + i cycle) */ /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0);
@ -718,30 +688,22 @@ void arm9tdmi_enable_single_step(struct target *target, uint32_t next_pc)
{ {
struct arm7_9_common *arm7_9 = target_to_arm7_9(target); struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
if (arm7_9->has_single_step) if (arm7_9->has_single_step) {
{
buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 1); buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 1);
embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]); embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
} } else
else
{
arm7_9_enable_eice_step(target, next_pc); arm7_9_enable_eice_step(target, next_pc);
}
} }
void arm9tdmi_disable_single_step(struct target *target) void arm9tdmi_disable_single_step(struct target *target)
{ {
struct arm7_9_common *arm7_9 = target_to_arm7_9(target); struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
if (arm7_9->has_single_step) if (arm7_9->has_single_step) {
{
buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 0); buf_set_u32(arm7_9->eice_cache->reg_list[EICE_DBG_CTRL].value, 3, 1, 0);
embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]); embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]);
} } else
else
{
arm7_9_disable_eice_step(target); arm7_9_disable_eice_step(target);
}
} }
static void arm9tdmi_build_reg_cache(struct target *target) static void arm9tdmi_build_reg_cache(struct target *target)
@ -815,7 +777,7 @@ int arm9tdmi_init_arch_info(struct target *target,
static int arm9tdmi_target_create(struct target *target, Jim_Interp *interp) static int arm9tdmi_target_create(struct target *target, Jim_Interp *interp)
{ {
struct arm7_9_common *arm7_9 = calloc(1,sizeof(struct arm7_9_common)); struct arm7_9_common *arm7_9 = calloc(1, sizeof(struct arm7_9_common));
arm9tdmi_init_arch_info(target, arm7_9, target->tap); arm9tdmi_init_arch_info(target, arm7_9, target->tap);
arm7_9->arm.is_armv4 = true; arm7_9->arm.is_armv4 = true;
@ -830,8 +792,7 @@ COMMAND_HANDLER(handle_arm9tdmi_catch_vectors_command)
struct reg *vector_catch; struct reg *vector_catch;
uint32_t vector_catch_value; uint32_t vector_catch_value;
if (!target_was_examined(target)) if (!target_was_examined(target)) {
{
LOG_ERROR("Target not examined yet"); LOG_ERROR("Target not examined yet");
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -853,42 +814,31 @@ COMMAND_HANDLER(handle_arm9tdmi_catch_vectors_command)
/* get the current setting */ /* get the current setting */
vector_catch_value = buf_get_u32(vector_catch->value, 0, 8); vector_catch_value = buf_get_u32(vector_catch->value, 0, 8);
if (CMD_ARGC > 0) if (CMD_ARGC > 0) {
{
vector_catch_value = 0x0; vector_catch_value = 0x0;
if (strcmp(CMD_ARGV[0], "all") == 0) if (strcmp(CMD_ARGV[0], "all") == 0)
{
vector_catch_value = 0xdf; vector_catch_value = 0xdf;
} else if (strcmp(CMD_ARGV[0], "none") == 0) {
else if (strcmp(CMD_ARGV[0], "none") == 0)
{
/* do nothing */ /* do nothing */
} } else {
else for (unsigned i = 0; i < CMD_ARGC; i++) {
{
for (unsigned i = 0; i < CMD_ARGC; i++)
{
/* go through list of vectors */ /* go through list of vectors */
unsigned j; unsigned j;
for (j = 0; arm9tdmi_vectors[j].name; j++) for (j = 0; arm9tdmi_vectors[j].name; j++) {
{ if (strcmp(CMD_ARGV[i], arm9tdmi_vectors[j].name) == 0) {
if (strcmp(CMD_ARGV[i], arm9tdmi_vectors[j].name) == 0)
{
vector_catch_value |= arm9tdmi_vectors[j].value; vector_catch_value |= arm9tdmi_vectors[j].value;
break; break;
} }
} }
/* complain if vector wasn't found */ /* complain if vector wasn't found */
if (!arm9tdmi_vectors[j].name) if (!arm9tdmi_vectors[j].name) {
{
command_print(CMD_CTX, "vector '%s' not found, leaving current setting unchanged", CMD_ARGV[i]); command_print(CMD_CTX, "vector '%s' not found, leaving current setting unchanged", CMD_ARGV[i]);
/* reread current setting */ /* reread current setting */
vector_catch_value = buf_get_u32( vector_catch_value = buf_get_u32(
vector_catch->value, vector_catch->value,
0, 8); 0, 8);
break; break;
} }
} }
@ -935,8 +885,7 @@ const struct command_registration arm9tdmi_command_handlers[] = {
}; };
/** Holds methods for ARM9TDMI targets. */ /** Holds methods for ARM9TDMI targets. */
struct target_type arm9tdmi_target = struct target_type arm9tdmi_target = {
{
.name = "arm9tdmi", .name = "arm9tdmi",
.poll = arm7_9_poll, .poll = arm7_9_poll,

View File

@ -20,6 +20,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARM9TDMI_H #ifndef ARM9TDMI_H
#define ARM9TDMI_H #define ARM9TDMI_H
@ -37,7 +38,7 @@ int arm9tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in);
int arm9tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info, int arm9tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info,
void *in, int size, int be); void *in, int size, int be);
void arm9tdmi_read_core_regs(struct target *target, void arm9tdmi_read_core_regs(struct target *target,
uint32_t mask, uint32_t* core_regs[16]); uint32_t mask, uint32_t *core_regs[16]);
void arm9tdmi_write_core_regs(struct target *target, void arm9tdmi_write_core_regs(struct target *target,
uint32_t mask, uint32_t core_regs[16]); uint32_t mask, uint32_t core_regs[16]);

View File

@ -73,7 +73,6 @@
#include "arm_adi_v5.h" #include "arm_adi_v5.h"
#include <helper/time_support.h> #include <helper/time_support.h>
/* ARM ADI Specification requires at least 10 bits used for TAR autoincrement */ /* ARM ADI Specification requires at least 10 bits used for TAR autoincrement */
/* /*
@ -100,12 +99,11 @@ static uint32_t max_tar_block_size(uint32_t tar_autoincr_block, uint32_t address
* @param apsel Number of the AP to (implicitly) use with further * @param apsel Number of the AP to (implicitly) use with further
* transactions. This normally identifies a MEM-AP. * transactions. This normally identifies a MEM-AP.
*/ */
void dap_ap_select(struct adiv5_dap *dap,uint8_t ap) void dap_ap_select(struct adiv5_dap *dap, uint8_t ap)
{ {
uint32_t new_ap = (ap << 24) & 0xFF000000; uint32_t new_ap = (ap << 24) & 0xFF000000;
if (new_ap != dap->ap_current) if (new_ap != dap->ap_current) {
{
dap->ap_current = new_ap; dap->ap_current = new_ap;
/* Switching AP invalidates cached values. /* Switching AP invalidates cached values.
* Values MUST BE UPDATED BEFORE AP ACCESS. * Values MUST BE UPDATED BEFORE AP ACCESS.
@ -140,16 +138,14 @@ int dap_setup_accessport(struct adiv5_dap *dap, uint32_t csw, uint32_t tar)
int retval; int retval;
csw = csw | CSW_DBGSWENABLE | CSW_MASTER_DEBUG | CSW_HPROT; csw = csw | CSW_DBGSWENABLE | CSW_MASTER_DEBUG | CSW_HPROT;
if (csw != dap->ap_csw_value) if (csw != dap->ap_csw_value) {
{
/* LOG_DEBUG("DAP: Set CSW %x",csw); */ /* LOG_DEBUG("DAP: Set CSW %x",csw); */
retval = dap_queue_ap_write(dap, AP_REG_CSW, csw); retval = dap_queue_ap_write(dap, AP_REG_CSW, csw);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
dap->ap_csw_value = csw; dap->ap_csw_value = csw;
} }
if (tar != dap->ap_tar_value) if (tar != dap->ap_tar_value) {
{
/* LOG_DEBUG("DAP: Set TAR %x",tar); */ /* LOG_DEBUG("DAP: Set TAR %x",tar); */
retval = dap_queue_ap_write(dap, AP_REG_TAR, tar); retval = dap_queue_ap_write(dap, AP_REG_TAR, tar);
if (retval != ERROR_OK) if (retval != ERROR_OK)
@ -274,23 +270,20 @@ int mem_ap_write_buf_u32(struct adiv5_dap *dap, const uint8_t *buffer, int count
{ {
int wcount, blocksize, writecount, errorcount = 0, retval = ERROR_OK; int wcount, blocksize, writecount, errorcount = 0, retval = ERROR_OK;
uint32_t adr = address; uint32_t adr = address;
const uint8_t* pBuffer = buffer; const uint8_t *pBuffer = buffer;
count >>= 2; count >>= 2;
wcount = count; wcount = count;
/* if we have an unaligned access - reorder data */ /* if we have an unaligned access - reorder data */
if (adr & 0x3u) if (adr & 0x3u) {
{ for (writecount = 0; writecount < count; writecount++) {
for (writecount = 0; writecount < count; writecount++)
{
int i; int i;
uint32_t outvalue; uint32_t outvalue;
memcpy(&outvalue, pBuffer, sizeof(uint32_t)); memcpy(&outvalue, pBuffer, sizeof(uint32_t));
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++) {
{ *((uint8_t *)pBuffer + (adr & 0x3)) = outvalue;
*((uint8_t*)pBuffer + (adr & 0x3)) = outvalue;
outvalue >>= 8; outvalue >>= 8;
adr++; adr++;
} }
@ -298,8 +291,7 @@ int mem_ap_write_buf_u32(struct adiv5_dap *dap, const uint8_t *buffer, int count
} }
} }
while (wcount > 0) while (wcount > 0) {
{
/* Adjust to write blocks within boundaries aligned to the TAR autoincremnent size*/ /* Adjust to write blocks within boundaries aligned to the TAR autoincremnent size*/
blocksize = max_tar_block_size(dap->tar_autoincr_block, address); blocksize = max_tar_block_size(dap->tar_autoincr_block, address);
if (wcount < blocksize) if (wcount < blocksize)
@ -313,27 +305,22 @@ int mem_ap_write_buf_u32(struct adiv5_dap *dap, const uint8_t *buffer, int count
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
for (writecount = 0; writecount < blocksize; writecount++) for (writecount = 0; writecount < blocksize; writecount++) {
{
retval = dap_queue_ap_write(dap, AP_REG_DRW, retval = dap_queue_ap_write(dap, AP_REG_DRW,
*(uint32_t *) ((void *) (buffer + 4 * writecount))); *(uint32_t *) ((void *) (buffer + 4 * writecount)));
if (retval != ERROR_OK) if (retval != ERROR_OK)
break; break;
} }
if ((retval = dap_run(dap)) == ERROR_OK) retval = dap_run(dap);
{ if (retval == ERROR_OK) {
wcount = wcount - blocksize; wcount = wcount - blocksize;
address = address + 4 * blocksize; address = address + 4 * blocksize;
buffer = buffer + 4 * blocksize; buffer = buffer + 4 * blocksize;
} } else
else
{
errorcount++; errorcount++;
}
if (errorcount > 1) if (errorcount > 1) {
{
LOG_WARNING("Block write error address 0x%" PRIx32 ", wcount 0x%x", address, wcount); LOG_WARNING("Block write error address 0x%" PRIx32 ", wcount 0x%x", address, wcount);
return retval; return retval;
} }
@ -350,8 +337,7 @@ static int mem_ap_write_buf_packed_u16(struct adiv5_dap *dap,
wcount = count >> 1; wcount = count >> 1;
while (wcount > 0) while (wcount > 0) {
{
int nbytes; int nbytes;
/* Adjust to write blocks within boundaries aligned to the TAR autoincremnent size*/ /* Adjust to write blocks within boundaries aligned to the TAR autoincremnent size*/
@ -369,16 +355,13 @@ static int mem_ap_write_buf_packed_u16(struct adiv5_dap *dap,
return retval; return retval;
writecount = blocksize; writecount = blocksize;
do do {
{
nbytes = MIN((writecount << 1), 4); nbytes = MIN((writecount << 1), 4);
if (nbytes < 4) if (nbytes < 4) {
{
retval = mem_ap_write_buf_u16(dap, buffer, retval = mem_ap_write_buf_u16(dap, buffer,
nbytes, address); nbytes, address);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
LOG_WARNING("Block write error address " LOG_WARNING("Block write error address "
"0x%" PRIx32 ", count 0x%x", "0x%" PRIx32 ", count 0x%x",
address, count); address, count);
@ -386,15 +369,12 @@ static int mem_ap_write_buf_packed_u16(struct adiv5_dap *dap,
} }
address += nbytes >> 1; address += nbytes >> 1;
} } else {
else
{
uint32_t outvalue; uint32_t outvalue;
memcpy(&outvalue, buffer, sizeof(uint32_t)); memcpy(&outvalue, buffer, sizeof(uint32_t));
for (i = 0; i < nbytes; i++) for (i = 0; i < nbytes; i++) {
{ *((uint8_t *)buffer + (address & 0x3)) = outvalue;
*((uint8_t*)buffer + (address & 0x3)) = outvalue;
outvalue >>= 8; outvalue >>= 8;
address++; address++;
} }
@ -405,8 +385,8 @@ static int mem_ap_write_buf_packed_u16(struct adiv5_dap *dap,
if (retval != ERROR_OK) if (retval != ERROR_OK)
break; break;
if ((retval = dap_run(dap)) != ERROR_OK) retval = dap_run(dap);
{ if (retval != ERROR_OK) {
LOG_WARNING("Block write error address " LOG_WARNING("Block write error address "
"0x%" PRIx32 ", count 0x%x", "0x%" PRIx32 ", count 0x%x",
address, count); address, count);
@ -431,8 +411,7 @@ int mem_ap_write_buf_u16(struct adiv5_dap *dap, const uint8_t *buffer, int count
if (count >= 4) if (count >= 4)
return mem_ap_write_buf_packed_u16(dap, buffer, count, address); return mem_ap_write_buf_packed_u16(dap, buffer, count, address);
while (count > 0) while (count > 0) {
{
retval = dap_setup_accessport(dap, CSW_16BIT | CSW_ADDRINC_SINGLE, address); retval = dap_setup_accessport(dap, CSW_16BIT | CSW_ADDRINC_SINGLE, address);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -463,8 +442,7 @@ static int mem_ap_write_buf_packed_u8(struct adiv5_dap *dap,
wcount = count; wcount = count;
while (wcount > 0) while (wcount > 0) {
{
int nbytes; int nbytes;
/* Adjust to write blocks within boundaries aligned to the TAR autoincremnent size*/ /* Adjust to write blocks within boundaries aligned to the TAR autoincremnent size*/
@ -478,15 +456,12 @@ static int mem_ap_write_buf_packed_u8(struct adiv5_dap *dap,
return retval; return retval;
writecount = blocksize; writecount = blocksize;
do do {
{
nbytes = MIN(writecount, 4); nbytes = MIN(writecount, 4);
if (nbytes < 4) if (nbytes < 4) {
{
retval = mem_ap_write_buf_u8(dap, buffer, nbytes, address); retval = mem_ap_write_buf_u8(dap, buffer, nbytes, address);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
LOG_WARNING("Block write error address " LOG_WARNING("Block write error address "
"0x%" PRIx32 ", count 0x%x", "0x%" PRIx32 ", count 0x%x",
address, count); address, count);
@ -494,15 +469,12 @@ static int mem_ap_write_buf_packed_u8(struct adiv5_dap *dap,
} }
address += nbytes; address += nbytes;
} } else {
else
{
uint32_t outvalue; uint32_t outvalue;
memcpy(&outvalue, buffer, sizeof(uint32_t)); memcpy(&outvalue, buffer, sizeof(uint32_t));
for (i = 0; i < nbytes; i++) for (i = 0; i < nbytes; i++) {
{ *((uint8_t *)buffer + (address & 0x3)) = outvalue;
*((uint8_t*)buffer + (address & 0x3)) = outvalue;
outvalue >>= 8; outvalue >>= 8;
address++; address++;
} }
@ -513,8 +485,8 @@ static int mem_ap_write_buf_packed_u8(struct adiv5_dap *dap,
if (retval != ERROR_OK) if (retval != ERROR_OK)
break; break;
if ((retval = dap_run(dap)) != ERROR_OK) retval = dap_run(dap);
{ if (retval != ERROR_OK) {
LOG_WARNING("Block write error address " LOG_WARNING("Block write error address "
"0x%" PRIx32 ", count 0x%x", "0x%" PRIx32 ", count 0x%x",
address, count); address, count);
@ -539,8 +511,7 @@ int mem_ap_write_buf_u8(struct adiv5_dap *dap, const uint8_t *buffer, int count,
if (count >= 4) if (count >= 4)
return mem_ap_write_buf_packed_u8(dap, buffer, count, address); return mem_ap_write_buf_packed_u8(dap, buffer, count, address);
while (count > 0) while (count > 0) {
{
retval = dap_setup_accessport(dap, CSW_8BIT | CSW_ADDRINC_SINGLE, address); retval = dap_setup_accessport(dap, CSW_8BIT | CSW_ADDRINC_SINGLE, address);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -581,13 +552,12 @@ int mem_ap_read_buf_u32(struct adiv5_dap *dap, uint8_t *buffer,
{ {
int wcount, blocksize, readcount, errorcount = 0, retval = ERROR_OK; int wcount, blocksize, readcount, errorcount = 0, retval = ERROR_OK;
uint32_t adr = address; uint32_t adr = address;
uint8_t* pBuffer = buffer; uint8_t *pBuffer = buffer;
count >>= 2; count >>= 2;
wcount = count; wcount = count;
while (wcount > 0) while (wcount > 0) {
{
/* Adjust to read blocks within boundaries aligned to the /* Adjust to read blocks within boundaries aligned to the
* TAR autoincrement size (at least 2^10). Autoincrement * TAR autoincrement size (at least 2^10). Autoincrement
* mode avoids an extra per-word roundtrip to update TAR. * mode avoids an extra per-word roundtrip to update TAR.
@ -618,8 +588,7 @@ int mem_ap_read_buf_u32(struct adiv5_dap *dap, uint8_t *buffer,
DPAP_READ, 0, NULL, NULL); DPAP_READ, 0, NULL, NULL);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
for (readcount = 0; readcount < blocksize - 1; readcount++) for (readcount = 0; readcount < blocksize - 1; readcount++) {
{
/* Scan out next read; scan in posted value for the /* Scan out next read; scan in posted value for the
* previous one. Assumes read is acked "OK/FAULT", * previous one. Assumes read is acked "OK/FAULT",
* and CTRL_STAT says that meant "OK". * and CTRL_STAT says that meant "OK".
@ -641,11 +610,9 @@ int mem_ap_read_buf_u32(struct adiv5_dap *dap, uint8_t *buffer,
return retval; return retval;
retval = dap_run(dap); retval = dap_run(dap);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
errorcount++; errorcount++;
if (errorcount <= 1) if (errorcount <= 1) {
{
/* try again */ /* try again */
continue; continue;
} }
@ -658,17 +625,14 @@ int mem_ap_read_buf_u32(struct adiv5_dap *dap, uint8_t *buffer,
} }
/* if we have an unaligned access - reorder data */ /* if we have an unaligned access - reorder data */
if (adr & 0x3u) if (adr & 0x3u) {
{ for (readcount = 0; readcount < count; readcount++) {
for (readcount = 0; readcount < count; readcount++)
{
int i; int i;
uint32_t data; uint32_t data;
memcpy(&data, pBuffer, sizeof(uint32_t)); memcpy(&data, pBuffer, sizeof(uint32_t));
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++) {
{ *((uint8_t *)pBuffer) =
*((uint8_t*)pBuffer) =
(data >> 8 * (adr & 0x3)); (data >> 8 * (adr & 0x3));
pBuffer++; pBuffer++;
adr++; adr++;
@ -688,8 +652,7 @@ static int mem_ap_read_buf_packed_u16(struct adiv5_dap *dap,
wcount = count >> 1; wcount = count >> 1;
while (wcount > 0) while (wcount > 0) {
{
int nbytes; int nbytes;
/* Adjust to read blocks within boundaries aligned to the TAR autoincremnent size*/ /* Adjust to read blocks within boundaries aligned to the TAR autoincremnent size*/
@ -706,22 +669,20 @@ static int mem_ap_read_buf_packed_u16(struct adiv5_dap *dap,
blocksize = 1; blocksize = 1;
readcount = blocksize; readcount = blocksize;
do do {
{
retval = dap_queue_ap_read(dap, AP_REG_DRW, &invalue); retval = dap_queue_ap_read(dap, AP_REG_DRW, &invalue);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if ((retval = dap_run(dap)) != ERROR_OK) retval = dap_run(dap);
{ if (retval != ERROR_OK) {
LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count); LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count);
return retval; return retval;
} }
nbytes = MIN((readcount << 1), 4); nbytes = MIN((readcount << 1), 4);
for (i = 0; i < nbytes; i++) for (i = 0; i < nbytes; i++) {
{ *((uint8_t *)buffer) = (invalue >> 8 * (address & 0x3));
*((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
buffer++; buffer++;
address++; address++;
} }
@ -751,8 +712,7 @@ int mem_ap_read_buf_u16(struct adiv5_dap *dap, uint8_t *buffer,
if (count >= 4) if (count >= 4)
return mem_ap_read_buf_packed_u16(dap, buffer, count, address); return mem_ap_read_buf_packed_u16(dap, buffer, count, address);
while (count > 0) while (count > 0) {
{
retval = dap_setup_accessport(dap, CSW_16BIT | CSW_ADDRINC_SINGLE, address); retval = dap_setup_accessport(dap, CSW_16BIT | CSW_ADDRINC_SINGLE, address);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -764,17 +724,13 @@ int mem_ap_read_buf_u16(struct adiv5_dap *dap, uint8_t *buffer,
if (retval != ERROR_OK) if (retval != ERROR_OK)
break; break;
if (address & 0x1) if (address & 0x1) {
{ for (i = 0; i < 2; i++) {
for (i = 0; i < 2; i++) *((uint8_t *)buffer) = (invalue >> 8 * (address & 0x3));
{
*((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
buffer++; buffer++;
address++; address++;
} }
} } else {
else
{
uint16_t svalue = (invalue >> 8 * (address & 0x3)); uint16_t svalue = (invalue >> 8 * (address & 0x3));
memcpy(buffer, &svalue, sizeof(uint16_t)); memcpy(buffer, &svalue, sizeof(uint16_t));
address += 2; address += 2;
@ -801,8 +757,7 @@ static int mem_ap_read_buf_packed_u8(struct adiv5_dap *dap,
wcount = count; wcount = count;
while (wcount > 0) while (wcount > 0) {
{
int nbytes; int nbytes;
/* Adjust to read blocks within boundaries aligned to the TAR autoincremnent size*/ /* Adjust to read blocks within boundaries aligned to the TAR autoincremnent size*/
@ -816,22 +771,20 @@ static int mem_ap_read_buf_packed_u8(struct adiv5_dap *dap,
return retval; return retval;
readcount = blocksize; readcount = blocksize;
do do {
{
retval = dap_queue_ap_read(dap, AP_REG_DRW, &invalue); retval = dap_queue_ap_read(dap, AP_REG_DRW, &invalue);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if ((retval = dap_run(dap)) != ERROR_OK) retval = dap_run(dap);
{ if (retval != ERROR_OK) {
LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count); LOG_WARNING("Block read error address 0x%" PRIx32 ", count 0x%x", address, count);
return retval; return retval;
} }
nbytes = MIN(readcount, 4); nbytes = MIN(readcount, 4);
for (i = 0; i < nbytes; i++) for (i = 0; i < nbytes; i++) {
{ *((uint8_t *)buffer) = (invalue >> 8 * (address & 0x3));
*((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3));
buffer++; buffer++;
address++; address++;
} }
@ -861,8 +814,7 @@ int mem_ap_read_buf_u8(struct adiv5_dap *dap, uint8_t *buffer,
if (count >= 4) if (count >= 4)
return mem_ap_read_buf_packed_u8(dap, buffer, count, address); return mem_ap_read_buf_packed_u8(dap, buffer, count, address);
while (count > 0) while (count > 0) {
{
retval = dap_setup_accessport(dap, CSW_8BIT | CSW_ADDRINC_SINGLE, address); retval = dap_setup_accessport(dap, CSW_8BIT | CSW_ADDRINC_SINGLE, address);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -873,7 +825,7 @@ int mem_ap_read_buf_u8(struct adiv5_dap *dap, uint8_t *buffer,
if (retval != ERROR_OK) if (retval != ERROR_OK)
break; break;
*((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3)); *((uint8_t *)buffer) = (invalue >> 8 * (address & 0x3));
count--; count--;
address++; address++;
buffer++; buffer++;
@ -999,9 +951,8 @@ int dap_syssec_kinetis_mdmap(struct adiv5_dap *dap)
return retval; return retval;
dap_run(dap); dap_run(dap);
if ( val != 0x001C0000 ) if (val != 0x001C0000) {
{ LOG_DEBUG("id doesn't match %08X != 0x001C0000", val);
LOG_DEBUG("id doesn't match %08X != 0x001C0000",val);
dap_ap_select(dap, 0); dap_ap_select(dap, 0);
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -1015,40 +966,28 @@ int dap_syssec_kinetis_mdmap(struct adiv5_dap *dap)
return retval; return retval;
dap_run(dap); dap_run(dap);
LOG_DEBUG("MDM_REG_STAT %08X",val); LOG_DEBUG("MDM_REG_STAT %08X", val);
if ( (val & (MDM_STAT_SYSSEC|MDM_STAT_FREADY)) != (MDM_STAT_FREADY) ) if ((val & (MDM_STAT_SYSSEC|MDM_STAT_FREADY)) != (MDM_STAT_FREADY)) {
{
LOG_DEBUG("MDMAP: system is secured, masserase needed"); LOG_DEBUG("MDMAP: system is secured, masserase needed");
if ( !(val & MDM_STAT_FMEEN) ) if (!(val & MDM_STAT_FMEEN))
{
LOG_DEBUG("MDMAP: masserase is disabled"); LOG_DEBUG("MDMAP: masserase is disabled");
} else {
else
{
/* we need to assert reset */ /* we need to assert reset */
if ( jtag_reset_config & RESET_HAS_SRST ) if (jtag_reset_config & RESET_HAS_SRST) {
{
/* default to asserting srst */ /* default to asserting srst */
if (jtag_reset_config & RESET_SRST_PULLS_TRST) if (jtag_reset_config & RESET_SRST_PULLS_TRST)
{
jtag_add_reset(1, 1); jtag_add_reset(1, 1);
}
else else
{
jtag_add_reset(0, 1); jtag_add_reset(0, 1);
} } else {
}
else
{
LOG_DEBUG("SRST not configured"); LOG_DEBUG("SRST not configured");
dap_ap_select(dap, 0); dap_ap_select(dap, 0);
return ERROR_FAIL; return ERROR_FAIL;
} }
while(1) while (1) {
{
retval = dap_queue_ap_write(dap, MDM_REG_CTRL, MEM_CTRL_FMEIP); retval = dap_queue_ap_write(dap, MDM_REG_CTRL, MEM_CTRL_FMEIP);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -1058,14 +997,13 @@ int dap_syssec_kinetis_mdmap(struct adiv5_dap *dap)
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
dap_run(dap); dap_run(dap);
LOG_DEBUG("MDM_REG_STAT %08X",val); LOG_DEBUG("MDM_REG_STAT %08X", val);
if ( (val&1)) if ((val & 1))
break; break;
} }
while(1) while (1) {
{
retval = dap_queue_ap_write(dap, MDM_REG_CTRL, 0); retval = dap_queue_ap_write(dap, MDM_REG_CTRL, 0);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -1075,15 +1013,15 @@ int dap_syssec_kinetis_mdmap(struct adiv5_dap *dap)
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
dap_run(dap); dap_run(dap);
LOG_DEBUG("MDM_REG_STAT %08X",val); LOG_DEBUG("MDM_REG_STAT %08X", val);
/* read control register and wait for ready */ /* read control register and wait for ready */
retval = dap_queue_ap_read(dap, MDM_REG_CTRL, &val); retval = dap_queue_ap_read(dap, MDM_REG_CTRL, &val);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
dap_run(dap); dap_run(dap);
LOG_DEBUG("MDM_REG_CTRL %08X",val); LOG_DEBUG("MDM_REG_CTRL %08X", val);
if ( val == 0x00 ) if (val == 0x00)
break; break;
} }
} }
@ -1107,7 +1045,6 @@ static struct dap_syssec_filter dap_syssec_filter_data[] = {
{ 0x4BA00477, dap_syssec_kinetis_mdmap } { 0x4BA00477, dap_syssec_kinetis_mdmap }
}; };
/** /**
* *
*/ */
@ -1116,15 +1053,12 @@ int dap_syssec(struct adiv5_dap *dap)
unsigned int i; unsigned int i;
struct jtag_tap *tap; struct jtag_tap *tap;
for(i=0;i<sizeof(dap_syssec_filter_data);i++) for (i = 0; i < sizeof(dap_syssec_filter_data); i++) {
{
tap = dap->jtag_info->tap; tap = dap->jtag_info->tap;
while (tap != NULL) while (tap != NULL) {
{ if (tap->hasidcode && (dap_syssec_filter_data[i].idcode == tap->idcode)) {
if ( tap->hasidcode && (dap_syssec_filter_data[i].idcode == tap->idcode) ) LOG_DEBUG("DAP: mdmap_init for idcode: %08x", tap->idcode);
{
LOG_DEBUG("DAP: mdmap_init for idcode: %08x",tap->idcode);
dap_syssec_filter_data[i].dap_init(dap); dap_syssec_filter_data[i].dap_init(dap);
} }
tap = tap->next_tap; tap = tap->next_tap;
@ -1202,28 +1136,29 @@ int ahbap_debugport_init(struct adiv5_dap *dap)
retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat); retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if ((retval = dap_run(dap)) != ERROR_OK) retval = dap_run(dap);
if (retval != ERROR_OK)
return retval; return retval;
/* Check that we have debug power domains activated */ /* Check that we have debug power domains activated */
while (!(ctrlstat & CDBGPWRUPACK) && (cnt++ < 10)) while (!(ctrlstat & CDBGPWRUPACK) && (cnt++ < 10)) {
{
LOG_DEBUG("DAP: wait CDBGPWRUPACK"); LOG_DEBUG("DAP: wait CDBGPWRUPACK");
retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat); retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if ((retval = dap_run(dap)) != ERROR_OK) retval = dap_run(dap);
if (retval != ERROR_OK)
return retval; return retval;
alive_sleep(10); alive_sleep(10);
} }
while (!(ctrlstat & CSYSPWRUPACK) && (cnt++ < 10)) while (!(ctrlstat & CSYSPWRUPACK) && (cnt++ < 10)) {
{
LOG_DEBUG("DAP: wait CSYSPWRUPACK"); LOG_DEBUG("DAP: wait CSYSPWRUPACK");
retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat); retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if ((retval = dap_run(dap)) != ERROR_OK) retval = dap_run(dap);
if (retval != ERROR_OK)
return retval; return retval;
alive_sleep(10); alive_sleep(10);
} }
@ -1248,16 +1183,15 @@ int ahbap_debugport_init(struct adiv5_dap *dap)
/* CID interpretation -- see ARM IHI 0029B section 3 /* CID interpretation -- see ARM IHI 0029B section 3
* and ARM IHI 0031A table 13-3. * and ARM IHI 0031A table 13-3.
*/ */
static const char *class_description[16] ={ static const char *class_description[16] = {
"Reserved", "ROM table", "Reserved", "Reserved", "Reserved", "ROM table", "Reserved", "Reserved",
"Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved", "Reserved",
"Reserved", "CoreSight component", "Reserved", "Peripheral Test Block", "Reserved", "CoreSight component", "Reserved", "Peripheral Test Block",
"Reserved", "OptimoDE DESS", "Reserved", "OptimoDE DESS",
"Generic IP component", "PrimeCell or System component" "Generic IP component", "PrimeCell or System component"
}; };
static bool static bool is_dap_cid_ok(uint32_t cid3, uint32_t cid2, uint32_t cid1, uint32_t cid0)
is_dap_cid_ok(uint32_t cid3, uint32_t cid2, uint32_t cid1, uint32_t cid0)
{ {
return cid3 == 0xb1 && cid2 == 0x05 return cid3 == 0xb1 && cid2 == 0x05
&& ((cid1 & 0x0f) == 0) && cid0 == 0x0d; && ((cid1 & 0x0f) == 0) && cid0 == 0x0d;
@ -1320,8 +1254,7 @@ int dap_lookup_cs_component(struct adiv5_dap *dap, int ap,
ap_old = dap->ap_current; ap_old = dap->ap_current;
dap_ap_select(dap, ap); dap_ap_select(dap, ap);
do do {
{
retval = mem_ap_read_atomic_u32(dap, (dbgbase&0xFFFFF000) | retval = mem_ap_read_atomic_u32(dap, (dbgbase&0xFFFFF000) |
entry_offset, &romentry); entry_offset, &romentry);
if (retval != ERROR_OK) if (retval != ERROR_OK)
@ -1367,10 +1300,8 @@ static int dap_info_command(struct command_context *cmd_ctx,
/* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */ /* Now we read ROM table ID registers, ref. ARM IHI 0029B sec */
mem_ap = ((apid&0x10000) && ((apid&0x0F) != 0)); mem_ap = ((apid&0x10000) && ((apid&0x0F) != 0));
command_print(cmd_ctx, "AP ID register 0x%8.8" PRIx32, apid); command_print(cmd_ctx, "AP ID register 0x%8.8" PRIx32, apid);
if (apid) if (apid) {
{ switch (apid&0x0F) {
switch (apid&0x0F)
{
case 0: case 0:
command_print(cmd_ctx, "\tType is JTAG-AP"); command_print(cmd_ctx, "\tType is JTAG-AP");
break; break;
@ -1389,18 +1320,13 @@ static int dap_info_command(struct command_context *cmd_ctx,
* not a ROM table ... or have no such components at all. * not a ROM table ... or have no such components at all.
*/ */
if (mem_ap) if (mem_ap)
command_print(cmd_ctx, "AP BASE 0x%8.8" PRIx32, command_print(cmd_ctx, "AP BASE 0x%8.8" PRIx32, dbgbase);
dbgbase); } else
}
else
{
command_print(cmd_ctx, "No AP found at this ap 0x%x", ap); command_print(cmd_ctx, "No AP found at this ap 0x%x", ap);
}
romtable_present = ((mem_ap) && (dbgbase != 0xFFFFFFFF)); romtable_present = ((mem_ap) && (dbgbase != 0xFFFFFFFF));
if (romtable_present) if (romtable_present) {
{ uint32_t cid0, cid1, cid2, cid3, memtype, romentry;
uint32_t cid0,cid1,cid2,cid3,memtype,romentry;
uint16_t entry_offset; uint16_t entry_offset;
/* bit 16 of apid indicates a memory access port */ /* bit 16 of apid indicates a memory access port */
@ -1444,78 +1370,61 @@ static int dap_info_command(struct command_context *cmd_ctx,
/* Now we read ROM table entries from dbgbase&0xFFFFF000) | 0x000 until we get 0x00000000 */ /* Now we read ROM table entries from dbgbase&0xFFFFF000) | 0x000 until we get 0x00000000 */
entry_offset = 0; entry_offset = 0;
do do {
{
retval = mem_ap_read_atomic_u32(dap, (dbgbase&0xFFFFF000) | entry_offset, &romentry); retval = mem_ap_read_atomic_u32(dap, (dbgbase&0xFFFFF000) | entry_offset, &romentry);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
command_print(cmd_ctx, "\tROMTABLE[0x%x] = 0x%" PRIx32 "",entry_offset,romentry); command_print(cmd_ctx, "\tROMTABLE[0x%x] = 0x%" PRIx32 "", entry_offset, romentry);
if (romentry&0x01) if (romentry & 0x01) {
{
uint32_t c_cid0, c_cid1, c_cid2, c_cid3; uint32_t c_cid0, c_cid1, c_cid2, c_cid3;
uint32_t c_pid0, c_pid1, c_pid2, c_pid3, c_pid4; uint32_t c_pid0, c_pid1, c_pid2, c_pid3, c_pid4;
uint32_t component_base; uint32_t component_base;
unsigned part_num; unsigned part_num;
char *type, *full; char *type, *full;
component_base = (dbgbase & 0xFFFFF000) component_base = (dbgbase & 0xFFFFF000) + (romentry & 0xFFFFF000);
+ (romentry & 0xFFFFF000);
/* IDs are in last 4K section */ /* IDs are in last 4K section */
retval = mem_ap_read_atomic_u32(dap, component_base + 0xFE0, &c_pid0);
retval = mem_ap_read_atomic_u32(dap,
component_base + 0xFE0, &c_pid0);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
c_pid0 &= 0xff; c_pid0 &= 0xff;
retval = mem_ap_read_atomic_u32(dap, retval = mem_ap_read_atomic_u32(dap, component_base + 0xFE4, &c_pid1);
component_base + 0xFE4, &c_pid1);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
c_pid1 &= 0xff; c_pid1 &= 0xff;
retval = mem_ap_read_atomic_u32(dap, retval = mem_ap_read_atomic_u32(dap, component_base + 0xFE8, &c_pid2);
component_base + 0xFE8, &c_pid2);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
c_pid2 &= 0xff; c_pid2 &= 0xff;
retval = mem_ap_read_atomic_u32(dap, retval = mem_ap_read_atomic_u32(dap, component_base + 0xFEC, &c_pid3);
component_base + 0xFEC, &c_pid3);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
c_pid3 &= 0xff; c_pid3 &= 0xff;
retval = mem_ap_read_atomic_u32(dap, retval = mem_ap_read_atomic_u32(dap, component_base + 0xFD0, &c_pid4);
component_base + 0xFD0, &c_pid4);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
c_pid4 &= 0xff; c_pid4 &= 0xff;
retval = mem_ap_read_atomic_u32(dap, retval = mem_ap_read_atomic_u32(dap, component_base + 0xFF0, &c_cid0);
component_base + 0xFF0, &c_cid0);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
c_cid0 &= 0xff; c_cid0 &= 0xff;
retval = mem_ap_read_atomic_u32(dap, retval = mem_ap_read_atomic_u32(dap, component_base + 0xFF4, &c_cid1);
component_base + 0xFF4, &c_cid1);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
c_cid1 &= 0xff; c_cid1 &= 0xff;
retval = mem_ap_read_atomic_u32(dap, retval = mem_ap_read_atomic_u32(dap, component_base + 0xFF8, &c_cid2);
component_base + 0xFF8, &c_cid2);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
c_cid2 &= 0xff; c_cid2 &= 0xff;
retval = mem_ap_read_atomic_u32(dap, retval = mem_ap_read_atomic_u32(dap, component_base + 0xFFC, &c_cid3);
component_base + 0xFFC, &c_cid3);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
c_cid3 &= 0xff; c_cid3 &= 0xff;
command_print(cmd_ctx, "\t\tComponent base address 0x%" PRIx32 ","
command_print(cmd_ctx, "start address 0x%" PRIx32, component_base,
"\t\tComponent base address 0x%" PRIx32
", start address 0x%" PRIx32,
component_base,
/* component may take multiple 4K pages */ /* component may take multiple 4K pages */
component_base - 0x1000*(c_pid4 >> 4)); component_base - 0x1000*(c_pid4 >> 4));
command_print(cmd_ctx, "\t\tComponent class is 0x%x, %s", command_print(cmd_ctx, "\t\tComponent class is 0x%x, %s",
@ -1638,7 +1547,7 @@ static int dap_info_command(struct command_context *cmd_ctx,
if (!is_dap_cid_ok(cid3, cid2, cid1, cid0)) if (!is_dap_cid_ok(cid3, cid2, cid1, cid0))
command_print(cmd_ctx, command_print(cmd_ctx,
"\t\tCID3 0%2.2x" "\t\tCID3 0%2.2x"
", CID2 0%2.2x" ", CID2 0%2.2x"
", CID1 0%2.2x" ", CID1 0%2.2x"
", CID0 0%2.2x", ", CID0 0%2.2x",
@ -1681,7 +1590,7 @@ static int dap_info_command(struct command_context *cmd_ctx,
type = "CoreSight ETM11"; type = "CoreSight ETM11";
full = "(Embedded Trace)"; full = "(Embedded Trace)";
break; break;
// case 0x113: what? /* case 0x113: what? */
case 0x120: /* from OMAP3 memmap */ case 0x120: /* from OMAP3 memmap */
type = "TI SDTI"; type = "TI SDTI";
full = "(System Debug Trace Interface)"; full = "(System Debug Trace Interface)";
@ -1741,9 +1650,7 @@ static int dap_info_command(struct command_context *cmd_ctx,
} }
command_print(cmd_ctx, "\t\tPart is %s %s", command_print(cmd_ctx, "\t\tPart is %s %s",
type, full); type, full);
} } else {
else
{
if (romentry) if (romentry)
command_print(cmd_ctx, "\t\tComponent not present"); command_print(cmd_ctx, "\t\tComponent not present");
else else
@ -1751,11 +1658,8 @@ static int dap_info_command(struct command_context *cmd_ctx,
} }
entry_offset += 4; entry_offset += 4;
} while (romentry > 0); } while (romentry > 0);
} } else
else
{
command_print(cmd_ctx, "\tNo ROM table present"); command_print(cmd_ctx, "\tNo ROM table present");
}
dap_ap_select(dap, ap_old); dap_ap_select(dap, ap_old);
return ERROR_OK; return ERROR_OK;
@ -1980,5 +1884,3 @@ const struct command_registration dap_command_handlers[] = {
}, },
COMMAND_REGISTRATION_DONE COMMAND_REGISTRATION_DONE
}; };

View File

@ -20,6 +20,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARM_ADI_V5_H #ifndef ARM_ADI_V5_H
#define ARM_ADI_V5_H #define ARM_ADI_V5_H
@ -133,15 +134,13 @@
* as part of setting up a debug session (if all the dual-role JTAG/SWD * as part of setting up a debug session (if all the dual-role JTAG/SWD
* signals are available). * signals are available).
*/ */
struct adiv5_dap struct adiv5_dap {
{
const struct dap_ops *ops; const struct dap_ops *ops;
struct arm_jtag *jtag_info; struct arm_jtag *jtag_info;
/* Control config */ /* Control config */
uint32_t dp_ctrl_stat; uint32_t dp_ctrl_stat;
uint32_t apsel; uint32_t apsel;
/** /**
@ -182,6 +181,7 @@ struct adiv5_dap
* MEM-AP access before we try to read its status (and/or result). * MEM-AP access before we try to read its status (and/or result).
*/ */
uint32_t memaccess_tck; uint32_t memaccess_tck;
/* Size of TAR autoincrement block, ARM ADI Specification requires at least 10 bits */ /* Size of TAR autoincrement block, ARM ADI Specification requires at least 10 bits */
uint32_t tar_autoincr_block; uint32_t tar_autoincr_block;
}; };
@ -216,6 +216,7 @@ struct dap_ops {
/** AP register write. */ /** AP register write. */
int (*queue_ap_write)(struct adiv5_dap *dap, unsigned reg, int (*queue_ap_write)(struct adiv5_dap *dap, unsigned reg,
uint32_t data); uint32_t data);
/** AP operation abort. */ /** AP operation abort. */
int (*queue_ap_abort)(struct adiv5_dap *dap, uint8_t *ack); int (*queue_ap_abort)(struct adiv5_dap *dap, uint8_t *ack);
@ -249,7 +250,7 @@ static inline int dap_queue_idcode_read(struct adiv5_dap *dap,
* @param dap The DAP used for reading. * @param dap The DAP used for reading.
* @param reg The two-bit number of the DP register being read. * @param reg The two-bit number of the DP register being read.
* @param data Pointer saying where to store the register's value * @param data Pointer saying where to store the register's value
* (in host endianness). * (in host endianness).
* *
* @return ERROR_OK for success, else a fault code. * @return ERROR_OK for success, else a fault code.
*/ */
@ -284,7 +285,7 @@ static inline int dap_queue_dp_write(struct adiv5_dap *dap,
* @param dap The DAP used for reading. * @param dap The DAP used for reading.
* @param reg The number of the AP register being read. * @param reg The number of the AP register being read.
* @param data Pointer saying where to store the register's value * @param data Pointer saying where to store the register's value
* (in host endianness). * (in host endianness).
* *
* @return ERROR_OK for success, else a fault code. * @return ERROR_OK for success, else a fault code.
*/ */
@ -347,11 +348,11 @@ static inline int dap_run(struct adiv5_dap *dap)
/** Accessor for currently selected DAP-AP number (0..255) */ /** Accessor for currently selected DAP-AP number (0..255) */
static inline uint8_t dap_ap_get_select(struct adiv5_dap *swjdp) static inline uint8_t dap_ap_get_select(struct adiv5_dap *swjdp)
{ {
return (uint8_t)(swjdp ->ap_current >> 24); return (uint8_t)(swjdp->ap_current >> 24);
} }
/* AP selection applies to future AP transactions */ /* AP selection applies to future AP transactions */
void dap_ap_select(struct adiv5_dap *dap,uint8_t ap); void dap_ap_select(struct adiv5_dap *dap, uint8_t ap);
/* Queued AP transactions */ /* Queued AP transactions */
int dap_setup_accessport(struct adiv5_dap *swjdp, int dap_setup_accessport(struct adiv5_dap *swjdp,
@ -382,8 +383,6 @@ int mem_ap_write_buf_u16(struct adiv5_dap *swjdp,
int mem_ap_write_buf_u32(struct adiv5_dap *swjdp, int mem_ap_write_buf_u32(struct adiv5_dap *swjdp,
const uint8_t *buffer, int count, uint32_t address); const uint8_t *buffer, int count, uint32_t address);
/* Queued MEM-AP memory mapped single word transfers with selection of ap */ /* Queued MEM-AP memory mapped single word transfers with selection of ap */
int mem_ap_sel_read_u32(struct adiv5_dap *swjdp, uint8_t ap, int mem_ap_sel_read_u32(struct adiv5_dap *swjdp, uint8_t ap,
uint32_t address, uint32_t *value); uint32_t address, uint32_t *value);
@ -411,8 +410,6 @@ int mem_ap_sel_write_buf_u16(struct adiv5_dap *swjdp, uint8_t ap,
int mem_ap_sel_write_buf_u32(struct adiv5_dap *swjdp, uint8_t ap, int mem_ap_sel_write_buf_u32(struct adiv5_dap *swjdp, uint8_t ap,
const uint8_t *buffer, int count, uint32_t address); const uint8_t *buffer, int count, uint32_t address);
/* Initialisation of the debug system, power domains and registers */ /* Initialisation of the debug system, power domains and registers */
int ahbap_debugport_init(struct adiv5_dap *swjdp); int ahbap_debugport_init(struct adiv5_dap *swjdp);

File diff suppressed because it is too large Load Diff

View File

@ -17,13 +17,13 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARM_DISASSEMBLER_H #ifndef ARM_DISASSEMBLER_H
#define ARM_DISASSEMBLER_H #define ARM_DISASSEMBLER_H
#include <helper/types.h> #include <helper/types.h>
enum arm_instruction_type enum arm_instruction_type {
{
ARM_UNKNOWN_INSTUCTION, ARM_UNKNOWN_INSTUCTION,
/* Branch instructions */ /* Branch instructions */
@ -120,14 +120,12 @@ enum arm_instruction_type
ARM_UNDEFINED_INSTRUCTION = 0xffffffff, ARM_UNDEFINED_INSTRUCTION = 0xffffffff,
}; };
struct arm_b_bl_bx_blx_instr struct arm_b_bl_bx_blx_instr {
{
int reg_operand; int reg_operand;
uint32_t target_address; uint32_t target_address;
}; };
union arm_shifter_operand union arm_shifter_operand {
{
struct { struct {
uint32_t immediate; uint32_t immediate;
} immediate; } immediate;
@ -143,8 +141,7 @@ union arm_shifter_operand
} register_shift; } register_shift;
}; };
struct arm_data_proc_instr struct arm_data_proc_instr {
{
int variant; /* 0: immediate, 1: immediate_shift, 2: register_shift */ int variant; /* 0: immediate, 1: immediate_shift, 2: register_shift */
uint8_t S; uint8_t S;
uint8_t Rn; uint8_t Rn;
@ -152,15 +149,13 @@ struct arm_data_proc_instr
union arm_shifter_operand shifter_operand; union arm_shifter_operand shifter_operand;
}; };
struct arm_load_store_instr struct arm_load_store_instr {
{
uint8_t Rd; uint8_t Rd;
uint8_t Rn; uint8_t Rn;
uint8_t U; uint8_t U;
int index_mode; /* 0: offset, 1: pre-indexed, 2: post-indexed */ int index_mode; /* 0: offset, 1: pre-indexed, 2: post-indexed */
int offset_mode; /* 0: immediate, 1: (scaled) register */ int offset_mode; /* 0: immediate, 1: (scaled) register */
union union {
{
uint32_t offset; uint32_t offset;
struct { struct {
uint8_t Rm; uint8_t Rm;
@ -170,8 +165,7 @@ struct arm_load_store_instr
} offset; } offset;
}; };
struct arm_load_store_multiple_instr struct arm_load_store_multiple_instr {
{
uint8_t Rn; uint8_t Rn;
uint32_t register_list; uint32_t register_list;
uint8_t addressing_mode; /* 0: IA, 1: IB, 2: DA, 3: DB */ uint8_t addressing_mode; /* 0: IA, 1: IB, 2: DA, 3: DB */
@ -179,8 +173,7 @@ struct arm_load_store_multiple_instr
uint8_t W; uint8_t W;
}; };
struct arm_instruction struct arm_instruction {
{
enum arm_instruction_type type; enum arm_instruction_type type;
char text[128]; char text[128];
uint32_t opcode; uint32_t opcode;

View File

@ -51,8 +51,8 @@
/* Read coprocessor */ /* Read coprocessor */
static int dpm_mrc(struct target *target, int cpnum, static int dpm_mrc(struct target *target, int cpnum,
uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm,
uint32_t *value) uint32_t *value)
{ {
struct arm *arm = target_to_arm(target); struct arm *arm = target_to_arm(target);
struct arm_dpm *dpm = arm->dpm; struct arm_dpm *dpm = arm->dpm;
@ -63,8 +63,8 @@ static int dpm_mrc(struct target *target, int cpnum,
return retval; return retval;
LOG_DEBUG("MRC p%d, %d, r0, c%d, c%d, %d", cpnum, LOG_DEBUG("MRC p%d, %d, r0, c%d, c%d, %d", cpnum,
(int) op1, (int) CRn, (int) op1, (int) CRn,
(int) CRm, (int) op2); (int) CRm, (int) op2);
/* read coprocessor register into R0; return via DCC */ /* read coprocessor register into R0; return via DCC */
retval = dpm->instr_read_data_r0(dpm, retval = dpm->instr_read_data_r0(dpm,
@ -76,8 +76,8 @@ static int dpm_mrc(struct target *target, int cpnum,
} }
static int dpm_mcr(struct target *target, int cpnum, static int dpm_mcr(struct target *target, int cpnum,
uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm,
uint32_t value) uint32_t value)
{ {
struct arm *arm = target_to_arm(target); struct arm *arm = target_to_arm(target);
struct arm_dpm *dpm = arm->dpm; struct arm_dpm *dpm = arm->dpm;
@ -88,8 +88,8 @@ static int dpm_mcr(struct target *target, int cpnum,
return retval; return retval;
LOG_DEBUG("MCR p%d, %d, r0, c%d, c%d, %d", cpnum, LOG_DEBUG("MCR p%d, %d, r0, c%d, c%d, %d", cpnum,
(int) op1, (int) CRn, (int) op1, (int) CRn,
(int) CRm, (int) op2); (int) CRm, (int) op2);
/* read DCC into r0; then write coprocessor register from R0 */ /* read DCC into r0; then write coprocessor register from R0 */
retval = dpm->instr_write_data_r0(dpm, retval = dpm->instr_write_data_r0(dpm,
@ -139,44 +139,44 @@ static int dpm_read_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
int retval; int retval;
switch (regnum) { switch (regnum) {
case 0 ... 14: case 0 ... 14:
/* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */ /* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */
retval = dpm->instr_read_data_dcc(dpm, retval = dpm->instr_read_data_dcc(dpm,
ARMV4_5_MCR(14, 0, regnum, 0, 5, 0), ARMV4_5_MCR(14, 0, regnum, 0, 5, 0),
&value); &value);
break; break;
case 15: /* PC */ case 15:/* PC
/* "MOV r0, pc"; then return via DCC */ * "MOV r0, pc"; then return via DCC */
retval = dpm->instr_read_data_r0(dpm, 0xe1a0000f, &value); retval = dpm->instr_read_data_r0(dpm, 0xe1a0000f, &value);
/* NOTE: this seems like a slightly awkward place to update /* NOTE: this seems like a slightly awkward place to update
* this value ... but if the PC gets written (the only way * this value ... but if the PC gets written (the only way
* to change what we compute), the arch spec says subsequent * to change what we compute), the arch spec says subsequent
* reads return values which are "unpredictable". So this * reads return values which are "unpredictable". So this
* is always right except in those broken-by-intent cases. * is always right except in those broken-by-intent cases.
*/ */
switch (dpm->arm->core_state) { switch (dpm->arm->core_state) {
case ARM_STATE_ARM: case ARM_STATE_ARM:
value -= 8; value -= 8;
break;
case ARM_STATE_THUMB:
case ARM_STATE_THUMB_EE:
value -= 4;
break;
case ARM_STATE_JAZELLE:
/* core-specific ... ? */
LOG_WARNING("Jazelle PC adjustment unknown");
break;
}
break; break;
case ARM_STATE_THUMB: default:
case ARM_STATE_THUMB_EE: /* 16: "MRS r0, CPSR"; then return via DCC
value -= 4; * 17: "MRS r0, SPSR"; then return via DCC
break; */
case ARM_STATE_JAZELLE: retval = dpm->instr_read_data_r0(dpm,
/* core-specific ... ? */
LOG_WARNING("Jazelle PC adjustment unknown");
break;
}
break;
default:
/* 16: "MRS r0, CPSR"; then return via DCC
* 17: "MRS r0, SPSR"; then return via DCC
*/
retval = dpm->instr_read_data_r0(dpm,
ARMV4_5_MRS(0, regnum & 1), ARMV4_5_MRS(0, regnum & 1),
&value); &value);
break; break;
} }
if (retval == ERROR_OK) { if (retval == ERROR_OK) {
@ -196,30 +196,30 @@ static int dpm_write_reg(struct arm_dpm *dpm, struct reg *r, unsigned regnum)
uint32_t value = buf_get_u32(r->value, 0, 32); uint32_t value = buf_get_u32(r->value, 0, 32);
switch (regnum) { switch (regnum) {
case 0 ... 14: case 0 ... 14:
/* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */ /* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */
retval = dpm->instr_write_data_dcc(dpm, retval = dpm->instr_write_data_dcc(dpm,
ARMV4_5_MRC(14, 0, regnum, 0, 5, 0), ARMV4_5_MRC(14, 0, regnum, 0, 5, 0),
value); value);
break; break;
case 15: /* PC */ case 15:/* PC
/* read r0 from DCC; then "MOV pc, r0" */ * read r0 from DCC; then "MOV pc, r0" */
retval = dpm->instr_write_data_r0(dpm, 0xe1a0f000, value); retval = dpm->instr_write_data_r0(dpm, 0xe1a0f000, value);
break; break;
default: default:
/* 16: read r0 from DCC, then "MSR r0, CPSR_cxsf" /* 16: read r0 from DCC, then "MSR r0, CPSR_cxsf"
* 17: read r0 from DCC, then "MSR r0, SPSR_cxsf" * 17: read r0 from DCC, then "MSR r0, SPSR_cxsf"
*/ */
retval = dpm->instr_write_data_r0(dpm, retval = dpm->instr_write_data_r0(dpm,
ARMV4_5_MSR_GP(0, 0xf, regnum & 1), ARMV4_5_MSR_GP(0, 0xf, regnum & 1),
value); value);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if (regnum == 16 && dpm->instr_cpsr_sync) if (regnum == 16 && dpm->instr_cpsr_sync)
retval = dpm->instr_cpsr_sync(dpm); retval = dpm->instr_cpsr_sync(dpm);
break; break;
} }
if (retval == ERROR_OK) { if (retval == ERROR_OK) {
@ -292,7 +292,7 @@ fail:
* or running debugger code. * or running debugger code.
*/ */
static int dpm_maybe_update_bpwp(struct arm_dpm *dpm, bool bpwp, static int dpm_maybe_update_bpwp(struct arm_dpm *dpm, bool bpwp,
struct dpm_bpwp *xp, int *set_p) struct dpm_bpwp *xp, int *set_p)
{ {
int retval = ERROR_OK; int retval = ERROR_OK;
bool disable; bool disable;
@ -325,10 +325,10 @@ static int dpm_maybe_update_bpwp(struct arm_dpm *dpm, bool bpwp,
if (retval != ERROR_OK) if (retval != ERROR_OK)
LOG_ERROR("%s: can't %s HW %spoint %d", LOG_ERROR("%s: can't %s HW %spoint %d",
disable ? "disable" : "enable", disable ? "disable" : "enable",
target_name(dpm->arm->target), target_name(dpm->arm->target),
(xp->number < 16) ? "break" : "watch", (xp->number < 16) ? "break" : "watch",
xp->number & 0xf); xp->number & 0xf);
done: done:
return retval; return retval;
} }
@ -423,25 +423,24 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp)
/* cope with special cases */ /* cope with special cases */
switch (regnum) { switch (regnum) {
case 8 ... 12: case 8 ... 12:
/* r8..r12 "anything but FIQ" case; /* r8..r12 "anything but FIQ" case;
* we "know" core mode is accurate * we "know" core mode is accurate
* since we haven't changed it yet * since we haven't changed it yet
*/ */
if (arm->core_mode == ARM_MODE_FIQ if (arm->core_mode == ARM_MODE_FIQ
&& ARM_MODE_ANY && ARM_MODE_ANY
!= mode) != mode)
tmode = ARM_MODE_USR; tmode = ARM_MODE_USR;
break; break;
case 16: case 16:
/* SPSR */ /* SPSR */
regnum++; regnum++;
break; break;
} }
/* REVISIT error checks */ /* REVISIT error checks */
if (tmode != ARM_MODE_ANY) if (tmode != ARM_MODE_ANY) {
{
retval = dpm_modeswitch(dpm, tmode); retval = dpm_modeswitch(dpm, tmode);
if (retval != ERROR_OK) if (retval != ERROR_OK)
goto done; goto done;
@ -490,34 +489,34 @@ done:
* or MODE_ANY. * or MODE_ANY.
*/ */
static enum arm_mode dpm_mapmode(struct arm *arm, static enum arm_mode dpm_mapmode(struct arm *arm,
unsigned num, enum arm_mode mode) unsigned num, enum arm_mode mode)
{ {
enum arm_mode amode = arm->core_mode; enum arm_mode amode = arm->core_mode;
/* don't switch if the mode is already correct */ /* don't switch if the mode is already correct */
if (amode == ARM_MODE_SYS) if (amode == ARM_MODE_SYS)
amode = ARM_MODE_USR; amode = ARM_MODE_USR;
if (mode == amode) if (mode == amode)
return ARM_MODE_ANY; return ARM_MODE_ANY;
switch (num) { switch (num) {
/* don't switch for non-shadowed registers (r0..r7, r15/pc, cpsr) */ /* don't switch for non-shadowed registers (r0..r7, r15/pc, cpsr) */
case 0 ... 7: case 0 ... 7:
case 15: case 15:
case 16: case 16:
break; break;
/* r8..r12 aren't shadowed for anything except FIQ */ /* r8..r12 aren't shadowed for anything except FIQ */
case 8 ... 12: case 8 ... 12:
if (mode == ARM_MODE_FIQ) if (mode == ARM_MODE_FIQ)
return mode;
break;
/* r13/sp, and r14/lr are always shadowed */
case 13:
case 14:
return mode; return mode;
break; default:
/* r13/sp, and r14/lr are always shadowed */ LOG_WARNING("invalid register #%u", num);
case 13: break;
case 14:
return mode;
default:
LOG_WARNING("invalid register #%u", num);
break;
} }
return ARM_MODE_ANY; return ARM_MODE_ANY;
} }
@ -530,7 +529,7 @@ static enum arm_mode dpm_mapmode(struct arm *arm,
*/ */
static int arm_dpm_read_core_reg(struct target *target, struct reg *r, static int arm_dpm_read_core_reg(struct target *target, struct reg *r,
int regnum, enum arm_mode mode) int regnum, enum arm_mode mode)
{ {
struct arm_dpm *dpm = target_to_arm(target)->dpm; struct arm_dpm *dpm = target_to_arm(target)->dpm;
int retval; int retval;
@ -572,7 +571,7 @@ fail:
} }
static int arm_dpm_write_core_reg(struct target *target, struct reg *r, static int arm_dpm_write_core_reg(struct target *target, struct reg *r,
int regnum, enum arm_mode mode, uint32_t value) int regnum, enum arm_mode mode, uint32_t value)
{ {
struct arm_dpm *dpm = target_to_arm(target)->dpm; struct arm_dpm *dpm = target_to_arm(target)->dpm;
int retval; int retval;
@ -693,7 +692,7 @@ done:
*/ */
static int dpm_bpwp_setup(struct arm_dpm *dpm, struct dpm_bpwp *xp, static int dpm_bpwp_setup(struct arm_dpm *dpm, struct dpm_bpwp *xp,
uint32_t addr, uint32_t length) uint32_t addr, uint32_t length)
{ {
uint32_t control; uint32_t control;
@ -710,26 +709,26 @@ static int dpm_bpwp_setup(struct arm_dpm *dpm, struct dpm_bpwp *xp,
* v7 hardware, unaligned 4-byte ones too. * v7 hardware, unaligned 4-byte ones too.
*/ */
switch (length) { switch (length) {
case 1: case 1:
control |= (1 << (addr & 3)) << 5; control |= (1 << (addr & 3)) << 5;
break;
case 2:
/* require 2-byte alignment */
if (!(addr & 1)) {
control |= (3 << (addr & 2)) << 5;
break; break;
} case 2:
/* require 2-byte alignment */
if (!(addr & 1)) {
control |= (3 << (addr & 2)) << 5;
break;
}
/* FALL THROUGH */ /* FALL THROUGH */
case 4: case 4:
/* require 4-byte alignment */ /* require 4-byte alignment */
if (!(addr & 3)) { if (!(addr & 3)) {
control |= 0xf << 5; control |= 0xf << 5;
break; break;
} }
/* FALL THROUGH */ /* FALL THROUGH */
default: default:
LOG_ERROR("unsupported {break,watch}point length/alignment"); LOG_ERROR("unsupported {break,watch}point length/alignment");
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
/* other shared control bits: /* other shared control bits:
@ -743,7 +742,7 @@ static int dpm_bpwp_setup(struct arm_dpm *dpm, struct dpm_bpwp *xp,
xp->dirty = true; xp->dirty = true;
LOG_DEBUG("BPWP: addr %8.8" PRIx32 ", control %" PRIx32 ", number %d", LOG_DEBUG("BPWP: addr %8.8" PRIx32 ", control %" PRIx32 ", number %d",
xp->address, control, xp->number); xp->address, control, xp->number);
/* hardware is updated in write_dirty_registers() */ /* hardware is updated in write_dirty_registers() */
return ERROR_OK; return ERROR_OK;
@ -798,7 +797,7 @@ static int dpm_remove_breakpoint(struct target *target, struct breakpoint *bp)
} }
static int dpm_watchpoint_setup(struct arm_dpm *dpm, unsigned index_t, static int dpm_watchpoint_setup(struct arm_dpm *dpm, unsigned index_t,
struct watchpoint *wp) struct watchpoint *wp)
{ {
int retval; int retval;
struct dpm_wp *dwp = dpm->dwp + index_t; struct dpm_wp *dwp = dpm->dwp + index_t;
@ -816,15 +815,15 @@ static int dpm_watchpoint_setup(struct arm_dpm *dpm, unsigned index_t,
control = dwp->bpwp.control; control = dwp->bpwp.control;
switch (wp->rw) { switch (wp->rw) {
case WPT_READ: case WPT_READ:
control |= 1 << 3; control |= 1 << 3;
break; break;
case WPT_WRITE: case WPT_WRITE:
control |= 2 << 3; control |= 2 << 3;
break; break;
case WPT_ACCESS: case WPT_ACCESS:
control |= 3 << 3; control |= 3 << 3;
break; break;
} }
dwp->bpwp.control = control; dwp->bpwp.control = control;
@ -874,16 +873,16 @@ static int dpm_remove_watchpoint(struct target *target, struct watchpoint *wp)
void arm_dpm_report_wfar(struct arm_dpm *dpm, uint32_t addr) void arm_dpm_report_wfar(struct arm_dpm *dpm, uint32_t addr)
{ {
switch (dpm->arm->core_state) { switch (dpm->arm->core_state) {
case ARM_STATE_ARM: case ARM_STATE_ARM:
addr -= 8; addr -= 8;
break; break;
case ARM_STATE_THUMB: case ARM_STATE_THUMB:
case ARM_STATE_THUMB_EE: case ARM_STATE_THUMB_EE:
addr -= 4; addr -= 4;
break; break;
case ARM_STATE_JAZELLE: case ARM_STATE_JAZELLE:
/* ?? */ /* ?? */
break; break;
} }
dpm->wp_pc = addr; dpm->wp_pc = addr;
} }
@ -902,25 +901,25 @@ void arm_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr)
/* Examine debug reason */ /* Examine debug reason */
switch (DSCR_ENTRY(dscr)) { switch (DSCR_ENTRY(dscr)) {
case 6: /* Data abort (v6 only) */ case 6: /* Data abort (v6 only) */
case 7: /* Prefetch abort (v6 only) */ case 7: /* Prefetch abort (v6 only) */
/* FALL THROUGH -- assume a v6 core in abort mode */ /* FALL THROUGH -- assume a v6 core in abort mode */
case 0: /* HALT request from debugger */ case 0: /* HALT request from debugger */
case 4: /* EDBGRQ */ case 4: /* EDBGRQ */
target->debug_reason = DBG_REASON_DBGRQ; target->debug_reason = DBG_REASON_DBGRQ;
break; break;
case 1: /* HW breakpoint */ case 1: /* HW breakpoint */
case 3: /* SW BKPT */ case 3: /* SW BKPT */
case 5: /* vector catch */ case 5: /* vector catch */
target->debug_reason = DBG_REASON_BREAKPOINT; target->debug_reason = DBG_REASON_BREAKPOINT;
break; break;
case 2: /* asynch watchpoint */ case 2: /* asynch watchpoint */
case 10: /* precise watchpoint */ case 10:/* precise watchpoint */
target->debug_reason = DBG_REASON_WATCHPOINT; target->debug_reason = DBG_REASON_WATCHPOINT;
break; break;
default: default:
target->debug_reason = DBG_REASON_UNDEFINED; target->debug_reason = DBG_REASON_UNDEFINED;
break; break;
} }
} }
@ -984,7 +983,7 @@ int arm_dpm_setup(struct arm_dpm *dpm)
} }
LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints", LOG_INFO("%s: hardware has %d breakpoints, %d watchpoints",
target_name(target), dpm->nbp, dpm->nwp); target_name(target), dpm->nbp, dpm->nwp);
/* REVISIT ... and some of those breakpoints could match /* REVISIT ... and some of those breakpoints could match
* execution context IDs... * execution context IDs...

View File

@ -126,7 +126,7 @@ struct arm_dpm {
/** Recent value of DSCR. */ /** Recent value of DSCR. */
uint32_t dscr; uint32_t dscr;
// FIXME -- read/write DCSR methods and symbols /* FIXME -- read/write DCSR methods and symbols */
}; };
int arm_dpm_setup(struct arm_dpm *dpm); int arm_dpm_setup(struct arm_dpm *dpm);

View File

@ -20,18 +20,19 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
#include "arm_jtag.h" #include "arm_jtag.h"
#if 0 #if 0
#define _ARM_JTAG_SCAN_N_CHECK_ #define _ARM_JTAG_SCAN_N_CHECK_
#endif #endif
int arm_jtag_set_instr_inner(struct arm_jtag *jtag_info, uint32_t new_instr, void *no_verify_capture, tap_state_t end_state) int arm_jtag_set_instr_inner(struct arm_jtag *jtag_info,
uint32_t new_instr, void *no_verify_capture, tap_state_t end_state)
{ {
struct jtag_tap *tap; struct jtag_tap *tap;
tap = jtag_info->tap; tap = jtag_info->tap;
@ -44,10 +45,8 @@ int arm_jtag_set_instr_inner(struct arm_jtag *jtag_info, uint32_t new_instr, vo
field.in_value = NULL; field.in_value = NULL;
if (no_verify_capture == NULL) if (no_verify_capture == NULL)
{
jtag_add_ir_scan(tap, &field, end_state); jtag_add_ir_scan(tap, &field, end_state);
} else else {
{
/* FIX!!!! this is a kludge!!! arm926ejs.c should reimplement this arm_jtag_set_instr to /* FIX!!!! this is a kludge!!! arm926ejs.c should reimplement this arm_jtag_set_instr to
* have special verification code. * have special verification code.
*/ */
@ -63,13 +62,12 @@ int arm_jtag_scann_inner(struct arm_jtag *jtag_info, uint32_t new_scan_chain, ta
uint32_t values[1]; uint32_t values[1];
int num_bits[1]; int num_bits[1];
values[0]=new_scan_chain; values[0] = new_scan_chain;
num_bits[0]=jtag_info->scann_size; num_bits[0] = jtag_info->scann_size;
if ((retval = arm_jtag_set_instr(jtag_info, jtag_info->scann_instr, NULL, end_state)) != ERROR_OK) retval = arm_jtag_set_instr(jtag_info, jtag_info->scann_instr, NULL, end_state);
{ if (retval != ERROR_OK)
return retval; return retval;
}
jtag_add_dr_out(jtag_info->tap, jtag_add_dr_out(jtag_info->tap,
1, 1,
@ -87,9 +85,7 @@ static int arm_jtag_reset_callback(enum jtag_event event, void *priv)
struct arm_jtag *jtag_info = priv; struct arm_jtag *jtag_info = priv;
if (event == JTAG_TRST_ASSERTED) if (event == JTAG_TRST_ASSERTED)
{
jtag_info->cur_scan_chain = 0; jtag_info->cur_scan_chain = 0;
}
return ERROR_OK; return ERROR_OK;
} }

View File

@ -20,13 +20,13 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARM_JTAG #ifndef ARM_JTAG
#define ARM_JTAG #define ARM_JTAG
#include <jtag/jtag.h> #include <jtag/jtag.h>
struct arm_jtag struct arm_jtag {
{
struct jtag_tap *tap; struct jtag_tap *tap;
uint32_t scann_size; uint32_t scann_size;
@ -39,53 +39,46 @@ struct arm_jtag
int arm_jtag_set_instr_inner(struct arm_jtag *jtag_info, uint32_t new_instr, int arm_jtag_set_instr_inner(struct arm_jtag *jtag_info, uint32_t new_instr,
void *no_verify_capture, void *no_verify_capture,
tap_state_t end_state); tap_state_t end_state);
static inline int arm_jtag_set_instr(struct arm_jtag *jtag_info, static inline int arm_jtag_set_instr(struct arm_jtag *jtag_info,
uint32_t new_instr, void *no_verify_capture, tap_state_t end_state) uint32_t new_instr, void *no_verify_capture, tap_state_t end_state)
{ {
/* inline most common code path */ /* inline most common code path */
struct jtag_tap *tap; struct jtag_tap *tap;
tap = jtag_info->tap; tap = jtag_info->tap;
assert (tap != NULL); assert(tap != NULL);
if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr)
{
return arm_jtag_set_instr_inner(jtag_info, new_instr, no_verify_capture, end_state); return arm_jtag_set_instr_inner(jtag_info, new_instr, no_verify_capture, end_state);
}
return ERROR_OK; return ERROR_OK;
} }
int arm_jtag_scann_inner(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state); int arm_jtag_scann_inner(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state);
static inline int arm_jtag_scann(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state) static inline int arm_jtag_scann(struct arm_jtag *jtag_info, uint32_t new_scan_chain, tap_state_t end_state)
{ {
/* inline most common code path */ /* inline most common code path */
int retval = ERROR_OK; int retval = ERROR_OK;
if (jtag_info->cur_scan_chain != new_scan_chain) if (jtag_info->cur_scan_chain != new_scan_chain)
{
return arm_jtag_scann_inner(jtag_info, new_scan_chain, end_state); return arm_jtag_scann_inner(jtag_info, new_scan_chain, end_state);
}
return retval; return retval;
} }
int arm_jtag_setup_connection(struct arm_jtag *jtag_info); int arm_jtag_setup_connection(struct arm_jtag *jtag_info);
/* use this as a static so we can inline it in -O3 and refer to it via a pointer */ /* use this as a static so we can inline it in -O3 and refer to it via a pointer */
static __inline__ void arm7flip32(jtag_callback_data_t arg) static inline void arm7flip32(jtag_callback_data_t arg)
{ {
uint8_t *in = (uint8_t *)arg; uint8_t *in = (uint8_t *)arg;
*((uint32_t *)arg) = flip_u32(le_to_h_u32(in), 32); *((uint32_t *)arg) = flip_u32(le_to_h_u32(in), 32);
} }
static __inline__ void arm_le_to_h_u32(jtag_callback_data_t arg) static inline void arm_le_to_h_u32(jtag_callback_data_t arg)
{ {
uint8_t *in = (uint8_t *)arg; uint8_t *in = (uint8_t *)arg;
*((uint32_t *)arg) = le_to_h_u32(in); *((uint32_t *)arg) = le_to_h_u32(in);
} }
#endif /* ARM_JTAG */ #endif /* ARM_JTAG */

View File

@ -90,8 +90,8 @@
* Rd: register to load * Rd: register to load
* Rn: base register * Rn: base register
*/ */
#define ARMV4_5_LDRW_IP(Rd, Rn) (0xe4900004 | ((Rd) << 12) | ((Rn) << 16)) #define ARMV4_5_LDRW_IP(Rd, Rn) (0xe4900004 | ((Rd) << 12) | ((Rn) << 16))
/* Load Register Halfword Immediate Post-Index /* Load Register Halfword Immediate Post-Index
* Rd: register to load * Rd: register to load
* Rn: base register * Rn: base register
@ -108,7 +108,7 @@
* Rd: register to store * Rd: register to store
* Rn: base register * Rn: base register
*/ */
#define ARMV4_5_STRW_IP(Rd, Rn) (0xe4800004 | ((Rd) << 12) | ((Rn) << 16)) #define ARMV4_5_STRW_IP(Rd, Rn) (0xe4800004 | ((Rd) << 12) | ((Rn) << 16))
/* Store register Halfword Immediate Post-Index /* Store register Halfword Immediate Post-Index
* Rd: register to store * Rd: register to store

View File

@ -323,7 +323,7 @@ static int do_semihosting(struct target *target)
if (l < s) if (l < s)
result = -1; result = -1;
else { else {
retval = target_write_buffer(target, a, s, (void*)arg); retval = target_write_buffer(target, a, s, (void *)arg);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
result = 0; result = 0;
@ -392,8 +392,7 @@ static int do_semihosting(struct target *target)
/* REVISIT this looks wrong ... ARM11 and Cortex-A8 /* REVISIT this looks wrong ... ARM11 and Cortex-A8
* should work this way at least sometimes. * should work this way at least sometimes.
*/ */
if (is_arm7_9(target_to_arm7_9(target))) if (is_arm7_9(target_to_arm7_9(target))) {
{
uint32_t spsr; uint32_t spsr;
/* return value in R0 */ /* return value in R0 */
@ -402,7 +401,7 @@ static int do_semihosting(struct target *target)
/* LR --> PC */ /* LR --> PC */
buf_set_u32(arm->core_cache->reg_list[15].value, 0, 32, buf_set_u32(arm->core_cache->reg_list[15].value, 0, 32,
buf_get_u32(arm_reg_current(arm,14)->value, 0, 32)); buf_get_u32(arm_reg_current(arm, 14)->value, 0, 32));
arm->core_cache->reg_list[15].dirty = 1; arm->core_cache->reg_list[15].dirty = 1;
/* saved PSR --> current PSR */ /* saved PSR --> current PSR */
@ -418,9 +417,7 @@ static int do_semihosting(struct target *target)
if (spsr & 0x20) if (spsr & 0x20)
arm->core_state = ARM_STATE_THUMB; arm->core_state = ARM_STATE_THUMB;
} } else {
else
{
/* resume execution, this will be pc+2 to skip over the /* resume execution, this will be pc+2 to skip over the
* bkpt instruction */ * bkpt instruction */
@ -454,8 +451,7 @@ int arm_semihosting(struct target *target, int *retval)
if (!arm->is_semihosting) if (!arm->is_semihosting)
return 0; return 0;
if (is_arm7_9(target_to_arm7_9(target))) if (is_arm7_9(target_to_arm7_9(target))) {
{
if (arm->core_mode != ARM_MODE_SVC) if (arm->core_mode != ARM_MODE_SVC)
return 0; return 0;
@ -510,9 +506,7 @@ int arm_semihosting(struct target *target, int *retval)
if (insn != 0xEF123456) if (insn != 0xEF123456)
return 0; return 0;
} }
} } else if (is_armv7m(target_to_armv7m(target))) {
else if (is_armv7m(target_to_armv7m(target)))
{
uint16_t insn; uint16_t insn;
if (target->debug_reason != DBG_REASON_BREAKPOINT) if (target->debug_reason != DBG_REASON_BREAKPOINT)
@ -529,9 +523,7 @@ int arm_semihosting(struct target *target, int *retval)
/* bkpt 0xAB */ /* bkpt 0xAB */
if (insn != 0xBEAB) if (insn != 0xBEAB)
return 0; return 0;
} } else {
else
{
LOG_ERROR("Unsupported semi-hosting Target"); LOG_ERROR("Unsupported semi-hosting Target");
return 0; return 0;
} }

View File

@ -20,6 +20,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -32,51 +33,32 @@
#include "register.h" #include "register.h"
#include <helper/log.h> #include <helper/log.h>
static uint32_t arm_shift(uint8_t shift, uint32_t Rm, static uint32_t arm_shift(uint8_t shift, uint32_t Rm,
uint32_t shift_amount, uint8_t *carry) uint32_t shift_amount, uint8_t *carry)
{ {
uint32_t return_value = 0; uint32_t return_value = 0;
shift_amount &= 0xff; shift_amount &= 0xff;
if (shift == 0x0) /* LSL */ if (shift == 0x0) { /* LSL */
{ if ((shift_amount > 0) && (shift_amount <= 32)) {
if ((shift_amount > 0) && (shift_amount <= 32))
{
return_value = Rm << shift_amount; return_value = Rm << shift_amount;
*carry = Rm >> (32 - shift_amount); *carry = Rm >> (32 - shift_amount);
} } else if (shift_amount > 32) {
else if (shift_amount > 32)
{
return_value = 0x0; return_value = 0x0;
*carry = 0x0; *carry = 0x0;
} } else /* (shift_amount == 0) */
else /* (shift_amount == 0) */
{
return_value = Rm; return_value = Rm;
} } else if (shift == 0x1) { /* LSR */
} if ((shift_amount > 0) && (shift_amount <= 32)) {
else if (shift == 0x1) /* LSR */
{
if ((shift_amount > 0) && (shift_amount <= 32))
{
return_value = Rm >> shift_amount; return_value = Rm >> shift_amount;
*carry = (Rm >> (shift_amount - 1)) & 1; *carry = (Rm >> (shift_amount - 1)) & 1;
} } else if (shift_amount > 32) {
else if (shift_amount > 32)
{
return_value = 0x0; return_value = 0x0;
*carry = 0x0; *carry = 0x0;
} } else /* (shift_amount == 0) */
else /* (shift_amount == 0) */
{
return_value = Rm; return_value = Rm;
} } else if (shift == 0x2) { /* ASR */
} if ((shift_amount > 0) && (shift_amount <= 32)) {
else if (shift == 0x2) /* ASR */
{
if ((shift_amount > 0) && (shift_amount <= 32))
{
/* C right shifts of unsigned values are guaranteed to /* C right shifts of unsigned values are guaranteed to
* be logical (shift in zeroes); simulate an arithmetic * be logical (shift in zeroes); simulate an arithmetic
* shift (shift in signed-bit) by adding the sign bit * shift (shift in signed-bit) by adding the sign bit
@ -85,40 +67,25 @@ static uint32_t arm_shift(uint8_t shift, uint32_t Rm,
return_value = Rm >> shift_amount; return_value = Rm >> shift_amount;
if (Rm & 0x80000000) if (Rm & 0x80000000)
return_value |= 0xffffffff << (32 - shift_amount); return_value |= 0xffffffff << (32 - shift_amount);
} } else if (shift_amount > 32) {
else if (shift_amount > 32) if (Rm & 0x80000000) {
{
if (Rm & 0x80000000)
{
return_value = 0xffffffff; return_value = 0xffffffff;
*carry = 0x1; *carry = 0x1;
} } else {
else
{
return_value = 0x0; return_value = 0x0;
*carry = 0x0; *carry = 0x0;
} }
} } else /* (shift_amount == 0) */
else /* (shift_amount == 0) */
{
return_value = Rm; return_value = Rm;
} } else if (shift == 0x3) { /* ROR */
}
else if (shift == 0x3) /* ROR */
{
if (shift_amount == 0) if (shift_amount == 0)
{
return_value = Rm; return_value = Rm;
} else {
else
{
shift_amount = shift_amount % 32; shift_amount = shift_amount % 32;
return_value = (Rm >> shift_amount) | (Rm << (32 - shift_amount)); return_value = (Rm >> shift_amount) | (Rm << (32 - shift_amount));
*carry = (return_value >> 31) & 0x1; *carry = (return_value >> 31) & 0x1;
} }
} } else if (shift == 0x4) { /* RRX */
else if (shift == 0x4) /* RRX */
{
return_value = Rm >> 1; return_value = Rm >> 1;
if (*carry) if (*carry)
Rm |= 0x80000000; Rm |= 0x80000000;
@ -130,8 +97,8 @@ static uint32_t arm_shift(uint8_t shift, uint32_t Rm,
static uint32_t arm_shifter_operand(struct arm_sim_interface *sim, static uint32_t arm_shifter_operand(struct arm_sim_interface *sim,
int variant, union arm_shifter_operand shifter_operand, int variant, union arm_shifter_operand shifter_operand,
uint8_t *shifter_carry_out) uint8_t *shifter_carry_out)
{ {
uint32_t return_value; uint32_t return_value;
int instruction_size; int instruction_size;
@ -144,11 +111,8 @@ static uint32_t arm_shifter_operand(struct arm_sim_interface *sim,
*shifter_carry_out = sim->get_cpsr(sim, 29, 1); *shifter_carry_out = sim->get_cpsr(sim, 29, 1);
if (variant == 0) /* 32-bit immediate */ if (variant == 0) /* 32-bit immediate */
{
return_value = shifter_operand.immediate.immediate; return_value = shifter_operand.immediate.immediate;
} else if (variant == 1) {/* immediate shift */
else if (variant == 1) /* immediate shift */
{
uint32_t Rm = sim->get_reg_mode(sim, shifter_operand.immediate_shift.Rm); uint32_t Rm = sim->get_reg_mode(sim, shifter_operand.immediate_shift.Rm);
/* adjust RM in case the PC is being read */ /* adjust RM in case the PC is being read */
@ -158,9 +122,7 @@ static uint32_t arm_shifter_operand(struct arm_sim_interface *sim,
return_value = arm_shift(shifter_operand.immediate_shift.shift, return_value = arm_shift(shifter_operand.immediate_shift.shift,
Rm, shifter_operand.immediate_shift.shift_imm, Rm, shifter_operand.immediate_shift.shift_imm,
shifter_carry_out); shifter_carry_out);
} } else if (variant == 2) { /* register shift */
else if (variant == 2) /* register shift */
{
uint32_t Rm = sim->get_reg_mode(sim, shifter_operand.register_shift.Rm); uint32_t Rm = sim->get_reg_mode(sim, shifter_operand.register_shift.Rm);
uint32_t Rs = sim->get_reg_mode(sim, shifter_operand.register_shift.Rs); uint32_t Rs = sim->get_reg_mode(sim, shifter_operand.register_shift.Rs);
@ -170,9 +132,7 @@ static uint32_t arm_shifter_operand(struct arm_sim_interface *sim,
return_value = arm_shift(shifter_operand.immediate_shift.shift, return_value = arm_shift(shifter_operand.immediate_shift.shift,
Rm, Rs, shifter_carry_out); Rm, Rs, shifter_carry_out);
} } else {
else
{
LOG_ERROR("BUG: shifter_operand.variant not 0, 1 or 2"); LOG_ERROR("BUG: shifter_operand.variant not 0, 1 or 2");
return_value = 0xffffffff; return_value = 0xffffffff;
} }
@ -182,8 +142,7 @@ static uint32_t arm_shifter_operand(struct arm_sim_interface *sim,
static int pass_condition(uint32_t cpsr, uint32_t opcode) static int pass_condition(uint32_t cpsr, uint32_t opcode)
{ {
switch ((opcode & 0xf0000000) >> 28) switch ((opcode & 0xf0000000) >> 28) {
{
case 0x0: /* EQ */ case 0x0: /* EQ */
if (cpsr & 0x40000000) if (cpsr & 0x40000000)
return 1; return 1;
@ -280,45 +239,35 @@ static int thumb_pass_branch_condition(uint32_t cpsr, uint16_t opcode)
* but the new pc is stored in the variable pointed at by the argument * but the new pc is stored in the variable pointed at by the argument
*/ */
static int arm_simulate_step_core(struct target *target, static int arm_simulate_step_core(struct target *target,
uint32_t *dry_run_pc, struct arm_sim_interface *sim) uint32_t *dry_run_pc, struct arm_sim_interface *sim)
{ {
uint32_t current_pc = sim->get_reg(sim, 15); uint32_t current_pc = sim->get_reg(sim, 15);
struct arm_instruction instruction; struct arm_instruction instruction;
int instruction_size; int instruction_size;
int retval = ERROR_OK; int retval = ERROR_OK;
if (sim->get_state(sim) == ARM_STATE_ARM) if (sim->get_state(sim) == ARM_STATE_ARM) {
{
uint32_t opcode; uint32_t opcode;
/* get current instruction, and identify it */ /* get current instruction, and identify it */
if ((retval = target_read_u32(target, current_pc, &opcode)) != ERROR_OK) retval = target_read_u32(target, current_pc, &opcode);
{ if (retval != ERROR_OK)
return retval; return retval;
} retval = arm_evaluate_opcode(opcode, current_pc, &instruction);
if ((retval = arm_evaluate_opcode(opcode, current_pc, &instruction)) != ERROR_OK) if (retval != ERROR_OK)
{
return retval; return retval;
}
instruction_size = 4; instruction_size = 4;
/* check condition code (for all instructions) */ /* check condition code (for all instructions) */
if (!pass_condition(sim->get_cpsr(sim, 0, 32), opcode)) if (!pass_condition(sim->get_cpsr(sim, 0, 32), opcode)) {
{
if (dry_run_pc) if (dry_run_pc)
{
*dry_run_pc = current_pc + instruction_size; *dry_run_pc = current_pc + instruction_size;
}
else else
{
sim->set_reg(sim, 15, current_pc + instruction_size); sim->set_reg(sim, 15, current_pc + instruction_size);
}
return ERROR_OK; return ERROR_OK;
} }
} } else {
else
{
uint16_t opcode; uint16_t opcode;
retval = target_read_u16(target, current_pc, &opcode); retval = target_read_u16(target, current_pc, &opcode);
@ -331,17 +280,12 @@ static int arm_simulate_step_core(struct target *target,
/* check condition code (only for branch (1) instructions) */ /* check condition code (only for branch (1) instructions) */
if ((opcode & 0xf000) == 0xd000 if ((opcode & 0xf000) == 0xd000
&& !thumb_pass_branch_condition( && !thumb_pass_branch_condition(
sim->get_cpsr(sim, 0, 32), opcode)) sim->get_cpsr(sim, 0, 32), opcode)) {
{
if (dry_run_pc) if (dry_run_pc)
{
*dry_run_pc = current_pc + instruction_size; *dry_run_pc = current_pc + instruction_size;
}
else else
{
sim->set_reg(sim, 15, current_pc + instruction_size); sim->set_reg(sim, 15, current_pc + instruction_size);
}
return ERROR_OK; return ERROR_OK;
} }
@ -362,67 +306,44 @@ static int arm_simulate_step_core(struct target *target,
/* examine instruction type */ /* examine instruction type */
/* branch instructions */ /* branch instructions */
if ((instruction.type >= ARM_B) && (instruction.type <= ARM_BLX)) if ((instruction.type >= ARM_B) && (instruction.type <= ARM_BLX)) {
{
uint32_t target_address; uint32_t target_address;
if (instruction.info.b_bl_bx_blx.reg_operand == -1) if (instruction.info.b_bl_bx_blx.reg_operand == -1)
{
target_address = instruction.info.b_bl_bx_blx.target_address; target_address = instruction.info.b_bl_bx_blx.target_address;
} else {
else target_address = sim->get_reg_mode(sim,
{ instruction.info.b_bl_bx_blx.reg_operand);
target_address = sim->get_reg_mode(sim, instruction.info.b_bl_bx_blx.reg_operand);
if (instruction.info.b_bl_bx_blx.reg_operand == 15) if (instruction.info.b_bl_bx_blx.reg_operand == 15)
{
target_address += 2 * instruction_size; target_address += 2 * instruction_size;
}
} }
if (dry_run_pc) if (dry_run_pc) {
{
*dry_run_pc = target_address & ~1; *dry_run_pc = target_address & ~1;
return ERROR_OK; return ERROR_OK;
} } else {
else
{
if (instruction.type == ARM_B) if (instruction.type == ARM_B)
{
sim->set_reg(sim, 15, target_address); sim->set_reg(sim, 15, target_address);
} else if (instruction.type == ARM_BL) {
else if (instruction.type == ARM_BL)
{
uint32_t old_pc = sim->get_reg(sim, 15); uint32_t old_pc = sim->get_reg(sim, 15);
int T = (sim->get_state(sim) == ARM_STATE_THUMB); int T = (sim->get_state(sim) == ARM_STATE_THUMB);
sim->set_reg_mode(sim, 14, old_pc + 4 + T); sim->set_reg_mode(sim, 14, old_pc + 4 + T);
sim->set_reg(sim, 15, target_address); sim->set_reg(sim, 15, target_address);
} } else if (instruction.type == ARM_BX) {
else if (instruction.type == ARM_BX)
{
if (target_address & 0x1) if (target_address & 0x1)
{
sim->set_state(sim, ARM_STATE_THUMB); sim->set_state(sim, ARM_STATE_THUMB);
}
else else
{
sim->set_state(sim, ARM_STATE_ARM); sim->set_state(sim, ARM_STATE_ARM);
}
sim->set_reg(sim, 15, target_address & 0xfffffffe); sim->set_reg(sim, 15, target_address & 0xfffffffe);
} } else if (instruction.type == ARM_BLX) {
else if (instruction.type == ARM_BLX)
{
uint32_t old_pc = sim->get_reg(sim, 15); uint32_t old_pc = sim->get_reg(sim, 15);
int T = (sim->get_state(sim) == ARM_STATE_THUMB); int T = (sim->get_state(sim) == ARM_STATE_THUMB);
sim->set_reg_mode(sim, 14, old_pc + 4 + T); sim->set_reg_mode(sim, 14, old_pc + 4 + T);
if (target_address & 0x1) if (target_address & 0x1)
{
sim->set_state(sim, ARM_STATE_THUMB); sim->set_state(sim, ARM_STATE_THUMB);
}
else else
{
sim->set_state(sim, ARM_STATE_ARM); sim->set_state(sim, ARM_STATE_ARM);
}
sim->set_reg(sim, 15, target_address & 0xfffffffe); sim->set_reg(sim, 15, target_address & 0xfffffffe);
} }
@ -431,8 +352,7 @@ static int arm_simulate_step_core(struct target *target,
} }
/* data processing instructions, except compare instructions (CMP, CMN, TST, TEQ) */ /* data processing instructions, except compare instructions (CMP, CMN, TST, TEQ) */
else if (((instruction.type >= ARM_AND) && (instruction.type <= ARM_RSC)) else if (((instruction.type >= ARM_AND) && (instruction.type <= ARM_RSC))
|| ((instruction.type >= ARM_ORR) && (instruction.type <= ARM_MVN))) || ((instruction.type >= ARM_ORR) && (instruction.type <= ARM_MVN))) {
{
uint32_t Rd, Rn, shifter_operand; uint32_t Rd, Rn, shifter_operand;
uint8_t C = sim->get_cpsr(sim, 29, 1); uint8_t C = sim->get_cpsr(sim, 29, 1);
uint8_t carry_out; uint8_t carry_out;
@ -480,17 +400,14 @@ static int arm_simulate_step_core(struct target *target,
else else
LOG_WARNING("unhandled instruction type"); LOG_WARNING("unhandled instruction type");
if (dry_run_pc) if (dry_run_pc) {
{
if (instruction.info.data_proc.Rd == 15) if (instruction.info.data_proc.Rd == 15)
*dry_run_pc = Rd & ~1; *dry_run_pc = Rd & ~1;
else else
*dry_run_pc = current_pc + instruction_size; *dry_run_pc = current_pc + instruction_size;
return ERROR_OK; return ERROR_OK;
} } else {
else
{
if (instruction.info.data_proc.Rd == 15) { if (instruction.info.data_proc.Rd == 15) {
sim->set_reg_mode(sim, 15, Rd & ~1); sim->set_reg_mode(sim, 15, Rd & ~1);
if (Rd & 1) if (Rd & 1)
@ -504,21 +421,15 @@ static int arm_simulate_step_core(struct target *target,
} }
} }
/* compare instructions (CMP, CMN, TST, TEQ) */ /* compare instructions (CMP, CMN, TST, TEQ) */
else if ((instruction.type >= ARM_TST) && (instruction.type <= ARM_CMN)) else if ((instruction.type >= ARM_TST) && (instruction.type <= ARM_CMN)) {
{ if (dry_run_pc) {
if (dry_run_pc)
{
*dry_run_pc = current_pc + instruction_size; *dry_run_pc = current_pc + instruction_size;
return ERROR_OK; return ERROR_OK;
} } else
else
{
LOG_WARNING("no updating of flags yet"); LOG_WARNING("no updating of flags yet");
}
} }
/* load register instructions */ /* load register instructions */
else if ((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDRSH)) else if ((instruction.type >= ARM_LDR) && (instruction.type <= ARM_LDRSH)) {
{
uint32_t load_address = 0, modified_address = 0, load_value = 0; uint32_t load_address = 0, modified_address = 0, load_value = 0;
uint32_t Rn = sim->get_reg_mode(sim, instruction.info.load_store.Rn); uint32_t Rn = sim->get_reg_mode(sim, instruction.info.load_store.Rn);
@ -526,15 +437,12 @@ static int arm_simulate_step_core(struct target *target,
if (instruction.info.load_store.Rn == 15) if (instruction.info.load_store.Rn == 15)
Rn += 2 * instruction_size; Rn += 2 * instruction_size;
if (instruction.info.load_store.offset_mode == 0) if (instruction.info.load_store.offset_mode == 0) {
{
if (instruction.info.load_store.U) if (instruction.info.load_store.U)
modified_address = Rn + instruction.info.load_store.offset.offset; modified_address = Rn + instruction.info.load_store.offset.offset;
else else
modified_address = Rn - instruction.info.load_store.offset.offset; modified_address = Rn - instruction.info.load_store.offset.offset;
} } else if (instruction.info.load_store.offset_mode == 1) {
else if (instruction.info.load_store.offset_mode == 1)
{
uint32_t offset; uint32_t offset;
uint32_t Rm = sim->get_reg_mode(sim, uint32_t Rm = sim->get_reg_mode(sim,
instruction.info.load_store.offset.reg.Rm); instruction.info.load_store.offset.reg.Rm);
@ -548,31 +456,23 @@ static int arm_simulate_step_core(struct target *target,
modified_address = Rn + offset; modified_address = Rn + offset;
else else
modified_address = Rn - offset; modified_address = Rn - offset;
} } else
else
{
LOG_ERROR("BUG: offset_mode neither 0 (offset) nor 1 (scaled register)"); LOG_ERROR("BUG: offset_mode neither 0 (offset) nor 1 (scaled register)");
}
if (instruction.info.load_store.index_mode == 0) if (instruction.info.load_store.index_mode == 0) {
{
/* offset mode /* offset mode
* we load from the modified address, but don't change * we load from the modified address, but don't change
* the base address register * the base address register
*/ */
load_address = modified_address; load_address = modified_address;
modified_address = Rn; modified_address = Rn;
} } else if (instruction.info.load_store.index_mode == 1) {
else if (instruction.info.load_store.index_mode == 1)
{
/* pre-indexed mode /* pre-indexed mode
* we load from the modified address, and write it * we load from the modified address, and write it
* back to the base address register * back to the base address register
*/ */
load_address = modified_address; load_address = modified_address;
} } else if (instruction.info.load_store.index_mode == 2) {
else if (instruction.info.load_store.index_mode == 2)
{
/* post-indexed mode /* post-indexed mode
* we load from the unmodified address, and write the * we load from the unmodified address, and write the
* modified address back * modified address back
@ -580,28 +480,24 @@ static int arm_simulate_step_core(struct target *target,
load_address = Rn; load_address = Rn;
} }
if ((!dry_run_pc) || (instruction.info.load_store.Rd == 15)) if ((!dry_run_pc) || (instruction.info.load_store.Rd == 15)) {
{
retval = target_read_u32(target, load_address, &load_value); retval = target_read_u32(target, load_address, &load_value);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
} }
if (dry_run_pc) if (dry_run_pc) {
{
if (instruction.info.load_store.Rd == 15) if (instruction.info.load_store.Rd == 15)
*dry_run_pc = load_value & ~1; *dry_run_pc = load_value & ~1;
else else
*dry_run_pc = current_pc + instruction_size; *dry_run_pc = current_pc + instruction_size;
return ERROR_OK; return ERROR_OK;
} } else {
else
{
if ((instruction.info.load_store.index_mode == 1) || if ((instruction.info.load_store.index_mode == 1) ||
(instruction.info.load_store.index_mode == 2)) (instruction.info.load_store.index_mode == 2))
{ sim->set_reg_mode(sim,
sim->set_reg_mode(sim, instruction.info.load_store.Rn, modified_address); instruction.info.load_store.Rn,
} modified_address);
if (instruction.info.load_store.Rd == 15) { if (instruction.info.load_store.Rd == 15) {
sim->set_reg_mode(sim, 15, load_value & ~1); sim->set_reg_mode(sim, 15, load_value & ~1);
@ -615,84 +511,68 @@ static int arm_simulate_step_core(struct target *target,
} }
} }
/* load multiple instruction */ /* load multiple instruction */
else if (instruction.type == ARM_LDM) else if (instruction.type == ARM_LDM) {
{
int i; int i;
uint32_t Rn = sim->get_reg_mode(sim, instruction.info.load_store_multiple.Rn); uint32_t Rn = sim->get_reg_mode(sim, instruction.info.load_store_multiple.Rn);
uint32_t load_values[16]; uint32_t load_values[16];
int bits_set = 0; int bits_set = 0;
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++) {
{
if (instruction.info.load_store_multiple.register_list & (1 << i)) if (instruction.info.load_store_multiple.register_list & (1 << i))
bits_set++; bits_set++;
} }
switch (instruction.info.load_store_multiple.addressing_mode) switch (instruction.info.load_store_multiple.addressing_mode) {
{ case 0: /* Increment after */
case 0: /* Increment after */
Rn = Rn; Rn = Rn;
break; break;
case 1: /* Increment before */ case 1: /* Increment before */
Rn = Rn + 4; Rn = Rn + 4;
break; break;
case 2: /* Decrement after */ case 2: /* Decrement after */
Rn = Rn - (bits_set * 4) + 4; Rn = Rn - (bits_set * 4) + 4;
break; break;
case 3: /* Decrement before */ case 3: /* Decrement before */
Rn = Rn - (bits_set * 4); Rn = Rn - (bits_set * 4);
break; break;
} }
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++) {
{ if (instruction.info.load_store_multiple.register_list & (1 << i)) {
if (instruction.info.load_store_multiple.register_list & (1 << i))
{
if ((!dry_run_pc) || (i == 15)) if ((!dry_run_pc) || (i == 15))
{
target_read_u32(target, Rn, &load_values[i]); target_read_u32(target, Rn, &load_values[i]);
}
Rn += 4; Rn += 4;
} }
} }
if (dry_run_pc) if (dry_run_pc) {
{ if (instruction.info.load_store_multiple.register_list & 0x8000) {
if (instruction.info.load_store_multiple.register_list & 0x8000)
{
*dry_run_pc = load_values[15] & ~1; *dry_run_pc = load_values[15] & ~1;
return ERROR_OK; return ERROR_OK;
} }
} } else {
else
{
int update_cpsr = 0; int update_cpsr = 0;
if (instruction.info.load_store_multiple.S) if (instruction.info.load_store_multiple.S) {
{
if (instruction.info.load_store_multiple.register_list & 0x8000) if (instruction.info.load_store_multiple.register_list & 0x8000)
update_cpsr = 1; update_cpsr = 1;
} }
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++) {
{ if (instruction.info.load_store_multiple.register_list & (1 << i)) {
if (instruction.info.load_store_multiple.register_list & (1 << i))
{
if (i == 15) { if (i == 15) {
uint32_t val = load_values[i]; uint32_t val = load_values[i];
sim->set_reg_mode(sim, i, val & ~1); sim->set_reg_mode(sim, i, val & ~1);
if (val & 1) if (val & 1)
sim->set_state(sim, ARM_STATE_THUMB); sim->set_state(sim, ARM_STATE_THUMB);
else else
sim->set_state(sim, ARM_STATE_ARM); sim->set_state(sim, ARM_STATE_ARM);
} else { } else
sim->set_reg_mode(sim, i, load_values[i]); sim->set_reg_mode(sim, i, load_values[i]);
}
} }
} }
if (update_cpsr) if (update_cpsr) {
{
uint32_t spsr = sim->get_reg_mode(sim, 16); uint32_t spsr = sim->get_reg_mode(sim, 16);
sim->set_reg(sim, ARMV4_5_CPSR, spsr); sim->set_reg(sim, ARMV4_5_CPSR, spsr);
} }
@ -701,51 +581,44 @@ static int arm_simulate_step_core(struct target *target,
if (instruction.info.load_store_multiple.W) if (instruction.info.load_store_multiple.W)
sim->set_reg_mode(sim, instruction.info.load_store_multiple.Rn, Rn); sim->set_reg_mode(sim, instruction.info.load_store_multiple.Rn, Rn);
if (instruction.info.load_store_multiple.register_list & 0x8000) if (instruction.info.load_store_multiple.register_list & 0x8000)
return ERROR_OK; return ERROR_OK;
} }
} }
/* store multiple instruction */ /* store multiple instruction */
else if (instruction.type == ARM_STM) else if (instruction.type == ARM_STM) {
{
int i; int i;
if (dry_run_pc) if (dry_run_pc) {
{
/* STM wont affect PC (advance by instruction size */ /* STM wont affect PC (advance by instruction size */
} } else {
else
{
uint32_t Rn = sim->get_reg_mode(sim, uint32_t Rn = sim->get_reg_mode(sim,
instruction.info.load_store_multiple.Rn); instruction.info.load_store_multiple.Rn);
int bits_set = 0; int bits_set = 0;
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++) {
{
if (instruction.info.load_store_multiple.register_list & (1 << i)) if (instruction.info.load_store_multiple.register_list & (1 << i))
bits_set++; bits_set++;
} }
switch (instruction.info.load_store_multiple.addressing_mode) switch (instruction.info.load_store_multiple.addressing_mode) {
{ case 0: /* Increment after */
case 0: /* Increment after */
Rn = Rn; Rn = Rn;
break; break;
case 1: /* Increment before */ case 1: /* Increment before */
Rn = Rn + 4; Rn = Rn + 4;
break; break;
case 2: /* Decrement after */ case 2: /* Decrement after */
Rn = Rn - (bits_set * 4) + 4; Rn = Rn - (bits_set * 4) + 4;
break; break;
case 3: /* Decrement before */ case 3: /* Decrement before */
Rn = Rn - (bits_set * 4); Rn = Rn - (bits_set * 4);
break; break;
} }
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++) {
{ if (instruction.info.load_store_multiple.register_list & (1 << i)) {
if (instruction.info.load_store_multiple.register_list & (1 << i))
{
target_write_u32(target, Rn, sim->get_reg_mode(sim, i)); target_write_u32(target, Rn, sim->get_reg_mode(sim, i));
Rn += 4; Rn += 4;
} }
@ -757,22 +630,17 @@ static int arm_simulate_step_core(struct target *target,
instruction.info.load_store_multiple.Rn, Rn); instruction.info.load_store_multiple.Rn, Rn);
} }
} } else if (!dry_run_pc) {
else if (!dry_run_pc)
{
/* the instruction wasn't handled, but we're supposed to simulate it /* the instruction wasn't handled, but we're supposed to simulate it
*/ */
LOG_ERROR("Unimplemented instruction, could not simulate it."); LOG_ERROR("Unimplemented instruction, could not simulate it.");
return ERROR_FAIL; return ERROR_FAIL;
} }
if (dry_run_pc) if (dry_run_pc) {
{
*dry_run_pc = current_pc + instruction_size; *dry_run_pc = current_pc + instruction_size;
return ERROR_OK; return ERROR_OK;
} } else {
else
{
sim->set_reg(sim, 15, current_pc + instruction_size); sim->set_reg(sim, 15, current_pc + instruction_size);
return ERROR_OK; return ERROR_OK;
} }
@ -806,7 +674,7 @@ static void armv4_5_set_reg_mode(struct arm_sim_interface *sim, int reg, uint32_
struct arm *arm = (struct arm *)sim->user_data; struct arm *arm = (struct arm *)sim->user_data;
buf_set_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache, buf_set_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache,
arm->core_mode, reg).value, 0, 32, value); arm->core_mode, reg).value, 0, 32, value);
} }
static uint32_t armv4_5_get_cpsr(struct arm_sim_interface *sim, int pos, int bits) static uint32_t armv4_5_get_cpsr(struct arm_sim_interface *sim, int pos, int bits)
@ -830,7 +698,6 @@ static void armv4_5_set_state(struct arm_sim_interface *sim, enum arm_state mode
arm->core_state = mode; arm->core_state = mode;
} }
static enum arm_mode armv4_5_get_mode(struct arm_sim_interface *sim) static enum arm_mode armv4_5_get_mode(struct arm_sim_interface *sim)
{ {
struct arm *arm = (struct arm *)sim->user_data; struct arm *arm = (struct arm *)sim->user_data;
@ -838,8 +705,6 @@ static enum arm_mode armv4_5_get_mode(struct arm_sim_interface *sim)
return arm->core_mode; return arm->core_mode;
} }
int arm_simulate_step(struct target *target, uint32_t *dry_run_pc) int arm_simulate_step(struct target *target, uint32_t *dry_run_pc)
{ {
struct arm *arm = target_to_arm(target); struct arm *arm = target_to_arm(target);
@ -857,4 +722,3 @@ int arm_simulate_step(struct target *target, uint32_t *dry_run_pc)
return arm_simulate_step_core(target, dry_run_pc, &sim); return arm_simulate_step_core(target, dry_run_pc, &sim);
} }

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARM_SIMULATOR_H #ifndef ARM_SIMULATOR_H
#define ARM_SIMULATOR_H #define ARM_SIMULATOR_H
@ -24,8 +25,7 @@
struct target; struct target;
struct arm_sim_interface struct arm_sim_interface {
{
void *user_data; void *user_data;
uint32_t (*get_reg)(struct arm_sim_interface *sim, int reg); uint32_t (*get_reg)(struct arm_sim_interface *sim, int reg);
void (*set_reg)(struct arm_sim_interface *sim, int reg, uint32_t value); void (*set_reg)(struct arm_sim_interface *sim, int reg, uint32_t value);

View File

@ -23,6 +23,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -36,10 +37,9 @@
#include "algorithm.h" #include "algorithm.h"
#include "register.h" #include "register.h"
/* offsets into armv4_5 core register cache */ /* offsets into armv4_5 core register cache */
enum { enum {
// ARMV4_5_CPSR = 31, /* ARMV4_5_CPSR = 31, */
ARMV4_5_SPSR_FIQ = 32, ARMV4_5_SPSR_FIQ = 32,
ARMV4_5_SPSR_IRQ = 33, ARMV4_5_SPSR_IRQ = 33,
ARMV4_5_SPSR_SVC = 34, ARMV4_5_SPSR_SVC = 34,
@ -167,27 +167,27 @@ bool is_arm_mode(unsigned psr_mode)
int arm_mode_to_number(enum arm_mode mode) int arm_mode_to_number(enum arm_mode mode)
{ {
switch (mode) { switch (mode) {
case ARM_MODE_ANY: case ARM_MODE_ANY:
/* map MODE_ANY to user mode */ /* map MODE_ANY to user mode */
case ARM_MODE_USR: case ARM_MODE_USR:
return 0; return 0;
case ARM_MODE_FIQ: case ARM_MODE_FIQ:
return 1; return 1;
case ARM_MODE_IRQ: case ARM_MODE_IRQ:
return 2; return 2;
case ARM_MODE_SVC: case ARM_MODE_SVC:
return 3; return 3;
case ARM_MODE_ABT: case ARM_MODE_ABT:
return 4; return 4;
case ARM_MODE_UND: case ARM_MODE_UND:
return 5; return 5;
case ARM_MODE_SYS: case ARM_MODE_SYS:
return 6; return 6;
case ARM_MODE_MON: case ARM_MODE_MON:
return 7; return 7;
default: default:
LOG_ERROR("invalid mode value encountered %d", mode); LOG_ERROR("invalid mode value encountered %d", mode);
return -1; return -1;
} }
} }
@ -195,30 +195,29 @@ int arm_mode_to_number(enum arm_mode mode)
enum arm_mode armv4_5_number_to_mode(int number) enum arm_mode armv4_5_number_to_mode(int number)
{ {
switch (number) { switch (number) {
case 0: case 0:
return ARM_MODE_USR; return ARM_MODE_USR;
case 1: case 1:
return ARM_MODE_FIQ; return ARM_MODE_FIQ;
case 2: case 2:
return ARM_MODE_IRQ; return ARM_MODE_IRQ;
case 3: case 3:
return ARM_MODE_SVC; return ARM_MODE_SVC;
case 4: case 4:
return ARM_MODE_ABT; return ARM_MODE_ABT;
case 5: case 5:
return ARM_MODE_UND; return ARM_MODE_UND;
case 6: case 6:
return ARM_MODE_SYS; return ARM_MODE_SYS;
case 7: case 7:
return ARM_MODE_MON; return ARM_MODE_MON;
default: default:
LOG_ERROR("mode index out of bounds %d", number); LOG_ERROR("mode index out of bounds %d", number);
return ARM_MODE_ANY; return ARM_MODE_ANY;
} }
} }
static const char *arm_state_strings[] = static const char *arm_state_strings[] = {
{
"ARM", "Thumb", "Jazelle", "ThumbEE", "ARM", "Thumb", "Jazelle", "ThumbEE",
}; };
@ -312,8 +311,7 @@ static const struct {
/* map core mode (USR, FIQ, ...) and register number to /* map core mode (USR, FIQ, ...) and register number to
* indices into the register cache * indices into the register cache
*/ */
const int armv4_5_core_reg_map[8][17] = const int armv4_5_core_reg_map[8][17] = {
{
{ /* USR */ { /* USR */
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 31
}, },
@ -371,8 +369,8 @@ void arm_set_cpsr(struct arm *arm, uint32_t cpsr)
arm->map = &armv4_5_core_reg_map[num][0]; arm->map = &armv4_5_core_reg_map[num][0];
arm->spsr = (mode == ARM_MODE_USR || mode == ARM_MODE_SYS) arm->spsr = (mode == ARM_MODE_USR || mode == ARM_MODE_SYS)
? NULL ? NULL
: arm->core_cache->reg_list + arm->map[16]; : arm->core_cache->reg_list + arm->map[16];
/* Older ARMs won't have the J bit */ /* Older ARMs won't have the J bit */
enum arm_state state; enum arm_state state;
@ -393,8 +391,8 @@ void arm_set_cpsr(struct arm *arm, uint32_t cpsr)
arm->core_state = state; arm->core_state = state;
LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr, LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr,
arm_mode_name(mode), arm_mode_name(mode),
arm_state_strings[arm->core_state]); arm_state_strings[arm->core_state]);
} }
/** /**
@ -437,8 +435,7 @@ static const uint8_t arm_gdb_dummy_fp_value[12];
* Modern ARM cores use Vector Floating Point (VFP), if they * Modern ARM cores use Vector Floating Point (VFP), if they
* have any floating point support. VFP is not FPA-compatible. * have any floating point support. VFP is not FPA-compatible.
*/ */
struct reg arm_gdb_dummy_fp_reg = struct reg arm_gdb_dummy_fp_reg = {
{
.name = "GDB dummy FPA register", .name = "GDB dummy FPA register",
.value = (uint8_t *) arm_gdb_dummy_fp_value, .value = (uint8_t *) arm_gdb_dummy_fp_value,
.valid = 1, .valid = 1,
@ -451,8 +448,7 @@ static const uint8_t arm_gdb_dummy_fps_value[4];
* Dummy FPA status registers are required to support GDB on ARM. * Dummy FPA status registers are required to support GDB on ARM.
* Register packets require an obsolete FPA status register. * Register packets require an obsolete FPA status register.
*/ */
struct reg arm_gdb_dummy_fps_reg = struct reg arm_gdb_dummy_fps_reg = {
{
.name = "GDB dummy FPA status register", .name = "GDB dummy FPA status register",
.value = (uint8_t *) arm_gdb_dummy_fps_value, .value = (uint8_t *) arm_gdb_dummy_fps_value,
.valid = 1, .valid = 1,
@ -473,8 +469,7 @@ static int armv4_5_get_core_reg(struct reg *reg)
struct arm_reg *reg_arch_info = reg->arch_info; struct arm_reg *reg_arch_info = reg->arch_info;
struct target *target = reg_arch_info->target; struct target *target = reg_arch_info->target;
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
LOG_ERROR("Target not halted"); LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
} }
@ -496,8 +491,7 @@ static int armv4_5_set_core_reg(struct reg *reg, uint8_t *buf)
struct arm *armv4_5_target = target_to_arm(target); struct arm *armv4_5_target = target_to_arm(target);
uint32_t value = buf_get_u32(buf, 0, 32); uint32_t value = buf_get_u32(buf, 0, 32);
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
LOG_ERROR("Target not halted"); LOG_ERROR("Target not halted");
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
} }
@ -514,12 +508,12 @@ static int armv4_5_set_core_reg(struct reg *reg, uint8_t *buf)
* it won't hurt since CPSR is always flushed anyway. * it won't hurt since CPSR is always flushed anyway.
*/ */
if (armv4_5_target->core_mode != if (armv4_5_target->core_mode !=
(enum arm_mode)(value & 0x1f)) { (enum arm_mode)(value & 0x1f)) {
LOG_DEBUG("changing ARM core mode to '%s'", LOG_DEBUG("changing ARM core mode to '%s'",
arm_mode_name(value & 0x1f)); arm_mode_name(value & 0x1f));
value &= ~((1 << 24) | (1 << 5)); value &= ~((1 << 24) | (1 << 5));
armv4_5_target->write_core_reg(target, reg, armv4_5_target->write_core_reg(target, reg,
16, ARM_MODE_ANY, value); 16, ARM_MODE_ANY, value);
} }
} else { } else {
buf_set_u32(reg->value, 0, 32, value); buf_set_u32(reg->value, 0, 32, value);
@ -555,11 +549,10 @@ struct reg_cache *arm_build_reg_cache(struct target *target, struct arm *arm)
cache->reg_list = reg_list; cache->reg_list = reg_list;
cache->num_regs = 0; cache->num_regs = 0;
for (i = 0; i < num_regs; i++) for (i = 0; i < num_regs; i++) {
{
/* Skip registers this core doesn't expose */ /* Skip registers this core doesn't expose */
if (arm_core_regs[i].mode == ARM_MODE_MON if (arm_core_regs[i].mode == ARM_MODE_MON
&& arm->core_type != ARM_MODE_MON) && arm->core_type != ARM_MODE_MON)
continue; continue;
/* REVISIT handle Cortex-M, which only shadows R13/SP */ /* REVISIT handle Cortex-M, which only shadows R13/SP */
@ -588,26 +581,25 @@ int arm_arch_state(struct target *target)
{ {
struct arm *arm = target_to_arm(target); struct arm *arm = target_to_arm(target);
if (arm->common_magic != ARM_COMMON_MAGIC) if (arm->common_magic != ARM_COMMON_MAGIC) {
{
LOG_ERROR("BUG: called for a non-ARM target"); LOG_ERROR("BUG: called for a non-ARM target");
return ERROR_FAIL; return ERROR_FAIL;
} }
LOG_USER("target halted in %s state due to %s, current mode: %s\n" LOG_USER("target halted in %s state due to %s, current mode: %s\n"
"cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "%s", "cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "%s",
arm_state_strings[arm->core_state], arm_state_strings[arm->core_state],
debug_reason_name(target), debug_reason_name(target),
arm_mode_name(arm->core_mode), arm_mode_name(arm->core_mode),
buf_get_u32(arm->cpsr->value, 0, 32), buf_get_u32(arm->cpsr->value, 0, 32),
buf_get_u32(arm->pc->value, 0, 32), buf_get_u32(arm->pc->value, 0, 32),
arm->is_semihosting ? ", semihosting" : ""); arm->is_semihosting ? ", semihosting" : "");
return ERROR_OK; return ERROR_OK;
} }
#define ARMV4_5_CORE_REG_MODENUM(cache, mode, num) \ #define ARMV4_5_CORE_REG_MODENUM(cache, mode, num) \
cache->reg_list[armv4_5_core_reg_map[mode][num]] (cache->reg_list[armv4_5_core_reg_map[mode][num]])
COMMAND_HANDLER(handle_armv4_5_reg_command) COMMAND_HANDLER(handle_armv4_5_reg_command)
{ {
@ -615,33 +607,30 @@ COMMAND_HANDLER(handle_armv4_5_reg_command)
struct arm *arm = target_to_arm(target); struct arm *arm = target_to_arm(target);
struct reg *regs; struct reg *regs;
if (!is_arm(arm)) if (!is_arm(arm)) {
{
command_print(CMD_CTX, "current target isn't an ARM"); command_print(CMD_CTX, "current target isn't an ARM");
return ERROR_FAIL; return ERROR_FAIL;
} }
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
command_print(CMD_CTX, "error: target must be halted for register accesses"); command_print(CMD_CTX, "error: target must be halted for register accesses");
return ERROR_FAIL; return ERROR_FAIL;
} }
if (arm->core_type != ARM_MODE_ANY) if (arm->core_type != ARM_MODE_ANY) {
{ command_print(CMD_CTX,
command_print(CMD_CTX, "Microcontroller Profile not supported - use standard reg cmd"); "Microcontroller Profile not supported - use standard reg cmd");
return ERROR_OK; return ERROR_OK;
} }
if (!is_arm_mode(arm->core_mode)) if (!is_arm_mode(arm->core_mode)) {
{
LOG_ERROR("not a valid arm core mode - communication failure?"); LOG_ERROR("not a valid arm core mode - communication failure?");
return ERROR_FAIL; return ERROR_FAIL;
} }
if (!arm->full_context) { if (!arm->full_context) {
command_print(CMD_CTX, "error: target doesn't support %s", command_print(CMD_CTX, "error: target doesn't support %s",
CMD_NAME); CMD_NAME);
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -654,26 +643,26 @@ COMMAND_HANDLER(handle_armv4_5_reg_command)
/* label this bank of registers (or shadows) */ /* label this bank of registers (or shadows) */
switch (arm_mode_data[mode].psr) { switch (arm_mode_data[mode].psr) {
case ARM_MODE_SYS: case ARM_MODE_SYS:
continue;
case ARM_MODE_USR:
name = "System and User";
sep = "";
break;
case ARM_MODE_MON:
if (arm->core_type != ARM_MODE_MON)
continue; continue;
case ARM_MODE_USR:
name = "System and User";
sep = "";
break;
case ARM_MODE_MON:
if (arm->core_type != ARM_MODE_MON)
continue;
/* FALLTHROUGH */ /* FALLTHROUGH */
default: default:
name = arm_mode_data[mode].name; name = arm_mode_data[mode].name;
shadow = "shadow "; shadow = "shadow ";
break; break;
} }
command_print(CMD_CTX, "%s%s mode %sregisters", command_print(CMD_CTX, "%s%s mode %sregisters",
sep, name, shadow); sep, name, shadow);
/* display N rows of up to 4 registers each */ /* display N rows of up to 4 registers each */
for (unsigned i = 0; i < arm_mode_data[mode].n_indices;) { for (unsigned i = 0; i < arm_mode_data[mode].n_indices; ) {
char output[80]; char output[80];
int output_len = 0; int output_len = 0;
@ -693,8 +682,8 @@ COMMAND_HANDLER(handle_armv4_5_reg_command)
value = buf_get_u32(reg->value, 0, 32); value = buf_get_u32(reg->value, 0, 32);
output_len += snprintf(output + output_len, output_len += snprintf(output + output_len,
sizeof(output) - output_len, sizeof(output) - output_len,
"%8s: %8.8" PRIx32 " ", "%8s: %8.8" PRIx32 " ",
reg->name, value); reg->name, value);
} }
command_print(CMD_CTX, "%s", output); command_print(CMD_CTX, "%s", output);
} }
@ -708,29 +697,22 @@ COMMAND_HANDLER(handle_armv4_5_core_state_command)
struct target *target = get_current_target(CMD_CTX); struct target *target = get_current_target(CMD_CTX);
struct arm *arm = target_to_arm(target); struct arm *arm = target_to_arm(target);
if (!is_arm(arm)) if (!is_arm(arm)) {
{
command_print(CMD_CTX, "current target isn't an ARM"); command_print(CMD_CTX, "current target isn't an ARM");
return ERROR_FAIL; return ERROR_FAIL;
} }
if (arm->core_type == ARM_MODE_THREAD) if (arm->core_type == ARM_MODE_THREAD) {
{
/* armv7m not supported */ /* armv7m not supported */
command_print(CMD_CTX, "Unsupported Command"); command_print(CMD_CTX, "Unsupported Command");
return ERROR_OK; return ERROR_OK;
} }
if (CMD_ARGC > 0) if (CMD_ARGC > 0) {
{
if (strcmp(CMD_ARGV[0], "arm") == 0) if (strcmp(CMD_ARGV[0], "arm") == 0)
{
arm->core_state = ARM_STATE_ARM; arm->core_state = ARM_STATE_ARM;
}
if (strcmp(CMD_ARGV[0], "thumb") == 0) if (strcmp(CMD_ARGV[0], "thumb") == 0)
{
arm->core_state = ARM_STATE_THUMB; arm->core_state = ARM_STATE_THUMB;
}
} }
command_print(CMD_CTX, "core state: %s", arm_state_strings[arm->core_state]); command_print(CMD_CTX, "core state: %s", arm_state_strings[arm->core_state]);
@ -758,35 +740,34 @@ COMMAND_HANDLER(handle_arm_disassemble_command)
return ERROR_FAIL; return ERROR_FAIL;
} }
if (arm->core_type == ARM_MODE_THREAD) if (arm->core_type == ARM_MODE_THREAD) {
{
/* armv7m is always thumb mode */ /* armv7m is always thumb mode */
thumb = 1; thumb = 1;
} }
switch (CMD_ARGC) { switch (CMD_ARGC) {
case 3: case 3:
if (strcmp(CMD_ARGV[2], "thumb") != 0) if (strcmp(CMD_ARGV[2], "thumb") != 0)
goto usage; goto usage;
thumb = 1; thumb = 1;
/* FALL THROUGH */ /* FALL THROUGH */
case 2: case 2:
COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], count); COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], count);
/* FALL THROUGH */ /* FALL THROUGH */
case 1: case 1:
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
if (address & 0x01) { if (address & 0x01) {
if (!thumb) { if (!thumb) {
command_print(CMD_CTX, "Disassemble as Thumb"); command_print(CMD_CTX, "Disassemble as Thumb");
thumb = 1; thumb = 1;
}
address &= ~1;
} }
address &= ~1; break;
} default:
break;
default:
usage: usage:
count = 0; count = 0;
retval = ERROR_COMMAND_SYNTAX_ERROR; retval = ERROR_COMMAND_SYNTAX_ERROR;
} }
while (count-- > 0) { while (count-- > 0) {
@ -819,7 +800,7 @@ usage:
return retval; return retval;
} }
static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj * const *argv)
{ {
struct command_context *context; struct command_context *context;
struct target *target; struct target *target;
@ -827,7 +808,7 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
int retval; int retval;
context = current_command_context(interp); context = current_command_context(interp);
assert( context != NULL); assert(context != NULL);
target = get_current_target(context); target = get_current_target(context);
if (target == NULL) { if (target == NULL) {
@ -868,7 +849,7 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return retval; return retval;
if (l & ~0xf) { if (l & ~0xf) {
LOG_ERROR("%s: %s %d out of range", __func__, LOG_ERROR("%s: %s %d out of range", __func__,
"coprocessor", (int) l); "coprocessor", (int) l);
return JIM_ERR; return JIM_ERR;
} }
cpnum = l; cpnum = l;
@ -878,7 +859,7 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return retval; return retval;
if (l & ~0x7) { if (l & ~0x7) {
LOG_ERROR("%s: %s %d out of range", __func__, LOG_ERROR("%s: %s %d out of range", __func__,
"op1", (int) l); "op1", (int) l);
return JIM_ERR; return JIM_ERR;
} }
op1 = l; op1 = l;
@ -888,7 +869,7 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return retval; return retval;
if (l & ~0xf) { if (l & ~0xf) {
LOG_ERROR("%s: %s %d out of range", __func__, LOG_ERROR("%s: %s %d out of range", __func__,
"CRn", (int) l); "CRn", (int) l);
return JIM_ERR; return JIM_ERR;
} }
CRn = l; CRn = l;
@ -898,7 +879,7 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return retval; return retval;
if (l & ~0xf) { if (l & ~0xf) {
LOG_ERROR("%s: %s %d out of range", __func__, LOG_ERROR("%s: %s %d out of range", __func__,
"CRm", (int) l); "CRm", (int) l);
return JIM_ERR; return JIM_ERR;
} }
CRm = l; CRm = l;
@ -908,7 +889,7 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
return retval; return retval;
if (l & ~0x7) { if (l & ~0x7) {
LOG_ERROR("%s: %s %d out of range", __func__, LOG_ERROR("%s: %s %d out of range", __func__,
"op2", (int) l); "op2", (int) l);
return JIM_ERR; return JIM_ERR;
} }
op2 = l; op2 = l;
@ -925,19 +906,18 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
*/ */
if (argc == 7) { if (argc == 7) {
retval = Jim_GetLong(interp, argv[6], &l); retval = Jim_GetLong(interp, argv[6], &l);
if (retval != JIM_OK) { if (retval != JIM_OK)
return retval; return retval;
}
value = l; value = l;
/* NOTE: parameters reordered! */ /* NOTE: parameters reordered! */
// ARMV4_5_MCR(cpnum, op1, 0, CRn, CRm, op2) /* ARMV4_5_MCR(cpnum, op1, 0, CRn, CRm, op2) */
retval = arm->mcr(target, cpnum, op1, op2, CRn, CRm, value); retval = arm->mcr(target, cpnum, op1, op2, CRn, CRm, value);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return JIM_ERR; return JIM_ERR;
} else { } else {
/* NOTE: parameters reordered! */ /* NOTE: parameters reordered! */
// ARMV4_5_MRC(cpnum, op1, 0, CRn, CRm, op2) /* ARMV4_5_MRC(cpnum, op1, 0, CRn, CRm, op2) */
retval = arm->mrc(target, cpnum, op1, op2, CRn, CRm, &value); retval = arm->mrc(target, cpnum, op1, op2, CRn, CRm, &value);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return JIM_ERR; return JIM_ERR;
@ -964,20 +944,17 @@ COMMAND_HANDLER(handle_arm_semihosting_command)
return ERROR_FAIL; return ERROR_FAIL;
} }
if (!arm->setup_semihosting) if (!arm->setup_semihosting) {
{
command_print(CMD_CTX, "semihosting not supported for current target"); command_print(CMD_CTX, "semihosting not supported for current target");
return ERROR_FAIL; return ERROR_FAIL;
} }
if (CMD_ARGC > 0) if (CMD_ARGC > 0) {
{
int semihosting; int semihosting;
COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting); COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting);
if (!target_was_examined(target)) if (!target_was_examined(target)) {
{
LOG_ERROR("Target not examined yet"); LOG_ERROR("Target not examined yet");
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -992,8 +969,8 @@ COMMAND_HANDLER(handle_arm_semihosting_command)
} }
command_print(CMD_CTX, "semihosting is %s", command_print(CMD_CTX, "semihosting is %s",
arm->is_semihosting arm->is_semihosting
? "enabled" : "disabled"); ? "enabled" : "disabled");
return ERROR_OK; return ERROR_OK;
} }
@ -1055,19 +1032,18 @@ const struct command_registration arm_command_handlers[] = {
}; };
int arm_get_gdb_reg_list(struct target *target, int arm_get_gdb_reg_list(struct target *target,
struct reg **reg_list[], int *reg_list_size) struct reg **reg_list[], int *reg_list_size)
{ {
struct arm *arm = target_to_arm(target); struct arm *arm = target_to_arm(target);
int i; int i;
if (!is_arm_mode(arm->core_mode)) if (!is_arm_mode(arm->core_mode)) {
{
LOG_ERROR("not a valid arm core mode - communication failure?"); LOG_ERROR("not a valid arm core mode - communication failure?");
return ERROR_FAIL; return ERROR_FAIL;
} }
*reg_list_size = 26; *reg_list_size = 26;
*reg_list = malloc(sizeof(struct reg*) * (*reg_list_size)); *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
(*reg_list)[i] = arm_reg_current(arm, i); (*reg_list)[i] = arm_reg_current(arm, i);
@ -1082,30 +1058,31 @@ int arm_get_gdb_reg_list(struct target *target,
} }
/* wait for execution to complete and check exit point */ /* wait for execution to complete and check exit point */
static int armv4_5_run_algorithm_completion(struct target *target, uint32_t exit_point, int timeout_ms, void *arch_info) static int armv4_5_run_algorithm_completion(struct target *target,
uint32_t exit_point,
int timeout_ms,
void *arch_info)
{ {
int retval; int retval;
struct arm *arm = target_to_arm(target); struct arm *arm = target_to_arm(target);
if ((retval = target_wait_state(target, TARGET_HALTED, timeout_ms)) != ERROR_OK) retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
{ if (retval != ERROR_OK)
return retval; return retval;
} if (target->state != TARGET_HALTED) {
if (target->state != TARGET_HALTED) retval = target_halt(target);
{ if (retval != ERROR_OK)
if ((retval = target_halt(target)) != ERROR_OK)
return retval; return retval;
if ((retval = target_wait_state(target, TARGET_HALTED, 500)) != ERROR_OK) retval = target_wait_state(target, TARGET_HALTED, 500);
{ if (retval != ERROR_OK)
return retval; return retval;
}
return ERROR_TARGET_TIMEOUT; return ERROR_TARGET_TIMEOUT;
} }
/* fast exit: ARMv5+ code can use BKPT */ /* fast exit: ARMv5+ code can use BKPT */
if (exit_point && buf_get_u32(arm->pc->value, 0, 32) != exit_point) if (exit_point && buf_get_u32(arm->pc->value, 0, 32) != exit_point) {
{ LOG_WARNING(
LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "", "target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "",
buf_get_u32(arm->pc->value, 0, 32)); buf_get_u32(arm->pc->value, 0, 32));
return ERROR_TARGET_TIMEOUT; return ERROR_TARGET_TIMEOUT;
} }
@ -1114,12 +1091,12 @@ static int armv4_5_run_algorithm_completion(struct target *target, uint32_t exit
} }
int armv4_5_run_algorithm_inner(struct target *target, int armv4_5_run_algorithm_inner(struct target *target,
int num_mem_params, struct mem_param *mem_params, int num_mem_params, struct mem_param *mem_params,
int num_reg_params, struct reg_param *reg_params, int num_reg_params, struct reg_param *reg_params,
uint32_t entry_point, uint32_t exit_point, uint32_t entry_point, uint32_t exit_point,
int timeout_ms, void *arch_info, int timeout_ms, void *arch_info,
int (*run_it)(struct target *target, uint32_t exit_point, int (*run_it)(struct target *target, uint32_t exit_point,
int timeout_ms, void *arch_info)) int timeout_ms, void *arch_info))
{ {
struct arm *arm = target_to_arm(target); struct arm *arm = target_to_arm(target);
struct arm_algorithm *arm_algorithm_info = arch_info; struct arm_algorithm *arm_algorithm_info = arch_info;
@ -1132,27 +1109,23 @@ int armv4_5_run_algorithm_inner(struct target *target,
LOG_DEBUG("Running algorithm"); LOG_DEBUG("Running algorithm");
if (arm_algorithm_info->common_magic != ARM_COMMON_MAGIC) if (arm_algorithm_info->common_magic != ARM_COMMON_MAGIC) {
{
LOG_ERROR("current target isn't an ARMV4/5 target"); LOG_ERROR("current target isn't an ARMV4/5 target");
return ERROR_TARGET_INVALID; return ERROR_TARGET_INVALID;
} }
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
LOG_WARNING("target not halted"); LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
} }
if (!is_arm_mode(arm->core_mode)) if (!is_arm_mode(arm->core_mode)) {
{
LOG_ERROR("not a valid arm core mode - communication failure?"); LOG_ERROR("not a valid arm core mode - communication failure?");
return ERROR_FAIL; return ERROR_FAIL;
} }
/* armv5 and later can terminate with BKPT instruction; less overhead */ /* armv5 and later can terminate with BKPT instruction; less overhead */
if (!exit_point && arm->is_armv4) if (!exit_point && arm->is_armv4) {
{
LOG_ERROR("ARMv4 target needs HW breakpoint location"); LOG_ERROR("ARMv4 target needs HW breakpoint location");
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -1160,46 +1133,41 @@ int armv4_5_run_algorithm_inner(struct target *target,
/* save r0..pc, cpsr-or-spsr, and then cpsr-for-sure; /* save r0..pc, cpsr-or-spsr, and then cpsr-for-sure;
* they'll be restored later. * they'll be restored later.
*/ */
for (i = 0; i <= 16; i++) for (i = 0; i <= 16; i++) {
{
struct reg *r; struct reg *r;
r = &ARMV4_5_CORE_REG_MODE(arm->core_cache, r = &ARMV4_5_CORE_REG_MODE(arm->core_cache,
arm_algorithm_info->core_mode, i); arm_algorithm_info->core_mode, i);
if (!r->valid) if (!r->valid)
arm->read_core_reg(target, r, i, arm->read_core_reg(target, r, i,
arm_algorithm_info->core_mode); arm_algorithm_info->core_mode);
context[i] = buf_get_u32(r->value, 0, 32); context[i] = buf_get_u32(r->value, 0, 32);
} }
cpsr = buf_get_u32(arm->cpsr->value, 0, 32); cpsr = buf_get_u32(arm->cpsr->value, 0, 32);
for (i = 0; i < num_mem_params; i++) for (i = 0; i < num_mem_params; i++) {
{ retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size,
if ((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK) mem_params[i].value);
{ if (retval != ERROR_OK)
return retval; return retval;
}
} }
for (i = 0; i < num_reg_params; i++) for (i = 0; i < num_reg_params; i++) {
{
struct reg *reg = register_get_by_name(arm->core_cache, reg_params[i].reg_name, 0); struct reg *reg = register_get_by_name(arm->core_cache, reg_params[i].reg_name, 0);
if (!reg) if (!reg) {
{
LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
if (reg->size != reg_params[i].size) if (reg->size != reg_params[i].size) {
{ LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name); reg_params[i].reg_name);
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
if ((retval = armv4_5_set_core_reg(reg, reg_params[i].value)) != ERROR_OK) retval = armv4_5_set_core_reg(reg, reg_params[i].value);
{ if (retval != ERROR_OK)
return retval; return retval;
}
} }
arm->core_state = arm_algorithm_info->core_state; arm->core_state = arm_algorithm_info->core_state;
@ -1207,35 +1175,33 @@ int armv4_5_run_algorithm_inner(struct target *target,
exit_breakpoint_size = 4; exit_breakpoint_size = 4;
else if (arm->core_state == ARM_STATE_THUMB) else if (arm->core_state == ARM_STATE_THUMB)
exit_breakpoint_size = 2; exit_breakpoint_size = 2;
else else {
{
LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state"); LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state");
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
if (arm_algorithm_info->core_mode != ARM_MODE_ANY) if (arm_algorithm_info->core_mode != ARM_MODE_ANY) {
{
LOG_DEBUG("setting core_mode: 0x%2.2x", LOG_DEBUG("setting core_mode: 0x%2.2x",
arm_algorithm_info->core_mode); arm_algorithm_info->core_mode);
buf_set_u32(arm->cpsr->value, 0, 5, buf_set_u32(arm->cpsr->value, 0, 5,
arm_algorithm_info->core_mode); arm_algorithm_info->core_mode);
arm->cpsr->dirty = 1; arm->cpsr->dirty = 1;
arm->cpsr->valid = 1; arm->cpsr->valid = 1;
} }
/* terminate using a hardware or (ARMv5+) software breakpoint */ /* terminate using a hardware or (ARMv5+) software breakpoint */
if (exit_point && (retval = breakpoint_add(target, exit_point, if (exit_point) {
exit_breakpoint_size, BKPT_HARD)) != ERROR_OK) retval = breakpoint_add(target, exit_point,
{ exit_breakpoint_size, BKPT_HARD);
LOG_ERROR("can't add HW breakpoint to terminate algorithm"); if (retval != ERROR_OK) {
return ERROR_TARGET_FAILURE; LOG_ERROR("can't add HW breakpoint to terminate algorithm");
return ERROR_TARGET_FAILURE;
}
} }
if ((retval = target_resume(target, 0, entry_point, 1, 1)) != ERROR_OK) retval = target_resume(target, 0, entry_point, 1, 1);
{ if (retval != ERROR_OK)
return retval; return retval;
}
int retvaltemp;
retval = run_it(target, exit_point, timeout_ms, arch_info); retval = run_it(target, exit_point, timeout_ms, arch_info);
if (exit_point) if (exit_point)
@ -1244,31 +1210,32 @@ int armv4_5_run_algorithm_inner(struct target *target,
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
for (i = 0; i < num_mem_params; i++) for (i = 0; i < num_mem_params; i++) {
{ if (mem_params[i].direction != PARAM_OUT) {
if (mem_params[i].direction != PARAM_OUT) int retvaltemp = target_read_buffer(target, mem_params[i].address,
if ((retvaltemp = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK) mem_params[i].size,
{ mem_params[i].value);
retval = retvaltemp; if (retvaltemp != ERROR_OK)
} retval = retvaltemp;
}
} }
for (i = 0; i < num_reg_params; i++) for (i = 0; i < num_reg_params; i++) {
{ if (reg_params[i].direction != PARAM_OUT) {
if (reg_params[i].direction != PARAM_OUT)
{
struct reg *reg = register_get_by_name(arm->core_cache, reg_params[i].reg_name, 0); struct reg *reg = register_get_by_name(arm->core_cache,
if (!reg) reg_params[i].reg_name,
{ 0);
if (!reg) {
LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
retval = ERROR_COMMAND_SYNTAX_ERROR; retval = ERROR_COMMAND_SYNTAX_ERROR;
continue; continue;
} }
if (reg->size != reg_params[i].size) if (reg->size != reg_params[i].size) {
{ LOG_ERROR(
LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name); "BUG: register '%s' size doesn't match reg_params[i].size",
reg_params[i].reg_name);
retval = ERROR_COMMAND_SYNTAX_ERROR; retval = ERROR_COMMAND_SYNTAX_ERROR;
continue; continue;
} }
@ -1278,20 +1245,20 @@ int armv4_5_run_algorithm_inner(struct target *target,
} }
/* restore everything we saved before (17 or 18 registers) */ /* restore everything we saved before (17 or 18 registers) */
for (i = 0; i <= 16; i++) for (i = 0; i <= 16; i++) {
{
uint32_t regvalue; uint32_t regvalue;
regvalue = buf_get_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache, regvalue = buf_get_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache,
arm_algorithm_info->core_mode, i).value, 0, 32); arm_algorithm_info->core_mode, i).value, 0, 32);
if (regvalue != context[i]) if (regvalue != context[i]) {
{
LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32 "", LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32 "",
ARMV4_5_CORE_REG_MODE(arm->core_cache, ARMV4_5_CORE_REG_MODE(arm->core_cache,
arm_algorithm_info->core_mode, i).name, context[i]); arm_algorithm_info->core_mode, i).name, context[i]);
buf_set_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache, buf_set_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache,
arm_algorithm_info->core_mode, i).value, 0, 32, context[i]); arm_algorithm_info->core_mode, i).value, 0, 32, context[i]);
ARMV4_5_CORE_REG_MODE(arm->core_cache, arm_algorithm_info->core_mode, i).valid = 1; ARMV4_5_CORE_REG_MODE(arm->core_cache, arm_algorithm_info->core_mode,
ARMV4_5_CORE_REG_MODE(arm->core_cache, arm_algorithm_info->core_mode, i).dirty = 1; i).valid = 1;
ARMV4_5_CORE_REG_MODE(arm->core_cache, arm_algorithm_info->core_mode,
i).dirty = 1;
} }
} }
@ -1303,9 +1270,26 @@ int armv4_5_run_algorithm_inner(struct target *target,
return retval; return retval;
} }
int armv4_5_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, uint32_t entry_point, uint32_t exit_point, int timeout_ms, void *arch_info) int armv4_5_run_algorithm(struct target *target,
int num_mem_params,
struct mem_param *mem_params,
int num_reg_params,
struct reg_param *reg_params,
uint32_t entry_point,
uint32_t exit_point,
int timeout_ms,
void *arch_info)
{ {
return armv4_5_run_algorithm_inner(target, num_mem_params, mem_params, num_reg_params, reg_params, entry_point, exit_point, timeout_ms, arch_info, armv4_5_run_algorithm_completion); return armv4_5_run_algorithm_inner(target,
num_mem_params,
mem_params,
num_reg_params,
reg_params,
entry_point,
exit_point,
timeout_ms,
arch_info,
armv4_5_run_algorithm_completion);
} }
/** /**
@ -1313,7 +1297,7 @@ int armv4_5_run_algorithm(struct target *target, int num_mem_params, struct mem_
* *
*/ */
int arm_checksum_memory(struct target *target, int arm_checksum_memory(struct target *target,
uint32_t address, uint32_t count, uint32_t *checksum) uint32_t address, uint32_t count, uint32_t *checksum)
{ {
struct working_area *crc_algorithm; struct working_area *crc_algorithm;
struct arm_algorithm armv4_5_info; struct arm_algorithm armv4_5_info;
@ -1414,7 +1398,7 @@ int arm_checksum_memory(struct target *target,
* *
*/ */
int arm_blank_check_memory(struct target *target, int arm_blank_check_memory(struct target *target,
uint32_t address, uint32_t count, uint32_t *blank) uint32_t address, uint32_t count, uint32_t *blank)
{ {
struct working_area *check_algorithm; struct working_area *check_algorithm;
struct reg_param reg_params[3]; struct reg_param reg_params[3];
@ -1444,7 +1428,7 @@ int arm_blank_check_memory(struct target *target,
for (i = 0; i < ARRAY_SIZE(check_code); i++) { for (i = 0; i < ARRAY_SIZE(check_code); i++) {
retval = target_write_u32(target, retval = target_write_u32(target,
check_algorithm->address check_algorithm->address
+ i * sizeof(uint32_t), + i * sizeof(uint32_t),
check_code[i]); check_code[i]);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -1506,18 +1490,18 @@ static int arm_full_context(struct target *target)
} }
static int arm_default_mrc(struct target *target, int cpnum, static int arm_default_mrc(struct target *target, int cpnum,
uint32_t op1, uint32_t op2, uint32_t op1, uint32_t op2,
uint32_t CRn, uint32_t CRm, uint32_t CRn, uint32_t CRm,
uint32_t *value) uint32_t *value)
{ {
LOG_ERROR("%s doesn't implement MRC", target_type_name(target)); LOG_ERROR("%s doesn't implement MRC", target_type_name(target));
return ERROR_FAIL; return ERROR_FAIL;
} }
static int arm_default_mcr(struct target *target, int cpnum, static int arm_default_mcr(struct target *target, int cpnum,
uint32_t op1, uint32_t op2, uint32_t op1, uint32_t op2,
uint32_t CRn, uint32_t CRm, uint32_t CRn, uint32_t CRm,
uint32_t value) uint32_t value)
{ {
LOG_ERROR("%s doesn't implement MCR", target_type_name(target)); LOG_ERROR("%s doesn't implement MCR", target_type_name(target));
return ERROR_FAIL; return ERROR_FAIL;

View File

@ -23,6 +23,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARMV4_5_H #ifndef ARMV4_5_H
#define ARMV4_5_H #define ARMV4_5_H
@ -42,7 +43,7 @@ enum arm_mode armv4_5_number_to_mode(int number);
extern const int armv4_5_core_reg_map[8][17]; extern const int armv4_5_core_reg_map[8][17];
#define ARMV4_5_CORE_REG_MODE(cache, mode, num) \ #define ARMV4_5_CORE_REG_MODE(cache, mode, num) \
cache->reg_list[armv4_5_core_reg_map[arm_mode_to_number(mode)][num]] (cache->reg_list[armv4_5_core_reg_map[arm_mode_to_number(mode)][num]])
/* offset into armv4_5 core register cache -- OBSOLETE, DO NOT USE! */ /* offset into armv4_5 core register cache -- OBSOLETE, DO NOT USE! */
enum { ARMV4_5_CPSR = 31, }; enum { ARMV4_5_CPSR = 31, };

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -37,16 +38,13 @@ int armv4_5_identify_cache(uint32_t cache_type_reg, struct armv4_5_cache_common
len = (cache_type_reg & 0x3000) >> 12; len = (cache_type_reg & 0x3000) >> 12;
multiplier = 2 + M; multiplier = 2 + M;
if ((assoc != 0) || (M != 1)) /* assoc 0 and M 1 means cache absent */ if ((assoc != 0) || (M != 1)) /* assoc 0 and M 1 means cache absent */ {
{
/* cache is present */ /* cache is present */
cache->d_u_size.linelen = 1 << (len + 3); cache->d_u_size.linelen = 1 << (len + 3);
cache->d_u_size.associativity = multiplier << (assoc - 1); cache->d_u_size.associativity = multiplier << (assoc - 1);
cache->d_u_size.nsets = 1 << (size + 6 - assoc - len); cache->d_u_size.nsets = 1 << (size + 6 - assoc - len);
cache->d_u_size.cachesize = multiplier << (size + 8); cache->d_u_size.cachesize = multiplier << (size + 8);
} } else {
else
{
/* cache is absent */ /* cache is absent */
cache->d_u_size.linelen = -1; cache->d_u_size.linelen = -1;
cache->d_u_size.associativity = -1; cache->d_u_size.associativity = -1;
@ -54,43 +52,35 @@ int armv4_5_identify_cache(uint32_t cache_type_reg, struct armv4_5_cache_common
cache->d_u_size.cachesize = -1; cache->d_u_size.cachesize = -1;
} }
if (cache->separate) if (cache->separate) {
{
size = (cache_type_reg & 0x1c0) >> 6; size = (cache_type_reg & 0x1c0) >> 6;
assoc = (cache_type_reg & 0x38) >> 3; assoc = (cache_type_reg & 0x38) >> 3;
M = (cache_type_reg & 0x4) >> 2; M = (cache_type_reg & 0x4) >> 2;
len = (cache_type_reg & 0x3); len = (cache_type_reg & 0x3);
multiplier = 2 + M; multiplier = 2 + M;
if ((assoc != 0) || (M != 1)) /* assoc 0 and M 1 means cache absent */ if ((assoc != 0) || (M != 1)) /* assoc 0 and M 1 means cache absent */ {
{
/* cache is present */ /* cache is present */
cache->i_size.linelen = 1 << (len + 3); cache->i_size.linelen = 1 << (len + 3);
cache->i_size.associativity = multiplier << (assoc - 1); cache->i_size.associativity = multiplier << (assoc - 1);
cache->i_size.nsets = 1 << (size + 6 - assoc - len); cache->i_size.nsets = 1 << (size + 6 - assoc - len);
cache->i_size.cachesize = multiplier << (size + 8); cache->i_size.cachesize = multiplier << (size + 8);
} } else {
else
{
/* cache is absent */ /* cache is absent */
cache->i_size.linelen = -1; cache->i_size.linelen = -1;
cache->i_size.associativity = -1; cache->i_size.associativity = -1;
cache->i_size.nsets = -1; cache->i_size.nsets = -1;
cache->i_size.cachesize = -1; cache->i_size.cachesize = -1;
} }
} } else
else
{
cache->i_size = cache->d_u_size; cache->i_size = cache->d_u_size;
}
return ERROR_OK; return ERROR_OK;
} }
int armv4_5_handle_cache_info_command(struct command_context *cmd_ctx, struct armv4_5_cache_common *armv4_5_cache) int armv4_5_handle_cache_info_command(struct command_context *cmd_ctx, struct armv4_5_cache_common *armv4_5_cache)
{ {
if (armv4_5_cache->ctype == -1) if (armv4_5_cache->ctype == -1) {
{
command_print(cmd_ctx, "cache not yet identified"); command_print(cmd_ctx, "cache not yet identified");
return ERROR_OK; return ERROR_OK;
} }

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARMV4_5_CACHE_H #ifndef ARMV4_5_CACHE_H
#define ARMV4_5_CACHE_H #define ARMV4_5_CACHE_H
@ -24,16 +25,14 @@
struct command_context; struct command_context;
struct armv4_5_cachesize struct armv4_5_cachesize {
{
int linelen; int linelen;
int associativity; int associativity;
int nsets; int nsets;
int cachesize; int cachesize;
}; };
struct armv4_5_cache_common struct armv4_5_cache_common {
{
int ctype; /* specify supported cache operations */ int ctype; /* specify supported cache operations */
int separate; /* separate caches or unified cache */ int separate; /* separate caches or unified cache */
struct armv4_5_cachesize d_u_size; /* data cache */ struct armv4_5_cachesize d_u_size; /* data cache */
@ -50,8 +49,7 @@ int armv4_5_cache_state(uint32_t cp15_control_reg,
int armv4_5_handle_cache_info_command(struct command_context *cmd_ctx, int armv4_5_handle_cache_info_command(struct command_context *cmd_ctx,
struct armv4_5_cache_common *armv4_5_cache); struct armv4_5_cache_common *armv4_5_cache);
enum enum {
{
ARMV4_5_D_U_CACHE_ENABLED = 0x4, ARMV4_5_D_U_CACHE_ENABLED = 0x4,
ARMV4_5_I_CACHE_ENABLED = 0x1000, ARMV4_5_I_CACHE_ENABLED = 0x1000,
ARMV4_5_WRITE_BUFFER_ENABLED = 0x8, ARMV4_5_WRITE_BUFFER_ENABLED = 0x8,

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -25,8 +26,8 @@
#include "target.h" #include "target.h"
#include "armv4_5_mmu.h" #include "armv4_5_mmu.h"
int armv4_5_mmu_translate_va(struct target *target,
int armv4_5_mmu_translate_va(struct target *target, struct armv4_5_mmu_common *armv4_5_mmu, uint32_t va, uint32_t *cb, uint32_t *val) struct armv4_5_mmu_common *armv4_5_mmu, uint32_t va, uint32_t *cb, uint32_t *val)
{ {
uint32_t first_lvl_descriptor = 0x0; uint32_t first_lvl_descriptor = 0x0;
uint32_t second_lvl_descriptor = 0x0; uint32_t second_lvl_descriptor = 0x0;
@ -34,62 +35,55 @@ int armv4_5_mmu_translate_va(struct target *target, struct armv4_5_mmu_common *a
int retval; int retval;
retval = armv4_5_mmu->get_ttb(target, &ttb); retval = armv4_5_mmu->get_ttb(target, &ttb);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
retval = armv4_5_mmu_read_physical(target, armv4_5_mmu, retval = armv4_5_mmu_read_physical(target, armv4_5_mmu,
(ttb & 0xffffc000) | ((va & 0xfff00000) >> 18), (ttb & 0xffffc000) | ((va & 0xfff00000) >> 18),
4, 1, (uint8_t*)&first_lvl_descriptor); 4, 1, (uint8_t *)&first_lvl_descriptor);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
first_lvl_descriptor = target_buffer_get_u32(target, (uint8_t*)&first_lvl_descriptor); first_lvl_descriptor = target_buffer_get_u32(target, (uint8_t *)&first_lvl_descriptor);
LOG_DEBUG("1st lvl desc: %8.8" PRIx32 "", first_lvl_descriptor); LOG_DEBUG("1st lvl desc: %8.8" PRIx32 "", first_lvl_descriptor);
if ((first_lvl_descriptor & 0x3) == 0) if ((first_lvl_descriptor & 0x3) == 0) {
{
LOG_ERROR("Address translation failure"); LOG_ERROR("Address translation failure");
return ERROR_TARGET_TRANSLATION_FAULT; return ERROR_TARGET_TRANSLATION_FAULT;
} }
if (!armv4_5_mmu->has_tiny_pages && ((first_lvl_descriptor & 0x3) == 3)) if (!armv4_5_mmu->has_tiny_pages && ((first_lvl_descriptor & 0x3) == 3)) {
{
LOG_ERROR("Address translation failure"); LOG_ERROR("Address translation failure");
return ERROR_TARGET_TRANSLATION_FAULT; return ERROR_TARGET_TRANSLATION_FAULT;
} }
if ((first_lvl_descriptor & 0x3) == 2) if ((first_lvl_descriptor & 0x3) == 2) {
{
/* section descriptor */ /* section descriptor */
*cb = (first_lvl_descriptor & 0xc) >> 2; *cb = (first_lvl_descriptor & 0xc) >> 2;
*val = (first_lvl_descriptor & 0xfff00000) | (va & 0x000fffff); *val = (first_lvl_descriptor & 0xfff00000) | (va & 0x000fffff);
return ERROR_OK; return ERROR_OK;
} }
if ((first_lvl_descriptor & 0x3) == 1) if ((first_lvl_descriptor & 0x3) == 1) {
{
/* coarse page table */ /* coarse page table */
retval = armv4_5_mmu_read_physical(target, armv4_5_mmu, retval = armv4_5_mmu_read_physical(target, armv4_5_mmu,
(first_lvl_descriptor & 0xfffffc00) | ((va & 0x000ff000) >> 10), (first_lvl_descriptor & 0xfffffc00) | ((va & 0x000ff000) >> 10),
4, 1, (uint8_t*)&second_lvl_descriptor); 4, 1, (uint8_t *)&second_lvl_descriptor);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
} } else if ((first_lvl_descriptor & 0x3) == 3) {
else if ((first_lvl_descriptor & 0x3) == 3)
{
/* fine page table */ /* fine page table */
retval = armv4_5_mmu_read_physical(target, armv4_5_mmu, retval = armv4_5_mmu_read_physical(target, armv4_5_mmu,
(first_lvl_descriptor & 0xfffff000) | ((va & 0x000ffc00) >> 8), (first_lvl_descriptor & 0xfffff000) | ((va & 0x000ffc00) >> 8),
4, 1, (uint8_t*)&second_lvl_descriptor); 4, 1, (uint8_t *)&second_lvl_descriptor);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
} }
second_lvl_descriptor = target_buffer_get_u32(target, (uint8_t*)&second_lvl_descriptor); second_lvl_descriptor = target_buffer_get_u32(target, (uint8_t *)&second_lvl_descriptor);
LOG_DEBUG("2nd lvl desc: %8.8" PRIx32 "", second_lvl_descriptor); LOG_DEBUG("2nd lvl desc: %8.8" PRIx32 "", second_lvl_descriptor);
if ((second_lvl_descriptor & 0x3) == 0) if ((second_lvl_descriptor & 0x3) == 0) {
{
LOG_ERROR("Address translation failure"); LOG_ERROR("Address translation failure");
return ERROR_TARGET_TRANSLATION_FAULT; return ERROR_TARGET_TRANSLATION_FAULT;
} }
@ -97,22 +91,19 @@ int armv4_5_mmu_translate_va(struct target *target, struct armv4_5_mmu_common *a
/* cacheable/bufferable is always specified in bits 3-2 */ /* cacheable/bufferable is always specified in bits 3-2 */
*cb = (second_lvl_descriptor & 0xc) >> 2; *cb = (second_lvl_descriptor & 0xc) >> 2;
if ((second_lvl_descriptor & 0x3) == 1) if ((second_lvl_descriptor & 0x3) == 1) {
{
/* large page descriptor */ /* large page descriptor */
*val = (second_lvl_descriptor & 0xffff0000) | (va & 0x0000ffff); *val = (second_lvl_descriptor & 0xffff0000) | (va & 0x0000ffff);
return ERROR_OK; return ERROR_OK;
} }
if ((second_lvl_descriptor & 0x3) == 2) if ((second_lvl_descriptor & 0x3) == 2) {
{
/* small page descriptor */ /* small page descriptor */
*val = (second_lvl_descriptor & 0xfffff000) | (va & 0x00000fff); *val = (second_lvl_descriptor & 0xfffff000) | (va & 0x00000fff);
return ERROR_OK; return ERROR_OK;
} }
if ((second_lvl_descriptor & 0x3) == 3) if ((second_lvl_descriptor & 0x3) == 3) {
{
/* tiny page descriptor */ /* tiny page descriptor */
*val = (second_lvl_descriptor & 0xfffffc00) | (va & 0x000003ff); *val = (second_lvl_descriptor & 0xfffffc00) | (va & 0x000003ff);
return ERROR_OK; return ERROR_OK;
@ -123,7 +114,9 @@ int armv4_5_mmu_translate_va(struct target *target, struct armv4_5_mmu_common *a
return ERROR_TARGET_TRANSLATION_FAULT; return ERROR_TARGET_TRANSLATION_FAULT;
} }
int armv4_5_mmu_read_physical(struct target *target, struct armv4_5_mmu_common *armv4_5_mmu, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer) int armv4_5_mmu_read_physical(struct target *target,
struct armv4_5_mmu_common *armv4_5_mmu, uint32_t address,
uint32_t size, uint32_t count, uint8_t *buffer)
{ {
int retval; int retval;
@ -132,24 +125,26 @@ int armv4_5_mmu_read_physical(struct target *target, struct armv4_5_mmu_common *
/* disable MMU and data (or unified) cache */ /* disable MMU and data (or unified) cache */
retval = armv4_5_mmu->disable_mmu_caches(target, 1, 1, 0); retval = armv4_5_mmu->disable_mmu_caches(target, 1, 1, 0);
if (retval !=ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
retval = armv4_5_mmu->read_memory(target, address, size, count, buffer); retval = armv4_5_mmu->read_memory(target, address, size, count, buffer);
if (retval !=ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
/* reenable MMU / cache */ /* reenable MMU / cache */
retval = armv4_5_mmu->enable_mmu_caches(target, armv4_5_mmu->mmu_enabled, retval = armv4_5_mmu->enable_mmu_caches(target, armv4_5_mmu->mmu_enabled,
armv4_5_mmu->armv4_5_cache.d_u_cache_enabled, armv4_5_mmu->armv4_5_cache.d_u_cache_enabled,
armv4_5_mmu->armv4_5_cache.i_cache_enabled); armv4_5_mmu->armv4_5_cache.i_cache_enabled);
if (retval !=ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
return retval; return retval;
} }
int armv4_5_mmu_write_physical(struct target *target, struct armv4_5_mmu_common *armv4_5_mmu, uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer) int armv4_5_mmu_write_physical(struct target *target,
struct armv4_5_mmu_common *armv4_5_mmu, uint32_t address,
uint32_t size, uint32_t count, const uint8_t *buffer)
{ {
int retval; int retval;
@ -158,18 +153,18 @@ int armv4_5_mmu_write_physical(struct target *target, struct armv4_5_mmu_common
/* disable MMU and data (or unified) cache */ /* disable MMU and data (or unified) cache */
retval = armv4_5_mmu->disable_mmu_caches(target, 1, 1, 0); retval = armv4_5_mmu->disable_mmu_caches(target, 1, 1, 0);
if (retval !=ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
retval = armv4_5_mmu->write_memory(target, address, size, count, buffer); retval = armv4_5_mmu->write_memory(target, address, size, count, buffer);
if (retval !=ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
/* reenable MMU / cache */ /* reenable MMU / cache */
retval = armv4_5_mmu->enable_mmu_caches(target, armv4_5_mmu->mmu_enabled, retval = armv4_5_mmu->enable_mmu_caches(target, armv4_5_mmu->mmu_enabled,
armv4_5_mmu->armv4_5_cache.d_u_cache_enabled, armv4_5_mmu->armv4_5_cache.d_u_cache_enabled,
armv4_5_mmu->armv4_5_cache.i_cache_enabled); armv4_5_mmu->armv4_5_cache.i_cache_enabled);
if (retval !=ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
return retval; return retval;

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARMV4_5_MMU_H #ifndef ARMV4_5_MMU_H
#define ARMV4_5_MMU_H #define ARMV4_5_MMU_H
@ -24,8 +25,7 @@
struct target; struct target;
struct armv4_5_mmu_common struct armv4_5_mmu_common {
{
int (*get_ttb)(struct target *target, uint32_t *result); int (*get_ttb)(struct target *target, uint32_t *result);
int (*read_memory)(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer); int (*read_memory)(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer);
int (*write_memory)(struct target *target, uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer); int (*write_memory)(struct target *target, uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer);
@ -48,8 +48,7 @@ int armv4_5_mmu_write_physical(struct target *target,
struct armv4_5_mmu_common *armv4_5_mmu, struct armv4_5_mmu_common *armv4_5_mmu,
uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer); uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer);
enum enum {
{
ARMV4_5_MMU_ENABLED = 0x1, ARMV4_5_MMU_ENABLED = 0x1,
ARMV4_5_ALIGNMENT_CHECK = 0x2, ARMV4_5_ALIGNMENT_CHECK = 0x2,
ARMV4_5_MMU_S_BIT = 0x100, ARMV4_5_MMU_S_BIT = 0x100,

View File

@ -18,6 +18,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -79,9 +80,9 @@ static void armv7a_show_fault_registers(struct target *target)
goto done; goto done;
LOG_USER("Data fault registers DFSR: %8.8" PRIx32 LOG_USER("Data fault registers DFSR: %8.8" PRIx32
", DFAR: %8.8" PRIx32, dfsr, dfar); ", DFAR: %8.8" PRIx32, dfsr, dfar);
LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32 LOG_USER("Instruction fault registers IFSR: %8.8" PRIx32
", IFAR: %8.8" PRIx32, ifsr, ifar); ", IFAR: %8.8" PRIx32, ifsr, ifar);
done: done:
/* (void) */ dpm->finish(dpm); /* (void) */ dpm->finish(dpm);
@ -93,29 +94,28 @@ static int armv7a_read_ttbcr(struct target *target)
struct arm_dpm *dpm = armv7a->arm.dpm; struct arm_dpm *dpm = armv7a->arm.dpm;
uint32_t ttbcr; uint32_t ttbcr;
int retval = dpm->prepare(dpm); int retval = dpm->prepare(dpm);
if (retval!=ERROR_OK) goto done; if (retval != ERROR_OK)
goto done;
/* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/ /* MRC p15,0,<Rt>,c2,c0,2 ; Read CP15 Translation Table Base Control Register*/
retval = dpm->instr_read_data_r0(dpm, retval = dpm->instr_read_data_r0(dpm,
ARMV4_5_MRC(15, 0, 0, 2, 0, 2), ARMV4_5_MRC(15, 0, 0, 2, 0, 2),
&ttbcr); &ttbcr);
if (retval!=ERROR_OK) goto done; if (retval != ERROR_OK)
armv7a->armv7a_mmu.ttbr1_used = ((ttbcr & 0x7)!=0)? 1: 0; goto done;
armv7a->armv7a_mmu.ttbr0_mask = 7 << (32 -((ttbcr & 0x7))); armv7a->armv7a_mmu.ttbr1_used = ((ttbcr & 0x7) != 0) ? 1 : 0;
armv7a->armv7a_mmu.ttbr0_mask = 7 << (32 - ((ttbcr & 0x7)));
#if 0 #if 0
LOG_INFO("ttb1 %s ,ttb0_mask %x", LOG_INFO("ttb1 %s ,ttb0_mask %x",
armv7a->armv7a_mmu.ttbr1_used ? "used":"not used", armv7a->armv7a_mmu.ttbr1_used ? "used" : "not used",
armv7a->armv7a_mmu.ttbr0_mask); armv7a->armv7a_mmu.ttbr0_mask);
#endif #endif
if (armv7a->armv7a_mmu.ttbr1_used == 1) if (armv7a->armv7a_mmu.ttbr1_used == 1) {
{
LOG_INFO("SVC access above %x", LOG_INFO("SVC access above %x",
(0xffffffff & armv7a->armv7a_mmu.ttbr0_mask)); (0xffffffff & armv7a->armv7a_mmu.ttbr0_mask));
armv7a->armv7a_mmu.os_border = 0xffffffff & armv7a->armv7a_mmu.ttbr0_mask; armv7a->armv7a_mmu.os_border = 0xffffffff & armv7a->armv7a_mmu.ttbr0_mask;
} } else {
else
{
/* fix me , default is hard coded LINUX border */ /* fix me , default is hard coded LINUX border */
armv7a->armv7a_mmu.os_border = 0xc0000000; armv7a->armv7a_mmu.os_border = 0xc0000000;
} }
done: done:
dpm->finish(dpm); dpm->finish(dpm);
@ -131,11 +131,11 @@ int armv7a_mmu_translate_va(struct target *target, uint32_t va, uint32_t *val)
int retval; int retval;
struct armv7a_common *armv7a = target_to_armv7a(target); struct armv7a_common *armv7a = target_to_armv7a(target);
struct arm_dpm *dpm = armv7a->arm.dpm; struct arm_dpm *dpm = armv7a->arm.dpm;
uint32_t ttb = 0; /* default ttb0 */ uint32_t ttb = 0; /* default ttb0 */
if (armv7a->armv7a_mmu.ttbr1_used == -1) armv7a_read_ttbcr(target); if (armv7a->armv7a_mmu.ttbr1_used == -1)
armv7a_read_ttbcr(target);
if ((armv7a->armv7a_mmu.ttbr1_used) && if ((armv7a->armv7a_mmu.ttbr1_used) &&
(va > (0xffffffff & armv7a->armv7a_mmu.ttbr0_mask))) (va > (0xffffffff & armv7a->armv7a_mmu.ttbr0_mask))) {
{
/* select ttb 1 */ /* select ttb 1 */
ttb = 1; ttb = 1;
} }
@ -151,74 +151,65 @@ int armv7a_mmu_translate_va(struct target *target, uint32_t va, uint32_t *val)
return retval; return retval;
retval = armv7a->armv7a_mmu.read_physical_memory(target, retval = armv7a->armv7a_mmu.read_physical_memory(target,
(ttb & 0xffffc000) | ((va & 0xfff00000) >> 18), (ttb & 0xffffc000) | ((va & 0xfff00000) >> 18),
4, 1, (uint8_t*)&first_lvl_descriptor); 4, 1, (uint8_t *)&first_lvl_descriptor);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
first_lvl_descriptor = target_buffer_get_u32(target, (uint8_t*) first_lvl_descriptor = target_buffer_get_u32(target, (uint8_t *)
&first_lvl_descriptor); &first_lvl_descriptor);
/* reuse armv4_5 piece of code, specific armv7a changes may come later */ /* reuse armv4_5 piece of code, specific armv7a changes may come later */
LOG_DEBUG("1st lvl desc: %8.8" PRIx32 "", first_lvl_descriptor); LOG_DEBUG("1st lvl desc: %8.8" PRIx32 "", first_lvl_descriptor);
if ((first_lvl_descriptor & 0x3) == 0) if ((first_lvl_descriptor & 0x3) == 0) {
{
LOG_ERROR("Address translation failure"); LOG_ERROR("Address translation failure");
return ERROR_TARGET_TRANSLATION_FAULT; return ERROR_TARGET_TRANSLATION_FAULT;
} }
if ((first_lvl_descriptor & 0x3) == 2) if ((first_lvl_descriptor & 0x3) == 2) {
{
/* section descriptor */ /* section descriptor */
*val = (first_lvl_descriptor & 0xfff00000) | (va & 0x000fffff); *val = (first_lvl_descriptor & 0xfff00000) | (va & 0x000fffff);
return ERROR_OK; return ERROR_OK;
} }
if ((first_lvl_descriptor & 0x3) == 1) if ((first_lvl_descriptor & 0x3) == 1) {
{
/* coarse page table */ /* coarse page table */
retval = armv7a->armv7a_mmu.read_physical_memory(target, retval = armv7a->armv7a_mmu.read_physical_memory(target,
(first_lvl_descriptor & 0xfffffc00) | ((va & 0x000ff000) >> 10), (first_lvl_descriptor & 0xfffffc00) | ((va & 0x000ff000) >> 10),
4, 1, (uint8_t*)&second_lvl_descriptor); 4, 1, (uint8_t *)&second_lvl_descriptor);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
} } else if ((first_lvl_descriptor & 0x3) == 3) {
else if ((first_lvl_descriptor & 0x3) == 3)
{
/* fine page table */ /* fine page table */
retval = armv7a->armv7a_mmu.read_physical_memory(target, retval = armv7a->armv7a_mmu.read_physical_memory(target,
(first_lvl_descriptor & 0xfffff000) | ((va & 0x000ffc00) >> 8), (first_lvl_descriptor & 0xfffff000) | ((va & 0x000ffc00) >> 8),
4, 1, (uint8_t*)&second_lvl_descriptor); 4, 1, (uint8_t *)&second_lvl_descriptor);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
} }
second_lvl_descriptor = target_buffer_get_u32(target, (uint8_t*) second_lvl_descriptor = target_buffer_get_u32(target, (uint8_t *)
&second_lvl_descriptor); &second_lvl_descriptor);
LOG_DEBUG("2nd lvl desc: %8.8" PRIx32 "", second_lvl_descriptor); LOG_DEBUG("2nd lvl desc: %8.8" PRIx32 "", second_lvl_descriptor);
if ((second_lvl_descriptor & 0x3) == 0) if ((second_lvl_descriptor & 0x3) == 0) {
{
LOG_ERROR("Address translation failure"); LOG_ERROR("Address translation failure");
return ERROR_TARGET_TRANSLATION_FAULT; return ERROR_TARGET_TRANSLATION_FAULT;
} }
if ((second_lvl_descriptor & 0x3) == 1) if ((second_lvl_descriptor & 0x3) == 1) {
{
/* large page descriptor */ /* large page descriptor */
*val = (second_lvl_descriptor & 0xffff0000) | (va & 0x0000ffff); *val = (second_lvl_descriptor & 0xffff0000) | (va & 0x0000ffff);
return ERROR_OK; return ERROR_OK;
} }
if ((second_lvl_descriptor & 0x3) == 2) if ((second_lvl_descriptor & 0x3) == 2) {
{
/* small page descriptor */ /* small page descriptor */
*val = (second_lvl_descriptor & 0xfffff000) | (va & 0x00000fff); *val = (second_lvl_descriptor & 0xfffff000) | (va & 0x00000fff);
return ERROR_OK; return ERROR_OK;
} }
if ((second_lvl_descriptor & 0x3) == 3) if ((second_lvl_descriptor & 0x3) == 3) {
{
*val = (second_lvl_descriptor & 0xfffffc00) | (va & 0x000003ff); *val = (second_lvl_descriptor & 0xfffffc00) | (va & 0x000003ff);
return ERROR_OK; return ERROR_OK;
} }
@ -231,69 +222,80 @@ done:
return retval; return retval;
} }
/* V7 method VA TO PA */ /* V7 method VA TO PA */
int armv7a_mmu_translate_va_pa(struct target *target, uint32_t va, int armv7a_mmu_translate_va_pa(struct target *target, uint32_t va,
uint32_t *val, int meminfo) uint32_t *val, int meminfo)
{ {
int retval = ERROR_FAIL; int retval = ERROR_FAIL;
struct armv7a_common *armv7a = target_to_armv7a(target); struct armv7a_common *armv7a = target_to_armv7a(target);
struct arm_dpm *dpm = armv7a->arm.dpm; struct arm_dpm *dpm = armv7a->arm.dpm;
uint32_t virt = va & ~0xfff; uint32_t virt = va & ~0xfff;
uint32_t NOS,NS,INNER,OUTER; uint32_t NOS, NS, INNER, OUTER;
*val = 0xdeadbeef; *val = 0xdeadbeef;
retval = dpm->prepare(dpm); retval = dpm->prepare(dpm);
if (retval != ERROR_OK) if (retval != ERROR_OK)
goto done; goto done;
/* mmu must be enable in order to get a correct translation */ /* mmu must be enable in order to get a correct translation
/* use VA to PA CP15 register for conversion */ * use VA to PA CP15 register for conversion */
retval = dpm->instr_write_data_r0(dpm, retval = dpm->instr_write_data_r0(dpm,
ARMV4_5_MCR(15, 0, 0, 7, 8, 0), ARMV4_5_MCR(15, 0, 0, 7, 8, 0),
virt); virt);
if (retval!=ERROR_OK) goto done; if (retval != ERROR_OK)
goto done;
retval = dpm->instr_read_data_r0(dpm, retval = dpm->instr_read_data_r0(dpm,
ARMV4_5_MRC(15, 0, 0, 7, 4, 0), ARMV4_5_MRC(15, 0, 0, 7, 4, 0),
val); val);
/* decode memory attribute */ /* decode memory attribute */
NOS = (*val >> 10) & 1; /* Not Outer shareable */ NOS = (*val >> 10) & 1; /* Not Outer shareable */
NS = (*val >> 9) & 1; /* Non secure */ NS = (*val >> 9) & 1; /* Non secure */
INNER = (*val >> 4) & 0x7; INNER = (*val >> 4) & 0x7;
OUTER = (*val >> 2) & 0x3; OUTER = (*val >> 2) & 0x3;
if (retval!=ERROR_OK) goto done; if (retval != ERROR_OK)
goto done;
*val = (*val & ~0xfff) + (va & 0xfff); *val = (*val & ~0xfff) + (va & 0xfff);
if (*val == va) if (*val == va)
LOG_WARNING("virt = phys : MMU disable !!"); LOG_WARNING("virt = phys : MMU disable !!");
if (meminfo) if (meminfo) {
{
LOG_INFO("%x : %x %s outer shareable %s secured", LOG_INFO("%x : %x %s outer shareable %s secured",
va, *val, va, *val,
NOS == 1 ? "not" : " ", NOS == 1 ? "not" : " ",
NS == 1 ? "not" :""); NS == 1 ? "not" : "");
switch (OUTER) { switch (OUTER) {
case 0 : LOG_INFO("outer: Non-Cacheable"); case 0:
break; LOG_INFO("outer: Non-Cacheable");
case 1 : LOG_INFO("outer: Write-Back, Write-Allocate"); break;
break; case 1:
case 2 : LOG_INFO("outer: Write-Through, No Write-Allocate"); LOG_INFO("outer: Write-Back, Write-Allocate");
break; break;
case 3 : LOG_INFO("outer: Write-Back, no Write-Allocate"); case 2:
break; LOG_INFO("outer: Write-Through, No Write-Allocate");
break;
case 3:
LOG_INFO("outer: Write-Back, no Write-Allocate");
break;
} }
switch (INNER) { switch (INNER) {
case 0 : LOG_INFO("inner: Non-Cacheable"); case 0:
break; LOG_INFO("inner: Non-Cacheable");
case 1 : LOG_INFO("inner: Strongly-ordered"); break;
break; case 1:
case 3 : LOG_INFO("inner: Device"); LOG_INFO("inner: Strongly-ordered");
break; break;
case 5 : LOG_INFO("inner: Write-Back, Write-Allocate"); case 3:
break; LOG_INFO("inner: Device");
case 6 : LOG_INFO("inner: Write-Through"); break;
break; case 5:
case 7 : LOG_INFO("inner: Write-Back, no Write-Allocate"); LOG_INFO("inner: Write-Back, Write-Allocate");
break;
case 6:
LOG_INFO("inner: Write-Through");
break;
case 7:
LOG_INFO("inner: Write-Back, no Write-Allocate");
default: LOG_INFO("inner: %x ???",INNER); default:
LOG_INFO("inner: %x ???", INNER);
} }
} }
@ -304,27 +306,26 @@ done:
} }
static int armv7a_handle_inner_cache_info_command(struct command_context *cmd_ctx, static int armv7a_handle_inner_cache_info_command(struct command_context *cmd_ctx,
struct armv7a_cache_common *armv7a_cache) struct armv7a_cache_common *armv7a_cache)
{ {
if (armv7a_cache->ctype == -1) if (armv7a_cache->ctype == -1) {
{
command_print(cmd_ctx, "cache not yet identified"); command_print(cmd_ctx, "cache not yet identified");
return ERROR_OK; return ERROR_OK;
} }
command_print(cmd_ctx, command_print(cmd_ctx,
"D-Cache: linelen %i, associativity %i, nsets %i, cachesize %d KBytes", "D-Cache: linelen %i, associativity %i, nsets %i, cachesize %d KBytes",
armv7a_cache->d_u_size.linelen, armv7a_cache->d_u_size.linelen,
armv7a_cache->d_u_size.associativity, armv7a_cache->d_u_size.associativity,
armv7a_cache->d_u_size.nsets, armv7a_cache->d_u_size.nsets,
armv7a_cache->d_u_size.cachesize); armv7a_cache->d_u_size.cachesize);
command_print(cmd_ctx, command_print(cmd_ctx,
"I-Cache: linelen %i, associativity %i, nsets %i, cachesize %d KBytes", "I-Cache: linelen %i, associativity %i, nsets %i, cachesize %d KBytes",
armv7a_cache->i_size.linelen, armv7a_cache->i_size.linelen,
armv7a_cache->i_size.associativity, armv7a_cache->i_size.associativity,
armv7a_cache->i_size.nsets, armv7a_cache->i_size.nsets,
armv7a_cache->i_size.cachesize); armv7a_cache->i_size.cachesize);
return ERROR_OK; return ERROR_OK;
} }
@ -338,28 +339,29 @@ static int _armv7a_flush_all_data(struct target *target)
int32_t c_way, c_index = d_u_size->index; int32_t c_way, c_index = d_u_size->index;
int retval; int retval;
/* check that cache data is on at target halt */ /* check that cache data is on at target halt */
if (!armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled) if (!armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled) {
{
LOG_INFO("flushed not performed :cache not on at target halt"); LOG_INFO("flushed not performed :cache not on at target halt");
return ERROR_OK; return ERROR_OK;
} }
retval = dpm->prepare(dpm); retval = dpm->prepare(dpm);
if (retval != ERROR_OK) goto done; if (retval != ERROR_OK)
goto done;
do { do {
c_way = d_u_size->way; c_way = d_u_size->way;
do { do {
uint32_t value = (c_index << d_u_size->index_shift) uint32_t value = (c_index << d_u_size->index_shift)
| (c_way << d_u_size->way_shift); | (c_way << d_u_size->way_shift);
/* DCCISW */ /* DCCISW */
//LOG_INFO ("%d %d %x",c_way,c_index,value); /* LOG_INFO ("%d %d %x",c_way,c_index,value); */
retval = dpm->instr_write_data_r0(dpm, retval = dpm->instr_write_data_r0(dpm,
ARMV4_5_MCR(15, 0, 0, 7, 14, 2), ARMV4_5_MCR(15, 0, 0, 7, 14, 2),
value); value);
if (retval!= ERROR_OK) goto done; if (retval != ERROR_OK)
goto done;
c_way -= 1; c_way -= 1;
} while (c_way >=0); } while (c_way >= 0);
c_index -= 1; c_index -= 1;
} while (c_index >=0); } while (c_index >= 0);
return retval; return retval;
done: done:
LOG_ERROR("flushed failed"); LOG_ERROR("flushed failed");
@ -367,89 +369,85 @@ done:
return retval; return retval;
} }
static int armv7a_flush_all_data( struct target * target) static int armv7a_flush_all_data(struct target *target)
{ {
int retval = ERROR_FAIL; int retval = ERROR_FAIL;
/* check that armv7a_cache is correctly identify */ /* check that armv7a_cache is correctly identify */
struct armv7a_common *armv7a = target_to_armv7a(target); struct armv7a_common *armv7a = target_to_armv7a(target);
if (armv7a->armv7a_mmu.armv7a_cache.ctype == -1) if (armv7a->armv7a_mmu.armv7a_cache.ctype == -1) {
{
LOG_ERROR("trying to flush un-identified cache"); LOG_ERROR("trying to flush un-identified cache");
return retval; return retval;
} }
if (target->smp) if (target->smp) {
{
/* look if all the other target have been flushed in order to flush level /* look if all the other target have been flushed in order to flush level
* 2 */ * 2 */
struct target_list *head; struct target_list *head;
struct target *curr; struct target *curr;
head = target->head; head = target->head;
while(head != (struct target_list*)NULL) while (head != (struct target_list *)NULL) {
{
curr = head->target; curr = head->target;
if ((curr->state == TARGET_HALTED)) if ((curr->state == TARGET_HALTED)) {
{ LOG_INFO("Wait flushing data l1 on core %d",curr->coreid); LOG_INFO("Wait flushing data l1 on core %d", curr->coreid);
retval = _armv7a_flush_all_data(curr); retval = _armv7a_flush_all_data(curr);
} }
head = head->next; head = head->next;
} }
} } else
else retval = _armv7a_flush_all_data(target); retval = _armv7a_flush_all_data(target);
return retval; return retval;
} }
/* L2 is not specific to armv7a a specific file is needed */ /* L2 is not specific to armv7a a specific file is needed */
static int armv7a_l2x_flush_all_data(struct target * target) static int armv7a_l2x_flush_all_data(struct target *target)
{ {
#define L2X0_CLEAN_INV_WAY 0x7FC #define L2X0_CLEAN_INV_WAY 0x7FC
int retval = ERROR_FAIL; int retval = ERROR_FAIL;
struct armv7a_common *armv7a = target_to_armv7a(target); struct armv7a_common *armv7a = target_to_armv7a(target);
struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache*) struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *)
(armv7a->armv7a_mmu.armv7a_cache.l2_cache); (armv7a->armv7a_mmu.armv7a_cache.l2_cache);
uint32_t base = l2x_cache->base; uint32_t base = l2x_cache->base;
uint32_t l2_way = l2x_cache->way; uint32_t l2_way = l2x_cache->way;
uint32_t l2_way_val = (1<<l2_way) -1; uint32_t l2_way_val = (1 << l2_way) - 1;
retval = armv7a_flush_all_data(target); retval = armv7a_flush_all_data(target);
if (retval!=ERROR_OK) return retval; if (retval != ERROR_OK)
return retval;
retval = target->type->write_phys_memory(target, retval = target->type->write_phys_memory(target,
(uint32_t)(base+(uint32_t)L2X0_CLEAN_INV_WAY), (uint32_t)(base+(uint32_t)L2X0_CLEAN_INV_WAY),
(uint32_t)4, (uint32_t)4,
(uint32_t)1, (uint32_t)1,
(uint8_t*)&l2_way_val); (uint8_t *)&l2_way_val);
return retval; return retval;
} }
static int armv7a_handle_l2x_cache_info_command(struct command_context *cmd_ctx, static int armv7a_handle_l2x_cache_info_command(struct command_context *cmd_ctx,
struct armv7a_cache_common *armv7a_cache) struct armv7a_cache_common *armv7a_cache)
{ {
struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache*) struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *)
(armv7a_cache->l2_cache); (armv7a_cache->l2_cache);
if (armv7a_cache->ctype == -1) if (armv7a_cache->ctype == -1) {
{
command_print(cmd_ctx, "cache not yet identified"); command_print(cmd_ctx, "cache not yet identified");
return ERROR_OK; return ERROR_OK;
} }
command_print(cmd_ctx, command_print(cmd_ctx,
"L1 D-Cache: linelen %i, associativity %i, nsets %i, cachesize %d KBytes", "L1 D-Cache: linelen %i, associativity %i, nsets %i, cachesize %d KBytes",
armv7a_cache->d_u_size.linelen, armv7a_cache->d_u_size.linelen,
armv7a_cache->d_u_size.associativity, armv7a_cache->d_u_size.associativity,
armv7a_cache->d_u_size.nsets, armv7a_cache->d_u_size.nsets,
armv7a_cache->d_u_size.cachesize); armv7a_cache->d_u_size.cachesize);
command_print(cmd_ctx, command_print(cmd_ctx,
"L1 I-Cache: linelen %i, associativity %i, nsets %i, cachesize %d KBytes", "L1 I-Cache: linelen %i, associativity %i, nsets %i, cachesize %d KBytes",
armv7a_cache->i_size.linelen, armv7a_cache->i_size.linelen,
armv7a_cache->i_size.associativity, armv7a_cache->i_size.associativity,
armv7a_cache->i_size.nsets, armv7a_cache->i_size.nsets,
armv7a_cache->i_size.cachesize); armv7a_cache->i_size.cachesize);
command_print(cmd_ctx, "L2 unified cache Base Address 0x%x, %d ways", command_print(cmd_ctx, "L2 unified cache Base Address 0x%x, %d ways",
l2x_cache->base, l2x_cache->way); l2x_cache->base, l2x_cache->way);
return ERROR_OK; return ERROR_OK;
@ -469,34 +467,28 @@ static int armv7a_l2x_cache_init(struct target *target, uint32_t base, uint32_t
/*LOG_INFO("cache l2 initialized base %x way %d", /*LOG_INFO("cache l2 initialized base %x way %d",
l2x_cache->base,l2x_cache->way);*/ l2x_cache->base,l2x_cache->way);*/
if (armv7a->armv7a_mmu.armv7a_cache.l2_cache) if (armv7a->armv7a_mmu.armv7a_cache.l2_cache)
{
LOG_INFO("cache l2 already initialized\n"); LOG_INFO("cache l2 already initialized\n");
} armv7a->armv7a_mmu.armv7a_cache.l2_cache = (void *) l2x_cache;
armv7a->armv7a_mmu.armv7a_cache.l2_cache = (void*) l2x_cache;
/* initialize l1 / l2x cache function */ /* initialize l1 / l2x cache function */
armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache
= armv7a_l2x_flush_all_data; = armv7a_l2x_flush_all_data;
armv7a->armv7a_mmu.armv7a_cache.display_cache_info = armv7a->armv7a_mmu.armv7a_cache.display_cache_info =
armv7a_handle_l2x_cache_info_command; armv7a_handle_l2x_cache_info_command;
/* initialize all target in this cluster (smp target)*/ /* initialize all target in this cluster (smp target)
/* l2 cache must be configured after smp declaration */ * l2 cache must be configured after smp declaration */
while(head != (struct target_list*)NULL) while (head != (struct target_list *)NULL) {
{
curr = head->target; curr = head->target;
if (curr != target) if (curr != target) {
{
armv7a = target_to_armv7a(curr); armv7a = target_to_armv7a(curr);
if (armv7a->armv7a_mmu.armv7a_cache.l2_cache) if (armv7a->armv7a_mmu.armv7a_cache.l2_cache)
{
LOG_ERROR("smp target : cache l2 already initialized\n"); LOG_ERROR("smp target : cache l2 already initialized\n");
} armv7a->armv7a_mmu.armv7a_cache.l2_cache = (void *) l2x_cache;
armv7a->armv7a_mmu.armv7a_cache.l2_cache = (void*) l2x_cache;
armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache = armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache =
armv7a_l2x_flush_all_data; armv7a_l2x_flush_all_data;
armv7a->armv7a_mmu.armv7a_cache.display_cache_info = armv7a->armv7a_mmu.armv7a_cache.display_cache_info =
armv7a_handle_l2x_cache_info_command; armv7a_handle_l2x_cache_info_command;
} }
head = head -> next; head = head->next;
} }
return JIM_OK; return JIM_OK;
} }
@ -504,33 +496,29 @@ static int armv7a_l2x_cache_init(struct target *target, uint32_t base, uint32_t
COMMAND_HANDLER(handle_cache_l2x) COMMAND_HANDLER(handle_cache_l2x)
{ {
struct target *target = get_current_target(CMD_CTX); struct target *target = get_current_target(CMD_CTX);
uint32_t base, way; uint32_t base, way;
switch (CMD_ARGC) { switch (CMD_ARGC) {
case 0: case 0:
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
break; break;
case 2: case 2:
//command_print(CMD_CTX, "%s %s", CMD_ARGV[0], CMD_ARGV[1]); /* command_print(CMD_CTX, "%s %s", CMD_ARGV[0], CMD_ARGV[1]); */
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], base);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], way);
/* AP address is in bits 31:24 of DP_SELECT */
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], base); armv7a_l2x_cache_init(target, base, way);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], way); break;
default:
/* AP address is in bits 31:24 of DP_SELECT */ return ERROR_COMMAND_SYNTAX_ERROR;
armv7a_l2x_cache_init(target, base, way);
break;
default:
return ERROR_COMMAND_SYNTAX_ERROR;
} }
return ERROR_OK; return ERROR_OK;
} }
int armv7a_handle_cache_info_command(struct command_context *cmd_ctx, int armv7a_handle_cache_info_command(struct command_context *cmd_ctx,
struct armv7a_cache_common *armv7a_cache) struct armv7a_cache_common *armv7a_cache)
{ {
if (armv7a_cache->ctype == -1) if (armv7a_cache->ctype == -1) {
{
command_print(cmd_ctx, "cache not yet identified"); command_print(cmd_ctx, "cache not yet identified");
return ERROR_OK; return ERROR_OK;
} }
@ -540,35 +528,34 @@ int armv7a_handle_cache_info_command(struct command_context *cmd_ctx,
return ERROR_OK; return ERROR_OK;
} }
/* retrieve core id cluster id */ /* retrieve core id cluster id */
static int armv7a_read_mpidr(struct target *target) static int armv7a_read_mpidr(struct target *target)
{ {
int retval = ERROR_FAIL; int retval = ERROR_FAIL;
struct armv7a_common *armv7a = target_to_armv7a(target); struct armv7a_common *armv7a = target_to_armv7a(target);
struct arm_dpm *dpm = armv7a->arm.dpm; struct arm_dpm *dpm = armv7a->arm.dpm;
uint32_t mpidr; uint32_t mpidr;
retval = dpm->prepare(dpm); retval = dpm->prepare(dpm);
if (retval!=ERROR_OK) goto done; if (retval != ERROR_OK)
goto done;
/* MRC p15,0,<Rd>,c0,c0,5; read Multiprocessor ID register*/ /* MRC p15,0,<Rd>,c0,c0,5; read Multiprocessor ID register*/
retval = dpm->instr_read_data_r0(dpm, retval = dpm->instr_read_data_r0(dpm,
ARMV4_5_MRC(15, 0, 0, 0, 0, 5), ARMV4_5_MRC(15, 0, 0, 0, 0, 5),
&mpidr); &mpidr);
if (retval!=ERROR_OK) goto done; if (retval != ERROR_OK)
if (mpidr & 1<<31) goto done;
{ if (mpidr & 1<<31) {
armv7a->multi_processor_system = (mpidr >> 30) & 1; armv7a->multi_processor_system = (mpidr >> 30) & 1;
armv7a->cluster_id = (mpidr >> 8) & 0xf; armv7a->cluster_id = (mpidr >> 8) & 0xf;
armv7a->cpu_id = mpidr & 0x3; armv7a->cpu_id = mpidr & 0x3;
LOG_INFO("%s cluster %x core %x %s", target->cmd_name, LOG_INFO("%s cluster %x core %x %s", target->cmd_name,
armv7a->cluster_id, armv7a->cluster_id,
armv7a->cpu_id, armv7a->cpu_id,
armv7a->multi_processor_system == 0 ? "multi core": "mono core"); armv7a->multi_processor_system == 0 ? "multi core" : "mono core");
} } else
else LOG_ERROR("mpdir not in multiprocessor format");
LOG_ERROR("mpdir not in multiprocessor format");
done: done:
dpm->finish(dpm); dpm->finish(dpm);
@ -577,138 +564,149 @@ done:
} }
int armv7a_identify_cache(struct target *target) int armv7a_identify_cache(struct target *target)
{ {
/* read cache descriptor */ /* read cache descriptor */
int retval = ERROR_FAIL; int retval = ERROR_FAIL;
struct armv7a_common *armv7a = target_to_armv7a(target); struct armv7a_common *armv7a = target_to_armv7a(target);
struct arm_dpm *dpm = armv7a->arm.dpm; struct arm_dpm *dpm = armv7a->arm.dpm;
uint32_t cache_selected,clidr; uint32_t cache_selected, clidr;
uint32_t cache_i_reg, cache_d_reg; uint32_t cache_i_reg, cache_d_reg;
struct armv7a_cache_common *cache = &(armv7a->armv7a_mmu.armv7a_cache); struct armv7a_cache_common *cache = &(armv7a->armv7a_mmu.armv7a_cache);
armv7a_read_ttbcr(target); armv7a_read_ttbcr(target);
retval = dpm->prepare(dpm); retval = dpm->prepare(dpm);
if (retval!=ERROR_OK) goto done; if (retval != ERROR_OK)
/* retrieve CLIDR */ goto done;
/* mrc p15, 1, r0, c0, c0, 1 @ read clidr */ /* retrieve CLIDR
* mrc p15, 1, r0, c0, c0, 1 @ read clidr */
retval = dpm->instr_read_data_r0(dpm, retval = dpm->instr_read_data_r0(dpm,
ARMV4_5_MRC(15, 1, 0, 0, 0, 1), ARMV4_5_MRC(15, 1, 0, 0, 0, 1),
&clidr); &clidr);
if (retval!=ERROR_OK) goto done; if (retval != ERROR_OK)
goto done;
clidr = (clidr & 0x7000000) >> 23; clidr = (clidr & 0x7000000) >> 23;
LOG_INFO("number of cache level %d",clidr /2 ); LOG_INFO("number of cache level %d", clidr / 2);
if ((clidr /2) > 1) if ((clidr / 2) > 1) {
{ /* FIXME not supported present in cortex A8 and later */
// FIXME not supported present in cortex A8 and later /* in cortex A7, A15 */
// in cortex A7, A15
LOG_ERROR("cache l2 present :not supported"); LOG_ERROR("cache l2 present :not supported");
} }
/* retrieve selected cache */ /* retrieve selected cache
/* MRC p15, 2,<Rd>, c0, c0, 0; Read CSSELR */ * MRC p15, 2,<Rd>, c0, c0, 0; Read CSSELR */
retval = dpm->instr_read_data_r0(dpm, retval = dpm->instr_read_data_r0(dpm,
ARMV4_5_MRC(15, 2, 0, 0, 0, 0), ARMV4_5_MRC(15, 2, 0, 0, 0, 0),
&cache_selected); &cache_selected);
if (retval!=ERROR_OK) goto done; if (retval != ERROR_OK)
goto done;
retval = armv7a->arm.mrc(target, 15, retval = armv7a->arm.mrc(target, 15,
2, 0, /* op1, op2 */ 2, 0, /* op1, op2 */
0, 0, /* CRn, CRm */ 0, 0, /* CRn, CRm */
&cache_selected); &cache_selected);
if (retval!=ERROR_OK) goto done; if (retval != ERROR_OK)
/* select instruction cache*/ goto done;
/* MCR p15, 2,<Rd>, c0, c0, 0; Write CSSELR */ /* select instruction cache
/* [0] : 1 instruction cache selection , 0 data cache selection */ * MCR p15, 2,<Rd>, c0, c0, 0; Write CSSELR
* [0] : 1 instruction cache selection , 0 data cache selection */
retval = dpm->instr_write_data_r0(dpm, retval = dpm->instr_write_data_r0(dpm,
ARMV4_5_MRC(15, 2, 0, 0, 0, 0), ARMV4_5_MRC(15, 2, 0, 0, 0, 0),
1); 1);
if (retval!=ERROR_OK) goto done; if (retval != ERROR_OK)
goto done;
/* read CCSIDR*/ /* read CCSIDR
/* MRC P15,1,<RT>,C0, C0,0 ;on cortex A9 read CCSIDR */ * MRC P15,1,<RT>,C0, C0,0 ;on cortex A9 read CCSIDR
/* [2:0] line size 001 eight word per line */ * [2:0] line size 001 eight word per line
/* [27:13] NumSet 0x7f 16KB, 0xff 32Kbytes, 0x1ff 64Kbytes */ * [27:13] NumSet 0x7f 16KB, 0xff 32Kbytes, 0x1ff 64Kbytes */
retval = dpm->instr_read_data_r0(dpm, retval = dpm->instr_read_data_r0(dpm,
ARMV4_5_MRC(15, 1, 0, 0, 0, 0), ARMV4_5_MRC(15, 1, 0, 0, 0, 0),
&cache_i_reg); &cache_i_reg);
if (retval!=ERROR_OK) goto done; if (retval != ERROR_OK)
goto done;
/* select data cache*/ /* select data cache*/
retval = dpm->instr_write_data_r0(dpm, retval = dpm->instr_write_data_r0(dpm,
ARMV4_5_MRC(15, 2, 0, 0, 0, 0), ARMV4_5_MRC(15, 2, 0, 0, 0, 0),
0); 0);
if (retval!=ERROR_OK) goto done; if (retval != ERROR_OK)
goto done;
retval = dpm->instr_read_data_r0(dpm, retval = dpm->instr_read_data_r0(dpm,
ARMV4_5_MRC(15, 1, 0, 0, 0, 0), ARMV4_5_MRC(15, 1, 0, 0, 0, 0),
&cache_d_reg); &cache_d_reg);
if (retval!=ERROR_OK) goto done; if (retval != ERROR_OK)
goto done;
/* restore selected cache */ /* restore selected cache */
dpm->instr_write_data_r0(dpm, dpm->instr_write_data_r0(dpm,
ARMV4_5_MRC(15, 2, 0, 0, 0, 0), ARMV4_5_MRC(15, 2, 0, 0, 0, 0),
cache_selected); cache_selected);
if (retval != ERROR_OK) goto done; if (retval != ERROR_OK)
goto done;
dpm->finish(dpm); dpm->finish(dpm);
// put fake type /* put fake type */
cache->d_u_size.linelen = 16 << (cache_d_reg & 0x7); cache->d_u_size.linelen = 16 << (cache_d_reg & 0x7);
cache->d_u_size.cachesize = (((cache_d_reg >> 13) & 0x7fff)+1)/8; cache->d_u_size.cachesize = (((cache_d_reg >> 13) & 0x7fff)+1)/8;
cache->d_u_size.nsets = (cache_d_reg >> 13) & 0x7fff; cache->d_u_size.nsets = (cache_d_reg >> 13) & 0x7fff;
cache->d_u_size.associativity = ((cache_d_reg >> 3) & 0x3ff) +1; cache->d_u_size.associativity = ((cache_d_reg >> 3) & 0x3ff) + 1;
/* compute info for set way operation on cache */ /* compute info for set way operation on cache */
cache->d_u_size.index_shift = (cache_d_reg & 0x7) + 4; cache->d_u_size.index_shift = (cache_d_reg & 0x7) + 4;
cache->d_u_size.index = (cache_d_reg >> 13) & 0x7fff; cache->d_u_size.index = (cache_d_reg >> 13) & 0x7fff;
cache->d_u_size.way = ((cache_d_reg >> 3) & 0x3ff); cache->d_u_size.way = ((cache_d_reg >> 3) & 0x3ff);
cache->d_u_size.way_shift = cache->d_u_size.way+1; cache->d_u_size.way_shift = cache->d_u_size.way + 1;
{ {
int i=0; int i = 0;
while(((cache->d_u_size.way_shift >> i) & 1)!=1) i++; while (((cache->d_u_size.way_shift >> i) & 1) != 1)
i++;
cache->d_u_size.way_shift = 32-i; cache->d_u_size.way_shift = 32-i;
} }
/*LOG_INFO("data cache index %d << %d, way %d << %d", #if 0
LOG_INFO("data cache index %d << %d, way %d << %d",
cache->d_u_size.index, cache->d_u_size.index_shift, cache->d_u_size.index, cache->d_u_size.index_shift,
cache->d_u_size.way, cache->d_u_size.way_shift); cache->d_u_size.way,
cache->d_u_size.way_shift);
LOG_INFO("data cache %d bytes %d KBytes asso %d ways", LOG_INFO("data cache %d bytes %d KBytes asso %d ways",
cache->d_u_size.linelen, cache->d_u_size.linelen,
cache->d_u_size.cachesize, cache->d_u_size.cachesize,
cache->d_u_size.associativity cache->d_u_size.associativity);
);*/ #endif
cache->i_size.linelen = 16 << (cache_i_reg & 0x7); cache->i_size.linelen = 16 << (cache_i_reg & 0x7);
cache->i_size.associativity = ((cache_i_reg >> 3) & 0x3ff) +1; cache->i_size.associativity = ((cache_i_reg >> 3) & 0x3ff) + 1;
cache->i_size.nsets = (cache_i_reg >> 13) & 0x7fff; cache->i_size.nsets = (cache_i_reg >> 13) & 0x7fff;
cache->i_size.cachesize = (((cache_i_reg >> 13) & 0x7fff)+1)/8; cache->i_size.cachesize = (((cache_i_reg >> 13) & 0x7fff)+1)/8;
/* compute info for set way operation on cache */ /* compute info for set way operation on cache */
cache->i_size.index_shift = (cache_i_reg & 0x7) + 4; cache->i_size.index_shift = (cache_i_reg & 0x7) + 4;
cache->i_size.index = (cache_i_reg >> 13) & 0x7fff; cache->i_size.index = (cache_i_reg >> 13) & 0x7fff;
cache->i_size.way = ((cache_i_reg >> 3) & 0x3ff); cache->i_size.way = ((cache_i_reg >> 3) & 0x3ff);
cache->i_size.way_shift = cache->i_size.way+1; cache->i_size.way_shift = cache->i_size.way + 1;
{ {
int i=0; int i = 0;
while(((cache->i_size.way_shift >> i) & 1)!=1) i++; while (((cache->i_size.way_shift >> i) & 1) != 1)
i++;
cache->i_size.way_shift = 32-i; cache->i_size.way_shift = 32-i;
} }
/*LOG_INFO("instruction cache index %d << %d, way %d << %d", #if 0
LOG_INFO("instruction cache index %d << %d, way %d << %d",
cache->i_size.index, cache->i_size.index_shift, cache->i_size.index, cache->i_size.index_shift,
cache->i_size.way, cache->i_size.way_shift); cache->i_size.way, cache->i_size.way_shift);
LOG_INFO("instruction cache %d bytes %d KBytes asso %d ways", LOG_INFO("instruction cache %d bytes %d KBytes asso %d ways",
cache->i_size.linelen, cache->i_size.linelen,
cache->i_size.cachesize, cache->i_size.cachesize,
cache->i_size.associativity cache->i_size.associativity);
);*/ #endif
/* if no l2 cache initialize l1 data cache flush function function */ /* if no l2 cache initialize l1 data cache flush function function */
if (armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache == NULL) if (armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache == NULL) {
{
armv7a->armv7a_mmu.armv7a_cache.display_cache_info = armv7a->armv7a_mmu.armv7a_cache.display_cache_info =
armv7a_handle_inner_cache_info_command; armv7a_handle_inner_cache_info_command;
armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache = armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache =
armv7a_flush_all_data; armv7a_flush_all_data;
} }
armv7a->armv7a_mmu.armv7a_cache.ctype = 0; armv7a->armv7a_mmu.armv7a_cache.ctype = 0;
done: done:
dpm->finish(dpm); dpm->finish(dpm);
@ -717,8 +715,6 @@ done:
} }
int armv7a_init_arch_info(struct target *target, struct armv7a_common *armv7a) int armv7a_init_arch_info(struct target *target, struct armv7a_common *armv7a)
{ {
struct arm *arm = &armv7a->arm; struct arm *arm = &armv7a->arm;
@ -726,27 +722,25 @@ int armv7a_init_arch_info(struct target *target, struct armv7a_common *armv7a)
target->arch_info = &armv7a->arm; target->arch_info = &armv7a->arm;
/* target is useful in all function arm v4 5 compatible */ /* target is useful in all function arm v4 5 compatible */
armv7a->arm.target = target; armv7a->arm.target = target;
armv7a->arm.common_magic = ARM_COMMON_MAGIC; armv7a->arm.common_magic = ARM_COMMON_MAGIC;
armv7a->common_magic = ARMV7_COMMON_MAGIC; armv7a->common_magic = ARMV7_COMMON_MAGIC;
armv7a->armv7a_mmu.armv7a_cache.l2_cache = NULL; armv7a->armv7a_mmu.armv7a_cache.l2_cache = NULL;
armv7a->armv7a_mmu.armv7a_cache.ctype = -1; armv7a->armv7a_mmu.armv7a_cache.ctype = -1;
armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache = NULL; armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache = NULL;
armv7a->armv7a_mmu.armv7a_cache.display_cache_info = NULL; armv7a->armv7a_mmu.armv7a_cache.display_cache_info = NULL;
return ERROR_OK; return ERROR_OK;
} }
int armv7a_arch_state(struct target *target) int armv7a_arch_state(struct target *target)
{ {
static const char *state[] = static const char *state[] = {
{
"disabled", "enabled" "disabled", "enabled"
}; };
struct armv7a_common *armv7a = target_to_armv7a(target); struct armv7a_common *armv7a = target_to_armv7a(target);
struct arm *arm = &armv7a->arm; struct arm *arm = &armv7a->arm;
if (armv7a->common_magic != ARMV7_COMMON_MAGIC) if (armv7a->common_magic != ARMV7_COMMON_MAGIC) {
{
LOG_ERROR("BUG: called for a non-ARMv7A target"); LOG_ERROR("BUG: called for a non-ARMv7A target");
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
@ -754,15 +748,15 @@ int armv7a_arch_state(struct target *target)
arm_arch_state(target); arm_arch_state(target);
LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s", LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s",
state[armv7a->armv7a_mmu.mmu_enabled], state[armv7a->armv7a_mmu.mmu_enabled],
state[armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled], state[armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled],
state[armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled]); state[armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled]);
if (arm->core_mode == ARM_MODE_ABT) if (arm->core_mode == ARM_MODE_ABT)
armv7a_show_fault_registers(target); armv7a_show_fault_registers(target);
if (target->debug_reason == DBG_REASON_WATCHPOINT) if (target->debug_reason == DBG_REASON_WATCHPOINT)
LOG_USER("Watchpoint triggered at PC %#08x", LOG_USER("Watchpoint triggered at PC %#08x",
(unsigned) armv7a->dpm.wp_pc); (unsigned) armv7a->dpm.wp_pc);
return ERROR_OK; return ERROR_OK;
} }
@ -776,7 +770,7 @@ static const struct command_registration l2_cache_commands[] = {
"", "",
.usage = "[base_addr] [number_of_way]", .usage = "[base_addr] [number_of_way]",
}, },
COMMAND_REGISTRATION_DONE COMMAND_REGISTRATION_DONE
}; };
@ -801,4 +795,3 @@ const struct command_registration armv7a_command_handlers[] = {
}, },
COMMAND_REGISTRATION_DONE COMMAND_REGISTRATION_DONE
}; };

View File

@ -16,6 +16,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARMV7A_H #ifndef ARMV7A_H
#define ARMV7A_H #define ARMV7A_H
@ -25,12 +26,10 @@
#include "armv4_5_cache.h" #include "armv4_5_cache.h"
#include "arm_dpm.h" #include "arm_dpm.h"
enum enum {
{
ARM_PC = 15, ARM_PC = 15,
ARM_CPSR = 16 ARM_CPSR = 16
} };
;
#define ARMV7_COMMON_MAGIC 0x0A450999 #define ARMV7_COMMON_MAGIC 0x0A450999
@ -49,8 +48,7 @@ struct armv7a_l2x_cache {
uint32_t way; uint32_t way;
}; };
struct armv7a_cachesize struct armv7a_cachesize {
{
uint32_t level_num; uint32_t level_num;
/* cache dimensionning */ /* cache dimensionning */
uint32_t linelen; uint32_t linelen;
@ -64,38 +62,32 @@ struct armv7a_cachesize
uint32_t way_shift; uint32_t way_shift;
}; };
struct armv7a_cache_common {
struct armv7a_cache_common
{
int ctype; int ctype;
struct armv7a_cachesize d_u_size; /* data cache */ struct armv7a_cachesize d_u_size; /* data cache */
struct armv7a_cachesize i_size; /* instruction cache */ struct armv7a_cachesize i_size; /* instruction cache */
int i_cache_enabled; int i_cache_enabled;
int d_u_cache_enabled; int d_u_cache_enabled;
/* l2 external unified cache if some */ /* l2 external unified cache if some */
void *l2_cache; void *l2_cache;
int (*flush_all_data_cache)(struct target *target); int (*flush_all_data_cache)(struct target *target);
int (*display_cache_info)(struct command_context *cmd_ctx, int (*display_cache_info)(struct command_context *cmd_ctx,
struct armv7a_cache_common *armv7a_cache); struct armv7a_cache_common *armv7a_cache);
}; };
struct armv7a_mmu_common {
struct armv7a_mmu_common /* following field mmu working way */
{
/* following field mmu working way */
int32_t ttbr1_used; /* -1 not initialized, 0 no ttbr1 1 ttbr1 used and */ int32_t ttbr1_used; /* -1 not initialized, 0 no ttbr1 1 ttbr1 used and */
uint32_t ttbr0_mask;/* masked to be used */ uint32_t ttbr0_mask;/* masked to be used */
uint32_t os_border; uint32_t os_border;
int (*read_physical_memory)(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t *buffer); int (*read_physical_memory)(struct target *target, uint32_t address, uint32_t size,
uint32_t count, uint8_t *buffer);
struct armv7a_cache_common armv7a_cache; struct armv7a_cache_common armv7a_cache;
uint32_t mmu_enabled; uint32_t mmu_enabled;
}; };
struct armv7a_common {
struct armv7a_common
{
struct arm arm; struct arm arm;
int common_magic; int common_magic;
struct reg_cache *core_cache; struct reg_cache *core_cache;
@ -124,8 +116,7 @@ struct armv7a_common
static inline struct armv7a_common * static inline struct armv7a_common *
target_to_armv7a(struct target *target) target_to_armv7a(struct target *target)
{ {
return container_of(target->arch_info, struct armv7a_common, return container_of(target->arch_info, struct armv7a_common, arm);
arm);
} }
/* register offsets from armv7a.debug_base */ /* register offsets from armv7a.debug_base */
@ -169,7 +160,7 @@ int armv7a_arch_state(struct target *target);
int armv7a_identify_cache(struct target *target); int armv7a_identify_cache(struct target *target);
int armv7a_init_arch_info(struct target *target, struct armv7a_common *armv7a); int armv7a_init_arch_info(struct target *target, struct armv7a_common *armv7a);
int armv7a_mmu_translate_va_pa(struct target *target, uint32_t va, int armv7a_mmu_translate_va_pa(struct target *target, uint32_t va,
uint32_t *val,int meminfo); uint32_t *val, int meminfo);
int armv7a_mmu_translate_va(struct target *target, uint32_t va, uint32_t *val); int armv7a_mmu_translate_va(struct target *target, uint32_t va, uint32_t *val);
int armv7a_handle_cache_info_command(struct command_context *cmd_ctx, int armv7a_handle_cache_info_command(struct command_context *cmd_ctx,

View File

@ -30,6 +30,7 @@
* ARM DDI 0405C (September 2008) * * ARM DDI 0405C (September 2008) *
* * * *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -39,19 +40,16 @@
#include "algorithm.h" #include "algorithm.h"
#include "register.h" #include "register.h"
#if 0 #if 0
#define _DEBUG_INSTRUCTION_EXECUTION_ #define _DEBUG_INSTRUCTION_EXECUTION_
#endif #endif
/** Maps from enum armv7m_mode (except ARMV7M_MODE_ANY) to name. */ /** Maps from enum armv7m_mode (except ARMV7M_MODE_ANY) to name. */
char *armv7m_mode_strings[] = char *armv7m_mode_strings[] = {
{
"Thread", "Thread (User)", "Handler", "Thread", "Thread (User)", "Handler",
}; };
static char *armv7m_exception_strings[] = static char *armv7m_exception_strings[] = {
{
"", "Reset", "NMI", "HardFault", "", "Reset", "NMI", "HardFault",
"MemManage", "BusFault", "UsageFault", "RESERVED", "MemManage", "BusFault", "UsageFault", "RESERVED",
"RESERVED", "RESERVED", "RESERVED", "SVCall", "RESERVED", "RESERVED", "RESERVED", "SVCall",
@ -79,8 +77,7 @@ const int armv7m_msp_reg_map[17] = {
#ifdef ARMV7_GDB_HACKS #ifdef ARMV7_GDB_HACKS
uint8_t armv7m_gdb_dummy_cpsr_value[] = {0, 0, 0, 0}; uint8_t armv7m_gdb_dummy_cpsr_value[] = {0, 0, 0, 0};
struct reg armv7m_gdb_dummy_cpsr_reg = struct reg armv7m_gdb_dummy_cpsr_reg = {
{
.name = "GDB dummy cpsr register", .name = "GDB dummy cpsr register",
.value = armv7m_gdb_dummy_cpsr_value, .value = armv7m_gdb_dummy_cpsr_value,
.dirty = 0, .dirty = 0,
@ -133,7 +130,7 @@ static const struct {
{ ARMV7M_CONTROL, "control", 2 }, { ARMV7M_CONTROL, "control", 2 },
}; };
#define ARMV7M_NUM_REGS ARRAY_SIZE(armv7m_regs) #define ARMV7M_NUM_REGS ARRAY_SIZE(armv7m_regs)
/** /**
* Restores target context using the cache of core registers set up * Restores target context using the cache of core registers set up
@ -149,12 +146,9 @@ int armv7m_restore_context(struct target *target)
if (armv7m->pre_restore_context) if (armv7m->pre_restore_context)
armv7m->pre_restore_context(target); armv7m->pre_restore_context(target);
for (i = ARMV7M_NUM_REGS - 1; i >= 0; i--) for (i = ARMV7M_NUM_REGS - 1; i >= 0; i--) {
{
if (armv7m->core_cache->reg_list[i].dirty) if (armv7m->core_cache->reg_list[i].dirty)
{
armv7m->write_core_reg(target, i); armv7m->write_core_reg(target, i);
}
} }
return ERROR_OK; return ERROR_OK;
@ -189,9 +183,7 @@ static int armv7m_get_core_reg(struct reg *reg)
struct armv7m_common *armv7m = target_to_armv7m(target); struct armv7m_common *armv7m = target_to_armv7m(target);
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED)
{
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
}
retval = armv7m->read_core_reg(target, armv7m_reg->num); retval = armv7m->read_core_reg(target, armv7m_reg->num);
@ -205,9 +197,7 @@ static int armv7m_set_core_reg(struct reg *reg, uint8_t *buf)
uint32_t value = buf_get_u32(buf, 0, 32); uint32_t value = buf_get_u32(buf, 0, 32);
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED)
{
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
}
buf_set_u32(reg->value, 0, 32, value); buf_set_u32(reg->value, 0, 32, value);
reg->dirty = 1; reg->dirty = 1;
@ -220,14 +210,17 @@ static int armv7m_read_core_reg(struct target *target, unsigned num)
{ {
uint32_t reg_value; uint32_t reg_value;
int retval; int retval;
struct armv7m_core_reg * armv7m_core_reg; struct armv7m_core_reg *armv7m_core_reg;
struct armv7m_common *armv7m = target_to_armv7m(target); struct armv7m_common *armv7m = target_to_armv7m(target);
if (num >= ARMV7M_NUM_REGS) if (num >= ARMV7M_NUM_REGS)
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
armv7m_core_reg = armv7m->core_cache->reg_list[num].arch_info; armv7m_core_reg = armv7m->core_cache->reg_list[num].arch_info;
retval = armv7m->load_core_reg_u32(target, armv7m_core_reg->type, armv7m_core_reg->num, &reg_value); retval = armv7m->load_core_reg_u32(target,
armv7m_core_reg->type,
armv7m_core_reg->num,
&reg_value);
buf_set_u32(armv7m->core_cache->reg_list[num].value, 0, 32, reg_value); buf_set_u32(armv7m->core_cache->reg_list[num].value, 0, 32, reg_value);
armv7m->core_cache->reg_list[num].valid = 1; armv7m->core_cache->reg_list[num].valid = 1;
armv7m->core_cache->reg_list[num].dirty = 0; armv7m->core_cache->reg_list[num].dirty = 0;
@ -247,14 +240,16 @@ static int armv7m_write_core_reg(struct target *target, unsigned num)
reg_value = buf_get_u32(armv7m->core_cache->reg_list[num].value, 0, 32); reg_value = buf_get_u32(armv7m->core_cache->reg_list[num].value, 0, 32);
armv7m_core_reg = armv7m->core_cache->reg_list[num].arch_info; armv7m_core_reg = armv7m->core_cache->reg_list[num].arch_info;
retval = armv7m->store_core_reg_u32(target, armv7m_core_reg->type, armv7m_core_reg->num, reg_value); retval = armv7m->store_core_reg_u32(target,
if (retval != ERROR_OK) armv7m_core_reg->type,
{ armv7m_core_reg->num,
reg_value);
if (retval != ERROR_OK) {
LOG_ERROR("JTAG failure"); LOG_ERROR("JTAG failure");
armv7m->core_cache->reg_list[num].dirty = armv7m->core_cache->reg_list[num].valid; armv7m->core_cache->reg_list[num].dirty = armv7m->core_cache->reg_list[num].valid;
return ERROR_JTAG_DEVICE_ERROR; return ERROR_JTAG_DEVICE_ERROR;
} }
LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num , reg_value); LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num, reg_value);
armv7m->core_cache->reg_list[num].valid = 1; armv7m->core_cache->reg_list[num].valid = 1;
armv7m->core_cache->reg_list[num].dirty = 0; armv7m->core_cache->reg_list[num].dirty = 0;
@ -273,7 +268,7 @@ int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int
int i; int i;
*reg_list_size = 26; *reg_list_size = 26;
*reg_list = malloc(sizeof(struct reg*) * (*reg_list_size)); *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
/* /*
* GDB register packet format for ARM: * GDB register packet format for ARM:
@ -283,9 +278,7 @@ int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int
* - CPSR * - CPSR
*/ */
for (i = 0; i < 16; i++) for (i = 0; i < 16; i++)
{
(*reg_list)[i] = &armv7m->core_cache->reg_list[i]; (*reg_list)[i] = &armv7m->core_cache->reg_list[i];
}
for (i = 16; i < 24; i++) for (i = 16; i < 24; i++)
(*reg_list)[i] = &arm_gdb_dummy_fp_reg; (*reg_list)[i] = &arm_gdb_dummy_fp_reg;
@ -297,7 +290,7 @@ int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int
/* ARMV7M is always in thumb mode, try to make GDB understand this /* ARMV7M is always in thumb mode, try to make GDB understand this
* if it does not support this arch */ * if it does not support this arch */
*((char*)armv7m->arm.pc->value) |= 1; *((char *)armv7m->arm.pc->value) |= 1;
#else #else
(*reg_list)[25] = &armv7m->core_cache->reg_list[ARMV7M_xPSR]; (*reg_list)[25] = &armv7m->core_cache->reg_list[ARMV7M_xPSR];
#endif #endif
@ -345,60 +338,60 @@ int armv7m_start_algorithm(struct target *target,
/* NOTE: armv7m_run_algorithm requires that each algorithm uses a software breakpoint /* NOTE: armv7m_run_algorithm requires that each algorithm uses a software breakpoint
* at the exit point */ * at the exit point */
if (armv7m_algorithm_info->common_magic != ARMV7M_COMMON_MAGIC) if (armv7m_algorithm_info->common_magic != ARMV7M_COMMON_MAGIC) {
{
LOG_ERROR("current target isn't an ARMV7M target"); LOG_ERROR("current target isn't an ARMV7M target");
return ERROR_TARGET_INVALID; return ERROR_TARGET_INVALID;
} }
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
LOG_WARNING("target not halted"); LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
} }
/* refresh core register cache */ /* refresh core register cache
/* Not needed if core register cache is always consistent with target process state */ * Not needed if core register cache is always consistent with target process state */
for (unsigned i = 0; i < ARMV7M_NUM_REGS; i++) for (unsigned i = 0; i < ARMV7M_NUM_REGS; i++) {
{
if (!armv7m->core_cache->reg_list[i].valid) if (!armv7m->core_cache->reg_list[i].valid)
armv7m->read_core_reg(target, i); armv7m->read_core_reg(target, i);
armv7m_algorithm_info->context[i] = buf_get_u32(armv7m->core_cache->reg_list[i].value, 0, 32); armv7m_algorithm_info->context[i] = buf_get_u32(
armv7m->core_cache->reg_list[i].value,
0,
32);
} }
for (int i = 0; i < num_mem_params; i++) for (int i = 0; i < num_mem_params; i++) {
{ /* TODO: Write only out params */
// TODO: Write only out params retval = target_write_buffer(target, mem_params[i].address,
if ((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK) mem_params[i].size,
mem_params[i].value);
if (retval != ERROR_OK)
return retval; return retval;
} }
for (int i = 0; i < num_reg_params; i++) for (int i = 0; i < num_reg_params; i++) {
{ struct reg *reg =
struct reg *reg = register_get_by_name(armv7m->core_cache, reg_params[i].reg_name, 0); register_get_by_name(armv7m->core_cache, reg_params[i].reg_name, 0);
// uint32_t regvalue; /* uint32_t regvalue; */
if (!reg) if (!reg) {
{
LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
if (reg->size != reg_params[i].size) if (reg->size != reg_params[i].size) {
{ LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name); reg_params[i].reg_name);
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
// regvalue = buf_get_u32(reg_params[i].value, 0, 32); /* regvalue = buf_get_u32(reg_params[i].value, 0, 32); */
armv7m_set_core_reg(reg, reg_params[i].value); armv7m_set_core_reg(reg, reg_params[i].value);
} }
if (armv7m_algorithm_info->core_mode != ARMV7M_MODE_ANY) if (armv7m_algorithm_info->core_mode != ARMV7M_MODE_ANY) {
{
LOG_DEBUG("setting core_mode: 0x%2.2x", armv7m_algorithm_info->core_mode); LOG_DEBUG("setting core_mode: 0x%2.2x", armv7m_algorithm_info->core_mode);
buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_CONTROL].value, buf_set_u32(armv7m->core_cache->reg_list[ARMV7M_CONTROL].value,
0, 1, armv7m_algorithm_info->core_mode); 0, 1, armv7m_algorithm_info->core_mode);
armv7m->core_cache->reg_list[ARMV7M_CONTROL].dirty = 1; armv7m->core_cache->reg_list[ARMV7M_CONTROL].dirty = 1;
armv7m->core_cache->reg_list[ARMV7M_CONTROL].valid = 1; armv7m->core_cache->reg_list[ARMV7M_CONTROL].valid = 1;
} }
@ -424,58 +417,58 @@ int armv7m_wait_algorithm(struct target *target,
/* NOTE: armv7m_run_algorithm requires that each algorithm uses a software breakpoint /* NOTE: armv7m_run_algorithm requires that each algorithm uses a software breakpoint
* at the exit point */ * at the exit point */
if (armv7m_algorithm_info->common_magic != ARMV7M_COMMON_MAGIC) if (armv7m_algorithm_info->common_magic != ARMV7M_COMMON_MAGIC) {
{
LOG_ERROR("current target isn't an ARMV7M target"); LOG_ERROR("current target isn't an ARMV7M target");
return ERROR_TARGET_INVALID; return ERROR_TARGET_INVALID;
} }
retval = target_wait_state(target, TARGET_HALTED, timeout_ms); retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
/* If the target fails to halt due to the breakpoint, force a halt */ /* If the target fails to halt due to the breakpoint, force a halt */
if (retval != ERROR_OK || target->state != TARGET_HALTED) if (retval != ERROR_OK || target->state != TARGET_HALTED) {
{ retval = target_halt(target);
if ((retval = target_halt(target)) != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if ((retval = target_wait_state(target, TARGET_HALTED, 500)) != ERROR_OK) retval = target_wait_state(target, TARGET_HALTED, 500);
{ if (retval != ERROR_OK)
return retval; return retval;
}
return ERROR_TARGET_TIMEOUT; return ERROR_TARGET_TIMEOUT;
} }
armv7m->load_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 15, &pc); armv7m->load_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 15, &pc);
if (exit_point && (pc != exit_point)) if (exit_point && (pc != exit_point)) {
{ LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 ", expected 0x%" PRIx32,
LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 ", expected 0x%" PRIx32 , pc, exit_point); pc,
exit_point);
return ERROR_TARGET_TIMEOUT; return ERROR_TARGET_TIMEOUT;
} }
/* Read memory values to mem_params[] */ /* Read memory values to mem_params[] */
for (int i = 0; i < num_mem_params; i++) for (int i = 0; i < num_mem_params; i++) {
{ if (mem_params[i].direction != PARAM_OUT) {
if (mem_params[i].direction != PARAM_OUT) retval = target_read_buffer(target, mem_params[i].address,
if ((retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK) mem_params[i].size,
{ mem_params[i].value);
if (retval != ERROR_OK)
return retval; return retval;
} }
} }
/* Copy core register values to reg_params[] */ /* Copy core register values to reg_params[] */
for (int i = 0; i < num_reg_params; i++) for (int i = 0; i < num_reg_params; i++) {
{ if (reg_params[i].direction != PARAM_OUT) {
if (reg_params[i].direction != PARAM_OUT) struct reg *reg = register_get_by_name(armv7m->core_cache,
{ reg_params[i].reg_name,
struct reg *reg = register_get_by_name(armv7m->core_cache, reg_params[i].reg_name, 0); 0);
if (!reg) if (!reg) {
{
LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
if (reg->size != reg_params[i].size) if (reg->size != reg_params[i].size) {
{ LOG_ERROR(
LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name); "BUG: register '%s' size doesn't match reg_params[i].size",
reg_params[i].reg_name);
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
@ -483,16 +476,15 @@ int armv7m_wait_algorithm(struct target *target,
} }
} }
for (int i = ARMV7M_NUM_REGS - 1; i >= 0; i--) for (int i = ARMV7M_NUM_REGS - 1; i >= 0; i--) {
{
uint32_t regvalue; uint32_t regvalue;
regvalue = buf_get_u32(armv7m->core_cache->reg_list[i].value, 0, 32); regvalue = buf_get_u32(armv7m->core_cache->reg_list[i].value, 0, 32);
if (regvalue != armv7m_algorithm_info->context[i]) if (regvalue != armv7m_algorithm_info->context[i]) {
{
LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32, LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
armv7m->core_cache->reg_list[i].name, armv7m_algorithm_info->context[i]); armv7m->core_cache->reg_list[i].name,
armv7m_algorithm_info->context[i]);
buf_set_u32(armv7m->core_cache->reg_list[i].value, buf_set_u32(armv7m->core_cache->reg_list[i].value,
0, 32, armv7m_algorithm_info->context[i]); 0, 32, armv7m_algorithm_info->context[i]);
armv7m->core_cache->reg_list[i].valid = 1; armv7m->core_cache->reg_list[i].valid = 1;
armv7m->core_cache->reg_list[i].dirty = 1; armv7m->core_cache->reg_list[i].dirty = 1;
} }
@ -555,8 +547,7 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target)
(*cache_p) = cache; (*cache_p) = cache;
armv7m->core_cache = cache; armv7m->core_cache = cache;
for (i = 0; i < num_regs; i++) for (i = 0; i < num_regs; i++) {
{
arch_info[i].num = armv7m_regs[i].id; arch_info[i].num = armv7m_regs[i].id;
arch_info[i].target = target; arch_info[i].target = target;
arch_info[i].armv7m_common = armv7m; arch_info[i].armv7m_common = armv7m;
@ -603,7 +594,7 @@ int armv7m_init_arch_info(struct target *target, struct armv7m_common *armv7m)
/** Generates a CRC32 checksum of a memory region. */ /** Generates a CRC32 checksum of a memory region. */
int armv7m_checksum_memory(struct target *target, int armv7m_checksum_memory(struct target *target,
uint32_t address, uint32_t count, uint32_t* checksum) uint32_t address, uint32_t count, uint32_t *checksum)
{ {
struct working_area *crc_algorithm; struct working_area *crc_algorithm;
struct armv7m_algorithm armv7m_info; struct armv7m_algorithm armv7m_info;
@ -618,27 +609,27 @@ int armv7m_checksum_memory(struct target *target,
0x460B, /* mov r3, r1 */ 0x460B, /* mov r3, r1 */
0xF04F, 0x0400, /* mov r4, #0 */ 0xF04F, 0x0400, /* mov r4, #0 */
0xE013, /* b ncomp */ 0xE013, /* b ncomp */
/* nbyte: */ /* nbyte: */
0x5D11, /* ldrb r1, [r2, r4] */ 0x5D11, /* ldrb r1, [r2, r4] */
0xF8DF, 0x7028, /* ldr r7, CRC32XOR */ 0xF8DF, 0x7028, /* ldr r7, CRC32XOR */
0xEA80, 0x6001, /* eor r0, r0, r1, asl #24 */ 0xEA80, 0x6001, /* eor r0, r0, r1, asl #24 */
0xF04F, 0x0500, /* mov r5, #0 */ 0xF04F, 0x0500, /* mov r5, #0 */
/* loop: */ /* loop: */
0x2800, /* cmp r0, #0 */ 0x2800, /* cmp r0, #0 */
0xEA4F, 0x0640, /* mov r6, r0, asl #1 */ 0xEA4F, 0x0640, /* mov r6, r0, asl #1 */
0xF105, 0x0501, /* add r5, r5, #1 */ 0xF105, 0x0501, /* add r5, r5, #1 */
0x4630, /* mov r0, r6 */ 0x4630, /* mov r0, r6 */
0xBFB8, /* it lt */ 0xBFB8, /* it lt */
0xEA86, 0x0007, /* eor r0, r6, r7 */ 0xEA86, 0x0007, /* eor r0, r6, r7 */
0x2D08, /* cmp r5, #8 */ 0x2D08, /* cmp r5, #8 */
0xD1F4, /* bne loop */ 0xD1F4, /* bne loop */
0xF104, 0x0401, /* add r4, r4, #1 */ 0xF104, 0x0401, /* add r4, r4, #1 */
/* ncomp: */ /* ncomp: */
0x429C, /* cmp r4, r3 */ 0x429C, /* cmp r4, r3 */
0xD1E9, /* bne nbyte */ 0xD1E9, /* bne nbyte */
0xBE00, /* bkpt #0 */ 0xBE00, /* bkpt #0 */
0x1DB7, 0x04C1 /* CRC32XOR: .word 0x04C11DB7 */ 0x1DB7, 0x04C1 /* CRC32XOR: .word 0x04C11DB7 */
}; };
@ -650,7 +641,9 @@ int armv7m_checksum_memory(struct target *target,
/* convert flash writing code into a buffer in target endianness */ /* convert flash writing code into a buffer in target endianness */
for (i = 0; i < ARRAY_SIZE(cortex_m3_crc_code); i++) { for (i = 0; i < ARRAY_SIZE(cortex_m3_crc_code); i++) {
retval = target_write_u16(target, crc_algorithm->address + i*sizeof(uint16_t), cortex_m3_crc_code[i]); retval = target_write_u16(target,
crc_algorithm->address + i*sizeof(uint16_t),
cortex_m3_crc_code[i]);
if (retval != ERROR_OK) if (retval != ERROR_OK)
goto cleanup; goto cleanup;
} }
@ -667,8 +660,8 @@ int armv7m_checksum_memory(struct target *target,
int timeout = 20000 * (1 + (count / (1024 * 1024))); int timeout = 20000 * (1 + (count / (1024 * 1024)));
retval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address, retval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address,
crc_algorithm->address + (sizeof(cortex_m3_crc_code) - 6), crc_algorithm->address + (sizeof(cortex_m3_crc_code) - 6),
timeout, &armv7m_info); timeout, &armv7m_info);
if (retval == ERROR_OK) if (retval == ERROR_OK)
*checksum = buf_get_u32(reg_params[0].value, 0, 32); *checksum = buf_get_u32(reg_params[0].value, 0, 32);
@ -686,7 +679,7 @@ cleanup:
/** Checks whether a memory region is zeroed. */ /** Checks whether a memory region is zeroed. */
int armv7m_blank_check_memory(struct target *target, int armv7m_blank_check_memory(struct target *target,
uint32_t address, uint32_t count, uint32_t* blank) uint32_t address, uint32_t count, uint32_t *blank)
{ {
struct working_area *erase_check_algorithm; struct working_area *erase_check_algorithm;
struct reg_param reg_params[3]; struct reg_param reg_params[3];
@ -694,25 +687,25 @@ int armv7m_blank_check_memory(struct target *target,
int retval; int retval;
uint32_t i; uint32_t i;
static const uint16_t erase_check_code[] = static const uint16_t erase_check_code[] = {
{
/* loop: */ /* loop: */
0xF810, 0x3B01, /* ldrb r3, [r0], #1 */ 0xF810, 0x3B01, /* ldrb r3, [r0], #1 */
0xEA02, 0x0203, /* and r2, r2, r3 */ 0xEA02, 0x0203, /* and r2, r2, r3 */
0x3901, /* subs r1, r1, #1 */ 0x3901, /* subs r1, r1, #1 */
0xD1F9, /* bne loop */ 0xD1F9, /* bne loop */
0xBE00, /* bkpt #0 */ 0xBE00, /* bkpt #0 */
}; };
/* make sure we have a working area */ /* make sure we have a working area */
if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK) if (target_alloc_working_area(target, sizeof(erase_check_code),
{ &erase_check_algorithm) != ERROR_OK)
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
/* convert flash writing code into a buffer in target endianness */ /* convert flash writing code into a buffer in target endianness */
for (i = 0; i < ARRAY_SIZE(erase_check_code); i++) for (i = 0; i < ARRAY_SIZE(erase_check_code); i++)
target_write_u16(target, erase_check_algorithm->address + i*sizeof(uint16_t), erase_check_code[i]); target_write_u16(target,
erase_check_algorithm->address + i*sizeof(uint16_t),
erase_check_code[i]);
armv7m_info.common_magic = ARMV7M_COMMON_MAGIC; armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
armv7m_info.core_mode = ARMV7M_MODE_ANY; armv7m_info.core_mode = ARMV7M_MODE_ANY;
@ -726,9 +719,15 @@ int armv7m_blank_check_memory(struct target *target,
init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT); init_reg_param(&reg_params[2], "r2", 32, PARAM_IN_OUT);
buf_set_u32(reg_params[2].value, 0, 32, 0xff); buf_set_u32(reg_params[2].value, 0, 32, 0xff);
retval = target_run_algorithm(target, 0, NULL, 3, reg_params, erase_check_algorithm->address, retval = target_run_algorithm(target,
erase_check_algorithm->address + (sizeof(erase_check_code) - 2), 0,
10000, &armv7m_info); NULL,
3,
reg_params,
erase_check_algorithm->address,
erase_check_algorithm->address + (sizeof(erase_check_code) - 2),
10000,
&armv7m_info);
if (retval == ERROR_OK) if (retval == ERROR_OK)
*blank = buf_get_u32(reg_params[2].value, 0, 32); *blank = buf_get_u32(reg_params[2].value, 0, 32);
@ -753,16 +752,13 @@ int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found)
* then we have to manually step over it, otherwise * then we have to manually step over it, otherwise
* the core will break again */ * the core will break again */
if (target->debug_reason == DBG_REASON_BREAKPOINT) if (target->debug_reason == DBG_REASON_BREAKPOINT) {
{
uint16_t op; uint16_t op;
uint32_t pc = buf_get_u32(r->value, 0, 32); uint32_t pc = buf_get_u32(r->value, 0, 32);
pc &= ~1; pc &= ~1;
if (target_read_u16(target, pc, &op) == ERROR_OK) if (target_read_u16(target, pc, &op) == ERROR_OK) {
{ if ((op & 0xFF00) == 0xBE00) {
if ((op & 0xFF00) == 0xBE00)
{
pc = buf_get_u32(r->value, 0, 32) + 2; pc = buf_get_u32(r->value, 0, 32) + 2;
buf_set_u32(r->value, 0, 32, pc); buf_set_u32(r->value, 0, 32, pc);
r->dirty = true; r->dirty = true;
@ -773,9 +769,8 @@ int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found)
} }
} }
if (inst_found) { if (inst_found)
*inst_found = result; *inst_found = result;
}
return ERROR_OK; return ERROR_OK;
} }

View File

@ -23,6 +23,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ARMV7M_COMMON_H #ifndef ARMV7M_COMMON_H
#define ARMV7M_COMMON_H #define ARMV7M_COMMON_H
@ -39,9 +40,7 @@ extern uint8_t armv7m_gdb_dummy_cpsr_value[];
extern struct reg armv7m_gdb_dummy_cpsr_reg; extern struct reg armv7m_gdb_dummy_cpsr_reg;
#endif #endif
enum armv7m_mode {
enum armv7m_mode
{
ARMV7M_MODE_THREAD = 0, ARMV7M_MODE_THREAD = 0,
ARMV7M_MODE_USER_THREAD = 1, ARMV7M_MODE_USER_THREAD = 1,
ARMV7M_MODE_HANDLER = 2, ARMV7M_MODE_HANDLER = 2,
@ -52,8 +51,7 @@ extern char *armv7m_mode_strings[];
extern const int armv7m_psp_reg_map[]; extern const int armv7m_psp_reg_map[];
extern const int armv7m_msp_reg_map[]; extern const int armv7m_msp_reg_map[];
enum armv7m_regtype enum armv7m_regtype {
{
ARMV7M_REGISTER_CORE_GP, ARMV7M_REGISTER_CORE_GP,
ARMV7M_REGISTER_CORE_SP, ARMV7M_REGISTER_CORE_SP,
ARMV7M_REGISTER_MEMMAP ARMV7M_REGISTER_MEMMAP
@ -62,8 +60,7 @@ enum armv7m_regtype
char *armv7m_exception_string(int number); char *armv7m_exception_string(int number);
/* offsets into armv7m core register cache */ /* offsets into armv7m core register cache */
enum enum {
{
/* for convenience, the first set of indices match /* for convenience, the first set of indices match
* the Cortex-M3 DCRSR selectors * the Cortex-M3 DCRSR selectors
*/ */
@ -100,8 +97,7 @@ enum
#define ARMV7M_COMMON_MAGIC 0x2A452A45 #define ARMV7M_COMMON_MAGIC 0x2A452A45
struct armv7m_common struct armv7m_common {
{
struct arm arm; struct arm arm;
int common_magic; int common_magic;
@ -139,17 +135,15 @@ static inline bool is_armv7m(struct armv7m_common *armv7m)
return armv7m->common_magic == ARMV7M_COMMON_MAGIC; return armv7m->common_magic == ARMV7M_COMMON_MAGIC;
} }
struct armv7m_algorithm struct armv7m_algorithm {
{
int common_magic; int common_magic;
enum armv7m_mode core_mode; enum armv7m_mode core_mode;
uint32_t context[ARMV7M_CONTROL + 1]; //ARMV7M_NUM_REGS uint32_t context[ARMV7M_CONTROL + 1]; /* ARMV7M_NUM_REGS */
}; };
struct armv7m_core_reg struct armv7m_core_reg {
{
uint32_t num; uint32_t num;
enum armv7m_regtype type; enum armv7m_regtype type;
struct target *target; struct target *target;
@ -189,9 +183,9 @@ int armv7m_invalidate_core_regs(struct target *target);
int armv7m_restore_context(struct target *target); int armv7m_restore_context(struct target *target);
int armv7m_checksum_memory(struct target *target, int armv7m_checksum_memory(struct target *target,
uint32_t address, uint32_t count, uint32_t* checksum); uint32_t address, uint32_t count, uint32_t *checksum);
int armv7m_blank_check_memory(struct target *target, int armv7m_blank_check_memory(struct target *target,
uint32_t address, uint32_t count, uint32_t* blank); uint32_t address, uint32_t count, uint32_t *blank);
int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found); int armv7m_maybe_skip_bkpt_inst(struct target *target, bool *inst_found);

View File

@ -19,6 +19,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -34,15 +35,13 @@
#include "avr32_regs.h" #include "avr32_regs.h"
#include "avr32_ap7k.h" #include "avr32_ap7k.h"
static char* avr32_core_reg_list[] = static char *avr32_core_reg_list[] = {
{ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8",
"r9", "r10", "r11", "r12", "sp", "lr", "pc", "sr" "r9", "r10", "r11", "r12", "sp", "lr", "pc", "sr"
}; };
static struct avr32_core_reg static struct avr32_core_reg
avr32_core_reg_list_arch_info[AVR32NUMCOREREGS] = avr32_core_reg_list_arch_info[AVR32NUMCOREREGS] = {
{
{0, NULL, NULL}, {0, NULL, NULL},
{1, NULL, NULL}, {1, NULL, NULL},
{2, NULL, NULL}, {2, NULL, NULL},
@ -75,12 +74,9 @@ int avr32_ap7k_save_context(struct target *target)
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
for (i = 0; i < AVR32NUMCOREREGS; i++) for (i = 0; i < AVR32NUMCOREREGS; i++) {
{
if (!ap7k->core_cache->reg_list[i].valid) if (!ap7k->core_cache->reg_list[i].valid)
{
avr32_read_core_reg(target, i); avr32_read_core_reg(target, i);
}
} }
return ERROR_OK; return ERROR_OK;
@ -93,12 +89,9 @@ int avr32_ap7k_restore_context(struct target *target)
/* get pointers to arch-specific information */ /* get pointers to arch-specific information */
struct avr32_ap7k_common *ap7k = target_to_ap7k(target); struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
for (i = 0; i < AVR32NUMCOREREGS; i++) for (i = 0; i < AVR32NUMCOREREGS; i++) {
{
if (ap7k->core_cache->reg_list[i].dirty) if (ap7k->core_cache->reg_list[i].dirty)
{
avr32_write_core_reg(target, i); avr32_write_core_reg(target, i);
}
} }
/* write core regs */ /* write core regs */
@ -137,7 +130,7 @@ static int avr32_write_core_reg(struct target *target, int num)
reg_value = buf_get_u32(ap7k->core_cache->reg_list[num].value, 0, 32); reg_value = buf_get_u32(ap7k->core_cache->reg_list[num].value, 0, 32);
ap7k->core_regs[num] = reg_value; ap7k->core_regs[num] = reg_value;
LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num , reg_value); LOG_DEBUG("write core reg %i value 0x%" PRIx32 "", num, reg_value);
ap7k->core_cache->reg_list[num].valid = 1; ap7k->core_cache->reg_list[num].valid = 1;
ap7k->core_cache->reg_list[num].dirty = 0; ap7k->core_cache->reg_list[num].dirty = 0;
@ -151,9 +144,7 @@ static int avr32_get_core_reg(struct reg *reg)
struct target *target = avr32_reg->target; struct target *target = avr32_reg->target;
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED)
{
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
}
retval = avr32_read_core_reg(target, avr32_reg->num); retval = avr32_read_core_reg(target, avr32_reg->num);
@ -167,9 +158,7 @@ static int avr32_set_core_reg(struct reg *reg, uint8_t *buf)
uint32_t value = buf_get_u32(buf, 0, 32); uint32_t value = buf_get_u32(buf, 0, 32);
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED)
{
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
}
buf_set_u32(reg->value, 0, 32, value); buf_set_u32(reg->value, 0, 32, value);
reg->dirty = 1; reg->dirty = 1;
@ -190,7 +179,7 @@ static struct reg_cache *avr32_build_reg_cache(struct target *target)
struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache); struct reg_cache **cache_p = register_get_last_cache_p(&target->reg_cache);
struct reg_cache *cache = malloc(sizeof(struct reg_cache)); struct reg_cache *cache = malloc(sizeof(struct reg_cache));
struct reg *reg_list = malloc(sizeof(struct reg) * num_regs); struct reg *reg_list = malloc(sizeof(struct reg) * num_regs);
struct avr32_core_reg *arch_info = struct avr32_core_reg *arch_info =
malloc(sizeof(struct avr32_core_reg) * num_regs); malloc(sizeof(struct avr32_core_reg) * num_regs);
int i; int i;
@ -202,8 +191,7 @@ static struct reg_cache *avr32_build_reg_cache(struct target *target)
(*cache_p) = cache; (*cache_p) = cache;
ap7k->core_cache = cache; ap7k->core_cache = cache;
for (i = 0; i < num_regs; i++) for (i = 0; i < num_regs; i++) {
{
arch_info[i] = avr32_core_reg_list_arch_info[i]; arch_info[i] = avr32_core_reg_list_arch_info[i];
arch_info[i].target = target; arch_info[i].target = target;
arch_info[i].avr32_common = ap7k; arch_info[i].avr32_common = ap7k;
@ -253,31 +241,26 @@ static int avr32_ap7k_poll(struct target *target)
return retval; return retval;
/* check for processor halted */ /* check for processor halted */
if (ds & OCDREG_DS_DBA) if (ds & OCDREG_DS_DBA) {
{ if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) {
if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
{
target->state = TARGET_HALTED; target->state = TARGET_HALTED;
if ((retval = avr32_ap7k_debug_entry(target)) != ERROR_OK) retval = avr32_ap7k_debug_entry(target);
if (retval != ERROR_OK)
return retval; return retval;
target_call_event_callbacks(target, TARGET_EVENT_HALTED); target_call_event_callbacks(target, TARGET_EVENT_HALTED);
} } else if (target->state == TARGET_DEBUG_RUNNING) {
else if (target->state == TARGET_DEBUG_RUNNING)
{
target->state = TARGET_HALTED; target->state = TARGET_HALTED;
if ((retval = avr32_ap7k_debug_entry(target)) != ERROR_OK) retval = avr32_ap7k_debug_entry(target);
if (retval != ERROR_OK)
return retval; return retval;
target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
} }
} } else
else
{
target->state = TARGET_RUNNING; target->state = TARGET_RUNNING;
}
return ERROR_OK; return ERROR_OK;
@ -288,28 +271,21 @@ static int avr32_ap7k_halt(struct target *target)
struct avr32_ap7k_common *ap7k = target_to_ap7k(target); struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
LOG_DEBUG("target->state: %s", LOG_DEBUG("target->state: %s",
target_state_name(target)); target_state_name(target));
if (target->state == TARGET_HALTED) if (target->state == TARGET_HALTED) {
{
LOG_DEBUG("target was already halted"); LOG_DEBUG("target was already halted");
return ERROR_OK; return ERROR_OK;
} }
if (target->state == TARGET_UNKNOWN) if (target->state == TARGET_UNKNOWN)
{
LOG_WARNING("target was in unknown state when halt was requested"); LOG_WARNING("target was in unknown state when halt was requested");
}
if (target->state == TARGET_RESET) if (target->state == TARGET_RESET) {
{ if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) {
if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst())
{
LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST"); LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
return ERROR_TARGET_FAILURE; return ERROR_TARGET_FAILURE;
} } else {
else
{
target->debug_reason = DBG_REASON_DBGRQ; target->debug_reason = DBG_REASON_DBGRQ;
return ERROR_OK; return ERROR_OK;
@ -345,21 +321,19 @@ static int avr32_ap7k_soft_reset_halt(struct target *target)
} }
static int avr32_ap7k_resume(struct target *target, int current, static int avr32_ap7k_resume(struct target *target, int current,
uint32_t address, int handle_breakpoints, int debug_execution) uint32_t address, int handle_breakpoints, int debug_execution)
{ {
struct avr32_ap7k_common *ap7k = target_to_ap7k(target); struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
struct breakpoint *breakpoint = NULL; struct breakpoint *breakpoint = NULL;
uint32_t resume_pc; uint32_t resume_pc;
int retval; int retval;
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
LOG_WARNING("target not halted"); LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
} }
if (!debug_execution) if (!debug_execution) {
{
target_free_all_working_areas(target); target_free_all_working_areas(target);
/* /*
avr32_ap7k_enable_breakpoints(target); avr32_ap7k_enable_breakpoints(target);
@ -368,24 +342,21 @@ static int avr32_ap7k_resume(struct target *target, int current,
} }
/* current = 1: continue on current pc, otherwise continue at <address> */ /* current = 1: continue on current pc, otherwise continue at <address> */
if (!current) if (!current) {
{
#if 0 #if 0
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
#endif #endif
} }
resume_pc = resume_pc = buf_get_u32(ap7k->core_cache->reg_list[AVR32_REG_PC].value, 0, 32);
buf_get_u32(ap7k->core_cache->reg_list[AVR32_REG_PC].value, 0, 32);
avr32_ap7k_restore_context(target); avr32_ap7k_restore_context(target);
/* the front-end may request us not to handle breakpoints */ /* the front-end may request us not to handle breakpoints */
if (handle_breakpoints) if (handle_breakpoints) {
{
/* Single step past breakpoint at current address */ /* Single step past breakpoint at current address */
if ((breakpoint = breakpoint_find(target, resume_pc))) breakpoint = breakpoint_find(target, resume_pc);
{ if (breakpoint) {
LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address); LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
#if 0 #if 0
avr32_ap7k_unset_breakpoint(target, breakpoint); avr32_ap7k_unset_breakpoint(target, breakpoint);
@ -418,14 +389,11 @@ static int avr32_ap7k_resume(struct target *target, int current,
/* registers are now invalid */ /* registers are now invalid */
register_cache_invalidate(ap7k->core_cache); register_cache_invalidate(ap7k->core_cache);
if (!debug_execution) if (!debug_execution) {
{
target->state = TARGET_RUNNING; target->state = TARGET_RUNNING;
target_call_event_callbacks(target, TARGET_EVENT_RESUMED); target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc); LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
} } else {
else
{
target->state = TARGET_DEBUG_RUNNING; target->state = TARGET_DEBUG_RUNNING;
target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc); LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
@ -435,7 +403,7 @@ static int avr32_ap7k_resume(struct target *target, int current,
} }
static int avr32_ap7k_step(struct target *target, int current, static int avr32_ap7k_step(struct target *target, int current,
uint32_t address, int handle_breakpoints) uint32_t address, int handle_breakpoints)
{ {
LOG_ERROR("%s: implement me", __func__); LOG_ERROR("%s: implement me", __func__);
@ -450,7 +418,7 @@ static int avr32_ap7k_add_breakpoint(struct target *target, struct breakpoint *b
} }
static int avr32_ap7k_remove_breakpoint(struct target *target, static int avr32_ap7k_remove_breakpoint(struct target *target,
struct breakpoint *breakpoint) struct breakpoint *breakpoint)
{ {
LOG_ERROR("%s: implement me", __func__); LOG_ERROR("%s: implement me", __func__);
@ -465,7 +433,7 @@ static int avr32_ap7k_add_watchpoint(struct target *target, struct watchpoint *w
} }
static int avr32_ap7k_remove_watchpoint(struct target *target, static int avr32_ap7k_remove_watchpoint(struct target *target,
struct watchpoint *watchpoint) struct watchpoint *watchpoint)
{ {
LOG_ERROR("%s: implement me", __func__); LOG_ERROR("%s: implement me", __func__);
@ -473,14 +441,16 @@ static int avr32_ap7k_remove_watchpoint(struct target *target,
} }
static int avr32_ap7k_read_memory(struct target *target, uint32_t address, static int avr32_ap7k_read_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, uint8_t *buffer) uint32_t size, uint32_t count, uint8_t *buffer)
{ {
struct avr32_ap7k_common *ap7k = target_to_ap7k(target); struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count); LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
address,
size,
count);
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
LOG_WARNING("target not halted"); LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
} }
@ -492,33 +462,36 @@ static int avr32_ap7k_read_memory(struct target *target, uint32_t address,
if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
return ERROR_TARGET_UNALIGNED_ACCESS; return ERROR_TARGET_UNALIGNED_ACCESS;
switch (size) switch (size) {
{ case 4:
case 4: return avr32_jtag_read_memory32(&ap7k->jtag, address, count,
return avr32_jtag_read_memory32(&ap7k->jtag, address, count, (uint32_t*)(void *)buffer); (uint32_t *)(void *)buffer);
break; break;
case 2: case 2:
return avr32_jtag_read_memory16(&ap7k->jtag, address, count, (uint16_t*)(void *)buffer); return avr32_jtag_read_memory16(&ap7k->jtag, address, count,
break; (uint16_t *)(void *)buffer);
case 1: break;
return avr32_jtag_read_memory8(&ap7k->jtag, address, count, buffer); case 1:
break; return avr32_jtag_read_memory8(&ap7k->jtag, address, count, buffer);
default: break;
break; default:
break;
} }
return ERROR_OK; return ERROR_OK;
} }
static int avr32_ap7k_write_memory(struct target *target, uint32_t address, static int avr32_ap7k_write_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, const uint8_t *buffer) uint32_t size, uint32_t count, const uint8_t *buffer)
{ {
struct avr32_ap7k_common *ap7k = target_to_ap7k(target); struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count); LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
address,
size,
count);
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
LOG_WARNING("target not halted"); LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
} }
@ -530,26 +503,27 @@ static int avr32_ap7k_write_memory(struct target *target, uint32_t address,
if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u))) if (((size == 4) && (address & 0x3u)) || ((size == 2) && (address & 0x1u)))
return ERROR_TARGET_UNALIGNED_ACCESS; return ERROR_TARGET_UNALIGNED_ACCESS;
switch (size) switch (size) {
{ case 4:
case 4: return avr32_jtag_write_memory32(&ap7k->jtag, address, count,
return avr32_jtag_write_memory32(&ap7k->jtag, address, count, (uint32_t*)(void *)buffer); (uint32_t *)(void *)buffer);
break; break;
case 2: case 2:
return avr32_jtag_write_memory16(&ap7k->jtag, address, count, (uint16_t*)(void *)buffer); return avr32_jtag_write_memory16(&ap7k->jtag, address, count,
break; (uint16_t *)(void *)buffer);
case 1: break;
return avr32_jtag_write_memory8(&ap7k->jtag, address, count, buffer); case 1:
break; return avr32_jtag_write_memory8(&ap7k->jtag, address, count, buffer);
default: break;
break; default:
break;
} }
return ERROR_OK; return ERROR_OK;
} }
static int avr32_ap7k_init_target(struct command_context *cmd_ctx, static int avr32_ap7k_init_target(struct command_context *cmd_ctx,
struct target *target) struct target *target)
{ {
struct avr32_ap7k_common *ap7k = target_to_ap7k(target); struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
@ -561,7 +535,7 @@ static int avr32_ap7k_init_target(struct command_context *cmd_ctx,
static int avr32_ap7k_target_create(struct target *target, Jim_Interp *interp) static int avr32_ap7k_target_create(struct target *target, Jim_Interp *interp)
{ {
struct avr32_ap7k_common *ap7k = calloc(1, sizeof(struct struct avr32_ap7k_common *ap7k = calloc(1, sizeof(struct
avr32_ap7k_common)); avr32_ap7k_common));
ap7k->common_magic = AP7k_COMMON_MAGIC; ap7k->common_magic = AP7k_COMMON_MAGIC;
target->arch_info = ap7k; target->arch_info = ap7k;
@ -574,21 +548,18 @@ static int avr32_ap7k_examine(struct target *target)
uint32_t devid, ds; uint32_t devid, ds;
struct avr32_ap7k_common *ap7k = target_to_ap7k(target); struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
if (!target_was_examined(target)) if (!target_was_examined(target)) {
{
target_set_examined(target); target_set_examined(target);
avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DID, &devid); avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DID, &devid);
LOG_INFO("device id: %08x", devid); LOG_INFO("device id: %08x", devid);
avr32_ocd_setbits(&ap7k->jtag, AVR32_OCDREG_DC,OCDREG_DC_DBE); avr32_ocd_setbits(&ap7k->jtag, AVR32_OCDREG_DC, OCDREG_DC_DBE);
avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DS, &ds); avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DS, &ds);
/* check for processor halted */ /* check for processor halted */
if (ds & OCDREG_DS_DBA) if (ds & OCDREG_DS_DBA) {
{
LOG_INFO("target is halted"); LOG_INFO("target is halted");
target->state = TARGET_HALTED; target->state = TARGET_HALTED;
} } else
else
target->state = TARGET_RUNNING; target->state = TARGET_RUNNING;
} }
@ -596,7 +567,7 @@ static int avr32_ap7k_examine(struct target *target)
} }
static int avr32_ap7k_bulk_write_memory(struct target *target, uint32_t address, static int avr32_ap7k_bulk_write_memory(struct target *target, uint32_t address,
uint32_t count, const uint8_t *buffer) uint32_t count, const uint8_t *buffer)
{ {
LOG_ERROR("%s: implement me", __func__); LOG_ERROR("%s: implement me", __func__);
@ -609,31 +580,28 @@ int avr32_ap7k_arch_state(struct target *target)
struct avr32_ap7k_common *ap7k = target_to_ap7k(target); struct avr32_ap7k_common *ap7k = target_to_ap7k(target);
LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32 "", LOG_USER("target halted due to %s, pc: 0x%8.8" PRIx32 "",
debug_reason_name(target), ap7k->jtag.dpc); debug_reason_name(target), ap7k->jtag.dpc);
return ERROR_OK; return ERROR_OK;
} }
int avr32_ap7k_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size) int avr32_ap7k_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int *reg_list_size)
{ {
#if 0 #if 0
/* get pointers to arch-specific information */ /* get pointers to arch-specific information */
int i; int i;
/* include floating point registers */ /* include floating point registers */
*reg_list_size = AVR32NUMCOREREGS + AVR32NUMFPREGS; *reg_list_size = AVR32NUMCOREREGS + AVR32NUMFPREGS;
*reg_list = malloc(sizeof(struct reg*) * (*reg_list_size)); *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
for (i = 0; i < AVR32NUMCOREREGS; i++) for (i = 0; i < AVR32NUMCOREREGS; i++)
{ (*reg_list)[i] = &mips32->core_cache->reg_list[i];
(*reg_list)[i] = &mips32->core_cache->reg_list[i];
} /* add dummy floating points regs */
for (i = AVR32NUMCOREREGS; i < (AVR32NUMCOREREGS + AVR32NUMFPREGS); i++)
(*reg_list)[i] = &avr32_ap7k_gdb_dummy_fp_reg;
/* add dummy floating points regs */
for (i = AVR32NUMCOREREGS; i < (AVR32NUMCOREREGS + AVR32NUMFPREGS); i++)
{
(*reg_list)[i] = &avr32_ap7k_gdb_dummy_fp_reg;
}
#endif #endif
LOG_ERROR("%s: implement me", __func__); LOG_ERROR("%s: implement me", __func__);
@ -642,8 +610,7 @@ int avr32_ap7k_get_gdb_reg_list(struct target *target, struct reg **reg_list[],
struct target_type avr32_ap7k_target = struct target_type avr32_ap7k_target = {
{
.name = "avr32_ap7k", .name = "avr32_ap7k",
.poll = avr32_ap7k_poll, .poll = avr32_ap7k_poll,
@ -664,10 +631,10 @@ struct target_type avr32_ap7k_target =
.read_memory = avr32_ap7k_read_memory, .read_memory = avr32_ap7k_read_memory,
.write_memory = avr32_ap7k_write_memory, .write_memory = avr32_ap7k_write_memory,
.bulk_write_memory = avr32_ap7k_bulk_write_memory, .bulk_write_memory = avr32_ap7k_bulk_write_memory,
// .checksum_memory = avr32_ap7k_checksum_memory, /* .checksum_memory = avr32_ap7k_checksum_memory, */
// .blank_check_memory = avr32_ap7k_blank_check_memory, /* .blank_check_memory = avr32_ap7k_blank_check_memory, */
// .run_algorithm = avr32_ap7k_run_algorithm, /* .run_algorithm = avr32_ap7k_run_algorithm, */
.add_breakpoint = avr32_ap7k_add_breakpoint, .add_breakpoint = avr32_ap7k_add_breakpoint,
.remove_breakpoint = avr32_ap7k_remove_breakpoint, .remove_breakpoint = avr32_ap7k_remove_breakpoint,

View File

@ -25,8 +25,7 @@
struct target; struct target;
#define AP7k_COMMON_MAGIC 0x4150374b #define AP7k_COMMON_MAGIC 0x4150374b
struct avr32_ap7k_common struct avr32_ap7k_common {
{
int common_magic; int common_magic;
struct avr32_jtag jtag; struct avr32_jtag jtag;
struct reg_cache *core_cache; struct reg_cache *core_cache;
@ -36,11 +35,10 @@ struct avr32_ap7k_common
static inline struct avr32_ap7k_common * static inline struct avr32_ap7k_common *
target_to_ap7k(struct target *target) target_to_ap7k(struct target *target)
{ {
return (struct avr32_ap7k_common*)target->arch_info; return (struct avr32_ap7k_common *)target->arch_info;
} }
struct avr32_core_reg struct avr32_core_reg {
{
uint32_t num; uint32_t num;
struct target *target; struct target *target;
struct avr32_ap7k_common *avr32_common; struct avr32_ap7k_common *avr32_common;

View File

@ -16,6 +16,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -34,8 +35,7 @@ static int avr32_jtag_set_instr(struct avr32_jtag *jtag_info, int new_instr)
if (tap == NULL) if (tap == NULL)
return ERROR_FAIL; return ERROR_FAIL;
if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != (uint32_t)new_instr) if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != (uint32_t)new_instr) {
{
do { do {
struct scan_field field; struct scan_field field;
uint8_t t[4]; uint8_t t[4];
@ -47,8 +47,7 @@ static int avr32_jtag_set_instr(struct avr32_jtag *jtag_info, int new_instr)
field.in_value = ret; field.in_value = ret;
jtag_add_ir_scan(tap, &field, TAP_IDLE); jtag_add_ir_scan(tap, &field, TAP_IDLE);
if (jtag_execute_queue() != ERROR_OK) if (jtag_execute_queue() != ERROR_OK) {
{
LOG_ERROR("%s: setting address failed", __func__); LOG_ERROR("%s: setting address failed", __func__);
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -59,7 +58,7 @@ static int avr32_jtag_set_instr(struct avr32_jtag *jtag_info, int new_instr)
return ERROR_OK; return ERROR_OK;
} }
int avr32_jtag_nexus_set_address(struct avr32_jtag *jtag_info, int avr32_jtag_nexus_set_address(struct avr32_jtag *jtag_info,
uint32_t addr, int mode) uint32_t addr, int mode)
{ {
struct scan_field fields[2]; struct scan_field fields[2];
@ -85,19 +84,18 @@ int avr32_jtag_nexus_set_address(struct avr32_jtag *jtag_info,
fields[1].out_value = addr_buf; fields[1].out_value = addr_buf;
jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE); jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);
if (jtag_execute_queue() != ERROR_OK) if (jtag_execute_queue() != ERROR_OK) {
{
LOG_ERROR("%s: setting address failed", __func__); LOG_ERROR("%s: setting address failed", __func__);
return ERROR_FAIL; return ERROR_FAIL;
} }
busy = buf_get_u32(busy_buf, 6, 1); busy = buf_get_u32(busy_buf, 6, 1);
} while(busy); } while (busy);
return ERROR_OK; return ERROR_OK;
} }
int avr32_jtag_nexus_read_data(struct avr32_jtag *jtag_info, int avr32_jtag_nexus_read_data(struct avr32_jtag *jtag_info,
uint32_t *pdata) uint32_t *pdata)
{ {
@ -121,8 +119,7 @@ int avr32_jtag_nexus_read_data(struct avr32_jtag *jtag_info,
jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE); jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);
if (jtag_execute_queue() != ERROR_OK) if (jtag_execute_queue() != ERROR_OK) {
{
LOG_ERROR("%s: reading data failed", __func__); LOG_ERROR("%s: reading data failed", __func__);
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -135,8 +132,7 @@ int avr32_jtag_nexus_read_data(struct avr32_jtag *jtag_info,
return ERROR_OK; return ERROR_OK;
} }
int avr32_jtag_nexus_write_data(struct avr32_jtag *jtag_info,
int avr32_jtag_nexus_write_data(struct avr32_jtag *jtag_info,
uint32_t data) uint32_t data)
{ {
@ -163,8 +159,7 @@ int avr32_jtag_nexus_write_data(struct avr32_jtag *jtag_info,
jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE); jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);
if (jtag_execute_queue() != ERROR_OK) if (jtag_execute_queue() != ERROR_OK) {
{
LOG_ERROR("%s: reading data failed", __func__); LOG_ERROR("%s: reading data failed", __func__);
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -176,9 +171,6 @@ int avr32_jtag_nexus_write_data(struct avr32_jtag *jtag_info,
return ERROR_OK; return ERROR_OK;
} }
int avr32_jtag_nexus_read(struct avr32_jtag *jtag_info, int avr32_jtag_nexus_read(struct avr32_jtag *jtag_info,
uint32_t addr, uint32_t *value) uint32_t addr, uint32_t *value)
{ {
@ -228,18 +220,17 @@ int avr32_jtag_mwa_set_address(struct avr32_jtag *jtag_info, int slave,
fields[1].out_value = slave_buf; fields[1].out_value = slave_buf;
jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE); jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);
if (jtag_execute_queue() != ERROR_OK) if (jtag_execute_queue() != ERROR_OK) {
{
LOG_ERROR("%s: setting address failed", __func__); LOG_ERROR("%s: setting address failed", __func__);
return ERROR_FAIL; return ERROR_FAIL;
} }
busy = buf_get_u32(busy_buf, 1, 1); busy = buf_get_u32(busy_buf, 1, 1);
} while(busy); } while (busy);
return ERROR_OK; return ERROR_OK;
} }
int avr32_jtag_mwa_read_data(struct avr32_jtag *jtag_info, int avr32_jtag_mwa_read_data(struct avr32_jtag *jtag_info,
uint32_t *pdata) uint32_t *pdata)
{ {
@ -263,8 +254,7 @@ int avr32_jtag_mwa_read_data(struct avr32_jtag *jtag_info,
jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE); jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);
if (jtag_execute_queue() != ERROR_OK) if (jtag_execute_queue() != ERROR_OK) {
{
LOG_ERROR("%s: reading data failed", __func__); LOG_ERROR("%s: reading data failed", __func__);
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -277,7 +267,7 @@ int avr32_jtag_mwa_read_data(struct avr32_jtag *jtag_info,
return ERROR_OK; return ERROR_OK;
} }
int avr32_jtag_mwa_write_data(struct avr32_jtag *jtag_info, int avr32_jtag_mwa_write_data(struct avr32_jtag *jtag_info,
uint32_t data) uint32_t data)
{ {
@ -304,8 +294,7 @@ int avr32_jtag_mwa_write_data(struct avr32_jtag *jtag_info,
jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE); jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_IDLE);
if (jtag_execute_queue() != ERROR_OK) if (jtag_execute_queue() != ERROR_OK) {
{
LOG_ERROR("%s: reading data failed", __func__); LOG_ERROR("%s: reading data failed", __func__);
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -316,8 +305,6 @@ int avr32_jtag_mwa_write_data(struct avr32_jtag *jtag_info,
return ERROR_OK; return ERROR_OK;
} }
int avr32_jtag_mwa_read(struct avr32_jtag *jtag_info, int slave, int avr32_jtag_mwa_read(struct avr32_jtag *jtag_info, int slave,
uint32_t addr, uint32_t *value) uint32_t addr, uint32_t *value)
{ {

View File

@ -16,6 +16,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef AVR32_JTAG #ifndef AVR32_JTAG
#define AVR32_JTAG #define AVR32_JTAG
@ -81,8 +82,7 @@
#define MTSR(sysreg, reg) (0xe3b00002 | ((reg) << 16) | sysreg) #define MTSR(sysreg, reg) (0xe3b00002 | ((reg) << 16) | sysreg)
#define MFSR(reg, sysreg) (0xe1b00002 | ((reg) << 16) | sysreg) #define MFSR(reg, sysreg) (0xe1b00002 | ((reg) << 16) | sysreg)
struct avr32_jtag struct avr32_jtag {
{
struct jtag_tap *tap; struct jtag_tap *tap;
uint32_t dpc; /* Debug PC value */ uint32_t dpc; /* Debug PC value */
}; };
@ -97,11 +97,9 @@ int avr32_jtag_mwa_read(struct avr32_jtag *jtag_info, int slave,
int avr32_jtag_mwa_write(struct avr32_jtag *jtag_info, int slave, int avr32_jtag_mwa_write(struct avr32_jtag *jtag_info, int slave,
uint32_t addr, uint32_t value); uint32_t addr, uint32_t value);
int avr32_ocd_setbits(struct avr32_jtag *jtag, int reg, uint32_t bits); int avr32_ocd_setbits(struct avr32_jtag *jtag, int reg, uint32_t bits);
int avr32_ocd_clearbits(struct avr32_jtag *jtag, int reg, uint32_t bits); int avr32_ocd_clearbits(struct avr32_jtag *jtag, int reg, uint32_t bits);
int avr32_jtag_exec(struct avr32_jtag *jtag_info, uint32_t inst); int avr32_jtag_exec(struct avr32_jtag *jtag_info, uint32_t inst);
#endif /* AVR32_JTAG */ #endif /* AVR32_JTAG */

View File

@ -16,6 +16,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -25,14 +26,13 @@
#include "avr32_jtag.h" #include "avr32_jtag.h"
#include "avr32_mem.h" #include "avr32_mem.h"
int avr32_jtag_read_memory32(struct avr32_jtag *jtag_info, int avr32_jtag_read_memory32(struct avr32_jtag *jtag_info,
uint32_t addr, int count, uint32_t *buffer) uint32_t addr, int count, uint32_t *buffer)
{ {
int i, retval; int i, retval;
uint32_t data; uint32_t data;
for (i = 0; i < count; i++) for (i = 0; i < count; i++) {
{
retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,
addr + i*4, &data); addr + i*4, &data);
@ -40,14 +40,14 @@ int avr32_jtag_read_memory32(struct avr32_jtag *jtag_info,
return retval; return retval;
/* XXX: Assume AVR32 is BE */ /* XXX: Assume AVR32 is BE */
buffer[i] = be_to_h_u32((uint8_t*)&data); buffer[i] = be_to_h_u32((uint8_t *)&data);
} }
return ERROR_OK; return ERROR_OK;
} }
int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info, int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info,
uint32_t addr, int count, uint16_t *buffer) uint32_t addr, int count, uint16_t *buffer)
{ {
int i, retval; int i, retval;
uint32_t data; uint32_t data;
@ -55,8 +55,7 @@ int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info,
i = 0; i = 0;
/* any unaligned half-words? */ /* any unaligned half-words? */
if (addr & 3) if (addr & 3) {
{
retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,
addr + i*2, &data); addr + i*2, &data);
@ -64,14 +63,13 @@ int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info,
return retval; return retval;
/* XXX: Assume AVR32 is BE */ /* XXX: Assume AVR32 is BE */
data = be_to_h_u32((uint8_t*)&data); data = be_to_h_u32((uint8_t *)&data);
buffer[i] = (data >> 16) & 0xffff; buffer[i] = (data >> 16) & 0xffff;
i++; i++;
} }
/* read all complete words */ /* read all complete words */
for (; i < (count & ~1); i+=2) for (; i < (count & ~1); i += 2) {
{
retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,
addr + i*2, &data); addr + i*2, &data);
@ -79,14 +77,13 @@ int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info,
return retval; return retval;
/* XXX: Assume AVR32 is BE */ /* XXX: Assume AVR32 is BE */
data = be_to_h_u32((uint8_t*)&data); data = be_to_h_u32((uint8_t *)&data);
buffer[i] = data & 0xffff; buffer[i] = data & 0xffff;
buffer[i+1] = (data >> 16) & 0xffff; buffer[i+1] = (data >> 16) & 0xffff;
} }
/* last halfword */ /* last halfword */
if (i < count) if (i < count) {
{
retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,
addr + i*2, &data); addr + i*2, &data);
@ -94,73 +91,68 @@ int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info,
return retval; return retval;
/* XXX: Assume AVR32 is BE */ /* XXX: Assume AVR32 is BE */
data = be_to_h_u32((uint8_t*)&data); data = be_to_h_u32((uint8_t *)&data);
buffer[i] = data & 0xffff; buffer[i] = data & 0xffff;
} }
return ERROR_OK; return ERROR_OK;
} }
int avr32_jtag_read_memory8(struct avr32_jtag *jtag_info, int avr32_jtag_read_memory8(struct avr32_jtag *jtag_info,
uint32_t addr, int count, uint8_t *buffer) uint32_t addr, int count, uint8_t *buffer)
{ {
int i, j, retval; int i, j, retval;
uint8_t data[4]; uint8_t data[4];
i = 0; i = 0;
/* Do we have non-aligned bytes? */ /* Do we have non-aligned bytes? */
if (addr & 3) if (addr & 3) {
{
retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,
addr + i, (uint32_t*)(void *)data); addr + i, (uint32_t *)(void *)data);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
for (j = addr & 3; (j < 4) && (i < count); j++, i++) for (j = addr & 3; (j < 4) && (i < count); j++, i++)
buffer[i] = data[3-j]; buffer[i] = data[3-j];
} }
/* read all complete words */ /* read all complete words */
for (; i < (count & ~3); i+=4) for (; i < (count & ~3); i += 4) {
{
retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,
addr + i, (uint32_t*)(void *)data); addr + i, (uint32_t *)(void *)data);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
buffer[i+j] = data[3-j]; buffer[i+j] = data[3-j];
} }
/* remaining bytes */ /* remaining bytes */
if (i < count) if (i < count) {
{
retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,
addr + i, (uint32_t*)(void *)data); addr + i, (uint32_t *)(void *)data);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
for (j = 0; i + j < count; j++) for (j = 0; i + j < count; j++)
buffer[i+j] = data[3-j]; buffer[i+j] = data[3-j];
} }
return ERROR_OK; return ERROR_OK;
} }
int avr32_jtag_write_memory32(struct avr32_jtag *jtag_info, int avr32_jtag_write_memory32(struct avr32_jtag *jtag_info,
uint32_t addr, int count, const uint32_t *buffer) uint32_t addr, int count, const uint32_t *buffer)
{ {
int i, retval; int i, retval;
uint32_t data; uint32_t data;
for (i = 0; i < count; i++) for (i = 0; i < count; i++) {
{
/* XXX: Assume AVR32 is BE */ /* XXX: Assume AVR32 is BE */
h_u32_to_be((uint8_t*)&data, buffer[i]); h_u32_to_be((uint8_t *)&data, buffer[i]);
retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED,
addr + i*4, data); addr + i*4, data);
@ -172,8 +164,8 @@ int avr32_jtag_write_memory32(struct avr32_jtag *jtag_info,
return ERROR_OK; return ERROR_OK;
} }
int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info, int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info,
uint32_t addr, int count, const uint16_t *buffer) uint32_t addr, int count, const uint16_t *buffer)
{ {
int i, retval; int i, retval;
uint32_t data; uint32_t data;
@ -185,7 +177,7 @@ int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info,
* Do we have any non-aligned half-words? * Do we have any non-aligned half-words?
*/ */
if (addr & 3) { if (addr & 3) {
/* /*
* mwa_read will read whole world, no nead to fiddle * mwa_read will read whole world, no nead to fiddle
* with address. It will be truncated in set_addr * with address. It will be truncated in set_addr
*/ */
@ -195,9 +187,9 @@ int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info,
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
data = be_to_h_u32((uint8_t*)&data); data = be_to_h_u32((uint8_t *)&data);
data = (buffer[i] << 16) | (data & 0xffff); data = (buffer[i] << 16) | (data & 0xffff);
h_u32_to_be((uint8_t*)&data_out, data); h_u32_to_be((uint8_t *)&data_out, data);
retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED,
addr, data_out); addr, data_out);
@ -208,13 +200,11 @@ int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info,
i++; i++;
} }
/* write all complete words */ /* write all complete words */
for (; i < (count & ~1); i+=2) for (; i < (count & ~1); i += 2) {
{
/* XXX: Assume AVR32 is BE */ /* XXX: Assume AVR32 is BE */
data = (buffer[i+1] << 16) | buffer[i]; data = (buffer[i+1] << 16) | buffer[i];
h_u32_to_be((uint8_t*)&data_out, data); h_u32_to_be((uint8_t *)&data_out, data);
retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED,
addr + i*2, data_out); addr + i*2, data_out);
@ -224,18 +214,17 @@ int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info,
} }
/* last halfword */ /* last halfword */
if (i < count) if (i < count) {
{
retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED,
addr + i*2, &data); addr + i*2, &data);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
data = be_to_h_u32((uint8_t*)&data); data = be_to_h_u32((uint8_t *)&data);
data &= ~0xffff; data &= ~0xffff;
data |= buffer[i]; data |= buffer[i];
h_u32_to_be((uint8_t*)&data_out, data); h_u32_to_be((uint8_t *)&data_out, data);
retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED,
addr + i*2, data_out); addr + i*2, data_out);
@ -247,8 +236,8 @@ int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info,
return ERROR_OK; return ERROR_OK;
} }
int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info, int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info,
uint32_t addr, int count, const uint8_t *buffer) uint32_t addr, int count, const uint8_t *buffer)
{ {
int i, j, retval; int i, j, retval;
uint32_t data; uint32_t data;
@ -260,7 +249,7 @@ int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info,
* Do we have any non-aligned bytes? * Do we have any non-aligned bytes?
*/ */
if (addr & 3) { if (addr & 3) {
/* /*
* mwa_read will read whole world, no nead to fiddle * mwa_read will read whole world, no nead to fiddle
* with address. It will be truncated in set_addr * with address. It will be truncated in set_addr
*/ */
@ -270,14 +259,13 @@ int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info,
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
data = be_to_h_u32((uint8_t*)&data); data = be_to_h_u32((uint8_t *)&data);
for (j = addr & 3; (j < 4) && (i < count); j++, i++) for (j = addr & 3; (j < 4) && (i < count); j++, i++) {
{
data &= ~(0xff << j*8); data &= ~(0xff << j*8);
data |= (buffer[i] << j*8); data |= (buffer[i] << j*8);
} }
h_u32_to_be((uint8_t*)&data_out, data); h_u32_to_be((uint8_t *)&data_out, data);
retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED,
addr, data_out); addr, data_out);
@ -287,14 +275,13 @@ int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info,
/* write all complete words */ /* write all complete words */
for (; i < (count & ~3); i+=4) for (; i < (count & ~3); i += 4) {
{
data = 0; data = 0;
for (j = 0; j < 4; j++) for (j = 0; j < 4; j++)
data |= (buffer[j+i] << j*8); data |= (buffer[j+i] << j*8);
h_u32_to_be((uint8_t*)&data_out, data); h_u32_to_be((uint8_t *)&data_out, data);
retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED,
addr + i, data_out); addr + i, data_out);
@ -313,14 +300,13 @@ int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info,
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
data = be_to_h_u32((uint8_t*)&data); data = be_to_h_u32((uint8_t *)&data);
for (j = 0; i < count; j++, i++) for (j = 0; i < count; j++, i++) {
{
data &= ~(0xff << j*8); data &= ~(0xff << j*8);
data |= (buffer[j+i] << j*8); data |= (buffer[j+i] << j*8);
} }
h_u32_to_be((uint8_t*)&data_out, data); h_u32_to_be((uint8_t *)&data_out, data);
retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED, retval = avr32_jtag_mwa_write(jtag_info, SLAVE_HSB_UNCACHED,
addr+i, data_out); addr+i, data_out);

View File

@ -16,22 +16,22 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef AVR32_MEM #ifndef AVR32_MEM
#define AVR32_MEM #define AVR32_MEM
int avr32_jtag_read_memory32(struct avr32_jtag *jtag_info, int avr32_jtag_read_memory32(struct avr32_jtag *jtag_info,
uint32_t addr, int count, uint32_t *buffer); uint32_t addr, int count, uint32_t *buffer);
int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info, int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info,
uint32_t addr, int count, uint16_t *buffer); uint32_t addr, int count, uint16_t *buffer);
int avr32_jtag_read_memory8(struct avr32_jtag *jtag_info, int avr32_jtag_read_memory8(struct avr32_jtag *jtag_info,
uint32_t addr, int count, uint8_t *buffer); uint32_t addr, int count, uint8_t *buffer);
int avr32_jtag_write_memory32(struct avr32_jtag *jtag_info, int avr32_jtag_write_memory32(struct avr32_jtag *jtag_info,
uint32_t addr, int count, const uint32_t *buffer); uint32_t addr, int count, const uint32_t *buffer);
int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info, int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info,
uint32_t addr, int count, const uint16_t *buffer); uint32_t addr, int count, const uint16_t *buffer);
int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info, int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info,
uint32_t addr, int count, const uint8_t *buffer); uint32_t addr, int count, const uint8_t *buffer);
#endif /* AVR32_MEM */ #endif /* AVR32_MEM */

View File

@ -16,6 +16,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -25,7 +26,7 @@
#include "avr32_jtag.h" #include "avr32_jtag.h"
#include "avr32_regs.h" #include "avr32_regs.h"
static int avr32_jtag_read_reg(struct avr32_jtag *jtag_info, int reg, static int avr32_jtag_read_reg(struct avr32_jtag *jtag_info, int reg,
uint32_t *val) uint32_t *val)
{ {
int retval; int retval;
@ -36,27 +37,27 @@ static int avr32_jtag_read_reg(struct avr32_jtag *jtag_info, int reg,
return retval; return retval;
do { do {
retval = avr32_jtag_nexus_read(jtag_info, retval = avr32_jtag_nexus_read(jtag_info,
AVR32_OCDREG_DCSR, &dcsr); AVR32_OCDREG_DCSR, &dcsr);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
} while (!(dcsr & OCDREG_DCSR_CPUD)); } while (!(dcsr & OCDREG_DCSR_CPUD));
retval = avr32_jtag_nexus_read(jtag_info, retval = avr32_jtag_nexus_read(jtag_info,
AVR32_OCDREG_DCCPU, val); AVR32_OCDREG_DCCPU, val);
return retval; return retval;
} }
static int avr32_jtag_write_reg(struct avr32_jtag *jtag_info, int reg, static int avr32_jtag_write_reg(struct avr32_jtag *jtag_info, int reg,
uint32_t val) uint32_t val)
{ {
int retval; int retval;
uint32_t dcsr; uint32_t dcsr;
/* Restore Status reg */ /* Restore Status reg */
retval = avr32_jtag_nexus_write(jtag_info, retval = avr32_jtag_nexus_write(jtag_info,
AVR32_OCDREG_DCEMU, val); AVR32_OCDREG_DCEMU, val);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -65,7 +66,7 @@ static int avr32_jtag_write_reg(struct avr32_jtag *jtag_info, int reg,
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
do { do {
retval = avr32_jtag_nexus_read(jtag_info, retval = avr32_jtag_nexus_read(jtag_info,
AVR32_OCDREG_DCSR, &dcsr); AVR32_OCDREG_DCSR, &dcsr);
} while (!(dcsr & OCDREG_DCSR_EMUD) && (retval == ERROR_OK)); } while (!(dcsr & OCDREG_DCSR_EMUD) && (retval == ERROR_OK));
@ -79,7 +80,7 @@ int avr32_jtag_read_regs(struct avr32_jtag *jtag_info, uint32_t *regs)
int i, retval; int i, retval;
/* read core registers */ /* read core registers */
for (i = 0; i < AVR32NUMCOREREGS - 1; i++) for (i = 0; i < AVR32NUMCOREREGS - 1; i++)
avr32_jtag_read_reg(jtag_info, i, regs + i); avr32_jtag_read_reg(jtag_info, i, regs + i);
/* read status register */ /* read status register */
@ -108,7 +109,7 @@ int avr32_jtag_write_regs(struct avr32_jtag *jtag_info, uint32_t *regs)
/* /*
* And now the rest of registers * And now the rest of registers
*/ */
for (i = 0; i < AVR32NUMCOREREGS - 1; i++) for (i = 0; i < AVR32NUMCOREREGS - 1; i++)
avr32_jtag_write_reg(jtag_info, i, regs[i]); avr32_jtag_write_reg(jtag_info, i, regs[i]);
return ERROR_OK; return ERROR_OK;

View File

@ -16,6 +16,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef AVR32_REGS #ifndef AVR32_REGS
#define AVR32_REGS #define AVR32_REGS
@ -43,4 +44,3 @@ int avr32_jtag_read_regs(struct avr32_jtag *jtag_info, uint32_t *regs);
int avr32_jtag_write_regs(struct avr32_jtag *jtag_info, uint32_t *regs); int avr32_jtag_write_regs(struct avr32_jtag *jtag_info, uint32_t *regs);
#endif /* AVR32_REGS */ #endif /* AVR32_REGS */

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -25,7 +26,6 @@
#include "target.h" #include "target.h"
#include "target_type.h" #include "target_type.h"
#define AVR_JTAG_INS_LEN 4 #define AVR_JTAG_INS_LEN 4
/* forward declarations */ /* forward declarations */
@ -35,8 +35,10 @@ static int avr_init_target(struct command_context *cmd_ctx, struct target *targe
static int avr_arch_state(struct target *target); static int avr_arch_state(struct target *target);
static int avr_poll(struct target *target); static int avr_poll(struct target *target);
static int avr_halt(struct target *target); static int avr_halt(struct target *target);
static int avr_resume(struct target *target, int current, uint32_t address, int handle_breakpoints, int debug_execution); static int avr_resume(struct target *target, int current, uint32_t address,
static int avr_step(struct target *target, int current, uint32_t address, int handle_breakpoints); int handle_breakpoints, int debug_execution);
static int avr_step(struct target *target, int current, uint32_t address,
int handle_breakpoints);
static int avr_assert_reset(struct target *target); static int avr_assert_reset(struct target *target);
static int avr_deassert_reset(struct target *target); static int avr_deassert_reset(struct target *target);
@ -48,8 +50,7 @@ static int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out, i
static int mcu_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out, int ir_len, int rti); static int mcu_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out, int ir_len, int rti);
static int mcu_write_dr_u32(struct jtag_tap *tap, uint32_t *ir_in, uint32_t ir_out, int dr_len, int rti); static int mcu_write_dr_u32(struct jtag_tap *tap, uint32_t *ir_in, uint32_t ir_out, int dr_len, int rti);
struct target_type avr_target = struct target_type avr_target = {
{
.name = "avr", .name = "avr",
.poll = avr_poll, .poll = avr_poll,
@ -96,43 +97,41 @@ static int avr_target_create(struct target *target, Jim_Interp *interp)
static int avr_init_target(struct command_context *cmd_ctx, struct target *target) static int avr_init_target(struct command_context *cmd_ctx, struct target *target)
{ {
LOG_DEBUG("%s", __FUNCTION__); LOG_DEBUG("%s", __func__);
return ERROR_OK; return ERROR_OK;
} }
static int avr_arch_state(struct target *target) static int avr_arch_state(struct target *target)
{ {
LOG_DEBUG("%s", __FUNCTION__); LOG_DEBUG("%s", __func__);
return ERROR_OK; return ERROR_OK;
} }
static int avr_poll(struct target *target) static int avr_poll(struct target *target)
{ {
if ((target->state == TARGET_RUNNING) || (target->state == TARGET_DEBUG_RUNNING)) if ((target->state == TARGET_RUNNING) || (target->state == TARGET_DEBUG_RUNNING))
{
target->state = TARGET_HALTED; target->state = TARGET_HALTED;
}
LOG_DEBUG("%s", __FUNCTION__); LOG_DEBUG("%s", __func__);
return ERROR_OK; return ERROR_OK;
} }
static int avr_halt(struct target *target) static int avr_halt(struct target *target)
{ {
LOG_DEBUG("%s", __FUNCTION__); LOG_DEBUG("%s", __func__);
return ERROR_OK; return ERROR_OK;
} }
static int avr_resume(struct target *target, int current, uint32_t address, static int avr_resume(struct target *target, int current, uint32_t address,
int handle_breakpoints, int debug_execution) int handle_breakpoints, int debug_execution)
{ {
LOG_DEBUG("%s", __FUNCTION__); LOG_DEBUG("%s", __func__);
return ERROR_OK; return ERROR_OK;
} }
static int avr_step(struct target *target, int current, uint32_t address, int handle_breakpoints) static int avr_step(struct target *target, int current, uint32_t address, int handle_breakpoints)
{ {
LOG_DEBUG("%s", __FUNCTION__); LOG_DEBUG("%s", __func__);
return ERROR_OK; return ERROR_OK;
} }
@ -140,7 +139,7 @@ static int avr_assert_reset(struct target *target)
{ {
target->state = TARGET_RESET; target->state = TARGET_RESET;
LOG_DEBUG("%s", __FUNCTION__); LOG_DEBUG("%s", __func__);
return ERROR_OK; return ERROR_OK;
} }
@ -148,13 +147,13 @@ static int avr_deassert_reset(struct target *target)
{ {
target->state = TARGET_RUNNING; target->state = TARGET_RUNNING;
LOG_DEBUG("%s", __FUNCTION__); LOG_DEBUG("%s", __func__);
return ERROR_OK; return ERROR_OK;
} }
static int avr_soft_reset_halt(struct target *target) static int avr_soft_reset_halt(struct target *target)
{ {
LOG_DEBUG("%s", __FUNCTION__); LOG_DEBUG("%s", __func__);
return ERROR_OK; return ERROR_OK;
} }
@ -173,13 +172,11 @@ int avr_jtag_sendinstr(struct jtag_tap *tap, uint8_t *ir_in, uint8_t ir_out)
static int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out, static int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out,
int ir_len, int rti) int ir_len, int rti)
{ {
if (NULL == tap) if (NULL == tap) {
{
LOG_ERROR("invalid tap"); LOG_ERROR("invalid tap");
return ERROR_FAIL; return ERROR_FAIL;
} }
if (ir_len != tap->ir_length) if (ir_len != tap->ir_length) {
{
LOG_ERROR("invalid ir_len"); LOG_ERROR("invalid ir_len");
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -194,8 +191,7 @@ static int mcu_write_ir(struct jtag_tap *tap, uint8_t *ir_in, uint8_t *ir_out,
static int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out, static int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out,
int dr_len, int rti) int dr_len, int rti)
{ {
if (NULL == tap) if (NULL == tap) {
{
LOG_ERROR("invalid tap"); LOG_ERROR("invalid tap");
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -210,8 +206,7 @@ static int mcu_write_dr(struct jtag_tap *tap, uint8_t *dr_in, uint8_t *dr_out,
static int mcu_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in, static int mcu_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in,
uint8_t ir_out, int ir_len, int rti) uint8_t ir_out, int ir_len, int rti)
{ {
if (ir_len > 8) if (ir_len > 8) {
{
LOG_ERROR("ir_len overflow, maxium is 8"); LOG_ERROR("ir_len overflow, maxium is 8");
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -224,13 +219,12 @@ static int mcu_write_ir_u8(struct jtag_tap *tap, uint8_t *ir_in,
static int mcu_write_dr_u32(struct jtag_tap *tap, uint32_t *dr_in, static int mcu_write_dr_u32(struct jtag_tap *tap, uint32_t *dr_in,
uint32_t dr_out, int dr_len, int rti) uint32_t dr_out, int dr_len, int rti)
{ {
if (dr_len > 32) if (dr_len > 32) {
{
LOG_ERROR("dr_len overflow, maxium is 32"); LOG_ERROR("dr_len overflow, maxium is 32");
return ERROR_FAIL; return ERROR_FAIL;
} }
mcu_write_dr(tap, (uint8_t*)dr_in, (uint8_t*)&dr_out, dr_len, rti); mcu_write_dr(tap, (uint8_t *)dr_in, (uint8_t *)&dr_out, dr_len, rti);
return ERROR_OK; return ERROR_OK;
} }

View File

@ -17,18 +17,17 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef AVRT_H #ifndef AVRT_H
#define AVRT_H #define AVRT_H
#include <jtag/jtag.h> #include <jtag/jtag.h>
struct mcu_jtag struct mcu_jtag {
{
struct jtag_tap *tap; struct jtag_tap *tap;
}; };
struct avr_common struct avr_common {
{
struct mcu_jtag jtag_info; struct mcu_jtag jtag_info;
}; };

View File

@ -20,6 +20,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -28,24 +29,24 @@
#include <helper/log.h> #include <helper/log.h>
#include "breakpoints.h" #include "breakpoints.h"
static char *breakpoint_type_strings[] = {
static char *breakpoint_type_strings[] =
{
"hardware", "hardware",
"software" "software"
}; };
static char *watchpoint_rw_strings[] = static char *watchpoint_rw_strings[] = {
{
"read", "read",
"write", "write",
"access" "access"
}; };
// monotonic counter/id-number for breakpoints and watch points /* monotonic counter/id-number for breakpoints and watch points */
static int bpwp_unique_id; static int bpwp_unique_id;
int breakpoint_add_internal(struct target *target, uint32_t address, uint32_t length, enum breakpoint_type type) int breakpoint_add_internal(struct target *target,
uint32_t address,
uint32_t length,
enum breakpoint_type type)
{ {
struct breakpoint *breakpoint = target->breakpoints; struct breakpoint *breakpoint = target->breakpoints;
struct breakpoint **breakpoint_p = &target->breakpoints; struct breakpoint **breakpoint_p = &target->breakpoints;
@ -54,8 +55,7 @@ int breakpoint_add_internal(struct target *target, uint32_t address, uint32_t le
int n; int n;
n = 0; n = 0;
while (breakpoint) while (breakpoint) {
{
n++; n++;
if (breakpoint->address == address) { if (breakpoint->address == address) {
/* FIXME don't assume "same address" means "same /* FIXME don't assume "same address" means "same
@ -63,7 +63,7 @@ int breakpoint_add_internal(struct target *target, uint32_t address, uint32_t le
* succeeding. * succeeding.
*/ */
LOG_DEBUG("Duplicate Breakpoint address: 0x%08" PRIx32 " (BP %d)", LOG_DEBUG("Duplicate Breakpoint address: 0x%08" PRIx32 " (BP %d)",
address, breakpoint->unique_id); address, breakpoint->unique_id);
return ERROR_OK; return ERROR_OK;
} }
breakpoint_p = &breakpoint->next; breakpoint_p = &breakpoint->next;
@ -82,33 +82,36 @@ int breakpoint_add_internal(struct target *target, uint32_t address, uint32_t le
retval = target_add_breakpoint(target, *breakpoint_p); retval = target_add_breakpoint(target, *breakpoint_p);
switch (retval) { switch (retval) {
case ERROR_OK: case ERROR_OK:
break; break;
case ERROR_TARGET_RESOURCE_NOT_AVAILABLE: case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
reason = "resource not available"; reason = "resource not available";
goto fail; goto fail;
case ERROR_TARGET_NOT_HALTED: case ERROR_TARGET_NOT_HALTED:
reason = "target running"; reason = "target running";
goto fail; goto fail;
default: default:
reason = "unknown reason"; reason = "unknown reason";
fail: fail:
LOG_ERROR("can't add breakpoint: %s", reason); LOG_ERROR("can't add breakpoint: %s", reason);
free((*breakpoint_p)->orig_instr); free((*breakpoint_p)->orig_instr);
free(*breakpoint_p); free(*breakpoint_p);
*breakpoint_p = NULL; *breakpoint_p = NULL;
return retval; return retval;
} }
LOG_DEBUG("added %s breakpoint at 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %d)", LOG_DEBUG("added %s breakpoint at 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %d)",
breakpoint_type_strings[(*breakpoint_p)->type], breakpoint_type_strings[(*breakpoint_p)->type],
(*breakpoint_p)->address, (*breakpoint_p)->length, (*breakpoint_p)->address, (*breakpoint_p)->length,
(*breakpoint_p)->unique_id); (*breakpoint_p)->unique_id);
return ERROR_OK; return ERROR_OK;
} }
int context_breakpoint_add_internal(struct target *target, uint32_t asid, uint32_t length, enum breakpoint_type type) int context_breakpoint_add_internal(struct target *target,
uint32_t asid,
uint32_t length,
enum breakpoint_type type)
{ {
struct breakpoint *breakpoint = target->breakpoints; struct breakpoint *breakpoint = target->breakpoints;
struct breakpoint **breakpoint_p = &target->breakpoints; struct breakpoint **breakpoint_p = &target->breakpoints;
@ -116,17 +119,15 @@ int context_breakpoint_add_internal(struct target *target, uint32_t asid, uint32
int n; int n;
n = 0; n = 0;
while (breakpoint) while (breakpoint) {
{
n++; n++;
if (breakpoint->asid == asid) if (breakpoint->asid == asid) {
{
/* FIXME don't assume "same address" means "same /* FIXME don't assume "same address" means "same
* breakpoint" ... check all the parameters before * breakpoint" ... check all the parameters before
* succeeding. * succeeding.
*/ */
LOG_DEBUG("Duplicate Breakpoint asid: 0x%08" PRIx32 " (BP %d)", LOG_DEBUG("Duplicate Breakpoint asid: 0x%08" PRIx32 " (BP %d)",
asid, breakpoint->unique_id); asid, breakpoint->unique_id);
return -1; return -1;
} }
breakpoint_p = &breakpoint->next; breakpoint_p = &breakpoint->next;
@ -143,8 +144,7 @@ int context_breakpoint_add_internal(struct target *target, uint32_t asid, uint32
(*breakpoint_p)->next = NULL; (*breakpoint_p)->next = NULL;
(*breakpoint_p)->unique_id = bpwp_unique_id++; (*breakpoint_p)->unique_id = bpwp_unique_id++;
retval = target_add_context_breakpoint(target, *breakpoint_p); retval = target_add_context_breakpoint(target, *breakpoint_p);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
LOG_ERROR("could not add breakpoint"); LOG_ERROR("could not add breakpoint");
free((*breakpoint_p)->orig_instr); free((*breakpoint_p)->orig_instr);
free(*breakpoint_p); free(*breakpoint_p);
@ -153,22 +153,25 @@ int context_breakpoint_add_internal(struct target *target, uint32_t asid, uint32
} }
LOG_DEBUG("added %s Context breakpoint at 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %d)", LOG_DEBUG("added %s Context breakpoint at 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %d)",
breakpoint_type_strings[(*breakpoint_p)->type], breakpoint_type_strings[(*breakpoint_p)->type],
(*breakpoint_p)->asid, (*breakpoint_p)->length, (*breakpoint_p)->asid, (*breakpoint_p)->length,
(*breakpoint_p)->unique_id); (*breakpoint_p)->unique_id);
return ERROR_OK; return ERROR_OK;
} }
int hybrid_breakpoint_add_internal(struct target *target, uint32_t address, uint32_t asid, uint32_t length, enum breakpoint_type type) int hybrid_breakpoint_add_internal(struct target *target,
uint32_t address,
uint32_t asid,
uint32_t length,
enum breakpoint_type type)
{ {
struct breakpoint *breakpoint = target->breakpoints; struct breakpoint *breakpoint = target->breakpoints;
struct breakpoint **breakpoint_p = &target->breakpoints; struct breakpoint **breakpoint_p = &target->breakpoints;
int retval; int retval;
int n; int n;
n = 0; n = 0;
while (breakpoint) while (breakpoint) {
{
n++; n++;
if ((breakpoint->asid == asid) && (breakpoint->address == address)) { if ((breakpoint->asid == asid) && (breakpoint->address == address)) {
/* FIXME don't assume "same address" means "same /* FIXME don't assume "same address" means "same
@ -176,13 +179,11 @@ int hybrid_breakpoint_add_internal(struct target *target, uint32_t address, uint
* succeeding. * succeeding.
*/ */
LOG_DEBUG("Duplicate Hybrid Breakpoint asid: 0x%08" PRIx32 " (BP %d)", LOG_DEBUG("Duplicate Hybrid Breakpoint asid: 0x%08" PRIx32 " (BP %d)",
asid, breakpoint->unique_id); asid, breakpoint->unique_id);
return -1; return -1;
} } else if ((breakpoint->address == address) && (breakpoint->asid == 0)) {
else if ((breakpoint->address == address) && (breakpoint->asid == 0))
{
LOG_DEBUG("Duplicate Breakpoint IVA: 0x%08" PRIx32 " (BP %d)", LOG_DEBUG("Duplicate Breakpoint IVA: 0x%08" PRIx32 " (BP %d)",
address, breakpoint->unique_id); address, breakpoint->unique_id);
return -1; return -1;
} }
@ -201,92 +202,89 @@ int hybrid_breakpoint_add_internal(struct target *target, uint32_t address, uint
retval = target_add_hybrid_breakpoint(target, *breakpoint_p); retval = target_add_hybrid_breakpoint(target, *breakpoint_p);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
LOG_ERROR("could not add breakpoint"); LOG_ERROR("could not add breakpoint");
free((*breakpoint_p)->orig_instr); free((*breakpoint_p)->orig_instr);
free(*breakpoint_p); free(*breakpoint_p);
*breakpoint_p = NULL; *breakpoint_p = NULL;
return retval; return retval;
} }
LOG_DEBUG("added %s Hybrid breakpoint at address 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %d)", LOG_DEBUG(
breakpoint_type_strings[(*breakpoint_p)->type], "added %s Hybrid breakpoint at address 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %d)",
(*breakpoint_p)->address, (*breakpoint_p)->length, breakpoint_type_strings[(*breakpoint_p)->type],
(*breakpoint_p)->unique_id); (*breakpoint_p)->address,
(*breakpoint_p)->length,
(*breakpoint_p)->unique_id);
return ERROR_OK; return ERROR_OK;
} }
int breakpoint_add(struct target *target,
uint32_t address,
int breakpoint_add(struct target *target, uint32_t address, uint32_t length, enum breakpoint_type type) uint32_t length,
enum breakpoint_type type)
{ {
int retval = ERROR_OK; int retval = ERROR_OK;
if (target->smp) if (target->smp) {
{
struct target_list *head; struct target_list *head;
struct target *curr; struct target *curr;
head = target->head; head = target->head;
if (type == BKPT_SOFT) if (type == BKPT_SOFT)
return(breakpoint_add_internal(head->target, address,length, type)); return breakpoint_add_internal(head->target, address, length, type);
while(head != (struct target_list*)NULL) while (head != (struct target_list *)NULL) {
{
curr = head->target; curr = head->target;
retval = breakpoint_add_internal(curr, address,length, type); retval = breakpoint_add_internal(curr, address, length, type);
if (retval != ERROR_OK) return retval; if (retval != ERROR_OK)
return retval;
head = head->next; head = head->next;
} }
return retval; return retval;
} } else
else return breakpoint_add_internal(target, address, length, type);
return(breakpoint_add_internal(target, address, length, type));
} }
int context_breakpoint_add(struct target *target, uint32_t asid, uint32_t length, enum breakpoint_type type) int context_breakpoint_add(struct target *target,
uint32_t asid,
uint32_t length,
enum breakpoint_type type)
{ {
int retval = ERROR_OK; int retval = ERROR_OK;
if (target->smp) if (target->smp) {
{
struct target_list *head; struct target_list *head;
struct target *curr; struct target *curr;
head = target->head; head = target->head;
while(head != (struct target_list*)NULL) while (head != (struct target_list *)NULL) {
{
curr = head->target; curr = head->target;
retval = context_breakpoint_add_internal(curr, asid,length, type); retval = context_breakpoint_add_internal(curr, asid, length, type);
if (retval != ERROR_OK) return retval; if (retval != ERROR_OK)
return retval;
head = head->next; head = head->next;
} }
return retval; return retval;
} } else
else return context_breakpoint_add_internal(target, asid, length, type);
return(context_breakpoint_add_internal(target, asid, length, type));
} }
int hybrid_breakpoint_add(struct target *target, uint32_t address, uint32_t asid, uint32_t length, enum breakpoint_type type) int hybrid_breakpoint_add(struct target *target,
uint32_t address,
uint32_t asid,
uint32_t length,
enum breakpoint_type type)
{ {
int retval = ERROR_OK; int retval = ERROR_OK;
if (target->smp) if (target->smp) {
{
struct target_list *head; struct target_list *head;
struct target *curr; struct target *curr;
head = target->head; head = target->head;
while(head != (struct target_list*)NULL) while (head != (struct target_list *)NULL) {
{
curr = head->target; curr = head->target;
retval = hybrid_breakpoint_add_internal(curr, address, asid, length, type); retval = hybrid_breakpoint_add_internal(curr, address, asid, length, type);
if (retval != ERROR_OK) return retval; if (retval != ERROR_OK)
return retval;
head = head->next; head = head->next;
} }
return retval; return retval;
} } else
else return hybrid_breakpoint_add_internal(target, address, asid, length, type);
return(hybrid_breakpoint_add_internal(target, address, asid, length, type));
} }
/* free up a breakpoint */ /* free up a breakpoint */
@ -296,8 +294,7 @@ static void breakpoint_free(struct target *target, struct breakpoint *breakpoint
struct breakpoint **breakpoint_p = &target->breakpoints; struct breakpoint **breakpoint_p = &target->breakpoints;
int retval; int retval;
while (breakpoint) while (breakpoint) {
{
if (breakpoint == breakpoint_to_remove) if (breakpoint == breakpoint_to_remove)
break; break;
breakpoint_p = &breakpoint->next; breakpoint_p = &breakpoint->next;
@ -319,8 +316,7 @@ int breakpoint_remove_internal(struct target *target, uint32_t address)
{ {
struct breakpoint *breakpoint = target->breakpoints; struct breakpoint *breakpoint = target->breakpoints;
while (breakpoint) while (breakpoint) {
{
if ((breakpoint->address == address) && (breakpoint->asid == 0)) if ((breakpoint->address == address) && (breakpoint->asid == 0))
break; break;
else if ((breakpoint->address == 0) && (breakpoint->asid == address)) else if ((breakpoint->address == 0) && (breakpoint->asid == address))
@ -330,13 +326,10 @@ int breakpoint_remove_internal(struct target *target, uint32_t address)
breakpoint = breakpoint->next; breakpoint = breakpoint->next;
} }
if (breakpoint) if (breakpoint) {
{
breakpoint_free(target, breakpoint); breakpoint_free(target, breakpoint);
return 1; return 1;
} } else {
else
{
if (!target->smp) if (!target->smp)
LOG_ERROR("no breakpoint at address 0x%8.8" PRIx32 " found", address); LOG_ERROR("no breakpoint at address 0x%8.8" PRIx32 " found", address);
return 0; return 0;
@ -345,60 +338,50 @@ int breakpoint_remove_internal(struct target *target, uint32_t address)
void breakpoint_remove(struct target *target, uint32_t address) void breakpoint_remove(struct target *target, uint32_t address)
{ {
int found = 0; int found = 0;
if (target->smp) if (target->smp) {
{
struct target_list *head; struct target_list *head;
struct target *curr; struct target *curr;
head = target->head; head = target->head;
while(head != (struct target_list*)NULL) while (head != (struct target_list *)NULL) {
{
curr = head->target; curr = head->target;
found += breakpoint_remove_internal(curr, address); found += breakpoint_remove_internal(curr, address);
head = head->next; head = head->next;
} }
if (found == 0) if (found == 0)
LOG_ERROR("no breakpoint at address 0x%8.8" PRIx32 " found", address); LOG_ERROR("no breakpoint at address 0x%8.8" PRIx32 " found", address);
} } else
else breakpoint_remove_internal(target, address); breakpoint_remove_internal(target, address);
} }
void breakpoint_clear_target_internal(struct target *target) void breakpoint_clear_target_internal(struct target *target)
{ {
struct breakpoint *breakpoint;
LOG_DEBUG("Delete all breakpoints for target: %s", LOG_DEBUG("Delete all breakpoints for target: %s",
target_name(target)); target_name(target));
while ((breakpoint = target->breakpoints) != NULL) while (target->breakpoints != NULL)
{ breakpoint_free(target, target->breakpoints);
breakpoint_free(target, breakpoint);
}
} }
void breakpoint_clear_target(struct target *target) void breakpoint_clear_target(struct target *target)
{ {
if (target->smp) if (target->smp) {
{
struct target_list *head; struct target_list *head;
struct target *curr; struct target *curr;
head = target->head; head = target->head;
while(head != (struct target_list*)NULL) while (head != (struct target_list *)NULL) {
{
curr = head->target; curr = head->target;
breakpoint_clear_target_internal(curr); breakpoint_clear_target_internal(curr);
head = head->next; head = head->next;
} }
} } else
else breakpoint_clear_target_internal(target); breakpoint_clear_target_internal(target);
} }
struct breakpoint *breakpoint_find(struct target *target, uint32_t address)
struct breakpoint* breakpoint_find(struct target *target, uint32_t address)
{ {
struct breakpoint *breakpoint = target->breakpoints; struct breakpoint *breakpoint = target->breakpoints;
while (breakpoint) while (breakpoint) {
{
if (breakpoint->address == address) if (breakpoint->address == address)
return breakpoint; return breakpoint;
breakpoint = breakpoint->next; breakpoint = breakpoint->next;
@ -408,23 +391,22 @@ struct breakpoint* breakpoint_find(struct target *target, uint32_t address)
} }
int watchpoint_add(struct target *target, uint32_t address, uint32_t length, int watchpoint_add(struct target *target, uint32_t address, uint32_t length,
enum watchpoint_rw rw, uint32_t value, uint32_t mask) enum watchpoint_rw rw, uint32_t value, uint32_t mask)
{ {
struct watchpoint *watchpoint = target->watchpoints; struct watchpoint *watchpoint = target->watchpoints;
struct watchpoint **watchpoint_p = &target->watchpoints; struct watchpoint **watchpoint_p = &target->watchpoints;
int retval; int retval;
char *reason; char *reason;
while (watchpoint) while (watchpoint) {
{
if (watchpoint->address == address) { if (watchpoint->address == address) {
if (watchpoint->length != length if (watchpoint->length != length
|| watchpoint->value != value || watchpoint->value != value
|| watchpoint->mask != mask || watchpoint->mask != mask
|| watchpoint->rw != rw) { || watchpoint->rw != rw) {
LOG_ERROR("address 0x%8.8" PRIx32 LOG_ERROR("address 0x%8.8" PRIx32
"already has watchpoint %d", "already has watchpoint %d",
address, watchpoint->unique_id); address, watchpoint->unique_id);
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -445,31 +427,31 @@ int watchpoint_add(struct target *target, uint32_t address, uint32_t length,
retval = target_add_watchpoint(target, *watchpoint_p); retval = target_add_watchpoint(target, *watchpoint_p);
switch (retval) { switch (retval) {
case ERROR_OK: case ERROR_OK:
break; break;
case ERROR_TARGET_RESOURCE_NOT_AVAILABLE: case ERROR_TARGET_RESOURCE_NOT_AVAILABLE:
reason = "resource not available"; reason = "resource not available";
goto bye; goto bye;
case ERROR_TARGET_NOT_HALTED: case ERROR_TARGET_NOT_HALTED:
reason = "target running"; reason = "target running";
goto bye; goto bye;
default: default:
reason = "unrecognized error"; reason = "unrecognized error";
bye: bye:
LOG_ERROR("can't add %s watchpoint at 0x%8.8" PRIx32 ", %s", LOG_ERROR("can't add %s watchpoint at 0x%8.8" PRIx32 ", %s",
watchpoint_rw_strings[(*watchpoint_p)->rw], watchpoint_rw_strings[(*watchpoint_p)->rw],
address, reason); address, reason);
free (*watchpoint_p); free(*watchpoint_p);
*watchpoint_p = NULL; *watchpoint_p = NULL;
return retval; return retval;
} }
LOG_DEBUG("added %s watchpoint at 0x%8.8" PRIx32 LOG_DEBUG("added %s watchpoint at 0x%8.8" PRIx32
" of length 0x%8.8" PRIx32 " (WPID: %d)", " of length 0x%8.8" PRIx32 " (WPID: %d)",
watchpoint_rw_strings[(*watchpoint_p)->rw], watchpoint_rw_strings[(*watchpoint_p)->rw],
(*watchpoint_p)->address, (*watchpoint_p)->address,
(*watchpoint_p)->length, (*watchpoint_p)->length,
(*watchpoint_p)->unique_id); (*watchpoint_p)->unique_id);
return ERROR_OK; return ERROR_OK;
} }
@ -480,8 +462,7 @@ static void watchpoint_free(struct target *target, struct watchpoint *watchpoint
struct watchpoint **watchpoint_p = &target->watchpoints; struct watchpoint **watchpoint_p = &target->watchpoints;
int retval; int retval;
while (watchpoint) while (watchpoint) {
{
if (watchpoint == watchpoint_to_remove) if (watchpoint == watchpoint_to_remove)
break; break;
watchpoint_p = &watchpoint->next; watchpoint_p = &watchpoint->next;
@ -500,31 +481,22 @@ void watchpoint_remove(struct target *target, uint32_t address)
{ {
struct watchpoint *watchpoint = target->watchpoints; struct watchpoint *watchpoint = target->watchpoints;
while (watchpoint) while (watchpoint) {
{
if (watchpoint->address == address) if (watchpoint->address == address)
break; break;
watchpoint = watchpoint->next; watchpoint = watchpoint->next;
} }
if (watchpoint) if (watchpoint)
{
watchpoint_free(target, watchpoint); watchpoint_free(target, watchpoint);
}
else else
{
LOG_ERROR("no watchpoint at address 0x%8.8" PRIx32 " found", address); LOG_ERROR("no watchpoint at address 0x%8.8" PRIx32 " found", address);
}
} }
void watchpoint_clear_target(struct target *target) void watchpoint_clear_target(struct target *target)
{ {
struct watchpoint *watchpoint;
LOG_DEBUG("Delete all watchpoints for target: %s", LOG_DEBUG("Delete all watchpoints for target: %s",
target_name(target)); target_name(target));
while ((watchpoint = target->watchpoints) != NULL) while (target->watchpoints != NULL)
{ watchpoint_free(target, target->watchpoints);
watchpoint_free(target, watchpoint);
}
} }

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef BREAKPOINTS_H #ifndef BREAKPOINTS_H
#define BREAKPOINTS_H #define BREAKPOINTS_H
@ -24,19 +25,16 @@
struct target; struct target;
enum breakpoint_type enum breakpoint_type {
{
BKPT_HARD, BKPT_HARD,
BKPT_SOFT, BKPT_SOFT,
}; };
enum watchpoint_rw enum watchpoint_rw {
{
WPT_READ = 0, WPT_WRITE = 1, WPT_ACCESS = 2 WPT_READ = 0, WPT_WRITE = 1, WPT_ACCESS = 2
}; };
struct breakpoint struct breakpoint {
{
uint32_t address; uint32_t address;
uint32_t asid; uint32_t asid;
int length; int length;
@ -45,11 +43,10 @@ struct breakpoint
uint8_t *orig_instr; uint8_t *orig_instr;
struct breakpoint *next; struct breakpoint *next;
uint32_t unique_id; uint32_t unique_id;
int linked_BRP; int linked_BRP;
}; };
struct watchpoint struct watchpoint {
{
uint32_t address; uint32_t address;
uint32_t length; uint32_t length;
uint32_t mask; uint32_t mask;
@ -69,7 +66,7 @@ int hybrid_breakpoint_add(struct target *target,
uint32_t address, uint32_t asid, uint32_t length, enum breakpoint_type type); uint32_t address, uint32_t asid, uint32_t length, enum breakpoint_type type);
void breakpoint_remove(struct target *target, uint32_t address); void breakpoint_remove(struct target *target, uint32_t address);
struct breakpoint* breakpoint_find(struct target *target, uint32_t address); struct breakpoint *breakpoint_find(struct target *target, uint32_t address);
void watchpoint_clear_target(struct target *target); void watchpoint_clear_target(struct target *target);
int watchpoint_add(struct target *target, int watchpoint_add(struct target *target,

File diff suppressed because it is too large Load Diff

View File

@ -26,6 +26,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef CORTEX_A8_H #ifndef CORTEX_A8_H
#define CORTEX_A8_H #define CORTEX_A8_H
@ -44,8 +45,7 @@
#define CORTEX_A8_PADDRDBG_CPU_SHIFT 13 #define CORTEX_A8_PADDRDBG_CPU_SHIFT 13
struct cortex_a8_brp struct cortex_a8_brp {
{
int used; int used;
int type; int type;
uint32_t value; uint32_t value;
@ -53,8 +53,7 @@ struct cortex_a8_brp
uint8_t BRPn; uint8_t BRPn;
}; };
struct cortex_a8_common struct cortex_a8_common {
{
int common_magic; int common_magic;
struct arm_jtag jtag_info; struct arm_jtag jtag_info;
@ -65,7 +64,7 @@ struct cortex_a8_common
uint32_t cp15_control_reg; uint32_t cp15_control_reg;
/* latest cp15 register value written and cpsr processor mode */ /* latest cp15 register value written and cpsr processor mode */
uint32_t cp15_control_reg_curr; uint32_t cp15_control_reg_curr;
enum arm_mode curr_mode; enum arm_mode curr_mode;
/* Breakpoint register pairs */ /* Breakpoint register pairs */
@ -84,8 +83,7 @@ struct cortex_a8_common
static inline struct cortex_a8_common * static inline struct cortex_a8_common *
target_to_cortex_a8(struct target *target) target_to_cortex_a8(struct target *target)
{ {
return container_of(target->arch_info, struct cortex_a8_common, return container_of(target->arch_info, struct cortex_a8_common, armv7a_common.arm);
armv7a_common.arm);
} }
#endif /* CORTEX_A8_H */ #endif /* CORTEX_A8_H */

File diff suppressed because it is too large Load Diff

View File

@ -23,12 +23,12 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef CORTEX_M3_H #ifndef CORTEX_M3_H
#define CORTEX_M3_H #define CORTEX_M3_H
#include "armv7m.h" #include "armv7m.h"
#define CORTEX_M3_COMMON_MAGIC 0x1A451A45 #define CORTEX_M3_COMMON_MAGIC 0x1A451A45
#define SYSTEM_CONTROL_BASE 0x400FE000 #define SYSTEM_CONTROL_BASE 0x400FE000
@ -117,16 +117,14 @@
#define FPCR_REPLACE_BKPT_HIGH (2 << 30) #define FPCR_REPLACE_BKPT_HIGH (2 << 30)
#define FPCR_REPLACE_BKPT_BOTH (3 << 30) #define FPCR_REPLACE_BKPT_BOTH (3 << 30)
struct cortex_m3_fp_comparator struct cortex_m3_fp_comparator {
{
int used; int used;
int type; int type;
uint32_t fpcr_value; uint32_t fpcr_value;
uint32_t fpcr_address; uint32_t fpcr_address;
}; };
struct cortex_m3_dwt_comparator struct cortex_m3_dwt_comparator {
{
int used; int used;
uint32_t comp; uint32_t comp;
uint32_t mask; uint32_t mask;
@ -134,21 +132,18 @@ struct cortex_m3_dwt_comparator
uint32_t dwt_comparator_address; uint32_t dwt_comparator_address;
}; };
enum cortex_m3_soft_reset_config enum cortex_m3_soft_reset_config {
{
CORTEX_M3_RESET_SYSRESETREQ, CORTEX_M3_RESET_SYSRESETREQ,
CORTEX_M3_RESET_VECTRESET, CORTEX_M3_RESET_VECTRESET,
}; };
enum cortex_m3_isrmasking_mode enum cortex_m3_isrmasking_mode {
{
CORTEX_M3_ISRMASK_AUTO, CORTEX_M3_ISRMASK_AUTO,
CORTEX_M3_ISRMASK_OFF, CORTEX_M3_ISRMASK_OFF,
CORTEX_M3_ISRMASK_ON, CORTEX_M3_ISRMASK_ON,
}; };
struct cortex_m3_common struct cortex_m3_common {
{
int common_magic; int common_magic;
struct arm_jtag jtag_info; struct arm_jtag jtag_info;

File diff suppressed because it is too large Load Diff

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef DSP563XX_H #ifndef DSP563XX_H
#define DSP563XX_H #define DSP563XX_H
@ -26,25 +27,22 @@
#define DSP563XX_NUMCOREREGS 54 #define DSP563XX_NUMCOREREGS 54
#define DSP563XX_NUMONCEREGS 25 #define DSP563XX_NUMONCEREGS 25
struct mcu_jtag struct mcu_jtag {
{
struct jtag_tap *tap; struct jtag_tap *tap;
}; };
struct dsp563xx_common struct dsp563xx_common {
{
struct mcu_jtag jtag_info; struct mcu_jtag jtag_info;
struct reg_cache *core_cache; struct reg_cache *core_cache;
uint32_t core_regs[DSP563XX_NUMCOREREGS]; uint32_t core_regs[DSP563XX_NUMCOREREGS];
struct once_reg once_regs[DSP563XX_NUMONCEREGS]; struct once_reg once_regs[DSP563XX_NUMONCEREGS];
/* register cache to processor synchronization */ /* register cache to processor synchronization */
int (*read_core_reg) (struct target * target, int num); int (*read_core_reg) (struct target *target, int num);
int (*write_core_reg) (struct target * target, int num); int (*write_core_reg) (struct target *target, int num);
}; };
struct dsp563xx_core_reg struct dsp563xx_core_reg {
{
uint32_t num; uint32_t num;
const char *name; const char *name;
uint32_t size; uint32_t size;

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -63,7 +64,7 @@ static inline int dsp563xx_write_dr_u8(struct jtag_tap *tap, uint8_t * dr_in, ui
/** */ /** */
static inline int dsp563xx_write_dr_u32(struct jtag_tap *tap, uint32_t * dr_in, uint32_t dr_out, int dr_len, int rti) static inline int dsp563xx_write_dr_u32(struct jtag_tap *tap, uint32_t * dr_in, uint32_t dr_out, int dr_len, int rti)
{ {
return dsp563xx_write_dr(tap, (uint8_t *) dr_in, (uint8_t *) & dr_out, dr_len, rti); return dsp563xx_write_dr(tap, (uint8_t *) dr_in, (uint8_t *) &dr_out, dr_len, rti);
} }
/** single word instruction */ /** single word instruction */
@ -71,9 +72,10 @@ static inline int dsp563xx_once_ir_exec(struct jtag_tap *tap, int flush, uint8_t
{ {
int err; int err;
if ((err = dsp563xx_write_dr_u8(tap, 0, instr | (ex << 5) | (go << 6) | (rw << 7), 8, 0)) != ERROR_OK) err = dsp563xx_write_dr_u8(tap, 0, instr | (ex << 5) | (go << 6) | (rw << 7), 8, 0);
if (err != ERROR_OK)
return err; return err;
if ( flush ) if (flush)
err = jtag_execute_queue(); err = jtag_execute_queue();
return err; return err;
} }
@ -102,13 +104,15 @@ int dsp563xx_once_target_status(struct jtag_tap *tap)
int err; int err;
uint8_t jtag_status; uint8_t jtag_status;
if ((err = dsp563xx_jtag_sendinstr(tap, &jtag_status, JTAG_INSTR_ENABLE_ONCE)) != ERROR_OK) err = dsp563xx_jtag_sendinstr(tap, &jtag_status, JTAG_INSTR_ENABLE_ONCE);
if (err != ERROR_OK)
return TARGET_UNKNOWN; return TARGET_UNKNOWN;
if ((err = jtag_execute_queue()) != ERROR_OK) err = jtag_execute_queue();
if (err != ERROR_OK)
return TARGET_UNKNOWN; return TARGET_UNKNOWN;
/* verify correct static status pattern */ /* verify correct static status pattern */
if ( (jtag_status & JTAG_STATUS_STATIC_MASK) != JTAG_STATUS_STATIC_VALUE ) if ((jtag_status & JTAG_STATUS_STATIC_MASK) != JTAG_STATUS_STATIC_VALUE)
return TARGET_UNKNOWN; return TARGET_UNKNOWN;
if (jtag_status != JTAG_STATUS_DEBUG) if (jtag_status != JTAG_STATUS_DEBUG)
@ -127,59 +131,50 @@ int dsp563xx_once_request_debug(struct jtag_tap *tap, int reset_state)
/* in reset state we only get a ACK /* in reset state we only get a ACK
* from the interface */ * from the interface */
if (reset_state) if (reset_state)
{
pattern = 1; pattern = 1;
}
else else
{
pattern = JTAG_STATUS_DEBUG; pattern = JTAG_STATUS_DEBUG;
}
/* wait until we get the ack */ /* wait until we get the ack */
while (ir_in != pattern) while (ir_in != pattern) {
{ err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_DEBUG_REQUEST);
if ((err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_DEBUG_REQUEST)) != ERROR_OK) if (err != ERROR_OK)
return err; return err;
if ((err = jtag_execute_queue()) != ERROR_OK) err = jtag_execute_queue();
if (err != ERROR_OK)
return err; return err;
LOG_DEBUG("debug request: %02X", ir_in); LOG_DEBUG("debug request: %02X", ir_in);
if (retry++ == 100) if (retry++ == 100)
{
return ERROR_TARGET_FAILURE; return ERROR_TARGET_FAILURE;
}
} }
/* we cant enable the once in reset state */ /* we cant enable the once in reset state */
if (pattern == 1) if (pattern == 1)
{
return ERROR_OK; return ERROR_OK;
}
/* try to enable once */ /* try to enable once */
retry = 0; retry = 0;
ir_in = 0; ir_in = 0;
while (ir_in != pattern) while (ir_in != pattern) {
{ err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_ENABLE_ONCE);
if ((err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_ENABLE_ONCE)) != ERROR_OK) if (err != ERROR_OK)
return err; return err;
if ((err = jtag_execute_queue()) != ERROR_OK) err = jtag_execute_queue();
if (err != ERROR_OK)
return err; return err;
LOG_DEBUG("enable once: %02X", ir_in); LOG_DEBUG("enable once: %02X", ir_in);
if (retry++ == 100) if (retry++ == 100) {
{
LOG_DEBUG("error"); LOG_DEBUG("error");
return ERROR_TARGET_FAILURE; return ERROR_TARGET_FAILURE;
} }
} }
if (ir_in != JTAG_STATUS_DEBUG) if (ir_in != JTAG_STATUS_DEBUG)
{
return ERROR_TARGET_FAILURE; return ERROR_TARGET_FAILURE;
}
return ERROR_OK; return ERROR_OK;
} }
@ -190,13 +185,13 @@ int dsp563xx_once_read_register(struct jtag_tap *tap, int flush, struct once_reg
int i; int i;
int err = ERROR_OK; int err = ERROR_OK;
for (i = 0; i < len; i++) for (i = 0; i < len; i++) {
{ err = dsp563xx_once_reg_read_ex(tap, flush, regs[i].addr, regs[i].len, &regs[i].reg);
if ((err = dsp563xx_once_reg_read_ex(tap, flush, regs[i].addr, regs[i].len, &regs[i].reg)) != ERROR_OK) if (err != ERROR_OK)
return err; return err;
} }
if ( flush ) if (flush)
err = jtag_execute_queue(); err = jtag_execute_queue();
return err; return err;
} }
@ -206,11 +201,13 @@ int dsp563xx_once_reg_read_ex(struct jtag_tap *tap, int flush, uint8_t reg, uint
{ {
int err; int err;
if ((err = dsp563xx_once_ir_exec(tap, 1, reg, 1, 0, 0)) != ERROR_OK) err = dsp563xx_once_ir_exec(tap, 1, reg, 1, 0, 0);
if (err != ERROR_OK)
return err; return err;
if ((err = dsp563xx_write_dr_u32(tap, data, 0x00, len, 0)) != ERROR_OK) err = dsp563xx_write_dr_u32(tap, data, 0x00, len, 0);
if (err != ERROR_OK)
return err; return err;
if ( flush ) if (flush)
err = jtag_execute_queue(); err = jtag_execute_queue();
return err; return err;
} }
@ -220,11 +217,13 @@ int dsp563xx_once_reg_read(struct jtag_tap *tap, int flush, uint8_t reg, uint32_
{ {
int err; int err;
if ((err = dsp563xx_once_ir_exec(tap, flush, reg, 1, 0, 0)) != ERROR_OK) err = dsp563xx_once_ir_exec(tap, flush, reg, 1, 0, 0);
if (err != ERROR_OK)
return err; return err;
if ((err = dsp563xx_write_dr_u32(tap, data, 0x00, 24, 0)) != ERROR_OK) err = dsp563xx_write_dr_u32(tap, data, 0x00, 24, 0);
if (err != ERROR_OK)
return err; return err;
if ( flush ) if (flush)
err = jtag_execute_queue(); err = jtag_execute_queue();
return err; return err;
} }
@ -234,11 +233,13 @@ int dsp563xx_once_reg_write(struct jtag_tap *tap, int flush, uint8_t reg, uint32
{ {
int err; int err;
if ((err = dsp563xx_once_ir_exec(tap, flush, reg, 0, 0, 0)) != ERROR_OK) err = dsp563xx_once_ir_exec(tap, flush, reg, 0, 0, 0);
if (err != ERROR_OK)
return err; return err;
if ((err = dsp563xx_write_dr_u32(tap, 0x00, data, 24, 0)) != ERROR_OK) err = dsp563xx_write_dr_u32(tap, 0x00, data, 24, 0);
if (err != ERROR_OK)
return err; return err;
if ( flush ) if (flush)
err = jtag_execute_queue(); err = jtag_execute_queue();
return err; return err;
} }
@ -248,11 +249,13 @@ int dsp563xx_once_execute_sw_ir(struct jtag_tap *tap, int flush, uint32_t opcode
{ {
int err; int err;
if ((err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 1, 0)) != ERROR_OK) err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 1, 0);
if (err != ERROR_OK)
return err; return err;
if ((err = dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0)) != ERROR_OK) err = dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
if (err != ERROR_OK)
return err; return err;
if ( flush ) if (flush)
err = jtag_execute_queue(); err = jtag_execute_queue();
return err; return err;
} }
@ -262,21 +265,29 @@ int dsp563xx_once_execute_dw_ir(struct jtag_tap *tap, int flush, uint32_t opcode
{ {
int err; int err;
if ((err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 0, 0)) != ERROR_OK) err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 0, 0);
if (err != ERROR_OK)
return err; return err;
if ((err = dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0)) != ERROR_OK) err = dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
if (err != ERROR_OK)
return err; return err;
if ( flush ) if (flush) {
if ((err = jtag_execute_queue()) != ERROR_OK) err = jtag_execute_queue();
if (err != ERROR_OK)
return err; return err;
}
if ((err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 1, 0)) != ERROR_OK) err = dsp563xx_once_ir_exec(tap, flush, DSP563XX_ONCE_OPDBR, 0, 1, 0);
if (err != ERROR_OK)
return err; return err;
if ((err = dsp563xx_write_dr_u32(tap, 0, operand, 24, 0)) != ERROR_OK) err = dsp563xx_write_dr_u32(tap, 0, operand, 24, 0);
if (err != ERROR_OK)
return err; return err;
if ( flush ) if (flush) {
if ((err = jtag_execute_queue()) != ERROR_OK) err = jtag_execute_queue();
if (err != ERROR_OK)
return err; return err;
}
return ERROR_OK; return ERROR_OK;
} }

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef DSP563XX_ONCE_H #ifndef DSP563XX_ONCE_H
#define DSP563XX_ONCE_H #define DSP563XX_ONCE_H
@ -57,8 +58,7 @@
#define DSP563XX_ONCE_OPABF11 0x012 /* trace buffer/inc ptr */ #define DSP563XX_ONCE_OPABF11 0x012 /* trace buffer/inc ptr */
#define DSP563XX_ONCE_NOREG 0x01F /* no register selected */ #define DSP563XX_ONCE_NOREG 0x01F /* no register selected */
struct once_reg struct once_reg {
{
uint8_t num; uint8_t num;
uint8_t addr; uint8_t addr;
uint8_t len; uint8_t len;

View File

@ -20,6 +20,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -1542,7 +1543,7 @@ static int perl_crc(uint8_t *buff8, uint32_t word_count)
data = (buff8[2 * i] | (buff8[2 * i + 1] << 8)); data = (buff8[2 * i] | (buff8[2 * i + 1] << 8));
fbmisr = fbmisr =
(checksum & 2) >> 1 ^ (checksum & 4) >> 2 ^ (checksum & 16) (checksum & 2) >> 1 ^ (checksum & 4) >> 2 ^ (checksum & 16)
>> 4 ^ (checksum & 0x8000) >> 15; >> 4 ^ (checksum & 0x8000) >> 15;
checksum = (data ^ ((checksum << 1) | fbmisr)); checksum = (data ^ ((checksum << 1) | fbmisr));
} }
i--; i--;
@ -1978,13 +1979,13 @@ int dsp5680xx_f_erase(struct target *target, int first, int last)
*/ */
const uint16_t pgm_write_pflash[] = { 0x8A46, 0x0013, 0x807D, 0xE700, const uint16_t pgm_write_pflash[] = { 0x8A46, 0x0013, 0x807D, 0xE700,
0xE700, 0x8A44, 0xFFFE, 0x017B, 0xE700, 0x8A44, 0xFFFE, 0x017B,
0xE700, 0xF514, 0x8563, 0x8646, 0xE700, 0xF514, 0x8563, 0x8646,
0x0020, 0x0014, 0x8646, 0x0080, 0x0020, 0x0014, 0x8646, 0x0080,
0x0013, 0xF042, 0x0013, 0x8B40, 0x0013, 0xF042, 0x0013, 0x8B40,
0x2004, 0x8246, 0x0013, 0x0020, 0x2004, 0x8246, 0x0013, 0x0020,
0xA967, 0x8B40, 0x1065, 0x8246, 0xA967, 0x8B40, 0x1065, 0x8246,
0x0013, 0x0010, 0xA961 0x0013, 0x0010, 0xA961
}; };
const uint32_t pgm_write_pflash_length = 31; const uint32_t pgm_write_pflash_length = 31;

View File

@ -20,6 +20,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef DSP5680XX_H #ifndef DSP5680XX_H
#define DSP5680XX_H #define DSP5680XX_H
@ -29,12 +30,12 @@
* @file dsp5680xx.h * @file dsp5680xx.h
* @author Rodrigo Rosa <rodrigorosa.LG@gmail.com> * @author Rodrigo Rosa <rodrigorosa.LG@gmail.com>
* @date Thu Jun 9 18:54:38 2011 * @date Thu Jun 9 18:54:38 2011
* *
* @brief Basic support for the 5680xx DSP from Freescale. * @brief Basic support for the 5680xx DSP from Freescale.
* The chip has two taps in the JTAG chain, the Master tap and the Core tap. * The chip has two taps in the JTAG chain, the Master tap and the Core tap.
* In this code the Master tap is only used to unlock the flash memory by executing a JTAG instruction. * In this code the Master tap is only used to unlock the flash memory by executing a JTAG instruction.
* *
* *
*/ */
#define S_FILE_DATA_OFFSET 0x200000 #define S_FILE_DATA_OFFSET 0x200000
@ -153,7 +154,7 @@
* ---------------------------------------------------------------- * ----------------------------------------------------------------
*/ */
#define FLUSH_COUNT_READ_WRITE 8192 // This value works, higher values (and lower...) may work as well. #define FLUSH_COUNT_READ_WRITE 8192 /* This value works, higher values (and lower...) may work as well. */
#define FLUSH_COUNT_FLASH 8192 #define FLUSH_COUNT_FLASH 8192
/** ---------------------------------------------------------------- /** ----------------------------------------------------------------
* HFM (flash module) Commands (ref:MC56F801xRM.pdf@159) * HFM (flash module) Commands (ref:MC56F801xRM.pdf@159)
@ -201,7 +202,7 @@
/** /**
* The value used on for the FM clock is important to prevent flashing errors and to prevent deterioration of the FM. * The value used on for the FM clock is important to prevent flashing errors and to prevent deterioration of the FM.
* This value was calculated using a spreadsheet tool available on the Freescale website under FAQ 25464. * This value was calculated using a spreadsheet tool available on the Freescale website under FAQ 25464.
* *
*/ */
#define HFM_CLK_DEFAULT 0x27 #define HFM_CLK_DEFAULT 0x27
/* 0x27 according to freescale cfg, but 0x40 according to freescale spreadsheet... */ /* 0x27 according to freescale cfg, but 0x40 according to freescale spreadsheet... */
@ -299,73 +300,86 @@ static inline struct dsp5680xx_common *target_to_dsp5680xx(struct target
return target->arch_info; return target->arch_info;
} }
/** /**
* Writes to flash memory. * Writes to flash memory.
* Does not check if flash is erased, it's up to the user to erase the flash before running this function. * Does not check if flash is erased, it's up to the user to erase the flash before running
* The flashing algorithm runs from RAM, reading from a register to which this function writes to. The algorithm is open loop, there is no control to verify that the FM read the register before writing the next data. A closed loop approach was much slower, and the current implementation does not fail, and if it did the crc check would detect it, allowing to flash again. * this function.
* * The flashing algorithm runs from RAM, reading from a register to which this function
* @param target * writes to. The algorithm is open loop, there is no control to verify that the FM read
* @param buffer * the register before writing the next data. A closed loop approach was much slower,
* and the current implementation does not fail, and if it did the crc check would detect it,
* allowing to flash again.
*
* @param target
* @param buffer
* @param address Word addressing. * @param address Word addressing.
* @param count In bytes. * @param count In bytes.
* @param verify_flash Execute a CRC check after flashing. * @param verify_flash Execute a CRC check after flashing.
* *
* @return * @return
*/ */
int dsp5680xx_f_wr(struct target *target, uint8_t * buffer, uint32_t address, int dsp5680xx_f_wr(struct target *target, uint8_t * buffer, uint32_t address,
uint32_t count, int is_flash_lock); uint32_t count, int is_flash_lock);
/** /**
* The FM has the funcionality of checking if the flash array is erased. This function executes it. It does not support individual sector analysis. * The FM has the funcionality of checking if the flash array is erased. This function
* * executes it. It does not support individual sector analysis.
* @param target *
* @param erased * @param target
* @param sector This parameter is ignored because the FM does not support checking if individual sectors are erased. * @param erased
* * @param sector This parameter is ignored because the FM does not support checking if
* @return * individual sectors are erased.
*
* @return
*/ */
int dsp5680xx_f_erase_check(struct target *target, uint8_t * erased, int dsp5680xx_f_erase_check(struct target *target, uint8_t * erased,
uint32_t sector); uint32_t sector);
/** /**
* Erases either a sector or the complete flash array. If either the range first-last covers the complete array or if @first == 0 and @last == 0 then a mass erase command is executed on the FM. If not, then individual sectors are erased. * Erases either a sector or the complete flash array. If either the range first-last covers
* * the complete array or if @first == 0 and @last == 0 then a mass erase command is executed
* @param target * on the FM. If not, then individual sectors are erased.
* @param first *
* @param last * @param target
* * @param first
* @return * @param last
*
* @return
*/ */
int dsp5680xx_f_erase(struct target *target, int first, int last); int dsp5680xx_f_erase(struct target *target, int first, int last);
/** /**
* Reads the memory mapped protection register. A 1 implies the sector is protected, a 0 implies the sector is not protected. * Reads the memory mapped protection register. A 1 implies the sector is protected,
* * a 0 implies the sector is not protected.
* @param target *
* @param target
* @param protected Data read from the protection register. * @param protected Data read from the protection register.
* *
* @return * @return
*/ */
int dsp5680xx_f_protect_check(struct target *target, uint16_t * protected); int dsp5680xx_f_protect_check(struct target *target, uint16_t * protected);
/** /**
* Writes the flash security words with a specific value. The chip's security will be enabled after the first reset following the execution of this function. * Writes the flash security words with a specific value. The chip's security will be
* * enabled after the first reset following the execution of this function.
* @param target *
* * @param target
* @return *
* @return
*/ */
int dsp5680xx_f_lock(struct target *target); int dsp5680xx_f_lock(struct target *target);
/** /**
* Executes a mass erase command. The must be done from the Master tap. * Executes a mass erase command. The must be done from the Master tap.
* It is up to the user to select the master tap (jtag tapenable dsp5680xx.chp) before running this function. * It is up to the user to select the master tap (jtag tapenable dsp5680xx.chp)
* The flash array will be unsecured (and erased) after the first reset following the execution of this function. * before running this function.
* * The flash array will be unsecured (and erased) after the first reset following
* @param target * the execution of this function.
* *
* @return * @param target
*
* @return
*/ */
int dsp5680xx_f_unlock(struct target *target); int dsp5680xx_f_unlock(struct target *target);
#endif /* dsp5680xx.h */ #endif /* dsp5680xx.h */

View File

@ -23,6 +23,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -87,7 +88,7 @@ static const struct {
.addr = 9, .addr = 9,
.width = 32, .width = 32,
}, },
[EICE_W0_DATA_VALUE ] = { [EICE_W0_DATA_VALUE] = {
.name = "watch_0_data_value", .name = "watch_0_data_value",
.addr = 10, .addr = 10,
.width = 32, .width = 32,
@ -145,14 +146,16 @@ static const struct {
}, },
}; };
static int embeddedice_get_reg(struct reg *reg) static int embeddedice_get_reg(struct reg *reg)
{ {
int retval; int retval = embeddedice_read_reg(reg);
if (retval != ERROR_OK) {
if ((retval = embeddedice_read_reg(reg)) != ERROR_OK)
LOG_ERROR("error queueing EmbeddedICE register read"); LOG_ERROR("error queueing EmbeddedICE register read");
else if ((retval = jtag_execute_queue()) != ERROR_OK) return retval;
}
retval = jtag_execute_queue();
if (retval != ERROR_OK)
LOG_ERROR("EmbeddedICE register read failed"); LOG_ERROR("EmbeddedICE register read failed");
return retval; return retval;
@ -168,8 +171,8 @@ static const struct reg_arch_type eice_reg_type = {
* Different versions of the modules have different capabilities, such as * Different versions of the modules have different capabilities, such as
* hardware support for vector_catch, single stepping, and monitor mode. * hardware support for vector_catch, single stepping, and monitor mode.
*/ */
struct reg_cache * struct reg_cache *embeddedice_build_reg_cache(struct target *target,
embeddedice_build_reg_cache(struct target *target, struct arm7_9_common *arm7_9) struct arm7_9_common *arm7_9)
{ {
int retval; int retval;
struct reg_cache *reg_cache = malloc(sizeof(struct reg_cache)); struct reg_cache *reg_cache = malloc(sizeof(struct reg_cache));
@ -200,8 +203,7 @@ embeddedice_build_reg_cache(struct target *target, struct arm7_9_common *arm7_9)
*/ */
/* set up registers */ /* set up registers */
for (i = 0; i < num_regs; i++) for (i = 0; i < num_regs; i++) {
{
reg_list[i].name = eice_regs[i].name; reg_list[i].name = eice_regs[i].name;
reg_list[i].size = eice_regs[i].width; reg_list[i].size = eice_regs[i].width;
reg_list[i].dirty = 0; reg_list[i].dirty = 0;
@ -215,12 +217,10 @@ embeddedice_build_reg_cache(struct target *target, struct arm7_9_common *arm7_9)
/* identify EmbeddedICE version by reading DCC control register */ /* identify EmbeddedICE version by reading DCC control register */
embeddedice_read_reg(&reg_list[EICE_COMMS_CTRL]); embeddedice_read_reg(&reg_list[EICE_COMMS_CTRL]);
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK) {
for (i = 0; i < num_regs; i++) for (i = 0; i < num_regs; i++)
{
free(reg_list[i].value); free(reg_list[i].value);
}
free(reg_list); free(reg_list);
free(reg_cache); free(reg_cache);
free(arch_info); free(arch_info);
@ -230,8 +230,7 @@ embeddedice_build_reg_cache(struct target *target, struct arm7_9_common *arm7_9)
eice_version = buf_get_u32(reg_list[EICE_COMMS_CTRL].value, 28, 4); eice_version = buf_get_u32(reg_list[EICE_COMMS_CTRL].value, 28, 4);
LOG_INFO("Embedded ICE version %d", eice_version); LOG_INFO("Embedded ICE version %d", eice_version);
switch (eice_version) switch (eice_version) {
{
case 1: case 1:
/* ARM7TDMI r3, ARM7TDMI-S r3 /* ARM7TDMI r3, ARM7TDMI-S r3
* *
@ -290,7 +289,7 @@ embeddedice_build_reg_cache(struct target *target, struct arm7_9_common *arm7_9)
* and do the appropriate setup itself. * and do the appropriate setup itself.
*/ */
if (strcmp(target_type_name(target), "feroceon") == 0 || if (strcmp(target_type_name(target), "feroceon") == 0 ||
strcmp(target_type_name(target), "dragonite") == 0) strcmp(target_type_name(target), "dragonite") == 0)
break; break;
LOG_ERROR("unknown EmbeddedICE version " LOG_ERROR("unknown EmbeddedICE version "
"(comms ctrl: 0x%8.8" PRIx32 ")", "(comms ctrl: 0x%8.8" PRIx32 ")",
@ -318,12 +317,12 @@ int embeddedice_setup(struct target *target)
* that manages break requests. ARM's "Angel Debug Monitor" is one * that manages break requests. ARM's "Angel Debug Monitor" is one
* common example of such code. * common example of such code.
*/ */
if (arm7_9->has_monitor_mode) if (arm7_9->has_monitor_mode) {
{
struct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]; struct reg *dbg_ctrl = &arm7_9->eice_cache->reg_list[EICE_DBG_CTRL];
embeddedice_read_reg(dbg_ctrl); embeddedice_read_reg(dbg_ctrl);
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
if (retval != ERROR_OK)
return retval; return retval;
buf_set_u32(dbg_ctrl->value, 4, 1, 0); buf_set_u32(dbg_ctrl->value, 4, 1, 0);
embeddedice_set_reg_w_exec(dbg_ctrl, dbg_ctrl->value); embeddedice_set_reg_w_exec(dbg_ctrl, dbg_ctrl->value);
@ -350,7 +349,8 @@ int embeddedice_read_reg_w_check(struct reg *reg,
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
retval = arm_jtag_set_instr(ice_reg->jtag_info, ice_reg->jtag_info->intest_instr, NULL, TAP_IDLE); retval = arm_jtag_set_instr(ice_reg->jtag_info,
ice_reg->jtag_info->intest_instr, NULL, TAP_IDLE);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
@ -435,8 +435,7 @@ int embeddedice_receive(struct arm_jtag *jtag_info, uint32_t *data, uint32_t siz
jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE); jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
while (size > 0) while (size > 0) {
{
/* when reading the last item, set the register address to the DCC control reg, /* when reading the last item, set the register address to the DCC control reg,
* to avoid reading additional data from the DCC data reg * to avoid reading additional data from the DCC data reg
*/ */
@ -486,7 +485,8 @@ static int embeddedice_set_reg_w_exec(struct reg *reg, uint8_t *buf)
int retval; int retval;
embeddedice_set_reg(reg, buf_get_u32(buf, 0, reg->size)); embeddedice_set_reg(reg, buf_get_u32(buf, 0, reg->size));
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
if (retval != ERROR_OK)
LOG_ERROR("register write failed"); LOG_ERROR("register write failed");
return retval; return retval;
} }
@ -555,8 +555,7 @@ int embeddedice_send(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size)
fields[2].in_value = NULL; fields[2].in_value = NULL;
while (size > 0) while (size > 0) {
{
buf_set_u32(field0_out, 0, 32, *data); buf_set_u32(field0_out, 0, 32, *data);
jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE); jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
@ -586,8 +585,7 @@ int embeddedice_handshake(struct arm_jtag *jtag_info, int hsbit, uint32_t timeou
hsact = 1; hsact = 1;
else if (hsbit == EICE_COMM_CTRL_RBIT) else if (hsbit == EICE_COMM_CTRL_RBIT)
hsact = 0; hsact = 0;
else else {
{
LOG_ERROR("Invalid arguments"); LOG_ERROR("Invalid arguments");
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
@ -617,7 +615,8 @@ int embeddedice_handshake(struct arm_jtag *jtag_info, int hsbit, uint32_t timeou
gettimeofday(&lap, NULL); gettimeofday(&lap, NULL);
do { do {
jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE); jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_IDLE);
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
if (retval != ERROR_OK)
return retval; return retval;
if (buf_get_u32(field0_in, hsbit, 1) == hsact) if (buf_get_u32(field0_in, hsbit, 1) == hsact)
@ -640,8 +639,7 @@ void embeddedice_write_dcc(struct jtag_tap *tap,
{ {
int i; int i;
for (i = 0; i < count; i++) for (i = 0; i < count; i++) {
{
embeddedice_write_reg_inner(tap, reg_addr, embeddedice_write_reg_inner(tap, reg_addr,
fast_target_buffer_get_u32(buffer, little)); fast_target_buffer_get_u32(buffer, little));
buffer += 4; buffer += 4;

View File

@ -23,13 +23,13 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef EMBEDDED_ICE_H #ifndef EMBEDDED_ICE_H
#define EMBEDDED_ICE_H #define EMBEDDED_ICE_H
#include "arm7_9_common.h" #include "arm7_9_common.h"
enum enum {
{
EICE_DBG_CTRL = 0, EICE_DBG_CTRL = 0,
EICE_DBG_STAT = 1, EICE_DBG_STAT = 1,
EICE_COMMS_CTRL = 2, EICE_COMMS_CTRL = 2,
@ -49,8 +49,7 @@ enum
EICE_VEC_CATCH = 16 EICE_VEC_CATCH = 16
}; };
enum enum {
{
EICE_DBG_CONTROL_ICEDIS = 5, EICE_DBG_CONTROL_ICEDIS = 5,
EICE_DBG_CONTROL_MONEN = 4, EICE_DBG_CONTROL_MONEN = 4,
EICE_DBG_CONTROL_INTDIS = 2, EICE_DBG_CONTROL_INTDIS = 2,
@ -58,8 +57,7 @@ enum
EICE_DBG_CONTROL_DBGACK = 0, EICE_DBG_CONTROL_DBGACK = 0,
}; };
enum enum {
{
EICE_DBG_STATUS_IJBIT = 5, EICE_DBG_STATUS_IJBIT = 5,
EICE_DBG_STATUS_ITBIT = 4, EICE_DBG_STATUS_ITBIT = 4,
EICE_DBG_STATUS_SYSCOMP = 3, EICE_DBG_STATUS_SYSCOMP = 3,
@ -68,8 +66,7 @@ enum
EICE_DBG_STATUS_DBGACK = 0 EICE_DBG_STATUS_DBGACK = 0
}; };
enum enum {
{
EICE_W_CTRL_ENABLE = 0x100, EICE_W_CTRL_ENABLE = 0x100,
EICE_W_CTRL_RANGE = 0x80, EICE_W_CTRL_RANGE = 0x80,
EICE_W_CTRL_CHAIN = 0x40, EICE_W_CTRL_CHAIN = 0x40,
@ -81,26 +78,24 @@ enum
EICE_W_CTRL_nRW = 0x1 EICE_W_CTRL_nRW = 0x1
}; };
enum enum {
{
EICE_COMM_CTRL_WBIT = 1, EICE_COMM_CTRL_WBIT = 1,
EICE_COMM_CTRL_RBIT = 0 EICE_COMM_CTRL_RBIT = 0
}; };
struct embeddedice_reg struct embeddedice_reg {
{
int addr; int addr;
struct arm_jtag *jtag_info; struct arm_jtag *jtag_info;
}; };
struct reg_cache* embeddedice_build_reg_cache(struct target *target, struct reg_cache *embeddedice_build_reg_cache(struct target *target,
struct arm7_9_common *arm7_9); struct arm7_9_common *arm7_9);
int embeddedice_setup(struct target *target); int embeddedice_setup(struct target *target);
int embeddedice_read_reg(struct reg *reg); int embeddedice_read_reg(struct reg *reg);
int embeddedice_read_reg_w_check(struct reg *reg, int embeddedice_read_reg_w_check(struct reg *reg,
uint8_t* check_value, uint8_t* check_mask); uint8_t *check_value, uint8_t *check_mask);
void embeddedice_write_reg(struct reg *reg, uint32_t value); void embeddedice_write_reg(struct reg *reg, uint32_t value);
void embeddedice_store_reg(struct reg *reg); void embeddedice_store_reg(struct reg *reg);
@ -112,10 +107,10 @@ int embeddedice_send(struct arm_jtag *jtag_info, uint32_t *data, uint32_t size);
int embeddedice_handshake(struct arm_jtag *jtag_info, int hsbit, uint32_t timeout); int embeddedice_handshake(struct arm_jtag *jtag_info, int hsbit, uint32_t timeout);
/* If many embeddedice_write_reg() follow eachother, then the >1 invocations can be this faster version of /* If many embeddedice_write_reg() follow eachother, then the >1 invocations can be
* embeddedice_write_reg * this faster version of embeddedice_write_reg
*/ */
static __inline__ void embeddedice_write_reg_inner(struct jtag_tap *tap, int reg_addr, uint32_t value) static inline void embeddedice_write_reg_inner(struct jtag_tap *tap, int reg_addr, uint32_t value)
{ {
static const int embeddedice_num_bits[] = {32, 6}; static const int embeddedice_num_bits[] = {32, 6};
uint32_t values[2]; uint32_t values[2];
@ -123,13 +118,10 @@ static __inline__ void embeddedice_write_reg_inner(struct jtag_tap *tap, int reg
values[0] = value; values[0] = value;
values[1] = (1 << 5) | reg_addr; values[1] = (1 << 5) | reg_addr;
jtag_add_dr_out(tap, jtag_add_dr_out(tap, 2, embeddedice_num_bits, values, TAP_IDLE);
2,
embeddedice_num_bits,
values,
TAP_IDLE);
} }
void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, const uint8_t *buffer, int little, int count); void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, const uint8_t *buffer,
int little, int count);
#endif /* EMBEDDED_ICE_H */ #endif /* EMBEDDED_ICE_H */

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -26,9 +27,7 @@
#include "etb.h" #include "etb.h"
#include "register.h" #include "register.h"
static char *etb_reg_list[] = {
static char* etb_reg_list[] =
{
"ETB_identification", "ETB_identification",
"ETB_ram_depth", "ETB_ram_depth",
"ETB_ram_width", "ETB_ram_width",
@ -50,12 +49,11 @@ static int etb_set_instr(struct etb *etb, uint32_t new_instr)
if (tap == NULL) if (tap == NULL)
return ERROR_FAIL; return ERROR_FAIL;
if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {
{
struct scan_field field; struct scan_field field;
field.num_bits = tap->ir_length; field.num_bits = tap->ir_length;
void * t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1); void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
field.out_value = t; field.out_value = t;
buf_set_u32(t, 0, field.num_bits, new_instr); buf_set_u32(t, 0, field.num_bits, new_instr);
@ -71,12 +69,11 @@ static int etb_set_instr(struct etb *etb, uint32_t new_instr)
static int etb_scann(struct etb *etb, uint32_t new_scan_chain) static int etb_scann(struct etb *etb, uint32_t new_scan_chain)
{ {
if (etb->cur_scan_chain != new_scan_chain) if (etb->cur_scan_chain != new_scan_chain) {
{
struct scan_field field; struct scan_field field;
field.num_bits = 5; field.num_bits = 5;
void * t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1); void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
field.out_value = t; field.out_value = t;
buf_set_u32(t, 0, field.num_bits, new_scan_chain); buf_set_u32(t, 0, field.num_bits, new_scan_chain);
@ -106,14 +103,14 @@ static int etb_get_reg(struct reg *reg)
{ {
int retval; int retval;
if ((retval = etb_read_reg(reg)) != ERROR_OK) retval = etb_read_reg(reg);
{ if (retval != ERROR_OK) {
LOG_ERROR("BUG: error scheduling ETB register read"); LOG_ERROR("BUG: error scheduling ETB register read");
return retval; return retval;
} }
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK) {
LOG_ERROR("ETB register read failed"); LOG_ERROR("ETB register read failed");
return retval; return retval;
} }
@ -126,7 +123,7 @@ static const struct reg_arch_type etb_reg_type = {
.set = etb_set_reg_w_exec, .set = etb_set_reg_w_exec,
}; };
struct reg_cache* etb_build_reg_cache(struct etb *etb) struct reg_cache *etb_build_reg_cache(struct etb *etb)
{ {
struct reg_cache *reg_cache = malloc(sizeof(struct reg_cache)); struct reg_cache *reg_cache = malloc(sizeof(struct reg_cache));
struct reg *reg_list = NULL; struct reg *reg_list = NULL;
@ -145,8 +142,7 @@ struct reg_cache* etb_build_reg_cache(struct etb *etb)
reg_cache->num_regs = num_regs; reg_cache->num_regs = num_regs;
/* set up registers */ /* set up registers */
for (i = 0; i < num_regs; i++) for (i = 0; i < num_regs; i++) {
{
reg_list[i].name = etb_reg_list[i]; reg_list[i].name = etb_reg_list[i];
reg_list[i].size = 32; reg_list[i].size = 32;
reg_list[i].dirty = 0; reg_list[i].dirty = 0;
@ -196,8 +192,7 @@ static int etb_read_ram(struct etb *etb, uint32_t *data, int num_frames)
jtag_add_dr_scan(etb->tap, 3, fields, TAP_IDLE); jtag_add_dr_scan(etb->tap, 3, fields, TAP_IDLE);
for (i = 0; i < num_frames; i++) for (i = 0; i < num_frames; i++) {
{
/* ensure nR/W reamins set to read */ /* ensure nR/W reamins set to read */
buf_set_u32(&temp2, 0, 1, 0); buf_set_u32(&temp2, 0, 1, 0);
@ -219,7 +214,7 @@ static int etb_read_ram(struct etb *etb, uint32_t *data, int num_frames)
} }
static int etb_read_reg_w_check(struct reg *reg, static int etb_read_reg_w_check(struct reg *reg,
uint8_t* check_value, uint8_t* check_mask) uint8_t *check_value, uint8_t *check_mask)
{ {
struct etb_reg *etb_reg = reg->arch_info; struct etb_reg *etb_reg = reg->arch_info;
uint8_t reg_addr = etb_reg->addr & 0x7f; uint8_t reg_addr = etb_reg->addr & 0x7f;
@ -273,8 +268,8 @@ static int etb_set_reg(struct reg *reg, uint32_t value)
{ {
int retval; int retval;
if ((retval = etb_write_reg(reg, value)) != ERROR_OK) retval = etb_write_reg(reg, value);
{ if (retval != ERROR_OK) {
LOG_ERROR("BUG: error scheduling ETB register write"); LOG_ERROR("BUG: error scheduling ETB register write");
return retval; return retval;
} }
@ -292,8 +287,8 @@ static int etb_set_reg_w_exec(struct reg *reg, uint8_t *buf)
etb_set_reg(reg, buf_get_u32(buf, 0, reg->size)); etb_set_reg(reg, buf_get_u32(buf, 0, reg->size));
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK) {
LOG_ERROR("ETB: register write failed"); LOG_ERROR("ETB: register write failed");
return retval; return retval;
} }
@ -341,34 +336,28 @@ COMMAND_HANDLER(handle_etb_config_command)
struct arm *arm; struct arm *arm;
if (CMD_ARGC != 2) if (CMD_ARGC != 2)
{
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
}
target = get_target(CMD_ARGV[0]); target = get_target(CMD_ARGV[0]);
if (!target) if (!target) {
{
LOG_ERROR("ETB: target '%s' not defined", CMD_ARGV[0]); LOG_ERROR("ETB: target '%s' not defined", CMD_ARGV[0]);
return ERROR_FAIL; return ERROR_FAIL;
} }
arm = target_to_arm(target); arm = target_to_arm(target);
if (!is_arm(arm)) if (!is_arm(arm)) {
{
command_print(CMD_CTX, "ETB: '%s' isn't an ARM", CMD_ARGV[0]); command_print(CMD_CTX, "ETB: '%s' isn't an ARM", CMD_ARGV[0]);
return ERROR_FAIL; return ERROR_FAIL;
} }
tap = jtag_tap_by_string(CMD_ARGV[1]); tap = jtag_tap_by_string(CMD_ARGV[1]);
if (tap == NULL) if (tap == NULL) {
{
command_print(CMD_CTX, "ETB: TAP %s does not exist", CMD_ARGV[1]); command_print(CMD_CTX, "ETB: TAP %s does not exist", CMD_ARGV[1]);
return ERROR_FAIL; return ERROR_FAIL;
} }
if (arm->etm) if (arm->etm) {
{
struct etb *etb = malloc(sizeof(struct etb)); struct etb *etb = malloc(sizeof(struct etb));
arm->etm->capture_driver_priv = etb; arm->etm->capture_driver_priv = etb;
@ -378,9 +367,7 @@ COMMAND_HANDLER(handle_etb_config_command)
etb->reg_cache = NULL; etb->reg_cache = NULL;
etb->ram_width = 0; etb->ram_width = 0;
etb->ram_depth = 0; etb->ram_depth = 0;
} } else {
else
{
LOG_ERROR("ETM: target has no ETM defined, ETB left unconfigured"); LOG_ERROR("ETM: target has no ETM defined, ETB left unconfigured");
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -397,8 +384,7 @@ COMMAND_HANDLER(handle_etb_trigger_percent_command)
target = get_current_target(CMD_CTX); target = get_current_target(CMD_CTX);
arm = target_to_arm(target); arm = target_to_arm(target);
if (!is_arm(arm)) if (!is_arm(arm)) {
{
command_print(CMD_CTX, "ETB: current target isn't an ARM"); command_print(CMD_CTX, "ETB: current target isn't an ARM");
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -426,7 +412,7 @@ COMMAND_HANDLER(handle_etb_trigger_percent_command)
} }
command_print(CMD_CTX, "%d percent of tracebuffer fills after trigger", command_print(CMD_CTX, "%d percent of tracebuffer fills after trigger",
etb->trigger_percent); etb->trigger_percent);
return ERROR_OK; return ERROR_OK;
} }
@ -550,13 +536,13 @@ static int etb_read_trace(struct etm_context *etm_ctx)
* i.e. don't read invalid entries * i.e. don't read invalid entries
*/ */
if (buf_get_u32(etb->reg_cache->reg_list[ETB_STATUS].value, 0, 1)) if (buf_get_u32(etb->reg_cache->reg_list[ETB_STATUS].value, 0, 1))
{ first_frame = buf_get_u32(etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER].value,
first_frame = buf_get_u32(etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER].value, 0, 32); 0,
} 32);
else else
{ num_frames = buf_get_u32(etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER].value,
num_frames = buf_get_u32(etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER].value, 0, 32); 0,
} 32);
etb_write_reg(&etb->reg_cache->reg_list[ETB_RAM_READ_POINTER], first_frame); etb_write_reg(&etb->reg_cache->reg_list[ETB_RAM_READ_POINTER], first_frame);
@ -565,9 +551,7 @@ static int etb_read_trace(struct etm_context *etm_ctx)
etb_read_ram(etb, trace_data, num_frames); etb_read_ram(etb, trace_data, num_frames);
if (etm_ctx->trace_depth > 0) if (etm_ctx->trace_depth > 0)
{
free(etm_ctx->trace_data); free(etm_ctx->trace_data);
}
if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_4BIT) if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_4BIT)
etm_ctx->trace_depth = num_frames * 3; etm_ctx->trace_depth = num_frames * 3;
@ -578,21 +562,17 @@ static int etb_read_trace(struct etm_context *etm_ctx)
etm_ctx->trace_data = malloc(sizeof(struct etmv1_trace_data) * etm_ctx->trace_depth); etm_ctx->trace_data = malloc(sizeof(struct etmv1_trace_data) * etm_ctx->trace_depth);
for (i = 0, j = 0; i < num_frames; i++) for (i = 0, j = 0; i < num_frames; i++) {
{ if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_4BIT) {
if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_4BIT)
{
/* trace word j */ /* trace word j */
etm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7; etm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7;
etm_ctx->trace_data[j].packet = (trace_data[i] & 0x78) >> 3; etm_ctx->trace_data[j].packet = (trace_data[i] & 0x78) >> 3;
etm_ctx->trace_data[j].flags = 0; etm_ctx->trace_data[j].flags = 0;
if ((trace_data[i] & 0x80) >> 7) if ((trace_data[i] & 0x80) >> 7)
{
etm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE; etm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE;
} if (etm_ctx->trace_data[j].pipestat == STAT_TR) {
if (etm_ctx->trace_data[j].pipestat == STAT_TR) etm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet &
{ 0x7;
etm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet & 0x7;
etm_ctx->trace_data[j].flags |= ETMV1_TRIGGER_CYCLE; etm_ctx->trace_data[j].flags |= ETMV1_TRIGGER_CYCLE;
} }
@ -601,12 +581,10 @@ static int etb_read_trace(struct etm_context *etm_ctx)
etm_ctx->trace_data[j + 1].packet = (trace_data[i] & 0x7800) >> 11; etm_ctx->trace_data[j + 1].packet = (trace_data[i] & 0x7800) >> 11;
etm_ctx->trace_data[j + 1].flags = 0; etm_ctx->trace_data[j + 1].flags = 0;
if ((trace_data[i] & 0x8000) >> 15) if ((trace_data[i] & 0x8000) >> 15)
{
etm_ctx->trace_data[j + 1].flags |= ETMV1_TRACESYNC_CYCLE; etm_ctx->trace_data[j + 1].flags |= ETMV1_TRACESYNC_CYCLE;
} if (etm_ctx->trace_data[j + 1].pipestat == STAT_TR) {
if (etm_ctx->trace_data[j + 1].pipestat == STAT_TR) etm_ctx->trace_data[j +
{ 1].pipestat = etm_ctx->trace_data[j + 1].packet & 0x7;
etm_ctx->trace_data[j + 1].pipestat = etm_ctx->trace_data[j + 1].packet & 0x7;
etm_ctx->trace_data[j + 1].flags |= ETMV1_TRIGGER_CYCLE; etm_ctx->trace_data[j + 1].flags |= ETMV1_TRIGGER_CYCLE;
} }
@ -615,30 +593,24 @@ static int etb_read_trace(struct etm_context *etm_ctx)
etm_ctx->trace_data[j + 2].packet = (trace_data[i] & 0x780000) >> 19; etm_ctx->trace_data[j + 2].packet = (trace_data[i] & 0x780000) >> 19;
etm_ctx->trace_data[j + 2].flags = 0; etm_ctx->trace_data[j + 2].flags = 0;
if ((trace_data[i] & 0x800000) >> 23) if ((trace_data[i] & 0x800000) >> 23)
{
etm_ctx->trace_data[j + 2].flags |= ETMV1_TRACESYNC_CYCLE; etm_ctx->trace_data[j + 2].flags |= ETMV1_TRACESYNC_CYCLE;
} if (etm_ctx->trace_data[j + 2].pipestat == STAT_TR) {
if (etm_ctx->trace_data[j + 2].pipestat == STAT_TR) etm_ctx->trace_data[j +
{ 2].pipestat = etm_ctx->trace_data[j + 2].packet & 0x7;
etm_ctx->trace_data[j + 2].pipestat = etm_ctx->trace_data[j + 2].packet & 0x7;
etm_ctx->trace_data[j + 2].flags |= ETMV1_TRIGGER_CYCLE; etm_ctx->trace_data[j + 2].flags |= ETMV1_TRIGGER_CYCLE;
} }
j += 3; j += 3;
} } else if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_8BIT) {
else if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_8BIT)
{
/* trace word j */ /* trace word j */
etm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7; etm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7;
etm_ctx->trace_data[j].packet = (trace_data[i] & 0x7f8) >> 3; etm_ctx->trace_data[j].packet = (trace_data[i] & 0x7f8) >> 3;
etm_ctx->trace_data[j].flags = 0; etm_ctx->trace_data[j].flags = 0;
if ((trace_data[i] & 0x800) >> 11) if ((trace_data[i] & 0x800) >> 11)
{
etm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE; etm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE;
} if (etm_ctx->trace_data[j].pipestat == STAT_TR) {
if (etm_ctx->trace_data[j].pipestat == STAT_TR) etm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet &
{ 0x7;
etm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet & 0x7;
etm_ctx->trace_data[j].flags |= ETMV1_TRIGGER_CYCLE; etm_ctx->trace_data[j].flags |= ETMV1_TRIGGER_CYCLE;
} }
@ -647,30 +619,24 @@ static int etb_read_trace(struct etm_context *etm_ctx)
etm_ctx->trace_data[j + 1].packet = (trace_data[i] & 0x7f8000) >> 15; etm_ctx->trace_data[j + 1].packet = (trace_data[i] & 0x7f8000) >> 15;
etm_ctx->trace_data[j + 1].flags = 0; etm_ctx->trace_data[j + 1].flags = 0;
if ((trace_data[i] & 0x800000) >> 23) if ((trace_data[i] & 0x800000) >> 23)
{
etm_ctx->trace_data[j + 1].flags |= ETMV1_TRACESYNC_CYCLE; etm_ctx->trace_data[j + 1].flags |= ETMV1_TRACESYNC_CYCLE;
} if (etm_ctx->trace_data[j + 1].pipestat == STAT_TR) {
if (etm_ctx->trace_data[j + 1].pipestat == STAT_TR) etm_ctx->trace_data[j +
{ 1].pipestat = etm_ctx->trace_data[j + 1].packet & 0x7;
etm_ctx->trace_data[j + 1].pipestat = etm_ctx->trace_data[j + 1].packet & 0x7;
etm_ctx->trace_data[j + 1].flags |= ETMV1_TRIGGER_CYCLE; etm_ctx->trace_data[j + 1].flags |= ETMV1_TRIGGER_CYCLE;
} }
j += 2; j += 2;
} } else {
else
{
/* trace word j */ /* trace word j */
etm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7; etm_ctx->trace_data[j].pipestat = trace_data[i] & 0x7;
etm_ctx->trace_data[j].packet = (trace_data[i] & 0x7fff8) >> 3; etm_ctx->trace_data[j].packet = (trace_data[i] & 0x7fff8) >> 3;
etm_ctx->trace_data[j].flags = 0; etm_ctx->trace_data[j].flags = 0;
if ((trace_data[i] & 0x80000) >> 19) if ((trace_data[i] & 0x80000) >> 19)
{
etm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE; etm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE;
} if (etm_ctx->trace_data[j].pipestat == STAT_TR) {
if (etm_ctx->trace_data[j].pipestat == STAT_TR) etm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet &
{ 0x7;
etm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet & 0x7;
etm_ctx->trace_data[j].flags |= ETMV1_TRIGGER_CYCLE; etm_ctx->trace_data[j].flags |= ETMV1_TRIGGER_CYCLE;
} }
@ -689,10 +655,8 @@ static int etb_start_capture(struct etm_context *etm_ctx)
uint32_t etb_ctrl_value = 0x1; uint32_t etb_ctrl_value = 0x1;
uint32_t trigger_count; uint32_t trigger_count;
if ((etm_ctx->control & ETM_PORT_MODE_MASK) == ETM_PORT_DEMUXED) if ((etm_ctx->control & ETM_PORT_MODE_MASK) == ETM_PORT_DEMUXED) {
{ if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) != ETM_PORT_8BIT) {
if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) != ETM_PORT_8BIT)
{
LOG_ERROR("ETB can't run in demultiplexed mode with a 4 or 16 bit port"); LOG_ERROR("ETB can't run in demultiplexed mode with a 4 or 16 bit port");
return ERROR_ETM_PORTMODE_NOT_SUPPORTED; return ERROR_ETM_PORTMODE_NOT_SUPPORTED;
} }
@ -731,8 +695,7 @@ static int etb_stop_capture(struct etm_context *etm_ctx)
return ERROR_OK; return ERROR_OK;
} }
struct etm_capture_driver etb_capture_driver = struct etm_capture_driver etb_capture_driver = {
{
.name = "etb", .name = "etb",
.commands = etb_command_handlers, .commands = etb_command_handlers,
.init = etb_init, .init = etb_init,

View File

@ -17,12 +17,12 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ETB_H #ifndef ETB_H
#define ETB_H #define ETB_H
/* ETB registers */ /* ETB registers */
enum enum {
{
ETB_ID = 0x00, ETB_ID = 0x00,
ETB_RAM_DEPTH = 0x01, ETB_RAM_DEPTH = 0x01,
ETB_RAM_WIDTH = 0x02, ETB_RAM_WIDTH = 0x02,
@ -34,8 +34,7 @@ enum
ETB_CTRL = 0x08, ETB_CTRL = 0x08,
}; };
struct etb struct etb {
{
struct etm_context *etm_ctx; struct etm_context *etm_ctx;
struct jtag_tap *tap; struct jtag_tap *tap;
uint32_t cur_scan_chain; uint32_t cur_scan_chain;
@ -49,14 +48,13 @@ struct etb
unsigned trigger_percent; unsigned trigger_percent;
}; };
struct etb_reg struct etb_reg {
{
uint32_t addr; uint32_t addr;
struct etb *etb; struct etb *etb;
}; };
extern struct etm_capture_driver etb_capture_driver; extern struct etm_capture_driver etb_capture_driver;
struct reg_cache* etb_build_reg_cache(struct etb *etb); struct reg_cache *etb_build_reg_cache(struct etb *etb);
#endif /* ETB_H */ #endif /* ETB_H */

File diff suppressed because it is too large Load Diff

View File

@ -20,6 +20,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ETM_H #ifndef ETM_H
#define ETM_H #define ETM_H
@ -29,8 +30,7 @@
struct image; struct image;
/* ETM registers (JTAG protocol) */ /* ETM registers (JTAG protocol) */
enum enum {
{
ETM_CTRL = 0x00, ETM_CTRL = 0x00,
ETM_CONFIG = 0x01, ETM_CONFIG = 0x01,
ETM_TRIG_EVENT = 0x02, ETM_TRIG_EVENT = 0x02,
@ -71,8 +71,7 @@ enum
ETM_ID = 0x79, ETM_ID = 0x79,
}; };
struct etm_reg struct etm_reg {
{
uint32_t value; uint32_t value;
const struct etm_reg_info *reg_info; const struct etm_reg_info *reg_info;
struct arm_jtag *jtag_info; struct arm_jtag *jtag_info;
@ -84,8 +83,7 @@ struct etm_reg
* *
* NOTE that these have evolved since the ~v1.3 defns ... * NOTE that these have evolved since the ~v1.3 defns ...
*/ */
enum enum {
{
ETM_CTRL_POWERDOWN = (1 << 0), ETM_CTRL_POWERDOWN = (1 << 0),
ETM_CTRL_MONITOR_CPRT = (1 << 1), ETM_CTRL_MONITOR_CPRT = (1 << 1),
@ -118,7 +116,7 @@ enum
ETM_PORT_HALF_CLOCK = (1 << 13), ETM_PORT_HALF_CLOCK = (1 << 13),
ETM_PORT_CLOCK_MASK = (1 << 13), ETM_PORT_CLOCK_MASK = (1 << 13),
// bits 15:14 == context ID size used in tracing /* bits 15:14 == context ID size used in tracing */
ETM_CTRL_CONTEXTID_NONE = (0 << 14), ETM_CTRL_CONTEXTID_NONE = (0 << 14),
ETM_CTRL_CONTEXTID_8 = (1 << 14), ETM_CTRL_CONTEXTID_8 = (1 << 14),
ETM_CTRL_CONTEXTID_16 = (2 << 14), ETM_CTRL_CONTEXTID_16 = (2 << 14),
@ -131,14 +129,13 @@ enum
ETM_PORT_DEMUXED = (2 << 16), ETM_PORT_DEMUXED = (2 << 16),
ETM_PORT_MODE_MASK = (3 << 16), ETM_PORT_MODE_MASK = (3 << 16),
// bits 31:18 defined in v3.0 and later (e.g. ARM11+) /* bits 31:18 defined in v3.0 and later (e.g. ARM11+) */
}; };
/* forward-declare ETM context */ /* forward-declare ETM context */
struct etm_context; struct etm_context;
struct etm_capture_driver struct etm_capture_driver {
{
const char *name; const char *name;
const struct command_registration *commands; const struct command_registration *commands;
int (*init)(struct etm_context *etm_ctx); int (*init)(struct etm_context *etm_ctx);
@ -148,14 +145,12 @@ struct etm_capture_driver
int (*stop_capture)(struct etm_context *etm_ctx); int (*stop_capture)(struct etm_context *etm_ctx);
}; };
enum enum {
{
ETMV1_TRACESYNC_CYCLE = 0x1, ETMV1_TRACESYNC_CYCLE = 0x1,
ETMV1_TRIGGER_CYCLE = 0x2, ETMV1_TRIGGER_CYCLE = 0x2,
}; };
struct etmv1_trace_data struct etmv1_trace_data {
{
uint8_t pipestat; /* bits 0-2 pipeline status */ uint8_t pipestat; /* bits 0-2 pipeline status */
uint16_t packet; /* packet data (4, 8 or 16 bit) */ uint16_t packet; /* packet data (4, 8 or 16 bit) */
int flags; /* ETMV1_TRACESYNC_CYCLE, ETMV1_TRIGGER_CYCLE */ int flags; /* ETMV1_TRACESYNC_CYCLE, ETMV1_TRIGGER_CYCLE */
@ -166,8 +161,7 @@ struct etmv1_trace_data
* this will have to be split into version independent elements * this will have to be split into version independent elements
* and a version specific part * and a version specific part
*/ */
struct etm_context struct etm_context {
{
struct target *target; /* target this ETM is connected to */ struct target *target; /* target this ETM is connected to */
struct reg_cache *reg_cache; /* ETM register cache */ struct reg_cache *reg_cache; /* ETM register cache */
struct etm_capture_driver *capture_driver; /* driver used to access ETM data */ struct etm_capture_driver *capture_driver; /* driver used to access ETM data */
@ -194,8 +188,7 @@ struct etm_context
}; };
/* PIPESTAT values */ /* PIPESTAT values */
typedef enum typedef enum {
{
STAT_IE = 0x0, STAT_IE = 0x0,
STAT_ID = 0x1, STAT_ID = 0x1,
STAT_IN = 0x2, STAT_IN = 0x2,
@ -207,8 +200,7 @@ typedef enum
} etmv1_pipestat_t; } etmv1_pipestat_t;
/* branch reason values */ /* branch reason values */
typedef enum typedef enum {
{
BR_NORMAL = 0x0, /* Normal PC change : periodic synchro (ETMv1.1) */ BR_NORMAL = 0x0, /* Normal PC change : periodic synchro (ETMv1.1) */
BR_ENABLE = 0x1, /* Trace has been enabled */ BR_ENABLE = 0x1, /* Trace has been enabled */
BR_RESTART = 0x2, /* Trace restarted after a FIFO overflow */ BR_RESTART = 0x2, /* Trace restarted after a FIFO overflow */
@ -219,7 +211,7 @@ typedef enum
BR_RSVD7 = 0x7, /* reserved */ BR_RSVD7 = 0x7, /* reserved */
} etmv1_branch_reason_t; } etmv1_branch_reason_t;
struct reg_cache* etm_build_reg_cache(struct target *target, struct reg_cache *etm_build_reg_cache(struct target *target,
struct arm_jtag *jtag_info, struct etm_context *etm_ctx); struct arm_jtag *jtag_info, struct etm_context *etm_ctx);
int etm_setup(struct target *target); int etm_setup(struct target *target);

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -24,7 +25,6 @@
#include "arm.h" #include "arm.h"
#include "etm_dummy.h" #include "etm_dummy.h"
COMMAND_HANDLER(handle_etm_dummy_config_command) COMMAND_HANDLER(handle_etm_dummy_config_command)
{ {
struct target *target; struct target *target;
@ -32,25 +32,20 @@ COMMAND_HANDLER(handle_etm_dummy_config_command)
target = get_target(CMD_ARGV[0]); target = get_target(CMD_ARGV[0]);
if (!target) if (!target) {
{
LOG_ERROR("target '%s' not defined", CMD_ARGV[0]); LOG_ERROR("target '%s' not defined", CMD_ARGV[0]);
return ERROR_FAIL; return ERROR_FAIL;
} }
arm = target_to_arm(target); arm = target_to_arm(target);
if (!is_arm(arm)) if (!is_arm(arm)) {
{
command_print(CMD_CTX, "target '%s' isn't an ARM", CMD_ARGV[0]); command_print(CMD_CTX, "target '%s' isn't an ARM", CMD_ARGV[0]);
return ERROR_FAIL; return ERROR_FAIL;
} }
if (arm->etm) if (arm->etm)
{
arm->etm->capture_driver_priv = NULL; arm->etm->capture_driver_priv = NULL;
} else {
else
{
LOG_ERROR("target has no ETM defined, ETM dummy left unconfigured"); LOG_ERROR("target has no ETM defined, ETM dummy left unconfigured");
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -102,8 +97,7 @@ static int etm_dummy_stop_capture(struct etm_context *etm_ctx)
return ERROR_OK; return ERROR_OK;
} }
struct etm_capture_driver etm_dummy_capture_driver = struct etm_capture_driver etm_dummy_capture_driver = {
{
.name = "dummy", .name = "dummy",
.commands = etm_dummy_command_handlers, .commands = etm_dummy_command_handlers,
.init = etm_dummy_init, .init = etm_dummy_init,

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef ETM_DUMMY_H #ifndef ETM_DUMMY_H
#define ETM_DUMMY_H #define ETM_DUMMY_H

View File

@ -41,7 +41,7 @@ static void fa526_change_to_arm(struct target *target, uint32_t *r0, uint32_t *p
} }
static void fa526_read_core_regs(struct target *target, static void fa526_read_core_regs(struct target *target,
uint32_t mask, uint32_t* core_regs[16]) uint32_t mask, uint32_t *core_regs[16])
{ {
int i; int i;
struct arm7_9_common *arm7_9 = target_to_arm7_9(target); struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
@ -59,8 +59,7 @@ static void fa526_read_core_regs(struct target *target,
/* fetch NOP, STM in EXECUTE stage (1st cycle) */ /* fetch NOP, STM in EXECUTE stage (1st cycle) */
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
for (i = 0; i <= 15; i++) for (i = 0; i <= 15; i++) {
{
if (mask & (1 << i)) if (mask & (1 << i))
/* nothing fetched, STM in MEMORY (i'th cycle) */ /* nothing fetched, STM in MEMORY (i'th cycle) */
arm9tdmi_clock_data_in(jtag_info, core_regs[i]); arm9tdmi_clock_data_in(jtag_info, core_regs[i]);
@ -68,7 +67,7 @@ static void fa526_read_core_regs(struct target *target,
} }
static void fa526_read_core_regs_target_buffer(struct target *target, static void fa526_read_core_regs_target_buffer(struct target *target,
uint32_t mask, void* buffer, int size) uint32_t mask, void *buffer, int size)
{ {
int i; int i;
struct arm7_9_common *arm7_9 = target_to_arm7_9(target); struct arm7_9_common *arm7_9 = target_to_arm7_9(target);
@ -90,12 +89,10 @@ static void fa526_read_core_regs_target_buffer(struct target *target,
/* fetch NOP, STM in EXECUTE stage (1st cycle) */ /* fetch NOP, STM in EXECUTE stage (1st cycle) */
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
for (i = 0; i <= 15; i++) for (i = 0; i <= 15; i++) {
{
if (mask & (1 << i)) if (mask & (1 << i))
/* nothing fetched, STM in MEMORY (i'th cycle) */ /* nothing fetched, STM in MEMORY (i'th cycle) */
switch (size) switch (size) {
{
case 4: case 4:
arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be); arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
break; break;
@ -188,8 +185,7 @@ static void fa526_write_xpsr_im8(struct target *target,
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
/* rot == 4 writes flags, which takes only one cycle */ /* rot == 4 writes flags, which takes only one cycle */
if (rot != 4) if (rot != 4) {
{
/* nothing fetched, MSR in EXECUTE (2) */ /* nothing fetched, MSR in EXECUTE (2) */
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
/* nothing fetched, MSR in EXECUTE (3) */ /* nothing fetched, MSR in EXECUTE (3) */
@ -216,8 +212,7 @@ static void fa526_write_core_regs(struct target *target,
/* fetch NOP, LDM in EXECUTE stage (1st cycle) */ /* fetch NOP, LDM in EXECUTE stage (1st cycle) */
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
for (i = 0; i <= 15; i++) for (i = 0; i <= 15; i++) {
{
if (mask & (1 << i)) if (mask & (1 << i))
/* nothing fetched, LDM still in EXECUTE (1 + i cycle) */ /* nothing fetched, LDM still in EXECUTE (1 + i cycle) */
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, core_regs[i], NULL, 0);
@ -346,14 +341,13 @@ static int fa526_init_arch_info(struct target *target,
static int fa526_target_create(struct target *target, Jim_Interp *interp) static int fa526_target_create(struct target *target, Jim_Interp *interp)
{ {
struct arm920t_common *arm920t = calloc(1,sizeof(struct arm920t_common)); struct arm920t_common *arm920t = calloc(1, sizeof(struct arm920t_common));
return fa526_init_arch_info(target, arm920t, target->tap); return fa526_init_arch_info(target, arm920t, target->tap);
} }
/** Holds methods for FA526 targets. */ /** Holds methods for FA526 targets. */
struct target_type fa526_target = struct target_type fa526_target = {
{
.name = "fa526", .name = "fa526",
.poll = arm7_9_poll, .poll = arm7_9_poll,

View File

@ -58,7 +58,6 @@
#include "register.h" #include "register.h"
#include "arm_opcodes.h" #include "arm_opcodes.h"
static int feroceon_assert_reset(struct target *target) static int feroceon_assert_reset(struct target *target)
{ {
struct arm *arm = target->arch_info; struct arm *arm = target->arch_info;
@ -160,7 +159,7 @@ static void feroceon_change_to_arm(struct target *target, uint32_t *r0,
} }
static void feroceon_read_core_regs(struct target *target, static void feroceon_read_core_regs(struct target *target,
uint32_t mask, uint32_t* core_regs[16]) uint32_t mask, uint32_t *core_regs[16])
{ {
int i; int i;
struct arm *arm = target->arch_info; struct arm *arm = target->arch_info;
@ -180,7 +179,7 @@ static void feroceon_read_core_regs(struct target *target,
} }
static void feroceon_read_core_regs_target_buffer(struct target *target, static void feroceon_read_core_regs_target_buffer(struct target *target,
uint32_t mask, void* buffer, int size) uint32_t mask, void *buffer, int size)
{ {
int i; int i;
struct arm *arm = target->arch_info; struct arm *arm = target->arch_info;
@ -195,11 +194,9 @@ static void feroceon_read_core_regs_target_buffer(struct target *target,
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
for (i = 0; i <= 15; i++) for (i = 0; i <= 15; i++) {
{
if (mask & (1 << i)) { if (mask & (1 << i)) {
switch (size) switch (size) {
{
case 4: case 4:
arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be); arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be);
break; break;
@ -350,7 +347,7 @@ static void feroceon_branch_resume_thumb(struct target *target)
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
arm9tdmi_clock_out(jtag_info, 0xE28F0001, 0, NULL, 0); // add r0,pc,#1 arm9tdmi_clock_out(jtag_info, 0xE28F0001, 0, NULL, 0); /* add r0,pc,#1 */
arm9tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_BX(0), 0, NULL, 0);
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0);
@ -452,9 +449,7 @@ static int feroceon_examine_debug_reason(struct target *target)
{ {
/* the MOE is not implemented */ /* the MOE is not implemented */
if (target->debug_reason != DBG_REASON_SINGLESTEP) if (target->debug_reason != DBG_REASON_SINGLESTEP)
{
target->debug_reason = DBG_REASON_DBGRQ; target->debug_reason = DBG_REASON_DBGRQ;
}
return ERROR_OK; return ERROR_OK;
} }
@ -473,8 +468,7 @@ static int feroceon_bulk_write_memory(struct target *target,
* We can't use the dcc flow control bits, so let's transfer data * We can't use the dcc flow control bits, so let's transfer data
* with 31 bits and flip the MSB each time a new data word is sent. * with 31 bits and flip the MSB each time a new data word is sent.
*/ */
static uint32_t dcc_code[] = static uint32_t dcc_code[] = {
{
0xee115e10, /* 3: mrc p14, 0, r5, c1, c0, 0 */ 0xee115e10, /* 3: mrc p14, 0, r5, c1, c0, 0 */
0xe3a0301e, /* 1: mov r3, #30 */ 0xe3a0301e, /* 1: mov r3, #30 */
0xe3a04002, /* mov r4, #2 */ 0xe3a04002, /* mov r4, #2 */
@ -503,13 +497,11 @@ static int feroceon_bulk_write_memory(struct target *target,
return target_write_memory(target, address, 4, count, buffer); return target_write_memory(target, address, 4, count, buffer);
/* regrab previously allocated working_area, or allocate a new one */ /* regrab previously allocated working_area, or allocate a new one */
if (!arm7_9->dcc_working_area) if (!arm7_9->dcc_working_area) {
{
uint8_t dcc_code_buf[dcc_size]; uint8_t dcc_code_buf[dcc_size];
/* make sure we have a working area */ /* make sure we have a working area */
if (target_alloc_working_area(target, dcc_size, &arm7_9->dcc_working_area) != ERROR_OK) if (target_alloc_working_area(target, dcc_size, &arm7_9->dcc_working_area) != ERROR_OK) {
{
LOG_INFO("no working area available, falling back to memory writes"); LOG_INFO("no working area available, falling back to memory writes");
return target_write_memory(target, address, 4, count, buffer); return target_write_memory(target, address, 4, count, buffer);
} }
@ -519,10 +511,10 @@ static int feroceon_bulk_write_memory(struct target *target,
target_buffer_set_u32(target, dcc_code_buf + i*4, dcc_code[i]); target_buffer_set_u32(target, dcc_code_buf + i*4, dcc_code[i]);
/* write DCC code to working area */ /* write DCC code to working area */
if ((retval = target_write_memory(target, arm7_9->dcc_working_area->address, 4, dcc_size/4, dcc_code_buf)) != ERROR_OK) retval = target_write_memory(target,
{ arm7_9->dcc_working_area->address, 4, dcc_size/4, dcc_code_buf);
if (retval != ERROR_OK)
return retval; return retval;
}
} }
/* backup clobbered processor state */ /* backup clobbered processor state */
@ -543,14 +535,12 @@ static int feroceon_bulk_write_memory(struct target *target,
x = 0; x = 0;
flip = 0; flip = 0;
shift = 1; shift = 1;
for (i = 0; i < count; i++) for (i = 0; i < count; i++) {
{
uint32_t y = target_buffer_get_u32(target, buffer); uint32_t y = target_buffer_get_u32(target, buffer);
uint32_t z = (x >> 1) | (y >> shift) | (flip ^= 0x80000000); uint32_t z = (x >> 1) | (y >> shift) | (flip ^= 0x80000000);
embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], z); embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], z);
x = y << (32 - shift); x = y << (32 - shift);
if (++shift >= 32 || i + 1 >= count) if (++shift >= 32 || i + 1 >= count) {
{
z = (x >> 1) | (flip ^= 0x80000000); z = (x >> 1) | (flip ^= 0x80000000);
embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], z); embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], z);
x = 0; x = 0;
@ -563,20 +553,19 @@ static int feroceon_bulk_write_memory(struct target *target,
if (retval == ERROR_OK) if (retval == ERROR_OK)
retval = target_wait_state(target, TARGET_HALTED, 500); retval = target_wait_state(target, TARGET_HALTED, 500);
if (retval == ERROR_OK) { if (retval == ERROR_OK) {
uint32_t endaddress = uint32_t endaddress =
buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32); buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32);
if (endaddress != address + count*4) { if (endaddress != address + count*4) {
LOG_ERROR("DCC write failed," LOG_ERROR("DCC write failed,"
" expected end address 0x%08" PRIx32 " expected end address 0x%08" PRIx32
" got 0x%0" PRIx32 "", " got 0x%0" PRIx32 "",
address + count*4, endaddress); address + count*4, endaddress);
retval = ERROR_FAIL; retval = ERROR_FAIL;
} }
} }
/* restore target state */ /* restore target state */
for (i = 0; i <= 5; i++) for (i = 0; i <= 5; i++) {
{
buf_set_u32(arm->core_cache->reg_list[i].value, 0, 32, save[i]); buf_set_u32(arm->core_cache->reg_list[i].value, 0, 32, save[i]);
arm->core_cache->reg_list[i].valid = 1; arm->core_cache->reg_list[i].valid = 1;
arm->core_cache->reg_list[i].dirty = 1; arm->core_cache->reg_list[i].dirty = 1;
@ -631,7 +620,7 @@ static void feroceon_common_setup(struct target *target)
static int feroceon_target_create(struct target *target, Jim_Interp *interp) static int feroceon_target_create(struct target *target, Jim_Interp *interp)
{ {
struct arm926ejs_common *arm926ejs = calloc(1,sizeof(struct arm926ejs_common)); struct arm926ejs_common *arm926ejs = calloc(1, sizeof(struct arm926ejs_common));
arm926ejs_init_arch_info(target, arm926ejs, target->tap); arm926ejs_init_arch_info(target, arm926ejs, target->tap);
feroceon_common_setup(target); feroceon_common_setup(target);
@ -645,7 +634,7 @@ static int feroceon_target_create(struct target *target, Jim_Interp *interp)
static int dragonite_target_create(struct target *target, Jim_Interp *interp) static int dragonite_target_create(struct target *target, Jim_Interp *interp)
{ {
struct arm966e_common *arm966e = calloc(1,sizeof(struct arm966e_common)); struct arm966e_common *arm966e = calloc(1, sizeof(struct arm966e_common));
arm966e_init_arch_info(target, arm966e, target->tap); arm966e_init_arch_info(target, arm966e, target->tap);
feroceon_common_setup(target); feroceon_common_setup(target);
@ -687,8 +676,7 @@ static int feroceon_examine(struct target *target)
return ERROR_OK; return ERROR_OK;
} }
struct target_type feroceon_target = struct target_type feroceon_target = {
{
.name = "feroceon", .name = "feroceon",
.poll = arm7_9_poll, .poll = arm7_9_poll,
@ -726,8 +714,7 @@ struct target_type feroceon_target =
.examine = feroceon_examine, .examine = feroceon_examine,
}; };
struct target_type dragonite_target = struct target_type dragonite_target = {
{
.name = "dragonite", .name = "dragonite",
.poll = arm7_9_poll, .poll = arm7_9_poll,
@ -764,4 +751,3 @@ struct target_type dragonite_target =
.init_target = feroceon_init_target, .init_target = feroceon_init_target,
.examine = feroceon_examine, .examine = feroceon_examine,
}; };

File diff suppressed because it is too large Load Diff

View File

@ -23,6 +23,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef IMAGE_H #ifndef IMAGE_H
#define IMAGE_H #define IMAGE_H
@ -37,8 +38,7 @@
#define IMAGE_MEMORY_CACHE_SIZE (2048) #define IMAGE_MEMORY_CACHE_SIZE (2048)
enum image_type enum image_type {
{
IMAGE_BINARY, /* plain binary */ IMAGE_BINARY, /* plain binary */
IMAGE_IHEX, /* intel hex-record format */ IMAGE_IHEX, /* intel hex-record format */
IMAGE_MEMORY, /* target-memory pseudo-image */ IMAGE_MEMORY, /* target-memory pseudo-image */
@ -47,16 +47,14 @@ enum image_type
IMAGE_BUILDER, /* when building a new image */ IMAGE_BUILDER, /* when building a new image */
}; };
struct imagesection struct imagesection {
{
uint32_t base_address; uint32_t base_address;
uint32_t size; uint32_t size;
int flags; int flags;
void *private; /* private data */ void *private; /* private data */
}; };
struct image struct image {
{
enum image_type type; /* image type (plain, ihex, ...) */ enum image_type type; /* image type (plain, ihex, ...) */
void *type_private; /* type private data */ void *type_private; /* type private data */
int num_sections; /* number of sections contained in the image */ int num_sections; /* number of sections contained in the image */
@ -67,26 +65,22 @@ struct image
uint32_t start_address; /* start address, if one is set */ uint32_t start_address; /* start address, if one is set */
}; };
struct image_binary struct image_binary {
{
struct fileio fileio; struct fileio fileio;
}; };
struct image_ihex struct image_ihex {
{
struct fileio fileio; struct fileio fileio;
uint8_t *buffer; uint8_t *buffer;
}; };
struct image_memory struct image_memory {
{
struct target *target; struct target *target;
uint8_t *cache; uint8_t *cache;
uint32_t cache_address; uint32_t cache_address;
}; };
struct image_elf struct image_elf {
{
struct fileio fileio; struct fileio fileio;
Elf32_Ehdr *header; Elf32_Ehdr *header;
Elf32_Phdr *segments; Elf32_Phdr *segments;
@ -94,8 +88,7 @@ struct image_elf
uint8_t endianness; uint8_t endianness;
}; };
struct image_mot struct image_mot {
{
struct fileio fileio; struct fileio fileio;
uint8_t *buffer; uint8_t *buffer;
}; };
@ -108,8 +101,8 @@ void image_close(struct image *image);
int image_add_section(struct image *image, uint32_t base, uint32_t size, int image_add_section(struct image *image, uint32_t base, uint32_t size,
int flags, uint8_t *data); int flags, uint8_t *data);
int image_calculate_checksum(uint8_t* buffer, uint32_t nbytes, int image_calculate_checksum(uint8_t *buffer, uint32_t nbytes,
uint32_t* checksum); uint32_t *checksum);
#define ERROR_IMAGE_FORMAT_ERROR (-1400) #define ERROR_IMAGE_FORMAT_ERROR (-1400)
#define ERROR_IMAGE_TYPE_UNKNOWN (-1401) #define ERROR_IMAGE_TYPE_UNKNOWN (-1401)

View File

@ -25,6 +25,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -34,8 +35,7 @@
#include "algorithm.h" #include "algorithm.h"
#include "register.h" #include "register.h"
static char* mips32_core_reg_list[] = static char *mips32_core_reg_list[] = {
{
"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", "zero", "at", "v0", "v1", "a0", "a1", "a2", "a3",
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", "t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7",
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", "s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7",
@ -43,13 +43,11 @@ static char* mips32_core_reg_list[] =
"status", "lo", "hi", "badvaddr", "cause", "pc" "status", "lo", "hi", "badvaddr", "cause", "pc"
}; };
static const char *mips_isa_strings[] = static const char *mips_isa_strings[] = {
{
"MIPS32", "MIPS16e" "MIPS32", "MIPS16e"
}; };
static struct mips32_core_reg mips32_core_reg_list_arch_info[MIPS32NUMCOREREGS] = static struct mips32_core_reg mips32_core_reg_list_arch_info[MIPS32NUMCOREREGS] = {
{
{0, NULL, NULL}, {0, NULL, NULL},
{1, NULL, NULL}, {1, NULL, NULL},
{2, NULL, NULL}, {2, NULL, NULL},
@ -94,12 +92,11 @@ static struct mips32_core_reg mips32_core_reg_list_arch_info[MIPS32NUMCOREREGS]
/* number of mips dummy fp regs fp0 - fp31 + fsr and fir /* number of mips dummy fp regs fp0 - fp31 + fsr and fir
* we also add 18 unknown registers to handle gdb requests */ * we also add 18 unknown registers to handle gdb requests */
#define MIPS32NUMFPREGS 34 + 18 #define MIPS32NUMFPREGS (34 + 18)
static uint8_t mips32_gdb_dummy_fp_value[] = {0, 0, 0, 0}; static uint8_t mips32_gdb_dummy_fp_value[] = {0, 0, 0, 0};
static struct reg mips32_gdb_dummy_fp_reg = static struct reg mips32_gdb_dummy_fp_reg = {
{
.name = "GDB dummy floating-point register", .name = "GDB dummy floating-point register",
.value = mips32_gdb_dummy_fp_value, .value = mips32_gdb_dummy_fp_value,
.dirty = 0, .dirty = 0,
@ -116,9 +113,7 @@ static int mips32_get_core_reg(struct reg *reg)
struct mips32_common *mips32_target = target_to_mips32(target); struct mips32_common *mips32_target = target_to_mips32(target);
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED)
{
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
}
retval = mips32_target->read_core_reg(target, mips32_reg->num); retval = mips32_target->read_core_reg(target, mips32_reg->num);
@ -132,9 +127,7 @@ static int mips32_set_core_reg(struct reg *reg, uint8_t *buf)
uint32_t value = buf_get_u32(buf, 0, 32); uint32_t value = buf_get_u32(buf, 0, 32);
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED)
{
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
}
buf_set_u32(reg->value, 0, 32, value); buf_set_u32(reg->value, 0, 32, value);
reg->dirty = 1; reg->dirty = 1;
@ -188,18 +181,14 @@ int mips32_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int
/* include floating point registers */ /* include floating point registers */
*reg_list_size = MIPS32NUMCOREREGS + MIPS32NUMFPREGS; *reg_list_size = MIPS32NUMCOREREGS + MIPS32NUMFPREGS;
*reg_list = malloc(sizeof(struct reg*) * (*reg_list_size)); *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
for (i = 0; i < MIPS32NUMCOREREGS; i++) for (i = 0; i < MIPS32NUMCOREREGS; i++)
{
(*reg_list)[i] = &mips32->core_cache->reg_list[i]; (*reg_list)[i] = &mips32->core_cache->reg_list[i];
}
/* add dummy floating points regs */ /* add dummy floating points regs */
for (i = MIPS32NUMCOREREGS; i < (MIPS32NUMCOREREGS + MIPS32NUMFPREGS); i++) for (i = MIPS32NUMCOREREGS; i < (MIPS32NUMCOREREGS + MIPS32NUMFPREGS); i++)
{
(*reg_list)[i] = &mips32_gdb_dummy_fp_reg; (*reg_list)[i] = &mips32_gdb_dummy_fp_reg;
}
return ERROR_OK; return ERROR_OK;
} }
@ -215,12 +204,9 @@ int mips32_save_context(struct target *target)
/* read core registers */ /* read core registers */
mips32_pracc_read_regs(ejtag_info, mips32->core_regs); mips32_pracc_read_regs(ejtag_info, mips32->core_regs);
for (i = 0; i < MIPS32NUMCOREREGS; i++) for (i = 0; i < MIPS32NUMCOREREGS; i++) {
{
if (!mips32->core_cache->reg_list[i].valid) if (!mips32->core_cache->reg_list[i].valid)
{
mips32->read_core_reg(target, i); mips32->read_core_reg(target, i);
}
} }
return ERROR_OK; return ERROR_OK;
@ -234,12 +220,9 @@ int mips32_restore_context(struct target *target)
struct mips32_common *mips32 = target_to_mips32(target); struct mips32_common *mips32 = target_to_mips32(target);
struct mips_ejtag *ejtag_info = &mips32->ejtag_info; struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
for (i = 0; i < MIPS32NUMCOREREGS; i++) for (i = 0; i < MIPS32NUMCOREREGS; i++) {
{
if (mips32->core_cache->reg_list[i].dirty) if (mips32->core_cache->reg_list[i].dirty)
{
mips32->write_core_reg(target, i); mips32->write_core_reg(target, i);
}
} }
/* write core regs */ /* write core regs */
@ -287,8 +270,7 @@ struct reg_cache *mips32_build_reg_cache(struct target *target)
(*cache_p) = cache; (*cache_p) = cache;
mips32->core_cache = cache; mips32->core_cache = cache;
for (i = 0; i < num_regs; i++) for (i = 0; i < num_regs; i++) {
{
arch_info[i] = mips32_core_reg_list_arch_info[i]; arch_info[i] = mips32_core_reg_list_arch_info[i];
arch_info[i].target = target; arch_info[i].target = target;
arch_info[i].mips32_common = mips32; arch_info[i].mips32_common = mips32;
@ -329,27 +311,24 @@ static int mips32_run_and_wait(struct target *target, uint32_t entry_point,
int retval; int retval;
/* This code relies on the target specific resume() and poll()->debug_entry() /* This code relies on the target specific resume() and poll()->debug_entry()
* sequence to write register values to the processor and the read them back */ * sequence to write register values to the processor and the read them back */
if ((retval = target_resume(target, 0, entry_point, 0, 1)) != ERROR_OK) retval = target_resume(target, 0, entry_point, 0, 1);
{ if (retval != ERROR_OK)
return retval; return retval;
}
retval = target_wait_state(target, TARGET_HALTED, timeout_ms); retval = target_wait_state(target, TARGET_HALTED, timeout_ms);
/* If the target fails to halt due to the breakpoint, force a halt */ /* If the target fails to halt due to the breakpoint, force a halt */
if (retval != ERROR_OK || target->state != TARGET_HALTED) if (retval != ERROR_OK || target->state != TARGET_HALTED) {
{ retval = target_halt(target);
if ((retval = target_halt(target)) != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if ((retval = target_wait_state(target, TARGET_HALTED, 500)) != ERROR_OK) retval = target_wait_state(target, TARGET_HALTED, 500);
{ if (retval != ERROR_OK)
return retval; return retval;
}
return ERROR_TARGET_TIMEOUT; return ERROR_TARGET_TIMEOUT;
} }
pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32); pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
if (exit_point && (pc != exit_point)) if (exit_point && (pc != exit_point)) {
{
LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc); LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 " ", pc);
return ERROR_TARGET_TIMEOUT; return ERROR_TARGET_TIMEOUT;
} }
@ -375,47 +354,39 @@ int mips32_run_algorithm(struct target *target, int num_mem_params,
/* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint /* NOTE: mips32_run_algorithm requires that each algorithm uses a software breakpoint
* at the exit point */ * at the exit point */
if (mips32->common_magic != MIPS32_COMMON_MAGIC) if (mips32->common_magic != MIPS32_COMMON_MAGIC) {
{
LOG_ERROR("current target isn't a MIPS32 target"); LOG_ERROR("current target isn't a MIPS32 target");
return ERROR_TARGET_INVALID; return ERROR_TARGET_INVALID;
} }
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
LOG_WARNING("target not halted"); LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
} }
/* refresh core register cache */ /* refresh core register cache */
for (i = 0; i < MIPS32NUMCOREREGS; i++) for (i = 0; i < MIPS32NUMCOREREGS; i++) {
{
if (!mips32->core_cache->reg_list[i].valid) if (!mips32->core_cache->reg_list[i].valid)
mips32->read_core_reg(target, i); mips32->read_core_reg(target, i);
context[i] = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32); context[i] = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);
} }
for (i = 0; i < num_mem_params; i++) for (i = 0; i < num_mem_params; i++) {
{ retval = target_write_buffer(target, mem_params[i].address,
if ((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value);
mem_params[i].size, mem_params[i].value)) != ERROR_OK) if (retval != ERROR_OK)
{
return retval; return retval;
}
} }
for (i = 0; i < num_reg_params; i++) for (i = 0; i < num_reg_params; i++) {
{
struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0); struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0);
if (!reg) if (!reg) {
{
LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
if (reg->size != reg_params[i].size) if (reg->size != reg_params[i].size) {
{
LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
reg_params[i].reg_name); reg_params[i].reg_name);
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
@ -431,31 +402,24 @@ int mips32_run_algorithm(struct target *target, int num_mem_params,
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
for (i = 0; i < num_mem_params; i++) for (i = 0; i < num_mem_params; i++) {
{ if (mem_params[i].direction != PARAM_OUT) {
if (mem_params[i].direction != PARAM_OUT) retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size,
{ mem_params[i].value);
if ((retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size, if (retval != ERROR_OK)
mem_params[i].value)) != ERROR_OK)
{
return retval; return retval;
}
} }
} }
for (i = 0; i < num_reg_params; i++) for (i = 0; i < num_reg_params; i++) {
{ if (reg_params[i].direction != PARAM_OUT) {
if (reg_params[i].direction != PARAM_OUT)
{
struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0); struct reg *reg = register_get_by_name(mips32->core_cache, reg_params[i].reg_name, 0);
if (!reg) if (!reg) {
{
LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
} }
if (reg->size != reg_params[i].size) if (reg->size != reg_params[i].size) {
{
LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size",
reg_params[i].reg_name); reg_params[i].reg_name);
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
@ -466,12 +430,10 @@ int mips32_run_algorithm(struct target *target, int num_mem_params,
} }
/* restore everything we saved before */ /* restore everything we saved before */
for (i = 0; i < MIPS32NUMCOREREGS; i++) for (i = 0; i < MIPS32NUMCOREREGS; i++) {
{
uint32_t regvalue; uint32_t regvalue;
regvalue = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32); regvalue = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32);
if (regvalue != context[i]) if (regvalue != context[i]) {
{
LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32, LOG_DEBUG("restoring register %s with value 0x%8.8" PRIx32,
mips32->core_cache->reg_list[i].name, context[i]); mips32->core_cache->reg_list[i].name, context[i]);
buf_set_u32(mips32->core_cache->reg_list[i].value, buf_set_u32(mips32->core_cache->reg_list[i].value,
@ -490,8 +452,7 @@ int mips32_examine(struct target *target)
{ {
struct mips32_common *mips32 = target_to_mips32(target); struct mips32_common *mips32 = target_to_mips32(target);
if (!target_was_examined(target)) if (!target_was_examined(target)) {
{
target_set_examined(target); target_set_examined(target);
/* we will configure later */ /* we will configure later */
@ -517,53 +478,50 @@ int mips32_configure_break_unit(struct target *target)
return ERROR_OK; return ERROR_OK;
/* get info about breakpoint support */ /* get info about breakpoint support */
if ((retval = target_read_u32(target, EJTAG_DCR, &dcr)) != ERROR_OK) retval = target_read_u32(target, EJTAG_DCR, &dcr);
if (retval != ERROR_OK)
return retval; return retval;
if (dcr & EJTAG_DCR_IB) if (dcr & EJTAG_DCR_IB) {
{
/* get number of inst breakpoints */ /* get number of inst breakpoints */
if ((retval = target_read_u32(target, EJTAG_IBS, &bpinfo)) != ERROR_OK) retval = target_read_u32(target, EJTAG_IBS, &bpinfo);
if (retval != ERROR_OK)
return retval; return retval;
mips32->num_inst_bpoints = (bpinfo >> 24) & 0x0F; mips32->num_inst_bpoints = (bpinfo >> 24) & 0x0F;
mips32->num_inst_bpoints_avail = mips32->num_inst_bpoints; mips32->num_inst_bpoints_avail = mips32->num_inst_bpoints;
mips32->inst_break_list = calloc(mips32->num_inst_bpoints, sizeof(struct mips32_comparator)); mips32->inst_break_list = calloc(mips32->num_inst_bpoints, sizeof(struct mips32_comparator));
for (i = 0; i < mips32->num_inst_bpoints; i++) for (i = 0; i < mips32->num_inst_bpoints; i++)
{
mips32->inst_break_list[i].reg_address = EJTAG_IBA1 + (0x100 * i); mips32->inst_break_list[i].reg_address = EJTAG_IBA1 + (0x100 * i);
}
/* clear IBIS reg */ /* clear IBIS reg */
if ((retval = target_write_u32(target, EJTAG_IBS, 0)) != ERROR_OK) retval = target_write_u32(target, EJTAG_IBS, 0);
if (retval != ERROR_OK)
return retval; return retval;
} }
if (dcr & EJTAG_DCR_DB) if (dcr & EJTAG_DCR_DB) {
{
/* get number of data breakpoints */ /* get number of data breakpoints */
if ((retval = target_read_u32(target, EJTAG_DBS, &bpinfo)) != ERROR_OK) retval = target_read_u32(target, EJTAG_DBS, &bpinfo);
if (retval != ERROR_OK)
return retval; return retval;
mips32->num_data_bpoints = (bpinfo >> 24) & 0x0F; mips32->num_data_bpoints = (bpinfo >> 24) & 0x0F;
mips32->num_data_bpoints_avail = mips32->num_data_bpoints; mips32->num_data_bpoints_avail = mips32->num_data_bpoints;
mips32->data_break_list = calloc(mips32->num_data_bpoints, sizeof(struct mips32_comparator)); mips32->data_break_list = calloc(mips32->num_data_bpoints, sizeof(struct mips32_comparator));
for (i = 0; i < mips32->num_data_bpoints; i++) for (i = 0; i < mips32->num_data_bpoints; i++)
{
mips32->data_break_list[i].reg_address = EJTAG_DBA1 + (0x100 * i); mips32->data_break_list[i].reg_address = EJTAG_DBA1 + (0x100 * i);
}
/* clear DBIS reg */ /* clear DBIS reg */
if ((retval = target_write_u32(target, EJTAG_DBS, 0)) != ERROR_OK) retval = target_write_u32(target, EJTAG_DBS, 0);
if (retval != ERROR_OK)
return retval; return retval;
} }
/* check if target endianness settings matches debug control register */ /* check if target endianness settings matches debug control register */
if ( ( (dcr & EJTAG_DCR_ENM) && (target->endianness == TARGET_LITTLE_ENDIAN) ) || if (((dcr & EJTAG_DCR_ENM) && (target->endianness == TARGET_LITTLE_ENDIAN)) ||
( !(dcr & EJTAG_DCR_ENM) && (target->endianness == TARGET_BIG_ENDIAN) ) ) (!(dcr & EJTAG_DCR_ENM) && (target->endianness == TARGET_BIG_ENDIAN)))
{
LOG_WARNING("DCR endianness settings does not match target settings"); LOG_WARNING("DCR endianness settings does not match target settings");
}
LOG_DEBUG("DCR 0x%" PRIx32 " numinst %i numdata %i", dcr, mips32->num_inst_bpoints, LOG_DEBUG("DCR 0x%" PRIx32 " numinst %i numdata %i", dcr, mips32->num_inst_bpoints,
mips32->num_data_bpoints); mips32->num_data_bpoints);
@ -580,31 +538,27 @@ int mips32_enable_interrupts(struct target *target, int enable)
uint32_t dcr; uint32_t dcr;
/* read debug control register */ /* read debug control register */
if ((retval = target_read_u32(target, EJTAG_DCR, &dcr)) != ERROR_OK) retval = target_read_u32(target, EJTAG_DCR, &dcr);
if (retval != ERROR_OK)
return retval; return retval;
if (enable) if (enable) {
{ if (!(dcr & EJTAG_DCR_INTE)) {
if (!(dcr & EJTAG_DCR_INTE))
{
/* enable interrupts */ /* enable interrupts */
dcr |= EJTAG_DCR_INTE; dcr |= EJTAG_DCR_INTE;
update = 1; update = 1;
} }
} } else {
else if (dcr & EJTAG_DCR_INTE) {
{
if (dcr & EJTAG_DCR_INTE)
{
/* disable interrupts */ /* disable interrupts */
dcr &= ~EJTAG_DCR_INTE; dcr &= ~EJTAG_DCR_INTE;
update = 1; update = 1;
} }
} }
if (update) if (update) {
{ retval = target_write_u32(target, EJTAG_DCR, dcr);
if ((retval = target_write_u32(target, EJTAG_DCR, dcr)) != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
} }
@ -612,7 +566,7 @@ int mips32_enable_interrupts(struct target *target, int enable)
} }
int mips32_checksum_memory(struct target *target, uint32_t address, int mips32_checksum_memory(struct target *target, uint32_t address,
uint32_t count, uint32_t* checksum) uint32_t count, uint32_t *checksum)
{ {
struct working_area *crc_algorithm; struct working_area *crc_algorithm;
struct reg_param reg_params[2]; struct reg_param reg_params[2];
@ -622,9 +576,8 @@ int mips32_checksum_memory(struct target *target, uint32_t address,
/* see contib/loaders/checksum/mips32.s for src */ /* see contib/loaders/checksum/mips32.s for src */
static const uint32_t mips_crc_code[] = static const uint32_t mips_crc_code[] = {
{ 0x248C0000, /* addiu $t4, $a0, 0 */
0x248C0000, /* addiu $t4, $a0, 0 */
0x24AA0000, /* addiu $t2, $a1, 0 */ 0x24AA0000, /* addiu $t2, $a1, 0 */
0x2404FFFF, /* addiu $a0, $zero, 0xffffffff */ 0x2404FFFF, /* addiu $a0, $zero, 0xffffffff */
0x10000010, /* beq $zero, $zero, ncomp */ 0x10000010, /* beq $zero, $zero, ncomp */
@ -654,9 +607,7 @@ int mips32_checksum_memory(struct target *target, uint32_t address,
/* make sure we have a working area */ /* make sure we have a working area */
if (target_alloc_working_area(target, sizeof(mips_crc_code), &crc_algorithm) != ERROR_OK) if (target_alloc_working_area(target, sizeof(mips_crc_code), &crc_algorithm) != ERROR_OK)
{
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
/* convert flash writing code into a buffer in target endianness */ /* convert flash writing code into a buffer in target endianness */
for (i = 0; i < ARRAY_SIZE(mips_crc_code); i++) for (i = 0; i < ARRAY_SIZE(mips_crc_code); i++)
@ -673,10 +624,10 @@ int mips32_checksum_memory(struct target *target, uint32_t address,
int timeout = 20000 * (1 + (count / (1024 * 1024))); int timeout = 20000 * (1 + (count / (1024 * 1024)));
if ((retval = target_run_algorithm(target, 0, NULL, 2, reg_params, retval = target_run_algorithm(target, 0, NULL, 2, reg_params,
crc_algorithm->address, crc_algorithm->address + (sizeof(mips_crc_code)-4), timeout, crc_algorithm->address, crc_algorithm->address + (sizeof(mips_crc_code)-4), timeout,
&mips32_info)) != ERROR_OK) &mips32_info);
{ if (retval != ERROR_OK) {
destroy_reg_param(&reg_params[0]); destroy_reg_param(&reg_params[0]);
destroy_reg_param(&reg_params[1]); destroy_reg_param(&reg_params[1]);
target_free_working_area(target, crc_algorithm); target_free_working_area(target, crc_algorithm);
@ -695,7 +646,7 @@ int mips32_checksum_memory(struct target *target, uint32_t address,
/** Checks whether a memory region is zeroed. */ /** Checks whether a memory region is zeroed. */
int mips32_blank_check_memory(struct target *target, int mips32_blank_check_memory(struct target *target,
uint32_t address, uint32_t count, uint32_t* blank) uint32_t address, uint32_t count, uint32_t *blank)
{ {
struct working_area *erase_check_algorithm; struct working_area *erase_check_algorithm;
struct reg_param reg_params[3]; struct reg_param reg_params[3];
@ -703,8 +654,7 @@ int mips32_blank_check_memory(struct target *target,
int retval; int retval;
uint32_t i; uint32_t i;
static const uint32_t erase_check_code[] = static const uint32_t erase_check_code[] = {
{
/* nbyte: */ /* nbyte: */
0x80880000, /* lb $t0, ($a0) */ 0x80880000, /* lb $t0, ($a0) */
0x00C83024, /* and $a2, $a2, $t0 */ 0x00C83024, /* and $a2, $a2, $t0 */
@ -716,13 +666,10 @@ int mips32_blank_check_memory(struct target *target,
/* make sure we have a working area */ /* make sure we have a working area */
if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK) if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK)
{
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
}
/* convert flash writing code into a buffer in target endianness */ /* convert flash writing code into a buffer in target endianness */
for (i = 0; i < ARRAY_SIZE(erase_check_code); i++) for (i = 0; i < ARRAY_SIZE(erase_check_code); i++) {
{
target_write_u32(target, erase_check_algorithm->address + i*sizeof(uint32_t), target_write_u32(target, erase_check_algorithm->address + i*sizeof(uint32_t),
erase_check_code[i]); erase_check_code[i]);
} }
@ -739,11 +686,11 @@ int mips32_blank_check_memory(struct target *target,
init_reg_param(&reg_params[2], "a2", 32, PARAM_IN_OUT); init_reg_param(&reg_params[2], "a2", 32, PARAM_IN_OUT);
buf_set_u32(reg_params[2].value, 0, 32, 0xff); buf_set_u32(reg_params[2].value, 0, 32, 0xff);
if ((retval = target_run_algorithm(target, 0, NULL, 3, reg_params, retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
erase_check_algorithm->address, erase_check_algorithm->address,
erase_check_algorithm->address + (sizeof(erase_check_code)-2), erase_check_algorithm->address + (sizeof(erase_check_code)-2),
10000, &mips32_info)) != ERROR_OK) 10000, &mips32_info);
{ if (retval != ERROR_OK) {
destroy_reg_param(&reg_params[0]); destroy_reg_param(&reg_params[0]);
destroy_reg_param(&reg_params[1]); destroy_reg_param(&reg_params[1]);
destroy_reg_param(&reg_params[2]); destroy_reg_param(&reg_params[2]);
@ -788,48 +735,40 @@ COMMAND_HANDLER(mips32_handle_cp0_command)
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
return ERROR_OK; return ERROR_OK;
} }
/* two or more argument, access a single register/select (write if third argument is given) */ /* two or more argument, access a single register/select (write if third argument is given) */
if (CMD_ARGC < 2) if (CMD_ARGC < 2)
{ return ERROR_COMMAND_SYNTAX_ERROR;
return ERROR_COMMAND_SYNTAX_ERROR; else {
}
else
{
uint32_t cp0_reg, cp0_sel; uint32_t cp0_reg, cp0_sel;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
if (CMD_ARGC == 2) if (CMD_ARGC == 2) {
{
uint32_t value; uint32_t value;
if ((retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel)) != ERROR_OK) retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel);
{ if (retval != ERROR_OK) {
command_print(CMD_CTX, command_print(CMD_CTX,
"couldn't access reg %" PRIi32, "couldn't access reg %" PRIi32,
cp0_reg); cp0_reg);
return ERROR_OK; return ERROR_OK;
} }
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32, command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
cp0_reg, cp0_sel, value); cp0_reg, cp0_sel, value);
} } else if (CMD_ARGC == 3) {
else if (CMD_ARGC == 3)
{
uint32_t value; uint32_t value;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
if ((retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel)) != ERROR_OK) retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel);
{ if (retval != ERROR_OK) {
command_print(CMD_CTX, command_print(CMD_CTX,
"couldn't access cp0 reg %" PRIi32 ", select %" PRIi32, "couldn't access cp0 reg %" PRIi32 ", select %" PRIi32,
cp0_reg, cp0_sel); cp0_reg, cp0_sel);
@ -864,4 +803,3 @@ const struct command_registration mips32_command_handlers[] = {
}, },
COMMAND_REGISTRATION_DONE COMMAND_REGISTRATION_DONE
}; };

View File

@ -64,27 +64,23 @@
#define MIPS32_ARCH_REL2 0x1 #define MIPS32_ARCH_REL2 0x1
/* offsets into mips32 core register cache */ /* offsets into mips32 core register cache */
enum enum {
{
MIPS32_PC = 37, MIPS32_PC = 37,
MIPS32NUMCOREREGS MIPS32NUMCOREREGS
}; };
enum mips32_isa_mode enum mips32_isa_mode {
{
MIPS32_ISA_MIPS32 = 0, MIPS32_ISA_MIPS32 = 0,
MIPS32_ISA_MIPS16E = 1, MIPS32_ISA_MIPS16E = 1,
}; };
struct mips32_comparator struct mips32_comparator {
{
int used; int used;
uint32_t bp_value; uint32_t bp_value;
uint32_t reg_address; uint32_t reg_address;
}; };
struct mips32_common struct mips32_common {
{
uint32_t common_magic; uint32_t common_magic;
void *arch_info; void *arch_info;
struct reg_cache *core_cache; struct reg_cache *core_cache;
@ -114,15 +110,13 @@ target_to_mips32(struct target *target)
return target->arch_info; return target->arch_info;
} }
struct mips32_core_reg struct mips32_core_reg {
{
uint32_t num; uint32_t num;
struct target *target; struct target *target;
struct mips32_common *mips32_common; struct mips32_common *mips32_common;
}; };
struct mips32_algorithm struct mips32_algorithm {
{
int common_magic; int common_magic;
enum mips32_isa_mode isa_mode; enum mips32_isa_mode isa_mode;
}; };
@ -164,9 +158,11 @@ struct mips32_algorithm
#define MIPS32_COP0_MF 0x00 #define MIPS32_COP0_MF 0x00
#define MIPS32_COP0_MT 0x04 #define MIPS32_COP0_MT 0x04
#define MIPS32_R_INST(opcode, rs, rt, rd, shamt, funct) (((opcode) << 26) |((rs) << 21) | ((rt) << 16) | ((rd) << 11)| ((shamt) << 6) | (funct)) #define MIPS32_R_INST(opcode, rs, rt, rd, shamt, funct) \
#define MIPS32_I_INST(opcode, rs, rt, immd) (((opcode) << 26) |((rs) << 21) | ((rt) << 16) | (immd)) (((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | ((rd) << 11) | ((shamt) << 6) | (funct))
#define MIPS32_J_INST(opcode, addr) (((opcode) << 26) |(addr)) #define MIPS32_I_INST(opcode, rs, rt, immd) \
(((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | (immd))
#define MIPS32_J_INST(opcode, addr) (((opcode) << 26) | (addr))
#define MIPS32_NOP 0 #define MIPS32_NOP 0
#define MIPS32_ADDI(tar, src, val) MIPS32_I_INST(MIPS32_OP_ADDI, src, tar, val) #define MIPS32_ADDI(tar, src, val) MIPS32_I_INST(MIPS32_OP_ADDI, src, tar, val)
@ -176,7 +172,7 @@ struct mips32_algorithm
#define MIPS32_B(off) MIPS32_BEQ(0, 0, off) #define MIPS32_B(off) MIPS32_BEQ(0, 0, off)
#define MIPS32_BEQ(src, tar, off) MIPS32_I_INST(MIPS32_OP_BEQ, src, tar, off) #define MIPS32_BEQ(src, tar, off) MIPS32_I_INST(MIPS32_OP_BEQ, src, tar, off)
#define MIPS32_BGTZ(reg, off) MIPS32_I_INST(MIPS32_OP_BGTZ, reg, 0, off) #define MIPS32_BGTZ(reg, off) MIPS32_I_INST(MIPS32_OP_BGTZ, reg, 0, off)
#define MIPS32_BNE(src,tar,off) MIPS32_I_INST(MIPS32_OP_BNE, src, tar, off) #define MIPS32_BNE(src, tar, off) MIPS32_I_INST(MIPS32_OP_BNE, src, tar, off)
#define MIPS32_CACHE(op, off, base) MIPS32_I_INST(MIPS32_OP_CACHE, base, op, off) #define MIPS32_CACHE(op, off, base) MIPS32_I_INST(MIPS32_OP_CACHE, base, op, off)
#define MIPS32_JR(reg) MIPS32_R_INST(0, reg, 0, 0, 0, MIPS32_OP_JR) #define MIPS32_JR(reg) MIPS32_R_INST(0, reg, 0, 0, 0, MIPS32_OP_JR)
#define MIPS32_MFC0(gpr, cpr, sel) MIPS32_R_INST(MIPS32_OP_COP0, MIPS32_COP0_MF, gpr, cpr, 0, sel) #define MIPS32_MFC0(gpr, cpr, sel) MIPS32_R_INST(MIPS32_OP_COP0, MIPS32_COP0_MF, gpr, cpr, 0, sel)
@ -245,8 +241,8 @@ int mips32_register_commands(struct command_context *cmd_ctx);
int mips32_get_gdb_reg_list(struct target *target, int mips32_get_gdb_reg_list(struct target *target,
struct reg **reg_list[], int *reg_list_size); struct reg **reg_list[], int *reg_list_size);
int mips32_checksum_memory(struct target *target, uint32_t address, int mips32_checksum_memory(struct target *target, uint32_t address,
uint32_t count, uint32_t* checksum); uint32_t count, uint32_t *checksum);
int mips32_blank_check_memory(struct target *target, int mips32_blank_check_memory(struct target *target,
uint32_t address, uint32_t count, uint32_t* blank); uint32_t address, uint32_t count, uint32_t *blank);
#endif /*MIPS32_H*/ #endif /*MIPS32_H*/

View File

@ -22,6 +22,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -84,13 +85,11 @@ begin_ejtag_dma_read:
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
ejtag_ctrl = ejtag_info->ejtag_ctrl; ejtag_ctrl = ejtag_info->ejtag_ctrl;
mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
if (ejtag_ctrl & EJTAG_CTRL_DERR) if (ejtag_ctrl & EJTAG_CTRL_DERR) {
{
if (retries--) { if (retries--) {
LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ (retrying)", addr); LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ (retrying)", addr);
goto begin_ejtag_dma_read; goto begin_ejtag_dma_read;
} } else
else
LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ", addr); LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ", addr);
return ERROR_JTAG_DEVICE_ERROR; return ERROR_JTAG_DEVICE_ERROR;
} }
@ -113,7 +112,8 @@ begin_ejtag_dma_read_h:
/* Initiate DMA Read & set DSTRT */ /* Initiate DMA Read & set DSTRT */
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_HALFWORD | EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl; ejtag_ctrl = EJTAG_CTRL_DMAACC | EJTAG_CTRL_DRWN | EJTAG_CTRL_DMA_HALFWORD |
EJTAG_CTRL_DSTRT | ejtag_info->ejtag_ctrl;
mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
/* Wait for DSTRT to Clear */ /* Wait for DSTRT to Clear */
@ -130,13 +130,11 @@ begin_ejtag_dma_read_h:
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
ejtag_ctrl = ejtag_info->ejtag_ctrl; ejtag_ctrl = ejtag_info->ejtag_ctrl;
mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
if (ejtag_ctrl & EJTAG_CTRL_DERR) if (ejtag_ctrl & EJTAG_CTRL_DERR) {
{
if (retries--) { if (retries--) {
LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ (retrying)", addr); LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ (retrying)", addr);
goto begin_ejtag_dma_read_h; goto begin_ejtag_dma_read_h;
} } else
else
LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ", addr); LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ", addr);
return ERROR_JTAG_DEVICE_ERROR; return ERROR_JTAG_DEVICE_ERROR;
} }
@ -182,13 +180,11 @@ begin_ejtag_dma_read_b:
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
ejtag_ctrl = ejtag_info->ejtag_ctrl; ejtag_ctrl = ejtag_info->ejtag_ctrl;
mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
if (ejtag_ctrl & EJTAG_CTRL_DERR) if (ejtag_ctrl & EJTAG_CTRL_DERR) {
{
if (retries--) { if (retries--) {
LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ (retrying)", addr); LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ (retrying)", addr);
goto begin_ejtag_dma_read_b; goto begin_ejtag_dma_read_b;
} } else
else
LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ", addr); LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ", addr);
return ERROR_JTAG_DEVICE_ERROR; return ERROR_JTAG_DEVICE_ERROR;
} }
@ -245,13 +241,11 @@ begin_ejtag_dma_write:
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
ejtag_ctrl = ejtag_info->ejtag_ctrl; ejtag_ctrl = ejtag_info->ejtag_ctrl;
mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
if (ejtag_ctrl & EJTAG_CTRL_DERR) if (ejtag_ctrl & EJTAG_CTRL_DERR) {
{
if (retries--) { if (retries--) {
LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE (retrying)", addr); LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE (retrying)", addr);
goto begin_ejtag_dma_write; goto begin_ejtag_dma_write;
} } else
else
LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE", addr); LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE", addr);
return ERROR_JTAG_DEVICE_ERROR; return ERROR_JTAG_DEVICE_ERROR;
} }
@ -296,13 +290,11 @@ begin_ejtag_dma_write_h:
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
ejtag_ctrl = ejtag_info->ejtag_ctrl; ejtag_ctrl = ejtag_info->ejtag_ctrl;
mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
if (ejtag_ctrl & EJTAG_CTRL_DERR) if (ejtag_ctrl & EJTAG_CTRL_DERR) {
{
if (retries--) { if (retries--) {
LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE (retrying)", addr); LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE (retrying)", addr);
goto begin_ejtag_dma_write_h; goto begin_ejtag_dma_write_h;
} } else
else
LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE", addr); LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE", addr);
return ERROR_JTAG_DEVICE_ERROR; return ERROR_JTAG_DEVICE_ERROR;
} }
@ -348,13 +340,11 @@ begin_ejtag_dma_write_b:
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
ejtag_ctrl = ejtag_info->ejtag_ctrl; ejtag_ctrl = ejtag_info->ejtag_ctrl;
mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
if (ejtag_ctrl & EJTAG_CTRL_DERR) if (ejtag_ctrl & EJTAG_CTRL_DERR) {
{
if (retries--) { if (retries--) {
LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE (retrying)", addr); LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE (retrying)", addr);
goto begin_ejtag_dma_write_b; goto begin_ejtag_dma_write_b;
} } else
else
LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE", addr); LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE", addr);
return ERROR_JTAG_DEVICE_ERROR; return ERROR_JTAG_DEVICE_ERROR;
} }
@ -364,14 +354,13 @@ begin_ejtag_dma_write_b:
int mips32_dmaacc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf) int mips32_dmaacc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf)
{ {
switch (size) switch (size) {
{
case 1: case 1:
return mips32_dmaacc_read_mem8(ejtag_info, addr, count, (uint8_t*)buf); return mips32_dmaacc_read_mem8(ejtag_info, addr, count, (uint8_t *)buf);
case 2: case 2:
return mips32_dmaacc_read_mem16(ejtag_info, addr, count, (uint16_t*)buf); return mips32_dmaacc_read_mem16(ejtag_info, addr, count, (uint16_t *)buf);
case 4: case 4:
return mips32_dmaacc_read_mem32(ejtag_info, addr, count, (uint32_t*)buf); return mips32_dmaacc_read_mem32(ejtag_info, addr, count, (uint32_t *)buf);
} }
return ERROR_OK; return ERROR_OK;
@ -383,7 +372,8 @@ static int mips32_dmaacc_read_mem32(struct mips_ejtag *ejtag_info, uint32_t addr
int retval; int retval;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
if ((retval = ejtag_dma_read(ejtag_info, addr + i*sizeof(*buf), &buf[i])) != ERROR_OK) retval = ejtag_dma_read(ejtag_info, addr + i * sizeof(*buf), &buf[i]);
if (retval != ERROR_OK)
return retval; return retval;
} }
@ -396,7 +386,8 @@ static int mips32_dmaacc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr
int retval; int retval;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
if ((retval = ejtag_dma_read_h(ejtag_info, addr + i*sizeof(*buf), &buf[i])) != ERROR_OK) retval = ejtag_dma_read_h(ejtag_info, addr + i * sizeof(*buf), &buf[i]);
if (retval != ERROR_OK)
return retval; return retval;
} }
@ -409,7 +400,8 @@ static int mips32_dmaacc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr,
int retval; int retval;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
if ((retval = ejtag_dma_read_b(ejtag_info, addr + i*sizeof(*buf), &buf[i])) != ERROR_OK) retval = ejtag_dma_read_b(ejtag_info, addr + i * sizeof(*buf), &buf[i]);
if (retval != ERROR_OK)
return retval; return retval;
} }
@ -418,14 +410,13 @@ static int mips32_dmaacc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr,
int mips32_dmaacc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf) int mips32_dmaacc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf)
{ {
switch (size) switch (size) {
{
case 1: case 1:
return mips32_dmaacc_write_mem8(ejtag_info, addr, count, (uint8_t*)buf); return mips32_dmaacc_write_mem8(ejtag_info, addr, count, (uint8_t *)buf);
case 2: case 2:
return mips32_dmaacc_write_mem16(ejtag_info, addr, count,(uint16_t*)buf); return mips32_dmaacc_write_mem16(ejtag_info, addr, count, (uint16_t *)buf);
case 4: case 4:
return mips32_dmaacc_write_mem32(ejtag_info, addr, count, (uint32_t*)buf); return mips32_dmaacc_write_mem32(ejtag_info, addr, count, (uint32_t *)buf);
} }
return ERROR_OK; return ERROR_OK;
@ -437,7 +428,8 @@ static int mips32_dmaacc_write_mem32(struct mips_ejtag *ejtag_info, uint32_t add
int retval; int retval;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
if ((retval = ejtag_dma_write(ejtag_info, addr + i*sizeof(*buf), buf[i])) != ERROR_OK) retval = ejtag_dma_write(ejtag_info, addr + i * sizeof(*buf), buf[i]);
if (retval != ERROR_OK)
return retval; return retval;
} }
@ -450,7 +442,8 @@ static int mips32_dmaacc_write_mem16(struct mips_ejtag *ejtag_info, uint32_t add
int retval; int retval;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
if ((retval = ejtag_dma_write_h(ejtag_info, addr + i*sizeof(*buf), buf[i])) != ERROR_OK) retval = ejtag_dma_write_h(ejtag_info, addr + i * sizeof(*buf), buf[i]);
if (retval != ERROR_OK)
return retval; return retval;
} }
@ -463,7 +456,8 @@ static int mips32_dmaacc_write_mem8(struct mips_ejtag *ejtag_info, uint32_t addr
int retval; int retval;
for (i = 0; i < count; i++) { for (i = 0; i < count; i++) {
if ((retval = ejtag_dma_write_b(ejtag_info, addr + i*sizeof(*buf), buf[i])) != ERROR_OK) retval = ejtag_dma_write_b(ejtag_info, addr + i * sizeof(*buf), buf[i]);
if (retval != ERROR_OK)
return retval; return retval;
} }

View File

@ -22,6 +22,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef MIPS32_DMAACC_H #ifndef MIPS32_DMAACC_H
#define MIPS32_DMAACC_H #define MIPS32_DMAACC_H

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef MIPS32_PRACC_H #ifndef MIPS32_PRACC_H
#define MIPS32_PRACC_H #define MIPS32_PRACC_H
@ -71,7 +72,7 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, int code_len, const uint32_
* @return ERROR_OK on Sucess, ERROR_FAIL otherwise * @return ERROR_OK on Sucess, ERROR_FAIL otherwise
*/ */
int mips32_cp0_read(struct mips_ejtag *ejtag_info, int mips32_cp0_read(struct mips_ejtag *ejtag_info,
uint32_t *val, uint32_t cp0_reg, uint32_t cp0_sel); uint32_t *val, uint32_t cp0_reg, uint32_t cp0_sel);
/** /**
* \b mips32_cp0_write * \b mips32_cp0_write
@ -87,6 +88,6 @@ int mips32_cp0_read(struct mips_ejtag *ejtag_info,
* @return ERROR_OK on Sucess, ERROR_FAIL otherwise * @return ERROR_OK on Sucess, ERROR_FAIL otherwise
*/ */
int mips32_cp0_write(struct mips_ejtag *ejtag_info, int mips32_cp0_write(struct mips_ejtag *ejtag_info,
uint32_t val, uint32_t cp0_reg, uint32_t cp0_sel); uint32_t val, uint32_t cp0_reg, uint32_t cp0_sel);
#endif #endif

View File

@ -21,6 +21,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -35,8 +36,7 @@ void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, int new_instr)
tap = ejtag_info->tap; tap = ejtag_info->tap;
assert(tap != NULL); assert(tap != NULL);
if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != (uint32_t)new_instr) if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != (uint32_t)new_instr) {
{
struct scan_field field; struct scan_field field;
uint8_t t[4]; uint8_t t[4];
@ -63,8 +63,8 @@ int mips_ejtag_get_idcode(struct mips_ejtag *ejtag_info, uint32_t *idcode)
jtag_add_dr_scan(ejtag_info->tap, 1, &field, TAP_IDLE); jtag_add_dr_scan(ejtag_info->tap, 1, &field, TAP_IDLE);
int retval; int retval;
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK) {
LOG_ERROR("register read failed"); LOG_ERROR("register read failed");
return retval; return retval;
} }
@ -88,8 +88,8 @@ static int mips_ejtag_get_impcode(struct mips_ejtag *ejtag_info, uint32_t *impco
jtag_add_dr_scan(ejtag_info->tap, 1, &field, TAP_IDLE); jtag_add_dr_scan(ejtag_info->tap, 1, &field, TAP_IDLE);
int retval; int retval;
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK) {
LOG_ERROR("register read failed"); LOG_ERROR("register read failed");
return retval; return retval;
} }
@ -116,8 +116,8 @@ int mips_ejtag_drscan_32(struct mips_ejtag *ejtag_info, uint32_t *data)
jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK) {
LOG_ERROR("register read failed"); LOG_ERROR("register read failed");
return retval; return retval;
} }
@ -164,8 +164,8 @@ int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint32_t *data)
jtag_add_dr_scan(tap, 1, &field, TAP_IDLE); jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK) {
LOG_ERROR("register read failed"); LOG_ERROR("register read failed");
return retval; return retval;
} }
@ -193,12 +193,12 @@ void mips_ejtag_drscan_8_out(struct mips_ejtag *ejtag_info, uint8_t data)
static int mips_ejtag_step_enable(struct mips_ejtag *ejtag_info) static int mips_ejtag_step_enable(struct mips_ejtag *ejtag_info)
{ {
static const uint32_t code[] = { static const uint32_t code[] = {
MIPS32_MTC0(1,31,0), /* move $1 to COP0 DeSave */ MIPS32_MTC0(1, 31, 0), /* move $1 to COP0 DeSave */
MIPS32_MFC0(1,23,0), /* move COP0 Debug to $1 */ MIPS32_MFC0(1, 23, 0), /* move COP0 Debug to $1 */
MIPS32_ORI(1,1,0x0100), /* set SSt bit in debug reg */ MIPS32_ORI(1, 1, 0x0100), /* set SSt bit in debug reg */
MIPS32_MTC0(1,23,0), /* move $1 to COP0 Debug */ MIPS32_MTC0(1, 23, 0), /* move $1 to COP0 Debug */
MIPS32_B(NEG16(5)), MIPS32_B(NEG16(5)),
MIPS32_MFC0(1,31,0), /* move COP0 DeSave to $1 */ MIPS32_MFC0(1, 31, 0), /* move COP0 DeSave to $1 */
}; };
return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
@ -208,20 +208,20 @@ static int mips_ejtag_step_enable(struct mips_ejtag *ejtag_info)
static int mips_ejtag_step_disable(struct mips_ejtag *ejtag_info) static int mips_ejtag_step_disable(struct mips_ejtag *ejtag_info)
{ {
static const uint32_t code[] = { static const uint32_t code[] = {
MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */ MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */
MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */ MIPS32_LUI(15, UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)), MIPS32_ORI(15, 15, LOWER16(MIPS32_PRACC_STACK)),
MIPS32_SW(1,0,15), /* sw $1,($15) */ MIPS32_SW(1, 0, 15), /* sw $1,($15) */
MIPS32_SW(2,0,15), /* sw $2,($15) */ MIPS32_SW(2, 0, 15), /* sw $2,($15) */
MIPS32_MFC0(1,23,0), /* move COP0 Debug to $1 */ MIPS32_MFC0(1, 23, 0), /* move COP0 Debug to $1 */
MIPS32_LUI(2,0xFFFF), /* $2 = 0xfffffeff */ MIPS32_LUI(2, 0xFFFF), /* $2 = 0xfffffeff */
MIPS32_ORI(2,2,0xFEFF), MIPS32_ORI(2, 2, 0xFEFF),
MIPS32_AND(1,1,2), MIPS32_AND(1, 1, 2),
MIPS32_MTC0(1,23,0), /* move $1 to COP0 Debug */ MIPS32_MTC0(1, 23, 0), /* move $1 to COP0 Debug */
MIPS32_LW(2,0,15), MIPS32_LW(2, 0, 15),
MIPS32_LW(1,0,15), MIPS32_LW(1, 0, 15),
MIPS32_B(NEG16(13)), MIPS32_B(NEG16(13)),
MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */ MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */
}; };
return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
@ -248,8 +248,7 @@ int mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info)
ejtag_ctrl = ejtag_info->ejtag_ctrl; ejtag_ctrl = ejtag_info->ejtag_ctrl;
mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl); mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
LOG_DEBUG("ejtag_ctrl: 0x%8.8" PRIx32 "", ejtag_ctrl); LOG_DEBUG("ejtag_ctrl: 0x%8.8" PRIx32 "", ejtag_ctrl);
if ((ejtag_ctrl & EJTAG_CTRL_BRKST) == 0) if ((ejtag_ctrl & EJTAG_CTRL_BRKST) == 0) {
{
LOG_ERROR("Failed to enter Debug Mode!"); LOG_ERROR("Failed to enter Debug Mode!");
return ERROR_FAIL; return ERROR_FAIL;
} }
@ -270,19 +269,19 @@ int mips_ejtag_read_debug(struct mips_ejtag *ejtag_info, uint32_t* debug_reg)
{ {
/* read ejtag ECR */ /* read ejtag ECR */
static const uint32_t code[] = { static const uint32_t code[] = {
MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */ MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */
MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */ MIPS32_LUI(15, UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */
MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)), MIPS32_ORI(15, 15, LOWER16(MIPS32_PRACC_STACK)),
MIPS32_SW(1,0,15), /* sw $1,($15) */ MIPS32_SW(1, 0, 15), /* sw $1,($15) */
MIPS32_SW(2,0,15), /* sw $2,($15) */ MIPS32_SW(2, 0, 15), /* sw $2,($15) */
MIPS32_LUI(1,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $1 = MIPS32_PRACC_PARAM_OUT */ MIPS32_LUI(1, UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $1 = MIPS32_PRACC_PARAM_OUT */
MIPS32_ORI(1,1,LOWER16(MIPS32_PRACC_PARAM_OUT)), MIPS32_ORI(1, 1, LOWER16(MIPS32_PRACC_PARAM_OUT)),
MIPS32_MFC0(2,23,0), /* move COP0 Debug to $2 */ MIPS32_MFC0(2, 23, 0), /* move COP0 Debug to $2 */
MIPS32_SW(2,0,1), MIPS32_SW(2, 0, 1),
MIPS32_LW(2,0,15), MIPS32_LW(2, 0, 15),
MIPS32_LW(1,0,15), MIPS32_LW(1, 0, 15),
MIPS32_B(NEG16(12)), MIPS32_B(NEG16(12)),
MIPS32_MFC0(15,31,0), /* move COP0 DeSave to $15 */ MIPS32_MFC0(15, 31, 0), /* move COP0 DeSave to $15 */
}; };
return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
@ -302,8 +301,7 @@ int mips_ejtag_init(struct mips_ejtag *ejtag_info)
/* get ejtag version */ /* get ejtag version */
ejtag_version = ((ejtag_info->impcode >> 29) & 0x07); ejtag_version = ((ejtag_info->impcode >> 29) & 0x07);
switch (ejtag_version) switch (ejtag_version) {
{
case 0: case 0:
LOG_DEBUG("EJTAG: Version 1 or 2.0 Detected"); LOG_DEBUG("EJTAG: Version 1 or 2.0 Detected");
break; break;
@ -359,19 +357,15 @@ int mips_ejtag_fastdata_scan(struct mips_ejtag *ejtag_info, int write_t, uint32_
fields[1].num_bits = 32; fields[1].num_bits = 32;
fields[1].out_value = t; fields[1].out_value = t;
if (write_t) if (write_t) {
{
fields[1].in_value = NULL; fields[1].in_value = NULL;
buf_set_u32(t, 0, 32, *data); buf_set_u32(t, 0, 32, *data);
} } else
else
{
fields[1].in_value = (void *) data; fields[1].in_value = (void *) data;
}
jtag_add_dr_scan(tap, 2, fields, TAP_IDLE); jtag_add_dr_scan(tap, 2, fields, TAP_IDLE);
if ( (!write_t) && (data) ) if (!write_t && data)
jtag_add_callback(mips_le_to_h_u32, jtag_add_callback(mips_le_to_h_u32,
(jtag_callback_data_t) data); (jtag_callback_data_t) data);

View File

@ -122,8 +122,7 @@
#define EJTAG_DBCn_BLM_SHIFT 4 #define EJTAG_DBCn_BLM_SHIFT 4
#define EJTAG_DBCn_BE (1 << 0) #define EJTAG_DBCn_BE (1 << 0)
struct mips_ejtag struct mips_ejtag {
{
struct jtag_tap *tap; struct jtag_tap *tap;
uint32_t impcode; uint32_t impcode;
uint32_t idcode; uint32_t idcode;
@ -146,7 +145,7 @@ int mips_ejtag_init(struct mips_ejtag *ejtag_info);
int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step); int mips_ejtag_config_step(struct mips_ejtag *ejtag_info, int enable_step);
int mips_ejtag_read_debug(struct mips_ejtag *ejtag_info, uint32_t* debug_reg); int mips_ejtag_read_debug(struct mips_ejtag *ejtag_info, uint32_t* debug_reg);
static __inline__ void mips_le_to_h_u32(jtag_callback_data_t arg) static inline void mips_le_to_h_u32(jtag_callback_data_t arg)
{ {
uint8_t *in = (uint8_t *)arg; uint8_t *in = (uint8_t *)arg;
*((uint32_t *)arg) = le_to_h_u32(in); *((uint32_t *)arg) = le_to_h_u32(in);

View File

@ -24,6 +24,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -48,26 +49,27 @@ static int mips_m4k_examine_debug_reason(struct target *target)
int retval; int retval;
if ((target->debug_reason != DBG_REASON_DBGRQ) if ((target->debug_reason != DBG_REASON_DBGRQ)
&& (target->debug_reason != DBG_REASON_SINGLESTEP)) && (target->debug_reason != DBG_REASON_SINGLESTEP)) {
{
/* get info about inst breakpoint support */ /* get info about inst breakpoint support */
if ((retval = target_read_u32(target, EJTAG_IBS, &break_status)) != ERROR_OK) retval = target_read_u32(target, EJTAG_IBS, &break_status);
if (retval != ERROR_OK)
return retval; return retval;
if (break_status & 0x1f) if (break_status & 0x1f) {
{
/* we have halted on a breakpoint */ /* we have halted on a breakpoint */
if ((retval = target_write_u32(target, EJTAG_IBS, 0)) != ERROR_OK) retval = target_write_u32(target, EJTAG_IBS, 0);
if (retval != ERROR_OK)
return retval; return retval;
target->debug_reason = DBG_REASON_BREAKPOINT; target->debug_reason = DBG_REASON_BREAKPOINT;
} }
/* get info about data breakpoint support */ /* get info about data breakpoint support */
if ((retval = target_read_u32(target, EJTAG_DBS, &break_status)) != ERROR_OK) retval = target_read_u32(target, EJTAG_DBS, &break_status);
if (retval != ERROR_OK)
return retval; return retval;
if (break_status & 0x1f) if (break_status & 0x1f) {
{
/* we have halted on a breakpoint */ /* we have halted on a breakpoint */
if ((retval = target_write_u32(target, EJTAG_DBS, 0)) != ERROR_OK) retval = target_write_u32(target, EJTAG_DBS, 0);
if (retval != ERROR_OK)
return retval; return retval;
target->debug_reason = DBG_REASON_WATCHPOINT; target->debug_reason = DBG_REASON_WATCHPOINT;
} }
@ -92,8 +94,7 @@ static int mips_m4k_debug_entry(struct target *target)
mips_m4k_examine_debug_reason(target); mips_m4k_examine_debug_reason(target);
/* clear single step if active */ /* clear single step if active */
if (debug_reg & EJTAG_DEBUG_DSS) if (debug_reg & EJTAG_DEBUG_DSS) {
{
/* stopped due to single step - clear step bit */ /* stopped due to single step - clear step bit */
mips_ejtag_config_step(ejtag_info, 0); mips_ejtag_config_step(ejtag_info, 0);
} }
@ -103,9 +104,8 @@ static int mips_m4k_debug_entry(struct target *target)
/* default to mips32 isa, it will be changed below if required */ /* default to mips32 isa, it will be changed below if required */
mips32->isa_mode = MIPS32_ISA_MIPS32; mips32->isa_mode = MIPS32_ISA_MIPS32;
if (ejtag_info->impcode & EJTAG_IMP_MIPS16) { if (ejtag_info->impcode & EJTAG_IMP_MIPS16)
mips32->isa_mode = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1); mips32->isa_mode = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1);
}
LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s", LOG_DEBUG("entered debug state at PC 0x%" PRIx32 ", target->state: %s",
buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32), buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32),
@ -129,8 +129,7 @@ static int mips_m4k_poll(struct target *target)
/* clear this bit before handling polling /* clear this bit before handling polling
* as after reset registers will read zero */ * as after reset registers will read zero */
if (ejtag_ctrl & EJTAG_CTRL_ROCC) if (ejtag_ctrl & EJTAG_CTRL_ROCC) {
{
/* we have detected a reset, clear flag /* we have detected a reset, clear flag
* otherwise ejtag will not work */ * otherwise ejtag will not work */
ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC; ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_ROCC;
@ -143,35 +142,30 @@ static int mips_m4k_poll(struct target *target)
} }
/* check for processor halted */ /* check for processor halted */
if (ejtag_ctrl & EJTAG_CTRL_BRKST) if (ejtag_ctrl & EJTAG_CTRL_BRKST) {
{ if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) {
if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET))
{
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT); mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT);
target->state = TARGET_HALTED; target->state = TARGET_HALTED;
if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK) retval = mips_m4k_debug_entry(target);
if (retval != ERROR_OK)
return retval; return retval;
target_call_event_callbacks(target, TARGET_EVENT_HALTED); target_call_event_callbacks(target, TARGET_EVENT_HALTED);
} } else if (target->state == TARGET_DEBUG_RUNNING) {
else if (target->state == TARGET_DEBUG_RUNNING)
{
target->state = TARGET_HALTED; target->state = TARGET_HALTED;
if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK) retval = mips_m4k_debug_entry(target);
if (retval != ERROR_OK)
return retval; return retval;
target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
} }
} } else
else
{
target->state = TARGET_RUNNING; target->state = TARGET_RUNNING;
}
// LOG_DEBUG("ctrl = 0x%08X", ejtag_ctrl); /* LOG_DEBUG("ctrl = 0x%08X", ejtag_ctrl); */
return ERROR_OK; return ERROR_OK;
} }
@ -181,29 +175,21 @@ static int mips_m4k_halt(struct target *target)
struct mips32_common *mips32 = target_to_mips32(target); struct mips32_common *mips32 = target_to_mips32(target);
struct mips_ejtag *ejtag_info = &mips32->ejtag_info; struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
LOG_DEBUG("target->state: %s", LOG_DEBUG("target->state: %s", target_state_name(target));
target_state_name(target));
if (target->state == TARGET_HALTED) if (target->state == TARGET_HALTED) {
{
LOG_DEBUG("target was already halted"); LOG_DEBUG("target was already halted");
return ERROR_OK; return ERROR_OK;
} }
if (target->state == TARGET_UNKNOWN) if (target->state == TARGET_UNKNOWN)
{
LOG_WARNING("target was in unknown state when halt was requested"); LOG_WARNING("target was in unknown state when halt was requested");
}
if (target->state == TARGET_RESET) if (target->state == TARGET_RESET) {
{ if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) {
if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst())
{
LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST"); LOG_ERROR("can't request a halt while in reset if nSRST pulls nTRST");
return ERROR_TARGET_FAILURE; return ERROR_TARGET_FAILURE;
} } else {
else
{
/* we came here in a reset_halt or reset_init sequence /* we came here in a reset_halt or reset_init sequence
* debug entry was already prepared in mips32_prepare_reset_halt() * debug entry was already prepared in mips32_prepare_reset_halt()
*/ */
@ -235,32 +221,20 @@ static int mips_m4k_assert_reset(struct target *target)
if (!(jtag_reset_config & RESET_HAS_SRST)) if (!(jtag_reset_config & RESET_HAS_SRST))
assert_srst = 0; assert_srst = 0;
if (target->reset_halt) if (target->reset_halt) {
{
/* use hardware to catch reset */ /* use hardware to catch reset */
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT); mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT);
} } else
else
{
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT); mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT);
}
if (assert_srst) if (assert_srst) {
{
/* here we should issue a srst only, but we may have to assert trst as well */ /* here we should issue a srst only, but we may have to assert trst as well */
if (jtag_reset_config & RESET_SRST_PULLS_TRST) if (jtag_reset_config & RESET_SRST_PULLS_TRST)
{
jtag_add_reset(1, 1); jtag_add_reset(1, 1);
}
else else
{
jtag_add_reset(0, 1); jtag_add_reset(0, 1);
} } else {
} if (mips_m4k->is_pic32mx) {
else
{
if (mips_m4k->is_pic32mx)
{
LOG_DEBUG("Using MTAP reset to reset processor..."); LOG_DEBUG("Using MTAP reset to reset processor...");
/* use microchip specific MTAP reset */ /* use microchip specific MTAP reset */
@ -270,9 +244,7 @@ static int mips_m4k_assert_reset(struct target *target)
mips_ejtag_drscan_8_out(ejtag_info, MCHP_ASERT_RST); mips_ejtag_drscan_8_out(ejtag_info, MCHP_ASERT_RST);
mips_ejtag_drscan_8_out(ejtag_info, MCHP_DE_ASSERT_RST); mips_ejtag_drscan_8_out(ejtag_info, MCHP_DE_ASSERT_RST);
mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP); mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);
} } else {
else
{
/* use ejtag reset - not supported by all cores */ /* use ejtag reset - not supported by all cores */
uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_PRRST | EJTAG_CTRL_PERRST; uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_PRRST | EJTAG_CTRL_PERRST;
LOG_DEBUG("Using EJTAG reset (PRRST) to reset processor..."); LOG_DEBUG("Using EJTAG reset (PRRST) to reset processor...");
@ -286,10 +258,9 @@ static int mips_m4k_assert_reset(struct target *target)
register_cache_invalidate(mips_m4k->mips32.core_cache); register_cache_invalidate(mips_m4k->mips32.core_cache);
if (target->reset_halt) if (target->reset_halt) {
{ int retval = target_halt(target);
int retval; if (retval != ERROR_OK)
if ((retval = target_halt(target)) != ERROR_OK)
return retval; return retval;
} }
@ -298,8 +269,7 @@ static int mips_m4k_assert_reset(struct target *target)
static int mips_m4k_deassert_reset(struct target *target) static int mips_m4k_deassert_reset(struct target *target)
{ {
LOG_DEBUG("target->state: %s", LOG_DEBUG("target->state: %s", target_state_name(target));
target_state_name(target));
/* deassert reset lines */ /* deassert reset lines */
jtag_add_reset(0, 0); jtag_add_reset(0, 0);
@ -340,41 +310,36 @@ static int mips_m4k_resume(struct target *target, int current,
struct breakpoint *breakpoint = NULL; struct breakpoint *breakpoint = NULL;
uint32_t resume_pc; uint32_t resume_pc;
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
LOG_WARNING("target not halted"); LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
} }
if (!debug_execution) if (!debug_execution) {
{
target_free_all_working_areas(target); target_free_all_working_areas(target);
mips_m4k_enable_breakpoints(target); mips_m4k_enable_breakpoints(target);
mips_m4k_enable_watchpoints(target); mips_m4k_enable_watchpoints(target);
} }
/* current = 1: continue on current pc, otherwise continue at <address> */ /* current = 1: continue on current pc, otherwise continue at <address> */
if (!current) if (!current) {
{
buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address); buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
mips32->core_cache->reg_list[MIPS32_PC].dirty = 1; mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
mips32->core_cache->reg_list[MIPS32_PC].valid = 1; mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
} }
if (ejtag_info->impcode & EJTAG_IMP_MIPS16) { if (ejtag_info->impcode & EJTAG_IMP_MIPS16)
buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1, mips32->isa_mode); buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 1, mips32->isa_mode);
}
resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32); resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32);
mips32_restore_context(target); mips32_restore_context(target);
/* the front-end may request us not to handle breakpoints */ /* the front-end may request us not to handle breakpoints */
if (handle_breakpoints) if (handle_breakpoints) {
{
/* Single step past breakpoint at current address */ /* Single step past breakpoint at current address */
if ((breakpoint = breakpoint_find(target, resume_pc))) breakpoint = breakpoint_find(target, resume_pc);
{ if (breakpoint) {
LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address); LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 "", breakpoint->address);
mips_m4k_unset_breakpoint(target, breakpoint); mips_m4k_unset_breakpoint(target, breakpoint);
mips_m4k_single_step_core(target); mips_m4k_single_step_core(target);
@ -392,14 +357,11 @@ static int mips_m4k_resume(struct target *target, int current,
/* registers are now invalid */ /* registers are now invalid */
register_cache_invalidate(mips32->core_cache); register_cache_invalidate(mips32->core_cache);
if (!debug_execution) if (!debug_execution) {
{
target->state = TARGET_RUNNING; target->state = TARGET_RUNNING;
target_call_event_callbacks(target, TARGET_EVENT_RESUMED); target_call_event_callbacks(target, TARGET_EVENT_RESUMED);
LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc); LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc);
} } else {
else
{
target->state = TARGET_DEBUG_RUNNING; target->state = TARGET_DEBUG_RUNNING;
target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc); LOG_DEBUG("target debug resumed at 0x%" PRIx32 "", resume_pc);
@ -416,15 +378,13 @@ static int mips_m4k_step(struct target *target, int current,
struct mips_ejtag *ejtag_info = &mips32->ejtag_info; struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
struct breakpoint *breakpoint = NULL; struct breakpoint *breakpoint = NULL;
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
LOG_WARNING("target not halted"); LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
} }
/* current = 1: continue on current pc, otherwise continue at <address> */ /* current = 1: continue on current pc, otherwise continue at <address> */
if (!current) if (!current) {
{
buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address); buf_set_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32, address);
mips32->core_cache->reg_list[MIPS32_PC].dirty = 1; mips32->core_cache->reg_list[MIPS32_PC].dirty = 1;
mips32->core_cache->reg_list[MIPS32_PC].valid = 1; mips32->core_cache->reg_list[MIPS32_PC].valid = 1;
@ -473,8 +433,7 @@ static void mips_m4k_enable_breakpoints(struct target *target)
struct breakpoint *breakpoint = target->breakpoints; struct breakpoint *breakpoint = target->breakpoints;
/* set any pending breakpoints */ /* set any pending breakpoints */
while (breakpoint) while (breakpoint) {
{
if (breakpoint->set == 0) if (breakpoint->set == 0)
mips_m4k_set_breakpoint(target, breakpoint); mips_m4k_set_breakpoint(target, breakpoint);
breakpoint = breakpoint->next; breakpoint = breakpoint->next;
@ -485,85 +444,72 @@ static int mips_m4k_set_breakpoint(struct target *target,
struct breakpoint *breakpoint) struct breakpoint *breakpoint)
{ {
struct mips32_common *mips32 = target_to_mips32(target); struct mips32_common *mips32 = target_to_mips32(target);
struct mips32_comparator * comparator_list = mips32->inst_break_list; struct mips32_comparator *comparator_list = mips32->inst_break_list;
int retval; int retval;
if (breakpoint->set) if (breakpoint->set) {
{
LOG_WARNING("breakpoint already set"); LOG_WARNING("breakpoint already set");
return ERROR_OK; return ERROR_OK;
} }
if (breakpoint->type == BKPT_HARD) if (breakpoint->type == BKPT_HARD) {
{
int bp_num = 0; int bp_num = 0;
while (comparator_list[bp_num].used && (bp_num < mips32->num_inst_bpoints)) while (comparator_list[bp_num].used && (bp_num < mips32->num_inst_bpoints))
bp_num++; bp_num++;
if (bp_num >= mips32->num_inst_bpoints) if (bp_num >= mips32->num_inst_bpoints) {
{
LOG_ERROR("Can not find free FP Comparator(bpid: %d)", LOG_ERROR("Can not find free FP Comparator(bpid: %d)",
breakpoint->unique_id ); breakpoint->unique_id);
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
} }
breakpoint->set = bp_num + 1; breakpoint->set = bp_num + 1;
comparator_list[bp_num].used = 1; comparator_list[bp_num].used = 1;
comparator_list[bp_num].bp_value = breakpoint->address; comparator_list[bp_num].bp_value = breakpoint->address;
target_write_u32(target, comparator_list[bp_num].reg_address, comparator_list[bp_num].bp_value); target_write_u32(target, comparator_list[bp_num].reg_address,
comparator_list[bp_num].bp_value);
target_write_u32(target, comparator_list[bp_num].reg_address + 0x08, 0x00000000); target_write_u32(target, comparator_list[bp_num].reg_address + 0x08, 0x00000000);
target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 1); target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 1);
LOG_DEBUG("bpid: %d, bp_num %i bp_value 0x%" PRIx32 "", LOG_DEBUG("bpid: %d, bp_num %i bp_value 0x%" PRIx32 "",
breakpoint->unique_id, breakpoint->unique_id,
bp_num, comparator_list[bp_num].bp_value); bp_num, comparator_list[bp_num].bp_value);
} } else if (breakpoint->type == BKPT_SOFT) {
else if (breakpoint->type == BKPT_SOFT) LOG_DEBUG("bpid: %d", breakpoint->unique_id);
{ if (breakpoint->length == 4) {
LOG_DEBUG("bpid: %d", breakpoint->unique_id );
if (breakpoint->length == 4)
{
uint32_t verify = 0xffffffff; uint32_t verify = 0xffffffff;
if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1,
breakpoint->orig_instr)) != ERROR_OK) breakpoint->orig_instr);
{ if (retval != ERROR_OK)
return retval; return retval;
} retval = target_write_u32(target, breakpoint->address, MIPS32_SDBBP);
if ((retval = target_write_u32(target, breakpoint->address, MIPS32_SDBBP)) != ERROR_OK) if (retval != ERROR_OK)
{
return retval; return retval;
}
if ((retval = target_read_u32(target, breakpoint->address, &verify)) != ERROR_OK) retval = target_read_u32(target, breakpoint->address, &verify);
{ if (retval != ERROR_OK)
return retval; return retval;
} if (verify != MIPS32_SDBBP) {
if (verify != MIPS32_SDBBP) LOG_ERROR("Unable to set 32bit breakpoint at address %08" PRIx32
{ " - check that memory is read/writable", breakpoint->address);
LOG_ERROR("Unable to set 32bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address);
return ERROR_OK; return ERROR_OK;
} }
} } else {
else
{
uint16_t verify = 0xffff; uint16_t verify = 0xffff;
if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1,
breakpoint->orig_instr)) != ERROR_OK) breakpoint->orig_instr);
{ if (retval != ERROR_OK)
return retval; return retval;
} retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP);
if ((retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP)) != ERROR_OK) if (retval != ERROR_OK)
{
return retval; return retval;
}
if ((retval = target_read_u16(target, breakpoint->address, &verify)) != ERROR_OK) retval = target_read_u16(target, breakpoint->address, &verify);
{ if (retval != ERROR_OK)
return retval; return retval;
} if (verify != MIPS16_SDBBP) {
if (verify != MIPS16_SDBBP) LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx32
{ " - check that memory is read/writable", breakpoint->address);
LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address);
return ERROR_OK; return ERROR_OK;
} }
} }
@ -582,43 +528,36 @@ static int mips_m4k_unset_breakpoint(struct target *target,
struct mips32_comparator *comparator_list = mips32->inst_break_list; struct mips32_comparator *comparator_list = mips32->inst_break_list;
int retval; int retval;
if (!breakpoint->set) if (!breakpoint->set) {
{
LOG_WARNING("breakpoint not set"); LOG_WARNING("breakpoint not set");
return ERROR_OK; return ERROR_OK;
} }
if (breakpoint->type == BKPT_HARD) if (breakpoint->type == BKPT_HARD) {
{
int bp_num = breakpoint->set - 1; int bp_num = breakpoint->set - 1;
if ((bp_num < 0) || (bp_num >= mips32->num_inst_bpoints)) if ((bp_num < 0) || (bp_num >= mips32->num_inst_bpoints)) {
{
LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %d)", LOG_DEBUG("Invalid FP Comparator number in breakpoint (bpid: %d)",
breakpoint->unique_id); breakpoint->unique_id);
return ERROR_OK; return ERROR_OK;
} }
LOG_DEBUG("bpid: %d - releasing hw: %d", LOG_DEBUG("bpid: %d - releasing hw: %d",
breakpoint->unique_id, breakpoint->unique_id,
bp_num ); bp_num);
comparator_list[bp_num].used = 0; comparator_list[bp_num].used = 0;
comparator_list[bp_num].bp_value = 0; comparator_list[bp_num].bp_value = 0;
target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 0); target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 0);
} } else {
else
{
/* restore original instruction (kept in target endianness) */ /* restore original instruction (kept in target endianness) */
LOG_DEBUG("bpid: %d", breakpoint->unique_id); LOG_DEBUG("bpid: %d", breakpoint->unique_id);
if (breakpoint->length == 4) if (breakpoint->length == 4) {
{
uint32_t current_instr; uint32_t current_instr;
/* check that user program has not modified breakpoint instruction */ /* check that user program has not modified breakpoint instruction */
if ((retval = target_read_memory(target, breakpoint->address, 4, 1, retval = target_read_memory(target, breakpoint->address, 4, 1,
(uint8_t*)&current_instr)) != ERROR_OK) (uint8_t *)&current_instr);
{ if (retval != ERROR_OK)
return retval; return retval;
}
/** /**
* target_read_memory() gets us data in _target_ endianess. * target_read_memory() gets us data in _target_ endianess.
@ -627,33 +566,26 @@ static int mips_m4k_unset_breakpoint(struct target *target,
*/ */
current_instr = target_buffer_get_u32(target, (uint8_t *)&current_instr); current_instr = target_buffer_get_u32(target, (uint8_t *)&current_instr);
if (current_instr == MIPS32_SDBBP) if (current_instr == MIPS32_SDBBP) {
{ retval = target_write_memory(target, breakpoint->address, 4, 1,
if ((retval = target_write_memory(target, breakpoint->address, 4, 1, breakpoint->orig_instr);
breakpoint->orig_instr)) != ERROR_OK) if (retval != ERROR_OK)
{
return retval; return retval;
}
} }
} } else {
else
{
uint16_t current_instr; uint16_t current_instr;
/* check that user program has not modified breakpoint instruction */ /* check that user program has not modified breakpoint instruction */
if ((retval = target_read_memory(target, breakpoint->address, 2, 1, retval = target_read_memory(target, breakpoint->address, 2, 1,
(uint8_t*)&current_instr)) != ERROR_OK) (uint8_t *)&current_instr);
{ if (retval != ERROR_OK)
return retval; return retval;
}
current_instr = target_buffer_get_u16(target, (uint8_t *)&current_instr); current_instr = target_buffer_get_u16(target, (uint8_t *)&current_instr);
if (current_instr == MIPS16_SDBBP) if (current_instr == MIPS16_SDBBP) {
{ retval = target_write_memory(target, breakpoint->address, 2, 1,
if ((retval = target_write_memory(target, breakpoint->address, 2, 1, breakpoint->orig_instr);
breakpoint->orig_instr)) != ERROR_OK) if (retval != ERROR_OK)
{
return retval; return retval;
}
} }
} }
} }
@ -666,10 +598,8 @@ static int mips_m4k_add_breakpoint(struct target *target, struct breakpoint *bre
{ {
struct mips32_common *mips32 = target_to_mips32(target); struct mips32_common *mips32 = target_to_mips32(target);
if (breakpoint->type == BKPT_HARD) if (breakpoint->type == BKPT_HARD) {
{ if (mips32->num_inst_bpoints_avail < 1) {
if (mips32->num_inst_bpoints_avail < 1)
{
LOG_INFO("no hardware breakpoint available"); LOG_INFO("no hardware breakpoint available");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
} }
@ -686,16 +616,13 @@ static int mips_m4k_remove_breakpoint(struct target *target,
/* get pointers to arch-specific information */ /* get pointers to arch-specific information */
struct mips32_common *mips32 = target_to_mips32(target); struct mips32_common *mips32 = target_to_mips32(target);
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
LOG_WARNING("target not halted"); LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
} }
if (breakpoint->set) if (breakpoint->set)
{
mips_m4k_unset_breakpoint(target, breakpoint); mips_m4k_unset_breakpoint(target, breakpoint);
}
if (breakpoint->type == BKPT_HARD) if (breakpoint->type == BKPT_HARD)
mips32->num_inst_bpoints_avail++; mips32->num_inst_bpoints_avail++;
@ -715,36 +642,31 @@ static int mips_m4k_set_watchpoint(struct target *target,
* condition evaluation * condition evaluation
*/ */
int enable = EJTAG_DBCn_NOSB | EJTAG_DBCn_NOLB | EJTAG_DBCn_BE | int enable = EJTAG_DBCn_NOSB | EJTAG_DBCn_NOLB | EJTAG_DBCn_BE |
(0xff << EJTAG_DBCn_BLM_SHIFT); (0xff << EJTAG_DBCn_BLM_SHIFT);
if (watchpoint->set) if (watchpoint->set) {
{
LOG_WARNING("watchpoint already set"); LOG_WARNING("watchpoint already set");
return ERROR_OK; return ERROR_OK;
} }
while(comparator_list[wp_num].used && (wp_num < mips32->num_data_bpoints)) while (comparator_list[wp_num].used && (wp_num < mips32->num_data_bpoints))
wp_num++; wp_num++;
if (wp_num >= mips32->num_data_bpoints) if (wp_num >= mips32->num_data_bpoints) {
{
LOG_ERROR("Can not find free FP Comparator"); LOG_ERROR("Can not find free FP Comparator");
return ERROR_FAIL; return ERROR_FAIL;
} }
if (watchpoint->length != 4) if (watchpoint->length != 4) {
{
LOG_ERROR("Only watchpoints of length 4 are supported"); LOG_ERROR("Only watchpoints of length 4 are supported");
return ERROR_TARGET_UNALIGNED_ACCESS; return ERROR_TARGET_UNALIGNED_ACCESS;
} }
if (watchpoint->address % 4) if (watchpoint->address % 4) {
{
LOG_ERROR("Watchpoints address should be word aligned"); LOG_ERROR("Watchpoints address should be word aligned");
return ERROR_TARGET_UNALIGNED_ACCESS; return ERROR_TARGET_UNALIGNED_ACCESS;
} }
switch (watchpoint->rw) switch (watchpoint->rw) {
{
case WPT_READ: case WPT_READ:
enable &= ~EJTAG_DBCn_NOLB; enable &= ~EJTAG_DBCn_NOLB;
break; break;
@ -778,15 +700,13 @@ static int mips_m4k_unset_watchpoint(struct target *target,
struct mips32_common *mips32 = target_to_mips32(target); struct mips32_common *mips32 = target_to_mips32(target);
struct mips32_comparator *comparator_list = mips32->data_break_list; struct mips32_comparator *comparator_list = mips32->data_break_list;
if (!watchpoint->set) if (!watchpoint->set) {
{
LOG_WARNING("watchpoint not set"); LOG_WARNING("watchpoint not set");
return ERROR_OK; return ERROR_OK;
} }
int wp_num = watchpoint->set - 1; int wp_num = watchpoint->set - 1;
if ((wp_num < 0) || (wp_num >= mips32->num_data_bpoints)) if ((wp_num < 0) || (wp_num >= mips32->num_data_bpoints)) {
{
LOG_DEBUG("Invalid FP Comparator number in watchpoint"); LOG_DEBUG("Invalid FP Comparator number in watchpoint");
return ERROR_OK; return ERROR_OK;
} }
@ -802,8 +722,7 @@ static int mips_m4k_add_watchpoint(struct target *target, struct watchpoint *wat
{ {
struct mips32_common *mips32 = target_to_mips32(target); struct mips32_common *mips32 = target_to_mips32(target);
if (mips32->num_data_bpoints_avail < 1) if (mips32->num_data_bpoints_avail < 1) {
{
LOG_INFO("no hardware watchpoints available"); LOG_INFO("no hardware watchpoints available");
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
} }
@ -820,16 +739,13 @@ static int mips_m4k_remove_watchpoint(struct target *target,
/* get pointers to arch-specific information */ /* get pointers to arch-specific information */
struct mips32_common *mips32 = target_to_mips32(target); struct mips32_common *mips32 = target_to_mips32(target);
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
LOG_WARNING("target not halted"); LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
} }
if (watchpoint->set) if (watchpoint->set)
{
mips_m4k_unset_watchpoint(target, watchpoint); mips_m4k_unset_watchpoint(target, watchpoint);
}
mips32->num_data_bpoints_avail++; mips32->num_data_bpoints_avail++;
@ -841,8 +757,7 @@ static void mips_m4k_enable_watchpoints(struct target *target)
struct watchpoint *watchpoint = target->watchpoints; struct watchpoint *watchpoint = target->watchpoints;
/* set any pending watchpoints */ /* set any pending watchpoints */
while (watchpoint) while (watchpoint) {
{
if (watchpoint->set == 0) if (watchpoint->set == 0)
mips_m4k_set_watchpoint(target, watchpoint); mips_m4k_set_watchpoint(target, watchpoint);
watchpoint = watchpoint->next; watchpoint = watchpoint->next;
@ -855,10 +770,10 @@ static int mips_m4k_read_memory(struct target *target, uint32_t address,
struct mips32_common *mips32 = target_to_mips32(target); struct mips32_common *mips32 = target_to_mips32(target);
struct mips_ejtag *ejtag_info = &mips32->ejtag_info; struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count); LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
address, size, count);
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
LOG_WARNING("target not halted"); LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
} }
@ -873,19 +788,14 @@ static int mips_m4k_read_memory(struct target *target, uint32_t address,
/* since we don't know if buffer is aligned, we allocate new mem that is always aligned */ /* since we don't know if buffer is aligned, we allocate new mem that is always aligned */
void *t = NULL; void *t = NULL;
if (size > 1) if (size > 1) {
{
t = malloc(count * size * sizeof(uint8_t)); t = malloc(count * size * sizeof(uint8_t));
if (t == NULL) if (t == NULL) {
{
LOG_ERROR("Out of memory"); LOG_ERROR("Out of memory");
return ERROR_FAIL; return ERROR_FAIL;
} }
} } else
else
{
t = buffer; t = buffer;
}
/* if noDMA off, use DMAACC mode for memory read */ /* if noDMA off, use DMAACC mode for memory read */
int retval; int retval;
@ -896,15 +806,13 @@ static int mips_m4k_read_memory(struct target *target, uint32_t address,
/* mips32_..._read_mem with size 4/2 returns uint32_t/uint16_t in host */ /* mips32_..._read_mem with size 4/2 returns uint32_t/uint16_t in host */
/* endianness, but byte array should represent target endianness */ /* endianness, but byte array should represent target endianness */
if (ERROR_OK == retval) if (ERROR_OK == retval) {
{ switch (size) {
switch(size)
{
case 4: case 4:
target_buffer_set_u32_array(target,buffer,count,t); target_buffer_set_u32_array(target, buffer, count, t);
break; break;
case 2: case 2:
target_buffer_set_u16_array(target,buffer,count,t); target_buffer_set_u16_array(target, buffer, count, t);
break; break;
} }
} }
@ -924,8 +832,7 @@ static int mips_m4k_write_memory(struct target *target, uint32_t address,
LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "",
address, size, count); address, size, count);
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
LOG_WARNING("target not halted"); LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
} }
@ -939,24 +846,21 @@ static int mips_m4k_write_memory(struct target *target, uint32_t address,
/** correct endianess if we have word or hword access */ /** correct endianess if we have word or hword access */
void *t = NULL; void *t = NULL;
if (size > 1) if (size > 1) {
{
/* mips32_..._write_mem with size 4/2 requires uint32_t/uint16_t in host */ /* mips32_..._write_mem with size 4/2 requires uint32_t/uint16_t in host */
/* endianness, but byte array represents target endianness */ /* endianness, but byte array represents target endianness */
t = malloc(count * size * sizeof(uint8_t)); t = malloc(count * size * sizeof(uint8_t));
if (t == NULL) if (t == NULL) {
{
LOG_ERROR("Out of memory"); LOG_ERROR("Out of memory");
return ERROR_FAIL; return ERROR_FAIL;
} }
switch(size) switch (size) {
{
case 4: case 4:
target_buffer_get_u32_array(target,buffer,count,(uint32_t*)t); target_buffer_get_u32_array(target, buffer, count, (uint32_t *)t);
break; break;
case 2: case 2:
target_buffer_get_u16_array(target,buffer,count,(uint16_t*)t); target_buffer_get_u16_array(target, buffer, count, (uint16_t *)t);
break; break;
} }
buffer = t; buffer = t;
@ -1016,15 +920,13 @@ static int mips_m4k_examine(struct target *target)
struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info; struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info;
uint32_t idcode = 0; uint32_t idcode = 0;
if (!target_was_examined(target)) if (!target_was_examined(target)) {
{
retval = mips_ejtag_get_idcode(ejtag_info, &idcode); retval = mips_ejtag_get_idcode(ejtag_info, &idcode);
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
ejtag_info->idcode = idcode; ejtag_info->idcode = idcode;
if (((idcode >> 1) & 0x7FF) == 0x29) if (((idcode >> 1) & 0x7FF) == 0x29) {
{
/* we are using a pic32mx so select ejtag port /* we are using a pic32mx so select ejtag port
* as it is not selected by default */ * as it is not selected by default */
mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP); mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);
@ -1034,10 +936,12 @@ static int mips_m4k_examine(struct target *target)
} }
/* init rest of ejtag interface */ /* init rest of ejtag interface */
if ((retval = mips_ejtag_init(ejtag_info)) != ERROR_OK) retval = mips_ejtag_init(ejtag_info);
if (retval != ERROR_OK)
return retval; return retval;
if ((retval = mips32_examine(target)) != ERROR_OK) retval = mips32_examine(target);
if (retval != ERROR_OK)
return retval; return retval;
return ERROR_OK; return ERROR_OK;
@ -1053,8 +957,7 @@ static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
LOG_DEBUG("address: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, count); LOG_DEBUG("address: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, count);
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
LOG_WARNING("target not halted"); LOG_WARNING("target not halted");
return ERROR_TARGET_NOT_HALTED; return ERROR_TARGET_NOT_HALTED;
} }
@ -1063,8 +966,7 @@ static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
if (address & 0x3u) if (address & 0x3u)
return ERROR_TARGET_UNALIGNED_ACCESS; return ERROR_TARGET_UNALIGNED_ACCESS;
if (mips32->fast_data_area == NULL) if (mips32->fast_data_area == NULL) {
{
/* Get memory for block write handler /* Get memory for block write handler
* we preserve this area between calls and gain a speed increase * we preserve this area between calls and gain a speed increase
* of about 3kb/sec when writing flash * of about 3kb/sec when writing flash
@ -1072,8 +974,7 @@ static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
retval = target_alloc_working_area(target, retval = target_alloc_working_area(target,
MIPS32_FASTDATA_HANDLER_SIZE, MIPS32_FASTDATA_HANDLER_SIZE,
&mips32->fast_data_area); &mips32->fast_data_area);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
LOG_WARNING("No working area available, falling back to non-bulk write"); LOG_WARNING("No working area available, falling back to non-bulk write");
return mips_m4k_write_memory(target, address, 4, count, buffer); return mips_m4k_write_memory(target, address, 4, count, buffer);
} }
@ -1086,13 +987,12 @@ static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
/* but byte array represents target endianness */ /* but byte array represents target endianness */
uint32_t *t = NULL; uint32_t *t = NULL;
t = malloc(count * sizeof(uint32_t)); t = malloc(count * sizeof(uint32_t));
if (t == NULL) if (t == NULL) {
{
LOG_ERROR("Out of memory"); LOG_ERROR("Out of memory");
return ERROR_FAIL; return ERROR_FAIL;
} }
target_buffer_get_u32_array(target,buffer,count,t); target_buffer_get_u32_array(target, buffer, count, t);
retval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, write_t, address, retval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, write_t, address,
count, t); count, t);
@ -1100,8 +1000,7 @@ static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address,
if (t != NULL) if (t != NULL)
free(t); free(t);
if (retval != ERROR_OK) if (retval != ERROR_OK) {
{
/* FASTDATA access failed, try normal memory write */ /* FASTDATA access failed, try normal memory write */
LOG_DEBUG("Fastdata access Failed, falling back to non-bulk write"); LOG_DEBUG("Fastdata access Failed, falling back to non-bulk write");
retval = mips_m4k_write_memory(target, address, 4, count, buffer); retval = mips_m4k_write_memory(target, address, 4, count, buffer);
@ -1131,48 +1030,40 @@ COMMAND_HANDLER(mips_m4k_handle_cp0_command)
if (retval != ERROR_OK) if (retval != ERROR_OK)
return retval; return retval;
if (target->state != TARGET_HALTED) if (target->state != TARGET_HALTED) {
{
command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME); command_print(CMD_CTX, "target must be stopped for \"%s\" command", CMD_NAME);
return ERROR_OK; return ERROR_OK;
} }
/* two or more argument, access a single register/select (write if third argument is given) */ /* two or more argument, access a single register/select (write if third argument is given) */
if (CMD_ARGC < 2) if (CMD_ARGC < 2)
{ return ERROR_COMMAND_SYNTAX_ERROR;
return ERROR_COMMAND_SYNTAX_ERROR; else {
}
else
{
uint32_t cp0_reg, cp0_sel; uint32_t cp0_reg, cp0_sel;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg);
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel);
if (CMD_ARGC == 2) if (CMD_ARGC == 2) {
{
uint32_t value; uint32_t value;
if ((retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel)) != ERROR_OK) retval = mips32_cp0_read(ejtag_info, &value, cp0_reg, cp0_sel);
{ if (retval != ERROR_OK) {
command_print(CMD_CTX, command_print(CMD_CTX,
"couldn't access reg %" PRIi32, "couldn't access reg %" PRIi32,
cp0_reg); cp0_reg);
return ERROR_OK; return ERROR_OK;
} }
if ((retval = jtag_execute_queue()) != ERROR_OK) retval = jtag_execute_queue();
{ if (retval != ERROR_OK)
return retval; return retval;
}
command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32, command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32,
cp0_reg, cp0_sel, value); cp0_reg, cp0_sel, value);
} } else if (CMD_ARGC == 3) {
else if (CMD_ARGC == 3)
{
uint32_t value; uint32_t value;
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value); COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], value);
if ((retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel)) != ERROR_OK) retval = mips32_cp0_write(ejtag_info, value, cp0_reg, cp0_sel);
{ if (retval != ERROR_OK) {
command_print(CMD_CTX, command_print(CMD_CTX,
"couldn't access cp0 reg %" PRIi32 ", select %" PRIi32, "couldn't access cp0 reg %" PRIi32 ", select %" PRIi32,
cp0_reg, cp0_sel); cp0_reg, cp0_sel);
@ -1211,8 +1102,7 @@ const struct command_registration mips_m4k_command_handlers[] = {
COMMAND_REGISTRATION_DONE COMMAND_REGISTRATION_DONE
}; };
struct target_type mips_m4k_target = struct target_type mips_m4k_target = {
{
.name = "mips_m4k", .name = "mips_m4k",
.poll = mips_m4k_poll, .poll = mips_m4k_poll,

View File

@ -32,8 +32,7 @@ struct target;
#define MIPSM4K_COMMON_MAGIC 0xB321B321 #define MIPSM4K_COMMON_MAGIC 0xB321B321
struct mips_m4k_common struct mips_m4k_common {
{
uint32_t common_magic; uint32_t common_magic;
bool is_pic32mx; bool is_pic32mx;
struct mips32_common mips32; struct mips32_common mips32;

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -30,7 +31,6 @@
* https://lists.berlios.de/pipermail/openocd-development/2007-September/000336.html * https://lists.berlios.de/pipermail/openocd-development/2007-September/000336.html
*/ */
static int oocd_trace_read_reg(struct oocd_trace *oocd_trace, int reg, uint32_t *value) static int oocd_trace_read_reg(struct oocd_trace *oocd_trace, int reg, uint32_t *value)
{ {
size_t bytes_written, bytes_read, bytes_to_read; size_t bytes_written, bytes_read, bytes_to_read;
@ -40,9 +40,8 @@ static int oocd_trace_read_reg(struct oocd_trace *oocd_trace, int reg, uint32_t
bytes_written = write(oocd_trace->tty_fd, &cmd, 1); bytes_written = write(oocd_trace->tty_fd, &cmd, 1);
bytes_to_read = 4; bytes_to_read = 4;
while (bytes_to_read > 0) while (bytes_to_read > 0) {
{ bytes_read = read(oocd_trace->tty_fd, ((uint8_t *)value) + 4 - bytes_to_read, bytes_to_read);
bytes_read = read(oocd_trace->tty_fd, ((uint8_t*)value) + 4 - bytes_to_read, bytes_to_read);
bytes_to_read -= bytes_read; bytes_to_read -= bytes_read;
} }
@ -81,13 +80,11 @@ static int oocd_trace_read_memory(struct oocd_trace *oocd_trace, uint8_t *data,
bytes_written = write(oocd_trace->tty_fd, &cmd, 1); bytes_written = write(oocd_trace->tty_fd, &cmd, 1);
bytes_to_read = size * 16; bytes_to_read = size * 16;
while (bytes_to_read > 0) while (bytes_to_read > 0) {
{ bytes_read = read(oocd_trace->tty_fd,
if ((bytes_read = read(oocd_trace->tty_fd, ((uint8_t *)data) + (size * 16) - bytes_to_read, bytes_to_read);
((uint8_t*)data) + (size * 16) - bytes_to_read, bytes_to_read)) < 0) if (bytes_read < 0)
{
LOG_DEBUG("read() returned %zi (%s)", bytes_read, strerror(errno)); LOG_DEBUG("read() returned %zi (%s)", bytes_read, strerror(errno));
}
else else
bytes_to_read -= bytes_read; bytes_to_read -= bytes_read;
} }
@ -103,8 +100,7 @@ static int oocd_trace_init(struct etm_context *etm_ctx)
oocd_trace->tty_fd = open(oocd_trace->tty, O_RDWR | O_NOCTTY | O_NONBLOCK); oocd_trace->tty_fd = open(oocd_trace->tty, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (oocd_trace->tty_fd < 0) if (oocd_trace->tty_fd < 0) {
{
LOG_ERROR("can't open tty"); LOG_ERROR("can't open tty");
return ERROR_ETM_CAPTURE_INIT_FAILED; return ERROR_ETM_CAPTURE_INIT_FAILED;
} }
@ -134,10 +130,11 @@ static int oocd_trace_init(struct etm_context *etm_ctx)
/* occasionally one bogus character is left in the input buffer /* occasionally one bogus character is left in the input buffer
* read up any leftover characters to ensure communication is in sync */ * read up any leftover characters to ensure communication is in sync */
while ((bytes_read = read(oocd_trace->tty_fd, trash, sizeof(trash))) > 0) do {
{ bytes_read = read(oocd_trace->tty_fd, trash, sizeof(trash));
LOG_DEBUG("%zi bytes read", bytes_read); if (bytes_read)
}; LOG_DEBUG("%zi bytes read", bytes_read);
} while (bytes_read > 0);
return ERROR_OK; return ERROR_OK;
} }
@ -151,11 +148,8 @@ static trace_status_t oocd_trace_status(struct etm_context *etm_ctx)
/* if tracing is currently idle, return this information */ /* if tracing is currently idle, return this information */
if (etm_ctx->capture_status == TRACE_IDLE) if (etm_ctx->capture_status == TRACE_IDLE)
{
return etm_ctx->capture_status; return etm_ctx->capture_status;
} else if (etm_ctx->capture_status & TRACE_RUNNING) {
else if (etm_ctx->capture_status & TRACE_RUNNING)
{
/* check Full bit to identify an overflow */ /* check Full bit to identify an overflow */
if (status & 0x4) if (status & 0x4)
etm_ctx->capture_status |= TRACE_OVERFLOWED; etm_ctx->capture_status |= TRACE_OVERFLOWED;
@ -164,8 +158,7 @@ static trace_status_t oocd_trace_status(struct etm_context *etm_ctx)
if (status & 0x2) if (status & 0x2)
etm_ctx->capture_status |= TRACE_TRIGGERED; etm_ctx->capture_status |= TRACE_TRIGGERED;
if (status & 0x1) if (status & 0x1) {
{
etm_ctx->capture_status &= ~TRACE_RUNNING; etm_ctx->capture_status &= ~TRACE_RUNNING;
etm_ctx->capture_status |= TRACE_COMPLETED; etm_ctx->capture_status |= TRACE_COMPLETED;
} }
@ -202,26 +195,20 @@ static int oocd_trace_read_trace(struct etm_context *etm_ctx)
oocd_trace_read_memory(oocd_trace, trace_data, first_frame, num_frames); oocd_trace_read_memory(oocd_trace, trace_data, first_frame, num_frames);
if (etm_ctx->trace_depth > 0) if (etm_ctx->trace_depth > 0)
{
free(etm_ctx->trace_data); free(etm_ctx->trace_data);
}
etm_ctx->trace_depth = num_frames * 16; etm_ctx->trace_depth = num_frames * 16;
etm_ctx->trace_data = malloc(sizeof(struct etmv1_trace_data) * etm_ctx->trace_depth); etm_ctx->trace_data = malloc(sizeof(struct etmv1_trace_data) * etm_ctx->trace_depth);
for (i = 0; i < num_frames * 16; i++) for (i = 0; i < num_frames * 16; i++) {
{
etm_ctx->trace_data[i].pipestat = (trace_data[i] & 0x7); etm_ctx->trace_data[i].pipestat = (trace_data[i] & 0x7);
etm_ctx->trace_data[i].packet = (trace_data[i] & 0x78) >> 3; etm_ctx->trace_data[i].packet = (trace_data[i] & 0x78) >> 3;
etm_ctx->trace_data[i].flags = 0; etm_ctx->trace_data[i].flags = 0;
if ((trace_data[i] & 0x80) >> 7) if ((trace_data[i] & 0x80) >> 7)
{
etm_ctx->trace_data[i].flags |= ETMV1_TRACESYNC_CYCLE; etm_ctx->trace_data[i].flags |= ETMV1_TRACESYNC_CYCLE;
}
if (etm_ctx->trace_data[i].pipestat == STAT_TR) if (etm_ctx->trace_data[i].pipestat == STAT_TR) {
{
etm_ctx->trace_data[i].pipestat = etm_ctx->trace_data[i].packet & 0x7; etm_ctx->trace_data[i].pipestat = etm_ctx->trace_data[i].packet & 0x7;
etm_ctx->trace_data[i].flags |= ETMV1_TRIGGER_CYCLE; etm_ctx->trace_data[i].flags |= ETMV1_TRIGGER_CYCLE;
} }
@ -239,16 +226,13 @@ static int oocd_trace_start_capture(struct etm_context *etm_ctx)
uint32_t trigger_count; uint32_t trigger_count;
if (((etm_ctx->control & ETM_PORT_MODE_MASK) != ETM_PORT_NORMAL) if (((etm_ctx->control & ETM_PORT_MODE_MASK) != ETM_PORT_NORMAL)
|| ((etm_ctx->control & ETM_PORT_WIDTH_MASK) != ETM_PORT_4BIT)) || ((etm_ctx->control & ETM_PORT_WIDTH_MASK) != ETM_PORT_4BIT)) {
{
LOG_DEBUG("OpenOCD + trace only supports normal 4-bit ETM mode"); LOG_DEBUG("OpenOCD + trace only supports normal 4-bit ETM mode");
return ERROR_ETM_PORTMODE_NOT_SUPPORTED; return ERROR_ETM_PORTMODE_NOT_SUPPORTED;
} }
if ((etm_ctx->control & ETM_PORT_CLOCK_MASK) == ETM_PORT_HALF_CLOCK) if ((etm_ctx->control & ETM_PORT_CLOCK_MASK) == ETM_PORT_HALF_CLOCK)
{
control |= 0x2; /* half rate clock, capture at twice the clock rate */ control |= 0x2; /* half rate clock, capture at twice the clock rate */
}
/* OpenOCD + trace holds up to 16 million samples, /* OpenOCD + trace holds up to 16 million samples,
* but trigger counts is set in multiples of 16 */ * but trigger counts is set in multiples of 16 */
@ -283,20 +267,16 @@ COMMAND_HANDLER(handle_oocd_trace_config_command)
struct arm *arm; struct arm *arm;
if (CMD_ARGC != 2) if (CMD_ARGC != 2)
{
return ERROR_COMMAND_SYNTAX_ERROR; return ERROR_COMMAND_SYNTAX_ERROR;
}
target = get_current_target(CMD_CTX); target = get_current_target(CMD_CTX);
arm = target_to_arm(target); arm = target_to_arm(target);
if (!is_arm(arm)) if (!is_arm(arm)) {
{
command_print(CMD_CTX, "current target isn't an ARM"); command_print(CMD_CTX, "current target isn't an ARM");
return ERROR_FAIL; return ERROR_FAIL;
} }
if (arm->etm) if (arm->etm) {
{
struct oocd_trace *oocd_trace = malloc(sizeof(struct oocd_trace)); struct oocd_trace *oocd_trace = malloc(sizeof(struct oocd_trace));
arm->etm->capture_driver_priv = oocd_trace; arm->etm->capture_driver_priv = oocd_trace;
@ -304,11 +284,8 @@ COMMAND_HANDLER(handle_oocd_trace_config_command)
/* copy name of TTY device used to communicate with OpenOCD + trace */ /* copy name of TTY device used to communicate with OpenOCD + trace */
oocd_trace->tty = strndup(CMD_ARGV[1], 256); oocd_trace->tty = strndup(CMD_ARGV[1], 256);
} } else
else
{
LOG_ERROR("target has no ETM defined, OpenOCD + trace left unconfigured"); LOG_ERROR("target has no ETM defined, OpenOCD + trace left unconfigured");
}
return ERROR_OK; return ERROR_OK;
} }
@ -323,25 +300,22 @@ COMMAND_HANDLER(handle_oocd_trace_status_command)
target = get_current_target(CMD_CTX); target = get_current_target(CMD_CTX);
arm = target_to_arm(target); arm = target_to_arm(target);
if (!is_arm(arm)) if (!is_arm(arm)) {
{
command_print(CMD_CTX, "current target isn't an ARM"); command_print(CMD_CTX, "current target isn't an ARM");
return ERROR_FAIL; return ERROR_FAIL;
} }
if (!arm->etm) if (!arm->etm) {
{
command_print(CMD_CTX, "current target doesn't have an ETM configured"); command_print(CMD_CTX, "current target doesn't have an ETM configured");
return ERROR_FAIL; return ERROR_FAIL;
} }
if (strcmp(arm->etm->capture_driver->name, "oocd_trace") != 0) if (strcmp(arm->etm->capture_driver->name, "oocd_trace") != 0) {
{
command_print(CMD_CTX, "current target's ETM capture driver isn't 'oocd_trace'"); command_print(CMD_CTX, "current target's ETM capture driver isn't 'oocd_trace'");
return ERROR_FAIL; return ERROR_FAIL;
} }
oocd_trace = (struct oocd_trace*)arm->etm->capture_driver_priv; oocd_trace = (struct oocd_trace *)arm->etm->capture_driver_priv;
oocd_trace_read_reg(oocd_trace, OOCD_TRACE_STATUS, &status); oocd_trace_read_reg(oocd_trace, OOCD_TRACE_STATUS, &status);
@ -364,25 +338,22 @@ COMMAND_HANDLER(handle_oocd_trace_resync_command)
target = get_current_target(CMD_CTX); target = get_current_target(CMD_CTX);
arm = target_to_arm(target); arm = target_to_arm(target);
if (!is_arm(arm)) if (!is_arm(arm)) {
{
command_print(CMD_CTX, "current target isn't an ARM"); command_print(CMD_CTX, "current target isn't an ARM");
return ERROR_FAIL; return ERROR_FAIL;
} }
if (!arm->etm) if (!arm->etm) {
{
command_print(CMD_CTX, "current target doesn't have an ETM configured"); command_print(CMD_CTX, "current target doesn't have an ETM configured");
return ERROR_FAIL; return ERROR_FAIL;
} }
if (strcmp(arm->etm->capture_driver->name, "oocd_trace") != 0) if (strcmp(arm->etm->capture_driver->name, "oocd_trace") != 0) {
{
command_print(CMD_CTX, "current target's ETM capture driver isn't 'oocd_trace'"); command_print(CMD_CTX, "current target's ETM capture driver isn't 'oocd_trace'");
return ERROR_FAIL; return ERROR_FAIL;
} }
oocd_trace = (struct oocd_trace*)arm->etm->capture_driver_priv; oocd_trace = (struct oocd_trace *)arm->etm->capture_driver_priv;
cmd_array[0] = 0xf0; cmd_array[0] = 0xf0;
@ -428,8 +399,7 @@ static const struct command_registration oocd_trace_command_handlers[] = {
COMMAND_REGISTRATION_DONE COMMAND_REGISTRATION_DONE
}; };
struct etm_capture_driver oocd_trace_capture_driver = struct etm_capture_driver oocd_trace_capture_driver = {
{
.name = "oocd_trace", .name = "oocd_trace",
.commands = oocd_trace_command_handlers, .commands = oocd_trace_command_handlers,
.init = oocd_trace_init, .init = oocd_trace_init,
@ -438,5 +408,3 @@ struct etm_capture_driver oocd_trace_capture_driver =
.stop_capture = oocd_trace_stop_capture, .stop_capture = oocd_trace_stop_capture,
.read_trace = oocd_trace_read_trace, .read_trace = oocd_trace_read_trace,
}; };

View File

@ -17,14 +17,14 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef OOCD_TRACE_H #ifndef OOCD_TRACE_H
#define OOCD_TRACE_H #define OOCD_TRACE_H
#include <termios.h> #include <termios.h>
/* registers */ /* registers */
enum enum {
{
OOCD_TRACE_ID = 0x7, OOCD_TRACE_ID = 0x7,
OOCD_TRACE_ADDRESS = 0x0, OOCD_TRACE_ADDRESS = 0x0,
OOCD_TRACE_TRIGGER_COUNTER = 0x01, OOCD_TRACE_TRIGGER_COUNTER = 0x01,
@ -34,8 +34,7 @@ enum
}; };
/* commands */ /* commands */
enum enum {
{
OOCD_TRACE_NOP = 0x0, OOCD_TRACE_NOP = 0x0,
OOCD_TRACE_READ_REG = 0x10, OOCD_TRACE_READ_REG = 0x10,
OOCD_TRACE_WRITE_REG = 0x18, OOCD_TRACE_WRITE_REG = 0x18,
@ -44,8 +43,7 @@ enum
OOCD_TRACE_RESYNC = 0xf0, OOCD_TRACE_RESYNC = 0xf0,
}; };
struct oocd_trace struct oocd_trace {
{
struct etm_context *etm_ctx; struct etm_context *etm_ctx;
char *tty; char *tty;
int tty_fd; int tty_fd;

View File

@ -20,6 +20,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -38,16 +39,14 @@
* may be separate registers associated with debug or trace modules. * may be separate registers associated with debug or trace modules.
*/ */
struct reg* register_get_by_name(struct reg_cache *first, struct reg *register_get_by_name(struct reg_cache *first,
const char *name, bool search_all) const char *name, bool search_all)
{ {
unsigned i; unsigned i;
struct reg_cache *cache = first; struct reg_cache *cache = first;
while (cache) while (cache) {
{ for (i = 0; i < cache->num_regs; i++) {
for (i = 0; i < cache->num_regs; i++)
{
if (strcmp(cache->reg_list[i].name, name) == 0) if (strcmp(cache->reg_list[i].name, name) == 0)
return &(cache->reg_list[i]); return &(cache->reg_list[i]);
} }
@ -61,7 +60,7 @@ struct reg* register_get_by_name(struct reg_cache *first,
return NULL; return NULL;
} }
struct reg_cache** register_get_last_cache_p(struct reg_cache **first) struct reg_cache **register_get_last_cache_p(struct reg_cache **first)
{ {
struct reg_cache **cache_p = first; struct reg_cache **cache_p = first;

View File

@ -20,13 +20,13 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef REGISTER_H #ifndef REGISTER_H
#define REGISTER_H #define REGISTER_H
struct target; struct target;
struct reg struct reg {
{
const char *name; const char *name;
void *value; void *value;
bool dirty; bool dirty;
@ -36,23 +36,21 @@ struct reg
const struct reg_arch_type *type; const struct reg_arch_type *type;
}; };
struct reg_cache struct reg_cache {
{
const char *name; const char *name;
struct reg_cache *next; struct reg_cache *next;
struct reg *reg_list; struct reg *reg_list;
unsigned num_regs; unsigned num_regs;
}; };
struct reg_arch_type struct reg_arch_type {
{
int (*get)(struct reg *reg); int (*get)(struct reg *reg);
int (*set)(struct reg *reg, uint8_t *buf); int (*set)(struct reg *reg, uint8_t *buf);
}; };
struct reg* register_get_by_name(struct reg_cache *first, struct reg *register_get_by_name(struct reg_cache *first,
const char *name, bool search_all); const char *name, bool search_all);
struct reg_cache** register_get_last_cache_p(struct reg_cache **first); struct reg_cache **register_get_last_cache_p(struct reg_cache **first);
void register_cache_invalidate(struct reg_cache *cache); void register_cache_invalidate(struct reg_cache *cache);
void register_init_dummy(struct reg *reg); void register_init_dummy(struct reg *reg);

View File

@ -17,6 +17,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -29,7 +30,6 @@
#include "server/gdb_server.h" #include "server/gdb_server.h"
#include "smp.h" #include "smp.h"
/* implementation of new packet in gdb interface for smp feature */ /* implementation of new packet in gdb interface for smp feature */
/* */ /* */
/* j : smp status request */ /* j : smp status request */
@ -53,9 +53,8 @@
/* Another way to test this packet is the usage of maintenance packet */ /* Another way to test this packet is the usage of maintenance packet */
/* maint packet Jc01 */ /* maint packet Jc01 */
/* maint packet jc */ /* maint packet jc */
static const char DIGITS[16] = "0123456789abcdef";
static const char DIGITS[16] = "0123456789abcdef";
/* packet j :smp status request */ /* packet j :smp status request */
int gdb_read_smp_packet(struct connection *connection, int gdb_read_smp_packet(struct connection *connection,
@ -66,15 +65,12 @@ int gdb_read_smp_packet(struct connection *connection,
uint8_t *buffer; uint8_t *buffer;
char *hex_buffer; char *hex_buffer;
int retval = ERROR_OK; int retval = ERROR_OK;
if (target->smp) if (target->smp) {
{ if (strstr(packet, "jc")) {
if (strstr(packet, "jc"))
{
hex_buffer = malloc(len * 2 + 1); hex_buffer = malloc(len * 2 + 1);
buffer = (uint8_t *)&target->gdb_service->core[0]; buffer = (uint8_t *)&target->gdb_service->core[0];
uint32_t i; uint32_t i;
for (i = 0; i < 4; i++) for (i = 0; i < 4; i++) {
{
uint8_t t = buffer[i]; uint8_t t = buffer[i];
hex_buffer[2 * i] = DIGITS[(t >> 4) & 0xf]; hex_buffer[2 * i] = DIGITS[(t >> 4) & 0xf];
hex_buffer[2 * i + 1] = DIGITS[t & 0xf]; hex_buffer[2 * i + 1] = DIGITS[t & 0xf];
@ -84,9 +80,8 @@ int gdb_read_smp_packet(struct connection *connection,
free(hex_buffer); free(hex_buffer);
} }
} } else
else retval = gdb_put_packet(connection, "E01", 3);
retval = gdb_put_packet(connection,"E01",3);
return retval; return retval;
} }
@ -100,20 +95,15 @@ int gdb_write_smp_packet(struct connection *connection,
int retval = ERROR_OK; int retval = ERROR_OK;
/* skip command character */ /* skip command character */
if (target->smp) if (target->smp) {
{ if (strstr(packet, "Jc")) {
if (strstr(packet, "Jc")) packet += 2;
{
packet+=2;
coreid = strtoul(packet, &separator, 16); coreid = strtoul(packet, &separator, 16);
target->gdb_service->core[1] = coreid; target->gdb_service->core[1] = coreid;
retval = gdb_put_packet(connection, "OK", 2); retval = gdb_put_packet(connection, "OK", 2);
} }
} } else
else retval = gdb_put_packet(connection, "E01", 3);
{
retval = gdb_put_packet(connection,"E01",3);
}
return retval; return retval;
} }

View File

@ -17,7 +17,9 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#include "server/server.h" #include "server/server.h"
int gdb_read_smp_packet(struct connection *connection, int gdb_read_smp_packet(struct connection *connection,
char *packet, int packet_size); char *packet, int packet_size);
int gdb_write_smp_packet(struct connection *connection, int gdb_write_smp_packet(struct connection *connection,

View File

@ -20,6 +20,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifdef HAVE_CONFIG_H #ifdef HAVE_CONFIG_H
#include "config.h" #include "config.h"
#endif #endif
@ -42,8 +43,8 @@ static inline struct stlink_interface_s *target_to_stlink(struct target *target)
} }
static int stm32_stlink_load_core_reg_u32(struct target *target, static int stm32_stlink_load_core_reg_u32(struct target *target,
enum armv7m_regtype type, enum armv7m_regtype type,
uint32_t num, uint32_t *value) uint32_t num, uint32_t *value)
{ {
int retval; int retval;
struct stlink_interface_s *stlink_if = target_to_stlink(target); struct stlink_interface_s *stlink_if = target_to_stlink(target);
@ -57,8 +58,7 @@ static int stm32_stlink_load_core_reg_u32(struct target *target,
switch (num) { switch (num) {
case 0 ... 18: case 0 ... 18:
/* read a normal core register */ /* read a normal core register */
retval = retval = stlink_if->layout->api->read_reg(stlink_if->fd, num, value);
stlink_if->layout->api->read_reg(stlink_if->fd, num, value);
if (retval != ERROR_OK) { if (retval != ERROR_OK) {
LOG_ERROR("JTAG failure %i", retval); LOG_ERROR("JTAG failure %i", retval);
@ -76,8 +76,7 @@ static int stm32_stlink_load_core_reg_u32(struct target *target,
* in one Debug Core register. So say r0 and r2 docs; * in one Debug Core register. So say r0 and r2 docs;
* it was removed from r1 docs, but still works. * it was removed from r1 docs, but still works.
*/ */
retval = retval = stlink_if->layout->api->read_reg(stlink_if->fd, 20, value);
stlink_if->layout->api->read_reg(stlink_if->fd, 20, value);
switch (num) { switch (num) {
case ARMV7M_PRIMASK: case ARMV7M_PRIMASK:
@ -109,8 +108,8 @@ static int stm32_stlink_load_core_reg_u32(struct target *target,
} }
static int stm32_stlink_store_core_reg_u32(struct target *target, static int stm32_stlink_store_core_reg_u32(struct target *target,
enum armv7m_regtype type, enum armv7m_regtype type,
uint32_t num, uint32_t value) uint32_t num, uint32_t value)
{ {
int retval; int retval;
uint32_t reg; uint32_t reg;
@ -231,7 +230,7 @@ static int stm32_stlink_init_target(struct command_context *cmd_ctx,
} }
static int stm32_stlink_target_create(struct target *target, static int stm32_stlink_target_create(struct target *target,
Jim_Interp *interp) Jim_Interp *interp)
{ {
LOG_DEBUG("%s", __func__); LOG_DEBUG("%s", __func__);
@ -467,10 +466,8 @@ static int stm32_stlink_halt(struct target *target)
return ERROR_OK; return ERROR_OK;
} }
if (target->state == TARGET_UNKNOWN) { if (target->state == TARGET_UNKNOWN)
LOG_WARNING LOG_WARNING("target was in unknown state when halt was requested");
("target was in unknown state when halt was requested");
}
res = stlink_if->layout->api->halt(stlink_if->fd); res = stlink_if->layout->api->halt(stlink_if->fd);
@ -483,8 +480,8 @@ static int stm32_stlink_halt(struct target *target)
} }
static int stm32_stlink_resume(struct target *target, int current, static int stm32_stlink_resume(struct target *target, int current,
uint32_t address, int handle_breakpoints, uint32_t address, int handle_breakpoints,
int debug_execution) int debug_execution)
{ {
int res; int res;
struct stlink_interface_s *stlink_if = target_to_stlink(target); struct stlink_interface_s *stlink_if = target_to_stlink(target);
@ -494,7 +491,7 @@ static int stm32_stlink_resume(struct target *target, int current,
struct reg *pc; struct reg *pc;
LOG_DEBUG("%s %d %x %d %d", __func__, current, address, LOG_DEBUG("%s %d %x %d %d", __func__, current, address,
handle_breakpoints, debug_execution); handle_breakpoints, debug_execution);
if (target->state != TARGET_HALTED) { if (target->state != TARGET_HALTED) {
LOG_WARNING("target not halted"); LOG_WARNING("target not halted");
@ -526,8 +523,8 @@ static int stm32_stlink_resume(struct target *target, int current,
breakpoint = breakpoint_find(target, resume_pc); breakpoint = breakpoint_find(target, resume_pc);
if (breakpoint) { if (breakpoint) {
LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)", LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)",
breakpoint->address, breakpoint->address,
breakpoint->unique_id); breakpoint->unique_id);
cortex_m3_unset_breakpoint(target, breakpoint); cortex_m3_unset_breakpoint(target, breakpoint);
res = stlink_if->layout->api->step(stlink_if->fd); res = stlink_if->layout->api->step(stlink_if->fd);
@ -552,7 +549,7 @@ static int stm32_stlink_resume(struct target *target, int current,
} }
static int stm32_stlink_step(struct target *target, int current, static int stm32_stlink_step(struct target *target, int current,
uint32_t address, int handle_breakpoints) uint32_t address, int handle_breakpoints)
{ {
int res; int res;
struct stlink_interface_s *stlink_if = target_to_stlink(target); struct stlink_interface_s *stlink_if = target_to_stlink(target);
@ -613,8 +610,8 @@ static int stm32_stlink_step(struct target *target, int current,
} }
static int stm32_stlink_read_memory(struct target *target, uint32_t address, static int stm32_stlink_read_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, uint32_t size, uint32_t count,
uint8_t *buffer) uint8_t *buffer)
{ {
int res; int res;
uint32_t buffer_threshold = 128; uint32_t buffer_threshold = 128;
@ -644,13 +641,11 @@ static int stm32_stlink_read_memory(struct target *target, uint32_t address,
c = count; c = count;
if (size != 4) if (size != 4)
res = res = stlink_if->layout->api->read_mem8(stlink_if->fd,
stlink_if->layout->api->read_mem8(stlink_if->fd, address, address, c, dst);
c, dst);
else else
res = res = stlink_if->layout->api->read_mem32(stlink_if->fd,
stlink_if->layout->api->read_mem32(stlink_if->fd, address, address, c, (uint32_t *)dst);
c, (uint32_t *)dst);
if (res != ERROR_OK) if (res != ERROR_OK)
return res; return res;
@ -664,8 +659,8 @@ static int stm32_stlink_read_memory(struct target *target, uint32_t address,
} }
static int stm32_stlink_write_memory(struct target *target, uint32_t address, static int stm32_stlink_write_memory(struct target *target, uint32_t address,
uint32_t size, uint32_t count, uint32_t size, uint32_t count,
const uint8_t *buffer) const uint8_t *buffer)
{ {
int res; int res;
uint32_t buffer_threshold = 128; uint32_t buffer_threshold = 128;
@ -695,13 +690,11 @@ static int stm32_stlink_write_memory(struct target *target, uint32_t address,
c = count; c = count;
if (size != 4) if (size != 4)
res = res = stlink_if->layout->api->write_mem8(stlink_if->fd,
stlink_if->layout->api->write_mem8(stlink_if->fd, address, address, c, dst);
c, dst);
else else
res = res = stlink_if->layout->api->write_mem32(stlink_if->fd,
stlink_if->layout->api->write_mem32(stlink_if->fd, address, address, c, (uint32_t *)dst);
c, (uint32_t *)dst);
if (res != ERROR_OK) if (res != ERROR_OK)
return res; return res;
@ -715,8 +708,8 @@ static int stm32_stlink_write_memory(struct target *target, uint32_t address,
} }
static int stm32_stlink_bulk_write_memory(struct target *target, static int stm32_stlink_bulk_write_memory(struct target *target,
uint32_t address, uint32_t count, uint32_t address, uint32_t count,
const uint8_t *buffer) const uint8_t *buffer)
{ {
return stm32_stlink_write_memory(target, address, 4, count, buffer); return stm32_stlink_write_memory(target, address, 4, count, buffer);
} }

File diff suppressed because it is too large Load Diff

View File

@ -29,6 +29,7 @@
* Free Software Foundation, Inc., * * Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/ ***************************************************************************/
#ifndef TARGET_H #ifndef TARGET_H
#define TARGET_H #define TARGET_H
@ -57,8 +58,7 @@ struct target_list;
*/ */
enum target_state enum target_state {
{
TARGET_UNKNOWN = 0, TARGET_UNKNOWN = 0,
TARGET_RUNNING = 1, TARGET_RUNNING = 1,
TARGET_HALTED = 2, TARGET_HALTED = 2,
@ -71,16 +71,14 @@ enum nvp_assert {
NVP_ASSERT, NVP_ASSERT,
}; };
enum target_reset_mode enum target_reset_mode {
{
RESET_UNKNOWN = 0, RESET_UNKNOWN = 0,
RESET_RUN = 1, /* reset and let target run */ RESET_RUN = 1, /* reset and let target run */
RESET_HALT = 2, /* reset and halt target out of reset */ RESET_HALT = 2, /* reset and halt target out of reset */
RESET_INIT = 3, /* reset and halt target out of reset, then run init script */ RESET_INIT = 3, /* reset and halt target out of reset, then run init script */
}; };
enum target_debug_reason enum target_debug_reason {
{
DBG_REASON_DBGRQ = 0, DBG_REASON_DBGRQ = 0,
DBG_REASON_BREAKPOINT = 1, DBG_REASON_BREAKPOINT = 1,
DBG_REASON_WATCHPOINT = 2, DBG_REASON_WATCHPOINT = 2,
@ -90,14 +88,12 @@ enum target_debug_reason
DBG_REASON_UNDEFINED = 6 DBG_REASON_UNDEFINED = 6
}; };
enum target_endianness enum target_endianness {
{
TARGET_ENDIAN_UNKNOWN = 0, TARGET_ENDIAN_UNKNOWN = 0,
TARGET_BIG_ENDIAN = 1, TARGET_LITTLE_ENDIAN = 2 TARGET_BIG_ENDIAN = 1, TARGET_LITTLE_ENDIAN = 2
}; };
struct working_area struct working_area {
{
uint32_t address; uint32_t address;
uint32_t size; uint32_t size;
bool free; bool free;
@ -105,26 +101,23 @@ struct working_area
struct working_area **user; struct working_area **user;
struct working_area *next; struct working_area *next;
}; };
struct gdb_service struct gdb_service {
{
struct target *target; struct target *target;
/* field for smp display */ /* field for smp display */
/* element 0 coreid currently displayed ( 1 till n) */ /* element 0 coreid currently displayed ( 1 till n) */
/* element 1 coreid to be displayed at next resume 1 till n 0 means resume /* element 1 coreid to be displayed at next resume 1 till n 0 means resume
* all cores * all cores core displayed */
core displayed */
int32_t core[2]; int32_t core[2];
}; };
// target_type.h contains the full definitionof struct targe_type /* target_type.h contains the full definitionof struct targe_type */
struct target struct target {
{ struct target_type *type; /* target type definition (name, access functions) */
struct target_type *type; /* target type definition (name, access functions) */
const char *cmd_name; /* tcl Name of target */ const char *cmd_name; /* tcl Name of target */
int target_number; /* DO NOT USE! field to be removed in 2010 */ int target_number; /* DO NOT USE! field to be removed in 2010 */
struct jtag_tap *tap; /* where on the jtag chain is this */ struct jtag_tap *tap; /* where on the jtag chain is this */
int32_t coreid; /* which device on the TAP? */ int32_t coreid; /* which device on the TAP? */
const char *variant; /* what variant of this chip is it? */ const char *variant; /* what variant of this chip is it? */
/** /**
@ -146,25 +139,25 @@ struct target
struct target_event_action *event_action; struct target_event_action *event_action;
int reset_halt; /* attempt resetting the CPU into the halted mode? */ int reset_halt; /* attempt resetting the CPU into the halted mode? */
uint32_t working_area; /* working area (initialized RAM). Evaluated uint32_t working_area; /* working area (initialized RAM). Evaluated
* upon first allocation from virtual/physical address. */ * upon first allocation from virtual/physical address. */
bool working_area_virt_spec; /* virtual address specified? */ bool working_area_virt_spec; /* virtual address specified? */
uint32_t working_area_virt; /* virtual address */ uint32_t working_area_virt; /* virtual address */
bool working_area_phys_spec; /* virtual address specified? */ bool working_area_phys_spec; /* virtual address specified? */
uint32_t working_area_phys; /* physical address */ uint32_t working_area_phys; /* physical address */
uint32_t working_area_size; /* size in bytes */ uint32_t working_area_size; /* size in bytes */
uint32_t backup_working_area; /* whether the content of the working area has to be preserved */ uint32_t backup_working_area; /* whether the content of the working area has to be preserved */
struct working_area *working_areas;/* list of allocated working areas */ struct working_area *working_areas;/* list of allocated working areas */
enum target_debug_reason debug_reason;/* reason why the target entered debug state */ enum target_debug_reason debug_reason;/* reason why the target entered debug state */
enum target_endianness endianness; /* target endianness */ enum target_endianness endianness; /* target endianness */
// also see: target_state_name() /* also see: target_state_name() */
enum target_state state; /* the current backend-state (running, halted, ...) */ enum target_state state; /* the current backend-state (running, halted, ...) */
struct reg_cache *reg_cache; /* the first register cache of the target (core regs) */ struct reg_cache *reg_cache; /* the first register cache of the target (core regs) */
struct breakpoint *breakpoints; /* list of breakpoints */ struct breakpoint *breakpoints; /* list of breakpoints */
struct watchpoint *watchpoints; /* list of watchpoints */ struct watchpoint *watchpoints; /* list of watchpoints */
struct trace *trace_info; /* generic trace information */ struct trace *trace_info; /* generic trace information */
struct debug_msg_receiver *dbgmsg;/* list of debug message receivers */ struct debug_msg_receiver *dbgmsg; /* list of debug message receivers */
uint32_t dbg_msg_enabled; /* debug message status */ uint32_t dbg_msg_enabled; /* debug message status */
void *arch_info; /* architecture specific information */ void *arch_info; /* architecture specific information */
struct target *next; /* next target in list */ struct target *next; /* next target in list */
@ -175,13 +168,13 @@ struct target
bool dbgbase_set; /* By default the debug base is not set */ bool dbgbase_set; /* By default the debug base is not set */
uint32_t dbgbase; /* Really a Cortex-A specific option, but there is no uint32_t dbgbase; /* Really a Cortex-A specific option, but there is no
system in place to support target specific options system in place to support target specific options
currently. */ currently. */
struct rtos *rtos; /* Instance of Real Time Operating System support */ struct rtos *rtos; /* Instance of Real Time Operating System support */
bool rtos_auto_detect; /* A flag that indicates that the RTOS has been specified as "auto" bool rtos_auto_detect; /* A flag that indicates that the RTOS has been specified as "auto"
* and must be detected when symbols are offered */ * and must be detected when symbols are offered */
int smp; /* add some target attributes for smp support */ int smp; /* add some target attributes for smp support */
struct target_list *head; struct target_list *head;
/* the gdb service is there in case of smp , we have only one gdb server /* the gdb service is there in case of smp , we have only one gdb server
* for all smp target * for all smp target
@ -190,7 +183,6 @@ struct target
struct gdb_service *gdb_service; struct gdb_service *gdb_service;
}; };
struct target_list { struct target_list {
struct target *target; struct target *target;
struct target_list *next; struct target_list *next;
@ -204,8 +196,7 @@ static inline const char *target_name(struct target *target)
const char *debug_reason_name(struct target *t); const char *debug_reason_name(struct target *t);
enum target_event enum target_event {
{
/* LD historical names /* LD historical names
* - Prior to the great TCL change * - Prior to the great TCL change
* - June/July/Aug 2008 * - June/July/Aug 2008
@ -269,15 +260,13 @@ struct target_event_action {
bool target_has_event_action(struct target *target, enum target_event event); bool target_has_event_action(struct target *target, enum target_event event);
struct target_event_callback struct target_event_callback {
{
int (*callback)(struct target *target, enum target_event event, void *priv); int (*callback)(struct target *target, enum target_event event, void *priv);
void *priv; void *priv;
struct target_event_callback *next; struct target_event_callback *next;
}; };
struct target_timer_callback struct target_timer_callback {
{
int (*callback)(void *priv); int (*callback)(void *priv);
int time_ms; int time_ms;
int periodic; int periodic;
@ -291,11 +280,11 @@ int target_examine(void);
int target_register_event_callback( int target_register_event_callback(
int (*callback)(struct target *target, int (*callback)(struct target *target,
enum target_event event, void *priv), enum target_event event, void *priv),
void *priv); void *priv);
int target_unregister_event_callback( int target_unregister_event_callback(
int (*callback)(struct target *target, int (*callback)(struct target *target,
enum target_event event, void *priv), enum target_event event, void *priv),
void *priv); void *priv);
/* Poll the status of the target, detect any error conditions and report them. /* Poll the status of the target, detect any error conditions and report them.
* *
@ -329,7 +318,7 @@ int target_call_timer_callbacks(void);
*/ */
int target_call_timer_callbacks_now(void); int target_call_timer_callbacks_now(void);
struct target* get_current_target(struct command_context *cmd_ctx); struct target *get_current_target(struct command_context *cmd_ctx);
struct target *get_target(const char *id); struct target *get_target(const char *id);
/** /**
@ -348,14 +337,14 @@ const char *target_type_name(struct target *target);
*/ */
int target_examine_one(struct target *target); int target_examine_one(struct target *target);
/// @returns @c true if target_set_examined() has been called. /** @returns @c true if target_set_examined() has been called. */
static inline bool target_was_examined(struct target *target) static inline bool target_was_examined(struct target *target)
{ {
return target->examined; return target->examined;
} }
/// Sets the @c examined flag for the given target. /** Sets the @c examined flag for the given target. */
/// Use in target->type->examine() after one-time setup is done. /** Use in target->type->examine() after one-time setup is done. */
static inline void target_set_examined(struct target *target) static inline void target_set_examined(struct target *target)
{ {
target->examined = true; target->examined = true;
@ -520,13 +509,13 @@ int target_write_buffer(struct target *target,
int target_read_buffer(struct target *target, int target_read_buffer(struct target *target,
uint32_t address, uint32_t size, uint8_t *buffer); uint32_t address, uint32_t size, uint8_t *buffer);
int target_checksum_memory(struct target *target, int target_checksum_memory(struct target *target,
uint32_t address, uint32_t size, uint32_t* crc); uint32_t address, uint32_t size, uint32_t *crc);
int target_blank_check_memory(struct target *target, int target_blank_check_memory(struct target *target,
uint32_t address, uint32_t size, uint32_t* blank); uint32_t address, uint32_t size, uint32_t *blank);
int target_wait_state(struct target *target, enum target_state state, int ms); int target_wait_state(struct target *target, enum target_state state, int ms);
/** Return the *name* of this targets current state */ /** Return the *name* of this targets current state */
const char *target_state_name( struct target *target ); const char *target_state_name(struct target *target);
/* DANGER!!!!! /* DANGER!!!!!
* *

Some files were not shown because too many files have changed in this diff Show More