Change-Id: Ia055b6d2b5f6449a38afd0539a8c66e7d7e0c059 Signed-off-by: Spencer Oliver <spen@spen-soft.co.uk> Reviewed-on: http://openocd.zylin.com/430 Tested-by: jenkinstags/v0.6.0-rc1
@@ -40,7 +40,6 @@ | |||
#include "arm_adi_v5.h" | |||
#include <helper/time_support.h> | |||
/* JTAG instructions/registers for JTAG-DP and SWJ-DP */ | |||
#define JTAG_DP_ABORT 0x8 | |||
#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); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
dap->ack = dap->ack & 0x7; | |||
/* 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(); | |||
while (dap->ack != JTAG_ACK_OK_FAULT) | |||
{ | |||
if (dap->ack == JTAG_ACK_WAIT) | |||
{ | |||
if ((timeval_ms()-then) > 1000) | |||
{ | |||
while (dap->ack != JTAG_ACK_OK_FAULT) { | |||
if (dap->ack == JTAG_ACK_WAIT) { | |||
if ((timeval_ms()-then) > 1000) { | |||
/* NOTE: this would be a good spot | |||
* to use JTAG_DP_ABORT. | |||
*/ | |||
@@ -247,9 +243,7 @@ static int jtagdp_transaction_endcheck(struct adiv5_dap *dap) | |||
"in JTAG-DP transaction"); | |||
return ERROR_JTAG_DEVICE_ERROR; | |||
} | |||
} | |||
else | |||
{ | |||
} else { | |||
LOG_WARNING("Invalid ACK %#x " | |||
"in JTAG-DP transaction", | |||
dap->ack); | |||
@@ -260,7 +254,8 @@ static int jtagdp_transaction_endcheck(struct adiv5_dap *dap) | |||
DP_CTRL_STAT, DPAP_READ, 0, &ctrlstat); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
if ((retval = dap_run(dap)) != ERROR_OK) | |||
retval = dap_run(dap); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
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) */ | |||
/* Check for STICKYERR and STICKYORUN */ | |||
if (ctrlstat & (SSTICKYORUN | SSTICKYERR)) | |||
{ | |||
if (ctrlstat & (SSTICKYORUN | SSTICKYERR)) { | |||
LOG_DEBUG("jtag-dp: CTRL/STAT error, 0x%" PRIx32, ctrlstat); | |||
/* Check power to debug regions */ | |||
if ((ctrlstat & 0xf0000000) != 0xf0000000) | |||
{ | |||
if ((ctrlstat & 0xf0000000) != 0xf0000000) { | |||
retval = ahbap_debugport_init(dap); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
else | |||
{ | |||
} else { | |||
uint32_t mem_ap_csw, mem_ap_tar; | |||
/* 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); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
if ((retval = dap_run(dap)) != ERROR_OK) | |||
retval = dap_run(dap); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
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) | |||
return retval; | |||
if ((retval = dap_run(dap)) != ERROR_OK) | |||
retval = dap_run(dap); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
LOG_ERROR("MEM_AP_CSW 0x%" PRIx32 ", MEM_AP_TAR 0x%" | |||
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 ERROR_JTAG_DEVICE_ERROR; | |||
} | |||
@@ -55,12 +55,10 @@ | |||
#include <jtag/swd.h> | |||
static int swd_queue_dp_read(struct adiv5_dap *dap, unsigned reg, | |||
uint32_t *data) | |||
{ | |||
// REVISIT status return vs ack ... | |||
/* REVISIT status return vs ack ... */ | |||
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) | |||
return status; | |||
*ack = status; | |||
// ?? | |||
/* ?? */ | |||
return ERROR_OK; | |||
} | |||
static int (swd_queue_dp_write)(struct adiv5_dap *dap, unsigned reg, | |||
uint32_t data) | |||
{ | |||
// REVISIT status return vs ack ... | |||
/* REVISIT status return vs ack ... */ | |||
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, | |||
uint32_t *data) | |||
{ | |||
// REVISIT APSEL ... | |||
// REVISIT status return ... | |||
/* REVISIT APSEL ... */ | |||
/* REVISIT status return ... */ | |||
return swd->read_reg(swd_cmd(true, true, reg), data); | |||
} | |||
static int (swd_queue_ap_write)(struct adiv5_dap *dap, unsigned reg, | |||
uint32_t data) | |||
{ | |||
// REVISIT APSEL ... | |||
// REVISIT status return ... | |||
/* REVISIT APSEL ... */ | |||
/* REVISIT status return ... */ | |||
return swd->write_reg(swd_cmd(false, true, reg), data); | |||
} | |||
@@ -194,15 +192,14 @@ COMMAND_HANDLER(handle_swd_wcr) | |||
int retval; | |||
struct target *target = get_current_target(CMD_CTX); | |||
struct arm *arm = target_to_arm(target); | |||
struct adiv5_dap *dap = arm->dap; | |||
struct adiv5_dap *dap = arm->dap; | |||
uint32_t wcr; | |||
unsigned trn, scale = 0; | |||
switch (CMD_ARGC) { | |||
/* no-args: just dump state */ | |||
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); | |||
if (retval == ERROR_OK) | |||
dap->ops->run(dap); | |||
@@ -315,11 +312,10 @@ static int swd_init(struct command_context *ctx) | |||
{ | |||
struct target *target = get_current_target(ctx); | |||
struct arm *arm = target_to_arm(target); | |||
struct adiv5_dap *dap = arm->dap; | |||
struct adiv5_dap *dap = arm->dap; | |||
uint32_t idcode; | |||
int status; | |||
/* FIXME validate transport config ... is the | |||
* configured DAP present (check IDCODE)? | |||
* Is *only* one DAP configured? | |||
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -24,7 +25,6 @@ | |||
#include "algorithm.h" | |||
#include <helper/binarybuffer.h> | |||
void init_mem_param(struct mem_param *param, uint32_t address, uint32_t size, enum param_direction direction) | |||
{ | |||
param->address = address; | |||
@@ -17,26 +17,24 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef ALGORITHM_H | |||
#define ALGORITHM_H | |||
enum param_direction | |||
{ | |||
enum param_direction { | |||
PARAM_IN, | |||
PARAM_OUT, | |||
PARAM_IN_OUT | |||
}; | |||
struct mem_param | |||
{ | |||
struct mem_param { | |||
uint32_t address; | |||
uint32_t size; | |||
uint8_t *value; | |||
enum param_direction direction; | |||
}; | |||
struct reg_param | |||
{ | |||
struct reg_param { | |||
const char *reg_name; | |||
uint32_t size; | |||
uint8_t *value; | |||
@@ -23,6 +23,7 @@ | |||
* Free Software Foundation, Inc., | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | |||
*/ | |||
#ifndef ARM_H | |||
#define ARM_H | |||
@@ -26,38 +26,36 @@ | |||
#include "arm.h" | |||
#include "arm_dpm.h" | |||
#define ARM11_TAP_DEFAULT TAP_INVALID | |||
#define ARM11_TAP_DEFAULT TAP_INVALID | |||
#define CHECK_RETVAL(action) \ | |||
do { \ | |||
int __retval = (action); \ | |||
if (__retval != ERROR_OK) { \ | |||
LOG_DEBUG("error while calling \"%s\"", \ | |||
# action ); \ | |||
# action); \ | |||
return __retval; \ | |||
} \ | |||
} while (0) | |||
/* bits from ARMv7 DIDR */ | |||
enum arm11_debug_version | |||
{ | |||
ARM11_DEBUG_V6 = 0x01, | |||
ARM11_DEBUG_V61 = 0x02, | |||
ARM11_DEBUG_V7 = 0x03, | |||
ARM11_DEBUG_V7_CP14 = 0x04, | |||
enum arm11_debug_version { | |||
ARM11_DEBUG_V6 = 0x01, | |||
ARM11_DEBUG_V61 = 0x02, | |||
ARM11_DEBUG_V7 = 0x03, | |||
ARM11_DEBUG_V7_CP14 = 0x04, | |||
}; | |||
struct arm11_common | |||
{ | |||
struct arm arm; | |||
struct arm11_common { | |||
struct arm arm; | |||
/** Debug module state. */ | |||
struct arm_dpm dpm; | |||
struct arm11_sc7_action *bpwp_actions; | |||
unsigned bpwp_n; | |||
size_t brp; /**< Number of Breakpoint Register Pairs from DIDR */ | |||
size_t free_brps; /**< Number of breakpoints allocated */ | |||
size_t brp; /**< Number of Breakpoint Register Pairs from DIDR */ | |||
size_t free_brps; /**< Number of breakpoints allocated */ | |||
uint32_t dscr; /**< Last retrieved DSCR value. */ | |||
@@ -67,7 +65,7 @@ struct arm11_common | |||
bool is_rdtr_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. | |||
* 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) | |||
{ | |||
return container_of(target->arch_info, struct arm11_common, | |||
arm); | |||
return container_of(target->arch_info, struct arm11_common, 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 | |||
*/ | |||
enum arm11_instructions | |||
{ | |||
enum arm11_instructions { | |||
ARM11_EXTEST = 0x00, | |||
ARM11_SCAN_N = 0x02, | |||
ARM11_RESTART = 0x04, | |||
ARM11_HALT = 0x08, | |||
ARM11_HALT = 0x08, | |||
ARM11_INTEST = 0x0C, | |||
ARM11_ITRSEL = 0x1D, | |||
ARM11_IDCODE = 0x1E, | |||
ARM11_BYPASS = 0x1F, | |||
}; | |||
enum arm11_sc7 | |||
{ | |||
ARM11_SC7_NULL = 0, | |||
ARM11_SC7_VCR = 7, | |||
ARM11_SC7_PC = 8, | |||
ARM11_SC7_BVR0 = 64, | |||
ARM11_SC7_BCR0 = 80, | |||
ARM11_SC7_WVR0 = 96, | |||
ARM11_SC7_WCR0 = 112, | |||
enum arm11_sc7 { | |||
ARM11_SC7_NULL = 0, | |||
ARM11_SC7_VCR = 7, | |||
ARM11_SC7_PC = 8, | |||
ARM11_SC7_BVR0 = 64, | |||
ARM11_SC7_BCR0 = 80, | |||
ARM11_SC7_WVR0 = 96, | |||
ARM11_SC7_WCR0 = 112, | |||
}; | |||
#endif /* ARM11_H */ | |||
#endif /* ARM11_H */ |
@@ -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 | |||
#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 | |||
* scan chain 7 | |||
*/ | |||
struct arm11_sc7_action | |||
{ | |||
bool write; /**< Access mode: true for write, false for read. */ | |||
uint8_t address; /**< Register address mode. Use enum #arm11_sc7 */ | |||
struct arm11_sc7_action { | |||
bool write; /**< Access mode: true for write, false for read. */ | |||
uint8_t address;/**< Register address mode. Use enum #arm11_sc7 */ | |||
/** | |||
* If write then set this to value to be written. In read mode | |||
* 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_bpwp_flush(struct arm11_common *arm11); | |||
#endif // ARM11_DBGTAP_H | |||
#endif /* ARM11_DBGTAP_H */ |
@@ -20,6 +20,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -54,14 +55,12 @@ static int arm720t_scan_cp15(struct target *target, | |||
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; | |||
} | |||
if ((retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE)) != ERROR_OK) | |||
{ | |||
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
fields[0].num_bits = 1; | |||
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].in_value = NULL; | |||
if (in) | |||
{ | |||
if (in) { | |||
fields[1].in_value = (uint8_t *)in; | |||
jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE); | |||
jtag_add_callback(arm7flip32, (jtag_callback_data_t)in); | |||
} else | |||
{ | |||
jtag_add_dr_scan(jtag_info->tap, 2, fields, TAP_DRPAUSE); | |||
} | |||
if (clock_arg) | |||
jtag_add_runtest(0, TAP_DRPAUSE); | |||
#ifdef _DEBUG_INSTRUCTION_EXECUTION_ | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
if (in) | |||
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); | |||
static const char *state[] = | |||
{ | |||
static const char *state[] = { | |||
"disabled", "enabled" | |||
}; | |||
@@ -300,16 +294,14 @@ static int arm720t_read_memory(struct target *target, | |||
struct arm720t_common *arm720t = target_to_arm720(target); | |||
/* 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); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
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); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
@@ -342,36 +334,26 @@ static int arm720t_soft_reset_halt(struct target *target) | |||
.eice_cache->reg_list[EICE_DBG_STAT]; | |||
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; | |||
} | |||
long long then = timeval_ms(); | |||
int timeout; | |||
while (!(timeout = ((timeval_ms()-then) > 1000))) | |||
{ | |||
if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0) | |||
{ | |||
while (!(timeout = ((timeval_ms()-then) > 1000))) { | |||
if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0) { | |||
embeddedice_read_reg(dbg_stat); | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
} else | |||
{ | |||
break; | |||
} | |||
if (debug_level >= 3) | |||
{ | |||
alive_sleep(100); | |||
} else | |||
{ | |||
else | |||
keep_alive(); | |||
} | |||
} | |||
if (timeout) | |||
{ | |||
if (timeout) { | |||
LOG_ERROR("Failed to halt CPU after 1 sec"); | |||
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.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 ERROR_OK; | |||
} | |||
@@ -467,42 +448,35 @@ COMMAND_HANDLER(arm720t_handle_cp15_command) | |||
if (retval != ERROR_OK) | |||
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); | |||
return ERROR_OK; | |||
} | |||
/* 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; | |||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], opcode); | |||
if (CMD_ARGC == 1) | |||
{ | |||
if (CMD_ARGC == 1) { | |||
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); | |||
return ERROR_OK; | |||
} | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
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; | |||
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); | |||
return ERROR_OK; | |||
} | |||
@@ -518,8 +492,7 @@ static int arm720t_mrc(struct target *target, int cpnum, | |||
uint32_t CRn, uint32_t CRm, | |||
uint32_t *value) | |||
{ | |||
if (cpnum!=15) | |||
{ | |||
if (cpnum != 15) { | |||
LOG_ERROR("Only cp15 is supported"); | |||
return ERROR_FAIL; | |||
} | |||
@@ -536,8 +509,7 @@ static int arm720t_mcr(struct target *target, int cpnum, | |||
uint32_t CRn, uint32_t CRm, | |||
uint32_t value) | |||
{ | |||
if (cpnum!=15) | |||
{ | |||
if (cpnum != 15) { | |||
LOG_ERROR("Only cp15 is supported"); | |||
return ERROR_FAIL; | |||
} | |||
@@ -576,8 +548,7 @@ static const struct command_registration arm720t_command_handlers[] = { | |||
}; | |||
/** Holds methods for ARM720 targets. */ | |||
struct target_type arm720t_target = | |||
{ | |||
struct target_type arm720t_target = { | |||
.name = "arm720t", | |||
.poll = arm7_9_poll, | |||
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef ARM720T_H | |||
#define ARM720T_H | |||
@@ -25,8 +26,7 @@ | |||
#define ARM720T_COMMON_MAGIC 0xa720a720 | |||
struct arm720t_common | |||
{ | |||
struct arm720t_common { | |||
struct arm7_9_common arm7_9_common; | |||
uint32_t common_magic; | |||
struct armv4_5_mmu_common armv4_5_mmu; | |||
@@ -35,11 +35,9 @@ struct arm720t_common | |||
uint32_t far_reg; | |||
}; | |||
static inline struct arm720t_common * | |||
target_to_arm720(struct target *target) | |||
static inline struct arm720t_common *target_to_arm720(struct target *target) | |||
{ | |||
return container_of(target->arch_info, struct arm720t_common, | |||
arm7_9_common.arm); | |||
return container_of(target->arch_info, struct arm720t_common, arm7_9_common.arm); | |||
} | |||
#endif /* ARM720T_H */ |
@@ -26,6 +26,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef 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. | |||
*/ | |||
struct arm7_9_common | |||
{ | |||
struct arm7_9_common { | |||
struct arm arm; | |||
uint32_t common_magic; | |||
@@ -71,16 +71,26 @@ struct arm7_9_common | |||
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 (*read_core_regs)(struct target *target, uint32_t mask, uint32_t *core_regs[16]); | |||
/**< Function for reading the core registers */ | |||
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_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 (*read_core_regs)(struct target *target, uint32_t mask, uint32_t *core_regs[16]); /**< Function for reading the core registers */ | |||
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 (*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_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_thumb)(struct target *target); | |||
void (*enable_single_step)(struct target *target, uint32_t next_pc); | |||
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 * | |||
target_to_arm7_9(struct target *target) | |||
static inline struct arm7_9_common *target_to_arm7_9(struct target *target) | |||
{ | |||
return container_of(target->arch_info, struct arm7_9_common, | |||
arm); | |||
return container_of(target->arch_info, struct arm7_9_common, arm); | |||
} | |||
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_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_step(struct target *target, int current, uint32_t address, int handle_breakpoints); | |||
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_resume(struct target *target, int current, uint32_t address, | |||
int handle_breakpoints, int debug_execution); | |||
int arm7_9_step(struct target *target, int current, uint32_t address, | |||
int handle_breakpoints); | |||
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_add_breakpoint(struct target *target, struct breakpoint *breakpoint); | |||
int arm7_9_remove_breakpoint(struct target *target, struct breakpoint *breakpoint); | |||
@@ -23,6 +23,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -32,7 +33,6 @@ | |||
#include "register.h" | |||
#include "arm_opcodes.h" | |||
/* | |||
* For information about ARM7TDMI, see ARM DDI 0210C (r4p1) | |||
* 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 */ | |||
if ((target->debug_reason != DBG_REASON_DBGRQ) | |||
&& (target->debug_reason != DBG_REASON_SINGLESTEP)) | |||
{ | |||
&& (target->debug_reason != DBG_REASON_SINGLESTEP)) { | |||
struct scan_field fields[2]; | |||
uint8_t databus[4]; | |||
uint8_t breakpoint; | |||
@@ -64,19 +63,17 @@ static int arm7tdmi_examine_debug_reason(struct target *target) | |||
fields[1].out_value = NULL; | |||
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; | |||
} | |||
retval = arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL, TAP_DRPAUSE); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
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; | |||
} | |||
fields[0].in_value = NULL; | |||
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 __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, | |||
2, | |||
@@ -116,7 +113,7 @@ static __inline int arm7tdmi_clock_out_inner(struct arm_jtag *jtag_info, uint32_ | |||
* | |||
* 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) | |||
{ | |||
int retval; | |||
@@ -136,10 +133,9 @@ static int arm7tdmi_clock_data_in(struct arm_jtag *jtag_info, uint32_t *in) | |||
int retval = ERROR_OK; | |||
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; | |||
} | |||
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE); | |||
if (retval != ERROR_OK) | |||
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); | |||
#ifdef _DEBUG_INSTRUCTION_EXECUTION_ | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
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); | |||
if (flip) | |||
readback = flip_u32(readback, 32); | |||
switch (size) | |||
{ | |||
switch (size) { | |||
case 4: | |||
if (be) | |||
{ | |||
h_u32_to_be(((uint8_t*)in), readback); | |||
} else | |||
{ | |||
h_u32_to_le(((uint8_t*)in), readback); | |||
} | |||
h_u32_to_be(((uint8_t *)in), readback); | |||
else | |||
h_u32_to_le(((uint8_t *)in), readback); | |||
break; | |||
case 2: | |||
if (be) | |||
{ | |||
h_u16_to_be(((uint8_t*)in), readback & 0xffff); | |||
} else | |||
{ | |||
h_u16_to_le(((uint8_t*)in), readback & 0xffff); | |||
} | |||
h_u16_to_be(((uint8_t *)in), readback & 0xffff); | |||
else | |||
h_u16_to_le(((uint8_t *)in), readback & 0xffff); | |||
break; | |||
case 1: | |||
*((uint8_t *)in)= readback & 0xff; | |||
*((uint8_t *)in) = readback & 0xff; | |||
break; | |||
} | |||
} | |||
@@ -222,10 +212,9 @@ static int arm7tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info, | |||
int retval = ERROR_OK; | |||
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; | |||
} | |||
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
@@ -250,19 +239,14 @@ static int arm7tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info, | |||
#ifdef _DEBUG_INSTRUCTION_EXECUTION_ | |||
{ | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
if (in) | |||
{ | |||
LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in); | |||
} | |||
LOG_DEBUG("in: 0x%8.8x", *(uint32_t *)in); | |||
else | |||
{ | |||
LOG_ERROR("BUG: called with in == NULL"); | |||
} | |||
} | |||
#endif | |||
@@ -318,7 +302,6 @@ static void arm7tdmi_change_to_arm(struct target *target, | |||
*pc -= 0xa; | |||
} | |||
/* 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? | |||
* | |||
@@ -326,7 +309,7 @@ static void arm7tdmi_change_to_arm(struct target *target, | |||
* and convert data afterwards. | |||
*/ | |||
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; | |||
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) */ | |||
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)) | |||
/* nothing fetched, STM still in EXECUTE (1 + i cycle) */ | |||
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, | |||
uint32_t mask, void* buffer, int size) | |||
uint32_t mask, void *buffer, int size) | |||
{ | |||
int i; | |||
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) */ | |||
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 */ | |||
if (mask & (1 << i)) | |||
{ | |||
switch (size) | |||
{ | |||
if (mask & (1 << i)) { | |||
switch (size) { | |||
case 4: | |||
arm7tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be); | |||
break; | |||
@@ -474,8 +453,7 @@ static void arm7tdmi_write_core_regs(struct target *target, | |||
/* fetch NOP, LDM in EXECUTE stage (1st cycle) */ | |||
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)) | |||
/* nothing fetched, LDM still in EXECUTE (1 + i cycle) */ | |||
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; | |||
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); | |||
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. */ | |||
struct target_type arm7tdmi_target = | |||
{ | |||
struct target_type arm7tdmi_target = { | |||
.name = "arm7tdmi", | |||
.poll = arm7_9_poll, | |||
@@ -20,6 +20,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef ARM7TDMI_H | |||
#define ARM7TDMI_H | |||
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef ARM920T_H | |||
#define ARM920T_H | |||
@@ -25,8 +26,7 @@ | |||
#define ARM920T_COMMON_MAGIC 0xa920a920 | |||
struct arm920t_common | |||
{ | |||
struct arm920t_common { | |||
struct arm7_9_common arm7_9_common; | |||
uint32_t common_magic; | |||
struct armv4_5_mmu_common armv4_5_mmu; | |||
@@ -38,21 +38,17 @@ struct arm920t_common | |||
int preserve_cache; | |||
}; | |||
static inline struct arm920t_common * | |||
target_to_arm920(struct target *target) | |||
static inline struct arm920t_common *target_to_arm920(struct target *target) | |||
{ | |||
return container_of(target->arch_info, struct arm920t_common, | |||
arm7_9_common.arm); | |||
return container_of(target->arch_info, struct arm920t_common, arm7_9_common.arm); | |||
} | |||
struct arm920t_cache_line | |||
{ | |||
struct arm920t_cache_line { | |||
uint32_t cam; | |||
uint32_t data[8]; | |||
}; | |||
struct arm920t_tlb_entry | |||
{ | |||
struct arm920t_tlb_entry { | |||
uint32_t cam; | |||
uint32_t ram1; | |||
uint32_t ram2; | |||
@@ -20,6 +20,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#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); | |||
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; | |||
} | |||
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE); | |||
if (retval != ERROR_OK) | |||
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(); | |||
for (;;) | |||
{ | |||
for (;;) { | |||
/* rescan with NOP, to wait for the access to complete */ | |||
access_t = 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); | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
if (buf_get_u32(&access_t, 0, 1) == 1) | |||
{ | |||
break; | |||
} | |||
/* 10ms timeout */ | |||
if ((timeval_ms()-then)>10) | |||
{ | |||
if ((timeval_ms()-then) > 10) { | |||
LOG_ERROR("cp15 read operation timed out"); | |||
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(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; | |||
} | |||
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE); | |||
if (retval != ERROR_OK) | |||
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(); | |||
for (;;) | |||
{ | |||
for (;;) { | |||
/* rescan with NOP, to wait for the access to complete */ | |||
access_t = 0; | |||
nr_w_buf = 0; | |||
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; | |||
} | |||
if (buf_get_u32(&access_t, 0, 1) == 1) | |||
{ | |||
break; | |||
} | |||
/* 10ms timeout */ | |||
if ((timeval_ms()-then)>10) | |||
{ | |||
if ((timeval_ms()-then) > 10) { | |||
LOG_ERROR("cp15 write operation timed out"); | |||
return ERROR_FAIL; | |||
} | |||
@@ -236,14 +225,14 @@ static int arm926ejs_examine_debug_reason(struct target *target) | |||
int retval; | |||
embeddedice_read_reg(dbg_stat); | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
/* Method-Of-Entry (MOE) field */ | |||
debug_reason = buf_get_u32(dbg_stat->value, 6, 4); | |||
switch (debug_reason) | |||
{ | |||
switch (debug_reason) { | |||
case 0: | |||
LOG_DEBUG("no *NEW* debug entry (?missed one?)"); | |||
/* ... since last restart or debug reset ... */ | |||
@@ -337,7 +326,8 @@ static int arm926ejs_get_ttb(struct target *target, uint32_t *result) | |||
int retval; | |||
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; | |||
*result = ttb; | |||
@@ -360,8 +350,7 @@ static int arm926ejs_disable_mmu_caches(struct target *target, int mmu, | |||
if (retval != ERROR_OK) | |||
return retval; | |||
if (mmu) | |||
{ | |||
if (mmu) { | |||
/* invalidate TLB */ | |||
retval = arm926ejs->write_cp15(target, 0, 0, 8, 7, 0x0); | |||
if (retval != ERROR_OK) | |||
@@ -370,8 +359,7 @@ static int arm926ejs_disable_mmu_caches(struct target *target, int mmu, | |||
cp15_control &= ~0x1U; | |||
} | |||
if (d_u_cache) | |||
{ | |||
if (d_u_cache) { | |||
uint32_t debug_override; | |||
/* read-modify-write CP15 debug override register | |||
* to enable "test and clean all" */ | |||
@@ -398,8 +386,7 @@ static int arm926ejs_disable_mmu_caches(struct target *target, int mmu, | |||
cp15_control &= ~0x4U; | |||
} | |||
if (i_cache) | |||
{ | |||
if (i_cache) { | |||
/* invalidate ICache */ | |||
retval = arm926ejs->write_cp15(target, 0, 0, 7, 5, 0x0); | |||
if (retval != ERROR_OK) | |||
@@ -454,8 +441,7 @@ static int arm926ejs_post_debug_entry(struct target *target) | |||
return retval; | |||
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; | |||
/* identify caches */ | |||
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. */ | |||
int arm926ejs_arch_state(struct target *target) | |||
{ | |||
static const char *state[] = | |||
{ | |||
static const char *state[] = { | |||
"disabled", "enabled" | |||
}; | |||
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); | |||
return ERROR_TARGET_INVALID; | |||
} | |||
@@ -560,37 +544,27 @@ int arm926ejs_soft_reset_halt(struct target *target) | |||
struct arm *arm = &arm7_9->arm; | |||
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; | |||
} | |||
long long then = timeval_ms(); | |||
int timeout; | |||
while (!(timeout = ((timeval_ms()-then) > 1000))) | |||
{ | |||
if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0) | |||
{ | |||
while (!(timeout = ((timeval_ms()-then) > 1000))) { | |||
if (buf_get_u32(dbg_stat->value, EICE_DBG_STATUS_DBGACK, 1) == 0) { | |||
embeddedice_read_reg(dbg_stat); | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
} else | |||
{ | |||
} else | |||
break; | |||
} | |||
if (debug_level >= 1) | |||
{ | |||
if (debug_level >= 1) { | |||
/* do not eat all CPU, time out after 1 se*/ | |||
alive_sleep(100); | |||
} else | |||
{ | |||
keep_alive(); | |||
} | |||
} | |||
if (timeout) | |||
{ | |||
if (timeout) { | |||
LOG_ERROR("Failed to halt CPU after 1 sec"); | |||
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 | |||
* 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 | |||
* to allow implementation of breakpoints in memory marked read only | |||
* 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 | |||
* | |||
* 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); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} else | |||
{ | |||
if ((retval = arm7_9_write_memory(target, address, size, count, buffer)) != ERROR_OK) | |||
} else { | |||
retval = arm7_9_write_memory(target, address, size, count, buffer); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
/* 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 | |||
*/ | |||
if (arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled) | |||
{ | |||
if (count <= 1) | |||
{ | |||
if (arm926ejs->armv4_5_mmu.armv4_5_cache.i_cache_enabled) { | |||
if (count <= 1) { | |||
/* invalidate ICache single entry with MVA */ | |||
arm926ejs->write_cp15(target, 0, 1, 7, 5, address); | |||
} | |||
else | |||
{ | |||
} else { | |||
/* invalidate ICache */ | |||
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) | |||
{ | |||
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 */ | |||
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); | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
if (target->state != TARGET_HALTED) { | |||
LOG_ERROR("Target not halted"); | |||
return ERROR_TARGET_INVALID; | |||
} | |||
@@ -822,8 +789,7 @@ const struct command_registration arm926ejs_command_handlers[] = { | |||
}; | |||
/** Holds methods for ARM926 targets. */ | |||
struct target_type arm926ejs_target = | |||
{ | |||
struct target_type arm926ejs_target = { | |||
.name = "arm926ejs", | |||
.poll = arm7_9_poll, | |||
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef ARM926EJS_H | |||
#define ARM926EJS_H | |||
@@ -25,27 +26,25 @@ | |||
#define ARM926EJS_COMMON_MAGIC 0xa926a926 | |||
struct arm926ejs_common | |||
{ | |||
struct arm926ejs_common { | |||
struct arm7_9_common arm7_9_common; | |||
uint32_t common_magic; | |||
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 (*write_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, | |||
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 d_fsr; | |||
uint32_t i_fsr; | |||
uint32_t d_far; | |||
}; | |||
static inline struct arm926ejs_common * | |||
target_to_arm926(struct target *target) | |||
static inline struct arm926ejs_common *target_to_arm926(struct target *target) | |||
{ | |||
return container_of(target->arch_info, struct arm926ejs_common, | |||
arm7_9_common.arm); | |||
return container_of(target->arch_info, struct arm926ejs_common, arm7_9_common.arm); | |||
} | |||
int arm926ejs_init_arch_info(struct target *target, | |||
struct arm926ejs_common *arm926ejs, struct jtag_tap *tap); | |||
int arm926ejs_arch_state(struct target *target); | |||
@@ -23,6 +23,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -39,8 +40,8 @@ | |||
#define NB_CACHE_WAYS 4 | |||
static uint32_t dc = 0x0; | |||
static uint32_t ic = 0x0; | |||
static uint32_t dc; | |||
static uint32_t ic; | |||
/** | |||
* 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); | |||
static int arm946e_read_cp15(struct target *target, int reg_addr, uint32_t *value); | |||
int arm946e_init_arch_info(struct target *target, struct arm946e_common *arm946e, struct jtag_tap *tap) | |||
int arm946e_init_arch_info(struct target *target, | |||
struct arm946e_common *arm946e, | |||
struct jtag_tap *tap) | |||
{ | |||
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; | |||
/* override hw single-step capability from ARM9TDMI */ | |||
//arm7_9->has_single_step = 1; | |||
/* arm7_9->has_single_step = 1; */ | |||
return ERROR_OK; | |||
} | |||
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); | |||
@@ -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, | |||
struct arm946e_common *arm946e) | |||
struct arm946e_common *arm946e) | |||
{ | |||
if (arm946e->common_magic != ARM946E_COMMON_MAGIC) { | |||
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 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; | |||
} | |||
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE); | |||
if (retval != ERROR_OK) | |||
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); | |||
#endif | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
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); | |||
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; | |||
} | |||
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE); | |||
if (retval != ERROR_OK) | |||
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); | |||
#endif | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
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 csize = 0; | |||
uint32_t shift = 0; | |||
uint32_t cp15_idx, seg, dtag; | |||
int nb_idx, idx = 0; | |||
int retval; | |||
uint32_t csize = 0; | |||
uint32_t shift = 0; | |||
uint32_t cp15_idx, seg, dtag; | |||
int nb_idx, idx = 0; | |||
int retval; | |||
/* Get cache type */ | |||
arm946e_read_cp15(target, 0x01, (uint32_t *) &csize); | |||
/* Get cache type */ | |||
arm946e_read_cp15(target, 0x01, (uint32_t *) &csize); | |||
csize = (csize >> 18) & 0x0F; | |||
csize = (csize >> 18) & 0x0F; | |||
if (csize == 0) | |||
shift = 0; | |||
else | |||
shift = csize - 0x3; /* Now 0 = 4KB, 1 = 8KB, ... */ | |||
shift = csize - 0x3; /* Now 0 = 4KB, 1 = 8KB, ... */ | |||
/* Cache size, given in bytes */ | |||
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 */ | |||
/* 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 */ | |||
for(idx=0; idx < nb_idx; idx++) | |||
{ | |||
for (idx = 0; idx < nb_idx; idx++) { | |||
/* Form and write cp15 index (segment + line idx) */ | |||
cp15_idx = seg << 30 | idx << 5; | |||
retval = arm946e_write_cp15(target, 0x3a, cp15_idx); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
LOG_DEBUG("ERROR writing index"); | |||
return retval; | |||
} | |||
@@ -254,21 +249,19 @@ uint32_t arm946e_invalidate_whole_dcache(struct target *target) | |||
arm946e_read_cp15(target, 0x16, (uint32_t *) &dtag); | |||
/* Check cache line VALID bit */ | |||
if ( !(dtag >> 4 & 0x1) ) | |||
if (!(dtag >> 4 & 0x1)) | |||
continue; | |||
/* Clean data cache line */ | |||
retval = arm946e_write_cp15(target, 0x35, 0x1); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
LOG_DEBUG("ERROR cleaning cache line"); | |||
return retval; | |||
} | |||
/* Flush data cache line */ | |||
retval = arm946e_write_cp15(target, 0x1a, 0x1); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
LOG_DEBUG("ERROR flushing cache line"); | |||
return retval; | |||
} | |||
@@ -289,8 +282,7 @@ uint32_t arm946e_invalidate_whole_icache(struct target *target) | |||
* mcr 15, 0, r0, cr7, cr5, {0} | |||
*/ | |||
retval = arm946e_write_cp15(target, 0x0f, 0x1); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
LOG_DEBUG("ERROR flushing I$"); | |||
return retval; | |||
} | |||
@@ -309,10 +301,8 @@ int arm946e_post_debug_entry(struct target *target) | |||
dc = (ctr_reg >> 2) & 0x01; | |||
ic = (ctr_reg >> 12) & 0x01; | |||
if (arm946e_preserve_cache) | |||
{ | |||
if (dc == 1) | |||
{ | |||
if (arm946e_preserve_cache) { | |||
if (dc == 1) { | |||
/* Clean and flush D$ */ | |||
arm946e_invalidate_whole_dcache(target); | |||
@@ -320,8 +310,7 @@ int arm946e_post_debug_entry(struct target *target) | |||
ctr_reg &= ~(1 << 2); | |||
} | |||
if (ic == 1) | |||
{ | |||
if (ic == 1) { | |||
/* Flush I$ */ | |||
arm946e_invalidate_whole_icache(target); | |||
@@ -331,12 +320,11 @@ int arm946e_post_debug_entry(struct target *target) | |||
/* Write the new configuration */ | |||
retval = arm946e_write_cp15(target, 0x02, ctr_reg); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
LOG_DEBUG("ERROR disabling cache"); | |||
return retval; | |||
} | |||
} /* if preserve_cache */ | |||
} /* if preserve_cache */ | |||
return ERROR_OK; | |||
} | |||
@@ -346,8 +334,7 @@ void arm946e_pre_restore_context(struct target *target) | |||
uint32_t ctr_reg = 0x0; | |||
uint32_t retval; | |||
if (arm946e_preserve_cache) | |||
{ | |||
if (arm946e_preserve_cache) { | |||
/* Get the contents of the 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 | |||
* to reenable I/D-cache linefills | |||
*/ | |||
if (dc == 1) | |||
{ | |||
if (dc == 1) { | |||
/* Enable D$ */ | |||
ctr_reg |= 1 << 2; | |||
} | |||
if (ic == 1) | |||
{ | |||
if (ic == 1) { | |||
/* Enable I$ */ | |||
ctr_reg |= 1 << 12; | |||
} | |||
@@ -370,14 +355,12 @@ void arm946e_pre_restore_context(struct target *target) | |||
/* Write the new configuration */ | |||
retval = arm946e_write_cp15(target, 0x02, ctr_reg); | |||
if (retval != ERROR_OK) | |||
{ | |||
LOG_DEBUG("ERROR enabling cache"); | |||
} | |||
} /* if preserve_cache */ | |||
} /* if preserve_cache */ | |||
} | |||
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 shift = 0; | |||
@@ -386,8 +369,7 @@ uint32_t arm946e_invalidate_dcache(struct target *target, uint32_t address, | |||
uint32_t i = 0; | |||
int retval; | |||
for(i = 0; i < count*size; i++) | |||
{ | |||
for (i = 0; i < count*size; i++) { | |||
cur_addr = address + i; | |||
/* Get cache type */ | |||
@@ -399,14 +381,13 @@ uint32_t arm946e_invalidate_dcache(struct target *target, uint32_t address, | |||
if (csize == 0) | |||
shift = 0; | |||
else | |||
shift = csize - 0x3; /* Now 0 = 4KB, 1 = 8KB, ... */ | |||
shift = csize - 0x3; /* Now 0 = 4KB, 1 = 8KB, ... */ | |||
csize = 1 << (12 + shift); | |||
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. | |||
* 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) */ | |||
cp15_idx = way << 30 | set << 5; | |||
retval = arm946e_write_cp15(target, 0x3a, cp15_idx); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
LOG_DEBUG("ERROR writing index"); | |||
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); | |||
/* Check cache line VALID bit */ | |||
if ( !(dtag >> 4 & 0x1) ) | |||
if (!(dtag >> 4 & 0x1)) | |||
continue; | |||
/* 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 */ | |||
retval = arm946e_write_cp15(target, 0x35, 0x1); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
LOG_DEBUG("ERROR cleaning cache line"); | |||
return retval; | |||
} | |||
/* Flush data cache line */ | |||
retval = arm946e_write_cp15(target, 0x1c, 0x1); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
LOG_DEBUG("ERROR flushing cache line"); | |||
return retval; | |||
} | |||
break; | |||
} | |||
} /* loop through all 4 ways */ | |||
} /* loop through all addresses */ | |||
} /* loop through all 4 ways */ | |||
} /* loop through all addresses */ | |||
return ERROR_OK; | |||
} | |||
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 cp15_idx, set, way, itag; | |||
uint32_t i = 0; | |||
int retval; | |||
for(i = 0; i < count*size; i++) | |||
{ | |||
for (i = 0; i < count*size; i++) { | |||
cur_addr = address + i; | |||
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) */ | |||
cp15_idx = way << 30 | set << 5; | |||
retval = arm946e_write_cp15(target, 0x3a, cp15_idx); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
LOG_DEBUG("ERROR writing index"); | |||
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); | |||
/* Check cache line VALID bit */ | |||
if ( !(itag >> 4 & 0x1) ) | |||
if (!(itag >> 4 & 0x1)) | |||
continue; | |||
/* 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 */ | |||
retval = arm946e_write_cp15(target, 0x1d, 0x0); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
LOG_DEBUG("ERROR flushing cache line"); | |||
return retval; | |||
} | |||
break; | |||
} | |||
} /* way loop */ | |||
} /* addr loop */ | |||
} /* way loop */ | |||
} /* addr loop */ | |||
return ERROR_OK; | |||
} | |||
/** Writes a buffer, in the specified word size, with current MMU settings. */ | |||
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; | |||
@@ -518,18 +490,14 @@ int arm946e_write_memory(struct target *target, uint32_t address, | |||
/* Invalidate D$ if it is ON */ | |||
if (!arm946e_preserve_cache && dc == 1) | |||
{ | |||
arm946e_invalidate_dcache(target, address, size, count); | |||
} | |||
/** | |||
* Write memory | |||
*/ | |||
if ( ( retval = arm7_9_write_memory(target, address, | |||
size, count, buffer) ) != ERROR_OK ) | |||
{ | |||
retval = arm7_9_write_memory(target, address, size, count, buffer); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
/* * | |||
* 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 (!arm946e_preserve_cache && ic == 1) | |||
{ | |||
arm946e_invalidate_icache(target, address, size, count); | |||
} | |||
return ERROR_OK; | |||
} | |||
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; | |||
LOG_DEBUG("-"); | |||
if ( ( retval = arm7_9_read_memory(target, address, | |||
size, count, buffer) ) != ERROR_OK ) | |||
{ | |||
retval = arm7_9_read_memory(target, address, size, count, buffer); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
return ERROR_OK; | |||
} | |||
@@ -589,49 +553,37 @@ COMMAND_HANDLER(arm946e_handle_cp15_command) | |||
if (retval != ERROR_OK) | |||
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); | |||
return ERROR_OK; | |||
} | |||
/* 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; | |||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); | |||
if (CMD_ARGC == 1) | |||
{ | |||
if (CMD_ARGC == 1) { | |||
uint32_t value; | |||
if ((retval = arm946e_read_cp15(target, address, &value)) != ERROR_OK) | |||
{ | |||
command_print(CMD_CTX, | |||
"couldn't access reg %" PRIi32, | |||
address); | |||
retval = arm946e_read_cp15(target, address, &value); | |||
if (retval != ERROR_OK) { | |||
command_print(CMD_CTX, "couldn't access reg %" PRIi32, address); | |||
return ERROR_OK; | |||
} | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
command_print(CMD_CTX, "%" PRIi32 ": %8.8" PRIx32, | |||
address, value); | |||
} | |||
else if (CMD_ARGC == 2) | |||
{ | |||
command_print(CMD_CTX, "%" PRIi32 ": %8.8" PRIx32, address, value); | |||
} else if (CMD_ARGC == 2) { | |||
uint32_t value; | |||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value); | |||
if ((retval = arm946e_write_cp15(target, address, value)) != ERROR_OK) | |||
{ | |||
command_print(CMD_CTX, | |||
"couldn't access reg %" PRIi32, | |||
address); | |||
retval = arm946e_write_cp15(target, address, value); | |||
if (retval != ERROR_OK) { | |||
command_print(CMD_CTX, "couldn't access reg %" PRIi32, address); | |||
return ERROR_OK; | |||
} | |||
command_print(CMD_CTX, "%" PRIi32 ": %8.8" PRIx32, | |||
address, value); | |||
command_print(CMD_CTX, "%" PRIi32 ": %8.8" PRIx32, address, value); | |||
} | |||
} | |||
@@ -664,8 +616,7 @@ const struct command_registration arm946e_command_handlers[] = { | |||
}; | |||
/** Holds methods for ARM946 targets. */ | |||
struct target_type arm946e_target = | |||
{ | |||
struct target_type arm946e_target = { | |||
.name = "arm946e", | |||
.poll = arm7_9_poll, | |||
@@ -683,8 +634,8 @@ struct target_type arm946e_target = | |||
.get_gdb_reg_list = arm_get_gdb_reg_list, | |||
//.read_memory = arm7_9_read_memory, | |||
//.write_memory = arm7_9_write_memory, | |||
/* .read_memory = arm7_9_read_memory, */ | |||
/* .write_memory = arm7_9_write_memory, */ | |||
.read_memory = arm946e_read_memory, | |||
.write_memory = arm946e_write_memory, | |||
@@ -697,8 +648,8 @@ struct target_type arm946e_target = | |||
.add_breakpoint = arm7_9_add_breakpoint, | |||
.remove_breakpoint = arm7_9_remove_breakpoint, | |||
//.add_breakpoint = arm946e_add_breakpoint, | |||
//.remove_breakpoint = arm946e_remove_breakpoint, | |||
/* .add_breakpoint = arm946e_add_breakpoint, */ | |||
/* .remove_breakpoint = arm946e_remove_breakpoint, */ | |||
.add_watchpoint = arm7_9_add_watchpoint, | |||
.remove_watchpoint = arm7_9_remove_watchpoint, | |||
@@ -23,31 +23,30 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef ARM946E_H | |||
#define ARM946E_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; | |||
int common_magic; | |||
uint32_t cp15_control_reg; | |||
}; | |||
static inline struct arm946e_common * | |||
target_to_arm946(struct target *target) | |||
static inline struct arm946e_common *target_to_arm946(struct target *target) | |||
{ | |||
return container_of(target->arch_info, struct arm946e_common, | |||
arm7_9_common.arm); | |||
} | |||
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); | |||
extern const struct command_registration arm946e_command_handlers[]; | |||
#endif /* ARM946E_H */ | |||
#endif /* ARM946E_H */ |
@@ -20,6 +20,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -28,7 +29,6 @@ | |||
#include "target_type.h" | |||
#include "arm_opcodes.h" | |||
#if 0 | |||
#define _DEBUG_INSTRUCTION_EXECUTION_ | |||
#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) | |||
{ | |||
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); | |||
} | |||
@@ -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 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; | |||
} | |||
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
@@ -117,17 +116,16 @@ static int arm966e_read_cp15(struct target *target, int reg_addr, uint32_t *valu | |||
#ifdef _DEBUG_INSTRUCTION_EXECUTION_ | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
LOG_DEBUG("addr: 0x%x value: %8.8x", reg_addr, *value); | |||
#endif | |||
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 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); | |||
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; | |||
} | |||
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_IDLE); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
@@ -179,42 +176,36 @@ COMMAND_HANDLER(arm966e_handle_cp15_command) | |||
if (retval != ERROR_OK) | |||
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); | |||
return ERROR_OK; | |||
} | |||
/* 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; | |||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); | |||
if (CMD_ARGC == 1) | |||
{ | |||
if (CMD_ARGC == 1) { | |||
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, | |||
"couldn't access reg %" PRIi32, | |||
address); | |||
return ERROR_OK; | |||
} | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
command_print(CMD_CTX, "%" PRIi32 ": %8.8" PRIx32, | |||
address, value); | |||
} | |||
else if (CMD_ARGC == 2) | |||
{ | |||
} else if (CMD_ARGC == 2) { | |||
uint32_t 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, | |||
"couldn't access reg %" PRIi32, | |||
address); | |||
@@ -254,8 +245,7 @@ const struct command_registration arm966e_command_handlers[] = { | |||
}; | |||
/** Holds methods for ARM966 targets. */ | |||
struct target_type arm966e_target = | |||
{ | |||
struct target_type arm966e_target = { | |||
.name = "arm966e", | |||
.poll = arm7_9_poll, | |||
@@ -20,6 +20,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef ARM966E_H | |||
#define ARM966E_H | |||
@@ -27,8 +28,7 @@ | |||
#define ARM966E_COMMON_MAGIC 0x20f920f9 | |||
struct arm966e_common | |||
{ | |||
struct arm966e_common { | |||
struct arm7_9_common arm7_9_common; | |||
int common_magic; | |||
uint32_t cp15_control_reg; | |||
@@ -23,6 +23,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -32,7 +33,6 @@ | |||
#include "register.h" | |||
#include "arm_opcodes.h" | |||
/* | |||
* NOTE: this holds code that's used with multiple ARM9 processors: | |||
* - ARM9TDMI (ARMv4T) ... in ARM920, ARM922, and ARM940 cores | |||
@@ -47,8 +47,7 @@ | |||
#define _DEBUG_INSTRUCTION_EXECUTION_ | |||
#endif | |||
enum arm9tdmi_vector_bit | |||
{ | |||
enum arm9tdmi_vector_bit { | |||
ARM9TDMI_RESET_VECTOR = 0x01, | |||
ARM9TDMI_UNDEF_VECTOR = 0x02, | |||
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 */ | |||
if ((target->debug_reason != DBG_REASON_DBGRQ) | |||
&& (target->debug_reason != DBG_REASON_SINGLESTEP)) | |||
{ | |||
&& (target->debug_reason != DBG_REASON_SINGLESTEP)) { | |||
struct scan_field fields[3]; | |||
uint8_t databus[4]; | |||
uint8_t instructionbus[4]; | |||
@@ -99,19 +97,17 @@ int arm9tdmi_examine_debug_reason(struct target *target) | |||
fields[2].out_value = NULL; | |||
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; | |||
} | |||
retval = arm_jtag_set_instr(&arm7_9->jtag_info, arm7_9->jtag_info.intest_instr, NULL, TAP_DRPAUSE); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
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; | |||
} | |||
fields[0].in_value = NULL; | |||
fields[0].out_value = databus; | |||
@@ -154,10 +150,9 @@ int arm9tdmi_clock_out(struct arm_jtag *jtag_info, uint32_t instr, | |||
if (sysspeed) | |||
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; | |||
} | |||
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE); | |||
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].in_value = NULL; | |||
if (in) | |||
{ | |||
if (in) { | |||
fields[0].in_value = (uint8_t *)in; | |||
jtag_add_dr_scan(jtag_info->tap, 3, fields, TAP_DRPAUSE); | |||
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_runtest(0, TAP_DRPAUSE); | |||
#ifdef _DEBUG_INSTRUCTION_EXECUTION_ | |||
{ | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
if (in) | |||
{ | |||
LOG_DEBUG("instr: 0x%8.8x, out: 0x%8.8x, in: 0x%8.8x", instr, out, *in); | |||
} | |||
else | |||
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) */ | |||
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]; | |||
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; | |||
} | |||
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE); | |||
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_ | |||
{ | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
if (in) | |||
{ | |||
LOG_DEBUG("in: 0x%8.8x", *in); | |||
} | |||
else | |||
{ | |||
LOG_ERROR("BUG: called with in == NULL"); | |||
} | |||
} | |||
#endif | |||
@@ -282,10 +264,9 @@ int arm9tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info, | |||
int retval = ERROR_OK; | |||
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; | |||
} | |||
retval = arm_jtag_set_instr(jtag_info, jtag_info->intest_instr, NULL, TAP_DRPAUSE); | |||
if (retval != ERROR_OK) | |||
@@ -315,19 +296,14 @@ int arm9tdmi_clock_data_in_endianness(struct arm_jtag *jtag_info, | |||
#ifdef _DEBUG_INSTRUCTION_EXECUTION_ | |||
{ | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
if (in) | |||
{ | |||
LOG_DEBUG("in: 0x%8.8x", *(uint32_t*)in); | |||
} | |||
LOG_DEBUG("in: 0x%8.8x", *(uint32_t *)in); | |||
else | |||
{ | |||
LOG_ERROR("BUG: called with in == NULL"); | |||
} | |||
} | |||
#endif | |||
@@ -376,10 +352,9 @@ static void arm9tdmi_change_to_arm(struct target *target, | |||
/* NOP fetched, BX in Execute (1) */ | |||
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; | |||
} | |||
/* fix program counter: | |||
* 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, | |||
uint32_t mask, uint32_t* core_regs[16]) | |||
uint32_t mask, uint32_t *core_regs[16]) | |||
{ | |||
int i; | |||
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) */ | |||
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)) | |||
/* nothing fetched, STM in MEMORY (i'th cycle) */ | |||
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, | |||
uint32_t mask, void* buffer, int size) | |||
uint32_t mask, void *buffer, int size) | |||
{ | |||
int i; | |||
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) */ | |||
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)) | |||
/* nothing fetched, STM in MEMORY (i'th cycle) */ | |||
switch (size) | |||
{ | |||
switch (size) { | |||
case 4: | |||
arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be); | |||
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); | |||
/* rot == 4 writes flags, which takes only one cycle */ | |||
if (rot != 4) | |||
{ | |||
if (rot != 4) { | |||
/* nothing fetched, MSR in EXECUTE (2) */ | |||
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); | |||
/* 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) */ | |||
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)) | |||
/* nothing fetched, LDM still in EXECUTE (1 + i cycle) */ | |||
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); | |||
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); | |||
embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]); | |||
} | |||
else | |||
{ | |||
} else | |||
arm7_9_enable_eice_step(target, next_pc); | |||
} | |||
} | |||
void arm9tdmi_disable_single_step(struct target *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); | |||
embeddedice_store_reg(&arm7_9->eice_cache->reg_list[EICE_DBG_CTRL]); | |||
} | |||
else | |||
{ | |||
} else | |||
arm7_9_disable_eice_step(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) | |||
{ | |||
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); | |||
arm7_9->arm.is_armv4 = true; | |||
@@ -830,8 +792,7 @@ COMMAND_HANDLER(handle_arm9tdmi_catch_vectors_command) | |||
struct reg *vector_catch; | |||
uint32_t vector_catch_value; | |||
if (!target_was_examined(target)) | |||
{ | |||
if (!target_was_examined(target)) { | |||
LOG_ERROR("Target not examined yet"); | |||
return ERROR_FAIL; | |||
} | |||
@@ -853,42 +814,31 @@ COMMAND_HANDLER(handle_arm9tdmi_catch_vectors_command) | |||
/* get the current setting */ | |||
vector_catch_value = buf_get_u32(vector_catch->value, 0, 8); | |||
if (CMD_ARGC > 0) | |||
{ | |||
if (CMD_ARGC > 0) { | |||
vector_catch_value = 0x0; | |||
if (strcmp(CMD_ARGV[0], "all") == 0) | |||
{ | |||
vector_catch_value = 0xdf; | |||
} | |||
else if (strcmp(CMD_ARGV[0], "none") == 0) | |||
{ | |||
else if (strcmp(CMD_ARGV[0], "none") == 0) { | |||
/* do nothing */ | |||
} | |||
else | |||
{ | |||
for (unsigned i = 0; i < CMD_ARGC; i++) | |||
{ | |||
} else { | |||
for (unsigned i = 0; i < CMD_ARGC; i++) { | |||
/* go through list of vectors */ | |||
unsigned j; | |||
for (j = 0; arm9tdmi_vectors[j].name; j++) | |||
{ | |||
if (strcmp(CMD_ARGV[i], arm9tdmi_vectors[j].name) == 0) | |||
{ | |||
for (j = 0; arm9tdmi_vectors[j].name; j++) { | |||
if (strcmp(CMD_ARGV[i], arm9tdmi_vectors[j].name) == 0) { | |||
vector_catch_value |= arm9tdmi_vectors[j].value; | |||
break; | |||
} | |||
} | |||
/* 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]); | |||
/* reread current setting */ | |||
vector_catch_value = buf_get_u32( | |||
vector_catch->value, | |||
0, 8); | |||
break; | |||
} | |||
} | |||
@@ -935,8 +885,7 @@ const struct command_registration arm9tdmi_command_handlers[] = { | |||
}; | |||
/** Holds methods for ARM9TDMI targets. */ | |||
struct target_type arm9tdmi_target = | |||
{ | |||
struct target_type arm9tdmi_target = { | |||
.name = "arm9tdmi", | |||
.poll = arm7_9_poll, | |||
@@ -20,6 +20,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef 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, | |||
void *in, int size, int be); | |||
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, | |||
uint32_t mask, uint32_t core_regs[16]); | |||
@@ -73,7 +73,6 @@ | |||
#include "arm_adi_v5.h" | |||
#include <helper/time_support.h> | |||
/* 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 | |||
* 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; | |||
if (new_ap != dap->ap_current) | |||
{ | |||
if (new_ap != dap->ap_current) { | |||
dap->ap_current = new_ap; | |||
/* Switching AP invalidates cached values. | |||
* 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; | |||
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); */ | |||
retval = dap_queue_ap_write(dap, AP_REG_CSW, csw); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
dap->ap_csw_value = csw; | |||
} | |||
if (tar != dap->ap_tar_value) | |||
{ | |||
if (tar != dap->ap_tar_value) { | |||
/* LOG_DEBUG("DAP: Set TAR %x",tar); */ | |||
retval = dap_queue_ap_write(dap, AP_REG_TAR, tar); | |||
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; | |||
uint32_t adr = address; | |||
const uint8_t* pBuffer = buffer; | |||
const uint8_t *pBuffer = buffer; | |||
count >>= 2; | |||
wcount = count; | |||
/* if we have an unaligned access - reorder data */ | |||
if (adr & 0x3u) | |||
{ | |||
for (writecount = 0; writecount < count; writecount++) | |||
{ | |||
if (adr & 0x3u) { | |||
for (writecount = 0; writecount < count; writecount++) { | |||
int i; | |||
uint32_t outvalue; | |||
memcpy(&outvalue, pBuffer, sizeof(uint32_t)); | |||
for (i = 0; i < 4; i++) | |||
{ | |||
*((uint8_t*)pBuffer + (adr & 0x3)) = outvalue; | |||
for (i = 0; i < 4; i++) { | |||
*((uint8_t *)pBuffer + (adr & 0x3)) = outvalue; | |||
outvalue >>= 8; | |||
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*/ | |||
blocksize = max_tar_block_size(dap->tar_autoincr_block, address); | |||
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) | |||
return retval; | |||
for (writecount = 0; writecount < blocksize; writecount++) | |||
{ | |||
for (writecount = 0; writecount < blocksize; writecount++) { | |||
retval = dap_queue_ap_write(dap, AP_REG_DRW, | |||
*(uint32_t *) ((void *) (buffer + 4 * writecount))); | |||
if (retval != ERROR_OK) | |||
break; | |||
} | |||
if ((retval = dap_run(dap)) == ERROR_OK) | |||
{ | |||
retval = dap_run(dap); | |||
if (retval == ERROR_OK) { | |||
wcount = wcount - blocksize; | |||
address = address + 4 * blocksize; | |||
buffer = buffer + 4 * blocksize; | |||
} | |||
else | |||
{ | |||
} else | |||
errorcount++; | |||
} | |||
if (errorcount > 1) | |||
{ | |||
if (errorcount > 1) { | |||
LOG_WARNING("Block write error address 0x%" PRIx32 ", wcount 0x%x", address, wcount); | |||
return retval; | |||
} | |||
@@ -350,8 +337,7 @@ static int mem_ap_write_buf_packed_u16(struct adiv5_dap *dap, | |||
wcount = count >> 1; | |||
while (wcount > 0) | |||
{ | |||
while (wcount > 0) { | |||
int nbytes; | |||
/* 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; | |||
writecount = blocksize; | |||
do | |||
{ | |||
do { | |||
nbytes = MIN((writecount << 1), 4); | |||
if (nbytes < 4) | |||
{ | |||
if (nbytes < 4) { | |||
retval = mem_ap_write_buf_u16(dap, buffer, | |||
nbytes, address); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
LOG_WARNING("Block write error address " | |||
"0x%" PRIx32 ", count 0x%x", | |||
address, count); | |||
@@ -386,15 +369,12 @@ static int mem_ap_write_buf_packed_u16(struct adiv5_dap *dap, | |||
} | |||
address += nbytes >> 1; | |||
} | |||
else | |||
{ | |||
} else { | |||
uint32_t outvalue; | |||
memcpy(&outvalue, buffer, sizeof(uint32_t)); | |||
for (i = 0; i < nbytes; i++) | |||
{ | |||
*((uint8_t*)buffer + (address & 0x3)) = outvalue; | |||
for (i = 0; i < nbytes; i++) { | |||
*((uint8_t *)buffer + (address & 0x3)) = outvalue; | |||
outvalue >>= 8; | |||
address++; | |||
} | |||
@@ -405,8 +385,8 @@ static int mem_ap_write_buf_packed_u16(struct adiv5_dap *dap, | |||
if (retval != ERROR_OK) | |||
break; | |||
if ((retval = dap_run(dap)) != ERROR_OK) | |||
{ | |||
retval = dap_run(dap); | |||
if (retval != ERROR_OK) { | |||
LOG_WARNING("Block write error address " | |||
"0x%" PRIx32 ", count 0x%x", | |||
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) | |||
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); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
@@ -463,8 +442,7 @@ static int mem_ap_write_buf_packed_u8(struct adiv5_dap *dap, | |||
wcount = count; | |||
while (wcount > 0) | |||
{ | |||
while (wcount > 0) { | |||
int nbytes; | |||
/* 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; | |||
writecount = blocksize; | |||
do | |||
{ | |||
do { | |||
nbytes = MIN(writecount, 4); | |||
if (nbytes < 4) | |||
{ | |||
if (nbytes < 4) { | |||
retval = mem_ap_write_buf_u8(dap, buffer, nbytes, address); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
LOG_WARNING("Block write error address " | |||
"0x%" PRIx32 ", count 0x%x", | |||
address, count); | |||
@@ -494,15 +469,12 @@ static int mem_ap_write_buf_packed_u8(struct adiv5_dap *dap, | |||
} | |||
address += nbytes; | |||
} | |||
else | |||
{ | |||
} else { | |||
uint32_t outvalue; | |||
memcpy(&outvalue, buffer, sizeof(uint32_t)); | |||
for (i = 0; i < nbytes; i++) | |||
{ | |||
*((uint8_t*)buffer + (address & 0x3)) = outvalue; | |||
for (i = 0; i < nbytes; i++) { | |||
*((uint8_t *)buffer + (address & 0x3)) = outvalue; | |||
outvalue >>= 8; | |||
address++; | |||
} | |||
@@ -513,8 +485,8 @@ static int mem_ap_write_buf_packed_u8(struct adiv5_dap *dap, | |||
if (retval != ERROR_OK) | |||
break; | |||
if ((retval = dap_run(dap)) != ERROR_OK) | |||
{ | |||
retval = dap_run(dap); | |||
if (retval != ERROR_OK) { | |||
LOG_WARNING("Block write error address " | |||
"0x%" PRIx32 ", count 0x%x", | |||
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) | |||
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); | |||
if (retval != ERROR_OK) | |||
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; | |||
uint32_t adr = address; | |||
uint8_t* pBuffer = buffer; | |||
uint8_t *pBuffer = buffer; | |||
count >>= 2; | |||
wcount = count; | |||
while (wcount > 0) | |||
{ | |||
while (wcount > 0) { | |||
/* Adjust to read blocks within boundaries aligned to the | |||
* TAR autoincrement size (at least 2^10). Autoincrement | |||
* 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); | |||
if (retval != ERROR_OK) | |||
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 | |||
* previous one. Assumes read is acked "OK/FAULT", | |||
* 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; | |||
retval = dap_run(dap); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
errorcount++; | |||
if (errorcount <= 1) | |||
{ | |||
if (errorcount <= 1) { | |||
/* try again */ | |||
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 (adr & 0x3u) | |||
{ | |||
for (readcount = 0; readcount < count; readcount++) | |||
{ | |||
if (adr & 0x3u) { | |||
for (readcount = 0; readcount < count; readcount++) { | |||
int i; | |||
uint32_t data; | |||
memcpy(&data, pBuffer, sizeof(uint32_t)); | |||
for (i = 0; i < 4; i++) | |||
{ | |||
*((uint8_t*)pBuffer) = | |||
for (i = 0; i < 4; i++) { | |||
*((uint8_t *)pBuffer) = | |||
(data >> 8 * (adr & 0x3)); | |||
pBuffer++; | |||
adr++; | |||
@@ -688,8 +652,7 @@ static int mem_ap_read_buf_packed_u16(struct adiv5_dap *dap, | |||
wcount = count >> 1; | |||
while (wcount > 0) | |||
{ | |||
while (wcount > 0) { | |||
int nbytes; | |||
/* 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; | |||
readcount = blocksize; | |||
do | |||
{ | |||
do { | |||
retval = dap_queue_ap_read(dap, AP_REG_DRW, &invalue); | |||
if (retval != ERROR_OK) | |||
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); | |||
return retval; | |||
} | |||
nbytes = MIN((readcount << 1), 4); | |||
for (i = 0; i < nbytes; i++) | |||
{ | |||
*((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3)); | |||
for (i = 0; i < nbytes; i++) { | |||
*((uint8_t *)buffer) = (invalue >> 8 * (address & 0x3)); | |||
buffer++; | |||
address++; | |||
} | |||
@@ -751,8 +712,7 @@ int mem_ap_read_buf_u16(struct adiv5_dap *dap, uint8_t *buffer, | |||
if (count >= 4) | |||
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); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
@@ -764,17 +724,13 @@ int mem_ap_read_buf_u16(struct adiv5_dap *dap, uint8_t *buffer, | |||
if (retval != ERROR_OK) | |||
break; | |||
if (address & 0x1) | |||
{ | |||
for (i = 0; i < 2; i++) | |||
{ | |||
*((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3)); | |||
if (address & 0x1) { | |||
for (i = 0; i < 2; i++) { | |||
*((uint8_t *)buffer) = (invalue >> 8 * (address & 0x3)); | |||
buffer++; | |||
address++; | |||
} | |||
} | |||
else | |||
{ | |||
} else { | |||
uint16_t svalue = (invalue >> 8 * (address & 0x3)); | |||
memcpy(buffer, &svalue, sizeof(uint16_t)); | |||
address += 2; | |||
@@ -801,8 +757,7 @@ static int mem_ap_read_buf_packed_u8(struct adiv5_dap *dap, | |||
wcount = count; | |||
while (wcount > 0) | |||
{ | |||
while (wcount > 0) { | |||
int nbytes; | |||
/* 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; | |||
readcount = blocksize; | |||
do | |||
{ | |||
do { | |||
retval = dap_queue_ap_read(dap, AP_REG_DRW, &invalue); | |||
if (retval != ERROR_OK) | |||
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); | |||
return retval; | |||
} | |||
nbytes = MIN(readcount, 4); | |||
for (i = 0; i < nbytes; i++) | |||
{ | |||
*((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3)); | |||
for (i = 0; i < nbytes; i++) { | |||
*((uint8_t *)buffer) = (invalue >> 8 * (address & 0x3)); | |||
buffer++; | |||
address++; | |||
} | |||
@@ -861,8 +814,7 @@ int mem_ap_read_buf_u8(struct adiv5_dap *dap, uint8_t *buffer, | |||
if (count >= 4) | |||
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); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
@@ -873,7 +825,7 @@ int mem_ap_read_buf_u8(struct adiv5_dap *dap, uint8_t *buffer, | |||
if (retval != ERROR_OK) | |||
break; | |||
*((uint8_t*)buffer) = (invalue >> 8 * (address & 0x3)); | |||
*((uint8_t *)buffer) = (invalue >> 8 * (address & 0x3)); | |||
count--; | |||
address++; | |||
buffer++; | |||
@@ -999,9 +951,8 @@ int dap_syssec_kinetis_mdmap(struct adiv5_dap *dap) | |||
return retval; | |||
dap_run(dap); | |||
if ( val != 0x001C0000 ) | |||
{ | |||
LOG_DEBUG("id doesn't match %08X != 0x001C0000",val); | |||
if (val != 0x001C0000) { | |||
LOG_DEBUG("id doesn't match %08X != 0x001C0000", val); | |||
dap_ap_select(dap, 0); | |||
return ERROR_FAIL; | |||
} | |||
@@ -1015,40 +966,28 @@ int dap_syssec_kinetis_mdmap(struct adiv5_dap *dap) | |||
return retval; | |||
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"); | |||
if ( !(val & MDM_STAT_FMEEN) ) | |||
{ | |||
if (!(val & MDM_STAT_FMEEN)) | |||
LOG_DEBUG("MDMAP: masserase is disabled"); | |||
} | |||
else | |||
{ | |||
else { | |||
/* we need to assert reset */ | |||
if ( jtag_reset_config & RESET_HAS_SRST ) | |||
{ | |||
if (jtag_reset_config & RESET_HAS_SRST) { | |||
/* default to asserting srst */ | |||
if (jtag_reset_config & RESET_SRST_PULLS_TRST) | |||
{ | |||
jtag_add_reset(1, 1); | |||
} | |||
else | |||
{ | |||
jtag_add_reset(0, 1); | |||
} | |||
} | |||
else | |||
{ | |||
} else { | |||
LOG_DEBUG("SRST not configured"); | |||
dap_ap_select(dap, 0); | |||
return ERROR_FAIL; | |||
} | |||
while(1) | |||
{ | |||
while (1) { | |||
retval = dap_queue_ap_write(dap, MDM_REG_CTRL, MEM_CTRL_FMEIP); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
@@ -1058,14 +997,13 @@ int dap_syssec_kinetis_mdmap(struct adiv5_dap *dap) | |||
if (retval != ERROR_OK) | |||
return retval; | |||
dap_run(dap); | |||
LOG_DEBUG("MDM_REG_STAT %08X",val); | |||
LOG_DEBUG("MDM_REG_STAT %08X", val); | |||
if ( (val&1)) | |||
if ((val & 1)) | |||
break; | |||
} | |||
while(1) | |||
{ | |||
while (1) { | |||
retval = dap_queue_ap_write(dap, MDM_REG_CTRL, 0); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
@@ -1075,15 +1013,15 @@ int dap_syssec_kinetis_mdmap(struct adiv5_dap *dap) | |||
if (retval != ERROR_OK) | |||
return retval; | |||
dap_run(dap); | |||
LOG_DEBUG("MDM_REG_STAT %08X",val); | |||
LOG_DEBUG("MDM_REG_STAT %08X", val); | |||
/* read control register and wait for ready */ | |||
retval = dap_queue_ap_read(dap, MDM_REG_CTRL, &val); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
dap_run(dap); | |||
LOG_DEBUG("MDM_REG_CTRL %08X",val); | |||
LOG_DEBUG("MDM_REG_CTRL %08X", val); | |||
if ( val == 0x00 ) | |||
if (val == 0x00) | |||
break; | |||
} | |||
} | |||
@@ -1107,7 +1045,6 @@ static struct dap_syssec_filter dap_syssec_filter_data[] = { | |||
{ 0x4BA00477, dap_syssec_kinetis_mdmap } | |||
}; | |||
/** | |||
* | |||
*/ | |||
@@ -1116,15 +1053,12 @@ int dap_syssec(struct adiv5_dap *dap) | |||
unsigned int i; | |||
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; | |||
while (tap != NULL) | |||
{ | |||
if ( tap->hasidcode && (dap_syssec_filter_data[i].idcode == tap->idcode) ) | |||
{ | |||
LOG_DEBUG("DAP: mdmap_init for idcode: %08x",tap->idcode); | |||
while (tap != NULL) { | |||
if (tap->hasidcode && (dap_syssec_filter_data[i].idcode == tap->idcode)) { | |||
LOG_DEBUG("DAP: mdmap_init for idcode: %08x", tap->idcode); | |||
dap_syssec_filter_data[i].dap_init(dap); | |||
} | |||
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); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
if ((retval = dap_run(dap)) != ERROR_OK) | |||
retval = dap_run(dap); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
/* Check that we have debug power domains activated */ | |||
while (!(ctrlstat & CDBGPWRUPACK) && (cnt++ < 10)) | |||
{ | |||
while (!(ctrlstat & CDBGPWRUPACK) && (cnt++ < 10)) { | |||
LOG_DEBUG("DAP: wait CDBGPWRUPACK"); | |||
retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
if ((retval = dap_run(dap)) != ERROR_OK) | |||
retval = dap_run(dap); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
alive_sleep(10); | |||
} | |||
while (!(ctrlstat & CSYSPWRUPACK) && (cnt++ < 10)) | |||
{ | |||
while (!(ctrlstat & CSYSPWRUPACK) && (cnt++ < 10)) { | |||
LOG_DEBUG("DAP: wait CSYSPWRUPACK"); | |||
retval = dap_queue_dp_read(dap, DP_CTRL_STAT, &ctrlstat); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
if ((retval = dap_run(dap)) != ERROR_OK) | |||
retval = dap_run(dap); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
alive_sleep(10); | |||
} | |||
@@ -1248,16 +1183,15 @@ int ahbap_debugport_init(struct adiv5_dap *dap) | |||
/* CID interpretation -- see ARM IHI 0029B section 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", "Reserved", "Reserved", "Reserved", | |||
"Reserved", "CoreSight component", "Reserved", "Peripheral Test Block", | |||
"Reserved", "OptimoDE DESS", | |||
"Generic IP component", "PrimeCell or System component" | |||
"Generic IP component", "PrimeCell or System component" | |||
}; | |||
static bool | |||
is_dap_cid_ok(uint32_t cid3, uint32_t cid2, uint32_t cid1, uint32_t cid0) | |||
static bool is_dap_cid_ok(uint32_t cid3, uint32_t cid2, uint32_t cid1, uint32_t cid0) | |||
{ | |||
return cid3 == 0xb1 && cid2 == 0x05 | |||
&& ((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; | |||
dap_ap_select(dap, ap); | |||
do | |||
{ | |||
do { | |||
retval = mem_ap_read_atomic_u32(dap, (dbgbase&0xFFFFF000) | | |||
entry_offset, &romentry); | |||
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 */ | |||
mem_ap = ((apid&0x10000) && ((apid&0x0F) != 0)); | |||
command_print(cmd_ctx, "AP ID register 0x%8.8" PRIx32, apid); | |||
if (apid) | |||
{ | |||
switch (apid&0x0F) | |||
{ | |||
if (apid) { | |||
switch (apid&0x0F) { | |||
case 0: | |||
command_print(cmd_ctx, "\tType is JTAG-AP"); | |||
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. | |||
*/ | |||
if (mem_ap) | |||
command_print(cmd_ctx, "AP BASE 0x%8.8" PRIx32, | |||
dbgbase); | |||
} | |||
else | |||
{ | |||
command_print(cmd_ctx, "AP BASE 0x%8.8" PRIx32, dbgbase); | |||
} else | |||
command_print(cmd_ctx, "No AP found at this ap 0x%x", ap); | |||
} | |||
romtable_present = ((mem_ap) && (dbgbase != 0xFFFFFFFF)); | |||
if (romtable_present) | |||
{ | |||
uint32_t cid0,cid1,cid2,cid3,memtype,romentry; | |||
if (romtable_present) { | |||
uint32_t cid0, cid1, cid2, cid3, memtype, romentry; | |||
uint16_t entry_offset; | |||
/* 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 */ | |||
entry_offset = 0; | |||
do | |||
{ | |||
do { | |||
retval = mem_ap_read_atomic_u32(dap, (dbgbase&0xFFFFF000) | entry_offset, &romentry); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
command_print(cmd_ctx, "\tROMTABLE[0x%x] = 0x%" PRIx32 "",entry_offset,romentry); | |||
if (romentry&0x01) | |||
{ | |||
command_print(cmd_ctx, "\tROMTABLE[0x%x] = 0x%" PRIx32 "", entry_offset, romentry); | |||
if (romentry & 0x01) { | |||
uint32_t c_cid0, c_cid1, c_cid2, c_cid3; | |||
uint32_t c_pid0, c_pid1, c_pid2, c_pid3, c_pid4; | |||
uint32_t component_base; | |||
unsigned part_num; | |||
char *type, *full; | |||
component_base = (dbgbase & 0xFFFFF000) | |||
+ (romentry & 0xFFFFF000); | |||
component_base = (dbgbase & 0xFFFFF000) + (romentry & 0xFFFFF000); | |||
/* 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) | |||
return retval; | |||
c_pid0 &= 0xff; | |||
retval = mem_ap_read_atomic_u32(dap, | |||
component_base + 0xFE4, &c_pid1); | |||
retval = mem_ap_read_atomic_u32(dap, component_base + 0xFE4, &c_pid1); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
c_pid1 &= 0xff; | |||
retval = mem_ap_read_atomic_u32(dap, | |||
component_base + 0xFE8, &c_pid2); | |||
retval = mem_ap_read_atomic_u32(dap, component_base + 0xFE8, &c_pid2); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
c_pid2 &= 0xff; | |||
retval = mem_ap_read_atomic_u32(dap, | |||
component_base + 0xFEC, &c_pid3); | |||
retval = mem_ap_read_atomic_u32(dap, component_base + 0xFEC, &c_pid3); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
c_pid3 &= 0xff; | |||
retval = mem_ap_read_atomic_u32(dap, | |||
component_base + 0xFD0, &c_pid4); | |||
retval = mem_ap_read_atomic_u32(dap, component_base + 0xFD0, &c_pid4); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
c_pid4 &= 0xff; | |||
retval = mem_ap_read_atomic_u32(dap, | |||
component_base + 0xFF0, &c_cid0); | |||
retval = mem_ap_read_atomic_u32(dap, component_base + 0xFF0, &c_cid0); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
c_cid0 &= 0xff; | |||
retval = mem_ap_read_atomic_u32(dap, | |||
component_base + 0xFF4, &c_cid1); | |||
retval = mem_ap_read_atomic_u32(dap, component_base + 0xFF4, &c_cid1); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
c_cid1 &= 0xff; | |||
retval = mem_ap_read_atomic_u32(dap, | |||
component_base + 0xFF8, &c_cid2); | |||
retval = mem_ap_read_atomic_u32(dap, component_base + 0xFF8, &c_cid2); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
c_cid2 &= 0xff; | |||
retval = mem_ap_read_atomic_u32(dap, | |||
component_base + 0xFFC, &c_cid3); | |||
retval = mem_ap_read_atomic_u32(dap, component_base + 0xFFC, &c_cid3); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
c_cid3 &= 0xff; | |||
command_print(cmd_ctx, | |||
"\t\tComponent base address 0x%" PRIx32 | |||
", start address 0x%" PRIx32, | |||
component_base, | |||
command_print(cmd_ctx, "\t\tComponent base address 0x%" PRIx32 "," | |||
"start address 0x%" PRIx32, component_base, | |||
/* component may take multiple 4K pages */ | |||
component_base - 0x1000*(c_pid4 >> 4)); | |||
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)) | |||
command_print(cmd_ctx, | |||
"\t\tCID3 0%2.2x" | |||
"\t\tCID3 0%2.2x" | |||
", CID2 0%2.2x" | |||
", CID1 0%2.2x" | |||
", CID0 0%2.2x", | |||
@@ -1681,7 +1590,7 @@ static int dap_info_command(struct command_context *cmd_ctx, | |||
type = "CoreSight ETM11"; | |||
full = "(Embedded Trace)"; | |||
break; | |||
// case 0x113: what? | |||
/* case 0x113: what? */ | |||
case 0x120: /* from OMAP3 memmap */ | |||
type = "TI SDTI"; | |||
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", | |||
type, full); | |||
} | |||
else | |||
{ | |||
} else { | |||
if (romentry) | |||
command_print(cmd_ctx, "\t\tComponent not present"); | |||
else | |||
@@ -1751,11 +1658,8 @@ static int dap_info_command(struct command_context *cmd_ctx, | |||
} | |||
entry_offset += 4; | |||
} while (romentry > 0); | |||
} | |||
else | |||
{ | |||
} else | |||
command_print(cmd_ctx, "\tNo ROM table present"); | |||
} | |||
dap_ap_select(dap, ap_old); | |||
return ERROR_OK; | |||
@@ -1980,5 +1884,3 @@ const struct command_registration dap_command_handlers[] = { | |||
}, | |||
COMMAND_REGISTRATION_DONE | |||
}; | |||
@@ -20,6 +20,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef 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 | |||
* signals are available). | |||
*/ | |||
struct adiv5_dap | |||
{ | |||
struct adiv5_dap { | |||
const struct dap_ops *ops; | |||
struct arm_jtag *jtag_info; | |||
/* Control config */ | |||
uint32_t dp_ctrl_stat; | |||
uint32_t apsel; | |||
/** | |||
@@ -182,6 +181,7 @@ struct adiv5_dap | |||
* MEM-AP access before we try to read its status (and/or result). | |||
*/ | |||
uint32_t memaccess_tck; | |||
/* Size of TAR autoincrement block, ARM ADI Specification requires at least 10 bits */ | |||
uint32_t tar_autoincr_block; | |||
}; | |||
@@ -216,6 +216,7 @@ struct dap_ops { | |||
/** AP register write. */ | |||
int (*queue_ap_write)(struct adiv5_dap *dap, unsigned reg, | |||
uint32_t data); | |||
/** AP operation abort. */ | |||
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 reg The two-bit number of the DP register being read. | |||
* @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. | |||
*/ | |||
@@ -284,7 +285,7 @@ static inline int dap_queue_dp_write(struct adiv5_dap *dap, | |||
* @param dap The DAP used for reading. | |||
* @param reg The number of the AP register being read. | |||
* @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. | |||
*/ | |||
@@ -347,11 +348,11 @@ static inline int dap_run(struct adiv5_dap *dap) | |||
/** Accessor for currently selected DAP-AP number (0..255) */ | |||
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 */ | |||
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 */ | |||
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, | |||
const uint8_t *buffer, int count, uint32_t address); | |||
/* 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, | |||
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, | |||
const uint8_t *buffer, int count, uint32_t address); | |||
/* Initialisation of the debug system, power domains and registers */ | |||
int ahbap_debugport_init(struct adiv5_dap *swjdp); | |||
@@ -17,13 +17,13 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef ARM_DISASSEMBLER_H | |||
#define ARM_DISASSEMBLER_H | |||
#include <helper/types.h> | |||
enum arm_instruction_type | |||
{ | |||
enum arm_instruction_type { | |||
ARM_UNKNOWN_INSTUCTION, | |||
/* Branch instructions */ | |||
@@ -120,14 +120,12 @@ enum arm_instruction_type | |||
ARM_UNDEFINED_INSTRUCTION = 0xffffffff, | |||
}; | |||
struct arm_b_bl_bx_blx_instr | |||
{ | |||
struct arm_b_bl_bx_blx_instr { | |||
int reg_operand; | |||
uint32_t target_address; | |||
}; | |||
union arm_shifter_operand | |||
{ | |||
union arm_shifter_operand { | |||
struct { | |||
uint32_t immediate; | |||
} immediate; | |||
@@ -143,8 +141,7 @@ union arm_shifter_operand | |||
} register_shift; | |||
}; | |||
struct arm_data_proc_instr | |||
{ | |||
struct arm_data_proc_instr { | |||
int variant; /* 0: immediate, 1: immediate_shift, 2: register_shift */ | |||
uint8_t S; | |||
uint8_t Rn; | |||
@@ -152,15 +149,13 @@ struct arm_data_proc_instr | |||
union arm_shifter_operand shifter_operand; | |||
}; | |||
struct arm_load_store_instr | |||
{ | |||
struct arm_load_store_instr { | |||
uint8_t Rd; | |||
uint8_t Rn; | |||
uint8_t U; | |||
int index_mode; /* 0: offset, 1: pre-indexed, 2: post-indexed */ | |||
int offset_mode; /* 0: immediate, 1: (scaled) register */ | |||
union | |||
{ | |||
union { | |||
uint32_t offset; | |||
struct { | |||
uint8_t Rm; | |||
@@ -170,8 +165,7 @@ struct arm_load_store_instr | |||
} offset; | |||
}; | |||
struct arm_load_store_multiple_instr | |||
{ | |||
struct arm_load_store_multiple_instr { | |||
uint8_t Rn; | |||
uint32_t register_list; | |||
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; | |||
}; | |||
struct arm_instruction | |||
{ | |||
struct arm_instruction { | |||
enum arm_instruction_type type; | |||
char text[128]; | |||
uint32_t opcode; | |||
@@ -51,8 +51,8 @@ | |||
/* Read coprocessor */ | |||
static int dpm_mrc(struct target *target, int cpnum, | |||
uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, | |||
uint32_t *value) | |||
uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, | |||
uint32_t *value) | |||
{ | |||
struct arm *arm = target_to_arm(target); | |||
struct arm_dpm *dpm = arm->dpm; | |||
@@ -63,8 +63,8 @@ static int dpm_mrc(struct target *target, int cpnum, | |||
return retval; | |||
LOG_DEBUG("MRC p%d, %d, r0, c%d, c%d, %d", cpnum, | |||
(int) op1, (int) CRn, | |||
(int) CRm, (int) op2); | |||
(int) op1, (int) CRn, | |||
(int) CRm, (int) op2); | |||
/* read coprocessor register into R0; return via DCC */ | |||
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, | |||
uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, | |||
uint32_t value) | |||
uint32_t op1, uint32_t op2, uint32_t CRn, uint32_t CRm, | |||
uint32_t value) | |||
{ | |||
struct arm *arm = target_to_arm(target); | |||
struct arm_dpm *dpm = arm->dpm; | |||
@@ -88,8 +88,8 @@ static int dpm_mcr(struct target *target, int cpnum, | |||
return retval; | |||
LOG_DEBUG("MCR p%d, %d, r0, c%d, c%d, %d", cpnum, | |||
(int) op1, (int) CRn, | |||
(int) CRm, (int) op2); | |||
(int) op1, (int) CRn, | |||
(int) CRm, (int) op2); | |||
/* read DCC into r0; then write coprocessor register from R0 */ | |||
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; | |||
switch (regnum) { | |||
case 0 ... 14: | |||
/* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */ | |||
retval = dpm->instr_read_data_dcc(dpm, | |||
case 0 ... 14: | |||
/* return via DCC: "MCR p14, 0, Rnum, c0, c5, 0" */ | |||
retval = dpm->instr_read_data_dcc(dpm, | |||
ARMV4_5_MCR(14, 0, regnum, 0, 5, 0), | |||
&value); | |||
break; | |||
case 15: /* PC */ | |||
/* "MOV r0, pc"; then return via DCC */ | |||
retval = dpm->instr_read_data_r0(dpm, 0xe1a0000f, &value); | |||
/* NOTE: this seems like a slightly awkward place to update | |||
* this value ... but if the PC gets written (the only way | |||
* to change what we compute), the arch spec says subsequent | |||
* reads return values which are "unpredictable". So this | |||
* is always right except in those broken-by-intent cases. | |||
*/ | |||
switch (dpm->arm->core_state) { | |||
case ARM_STATE_ARM: | |||
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"); | |||
case 15:/* PC | |||
* "MOV r0, pc"; then return via DCC */ | |||
retval = dpm->instr_read_data_r0(dpm, 0xe1a0000f, &value); | |||
/* NOTE: this seems like a slightly awkward place to update | |||
* this value ... but if the PC gets written (the only way | |||
* to change what we compute), the arch spec says subsequent | |||
* reads return values which are "unpredictable". So this | |||
* is always right except in those broken-by-intent cases. | |||
*/ | |||
switch (dpm->arm->core_state) { | |||
case ARM_STATE_ARM: | |||
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; | |||
default: | |||
/* 16: "MRS r0, CPSR"; then return via DCC | |||
* 17: "MRS r0, SPSR"; then return via DCC | |||
*/ | |||
retval = dpm->instr_read_data_r0(dpm, | |||
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), | |||
&value); | |||
break; | |||
break; | |||
} | |||
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); | |||
switch (regnum) { | |||
case 0 ... 14: | |||
/* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */ | |||
retval = dpm->instr_write_data_dcc(dpm, | |||
case 0 ... 14: | |||
/* load register from DCC: "MRC p14, 0, Rnum, c0, c5, 0" */ | |||
retval = dpm->instr_write_data_dcc(dpm, | |||
ARMV4_5_MRC(14, 0, regnum, 0, 5, 0), | |||
value); | |||
break; | |||
case 15: /* PC */ | |||
/* read r0 from DCC; then "MOV pc, r0" */ | |||
retval = dpm->instr_write_data_r0(dpm, 0xe1a0f000, value); | |||
break; | |||
default: | |||
/* 16: read r0 from DCC, then "MSR r0, CPSR_cxsf" | |||
* 17: read r0 from DCC, then "MSR r0, SPSR_cxsf" | |||
*/ | |||
retval = dpm->instr_write_data_r0(dpm, | |||
break; | |||
case 15:/* PC | |||
* read r0 from DCC; then "MOV pc, r0" */ | |||
retval = dpm->instr_write_data_r0(dpm, 0xe1a0f000, value); | |||
break; | |||
default: | |||
/* 16: read r0 from DCC, then "MSR r0, CPSR_cxsf" | |||
* 17: read r0 from DCC, then "MSR r0, SPSR_cxsf" | |||
*/ | |||
retval = dpm->instr_write_data_r0(dpm, | |||
ARMV4_5_MSR_GP(0, 0xf, regnum & 1), | |||
value); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
if (retval != ERROR_OK) | |||
return retval; | |||
if (regnum == 16 && dpm->instr_cpsr_sync) | |||
retval = dpm->instr_cpsr_sync(dpm); | |||
if (regnum == 16 && dpm->instr_cpsr_sync) | |||
retval = dpm->instr_cpsr_sync(dpm); | |||
break; | |||
break; | |||
} | |||
if (retval == ERROR_OK) { | |||
@@ -292,7 +292,7 @@ fail: | |||
* or running debugger code. | |||
*/ | |||
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; | |||
bool disable; | |||
@@ -325,10 +325,10 @@ static int dpm_maybe_update_bpwp(struct arm_dpm *dpm, bool bpwp, | |||
if (retval != ERROR_OK) | |||
LOG_ERROR("%s: can't %s HW %spoint %d", | |||
disable ? "disable" : "enable", | |||
target_name(dpm->arm->target), | |||
(xp->number < 16) ? "break" : "watch", | |||
xp->number & 0xf); | |||
disable ? "disable" : "enable", | |||
target_name(dpm->arm->target), | |||
(xp->number < 16) ? "break" : "watch", | |||
xp->number & 0xf); | |||
done: | |||
return retval; | |||
} | |||
@@ -423,25 +423,24 @@ int arm_dpm_write_dirty_registers(struct arm_dpm *dpm, bool bpwp) | |||
/* cope with special cases */ | |||
switch (regnum) { | |||
case 8 ... 12: | |||
/* r8..r12 "anything but FIQ" case; | |||
* we "know" core mode is accurate | |||
* since we haven't changed it yet | |||
*/ | |||
if (arm->core_mode == ARM_MODE_FIQ | |||
case 8 ... 12: | |||
/* r8..r12 "anything but FIQ" case; | |||
* we "know" core mode is accurate | |||
* since we haven't changed it yet | |||
*/ | |||
if (arm->core_mode == ARM_MODE_FIQ | |||
&& ARM_MODE_ANY | |||
!= mode) | |||
tmode = ARM_MODE_USR; | |||
break; | |||
case 16: | |||
/* SPSR */ | |||
regnum++; | |||
break; | |||
!= mode) | |||
tmode = ARM_MODE_USR; | |||
break; | |||
case 16: | |||
/* SPSR */ | |||
regnum++; | |||
break; | |||
} | |||
/* REVISIT error checks */ | |||
if (tmode != ARM_MODE_ANY) | |||
{ | |||
if (tmode != ARM_MODE_ANY) { | |||
retval = dpm_modeswitch(dpm, tmode); | |||
if (retval != ERROR_OK) | |||
goto done; | |||
@@ -490,34 +489,34 @@ done: | |||
* or MODE_ANY. | |||
*/ | |||
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; | |||
/* don't switch if the mode is already correct */ | |||
if (amode == ARM_MODE_SYS) | |||
amode = ARM_MODE_USR; | |||
amode = ARM_MODE_USR; | |||
if (mode == amode) | |||
return ARM_MODE_ANY; | |||
switch (num) { | |||
/* don't switch for non-shadowed registers (r0..r7, r15/pc, cpsr) */ | |||
case 0 ... 7: | |||
case 15: | |||
case 16: | |||
break; | |||
/* r8..r12 aren't shadowed for anything except FIQ */ | |||
case 8 ... 12: | |||
if (mode == ARM_MODE_FIQ) | |||
/* don't switch for non-shadowed registers (r0..r7, r15/pc, cpsr) */ | |||
case 0 ... 7: | |||
case 15: | |||
case 16: | |||
break; | |||
/* r8..r12 aren't shadowed for anything except FIQ */ | |||
case 8 ... 12: | |||
if (mode == ARM_MODE_FIQ) | |||
return mode; | |||
break; | |||
/* r13/sp, and r14/lr are always shadowed */ | |||
case 13: | |||
case 14: | |||
return mode; | |||
break; | |||
/* r13/sp, and r14/lr are always shadowed */ | |||
case 13: | |||
case 14: | |||
return mode; | |||
default: | |||
LOG_WARNING("invalid register #%u", num); | |||
break; | |||
default: | |||
LOG_WARNING("invalid register #%u", num); | |||
break; | |||
} | |||
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, | |||
int regnum, enum arm_mode mode) | |||
int regnum, enum arm_mode mode) | |||
{ | |||
struct arm_dpm *dpm = target_to_arm(target)->dpm; | |||
int retval; | |||
@@ -572,7 +571,7 @@ fail: | |||
} | |||
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; | |||
int retval; | |||
@@ -693,7 +692,7 @@ done: | |||
*/ | |||
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; | |||
@@ -710,26 +709,26 @@ static int dpm_bpwp_setup(struct arm_dpm *dpm, struct dpm_bpwp *xp, | |||
* v7 hardware, unaligned 4-byte ones too. | |||
*/ | |||
switch (length) { | |||
case 1: | |||
control |= (1 << (addr & 3)) << 5; | |||
break; | |||
case 2: | |||
/* require 2-byte alignment */ | |||
if (!(addr & 1)) { | |||
control |= (3 << (addr & 2)) << 5; | |||
case 1: | |||
control |= (1 << (addr & 3)) << 5; | |||
break; | |||
} | |||
case 2: | |||
/* require 2-byte alignment */ | |||
if (!(addr & 1)) { | |||
control |= (3 << (addr & 2)) << 5; | |||
break; | |||
} | |||
/* FALL THROUGH */ | |||
case 4: | |||
/* require 4-byte alignment */ | |||
if (!(addr & 3)) { | |||
control |= 0xf << 5; | |||
break; | |||
} | |||
case 4: | |||
/* require 4-byte alignment */ | |||
if (!(addr & 3)) { | |||
control |= 0xf << 5; | |||
break; | |||
} | |||
/* FALL THROUGH */ | |||
default: | |||
LOG_ERROR("unsupported {break,watch}point length/alignment"); | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
default: | |||
LOG_ERROR("unsupported {break,watch}point length/alignment"); | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
} | |||
/* other shared control bits: | |||
@@ -743,7 +742,7 @@ static int dpm_bpwp_setup(struct arm_dpm *dpm, struct dpm_bpwp *xp, | |||
xp->dirty = true; | |||
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() */ | |||
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, | |||
struct watchpoint *wp) | |||
struct watchpoint *wp) | |||
{ | |||
int retval; | |||
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; | |||
switch (wp->rw) { | |||
case WPT_READ: | |||
control |= 1 << 3; | |||
break; | |||
case WPT_WRITE: | |||
control |= 2 << 3; | |||
break; | |||
case WPT_ACCESS: | |||
control |= 3 << 3; | |||
break; | |||
case WPT_READ: | |||
control |= 1 << 3; | |||
break; | |||
case WPT_WRITE: | |||
control |= 2 << 3; | |||
break; | |||
case WPT_ACCESS: | |||
control |= 3 << 3; | |||
break; | |||
} | |||
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) | |||
{ | |||
switch (dpm->arm->core_state) { | |||
case ARM_STATE_ARM: | |||
addr -= 8; | |||
break; | |||
case ARM_STATE_THUMB: | |||
case ARM_STATE_THUMB_EE: | |||
addr -= 4; | |||
break; | |||
case ARM_STATE_JAZELLE: | |||
/* ?? */ | |||
break; | |||
case ARM_STATE_ARM: | |||
addr -= 8; | |||
break; | |||
case ARM_STATE_THUMB: | |||
case ARM_STATE_THUMB_EE: | |||
addr -= 4; | |||
break; | |||
case ARM_STATE_JAZELLE: | |||
/* ?? */ | |||
break; | |||
} | |||
dpm->wp_pc = addr; | |||
} | |||
@@ -902,25 +901,25 @@ void arm_dpm_report_dscr(struct arm_dpm *dpm, uint32_t dscr) | |||
/* Examine debug reason */ | |||
switch (DSCR_ENTRY(dscr)) { | |||
case 6: /* Data abort (v6 only) */ | |||
case 7: /* Prefetch abort (v6 only) */ | |||
case 6: /* Data abort (v6 only) */ | |||
case 7: /* Prefetch abort (v6 only) */ | |||
/* FALL THROUGH -- assume a v6 core in abort mode */ | |||
case 0: /* HALT request from debugger */ | |||
case 4: /* EDBGRQ */ | |||
target->debug_reason = DBG_REASON_DBGRQ; | |||
break; | |||
case 1: /* HW breakpoint */ | |||
case 3: /* SW BKPT */ | |||
case 5: /* vector catch */ | |||
target->debug_reason = DBG_REASON_BREAKPOINT; | |||
break; | |||
case 2: /* asynch watchpoint */ | |||
case 10: /* precise watchpoint */ | |||
target->debug_reason = DBG_REASON_WATCHPOINT; | |||
break; | |||
default: | |||
target->debug_reason = DBG_REASON_UNDEFINED; | |||
break; | |||
case 0: /* HALT request from debugger */ | |||
case 4: /* EDBGRQ */ | |||
target->debug_reason = DBG_REASON_DBGRQ; | |||
break; | |||
case 1: /* HW breakpoint */ | |||
case 3: /* SW BKPT */ | |||
case 5: /* vector catch */ | |||
target->debug_reason = DBG_REASON_BREAKPOINT; | |||
break; | |||
case 2: /* asynch watchpoint */ | |||
case 10:/* precise watchpoint */ | |||
target->debug_reason = DBG_REASON_WATCHPOINT; | |||
break; | |||
default: | |||
target->debug_reason = DBG_REASON_UNDEFINED; | |||
break; | |||
} | |||
} | |||
@@ -984,7 +983,7 @@ int arm_dpm_setup(struct arm_dpm *dpm) | |||
} | |||
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 | |||
* execution context IDs... | |||
@@ -126,7 +126,7 @@ struct arm_dpm { | |||
/** Recent value of 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); | |||
@@ -20,18 +20,19 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
#include "arm_jtag.h" | |||
#if 0 | |||
#define _ARM_JTAG_SCAN_N_CHECK_ | |||
#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; | |||
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; | |||
if (no_verify_capture == NULL) | |||
{ | |||
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 | |||
* 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]; | |||
int num_bits[1]; | |||
values[0]=new_scan_chain; | |||
num_bits[0]=jtag_info->scann_size; | |||
values[0] = new_scan_chain; | |||
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; | |||
} | |||
jtag_add_dr_out(jtag_info->tap, | |||
1, | |||
@@ -87,9 +85,7 @@ static int arm_jtag_reset_callback(enum jtag_event event, void *priv) | |||
struct arm_jtag *jtag_info = priv; | |||
if (event == JTAG_TRST_ASSERTED) | |||
{ | |||
jtag_info->cur_scan_chain = 0; | |||
} | |||
return ERROR_OK; | |||
} | |||
@@ -20,13 +20,13 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef ARM_JTAG | |||
#define ARM_JTAG | |||
#include <jtag/jtag.h> | |||
struct arm_jtag | |||
{ | |||
struct arm_jtag { | |||
struct jtag_tap *tap; | |||
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, | |||
void *no_verify_capture, | |||
tap_state_t end_state); | |||
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) | |||
{ | |||
/* inline most common code path */ | |||
struct jtag_tap *tap; | |||
tap = jtag_info->tap; | |||
assert (tap != NULL); | |||
assert(tap != NULL); | |||
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 ERROR_OK; | |||
} | |||
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) | |||
{ | |||
/* inline most common code path */ | |||
int retval = ERROR_OK; | |||
if (jtag_info->cur_scan_chain != new_scan_chain) | |||
{ | |||
return arm_jtag_scann_inner(jtag_info, new_scan_chain, end_state); | |||
} | |||
return retval; | |||
} | |||
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 */ | |||
static __inline__ void arm7flip32(jtag_callback_data_t arg) | |||
static inline void arm7flip32(jtag_callback_data_t arg) | |||
{ | |||
uint8_t *in = (uint8_t *)arg; | |||
*((uint32_t *)arg) = flip_u32(le_to_h_u32(in), 32); | |||
uint8_t *in = (uint8_t *)arg; | |||
*((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; | |||
*((uint32_t *)arg) = le_to_h_u32(in); | |||
uint8_t *in = (uint8_t *)arg; | |||
*((uint32_t *)arg) = le_to_h_u32(in); | |||
} | |||
#endif /* ARM_JTAG */ | |||
@@ -90,8 +90,8 @@ | |||
* Rd: register to load | |||
* 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 | |||
* Rd: register to load | |||
* Rn: base register | |||
@@ -108,7 +108,7 @@ | |||
* Rd: register to store | |||
* 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 | |||
* Rd: register to store | |||
@@ -323,7 +323,7 @@ static int do_semihosting(struct target *target) | |||
if (l < s) | |||
result = -1; | |||
else { | |||
retval = target_write_buffer(target, a, s, (void*)arg); | |||
retval = target_write_buffer(target, a, s, (void *)arg); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
result = 0; | |||
@@ -392,8 +392,7 @@ static int do_semihosting(struct target *target) | |||
/* REVISIT this looks wrong ... ARM11 and Cortex-A8 | |||
* 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; | |||
/* return value in R0 */ | |||
@@ -402,7 +401,7 @@ static int do_semihosting(struct target *target) | |||
/* LR --> PC */ | |||
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; | |||
/* saved PSR --> current PSR */ | |||
@@ -418,9 +417,7 @@ static int do_semihosting(struct target *target) | |||
if (spsr & 0x20) | |||
arm->core_state = ARM_STATE_THUMB; | |||
} | |||
else | |||
{ | |||
} else { | |||
/* resume execution, this will be pc+2 to skip over the | |||
* bkpt instruction */ | |||
@@ -454,8 +451,7 @@ int arm_semihosting(struct target *target, int *retval) | |||
if (!arm->is_semihosting) | |||
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) | |||
return 0; | |||
@@ -510,9 +506,7 @@ int arm_semihosting(struct target *target, int *retval) | |||
if (insn != 0xEF123456) | |||
return 0; | |||
} | |||
} | |||
else if (is_armv7m(target_to_armv7m(target))) | |||
{ | |||
} else if (is_armv7m(target_to_armv7m(target))) { | |||
uint16_t insn; | |||
if (target->debug_reason != DBG_REASON_BREAKPOINT) | |||
@@ -529,9 +523,7 @@ int arm_semihosting(struct target *target, int *retval) | |||
/* bkpt 0xAB */ | |||
if (insn != 0xBEAB) | |||
return 0; | |||
} | |||
else | |||
{ | |||
} else { | |||
LOG_ERROR("Unsupported semi-hosting Target"); | |||
return 0; | |||
} | |||
@@ -20,6 +20,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -32,51 +33,32 @@ | |||
#include "register.h" | |||
#include <helper/log.h> | |||
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; | |||
shift_amount &= 0xff; | |||
if (shift == 0x0) /* LSL */ | |||
{ | |||
if ((shift_amount > 0) && (shift_amount <= 32)) | |||
{ | |||
if (shift == 0x0) { /* LSL */ | |||
if ((shift_amount > 0) && (shift_amount <= 32)) { | |||
return_value = Rm << shift_amount; | |||
*carry = Rm >> (32 - shift_amount); | |||
} | |||
else if (shift_amount > 32) | |||
{ | |||
} else if (shift_amount > 32) { | |||
return_value = 0x0; | |||
*carry = 0x0; | |||
} | |||
else /* (shift_amount == 0) */ | |||
{ | |||
} else /* (shift_amount == 0) */ | |||
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; | |||
*carry = (Rm >> (shift_amount - 1)) & 1; | |||
} | |||
else if (shift_amount > 32) | |||
{ | |||
} else if (shift_amount > 32) { | |||
return_value = 0x0; | |||
*carry = 0x0; | |||
} | |||
else /* (shift_amount == 0) */ | |||
{ | |||
} else /* (shift_amount == 0) */ | |||
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 | |||
* be logical (shift in zeroes); simulate an arithmetic | |||
* 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; | |||
if (Rm & 0x80000000) | |||
return_value |= 0xffffffff << (32 - shift_amount); | |||
} | |||
else if (shift_amount > 32) | |||
{ | |||
if (Rm & 0x80000000) | |||
{ | |||
} else if (shift_amount > 32) { | |||
if (Rm & 0x80000000) { | |||
return_value = 0xffffffff; | |||
*carry = 0x1; | |||
} | |||
else | |||
{ | |||
} else { | |||
return_value = 0x0; | |||
*carry = 0x0; | |||
} | |||
} | |||
else /* (shift_amount == 0) */ | |||
{ | |||
} else /* (shift_amount == 0) */ | |||
return_value = Rm; | |||
} | |||
} | |||
else if (shift == 0x3) /* ROR */ | |||
{ | |||
} else if (shift == 0x3) { /* ROR */ | |||
if (shift_amount == 0) | |||
{ | |||
return_value = Rm; | |||
} | |||
else | |||
{ | |||
else { | |||
shift_amount = shift_amount % 32; | |||
return_value = (Rm >> shift_amount) | (Rm << (32 - shift_amount)); | |||
*carry = (return_value >> 31) & 0x1; | |||
} | |||
} | |||
else if (shift == 0x4) /* RRX */ | |||
{ | |||
} else if (shift == 0x4) { /* RRX */ | |||
return_value = Rm >> 1; | |||
if (*carry) | |||
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, | |||
int variant, union arm_shifter_operand shifter_operand, | |||
uint8_t *shifter_carry_out) | |||
int variant, union arm_shifter_operand shifter_operand, | |||
uint8_t *shifter_carry_out) | |||
{ | |||
uint32_t return_value; | |||
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); | |||
if (variant == 0) /* 32-bit 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); | |||
/* 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, | |||
Rm, shifter_operand.immediate_shift.shift_imm, | |||
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 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, | |||
Rm, Rs, shifter_carry_out); | |||
} | |||
else | |||
{ | |||
} else { | |||
LOG_ERROR("BUG: shifter_operand.variant not 0, 1 or 2"); | |||
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) | |||
{ | |||
switch ((opcode & 0xf0000000) >> 28) | |||
{ | |||
switch ((opcode & 0xf0000000) >> 28) { | |||
case 0x0: /* EQ */ | |||
if (cpsr & 0x40000000) | |||
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 | |||
*/ | |||
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); | |||
struct arm_instruction instruction; | |||
int instruction_size; | |||
int retval = ERROR_OK; | |||
if (sim->get_state(sim) == ARM_STATE_ARM) | |||
{ | |||
if (sim->get_state(sim) == ARM_STATE_ARM) { | |||
uint32_t opcode; | |||
/* 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; | |||
} | |||
if ((retval = arm_evaluate_opcode(opcode, current_pc, &instruction)) != ERROR_OK) | |||
{ | |||
retval = arm_evaluate_opcode(opcode, current_pc, &instruction); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
instruction_size = 4; | |||
/* 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) | |||
{ | |||
*dry_run_pc = current_pc + instruction_size; | |||
} | |||
else | |||
{ | |||
sim->set_reg(sim, 15, current_pc + instruction_size); | |||
} | |||
return ERROR_OK; | |||
} | |||
} | |||
else | |||
{ | |||
} else { | |||
uint16_t 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) */ | |||
if ((opcode & 0xf000) == 0xd000 | |||
&& !thumb_pass_branch_condition( | |||
sim->get_cpsr(sim, 0, 32), opcode)) | |||
{ | |||
&& !thumb_pass_branch_condition( | |||
sim->get_cpsr(sim, 0, 32), opcode)) { | |||
if (dry_run_pc) | |||
{ | |||
*dry_run_pc = current_pc + instruction_size; | |||
} | |||
else | |||
{ | |||
sim->set_reg(sim, 15, current_pc + instruction_size); | |||
} | |||
return ERROR_OK; | |||
} | |||
@@ -362,67 +306,44 @@ static int arm_simulate_step_core(struct target *target, | |||
/* examine instruction type */ | |||
/* branch instructions */ | |||
if ((instruction.type >= ARM_B) && (instruction.type <= ARM_BLX)) | |||
{ | |||
if ((instruction.type >= ARM_B) && (instruction.type <= ARM_BLX)) { | |||
uint32_t target_address; | |||
if (instruction.info.b_bl_bx_blx.reg_operand == -1) | |||
{ | |||
target_address = instruction.info.b_bl_bx_blx.target_address; | |||
} | |||
else | |||
{ | |||
target_address = sim->get_reg_mode(sim, instruction.info.b_bl_bx_blx.reg_operand); | |||
else { | |||
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) | |||
{ | |||
target_address += 2 * instruction_size; | |||
} | |||
} | |||
if (dry_run_pc) | |||
{ | |||
if (dry_run_pc) { | |||
*dry_run_pc = target_address & ~1; | |||
return ERROR_OK; | |||
} | |||
else | |||
{ | |||
} else { | |||
if (instruction.type == ARM_B) | |||
{ | |||
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); | |||
int T = (sim->get_state(sim) == ARM_STATE_THUMB); | |||
sim->set_reg_mode(sim, 14, old_pc + 4 + T); | |||
sim->set_reg(sim, 15, target_address); | |||
} | |||
else if (instruction.type == ARM_BX) | |||
{ | |||
} else if (instruction.type == ARM_BX) { | |||
if (target_address & 0x1) | |||
{ | |||
sim->set_state(sim, ARM_STATE_THUMB); | |||
} | |||
else | |||
{ | |||
sim->set_state(sim, ARM_STATE_ARM); | |||
} | |||
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); | |||
int T = (sim->get_state(sim) == ARM_STATE_THUMB); | |||
sim->set_reg_mode(sim, 14, old_pc + 4 + T); | |||
if (target_address & 0x1) | |||
{ | |||
sim->set_state(sim, ARM_STATE_THUMB); | |||
} | |||
else | |||
{ | |||
sim->set_state(sim, ARM_STATE_ARM); | |||
} | |||
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) */ | |||
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; | |||
uint8_t C = sim->get_cpsr(sim, 29, 1); | |||
uint8_t carry_out; | |||
@@ -480,17 +400,14 @@ static int arm_simulate_step_core(struct target *target, | |||
else | |||
LOG_WARNING("unhandled instruction type"); | |||
if (dry_run_pc) | |||
{ | |||
if (dry_run_pc) { | |||
if (instruction.info.data_proc.Rd == 15) | |||
*dry_run_pc = Rd & ~1; | |||
else | |||
*dry_run_pc = current_pc + instruction_size; | |||
return ERROR_OK; | |||
} | |||
else | |||
{ | |||
} else { | |||
if (instruction.info.data_proc.Rd == 15) { | |||
sim->set_reg_mode(sim, 15, Rd & ~1); | |||
if (Rd & 1) | |||
@@ -504,21 +421,15 @@ static int arm_simulate_step_core(struct target *target, | |||
} | |||
} | |||
/* compare instructions (CMP, CMN, TST, TEQ) */ | |||
else if ((instruction.type >= ARM_TST) && (instruction.type <= ARM_CMN)) | |||
{ | |||
if (dry_run_pc) | |||
{ | |||
else if ((instruction.type >= ARM_TST) && (instruction.type <= ARM_CMN)) { | |||
if (dry_run_pc) { | |||
*dry_run_pc = current_pc + instruction_size; | |||
return ERROR_OK; | |||
} | |||
else | |||
{ | |||
} else | |||
LOG_WARNING("no updating of flags yet"); | |||
} | |||
} | |||
/* 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 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) | |||
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) | |||
modified_address = Rn + instruction.info.load_store.offset.offset; | |||
else | |||
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 Rm = sim->get_reg_mode(sim, | |||
instruction.info.load_store.offset.reg.Rm); | |||
@@ -548,31 +456,23 @@ static int arm_simulate_step_core(struct target *target, | |||
modified_address = Rn + offset; | |||
else | |||
modified_address = Rn - offset; | |||
} | |||
else | |||
{ | |||
} else | |||
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 | |||
* we load from the modified address, but don't change | |||
* the base address register | |||
*/ | |||
load_address = modified_address; | |||
modified_address = Rn; | |||
} | |||
else if (instruction.info.load_store.index_mode == 1) | |||
{ | |||
} else if (instruction.info.load_store.index_mode == 1) { | |||
/* pre-indexed mode | |||
* we load from the modified address, and write it | |||
* back to the base address register | |||
*/ | |||
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 | |||
* we load from the unmodified address, and write the | |||
* modified address back | |||
@@ -580,28 +480,24 @@ static int arm_simulate_step_core(struct target *target, | |||
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); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
if (dry_run_pc) | |||
{ | |||
if (dry_run_pc) { | |||
if (instruction.info.load_store.Rd == 15) | |||
*dry_run_pc = load_value & ~1; | |||
else | |||
*dry_run_pc = current_pc + instruction_size; | |||
return ERROR_OK; | |||
} | |||
else | |||
{ | |||
} else { | |||
if ((instruction.info.load_store.index_mode == 1) || | |||
(instruction.info.load_store.index_mode == 2)) | |||
{ | |||
sim->set_reg_mode(sim, instruction.info.load_store.Rn, modified_address); | |||
} | |||
sim->set_reg_mode(sim, | |||
instruction.info.load_store.Rn, | |||
modified_address); | |||
if (instruction.info.load_store.Rd == 15) { | |||
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 */ | |||
else if (instruction.type == ARM_LDM) | |||
{ | |||
else if (instruction.type == ARM_LDM) { | |||
int i; | |||
uint32_t Rn = sim->get_reg_mode(sim, instruction.info.load_store_multiple.Rn); | |||
uint32_t load_values[16]; | |||
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)) | |||
bits_set++; | |||
} | |||
switch (instruction.info.load_store_multiple.addressing_mode) | |||
{ | |||
case 0: /* Increment after */ | |||
switch (instruction.info.load_store_multiple.addressing_mode) { | |||
case 0: /* Increment after */ | |||
Rn = Rn; | |||
break; | |||
case 1: /* Increment before */ | |||
case 1: /* Increment before */ | |||
Rn = Rn + 4; | |||
break; | |||
case 2: /* Decrement after */ | |||
case 2: /* Decrement after */ | |||
Rn = Rn - (bits_set * 4) + 4; | |||
break; | |||
case 3: /* Decrement before */ | |||
case 3: /* Decrement before */ | |||
Rn = Rn - (bits_set * 4); | |||
break; | |||
} | |||
for (i = 0; i < 16; i++) | |||
{ | |||
if (instruction.info.load_store_multiple.register_list & (1 << i)) | |||
{ | |||
for (i = 0; i < 16; i++) { | |||
if (instruction.info.load_store_multiple.register_list & (1 << i)) { | |||
if ((!dry_run_pc) || (i == 15)) | |||
{ | |||
target_read_u32(target, Rn, &load_values[i]); | |||
} | |||
Rn += 4; | |||
} | |||
} | |||
if (dry_run_pc) | |||
{ | |||
if (instruction.info.load_store_multiple.register_list & 0x8000) | |||
{ | |||
if (dry_run_pc) { | |||
if (instruction.info.load_store_multiple.register_list & 0x8000) { | |||
*dry_run_pc = load_values[15] & ~1; | |||
return ERROR_OK; | |||
} | |||
} | |||
else | |||
{ | |||
} else { | |||
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) | |||
update_cpsr = 1; | |||
} | |||
for (i = 0; i < 16; i++) | |||
{ | |||
if (instruction.info.load_store_multiple.register_list & (1 << i)) | |||
{ | |||
for (i = 0; i < 16; i++) { | |||
if (instruction.info.load_store_multiple.register_list & (1 << i)) { | |||
if (i == 15) { | |||
uint32_t val = load_values[i]; | |||
sim->set_reg_mode(sim, i, val & ~1); | |||
if (val & 1) | |||
sim->set_state(sim, ARM_STATE_THUMB); | |||
else | |||
sim->set_state(sim, ARM_STATE_ARM); | |||
} else { | |||
sim->set_reg_mode(sim, i, val & ~1); | |||
if (val & 1) | |||
sim->set_state(sim, ARM_STATE_THUMB); | |||
else | |||
sim->set_state(sim, ARM_STATE_ARM); | |||
} else | |||
sim->set_reg_mode(sim, i, load_values[i]); | |||
} | |||
} | |||
} | |||
if (update_cpsr) | |||
{ | |||
if (update_cpsr) { | |||
uint32_t spsr = sim->get_reg_mode(sim, 16); | |||
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) | |||
sim->set_reg_mode(sim, instruction.info.load_store_multiple.Rn, Rn); | |||
if (instruction.info.load_store_multiple.register_list & 0x8000) | |||
return ERROR_OK; | |||
} | |||
} | |||
/* store multiple instruction */ | |||
else if (instruction.type == ARM_STM) | |||
{ | |||
else if (instruction.type == ARM_STM) { | |||
int i; | |||
if (dry_run_pc) | |||
{ | |||
if (dry_run_pc) { | |||
/* STM wont affect PC (advance by instruction size */ | |||
} | |||
else | |||
{ | |||
} else { | |||
uint32_t Rn = sim->get_reg_mode(sim, | |||
instruction.info.load_store_multiple.Rn); | |||
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)) | |||
bits_set++; | |||
} | |||
switch (instruction.info.load_store_multiple.addressing_mode) | |||
{ | |||
case 0: /* Increment after */ | |||
switch (instruction.info.load_store_multiple.addressing_mode) { | |||
case 0: /* Increment after */ | |||
Rn = Rn; | |||
break; | |||
case 1: /* Increment before */ | |||
case 1: /* Increment before */ | |||
Rn = Rn + 4; | |||
break; | |||
case 2: /* Decrement after */ | |||
case 2: /* Decrement after */ | |||
Rn = Rn - (bits_set * 4) + 4; | |||
break; | |||
case 3: /* Decrement before */ | |||
case 3: /* Decrement before */ | |||
Rn = Rn - (bits_set * 4); | |||
break; | |||
} | |||
for (i = 0; i < 16; i++) | |||
{ | |||
if (instruction.info.load_store_multiple.register_list & (1 << i)) | |||
{ | |||
for (i = 0; i < 16; i++) { | |||
if (instruction.info.load_store_multiple.register_list & (1 << i)) { | |||
target_write_u32(target, Rn, sim->get_reg_mode(sim, i)); | |||
Rn += 4; | |||
} | |||
@@ -757,22 +630,17 @@ static int arm_simulate_step_core(struct target *target, | |||
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 | |||
*/ | |||
LOG_ERROR("Unimplemented instruction, could not simulate it."); | |||
return ERROR_FAIL; | |||
} | |||
if (dry_run_pc) | |||
{ | |||
if (dry_run_pc) { | |||
*dry_run_pc = current_pc + instruction_size; | |||
return ERROR_OK; | |||
} | |||
else | |||
{ | |||
} else { | |||
sim->set_reg(sim, 15, current_pc + instruction_size); | |||
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; | |||
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) | |||
@@ -830,7 +698,6 @@ static void armv4_5_set_state(struct arm_sim_interface *sim, enum arm_state mode | |||
arm->core_state = mode; | |||
} | |||
static enum arm_mode armv4_5_get_mode(struct arm_sim_interface *sim) | |||
{ | |||
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; | |||
} | |||
int arm_simulate_step(struct target *target, uint32_t *dry_run_pc) | |||
{ | |||
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); | |||
} | |||
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef ARM_SIMULATOR_H | |||
#define ARM_SIMULATOR_H | |||
@@ -24,8 +25,7 @@ | |||
struct target; | |||
struct arm_sim_interface | |||
{ | |||
struct arm_sim_interface { | |||
void *user_data; | |||
uint32_t (*get_reg)(struct arm_sim_interface *sim, int reg); | |||
void (*set_reg)(struct arm_sim_interface *sim, int reg, uint32_t value); | |||
@@ -23,6 +23,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -36,10 +37,9 @@ | |||
#include "algorithm.h" | |||
#include "register.h" | |||
/* offsets into armv4_5 core register cache */ | |||
enum { | |||
// ARMV4_5_CPSR = 31, | |||
/* ARMV4_5_CPSR = 31, */ | |||
ARMV4_5_SPSR_FIQ = 32, | |||
ARMV4_5_SPSR_IRQ = 33, | |||
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) | |||
{ | |||
switch (mode) { | |||
case ARM_MODE_ANY: | |||
case ARM_MODE_ANY: | |||
/* map MODE_ANY to user mode */ | |||
case ARM_MODE_USR: | |||
return 0; | |||
case ARM_MODE_FIQ: | |||
return 1; | |||
case ARM_MODE_IRQ: | |||
return 2; | |||
case ARM_MODE_SVC: | |||
return 3; | |||
case ARM_MODE_ABT: | |||
return 4; | |||
case ARM_MODE_UND: | |||
return 5; | |||
case ARM_MODE_SYS: | |||
return 6; | |||
case ARM_MODE_MON: | |||
return 7; | |||
default: | |||
LOG_ERROR("invalid mode value encountered %d", mode); | |||
return -1; | |||
case ARM_MODE_USR: | |||
return 0; | |||
case ARM_MODE_FIQ: | |||
return 1; | |||
case ARM_MODE_IRQ: | |||
return 2; | |||
case ARM_MODE_SVC: | |||
return 3; | |||
case ARM_MODE_ABT: | |||
return 4; | |||
case ARM_MODE_UND: | |||
return 5; | |||
case ARM_MODE_SYS: | |||
return 6; | |||
case ARM_MODE_MON: | |||
return 7; | |||
default: | |||
LOG_ERROR("invalid mode value encountered %d", mode); | |||
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) | |||
{ | |||
switch (number) { | |||
case 0: | |||
return ARM_MODE_USR; | |||
case 1: | |||
return ARM_MODE_FIQ; | |||
case 2: | |||
return ARM_MODE_IRQ; | |||
case 3: | |||
return ARM_MODE_SVC; | |||
case 4: | |||
return ARM_MODE_ABT; | |||
case 5: | |||
return ARM_MODE_UND; | |||
case 6: | |||
return ARM_MODE_SYS; | |||
case 7: | |||
return ARM_MODE_MON; | |||
default: | |||
LOG_ERROR("mode index out of bounds %d", number); | |||
return ARM_MODE_ANY; | |||
case 0: | |||
return ARM_MODE_USR; | |||
case 1: | |||
return ARM_MODE_FIQ; | |||
case 2: | |||
return ARM_MODE_IRQ; | |||
case 3: | |||
return ARM_MODE_SVC; | |||
case 4: | |||
return ARM_MODE_ABT; | |||
case 5: | |||
return ARM_MODE_UND; | |||
case 6: | |||
return ARM_MODE_SYS; | |||
case 7: | |||
return ARM_MODE_MON; | |||
default: | |||
LOG_ERROR("mode index out of bounds %d", number); | |||
return ARM_MODE_ANY; | |||
} | |||
} | |||
static const char *arm_state_strings[] = | |||
{ | |||
static const char *arm_state_strings[] = { | |||
"ARM", "Thumb", "Jazelle", "ThumbEE", | |||
}; | |||
@@ -312,8 +311,7 @@ static const struct { | |||
/* map core mode (USR, FIQ, ...) and register number to | |||
* indices into the register cache | |||
*/ | |||
const int armv4_5_core_reg_map[8][17] = | |||
{ | |||
const int armv4_5_core_reg_map[8][17] = { | |||
{ /* USR */ | |||
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->spsr = (mode == ARM_MODE_USR || mode == ARM_MODE_SYS) | |||
? NULL | |||
: arm->core_cache->reg_list + arm->map[16]; | |||
? NULL | |||
: arm->core_cache->reg_list + arm->map[16]; | |||
/* Older ARMs won't have the J bit */ | |||
enum arm_state state; | |||
@@ -393,8 +391,8 @@ void arm_set_cpsr(struct arm *arm, uint32_t cpsr) | |||
arm->core_state = state; | |||
LOG_DEBUG("set CPSR %#8.8x: %s mode, %s state", (unsigned) cpsr, | |||
arm_mode_name(mode), | |||
arm_state_strings[arm->core_state]); | |||
arm_mode_name(mode), | |||
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 | |||
* 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", | |||
.value = (uint8_t *) arm_gdb_dummy_fp_value, | |||
.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. | |||
* 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", | |||
.value = (uint8_t *) arm_gdb_dummy_fps_value, | |||
.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 target *target = reg_arch_info->target; | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
if (target->state != TARGET_HALTED) { | |||
LOG_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); | |||
uint32_t value = buf_get_u32(buf, 0, 32); | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
if (target->state != TARGET_HALTED) { | |||
LOG_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. | |||
*/ | |||
if (armv4_5_target->core_mode != | |||
(enum arm_mode)(value & 0x1f)) { | |||
(enum arm_mode)(value & 0x1f)) { | |||
LOG_DEBUG("changing ARM core mode to '%s'", | |||
arm_mode_name(value & 0x1f)); | |||
arm_mode_name(value & 0x1f)); | |||
value &= ~((1 << 24) | (1 << 5)); | |||
armv4_5_target->write_core_reg(target, reg, | |||
16, ARM_MODE_ANY, value); | |||
16, ARM_MODE_ANY, value); | |||
} | |||
} else { | |||
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->num_regs = 0; | |||
for (i = 0; i < num_regs; i++) | |||
{ | |||
for (i = 0; i < num_regs; i++) { | |||
/* Skip registers this core doesn't expose */ | |||
if (arm_core_regs[i].mode == ARM_MODE_MON | |||
&& arm->core_type != ARM_MODE_MON) | |||
&& arm->core_type != ARM_MODE_MON) | |||
continue; | |||
/* 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); | |||
if (arm->common_magic != ARM_COMMON_MAGIC) | |||
{ | |||
if (arm->common_magic != ARM_COMMON_MAGIC) { | |||
LOG_ERROR("BUG: called for a non-ARM target"); | |||
return ERROR_FAIL; | |||
} | |||
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", | |||
arm_state_strings[arm->core_state], | |||
debug_reason_name(target), | |||
arm_mode_name(arm->core_mode), | |||
buf_get_u32(arm->cpsr->value, 0, 32), | |||
buf_get_u32(arm->pc->value, 0, 32), | |||
arm->is_semihosting ? ", semihosting" : ""); | |||
"cpsr: 0x%8.8" PRIx32 " pc: 0x%8.8" PRIx32 "%s", | |||
arm_state_strings[arm->core_state], | |||
debug_reason_name(target), | |||
arm_mode_name(arm->core_mode), | |||
buf_get_u32(arm->cpsr->value, 0, 32), | |||
buf_get_u32(arm->pc->value, 0, 32), | |||
arm->is_semihosting ? ", semihosting" : ""); | |||
return ERROR_OK; | |||
} | |||
#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) | |||
{ | |||
@@ -615,33 +607,30 @@ COMMAND_HANDLER(handle_armv4_5_reg_command) | |||
struct arm *arm = target_to_arm(target); | |||
struct reg *regs; | |||
if (!is_arm(arm)) | |||
{ | |||
if (!is_arm(arm)) { | |||
command_print(CMD_CTX, "current target isn't an ARM"); | |||
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"); | |||
return ERROR_FAIL; | |||
} | |||
if (arm->core_type != ARM_MODE_ANY) | |||
{ | |||
command_print(CMD_CTX, "Microcontroller Profile not supported - use standard reg cmd"); | |||
if (arm->core_type != ARM_MODE_ANY) { | |||
command_print(CMD_CTX, | |||
"Microcontroller Profile not supported - use standard reg cmd"); | |||
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?"); | |||
return ERROR_FAIL; | |||
} | |||
if (!arm->full_context) { | |||
command_print(CMD_CTX, "error: target doesn't support %s", | |||
CMD_NAME); | |||
CMD_NAME); | |||
return ERROR_FAIL; | |||
} | |||
@@ -654,26 +643,26 @@ COMMAND_HANDLER(handle_armv4_5_reg_command) | |||
/* label this bank of registers (or shadows) */ | |||
switch (arm_mode_data[mode].psr) { | |||
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) | |||
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; | |||
/* FALLTHROUGH */ | |||
default: | |||
name = arm_mode_data[mode].name; | |||
shadow = "shadow "; | |||
break; | |||
default: | |||
name = arm_mode_data[mode].name; | |||
shadow = "shadow "; | |||
break; | |||
} | |||
command_print(CMD_CTX, "%s%s mode %sregisters", | |||
sep, name, shadow); | |||
sep, name, shadow); | |||
/* 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]; | |||
int output_len = 0; | |||
@@ -693,8 +682,8 @@ COMMAND_HANDLER(handle_armv4_5_reg_command) | |||
value = buf_get_u32(reg->value, 0, 32); | |||
output_len += snprintf(output + output_len, | |||
sizeof(output) - output_len, | |||
"%8s: %8.8" PRIx32 " ", | |||
reg->name, value); | |||
"%8s: %8.8" PRIx32 " ", | |||
reg->name, value); | |||
} | |||
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 arm *arm = target_to_arm(target); | |||
if (!is_arm(arm)) | |||
{ | |||
if (!is_arm(arm)) { | |||
command_print(CMD_CTX, "current target isn't an ARM"); | |||
return ERROR_FAIL; | |||
} | |||
if (arm->core_type == ARM_MODE_THREAD) | |||
{ | |||
if (arm->core_type == ARM_MODE_THREAD) { | |||
/* armv7m not supported */ | |||
command_print(CMD_CTX, "Unsupported Command"); | |||
return ERROR_OK; | |||
} | |||
if (CMD_ARGC > 0) | |||
{ | |||
if (CMD_ARGC > 0) { | |||
if (strcmp(CMD_ARGV[0], "arm") == 0) | |||
{ | |||
arm->core_state = ARM_STATE_ARM; | |||
} | |||
if (strcmp(CMD_ARGV[0], "thumb") == 0) | |||
{ | |||
arm->core_state = ARM_STATE_THUMB; | |||
} | |||
} | |||
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; | |||
} | |||
if (arm->core_type == ARM_MODE_THREAD) | |||
{ | |||
if (arm->core_type == ARM_MODE_THREAD) { | |||
/* armv7m is always thumb mode */ | |||
thumb = 1; | |||
} | |||
switch (CMD_ARGC) { | |||
case 3: | |||
if (strcmp(CMD_ARGV[2], "thumb") != 0) | |||
goto usage; | |||
thumb = 1; | |||
case 3: | |||
if (strcmp(CMD_ARGV[2], "thumb") != 0) | |||
goto usage; | |||
thumb = 1; | |||
/* FALL THROUGH */ | |||
case 2: | |||
COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], count); | |||
case 2: | |||
COMMAND_PARSE_NUMBER(int, CMD_ARGV[1], count); | |||
/* FALL THROUGH */ | |||
case 1: | |||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); | |||
if (address & 0x01) { | |||
if (!thumb) { | |||
command_print(CMD_CTX, "Disassemble as Thumb"); | |||
thumb = 1; | |||
case 1: | |||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address); | |||
if (address & 0x01) { | |||
if (!thumb) { | |||
command_print(CMD_CTX, "Disassemble as Thumb"); | |||
thumb = 1; | |||
} | |||
address &= ~1; | |||
} | |||
address &= ~1; | |||
} | |||
break; | |||
default: | |||
break; | |||
default: | |||
usage: | |||
count = 0; | |||
retval = ERROR_COMMAND_SYNTAX_ERROR; | |||
count = 0; | |||
retval = ERROR_COMMAND_SYNTAX_ERROR; | |||
} | |||
while (count-- > 0) { | |||
@@ -819,7 +800,7 @@ usage: | |||
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 target *target; | |||
@@ -827,7 +808,7 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) | |||
int retval; | |||
context = current_command_context(interp); | |||
assert( context != NULL); | |||
assert(context != NULL); | |||
target = get_current_target(context); | |||
if (target == NULL) { | |||
@@ -868,7 +849,7 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) | |||
return retval; | |||
if (l & ~0xf) { | |||
LOG_ERROR("%s: %s %d out of range", __func__, | |||
"coprocessor", (int) l); | |||
"coprocessor", (int) l); | |||
return JIM_ERR; | |||
} | |||
cpnum = l; | |||
@@ -878,7 +859,7 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) | |||
return retval; | |||
if (l & ~0x7) { | |||
LOG_ERROR("%s: %s %d out of range", __func__, | |||
"op1", (int) l); | |||
"op1", (int) l); | |||
return JIM_ERR; | |||
} | |||
op1 = l; | |||
@@ -888,7 +869,7 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) | |||
return retval; | |||
if (l & ~0xf) { | |||
LOG_ERROR("%s: %s %d out of range", __func__, | |||
"CRn", (int) l); | |||
"CRn", (int) l); | |||
return JIM_ERR; | |||
} | |||
CRn = l; | |||
@@ -898,7 +879,7 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) | |||
return retval; | |||
if (l & ~0xf) { | |||
LOG_ERROR("%s: %s %d out of range", __func__, | |||
"CRm", (int) l); | |||
"CRm", (int) l); | |||
return JIM_ERR; | |||
} | |||
CRm = l; | |||
@@ -908,7 +889,7 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) | |||
return retval; | |||
if (l & ~0x7) { | |||
LOG_ERROR("%s: %s %d out of range", __func__, | |||
"op2", (int) l); | |||
"op2", (int) l); | |||
return JIM_ERR; | |||
} | |||
op2 = l; | |||
@@ -925,19 +906,18 @@ static int jim_mcrmrc(Jim_Interp *interp, int argc, Jim_Obj *const *argv) | |||
*/ | |||
if (argc == 7) { | |||
retval = Jim_GetLong(interp, argv[6], &l); | |||
if (retval != JIM_OK) { | |||
if (retval != JIM_OK) | |||
return retval; | |||
} | |||
value = l; | |||
/* 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); | |||
if (retval != ERROR_OK) | |||
return JIM_ERR; | |||
} else { | |||
/* 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); | |||
if (retval != ERROR_OK) | |||
return JIM_ERR; | |||
@@ -964,20 +944,17 @@ COMMAND_HANDLER(handle_arm_semihosting_command) | |||
return ERROR_FAIL; | |||
} | |||
if (!arm->setup_semihosting) | |||
{ | |||
if (!arm->setup_semihosting) { | |||
command_print(CMD_CTX, "semihosting not supported for current target"); | |||
return ERROR_FAIL; | |||
} | |||
if (CMD_ARGC > 0) | |||
{ | |||
if (CMD_ARGC > 0) { | |||
int semihosting; | |||
COMMAND_PARSE_ENABLE(CMD_ARGV[0], semihosting); | |||
if (!target_was_examined(target)) | |||
{ | |||
if (!target_was_examined(target)) { | |||
LOG_ERROR("Target not examined yet"); | |||
return ERROR_FAIL; | |||
} | |||
@@ -992,8 +969,8 @@ COMMAND_HANDLER(handle_arm_semihosting_command) | |||
} | |||
command_print(CMD_CTX, "semihosting is %s", | |||
arm->is_semihosting | |||
? "enabled" : "disabled"); | |||
arm->is_semihosting | |||
? "enabled" : "disabled"); | |||
return ERROR_OK; | |||
} | |||
@@ -1055,19 +1032,18 @@ const struct command_registration arm_command_handlers[] = { | |||
}; | |||
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); | |||
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?"); | |||
return ERROR_FAIL; | |||
} | |||
*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++) | |||
(*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 */ | |||
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; | |||
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; | |||
} | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
if ((retval = target_halt(target)) != ERROR_OK) | |||
if (target->state != TARGET_HALTED) { | |||
retval = target_halt(target); | |||
if (retval != ERROR_OK) | |||
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 ERROR_TARGET_TIMEOUT; | |||
} | |||
/* fast exit: ARMv5+ code can use BKPT */ | |||
if (exit_point && buf_get_u32(arm->pc->value, 0, 32) != exit_point) | |||
{ | |||
LOG_WARNING("target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "", | |||
if (exit_point && buf_get_u32(arm->pc->value, 0, 32) != exit_point) { | |||
LOG_WARNING( | |||
"target reentered debug state, but not at the desired exit point: 0x%4.4" PRIx32 "", | |||
buf_get_u32(arm->pc->value, 0, 32)); | |||
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 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 (*run_it)(struct target *target, uint32_t exit_point, | |||
int timeout_ms, void *arch_info)) | |||
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 (*run_it)(struct target *target, uint32_t exit_point, | |||
int timeout_ms, void *arch_info)) | |||
{ | |||
struct arm *arm = target_to_arm(target); | |||
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"); | |||
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"); | |||
return ERROR_TARGET_INVALID; | |||
} | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
if (target->state != TARGET_HALTED) { | |||
LOG_WARNING("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?"); | |||
return ERROR_FAIL; | |||
} | |||
/* 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"); | |||
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; | |||
* they'll be restored later. | |||
*/ | |||
for (i = 0; i <= 16; i++) | |||
{ | |||
for (i = 0; i <= 16; i++) { | |||
struct reg *r; | |||
r = &ARMV4_5_CORE_REG_MODE(arm->core_cache, | |||
arm_algorithm_info->core_mode, i); | |||
if (!r->valid) | |||
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); | |||
} | |||
cpsr = buf_get_u32(arm->cpsr->value, 0, 32); | |||
for (i = 0; i < num_mem_params; i++) | |||
{ | |||
if ((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK) | |||
{ | |||
for (i = 0; i < num_mem_params; i++) { | |||
retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, | |||
mem_params[i].value); | |||
if (retval != ERROR_OK) | |||
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); | |||
if (!reg) | |||
{ | |||
if (!reg) { | |||
LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
} | |||
if (reg->size != reg_params[i].size) | |||
{ | |||
LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name); | |||
if (reg->size != reg_params[i].size) { | |||
LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", | |||
reg_params[i].reg_name); | |||
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; | |||
} | |||
} | |||
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; | |||
else if (arm->core_state == ARM_STATE_THUMB) | |||
exit_breakpoint_size = 2; | |||
else | |||
{ | |||
else { | |||
LOG_ERROR("BUG: can't execute algorithms when not in ARM or Thumb state"); | |||
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", | |||
arm_algorithm_info->core_mode); | |||
arm_algorithm_info->core_mode); | |||
buf_set_u32(arm->cpsr->value, 0, 5, | |||
arm_algorithm_info->core_mode); | |||
arm_algorithm_info->core_mode); | |||
arm->cpsr->dirty = 1; | |||
arm->cpsr->valid = 1; | |||
} | |||
/* terminate using a hardware or (ARMv5+) software breakpoint */ | |||
if (exit_point && (retval = breakpoint_add(target, exit_point, | |||
exit_breakpoint_size, BKPT_HARD)) != ERROR_OK) | |||
{ | |||
LOG_ERROR("can't add HW breakpoint to terminate algorithm"); | |||
return ERROR_TARGET_FAILURE; | |||
if (exit_point) { | |||
retval = breakpoint_add(target, exit_point, | |||
exit_breakpoint_size, BKPT_HARD); | |||
if (retval != ERROR_OK) { | |||
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; | |||
} | |||
int retvaltemp; | |||
retval = run_it(target, exit_point, timeout_ms, arch_info); | |||
if (exit_point) | |||
@@ -1244,31 +1210,32 @@ int armv4_5_run_algorithm_inner(struct target *target, | |||
if (retval != ERROR_OK) | |||
return retval; | |||
for (i = 0; i < num_mem_params; i++) | |||
{ | |||
if (mem_params[i].direction != PARAM_OUT) | |||
if ((retvaltemp = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK) | |||
{ | |||
retval = retvaltemp; | |||
} | |||
for (i = 0; i < num_mem_params; i++) { | |||
if (mem_params[i].direction != PARAM_OUT) { | |||
int retvaltemp = target_read_buffer(target, mem_params[i].address, | |||
mem_params[i].size, | |||
mem_params[i].value); | |||
if (retvaltemp != ERROR_OK) | |||
retval = retvaltemp; | |||
} | |||
} | |||
for (i = 0; i < num_reg_params; i++) | |||
{ | |||
if (reg_params[i].direction != PARAM_OUT) | |||
{ | |||
for (i = 0; i < num_reg_params; i++) { | |||
if (reg_params[i].direction != PARAM_OUT) { | |||
struct reg *reg = register_get_by_name(arm->core_cache, reg_params[i].reg_name, 0); | |||
if (!reg) | |||
{ | |||
struct reg *reg = register_get_by_name(arm->core_cache, | |||
reg_params[i].reg_name, | |||
0); | |||
if (!reg) { | |||
LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); | |||
retval = ERROR_COMMAND_SYNTAX_ERROR; | |||
continue; | |||
} | |||
if (reg->size != reg_params[i].size) | |||
{ | |||
LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name); | |||
if (reg->size != reg_params[i].size) { | |||
LOG_ERROR( | |||
"BUG: register '%s' size doesn't match reg_params[i].size", | |||
reg_params[i].reg_name); | |||
retval = ERROR_COMMAND_SYNTAX_ERROR; | |||
continue; | |||
} | |||
@@ -1278,20 +1245,20 @@ int armv4_5_run_algorithm_inner(struct target *target, | |||
} | |||
/* restore everything we saved before (17 or 18 registers) */ | |||
for (i = 0; i <= 16; i++) | |||
{ | |||
for (i = 0; i <= 16; i++) { | |||
uint32_t regvalue; | |||
regvalue = buf_get_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache, | |||
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 "", | |||
ARMV4_5_CORE_REG_MODE(arm->core_cache, | |||
arm_algorithm_info->core_mode, i).name, context[i]); | |||
ARMV4_5_CORE_REG_MODE(arm->core_cache, | |||
arm_algorithm_info->core_mode, i).name, context[i]); | |||
buf_set_u32(ARMV4_5_CORE_REG_MODE(arm->core_cache, | |||
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, i).dirty = 1; | |||
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, | |||
i).dirty = 1; | |||
} | |||
} | |||
@@ -1303,9 +1270,26 @@ int armv4_5_run_algorithm_inner(struct target *target, | |||
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, | |||
uint32_t address, uint32_t count, uint32_t *checksum) | |||
uint32_t address, uint32_t count, uint32_t *checksum) | |||
{ | |||
struct working_area *crc_algorithm; | |||
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, | |||
uint32_t address, uint32_t count, uint32_t *blank) | |||
uint32_t address, uint32_t count, uint32_t *blank) | |||
{ | |||
struct working_area *check_algorithm; | |||
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++) { | |||
retval = target_write_u32(target, | |||
check_algorithm->address | |||
+ i * sizeof(uint32_t), | |||
+ i * sizeof(uint32_t), | |||
check_code[i]); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
@@ -1506,18 +1490,18 @@ static int arm_full_context(struct target *target) | |||
} | |||
static int arm_default_mrc(struct target *target, int cpnum, | |||
uint32_t op1, uint32_t op2, | |||
uint32_t CRn, uint32_t CRm, | |||
uint32_t *value) | |||
uint32_t op1, uint32_t op2, | |||
uint32_t CRn, uint32_t CRm, | |||
uint32_t *value) | |||
{ | |||
LOG_ERROR("%s doesn't implement MRC", target_type_name(target)); | |||
return ERROR_FAIL; | |||
} | |||
static int arm_default_mcr(struct target *target, int cpnum, | |||
uint32_t op1, uint32_t op2, | |||
uint32_t CRn, uint32_t CRm, | |||
uint32_t value) | |||
uint32_t op1, uint32_t op2, | |||
uint32_t CRn, uint32_t CRm, | |||
uint32_t value) | |||
{ | |||
LOG_ERROR("%s doesn't implement MCR", target_type_name(target)); | |||
return ERROR_FAIL; | |||
@@ -23,6 +23,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef 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]; | |||
#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! */ | |||
enum { ARMV4_5_CPSR = 31, }; | |||
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#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; | |||
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->d_u_size.linelen = 1 << (len + 3); | |||
cache->d_u_size.associativity = multiplier << (assoc - 1); | |||
cache->d_u_size.nsets = 1 << (size + 6 - assoc - len); | |||
cache->d_u_size.cachesize = multiplier << (size + 8); | |||
} | |||
else | |||
{ | |||
} else { | |||
/* cache is absent */ | |||
cache->d_u_size.linelen = -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; | |||
} | |||
if (cache->separate) | |||
{ | |||
if (cache->separate) { | |||
size = (cache_type_reg & 0x1c0) >> 6; | |||
assoc = (cache_type_reg & 0x38) >> 3; | |||
M = (cache_type_reg & 0x4) >> 2; | |||
len = (cache_type_reg & 0x3); | |||
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->i_size.linelen = 1 << (len + 3); | |||
cache->i_size.associativity = multiplier << (assoc - 1); | |||
cache->i_size.nsets = 1 << (size + 6 - assoc - len); | |||
cache->i_size.cachesize = multiplier << (size + 8); | |||
} | |||
else | |||
{ | |||
} else { | |||
/* cache is absent */ | |||
cache->i_size.linelen = -1; | |||
cache->i_size.associativity = -1; | |||
cache->i_size.nsets = -1; | |||
cache->i_size.cachesize = -1; | |||
} | |||
} | |||
else | |||
{ | |||
} else | |||
cache->i_size = cache->d_u_size; | |||
} | |||
return ERROR_OK; | |||
} | |||
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"); | |||
return ERROR_OK; | |||
} | |||
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef ARMV4_5_CACHE_H | |||
#define ARMV4_5_CACHE_H | |||
@@ -24,16 +25,14 @@ | |||
struct command_context; | |||
struct armv4_5_cachesize | |||
{ | |||
struct armv4_5_cachesize { | |||
int linelen; | |||
int associativity; | |||
int nsets; | |||
int cachesize; | |||
}; | |||
struct armv4_5_cache_common | |||
{ | |||
struct armv4_5_cache_common { | |||
int ctype; /* specify supported cache operations */ | |||
int separate; /* separate caches or unified 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, | |||
struct armv4_5_cache_common *armv4_5_cache); | |||
enum | |||
{ | |||
enum { | |||
ARMV4_5_D_U_CACHE_ENABLED = 0x4, | |||
ARMV4_5_I_CACHE_ENABLED = 0x1000, | |||
ARMV4_5_WRITE_BUFFER_ENABLED = 0x8, | |||
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -25,8 +26,8 @@ | |||
#include "target.h" | |||
#include "armv4_5_mmu.h" | |||
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) | |||
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) | |||
{ | |||
uint32_t first_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; | |||
retval = armv4_5_mmu->get_ttb(target, &ttb); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
return retval; | |||
retval = armv4_5_mmu_read_physical(target, armv4_5_mmu, | |||
(ttb & 0xffffc000) | ((va & 0xfff00000) >> 18), | |||
4, 1, (uint8_t*)&first_lvl_descriptor); | |||
4, 1, (uint8_t *)&first_lvl_descriptor); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
first_lvl_descriptor = target_buffer_get_u32(target, (uint8_t*)&first_lvl_descriptor); | |||
return retval; | |||
first_lvl_descriptor = target_buffer_get_u32(target, (uint8_t *)&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"); | |||
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"); | |||
return ERROR_TARGET_TRANSLATION_FAULT; | |||
} | |||
if ((first_lvl_descriptor & 0x3) == 2) | |||
{ | |||
if ((first_lvl_descriptor & 0x3) == 2) { | |||
/* section descriptor */ | |||
*cb = (first_lvl_descriptor & 0xc) >> 2; | |||
*val = (first_lvl_descriptor & 0xfff00000) | (va & 0x000fffff); | |||
return ERROR_OK; | |||
} | |||
if ((first_lvl_descriptor & 0x3) == 1) | |||
{ | |||
if ((first_lvl_descriptor & 0x3) == 1) { | |||
/* coarse page table */ | |||
retval = armv4_5_mmu_read_physical(target, armv4_5_mmu, | |||
(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) | |||
return retval; | |||
} | |||
else if ((first_lvl_descriptor & 0x3) == 3) | |||
{ | |||
} else if ((first_lvl_descriptor & 0x3) == 3) { | |||
/* fine page table */ | |||
retval = armv4_5_mmu_read_physical(target, armv4_5_mmu, | |||
(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) | |||
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); | |||
if ((second_lvl_descriptor & 0x3) == 0) | |||
{ | |||
if ((second_lvl_descriptor & 0x3) == 0) { | |||
LOG_ERROR("Address translation failure"); | |||
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 */ | |||
*cb = (second_lvl_descriptor & 0xc) >> 2; | |||
if ((second_lvl_descriptor & 0x3) == 1) | |||
{ | |||
if ((second_lvl_descriptor & 0x3) == 1) { | |||
/* large page descriptor */ | |||
*val = (second_lvl_descriptor & 0xffff0000) | (va & 0x0000ffff); | |||
return ERROR_OK; | |||
} | |||
if ((second_lvl_descriptor & 0x3) == 2) | |||
{ | |||
if ((second_lvl_descriptor & 0x3) == 2) { | |||
/* small page descriptor */ | |||
*val = (second_lvl_descriptor & 0xfffff000) | (va & 0x00000fff); | |||
return ERROR_OK; | |||
} | |||
if ((second_lvl_descriptor & 0x3) == 3) | |||
{ | |||
if ((second_lvl_descriptor & 0x3) == 3) { | |||
/* tiny page descriptor */ | |||
*val = (second_lvl_descriptor & 0xfffffc00) | (va & 0x000003ff); | |||
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; | |||
} | |||
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; | |||
@@ -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 */ | |||
retval = armv4_5_mmu->disable_mmu_caches(target, 1, 1, 0); | |||
if (retval !=ERROR_OK) | |||
if (retval != ERROR_OK) | |||
return retval; | |||
retval = armv4_5_mmu->read_memory(target, address, size, count, buffer); | |||
if (retval !=ERROR_OK) | |||
if (retval != ERROR_OK) | |||
return retval; | |||
/* reenable MMU / cache */ | |||
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.i_cache_enabled); | |||
if (retval !=ERROR_OK) | |||
if (retval != ERROR_OK) | |||
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; | |||
@@ -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 */ | |||
retval = armv4_5_mmu->disable_mmu_caches(target, 1, 1, 0); | |||
if (retval !=ERROR_OK) | |||
if (retval != ERROR_OK) | |||
return retval; | |||
retval = armv4_5_mmu->write_memory(target, address, size, count, buffer); | |||
if (retval !=ERROR_OK) | |||
if (retval != ERROR_OK) | |||
return retval; | |||
/* reenable MMU / cache */ | |||
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.i_cache_enabled); | |||
if (retval !=ERROR_OK) | |||
if (retval != ERROR_OK) | |||
return retval; | |||
return retval; | |||
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef ARMV4_5_MMU_H | |||
#define ARMV4_5_MMU_H | |||
@@ -24,8 +25,7 @@ | |||
struct target; | |||
struct armv4_5_mmu_common | |||
{ | |||
struct armv4_5_mmu_common { | |||
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 (*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, | |||
uint32_t address, uint32_t size, uint32_t count, const uint8_t *buffer); | |||
enum | |||
{ | |||
enum { | |||
ARMV4_5_MMU_ENABLED = 0x1, | |||
ARMV4_5_ALIGNMENT_CHECK = 0x2, | |||
ARMV4_5_MMU_S_BIT = 0x100, | |||
@@ -18,6 +18,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -79,9 +80,9 @@ static void armv7a_show_fault_registers(struct target *target) | |||
goto done; | |||
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 | |||
", IFAR: %8.8" PRIx32, ifsr, ifar); | |||
", IFAR: %8.8" PRIx32, ifsr, ifar); | |||
done: | |||
/* (void) */ dpm->finish(dpm); | |||
@@ -93,29 +94,28 @@ static int armv7a_read_ttbcr(struct target *target) | |||
struct arm_dpm *dpm = armv7a->arm.dpm; | |||
uint32_t ttbcr; | |||
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*/ | |||
retval = dpm->instr_read_data_r0(dpm, | |||
ARMV4_5_MRC(15, 0, 0, 2, 0, 2), | |||
&ttbcr); | |||
if (retval!=ERROR_OK) goto done; | |||
armv7a->armv7a_mmu.ttbr1_used = ((ttbcr & 0x7)!=0)? 1: 0; | |||
armv7a->armv7a_mmu.ttbr0_mask = 7 << (32 -((ttbcr & 0x7))); | |||
if (retval != ERROR_OK) | |||
goto done; | |||
armv7a->armv7a_mmu.ttbr1_used = ((ttbcr & 0x7) != 0) ? 1 : 0; | |||
armv7a->armv7a_mmu.ttbr0_mask = 7 << (32 - ((ttbcr & 0x7))); | |||
#if 0 | |||
LOG_INFO("ttb1 %s ,ttb0_mask %x", | |||
armv7a->armv7a_mmu.ttbr1_used ? "used":"not used", | |||
armv7a->armv7a_mmu.ttbr0_mask); | |||
LOG_INFO("ttb1 %s ,ttb0_mask %x", | |||
armv7a->armv7a_mmu.ttbr1_used ? "used" : "not used", | |||
armv7a->armv7a_mmu.ttbr0_mask); | |||
#endif | |||
if (armv7a->armv7a_mmu.ttbr1_used == 1) | |||
{ | |||
if (armv7a->armv7a_mmu.ttbr1_used == 1) { | |||
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; | |||
} | |||
else | |||
{ | |||
} else { | |||
/* fix me , default is hard coded LINUX border */ | |||
armv7a->armv7a_mmu.os_border = 0xc0000000; | |||
armv7a->armv7a_mmu.os_border = 0xc0000000; | |||
} | |||
done: | |||
dpm->finish(dpm); | |||
@@ -131,11 +131,11 @@ int armv7a_mmu_translate_va(struct target *target, uint32_t va, uint32_t *val) | |||
int retval; | |||
struct armv7a_common *armv7a = target_to_armv7a(target); | |||
struct arm_dpm *dpm = armv7a->arm.dpm; | |||
uint32_t ttb = 0; /* default ttb0 */ | |||
if (armv7a->armv7a_mmu.ttbr1_used == -1) armv7a_read_ttbcr(target); | |||
uint32_t ttb = 0; /* default ttb0 */ | |||
if (armv7a->armv7a_mmu.ttbr1_used == -1) | |||
armv7a_read_ttbcr(target); | |||
if ((armv7a->armv7a_mmu.ttbr1_used) && | |||
(va > (0xffffffff & armv7a->armv7a_mmu.ttbr0_mask))) | |||
{ | |||
(va > (0xffffffff & armv7a->armv7a_mmu.ttbr0_mask))) { | |||
/* select ttb 1 */ | |||
ttb = 1; | |||
} | |||
@@ -151,74 +151,65 @@ int armv7a_mmu_translate_va(struct target *target, uint32_t va, uint32_t *val) | |||
return retval; | |||
retval = armv7a->armv7a_mmu.read_physical_memory(target, | |||
(ttb & 0xffffc000) | ((va & 0xfff00000) >> 18), | |||
4, 1, (uint8_t*)&first_lvl_descriptor); | |||
4, 1, (uint8_t *)&first_lvl_descriptor); | |||
if (retval != ERROR_OK) | |||
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); | |||
/* reuse armv4_5 piece of code, specific armv7a changes may come later */ | |||
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"); | |||
return ERROR_TARGET_TRANSLATION_FAULT; | |||
} | |||
if ((first_lvl_descriptor & 0x3) == 2) | |||
{ | |||
if ((first_lvl_descriptor & 0x3) == 2) { | |||
/* section descriptor */ | |||
*val = (first_lvl_descriptor & 0xfff00000) | (va & 0x000fffff); | |||
return ERROR_OK; | |||
} | |||
if ((first_lvl_descriptor & 0x3) == 1) | |||
{ | |||
if ((first_lvl_descriptor & 0x3) == 1) { | |||
/* coarse page table */ | |||
retval = armv7a->armv7a_mmu.read_physical_memory(target, | |||
(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) | |||
return retval; | |||
} | |||
else if ((first_lvl_descriptor & 0x3) == 3) | |||
{ | |||
} else if ((first_lvl_descriptor & 0x3) == 3) { | |||
/* fine page table */ | |||
retval = armv7a->armv7a_mmu.read_physical_memory(target, | |||
(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) | |||
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); | |||
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"); | |||
return ERROR_TARGET_TRANSLATION_FAULT; | |||
} | |||
if ((second_lvl_descriptor & 0x3) == 1) | |||
{ | |||
if ((second_lvl_descriptor & 0x3) == 1) { | |||
/* large page descriptor */ | |||
*val = (second_lvl_descriptor & 0xffff0000) | (va & 0x0000ffff); | |||
return ERROR_OK; | |||
} | |||
if ((second_lvl_descriptor & 0x3) == 2) | |||
{ | |||
if ((second_lvl_descriptor & 0x3) == 2) { | |||
/* small page descriptor */ | |||
*val = (second_lvl_descriptor & 0xfffff000) | (va & 0x00000fff); | |||
return ERROR_OK; | |||
} | |||
if ((second_lvl_descriptor & 0x3) == 3) | |||
{ | |||
if ((second_lvl_descriptor & 0x3) == 3) { | |||
*val = (second_lvl_descriptor & 0xfffffc00) | (va & 0x000003ff); | |||
return ERROR_OK; | |||
} | |||
@@ -231,69 +222,80 @@ done: | |||
return retval; | |||
} | |||
/* V7 method VA TO PA */ | |||
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; | |||
struct armv7a_common *armv7a = target_to_armv7a(target); | |||
struct arm_dpm *dpm = armv7a->arm.dpm; | |||
uint32_t virt = va & ~0xfff; | |||
uint32_t NOS,NS,INNER,OUTER; | |||
uint32_t NOS, NS, INNER, OUTER; | |||
*val = 0xdeadbeef; | |||
retval = dpm->prepare(dpm); | |||
if (retval != ERROR_OK) | |||
goto done; | |||
/* mmu must be enable in order to get a correct translation */ | |||
/* use VA to PA CP15 register for conversion */ | |||
/* mmu must be enable in order to get a correct translation | |||
* use VA to PA CP15 register for conversion */ | |||
retval = dpm->instr_write_data_r0(dpm, | |||
ARMV4_5_MCR(15, 0, 0, 7, 8, 0), | |||
virt); | |||
if (retval!=ERROR_OK) goto done; | |||
if (retval != ERROR_OK) | |||
goto done; | |||
retval = dpm->instr_read_data_r0(dpm, | |||
ARMV4_5_MRC(15, 0, 0, 7, 4, 0), | |||
val); | |||
/* decode memory attribute */ | |||
NOS = (*val >> 10) & 1; /* Not Outer shareable */ | |||
NS = (*val >> 9) & 1; /* Non secure */ | |||
NOS = (*val >> 10) & 1; /* Not Outer shareable */ | |||
NS = (*val >> 9) & 1; /* Non secure */ | |||
INNER = (*val >> 4) & 0x7; | |||
OUTER = (*val >> 2) & 0x3; | |||
if (retval!=ERROR_OK) goto done; | |||
if (retval != ERROR_OK) | |||
goto done; | |||
*val = (*val & ~0xfff) + (va & 0xfff); | |||
if (*val == va) | |||
LOG_WARNING("virt = phys : MMU disable !!"); | |||
if (meminfo) | |||
{ | |||
if (meminfo) { | |||
LOG_INFO("%x : %x %s outer shareable %s secured", | |||
va, *val, | |||
NOS == 1 ? "not" : " ", | |||
NS == 1 ? "not" :""); | |||
va, *val, | |||
NOS == 1 ? "not" : " ", | |||
NS == 1 ? "not" : ""); | |||
switch (OUTER) { | |||
case 0 : LOG_INFO("outer: Non-Cacheable"); | |||
break; | |||
case 1 : LOG_INFO("outer: Write-Back, Write-Allocate"); | |||
break; | |||
case 2 : LOG_INFO("outer: Write-Through, No Write-Allocate"); | |||
break; | |||
case 3 : LOG_INFO("outer: Write-Back, no Write-Allocate"); | |||
break; | |||
case 0: | |||
LOG_INFO("outer: Non-Cacheable"); | |||
break; | |||
case 1: | |||
LOG_INFO("outer: Write-Back, Write-Allocate"); | |||
break; | |||
case 2: | |||
LOG_INFO("outer: Write-Through, No Write-Allocate"); | |||
break; | |||
case 3: | |||
LOG_INFO("outer: Write-Back, no Write-Allocate"); | |||
break; | |||
} | |||
switch (INNER) { | |||
case 0 : LOG_INFO("inner: Non-Cacheable"); | |||
break; | |||
case 1 : LOG_INFO("inner: Strongly-ordered"); | |||
break; | |||
case 3 : LOG_INFO("inner: Device"); | |||
break; | |||
case 5 : 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); | |||
case 0: | |||
LOG_INFO("inner: Non-Cacheable"); | |||
break; | |||
case 1: | |||
LOG_INFO("inner: Strongly-ordered"); | |||
break; | |||
case 3: | |||
LOG_INFO("inner: Device"); | |||
break; | |||
case 5: | |||
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); | |||
} | |||
} | |||
@@ -304,27 +306,26 @@ done: | |||
} | |||
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"); | |||
return ERROR_OK; | |||
} | |||
command_print(cmd_ctx, | |||
"D-Cache: linelen %i, associativity %i, nsets %i, cachesize %d KBytes", | |||
armv7a_cache->d_u_size.linelen, | |||
armv7a_cache->d_u_size.associativity, | |||
armv7a_cache->d_u_size.nsets, | |||
armv7a_cache->d_u_size.cachesize); | |||
"D-Cache: linelen %i, associativity %i, nsets %i, cachesize %d KBytes", | |||
armv7a_cache->d_u_size.linelen, | |||
armv7a_cache->d_u_size.associativity, | |||
armv7a_cache->d_u_size.nsets, | |||
armv7a_cache->d_u_size.cachesize); | |||
command_print(cmd_ctx, | |||
"I-Cache: linelen %i, associativity %i, nsets %i, cachesize %d KBytes", | |||
armv7a_cache->i_size.linelen, | |||
armv7a_cache->i_size.associativity, | |||
armv7a_cache->i_size.nsets, | |||
armv7a_cache->i_size.cachesize); | |||
"I-Cache: linelen %i, associativity %i, nsets %i, cachesize %d KBytes", | |||
armv7a_cache->i_size.linelen, | |||
armv7a_cache->i_size.associativity, | |||
armv7a_cache->i_size.nsets, | |||
armv7a_cache->i_size.cachesize); | |||
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; | |||
int retval; | |||
/* 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"); | |||
return ERROR_OK; | |||
} | |||
retval = dpm->prepare(dpm); | |||
if (retval != ERROR_OK) goto done; | |||
if (retval != ERROR_OK) | |||
goto done; | |||
do { | |||
c_way = d_u_size->way; | |||
do { | |||
uint32_t value = (c_index << d_u_size->index_shift) | |||
| (c_way << d_u_size->way_shift); | |||
/* 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, | |||
ARMV4_5_MCR(15, 0, 0, 7, 14, 2), | |||
value); | |||
if (retval!= ERROR_OK) goto done; | |||
if (retval != ERROR_OK) | |||
goto done; | |||
c_way -= 1; | |||
} while (c_way >=0); | |||
} while (c_way >= 0); | |||
c_index -= 1; | |||
} while (c_index >=0); | |||
} while (c_index >= 0); | |||
return retval; | |||
done: | |||
LOG_ERROR("flushed failed"); | |||
@@ -367,89 +369,85 @@ done: | |||
return retval; | |||
} | |||
static int armv7a_flush_all_data( struct target * target) | |||
static int armv7a_flush_all_data(struct target *target) | |||
{ | |||
int retval = ERROR_FAIL; | |||
/* check that armv7a_cache is correctly identify */ | |||
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"); | |||
return retval; | |||
} | |||
if (target->smp) | |||
{ | |||
if (target->smp) { | |||
/* look if all the other target have been flushed in order to flush level | |||
* 2 */ | |||
struct target_list *head; | |||
struct target *curr; | |||
head = target->head; | |||
while(head != (struct target_list*)NULL) | |||
{ | |||
while (head != (struct target_list *)NULL) { | |||
curr = head->target; | |||
if ((curr->state == TARGET_HALTED)) | |||
{ LOG_INFO("Wait flushing data l1 on core %d",curr->coreid); | |||
if ((curr->state == TARGET_HALTED)) { | |||
LOG_INFO("Wait flushing data l1 on core %d", curr->coreid); | |||
retval = _armv7a_flush_all_data(curr); | |||
} | |||
head = head->next; | |||
} | |||
} | |||
else retval = _armv7a_flush_all_data(target); | |||
} else | |||
retval = _armv7a_flush_all_data(target); | |||
return retval; | |||
} | |||
/* 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; | |||
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); | |||
uint32_t base = l2x_cache->base; | |||
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); | |||
if (retval!=ERROR_OK) return retval; | |||
if (retval != ERROR_OK) | |||
return retval; | |||
retval = target->type->write_phys_memory(target, | |||
(uint32_t)(base+(uint32_t)L2X0_CLEAN_INV_WAY), | |||
(uint32_t)4, | |||
(uint32_t)1, | |||
(uint8_t*)&l2_way_val); | |||
(uint8_t *)&l2_way_val); | |||
return retval; | |||
} | |||
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*) | |||
(armv7a_cache->l2_cache); | |||
struct armv7a_l2x_cache *l2x_cache = (struct armv7a_l2x_cache *) | |||
(armv7a_cache->l2_cache); | |||
if (armv7a_cache->ctype == -1) | |||
{ | |||
if (armv7a_cache->ctype == -1) { | |||
command_print(cmd_ctx, "cache not yet identified"); | |||
return ERROR_OK; | |||
} | |||
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.associativity, | |||
armv7a_cache->d_u_size.nsets, | |||
armv7a_cache->d_u_size.cachesize); | |||
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.associativity, | |||
armv7a_cache->i_size.nsets, | |||
armv7a_cache->i_size.cachesize); | |||
command_print(cmd_ctx, "L2 unified cache Base Address 0x%x, %d ways", | |||
l2x_cache->base, l2x_cache->way); | |||
command_print(cmd_ctx, "L2 unified cache Base Address 0x%x, %d ways", | |||
l2x_cache->base, l2x_cache->way); | |||
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", | |||
l2x_cache->base,l2x_cache->way);*/ | |||
if (armv7a->armv7a_mmu.armv7a_cache.l2_cache) | |||
{ | |||
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 */ | |||
armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache | |||
= armv7a_l2x_flush_all_data; | |||
armv7a->armv7a_mmu.armv7a_cache.display_cache_info = | |||
armv7a_handle_l2x_cache_info_command; | |||
/* initialize all target in this cluster (smp target)*/ | |||
/* l2 cache must be configured after smp declaration */ | |||
while(head != (struct target_list*)NULL) | |||
{ | |||
/* initialize all target in this cluster (smp target) | |||
* l2 cache must be configured after smp declaration */ | |||
while (head != (struct target_list *)NULL) { | |||
curr = head->target; | |||
if (curr != target) | |||
{ | |||
if (curr != target) { | |||
armv7a = target_to_armv7a(curr); | |||
if (armv7a->armv7a_mmu.armv7a_cache.l2_cache) | |||
{ | |||
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_l2x_flush_all_data; | |||
armv7a->armv7a_mmu.armv7a_cache.display_cache_info = | |||
armv7a_handle_l2x_cache_info_command; | |||
} | |||
head = head -> next; | |||
head = head->next; | |||
} | |||
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) | |||
{ | |||
struct target *target = get_current_target(CMD_CTX); | |||
uint32_t base, way; | |||
switch (CMD_ARGC) { | |||
case 0: | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
break; | |||
case 2: | |||
//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 */ | |||
armv7a_l2x_cache_init(target, base, way); | |||
break; | |||
default: | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
uint32_t base, way; | |||
switch (CMD_ARGC) { | |||
case 0: | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
break; | |||
case 2: | |||
/* 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 */ | |||
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, | |||
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"); | |||
return ERROR_OK; | |||
} | |||
@@ -540,35 +528,34 @@ int armv7a_handle_cache_info_command(struct command_context *cmd_ctx, | |||
return ERROR_OK; | |||
} | |||
/* retrieve core id cluster id */ | |||
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 arm_dpm *dpm = armv7a->arm.dpm; | |||
uint32_t mpidr; | |||
uint32_t mpidr; | |||
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*/ | |||
retval = dpm->instr_read_data_r0(dpm, | |||
ARMV4_5_MRC(15, 0, 0, 0, 0, 5), | |||
&mpidr); | |||
if (retval!=ERROR_OK) goto done; | |||
if (mpidr & 1<<31) | |||
{ | |||
if (retval != ERROR_OK) | |||
goto done; | |||
if (mpidr & 1<<31) { | |||
armv7a->multi_processor_system = (mpidr >> 30) & 1; | |||
armv7a->cluster_id = (mpidr >> 8) & 0xf; | |||
armv7a->cpu_id = mpidr & 0x3; | |||
LOG_INFO("%s cluster %x core %x %s", target->cmd_name, | |||
armv7a->cluster_id, | |||
armv7a->cpu_id, | |||
armv7a->multi_processor_system == 0 ? "multi core": "mono core"); | |||
armv7a->cluster_id, | |||
armv7a->cpu_id, | |||
armv7a->multi_processor_system == 0 ? "multi core" : "mono core"); | |||
} | |||
else | |||
LOG_ERROR("mpdir not in multiprocessor format"); | |||
} else | |||
LOG_ERROR("mpdir not in multiprocessor format"); | |||
done: | |||
dpm->finish(dpm); | |||
@@ -577,138 +564,149 @@ done: | |||
} | |||
int armv7a_identify_cache(struct target *target) | |||
{ | |||
/* read cache descriptor */ | |||
int retval = ERROR_FAIL; | |||
struct armv7a_common *armv7a = target_to_armv7a(target); | |||
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; | |||
struct armv7a_cache_common *cache = &(armv7a->armv7a_mmu.armv7a_cache); | |||
armv7a_read_ttbcr(target); | |||
retval = dpm->prepare(dpm); | |||
if (retval!=ERROR_OK) goto done; | |||
/* retrieve CLIDR */ | |||
/* mrc p15, 1, r0, c0, c0, 1 @ read clidr */ | |||
if (retval != ERROR_OK) | |||
goto done; | |||
/* retrieve CLIDR | |||
* mrc p15, 1, r0, c0, c0, 1 @ read clidr */ | |||
retval = dpm->instr_read_data_r0(dpm, | |||
ARMV4_5_MRC(15, 1, 0, 0, 0, 1), | |||
&clidr); | |||
if (retval!=ERROR_OK) goto done; | |||
if (retval != ERROR_OK) | |||
goto done; | |||
clidr = (clidr & 0x7000000) >> 23; | |||
LOG_INFO("number of cache level %d",clidr /2 ); | |||
if ((clidr /2) > 1) | |||
{ | |||
// FIXME not supported present in cortex A8 and later | |||
// in cortex A7, A15 | |||
LOG_INFO("number of cache level %d", clidr / 2); | |||
if ((clidr / 2) > 1) { | |||
/* FIXME not supported present in cortex A8 and later */ | |||
/* in cortex A7, A15 */ | |||
LOG_ERROR("cache l2 present :not supported"); | |||
} | |||
/* retrieve selected cache */ | |||
/* MRC p15, 2,<Rd>, c0, c0, 0; Read CSSELR */ | |||
/* retrieve selected cache | |||
* MRC p15, 2,<Rd>, c0, c0, 0; Read CSSELR */ | |||
retval = dpm->instr_read_data_r0(dpm, | |||
ARMV4_5_MRC(15, 2, 0, 0, 0, 0), | |||
&cache_selected); | |||
if (retval!=ERROR_OK) goto done; | |||
if (retval != ERROR_OK) | |||
goto done; | |||
retval = armv7a->arm.mrc(target, 15, | |||
2, 0, /* op1, op2 */ | |||
0, 0, /* CRn, CRm */ | |||
&cache_selected); | |||
if (retval!=ERROR_OK) goto done; | |||
/* select instruction cache*/ | |||
/* MCR p15, 2,<Rd>, c0, c0, 0; Write CSSELR */ | |||
/* [0] : 1 instruction cache selection , 0 data cache selection */ | |||
if (retval != ERROR_OK) | |||
goto done; | |||
/* select instruction cache | |||
* 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, | |||
ARMV4_5_MRC(15, 2, 0, 0, 0, 0), | |||
1); | |||
if (retval!=ERROR_OK) goto done; | |||
if (retval != ERROR_OK) | |||
goto done; | |||
/* read CCSIDR*/ | |||
/* MRC P15,1,<RT>,C0, C0,0 ;on cortex A9 read CCSIDR */ | |||
/* [2:0] line size 001 eight word per line */ | |||
/* [27:13] NumSet 0x7f 16KB, 0xff 32Kbytes, 0x1ff 64Kbytes */ | |||
/* read CCSIDR | |||
* MRC P15,1,<RT>,C0, C0,0 ;on cortex A9 read CCSIDR | |||
* [2:0] line size 001 eight word per line | |||
* [27:13] NumSet 0x7f 16KB, 0xff 32Kbytes, 0x1ff 64Kbytes */ | |||
retval = dpm->instr_read_data_r0(dpm, | |||
ARMV4_5_MRC(15, 1, 0, 0, 0, 0), | |||
&cache_i_reg); | |||
if (retval!=ERROR_OK) goto done; | |||
if (retval != ERROR_OK) | |||
goto done; | |||
/* select data cache*/ | |||
retval = dpm->instr_write_data_r0(dpm, | |||
ARMV4_5_MRC(15, 2, 0, 0, 0, 0), | |||
0); | |||
if (retval!=ERROR_OK) goto done; | |||
if (retval != ERROR_OK) | |||
goto done; | |||
retval = dpm->instr_read_data_r0(dpm, | |||
ARMV4_5_MRC(15, 1, 0, 0, 0, 0), | |||
&cache_d_reg); | |||
if (retval!=ERROR_OK) goto done; | |||
if (retval != ERROR_OK) | |||
goto done; | |||
/* restore selected cache */ | |||
dpm->instr_write_data_r0(dpm, | |||
ARMV4_5_MRC(15, 2, 0, 0, 0, 0), | |||
cache_selected); | |||
ARMV4_5_MRC(15, 2, 0, 0, 0, 0), | |||
cache_selected); | |||
if (retval != ERROR_OK) goto done; | |||
if (retval != ERROR_OK) | |||
goto done; | |||
dpm->finish(dpm); | |||
// put fake type | |||
/* put fake type */ | |||
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.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 */ | |||
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.way = ((cache_d_reg >> 3) & 0x3ff); | |||
cache->d_u_size.way_shift = cache->d_u_size.way+1; | |||
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_shift = cache->d_u_size.way + 1; | |||
{ | |||
int i=0; | |||
while(((cache->d_u_size.way_shift >> i) & 1)!=1) i++; | |||
int i = 0; | |||
while (((cache->d_u_size.way_shift >> i) & 1) != 1) | |||
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.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", | |||
cache->d_u_size.linelen, | |||
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.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.cachesize = (((cache_i_reg >> 13) & 0x7fff)+1)/8; | |||
/* compute info for set way operation on cache */ | |||
cache->i_size.index_shift = (cache_i_reg & 0x7) + 4; | |||
cache->i_size.index = (cache_i_reg >> 13) & 0x7fff; | |||
cache->i_size.way = ((cache_i_reg >> 3) & 0x3ff); | |||
cache->i_size.way_shift = cache->i_size.way+1; | |||
cache->i_size.index = (cache_i_reg >> 13) & 0x7fff; | |||
cache->i_size.way = ((cache_i_reg >> 3) & 0x3ff); | |||
cache->i_size.way_shift = cache->i_size.way + 1; | |||
{ | |||
int i=0; | |||
while(((cache->i_size.way_shift >> i) & 1)!=1) i++; | |||
int i = 0; | |||
while (((cache->i_size.way_shift >> i) & 1) != 1) | |||
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.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", | |||
cache->i_size.linelen, | |||
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 (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_handle_inner_cache_info_command; | |||
armv7a->armv7a_mmu.armv7a_cache.flush_all_data_cache = | |||
armv7a_flush_all_data; | |||
} | |||
armv7a->armv7a_mmu.armv7a_cache.ctype = 0; | |||
armv7a->armv7a_mmu.armv7a_cache.ctype = 0; | |||
done: | |||
dpm->finish(dpm); | |||
@@ -717,8 +715,6 @@ done: | |||
} | |||
int armv7a_init_arch_info(struct target *target, struct armv7a_common *armv7a) | |||
{ | |||
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 is useful in all function arm v4 5 compatible */ | |||
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->armv7a_mmu.armv7a_cache.l2_cache = NULL; | |||
armv7a->armv7a_mmu.armv7a_cache.ctype = -1; | |||
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; | |||
} | |||
int armv7a_arch_state(struct target *target) | |||
{ | |||
static const char *state[] = | |||
{ | |||
static const char *state[] = { | |||
"disabled", "enabled" | |||
}; | |||
struct armv7a_common *armv7a = target_to_armv7a(target); | |||
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"); | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
} | |||
@@ -754,15 +748,15 @@ int armv7a_arch_state(struct target *target) | |||
arm_arch_state(target); | |||
LOG_USER("MMU: %s, D-Cache: %s, I-Cache: %s", | |||
state[armv7a->armv7a_mmu.mmu_enabled], | |||
state[armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled], | |||
state[armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled]); | |||
state[armv7a->armv7a_mmu.mmu_enabled], | |||
state[armv7a->armv7a_mmu.armv7a_cache.d_u_cache_enabled], | |||
state[armv7a->armv7a_mmu.armv7a_cache.i_cache_enabled]); | |||
if (arm->core_mode == ARM_MODE_ABT) | |||
armv7a_show_fault_registers(target); | |||
if (target->debug_reason == DBG_REASON_WATCHPOINT) | |||
LOG_USER("Watchpoint triggered at PC %#08x", | |||
(unsigned) armv7a->dpm.wp_pc); | |||
(unsigned) armv7a->dpm.wp_pc); | |||
return ERROR_OK; | |||
} | |||
@@ -776,7 +770,7 @@ static const struct command_registration l2_cache_commands[] = { | |||
"", | |||
.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 | |||
}; | |||
@@ -16,6 +16,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef ARMV7A_H | |||
#define ARMV7A_H | |||
@@ -25,12 +26,10 @@ | |||
#include "armv4_5_cache.h" | |||
#include "arm_dpm.h" | |||
enum | |||
{ | |||
enum { | |||
ARM_PC = 15, | |||
ARM_CPSR = 16 | |||
} | |||
; | |||
}; | |||
#define ARMV7_COMMON_MAGIC 0x0A450999 | |||
@@ -49,8 +48,7 @@ struct armv7a_l2x_cache { | |||
uint32_t way; | |||
}; | |||
struct armv7a_cachesize | |||
{ | |||
struct armv7a_cachesize { | |||
uint32_t level_num; | |||
/* cache dimensionning */ | |||
uint32_t linelen; | |||
@@ -64,38 +62,32 @@ struct armv7a_cachesize | |||
uint32_t way_shift; | |||
}; | |||
struct armv7a_cache_common | |||
{ | |||
struct armv7a_cache_common { | |||
int ctype; | |||
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 d_u_cache_enabled; | |||
/* l2 external unified cache if some */ | |||
void *l2_cache; | |||
int (*flush_all_data_cache)(struct target *target); | |||
int (*display_cache_info)(struct command_context *cmd_ctx, | |||
int (*flush_all_data_cache)(struct target *target); | |||
int (*display_cache_info)(struct command_context *cmd_ctx, | |||
struct armv7a_cache_common *armv7a_cache); | |||
}; | |||
struct armv7a_mmu_common | |||
{ | |||
/* following field mmu working way */ | |||
struct armv7a_mmu_common { | |||
/* following field mmu working way */ | |||
int32_t ttbr1_used; /* -1 not initialized, 0 no ttbr1 1 ttbr1 used and */ | |||
uint32_t ttbr0_mask;/* masked to be used */ | |||
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; | |||
uint32_t mmu_enabled; | |||
}; | |||
struct armv7a_common | |||
{ | |||
struct armv7a_common { | |||
struct arm arm; | |||
int common_magic; | |||
struct reg_cache *core_cache; | |||
@@ -124,8 +116,7 @@ struct armv7a_common | |||
static inline struct armv7a_common * | |||
target_to_armv7a(struct target *target) | |||
{ | |||
return container_of(target->arch_info, struct armv7a_common, | |||
arm); | |||
return container_of(target->arch_info, struct armv7a_common, arm); | |||
} | |||
/* 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_init_arch_info(struct target *target, struct armv7a_common *armv7a); | |||
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_handle_cache_info_command(struct command_context *cmd_ctx, | |||
@@ -30,6 +30,7 @@ | |||
* ARM DDI 0405C (September 2008) * | |||
* * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -39,19 +40,16 @@ | |||
#include "algorithm.h" | |||
#include "register.h" | |||
#if 0 | |||
#define _DEBUG_INSTRUCTION_EXECUTION_ | |||
#endif | |||
/** Maps from enum armv7m_mode (except ARMV7M_MODE_ANY) to name. */ | |||
char *armv7m_mode_strings[] = | |||
{ | |||
char *armv7m_mode_strings[] = { | |||
"Thread", "Thread (User)", "Handler", | |||
}; | |||
static char *armv7m_exception_strings[] = | |||
{ | |||
static char *armv7m_exception_strings[] = { | |||
"", "Reset", "NMI", "HardFault", | |||
"MemManage", "BusFault", "UsageFault", "RESERVED", | |||
"RESERVED", "RESERVED", "RESERVED", "SVCall", | |||
@@ -79,8 +77,7 @@ const int armv7m_msp_reg_map[17] = { | |||
#ifdef ARMV7_GDB_HACKS | |||
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", | |||
.value = armv7m_gdb_dummy_cpsr_value, | |||
.dirty = 0, | |||
@@ -133,7 +130,7 @@ static const struct { | |||
{ 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 | |||
@@ -149,12 +146,9 @@ int armv7m_restore_context(struct target *target) | |||
if (armv7m->pre_restore_context) | |||
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) | |||
{ | |||
armv7m->write_core_reg(target, i); | |||
} | |||
} | |||
return ERROR_OK; | |||
@@ -189,9 +183,7 @@ static int armv7m_get_core_reg(struct reg *reg) | |||
struct armv7m_common *armv7m = target_to_armv7m(target); | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
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); | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
buf_set_u32(reg->value, 0, 32, value); | |||
reg->dirty = 1; | |||
@@ -220,14 +210,17 @@ static int armv7m_read_core_reg(struct target *target, unsigned num) | |||
{ | |||
uint32_t reg_value; | |||
int retval; | |||
struct armv7m_core_reg * armv7m_core_reg; | |||
struct armv7m_core_reg *armv7m_core_reg; | |||
struct armv7m_common *armv7m = target_to_armv7m(target); | |||
if (num >= ARMV7M_NUM_REGS) | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
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, ®_value); | |||
retval = armv7m->load_core_reg_u32(target, | |||
armv7m_core_reg->type, | |||
armv7m_core_reg->num, | |||
®_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].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); | |||
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); | |||
if (retval != ERROR_OK) | |||
{ | |||
retval = armv7m->store_core_reg_u32(target, | |||
armv7m_core_reg->type, | |||
armv7m_core_reg->num, | |||
reg_value); | |||
if (retval != ERROR_OK) { | |||
LOG_ERROR("JTAG failure"); | |||
armv7m->core_cache->reg_list[num].dirty = armv7m->core_cache->reg_list[num].valid; | |||
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].dirty = 0; | |||
@@ -273,7 +268,7 @@ int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int | |||
int i; | |||
*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: | |||
@@ -283,9 +278,7 @@ int armv7m_get_gdb_reg_list(struct target *target, struct reg **reg_list[], int | |||
* - CPSR | |||
*/ | |||
for (i = 0; i < 16; i++) | |||
{ | |||
(*reg_list)[i] = &armv7m->core_cache->reg_list[i]; | |||
} | |||
for (i = 16; i < 24; i++) | |||
(*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 | |||
* if it does not support this arch */ | |||
*((char*)armv7m->arm.pc->value) |= 1; | |||
*((char *)armv7m->arm.pc->value) |= 1; | |||
#else | |||
(*reg_list)[25] = &armv7m->core_cache->reg_list[ARMV7M_xPSR]; | |||
#endif | |||
@@ -345,60 +338,60 @@ int armv7m_start_algorithm(struct target *target, | |||
/* NOTE: armv7m_run_algorithm requires that each algorithm uses a software breakpoint | |||
* 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"); | |||
return ERROR_TARGET_INVALID; | |||
} | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
if (target->state != TARGET_HALTED) { | |||
LOG_WARNING("target not halted"); | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
/* refresh core register cache */ | |||
/* Not needed if core register cache is always consistent with target process state */ | |||
for (unsigned i = 0; i < ARMV7M_NUM_REGS; i++) | |||
{ | |||
/* refresh core register cache | |||
* Not needed if core register cache is always consistent with target process state */ | |||
for (unsigned i = 0; i < ARMV7M_NUM_REGS; i++) { | |||
if (!armv7m->core_cache->reg_list[i].valid) | |||
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++) | |||
{ | |||
// TODO: Write only out params | |||
if ((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK) | |||
for (int i = 0; i < num_mem_params; i++) { | |||
/* TODO: Write only out params */ | |||
retval = target_write_buffer(target, mem_params[i].address, | |||
mem_params[i].size, | |||
mem_params[i].value); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
for (int i = 0; i < num_reg_params; i++) | |||
{ | |||
struct reg *reg = register_get_by_name(armv7m->core_cache, reg_params[i].reg_name, 0); | |||
// uint32_t regvalue; | |||
for (int i = 0; i < num_reg_params; i++) { | |||
struct reg *reg = | |||
register_get_by_name(armv7m->core_cache, reg_params[i].reg_name, 0); | |||
/* uint32_t regvalue; */ | |||
if (!reg) | |||
{ | |||
if (!reg) { | |||
LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
} | |||
if (reg->size != reg_params[i].size) | |||
{ | |||
LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name); | |||
if (reg->size != reg_params[i].size) { | |||
LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", | |||
reg_params[i].reg_name); | |||
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); | |||
} | |||
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); | |||
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].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 | |||
* 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"); | |||
return ERROR_TARGET_INVALID; | |||
} | |||
retval = target_wait_state(target, TARGET_HALTED, timeout_ms); | |||
/* If the target fails to halt due to the breakpoint, force a halt */ | |||
if (retval != ERROR_OK || target->state != TARGET_HALTED) | |||
{ | |||
if ((retval = target_halt(target)) != ERROR_OK) | |||
if (retval != ERROR_OK || target->state != TARGET_HALTED) { | |||
retval = target_halt(target); | |||
if (retval != ERROR_OK) | |||
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 ERROR_TARGET_TIMEOUT; | |||
} | |||
armv7m->load_core_reg_u32(target, ARMV7M_REGISTER_CORE_GP, 15, &pc); | |||
if (exit_point && (pc != exit_point)) | |||
{ | |||
LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 ", expected 0x%" PRIx32 , pc, exit_point); | |||
if (exit_point && (pc != exit_point)) { | |||
LOG_DEBUG("failed algorithm halted at 0x%" PRIx32 ", expected 0x%" PRIx32, | |||
pc, | |||
exit_point); | |||
return ERROR_TARGET_TIMEOUT; | |||
} | |||
/* Read memory values to mem_params[] */ | |||
for (int i = 0; i < num_mem_params; i++) | |||
{ | |||
if (mem_params[i].direction != PARAM_OUT) | |||
if ((retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK) | |||
{ | |||
for (int i = 0; i < num_mem_params; i++) { | |||
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 != ERROR_OK) | |||
return retval; | |||
} | |||
} | |||
} | |||
/* Copy core register values to reg_params[] */ | |||
for (int i = 0; i < num_reg_params; i++) | |||
{ | |||
if (reg_params[i].direction != PARAM_OUT) | |||
{ | |||
struct reg *reg = register_get_by_name(armv7m->core_cache, reg_params[i].reg_name, 0); | |||
for (int i = 0; i < num_reg_params; i++) { | |||
if (reg_params[i].direction != PARAM_OUT) { | |||
struct reg *reg = register_get_by_name(armv7m->core_cache, | |||
reg_params[i].reg_name, | |||
0); | |||
if (!reg) | |||
{ | |||
if (!reg) { | |||
LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
} | |||
if (reg->size != reg_params[i].size) | |||
{ | |||
LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name); | |||
if (reg->size != reg_params[i].size) { | |||
LOG_ERROR( | |||
"BUG: register '%s' size doesn't match reg_params[i].size", | |||
reg_params[i].reg_name); | |||
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; | |||
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, | |||
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, | |||
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].dirty = 1; | |||
} | |||
@@ -555,8 +547,7 @@ struct reg_cache *armv7m_build_reg_cache(struct target *target) | |||
(*cache_p) = 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].target = target; | |||
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. */ | |||
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 armv7m_algorithm armv7m_info; | |||
@@ -618,27 +609,27 @@ int armv7m_checksum_memory(struct target *target, | |||
0x460B, /* mov r3, r1 */ | |||
0xF04F, 0x0400, /* mov r4, #0 */ | |||
0xE013, /* b ncomp */ | |||
/* nbyte: */ | |||
/* nbyte: */ | |||
0x5D11, /* ldrb r1, [r2, r4] */ | |||
0xF8DF, 0x7028, /* ldr r7, CRC32XOR */ | |||
0xEA80, 0x6001, /* eor r0, r0, r1, asl #24 */ | |||
0xF04F, 0x0500, /* mov r5, #0 */ | |||
/* loop: */ | |||
/* loop: */ | |||
0x2800, /* cmp r0, #0 */ | |||
0xEA4F, 0x0640, /* mov r6, r0, asl #1 */ | |||
0xF105, 0x0501, /* add r5, r5, #1 */ | |||
0x4630, /* mov r0, r6 */ | |||
0xBFB8, /* it lt */ | |||
0xEA86, 0x0007, /* eor r0, r6, r7 */ | |||
0x2D08, /* cmp r5, #8 */ | |||
0x2D08, /* cmp r5, #8 */ | |||
0xD1F4, /* bne loop */ | |||
0xF104, 0x0401, /* add r4, r4, #1 */ | |||
/* ncomp: */ | |||
/* ncomp: */ | |||
0x429C, /* cmp r4, r3 */ | |||
0xD1E9, /* bne nbyte */ | |||
0xBE00, /* bkpt #0 */ | |||
0xBE00, /* bkpt #0 */ | |||
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 */ | |||
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) | |||
goto cleanup; | |||
} | |||
@@ -667,8 +660,8 @@ int armv7m_checksum_memory(struct target *target, | |||
int timeout = 20000 * (1 + (count / (1024 * 1024))); | |||
retval = target_run_algorithm(target, 0, NULL, 2, reg_params, crc_algorithm->address, | |||
crc_algorithm->address + (sizeof(cortex_m3_crc_code) - 6), | |||
timeout, &armv7m_info); | |||
crc_algorithm->address + (sizeof(cortex_m3_crc_code) - 6), | |||
timeout, &armv7m_info); | |||
if (retval == ERROR_OK) | |||
*checksum = buf_get_u32(reg_params[0].value, 0, 32); | |||
@@ -686,7 +679,7 @@ cleanup: | |||
/** Checks whether a memory region is zeroed. */ | |||
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 reg_param reg_params[3]; | |||
@@ -694,25 +687,25 @@ int armv7m_blank_check_memory(struct target *target, | |||
int retval; | |||
uint32_t i; | |||
static const uint16_t erase_check_code[] = | |||
{ | |||
static const uint16_t erase_check_code[] = { | |||
/* loop: */ | |||
0xF810, 0x3B01, /* ldrb r3, [r0], #1 */ | |||
0xEA02, 0x0203, /* and r2, r2, r3 */ | |||
0x3901, /* subs r1, r1, #1 */ | |||
0xD1F9, /* bne loop */ | |||
0xBE00, /* bkpt #0 */ | |||
0xBE00, /* bkpt #0 */ | |||
}; | |||
/* 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; | |||
} | |||
/* convert flash writing code into a buffer in target endianness */ | |||
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.core_mode = ARMV7M_MODE_ANY; | |||
@@ -726,9 +719,15 @@ int armv7m_blank_check_memory(struct target *target, | |||
init_reg_param(®_params[2], "r2", 32, PARAM_IN_OUT); | |||
buf_set_u32(reg_params[2].value, 0, 32, 0xff); | |||
retval = target_run_algorithm(target, 0, NULL, 3, reg_params, erase_check_algorithm->address, | |||
erase_check_algorithm->address + (sizeof(erase_check_code) - 2), | |||
10000, &armv7m_info); | |||
retval = target_run_algorithm(target, | |||
0, | |||
NULL, | |||
3, | |||
reg_params, | |||
erase_check_algorithm->address, | |||
erase_check_algorithm->address + (sizeof(erase_check_code) - 2), | |||
10000, | |||
&armv7m_info); | |||
if (retval == ERROR_OK) | |||
*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 | |||
* the core will break again */ | |||
if (target->debug_reason == DBG_REASON_BREAKPOINT) | |||
{ | |||
if (target->debug_reason == DBG_REASON_BREAKPOINT) { | |||
uint16_t op; | |||
uint32_t pc = buf_get_u32(r->value, 0, 32); | |||
pc &= ~1; | |||
if (target_read_u16(target, pc, &op) == ERROR_OK) | |||
{ | |||
if ((op & 0xFF00) == 0xBE00) | |||
{ | |||
if (target_read_u16(target, pc, &op) == ERROR_OK) { | |||
if ((op & 0xFF00) == 0xBE00) { | |||
pc = buf_get_u32(r->value, 0, 32) + 2; | |||
buf_set_u32(r->value, 0, 32, pc); | |||
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; | |||
} | |||
return ERROR_OK; | |||
} | |||
@@ -23,6 +23,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef 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; | |||
#endif | |||
enum armv7m_mode | |||
{ | |||
enum armv7m_mode { | |||
ARMV7M_MODE_THREAD = 0, | |||
ARMV7M_MODE_USER_THREAD = 1, | |||
ARMV7M_MODE_HANDLER = 2, | |||
@@ -52,8 +51,7 @@ extern char *armv7m_mode_strings[]; | |||
extern const int armv7m_psp_reg_map[]; | |||
extern const int armv7m_msp_reg_map[]; | |||
enum armv7m_regtype | |||
{ | |||
enum armv7m_regtype { | |||
ARMV7M_REGISTER_CORE_GP, | |||
ARMV7M_REGISTER_CORE_SP, | |||
ARMV7M_REGISTER_MEMMAP | |||
@@ -62,8 +60,7 @@ enum armv7m_regtype | |||
char *armv7m_exception_string(int number); | |||
/* offsets into armv7m core register cache */ | |||
enum | |||
{ | |||
enum { | |||
/* for convenience, the first set of indices match | |||
* the Cortex-M3 DCRSR selectors | |||
*/ | |||
@@ -100,8 +97,7 @@ enum | |||
#define ARMV7M_COMMON_MAGIC 0x2A452A45 | |||
struct armv7m_common | |||
{ | |||
struct armv7m_common { | |||
struct arm arm; | |||
int common_magic; | |||
@@ -139,17 +135,15 @@ static inline bool is_armv7m(struct armv7m_common *armv7m) | |||
return armv7m->common_magic == ARMV7M_COMMON_MAGIC; | |||
} | |||
struct armv7m_algorithm | |||
{ | |||
struct armv7m_algorithm { | |||
int common_magic; | |||
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; | |||
enum armv7m_regtype type; | |||
struct target *target; | |||
@@ -189,9 +183,9 @@ int armv7m_invalidate_core_regs(struct target *target); | |||
int armv7m_restore_context(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, | |||
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); | |||
@@ -19,6 +19,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -34,15 +35,13 @@ | |||
#include "avr32_regs.h" | |||
#include "avr32_ap7k.h" | |||
static char* avr32_core_reg_list[] = | |||
{ | |||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", | |||
static char *avr32_core_reg_list[] = { | |||
"r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", "r8", | |||
"r9", "r10", "r11", "r12", "sp", "lr", "pc", "sr" | |||
}; | |||
static struct avr32_core_reg | |||
avr32_core_reg_list_arch_info[AVR32NUMCOREREGS] = | |||
{ | |||
static struct avr32_core_reg | |||
avr32_core_reg_list_arch_info[AVR32NUMCOREREGS] = { | |||
{0, NULL, NULL}, | |||
{1, NULL, NULL}, | |||
{2, NULL, NULL}, | |||
@@ -75,12 +74,9 @@ int avr32_ap7k_save_context(struct target *target) | |||
if (retval != ERROR_OK) | |||
return retval; | |||
for (i = 0; i < AVR32NUMCOREREGS; i++) | |||
{ | |||
for (i = 0; i < AVR32NUMCOREREGS; i++) { | |||
if (!ap7k->core_cache->reg_list[i].valid) | |||
{ | |||
avr32_read_core_reg(target, i); | |||
} | |||
} | |||
return ERROR_OK; | |||
@@ -93,12 +89,9 @@ int avr32_ap7k_restore_context(struct target *target) | |||
/* get pointers to arch-specific information */ | |||
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) | |||
{ | |||
avr32_write_core_reg(target, i); | |||
} | |||
} | |||
/* 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); | |||
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].dirty = 0; | |||
@@ -151,9 +144,7 @@ static int avr32_get_core_reg(struct reg *reg) | |||
struct target *target = avr32_reg->target; | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
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); | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
buf_set_u32(reg->value, 0, 32, value); | |||
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 = malloc(sizeof(struct reg_cache)); | |||
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); | |||
int i; | |||
@@ -202,8 +191,7 @@ static struct reg_cache *avr32_build_reg_cache(struct target *target) | |||
(*cache_p) = 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].target = target; | |||
arch_info[i].avr32_common = ap7k; | |||
@@ -253,31 +241,26 @@ static int avr32_ap7k_poll(struct target *target) | |||
return retval; | |||
/* check for processor halted */ | |||
if (ds & OCDREG_DS_DBA) | |||
{ | |||
if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) | |||
{ | |||
if (ds & OCDREG_DS_DBA) { | |||
if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) { | |||
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; | |||
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; | |||
if ((retval = avr32_ap7k_debug_entry(target)) != ERROR_OK) | |||
retval = avr32_ap7k_debug_entry(target); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); | |||
} | |||
} | |||
else | |||
{ | |||
} else | |||
target->state = TARGET_RUNNING; | |||
} | |||
return ERROR_OK; | |||
@@ -288,28 +271,21 @@ static int avr32_ap7k_halt(struct target *target) | |||
struct avr32_ap7k_common *ap7k = target_to_ap7k(target); | |||
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"); | |||
return ERROR_OK; | |||
} | |||
if (target->state == TARGET_UNKNOWN) | |||
{ | |||
LOG_WARNING("target was in unknown state when halt was requested"); | |||
} | |||
if (target->state == TARGET_RESET) | |||
{ | |||
if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) | |||
{ | |||
if (target->state == TARGET_RESET) { | |||
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"); | |||
return ERROR_TARGET_FAILURE; | |||
} | |||
else | |||
{ | |||
} else { | |||
target->debug_reason = DBG_REASON_DBGRQ; | |||
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, | |||
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 breakpoint *breakpoint = NULL; | |||
uint32_t resume_pc; | |||
int retval; | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
if (target->state != TARGET_HALTED) { | |||
LOG_WARNING("target not halted"); | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
if (!debug_execution) | |||
{ | |||
if (!debug_execution) { | |||
target_free_all_working_areas(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> */ | |||
if (!current) | |||
{ | |||
if (!current) { | |||
#if 0 | |||
if (retval != ERROR_OK) | |||
return retval; | |||
#endif | |||
} | |||
resume_pc = | |||
buf_get_u32(ap7k->core_cache->reg_list[AVR32_REG_PC].value, 0, 32); | |||
resume_pc = buf_get_u32(ap7k->core_cache->reg_list[AVR32_REG_PC].value, 0, 32); | |||
avr32_ap7k_restore_context(target); | |||
/* the front-end may request us not to handle breakpoints */ | |||
if (handle_breakpoints) | |||
{ | |||
if (handle_breakpoints) { | |||
/* 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); | |||
#if 0 | |||
avr32_ap7k_unset_breakpoint(target, breakpoint); | |||
@@ -418,14 +389,11 @@ static int avr32_ap7k_resume(struct target *target, int current, | |||
/* registers are now invalid */ | |||
register_cache_invalidate(ap7k->core_cache); | |||
if (!debug_execution) | |||
{ | |||
if (!debug_execution) { | |||
target->state = TARGET_RUNNING; | |||
target_call_event_callbacks(target, TARGET_EVENT_RESUMED); | |||
LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc); | |||
} | |||
else | |||
{ | |||
} else { | |||
target->state = TARGET_DEBUG_RUNNING; | |||
target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); | |||
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, | |||
uint32_t address, int handle_breakpoints) | |||
uint32_t address, int handle_breakpoints) | |||
{ | |||
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, | |||
struct breakpoint *breakpoint) | |||
struct breakpoint *breakpoint) | |||
{ | |||
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, | |||
struct watchpoint *watchpoint) | |||
struct watchpoint *watchpoint) | |||
{ | |||
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, | |||
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); | |||
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"); | |||
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))) | |||
return ERROR_TARGET_UNALIGNED_ACCESS; | |||
switch (size) | |||
{ | |||
case 4: | |||
return avr32_jtag_read_memory32(&ap7k->jtag, address, count, (uint32_t*)(void *)buffer); | |||
break; | |||
case 2: | |||
return avr32_jtag_read_memory16(&ap7k->jtag, address, count, (uint16_t*)(void *)buffer); | |||
break; | |||
case 1: | |||
return avr32_jtag_read_memory8(&ap7k->jtag, address, count, buffer); | |||
break; | |||
default: | |||
break; | |||
switch (size) { | |||
case 4: | |||
return avr32_jtag_read_memory32(&ap7k->jtag, address, count, | |||
(uint32_t *)(void *)buffer); | |||
break; | |||
case 2: | |||
return avr32_jtag_read_memory16(&ap7k->jtag, address, count, | |||
(uint16_t *)(void *)buffer); | |||
break; | |||
case 1: | |||
return avr32_jtag_read_memory8(&ap7k->jtag, address, count, buffer); | |||
break; | |||
default: | |||
break; | |||
} | |||
return ERROR_OK; | |||
} | |||
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); | |||
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"); | |||
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))) | |||
return ERROR_TARGET_UNALIGNED_ACCESS; | |||
switch (size) | |||
{ | |||
case 4: | |||
return avr32_jtag_write_memory32(&ap7k->jtag, address, count, (uint32_t*)(void *)buffer); | |||
break; | |||
case 2: | |||
return avr32_jtag_write_memory16(&ap7k->jtag, address, count, (uint16_t*)(void *)buffer); | |||
break; | |||
case 1: | |||
return avr32_jtag_write_memory8(&ap7k->jtag, address, count, buffer); | |||
break; | |||
default: | |||
break; | |||
switch (size) { | |||
case 4: | |||
return avr32_jtag_write_memory32(&ap7k->jtag, address, count, | |||
(uint32_t *)(void *)buffer); | |||
break; | |||
case 2: | |||
return avr32_jtag_write_memory16(&ap7k->jtag, address, count, | |||
(uint16_t *)(void *)buffer); | |||
break; | |||
case 1: | |||
return avr32_jtag_write_memory8(&ap7k->jtag, address, count, buffer); | |||
break; | |||
default: | |||
break; | |||
} | |||
return ERROR_OK; | |||
} | |||
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); | |||
@@ -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) | |||
{ | |||
struct avr32_ap7k_common *ap7k = calloc(1, sizeof(struct | |||
avr32_ap7k_common)); | |||
avr32_ap7k_common)); | |||
ap7k->common_magic = AP7k_COMMON_MAGIC; | |||
target->arch_info = ap7k; | |||
@@ -574,21 +548,18 @@ static int avr32_ap7k_examine(struct target *target) | |||
uint32_t devid, ds; | |||
struct avr32_ap7k_common *ap7k = target_to_ap7k(target); | |||
if (!target_was_examined(target)) | |||
{ | |||
if (!target_was_examined(target)) { | |||
target_set_examined(target); | |||
avr32_jtag_nexus_read(&ap7k->jtag, AVR32_OCDREG_DID, &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); | |||
/* check for processor halted */ | |||
if (ds & OCDREG_DS_DBA) | |||
{ | |||
if (ds & OCDREG_DS_DBA) { | |||
LOG_INFO("target is halted"); | |||
target->state = TARGET_HALTED; | |||
} | |||
else | |||
} else | |||
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, | |||
uint32_t count, const uint8_t *buffer) | |||
uint32_t count, const uint8_t *buffer) | |||
{ | |||
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); | |||
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) | |||
{ | |||
#if 0 | |||
/* get pointers to arch-specific information */ | |||
int i; | |||
/* include floating point registers */ | |||
*reg_list_size = AVR32NUMCOREREGS + AVR32NUMFPREGS; | |||
*reg_list = malloc(sizeof(struct reg*) * (*reg_list_size)); | |||
for (i = 0; i < AVR32NUMCOREREGS; 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; | |||
} | |||
/* get pointers to arch-specific information */ | |||
int i; | |||
/* include floating point registers */ | |||
*reg_list_size = AVR32NUMCOREREGS + AVR32NUMFPREGS; | |||
*reg_list = malloc(sizeof(struct reg *) * (*reg_list_size)); | |||
for (i = 0; i < AVR32NUMCOREREGS; 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; | |||
#endif | |||
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", | |||
.poll = avr32_ap7k_poll, | |||
@@ -664,10 +631,10 @@ struct target_type avr32_ap7k_target = | |||
.read_memory = avr32_ap7k_read_memory, | |||
.write_memory = avr32_ap7k_write_memory, | |||
.bulk_write_memory = avr32_ap7k_bulk_write_memory, | |||
// .checksum_memory = avr32_ap7k_checksum_memory, | |||
// .blank_check_memory = avr32_ap7k_blank_check_memory, | |||
/* .checksum_memory = avr32_ap7k_checksum_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, | |||
.remove_breakpoint = avr32_ap7k_remove_breakpoint, | |||
@@ -25,8 +25,7 @@ | |||
struct target; | |||
#define AP7k_COMMON_MAGIC 0x4150374b | |||
struct avr32_ap7k_common | |||
{ | |||
struct avr32_ap7k_common { | |||
int common_magic; | |||
struct avr32_jtag jtag; | |||
struct reg_cache *core_cache; | |||
@@ -36,11 +35,10 @@ struct avr32_ap7k_common | |||
static inline struct avr32_ap7k_common * | |||
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; | |||
struct target *target; | |||
struct avr32_ap7k_common *avr32_common; | |||
@@ -16,6 +16,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -34,8 +35,7 @@ static int avr32_jtag_set_instr(struct avr32_jtag *jtag_info, int new_instr) | |||
if (tap == NULL) | |||
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 { | |||
struct scan_field field; | |||
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; | |||
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__); | |||
return ERROR_FAIL; | |||
} | |||
@@ -59,7 +58,7 @@ static int avr32_jtag_set_instr(struct avr32_jtag *jtag_info, int new_instr) | |||
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) | |||
{ | |||
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; | |||
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__); | |||
return ERROR_FAIL; | |||
} | |||
busy = buf_get_u32(busy_buf, 6, 1); | |||
} while(busy); | |||
} while (busy); | |||
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) | |||
{ | |||
@@ -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); | |||
if (jtag_execute_queue() != ERROR_OK) | |||
{ | |||
if (jtag_execute_queue() != ERROR_OK) { | |||
LOG_ERROR("%s: reading data failed", __func__); | |||
return ERROR_FAIL; | |||
} | |||
@@ -135,8 +132,7 @@ int avr32_jtag_nexus_read_data(struct avr32_jtag *jtag_info, | |||
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) | |||
{ | |||
@@ -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); | |||
if (jtag_execute_queue() != ERROR_OK) | |||
{ | |||
if (jtag_execute_queue() != ERROR_OK) { | |||
LOG_ERROR("%s: reading data failed", __func__); | |||
return ERROR_FAIL; | |||
} | |||
@@ -176,9 +171,6 @@ int avr32_jtag_nexus_write_data(struct avr32_jtag *jtag_info, | |||
return ERROR_OK; | |||
} | |||
int avr32_jtag_nexus_read(struct avr32_jtag *jtag_info, | |||
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; | |||
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__); | |||
return ERROR_FAIL; | |||
} | |||
busy = buf_get_u32(busy_buf, 1, 1); | |||
} while(busy); | |||
} while (busy); | |||
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) | |||
{ | |||
@@ -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); | |||
if (jtag_execute_queue() != ERROR_OK) | |||
{ | |||
if (jtag_execute_queue() != ERROR_OK) { | |||
LOG_ERROR("%s: reading data failed", __func__); | |||
return ERROR_FAIL; | |||
} | |||
@@ -277,7 +267,7 @@ int avr32_jtag_mwa_read_data(struct avr32_jtag *jtag_info, | |||
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) | |||
{ | |||
@@ -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); | |||
if (jtag_execute_queue() != ERROR_OK) | |||
{ | |||
if (jtag_execute_queue() != ERROR_OK) { | |||
LOG_ERROR("%s: reading data failed", __func__); | |||
return ERROR_FAIL; | |||
} | |||
@@ -316,8 +305,6 @@ int avr32_jtag_mwa_write_data(struct avr32_jtag *jtag_info, | |||
return ERROR_OK; | |||
} | |||
int avr32_jtag_mwa_read(struct avr32_jtag *jtag_info, int slave, | |||
uint32_t addr, uint32_t *value) | |||
{ | |||
@@ -16,6 +16,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef AVR32_JTAG | |||
#define AVR32_JTAG | |||
@@ -81,8 +82,7 @@ | |||
#define MTSR(sysreg, reg) (0xe3b00002 | ((reg) << 16) | sysreg) | |||
#define MFSR(reg, sysreg) (0xe1b00002 | ((reg) << 16) | sysreg) | |||
struct avr32_jtag | |||
{ | |||
struct avr32_jtag { | |||
struct jtag_tap *tap; | |||
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, | |||
uint32_t addr, uint32_t value); | |||
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_jtag_exec(struct avr32_jtag *jtag_info, uint32_t inst); | |||
#endif /* AVR32_JTAG */ | |||
@@ -16,6 +16,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -25,14 +26,13 @@ | |||
#include "avr32_jtag.h" | |||
#include "avr32_mem.h" | |||
int avr32_jtag_read_memory32(struct avr32_jtag *jtag_info, | |||
uint32_t addr, int count, uint32_t *buffer) | |||
int avr32_jtag_read_memory32(struct avr32_jtag *jtag_info, | |||
uint32_t addr, int count, uint32_t *buffer) | |||
{ | |||
int i, retval; | |||
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, | |||
addr + i*4, &data); | |||
@@ -40,14 +40,14 @@ int avr32_jtag_read_memory32(struct avr32_jtag *jtag_info, | |||
return retval; | |||
/* 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; | |||
} | |||
int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info, | |||
uint32_t addr, int count, uint16_t *buffer) | |||
int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info, | |||
uint32_t addr, int count, uint16_t *buffer) | |||
{ | |||
int i, retval; | |||
uint32_t data; | |||
@@ -55,8 +55,7 @@ int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info, | |||
i = 0; | |||
/* any unaligned half-words? */ | |||
if (addr & 3) | |||
{ | |||
if (addr & 3) { | |||
retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, | |||
addr + i*2, &data); | |||
@@ -64,14 +63,13 @@ int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info, | |||
return retval; | |||
/* 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; | |||
i++; | |||
} | |||
/* 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, | |||
addr + i*2, &data); | |||
@@ -79,14 +77,13 @@ int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info, | |||
return retval; | |||
/* 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+1] = (data >> 16) & 0xffff; | |||
} | |||
/* last halfword */ | |||
if (i < count) | |||
{ | |||
if (i < count) { | |||
retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, | |||
addr + i*2, &data); | |||
@@ -94,73 +91,68 @@ int avr32_jtag_read_memory16(struct avr32_jtag *jtag_info, | |||
return retval; | |||
/* 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; | |||
} | |||
return ERROR_OK; | |||
} | |||
int avr32_jtag_read_memory8(struct avr32_jtag *jtag_info, | |||
uint32_t addr, int count, uint8_t *buffer) | |||
int avr32_jtag_read_memory8(struct avr32_jtag *jtag_info, | |||
uint32_t addr, int count, uint8_t *buffer) | |||
{ | |||
int i, j, retval; | |||
uint8_t data[4]; | |||
i = 0; | |||
/* Do we have non-aligned bytes? */ | |||
if (addr & 3) | |||
{ | |||
if (addr & 3) { | |||
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) | |||
return retval; | |||
for (j = addr & 3; (j < 4) && (i < count); j++, i++) | |||
buffer[i] = data[3-j]; | |||
for (j = addr & 3; (j < 4) && (i < count); j++, i++) | |||
buffer[i] = data[3-j]; | |||
} | |||
/* 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, | |||
addr + i, (uint32_t*)(void *)data); | |||
addr + i, (uint32_t *)(void *)data); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
for (j = 0; j < 4; j++) | |||
buffer[i+j] = data[3-j]; | |||
buffer[i+j] = data[3-j]; | |||
} | |||
/* remaining bytes */ | |||
if (i < count) | |||
{ | |||
if (i < count) { | |||
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) | |||
return retval; | |||
for (j = 0; i + j < count; j++) | |||
buffer[i+j] = data[3-j]; | |||
for (j = 0; i + j < count; j++) | |||
buffer[i+j] = data[3-j]; | |||
} | |||
return ERROR_OK; | |||
} | |||
int avr32_jtag_write_memory32(struct avr32_jtag *jtag_info, | |||
uint32_t addr, int count, const uint32_t *buffer) | |||
int avr32_jtag_write_memory32(struct avr32_jtag *jtag_info, | |||
uint32_t addr, int count, const uint32_t *buffer) | |||
{ | |||
int i, retval; | |||
uint32_t data; | |||
for (i = 0; i < count; i++) | |||
{ | |||
for (i = 0; i < count; i++) { | |||
/* 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, | |||
addr + i*4, data); | |||
@@ -172,8 +164,8 @@ int avr32_jtag_write_memory32(struct avr32_jtag *jtag_info, | |||
return ERROR_OK; | |||
} | |||
int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info, | |||
uint32_t addr, int count, const uint16_t *buffer) | |||
int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info, | |||
uint32_t addr, int count, const uint16_t *buffer) | |||
{ | |||
int i, retval; | |||
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? | |||
*/ | |||
if (addr & 3) { | |||
/* | |||
/* | |||
* mwa_read will read whole world, no nead to fiddle | |||
* 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) | |||
return retval; | |||
data = be_to_h_u32((uint8_t*)&data); | |||
data = be_to_h_u32((uint8_t *)&data); | |||
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, | |||
addr, data_out); | |||
@@ -208,13 +200,11 @@ int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info, | |||
i++; | |||
} | |||
/* write all complete words */ | |||
for (; i < (count & ~1); i+=2) | |||
{ | |||
for (; i < (count & ~1); i += 2) { | |||
/* XXX: Assume AVR32 is BE */ | |||
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, | |||
addr + i*2, data_out); | |||
@@ -224,18 +214,17 @@ int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info, | |||
} | |||
/* last halfword */ | |||
if (i < count) | |||
{ | |||
if (i < count) { | |||
retval = avr32_jtag_mwa_read(jtag_info, SLAVE_HSB_UNCACHED, | |||
addr + i*2, &data); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
data = be_to_h_u32((uint8_t*)&data); | |||
data = be_to_h_u32((uint8_t *)&data); | |||
data &= ~0xffff; | |||
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, | |||
addr + i*2, data_out); | |||
@@ -247,8 +236,8 @@ int avr32_jtag_write_memory16(struct avr32_jtag *jtag_info, | |||
return ERROR_OK; | |||
} | |||
int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info, | |||
uint32_t addr, int count, const uint8_t *buffer) | |||
int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info, | |||
uint32_t addr, int count, const uint8_t *buffer) | |||
{ | |||
int i, j, retval; | |||
uint32_t data; | |||
@@ -260,7 +249,7 @@ int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info, | |||
* Do we have any non-aligned bytes? | |||
*/ | |||
if (addr & 3) { | |||
/* | |||
/* | |||
* mwa_read will read whole world, no nead to fiddle | |||
* 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) | |||
return retval; | |||
data = be_to_h_u32((uint8_t*)&data); | |||
for (j = addr & 3; (j < 4) && (i < count); j++, i++) | |||
{ | |||
data = be_to_h_u32((uint8_t *)&data); | |||
for (j = addr & 3; (j < 4) && (i < count); j++, i++) { | |||
data &= ~(0xff << 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, | |||
addr, data_out); | |||
@@ -287,14 +275,13 @@ int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info, | |||
/* write all complete words */ | |||
for (; i < (count & ~3); i+=4) | |||
{ | |||
for (; i < (count & ~3); i += 4) { | |||
data = 0; | |||
for (j = 0; j < 4; j++) | |||
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, | |||
addr + i, data_out); | |||
@@ -313,14 +300,13 @@ int avr32_jtag_write_memory8(struct avr32_jtag *jtag_info, | |||
if (retval != ERROR_OK) | |||
return retval; | |||
data = be_to_h_u32((uint8_t*)&data); | |||
for (j = 0; i < count; j++, i++) | |||
{ | |||
data = be_to_h_u32((uint8_t *)&data); | |||
for (j = 0; i < count; j++, i++) { | |||
data &= ~(0xff << 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, | |||
addr+i, data_out); | |||
@@ -16,22 +16,22 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef 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); | |||
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); | |||
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); | |||
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); | |||
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); | |||
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); | |||
#endif /* AVR32_MEM */ | |||
@@ -16,6 +16,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -25,7 +26,7 @@ | |||
#include "avr32_jtag.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) | |||
{ | |||
int retval; | |||
@@ -36,27 +37,27 @@ static int avr32_jtag_read_reg(struct avr32_jtag *jtag_info, int reg, | |||
return retval; | |||
do { | |||
retval = avr32_jtag_nexus_read(jtag_info, | |||
retval = avr32_jtag_nexus_read(jtag_info, | |||
AVR32_OCDREG_DCSR, &dcsr); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} while (!(dcsr & OCDREG_DCSR_CPUD)); | |||
retval = avr32_jtag_nexus_read(jtag_info, | |||
retval = avr32_jtag_nexus_read(jtag_info, | |||
AVR32_OCDREG_DCCPU, val); | |||
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) | |||
{ | |||
int retval; | |||
uint32_t dcsr; | |||
/* Restore Status reg */ | |||
retval = avr32_jtag_nexus_write(jtag_info, | |||
retval = avr32_jtag_nexus_write(jtag_info, | |||
AVR32_OCDREG_DCEMU, val); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
@@ -65,7 +66,7 @@ static int avr32_jtag_write_reg(struct avr32_jtag *jtag_info, int reg, | |||
if (retval != ERROR_OK) | |||
return retval; | |||
do { | |||
retval = avr32_jtag_nexus_read(jtag_info, | |||
retval = avr32_jtag_nexus_read(jtag_info, | |||
AVR32_OCDREG_DCSR, &dcsr); | |||
} 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; | |||
/* 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); | |||
/* 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 | |||
*/ | |||
for (i = 0; i < AVR32NUMCOREREGS - 1; i++) | |||
for (i = 0; i < AVR32NUMCOREREGS - 1; i++) | |||
avr32_jtag_write_reg(jtag_info, i, regs[i]); | |||
return ERROR_OK; | |||
@@ -16,6 +16,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef 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); | |||
#endif /* AVR32_REGS */ | |||
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -25,7 +26,6 @@ | |||
#include "target.h" | |||
#include "target_type.h" | |||
#define AVR_JTAG_INS_LEN 4 | |||
/* 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_poll(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_step(struct target *target, int current, uint32_t address, int handle_breakpoints); | |||
static int avr_resume(struct target *target, int current, uint32_t address, | |||
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_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_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", | |||
.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) | |||
{ | |||
LOG_DEBUG("%s", __FUNCTION__); | |||
LOG_DEBUG("%s", __func__); | |||
return ERROR_OK; | |||
} | |||
static int avr_arch_state(struct target *target) | |||
{ | |||
LOG_DEBUG("%s", __FUNCTION__); | |||
LOG_DEBUG("%s", __func__); | |||
return ERROR_OK; | |||
} | |||
static int avr_poll(struct target *target) | |||
{ | |||
if ((target->state == TARGET_RUNNING) || (target->state == TARGET_DEBUG_RUNNING)) | |||
{ | |||
target->state = TARGET_HALTED; | |||
} | |||
LOG_DEBUG("%s", __FUNCTION__); | |||
LOG_DEBUG("%s", __func__); | |||
return ERROR_OK; | |||
} | |||
static int avr_halt(struct target *target) | |||
{ | |||
LOG_DEBUG("%s", __FUNCTION__); | |||
LOG_DEBUG("%s", __func__); | |||
return ERROR_OK; | |||
} | |||
static int avr_resume(struct target *target, int current, uint32_t address, | |||
int handle_breakpoints, int debug_execution) | |||
{ | |||
LOG_DEBUG("%s", __FUNCTION__); | |||
LOG_DEBUG("%s", __func__); | |||
return ERROR_OK; | |||
} | |||
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; | |||
} | |||
@@ -140,7 +139,7 @@ static int avr_assert_reset(struct target *target) | |||
{ | |||
target->state = TARGET_RESET; | |||
LOG_DEBUG("%s", __FUNCTION__); | |||
LOG_DEBUG("%s", __func__); | |||
return ERROR_OK; | |||
} | |||
@@ -148,13 +147,13 @@ static int avr_deassert_reset(struct target *target) | |||
{ | |||
target->state = TARGET_RUNNING; | |||
LOG_DEBUG("%s", __FUNCTION__); | |||
LOG_DEBUG("%s", __func__); | |||
return ERROR_OK; | |||
} | |||
static int avr_soft_reset_halt(struct target *target) | |||
{ | |||
LOG_DEBUG("%s", __FUNCTION__); | |||
LOG_DEBUG("%s", __func__); | |||
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, | |||
int ir_len, int rti) | |||
{ | |||
if (NULL == tap) | |||
{ | |||
if (NULL == tap) { | |||
LOG_ERROR("invalid tap"); | |||
return ERROR_FAIL; | |||
} | |||
if (ir_len != tap->ir_length) | |||
{ | |||
if (ir_len != tap->ir_length) { | |||
LOG_ERROR("invalid ir_len"); | |||
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, | |||
int dr_len, int rti) | |||
{ | |||
if (NULL == tap) | |||
{ | |||
if (NULL == tap) { | |||
LOG_ERROR("invalid tap"); | |||
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, | |||
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"); | |||
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, | |||
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"); | |||
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; | |||
} | |||
@@ -17,18 +17,17 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef AVRT_H | |||
#define AVRT_H | |||
#include <jtag/jtag.h> | |||
struct mcu_jtag | |||
{ | |||
struct mcu_jtag { | |||
struct jtag_tap *tap; | |||
}; | |||
struct avr_common | |||
{ | |||
struct avr_common { | |||
struct mcu_jtag jtag_info; | |||
}; | |||
@@ -20,6 +20,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -28,24 +29,24 @@ | |||
#include <helper/log.h> | |||
#include "breakpoints.h" | |||
static char *breakpoint_type_strings[] = | |||
{ | |||
static char *breakpoint_type_strings[] = { | |||
"hardware", | |||
"software" | |||
}; | |||
static char *watchpoint_rw_strings[] = | |||
{ | |||
static char *watchpoint_rw_strings[] = { | |||
"read", | |||
"write", | |||
"access" | |||
}; | |||
// monotonic counter/id-number for breakpoints and watch points | |||
/* monotonic counter/id-number for breakpoints and watch points */ | |||
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_p = &target->breakpoints; | |||
@@ -54,8 +55,7 @@ int breakpoint_add_internal(struct target *target, uint32_t address, uint32_t le | |||
int n; | |||
n = 0; | |||
while (breakpoint) | |||
{ | |||
while (breakpoint) { | |||
n++; | |||
if (breakpoint->address == address) { | |||
/* 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. | |||
*/ | |||
LOG_DEBUG("Duplicate Breakpoint address: 0x%08" PRIx32 " (BP %d)", | |||
address, breakpoint->unique_id); | |||
address, breakpoint->unique_id); | |||
return ERROR_OK; | |||
} | |||
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); | |||
switch (retval) { | |||
case ERROR_OK: | |||
break; | |||
case ERROR_TARGET_RESOURCE_NOT_AVAILABLE: | |||
reason = "resource not available"; | |||
goto fail; | |||
case ERROR_TARGET_NOT_HALTED: | |||
reason = "target running"; | |||
goto fail; | |||
default: | |||
reason = "unknown reason"; | |||
case ERROR_OK: | |||
break; | |||
case ERROR_TARGET_RESOURCE_NOT_AVAILABLE: | |||
reason = "resource not available"; | |||
goto fail; | |||
case ERROR_TARGET_NOT_HALTED: | |||
reason = "target running"; | |||
goto fail; | |||
default: | |||
reason = "unknown reason"; | |||
fail: | |||
LOG_ERROR("can't add breakpoint: %s", reason); | |||
free((*breakpoint_p)->orig_instr); | |||
free(*breakpoint_p); | |||
*breakpoint_p = NULL; | |||
return retval; | |||
LOG_ERROR("can't add breakpoint: %s", reason); | |||
free((*breakpoint_p)->orig_instr); | |||
free(*breakpoint_p); | |||
*breakpoint_p = NULL; | |||
return retval; | |||
} | |||
LOG_DEBUG("added %s breakpoint at 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %d)", | |||
breakpoint_type_strings[(*breakpoint_p)->type], | |||
(*breakpoint_p)->address, (*breakpoint_p)->length, | |||
(*breakpoint_p)->unique_id); | |||
breakpoint_type_strings[(*breakpoint_p)->type], | |||
(*breakpoint_p)->address, (*breakpoint_p)->length, | |||
(*breakpoint_p)->unique_id); | |||
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_p = &target->breakpoints; | |||
@@ -116,17 +119,15 @@ int context_breakpoint_add_internal(struct target *target, uint32_t asid, uint32 | |||
int n; | |||
n = 0; | |||
while (breakpoint) | |||
{ | |||
while (breakpoint) { | |||
n++; | |||
if (breakpoint->asid == asid) | |||
{ | |||
if (breakpoint->asid == asid) { | |||
/* FIXME don't assume "same address" means "same | |||
* breakpoint" ... check all the parameters before | |||
* succeeding. | |||
*/ | |||
LOG_DEBUG("Duplicate Breakpoint asid: 0x%08" PRIx32 " (BP %d)", | |||
asid, breakpoint->unique_id); | |||
asid, breakpoint->unique_id); | |||
return -1; | |||
} | |||
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)->unique_id = bpwp_unique_id++; | |||
retval = target_add_context_breakpoint(target, *breakpoint_p); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
LOG_ERROR("could not add breakpoint"); | |||
free((*breakpoint_p)->orig_instr); | |||
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)", | |||
breakpoint_type_strings[(*breakpoint_p)->type], | |||
(*breakpoint_p)->asid, (*breakpoint_p)->length, | |||
(*breakpoint_p)->unique_id); | |||
breakpoint_type_strings[(*breakpoint_p)->type], | |||
(*breakpoint_p)->asid, (*breakpoint_p)->length, | |||
(*breakpoint_p)->unique_id); | |||
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_p = &target->breakpoints; | |||
int retval; | |||
int n; | |||
n = 0; | |||
while (breakpoint) | |||
{ | |||
while (breakpoint) { | |||
n++; | |||
if ((breakpoint->asid == asid) && (breakpoint->address == address)) { | |||
/* 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. | |||
*/ | |||
LOG_DEBUG("Duplicate Hybrid Breakpoint asid: 0x%08" PRIx32 " (BP %d)", | |||
asid, breakpoint->unique_id); | |||
asid, breakpoint->unique_id); | |||
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)", | |||
address, breakpoint->unique_id); | |||
address, breakpoint->unique_id); | |||
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); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
LOG_ERROR("could not add breakpoint"); | |||
free((*breakpoint_p)->orig_instr); | |||
free(*breakpoint_p); | |||
*breakpoint_p = NULL; | |||
return retval; | |||
} | |||
LOG_DEBUG("added %s Hybrid breakpoint at address 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %d)", | |||
breakpoint_type_strings[(*breakpoint_p)->type], | |||
(*breakpoint_p)->address, (*breakpoint_p)->length, | |||
(*breakpoint_p)->unique_id); | |||
LOG_DEBUG( | |||
"added %s Hybrid breakpoint at address 0x%8.8" PRIx32 " of length 0x%8.8x, (BPID: %d)", | |||
breakpoint_type_strings[(*breakpoint_p)->type], | |||
(*breakpoint_p)->address, | |||
(*breakpoint_p)->length, | |||
(*breakpoint_p)->unique_id); | |||
return ERROR_OK; | |||
} | |||
int breakpoint_add(struct target *target, uint32_t address, uint32_t length, enum breakpoint_type type) | |||
int breakpoint_add(struct target *target, | |||
uint32_t address, | |||
uint32_t length, | |||
enum breakpoint_type type) | |||
{ | |||
int retval = ERROR_OK; | |||
if (target->smp) | |||
{ | |||
if (target->smp) { | |||
struct target_list *head; | |||
struct target *curr; | |||
head = target->head; | |||
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; | |||
retval = breakpoint_add_internal(curr, address,length, type); | |||
if (retval != ERROR_OK) return retval; | |||
retval = breakpoint_add_internal(curr, address, length, type); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
head = head->next; | |||
} | |||
return retval; | |||
} | |||
else | |||
return(breakpoint_add_internal(target, address, length, type)); | |||
} else | |||
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; | |||
if (target->smp) | |||
{ | |||
if (target->smp) { | |||
struct target_list *head; | |||
struct target *curr; | |||
head = target->head; | |||
while(head != (struct target_list*)NULL) | |||
{ | |||
while (head != (struct target_list *)NULL) { | |||
curr = head->target; | |||
retval = context_breakpoint_add_internal(curr, asid,length, type); | |||
if (retval != ERROR_OK) return retval; | |||
retval = context_breakpoint_add_internal(curr, asid, length, type); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
head = head->next; | |||
} | |||
return retval; | |||
} | |||
else | |||
return(context_breakpoint_add_internal(target, asid, length, type)); | |||
} else | |||
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; | |||
if (target->smp) | |||
{ | |||
if (target->smp) { | |||
struct target_list *head; | |||
struct target *curr; | |||
head = target->head; | |||
while(head != (struct target_list*)NULL) | |||
{ | |||
while (head != (struct target_list *)NULL) { | |||
curr = head->target; | |||
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; | |||
} | |||
return retval; | |||
} | |||
else | |||
return(hybrid_breakpoint_add_internal(target, address, asid, length, type)); | |||
} else | |||
return hybrid_breakpoint_add_internal(target, address, asid, length, type); | |||
} | |||
/* free up a breakpoint */ | |||
@@ -296,8 +294,7 @@ static void breakpoint_free(struct target *target, struct breakpoint *breakpoint | |||
struct breakpoint **breakpoint_p = &target->breakpoints; | |||
int retval; | |||
while (breakpoint) | |||
{ | |||
while (breakpoint) { | |||
if (breakpoint == breakpoint_to_remove) | |||
break; | |||
breakpoint_p = &breakpoint->next; | |||
@@ -319,8 +316,7 @@ int breakpoint_remove_internal(struct target *target, uint32_t address) | |||
{ | |||
struct breakpoint *breakpoint = target->breakpoints; | |||
while (breakpoint) | |||
{ | |||
while (breakpoint) { | |||
if ((breakpoint->address == address) && (breakpoint->asid == 0)) | |||
break; | |||
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; | |||
} | |||
if (breakpoint) | |||
{ | |||
if (breakpoint) { | |||
breakpoint_free(target, breakpoint); | |||
return 1; | |||
} | |||
else | |||
{ | |||
} else { | |||
if (!target->smp) | |||
LOG_ERROR("no breakpoint at address 0x%8.8" PRIx32 " found", address); | |||
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) | |||
{ | |||
int found = 0; | |||
if (target->smp) | |||
{ | |||
if (target->smp) { | |||
struct target_list *head; | |||
struct target *curr; | |||
head = target->head; | |||
while(head != (struct target_list*)NULL) | |||
{ | |||
while (head != (struct target_list *)NULL) { | |||
curr = head->target; | |||
found += breakpoint_remove_internal(curr, address); | |||
head = head->next; | |||
} | |||
if (found == 0) | |||
LOG_ERROR("no breakpoint at address 0x%8.8" PRIx32 " found", address); | |||
} | |||
else breakpoint_remove_internal(target, address); | |||
} else | |||
breakpoint_remove_internal(target, address); | |||
} | |||
void breakpoint_clear_target_internal(struct target *target) | |||
{ | |||
struct breakpoint *breakpoint; | |||
LOG_DEBUG("Delete all breakpoints for target: %s", | |||
target_name(target)); | |||
while ((breakpoint = target->breakpoints) != NULL) | |||
{ | |||
breakpoint_free(target, breakpoint); | |||
} | |||
target_name(target)); | |||
while (target->breakpoints != NULL) | |||
breakpoint_free(target, target->breakpoints); | |||
} | |||
void breakpoint_clear_target(struct target *target) | |||
{ | |||
if (target->smp) | |||
{ | |||
if (target->smp) { | |||
struct target_list *head; | |||
struct target *curr; | |||
head = target->head; | |||
while(head != (struct target_list*)NULL) | |||
{ | |||
while (head != (struct target_list *)NULL) { | |||
curr = head->target; | |||
breakpoint_clear_target_internal(curr); | |||
head = head->next; | |||
} | |||
} | |||
else breakpoint_clear_target_internal(target); | |||
} else | |||
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; | |||
while (breakpoint) | |||
{ | |||
while (breakpoint) { | |||
if (breakpoint->address == address) | |||
return breakpoint; | |||
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, | |||
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_p = &target->watchpoints; | |||
int retval; | |||
char *reason; | |||
while (watchpoint) | |||
{ | |||
while (watchpoint) { | |||
if (watchpoint->address == address) { | |||
if (watchpoint->length != length | |||
|| watchpoint->value != value | |||
|| watchpoint->mask != mask | |||
|| watchpoint->rw != rw) { | |||
|| watchpoint->value != value | |||
|| watchpoint->mask != mask | |||
|| watchpoint->rw != rw) { | |||
LOG_ERROR("address 0x%8.8" PRIx32 | |||
"already has watchpoint %d", | |||
address, watchpoint->unique_id); | |||
"already has watchpoint %d", | |||
address, watchpoint->unique_id); | |||
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); | |||
switch (retval) { | |||
case ERROR_OK: | |||
break; | |||
case ERROR_TARGET_RESOURCE_NOT_AVAILABLE: | |||
reason = "resource not available"; | |||
goto bye; | |||
case ERROR_TARGET_NOT_HALTED: | |||
reason = "target running"; | |||
goto bye; | |||
default: | |||
reason = "unrecognized error"; | |||
case ERROR_OK: | |||
break; | |||
case ERROR_TARGET_RESOURCE_NOT_AVAILABLE: | |||
reason = "resource not available"; | |||
goto bye; | |||
case ERROR_TARGET_NOT_HALTED: | |||
reason = "target running"; | |||
goto bye; | |||
default: | |||
reason = "unrecognized error"; | |||
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], | |||
address, reason); | |||
free (*watchpoint_p); | |||
*watchpoint_p = NULL; | |||
return retval; | |||
free(*watchpoint_p); | |||
*watchpoint_p = NULL; | |||
return retval; | |||
} | |||
LOG_DEBUG("added %s watchpoint at 0x%8.8" PRIx32 | |||
" of length 0x%8.8" PRIx32 " (WPID: %d)", | |||
watchpoint_rw_strings[(*watchpoint_p)->rw], | |||
(*watchpoint_p)->address, | |||
(*watchpoint_p)->length, | |||
(*watchpoint_p)->unique_id); | |||
" of length 0x%8.8" PRIx32 " (WPID: %d)", | |||
watchpoint_rw_strings[(*watchpoint_p)->rw], | |||
(*watchpoint_p)->address, | |||
(*watchpoint_p)->length, | |||
(*watchpoint_p)->unique_id); | |||
return ERROR_OK; | |||
} | |||
@@ -480,8 +462,7 @@ static void watchpoint_free(struct target *target, struct watchpoint *watchpoint | |||
struct watchpoint **watchpoint_p = &target->watchpoints; | |||
int retval; | |||
while (watchpoint) | |||
{ | |||
while (watchpoint) { | |||
if (watchpoint == watchpoint_to_remove) | |||
break; | |||
watchpoint_p = &watchpoint->next; | |||
@@ -500,31 +481,22 @@ void watchpoint_remove(struct target *target, uint32_t address) | |||
{ | |||
struct watchpoint *watchpoint = target->watchpoints; | |||
while (watchpoint) | |||
{ | |||
while (watchpoint) { | |||
if (watchpoint->address == address) | |||
break; | |||
watchpoint = watchpoint->next; | |||
} | |||
if (watchpoint) | |||
{ | |||
watchpoint_free(target, watchpoint); | |||
} | |||
else | |||
{ | |||
LOG_ERROR("no watchpoint at address 0x%8.8" PRIx32 " found", address); | |||
} | |||
} | |||
void watchpoint_clear_target(struct target *target) | |||
{ | |||
struct watchpoint *watchpoint; | |||
LOG_DEBUG("Delete all watchpoints for target: %s", | |||
target_name(target)); | |||
while ((watchpoint = target->watchpoints) != NULL) | |||
{ | |||
watchpoint_free(target, watchpoint); | |||
} | |||
target_name(target)); | |||
while (target->watchpoints != NULL) | |||
watchpoint_free(target, target->watchpoints); | |||
} |
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef BREAKPOINTS_H | |||
#define BREAKPOINTS_H | |||
@@ -24,19 +25,16 @@ | |||
struct target; | |||
enum breakpoint_type | |||
{ | |||
enum breakpoint_type { | |||
BKPT_HARD, | |||
BKPT_SOFT, | |||
}; | |||
enum watchpoint_rw | |||
{ | |||
enum watchpoint_rw { | |||
WPT_READ = 0, WPT_WRITE = 1, WPT_ACCESS = 2 | |||
}; | |||
struct breakpoint | |||
{ | |||
struct breakpoint { | |||
uint32_t address; | |||
uint32_t asid; | |||
int length; | |||
@@ -45,11 +43,10 @@ struct breakpoint | |||
uint8_t *orig_instr; | |||
struct breakpoint *next; | |||
uint32_t unique_id; | |||
int linked_BRP; | |||
int linked_BRP; | |||
}; | |||
struct watchpoint | |||
{ | |||
struct watchpoint { | |||
uint32_t address; | |||
uint32_t length; | |||
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); | |||
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); | |||
int watchpoint_add(struct target *target, | |||
@@ -26,6 +26,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef CORTEX_A8_H | |||
#define CORTEX_A8_H | |||
@@ -44,8 +45,7 @@ | |||
#define CORTEX_A8_PADDRDBG_CPU_SHIFT 13 | |||
struct cortex_a8_brp | |||
{ | |||
struct cortex_a8_brp { | |||
int used; | |||
int type; | |||
uint32_t value; | |||
@@ -53,8 +53,7 @@ struct cortex_a8_brp | |||
uint8_t BRPn; | |||
}; | |||
struct cortex_a8_common | |||
{ | |||
struct cortex_a8_common { | |||
int common_magic; | |||
struct arm_jtag jtag_info; | |||
@@ -65,7 +64,7 @@ struct cortex_a8_common | |||
uint32_t cp15_control_reg; | |||
/* latest cp15 register value written and cpsr processor mode */ | |||
uint32_t cp15_control_reg_curr; | |||
enum arm_mode curr_mode; | |||
enum arm_mode curr_mode; | |||
/* Breakpoint register pairs */ | |||
@@ -84,8 +83,7 @@ struct cortex_a8_common | |||
static inline struct cortex_a8_common * | |||
target_to_cortex_a8(struct target *target) | |||
{ | |||
return container_of(target->arch_info, struct cortex_a8_common, | |||
armv7a_common.arm); | |||
return container_of(target->arch_info, struct cortex_a8_common, armv7a_common.arm); | |||
} | |||
#endif /* CORTEX_A8_H */ |
@@ -23,12 +23,12 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef CORTEX_M3_H | |||
#define CORTEX_M3_H | |||
#include "armv7m.h" | |||
#define CORTEX_M3_COMMON_MAGIC 0x1A451A45 | |||
#define SYSTEM_CONTROL_BASE 0x400FE000 | |||
@@ -117,16 +117,14 @@ | |||
#define FPCR_REPLACE_BKPT_HIGH (2 << 30) | |||
#define FPCR_REPLACE_BKPT_BOTH (3 << 30) | |||
struct cortex_m3_fp_comparator | |||
{ | |||
struct cortex_m3_fp_comparator { | |||
int used; | |||
int type; | |||
uint32_t fpcr_value; | |||
uint32_t fpcr_address; | |||
}; | |||
struct cortex_m3_dwt_comparator | |||
{ | |||
struct cortex_m3_dwt_comparator { | |||
int used; | |||
uint32_t comp; | |||
uint32_t mask; | |||
@@ -134,21 +132,18 @@ struct cortex_m3_dwt_comparator | |||
uint32_t dwt_comparator_address; | |||
}; | |||
enum cortex_m3_soft_reset_config | |||
{ | |||
enum cortex_m3_soft_reset_config { | |||
CORTEX_M3_RESET_SYSRESETREQ, | |||
CORTEX_M3_RESET_VECTRESET, | |||
}; | |||
enum cortex_m3_isrmasking_mode | |||
{ | |||
enum cortex_m3_isrmasking_mode { | |||
CORTEX_M3_ISRMASK_AUTO, | |||
CORTEX_M3_ISRMASK_OFF, | |||
CORTEX_M3_ISRMASK_ON, | |||
}; | |||
struct cortex_m3_common | |||
{ | |||
struct cortex_m3_common { | |||
int common_magic; | |||
struct arm_jtag jtag_info; | |||
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef DSP563XX_H | |||
#define DSP563XX_H | |||
@@ -26,25 +27,22 @@ | |||
#define DSP563XX_NUMCOREREGS 54 | |||
#define DSP563XX_NUMONCEREGS 25 | |||
struct mcu_jtag | |||
{ | |||
struct mcu_jtag { | |||
struct jtag_tap *tap; | |||
}; | |||
struct dsp563xx_common | |||
{ | |||
struct dsp563xx_common { | |||
struct mcu_jtag jtag_info; | |||
struct reg_cache *core_cache; | |||
uint32_t core_regs[DSP563XX_NUMCOREREGS]; | |||
struct once_reg once_regs[DSP563XX_NUMONCEREGS]; | |||
/* register cache to processor synchronization */ | |||
int (*read_core_reg) (struct target * target, int num); | |||
int (*write_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); | |||
}; | |||
struct dsp563xx_core_reg | |||
{ | |||
struct dsp563xx_core_reg { | |||
uint32_t num; | |||
const char *name; | |||
uint32_t size; | |||
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#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) | |||
{ | |||
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 */ | |||
@@ -71,9 +72,10 @@ static inline int dsp563xx_once_ir_exec(struct jtag_tap *tap, int flush, uint8_t | |||
{ | |||
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; | |||
if ( flush ) | |||
if (flush) | |||
err = jtag_execute_queue(); | |||
return err; | |||
} | |||
@@ -102,13 +104,15 @@ int dsp563xx_once_target_status(struct jtag_tap *tap) | |||
int err; | |||
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; | |||
if ((err = jtag_execute_queue()) != ERROR_OK) | |||
err = jtag_execute_queue(); | |||
if (err != ERROR_OK) | |||
return TARGET_UNKNOWN; | |||
/* 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; | |||
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 | |||
* from the interface */ | |||
if (reset_state) | |||
{ | |||
pattern = 1; | |||
} | |||
else | |||
{ | |||
pattern = JTAG_STATUS_DEBUG; | |||
} | |||
/* wait until we get the ack */ | |||
while (ir_in != pattern) | |||
{ | |||
if ((err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_DEBUG_REQUEST)) != ERROR_OK) | |||
while (ir_in != pattern) { | |||
err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_DEBUG_REQUEST); | |||
if (err != ERROR_OK) | |||
return err; | |||
if ((err = jtag_execute_queue()) != ERROR_OK) | |||
err = jtag_execute_queue(); | |||
if (err != ERROR_OK) | |||
return err; | |||
LOG_DEBUG("debug request: %02X", ir_in); | |||
if (retry++ == 100) | |||
{ | |||
return ERROR_TARGET_FAILURE; | |||
} | |||
} | |||
/* we cant enable the once in reset state */ | |||
if (pattern == 1) | |||
{ | |||
return ERROR_OK; | |||
} | |||
/* try to enable once */ | |||
retry = 0; | |||
ir_in = 0; | |||
while (ir_in != pattern) | |||
{ | |||
if ((err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_ENABLE_ONCE)) != ERROR_OK) | |||
while (ir_in != pattern) { | |||
err = dsp563xx_jtag_sendinstr(tap, &ir_in, JTAG_INSTR_ENABLE_ONCE); | |||
if (err != ERROR_OK) | |||
return err; | |||
if ((err = jtag_execute_queue()) != ERROR_OK) | |||
err = jtag_execute_queue(); | |||
if (err != ERROR_OK) | |||
return err; | |||
LOG_DEBUG("enable once: %02X", ir_in); | |||
if (retry++ == 100) | |||
{ | |||
if (retry++ == 100) { | |||
LOG_DEBUG("error"); | |||
return ERROR_TARGET_FAILURE; | |||
} | |||
} | |||
if (ir_in != JTAG_STATUS_DEBUG) | |||
{ | |||
return ERROR_TARGET_FAILURE; | |||
} | |||
return ERROR_OK; | |||
} | |||
@@ -190,13 +185,13 @@ int dsp563xx_once_read_register(struct jtag_tap *tap, int flush, struct once_reg | |||
int i; | |||
int err = ERROR_OK; | |||
for (i = 0; i < len; i++) | |||
{ | |||
if ((err = dsp563xx_once_reg_read_ex(tap, flush, regs[i].addr, regs[i].len, ®s[i].reg)) != ERROR_OK) | |||
for (i = 0; i < len; i++) { | |||
err = dsp563xx_once_reg_read_ex(tap, flush, regs[i].addr, regs[i].len, ®s[i].reg); | |||
if (err != ERROR_OK) | |||
return err; | |||
} | |||
if ( flush ) | |||
if (flush) | |||
err = jtag_execute_queue(); | |||
return err; | |||
} | |||
@@ -206,11 +201,13 @@ int dsp563xx_once_reg_read_ex(struct jtag_tap *tap, int flush, uint8_t reg, uint | |||
{ | |||
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; | |||
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; | |||
if ( flush ) | |||
if (flush) | |||
err = jtag_execute_queue(); | |||
return err; | |||
} | |||
@@ -220,11 +217,13 @@ int dsp563xx_once_reg_read(struct jtag_tap *tap, int flush, uint8_t reg, uint32_ | |||
{ | |||
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; | |||
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; | |||
if ( flush ) | |||
if (flush) | |||
err = jtag_execute_queue(); | |||
return err; | |||
} | |||
@@ -234,11 +233,13 @@ int dsp563xx_once_reg_write(struct jtag_tap *tap, int flush, uint8_t reg, uint32 | |||
{ | |||
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; | |||
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; | |||
if ( flush ) | |||
if (flush) | |||
err = jtag_execute_queue(); | |||
return err; | |||
} | |||
@@ -248,11 +249,13 @@ int dsp563xx_once_execute_sw_ir(struct jtag_tap *tap, int flush, uint32_t opcode | |||
{ | |||
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; | |||
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; | |||
if ( flush ) | |||
if (flush) | |||
err = jtag_execute_queue(); | |||
return err; | |||
} | |||
@@ -262,21 +265,29 @@ int dsp563xx_once_execute_dw_ir(struct jtag_tap *tap, int flush, uint32_t opcode | |||
{ | |||
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; | |||
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; | |||
if ( flush ) | |||
if ((err = jtag_execute_queue()) != ERROR_OK) | |||
if (flush) { | |||
err = jtag_execute_queue(); | |||
if (err != ERROR_OK) | |||
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; | |||
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; | |||
if ( flush ) | |||
if ((err = jtag_execute_queue()) != ERROR_OK) | |||
if (flush) { | |||
err = jtag_execute_queue(); | |||
if (err != ERROR_OK) | |||
return err; | |||
} | |||
return ERROR_OK; | |||
} |
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef DSP563XX_ONCE_H | |||
#define DSP563XX_ONCE_H | |||
@@ -57,8 +58,7 @@ | |||
#define DSP563XX_ONCE_OPABF11 0x012 /* trace buffer/inc ptr */ | |||
#define DSP563XX_ONCE_NOREG 0x01F /* no register selected */ | |||
struct once_reg | |||
{ | |||
struct once_reg { | |||
uint8_t num; | |||
uint8_t addr; | |||
uint8_t len; | |||
@@ -20,6 +20,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#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)); | |||
fbmisr = | |||
(checksum & 2) >> 1 ^ (checksum & 4) >> 2 ^ (checksum & 16) | |||
>> 4 ^ (checksum & 0x8000) >> 15; | |||
>> 4 ^ (checksum & 0x8000) >> 15; | |||
checksum = (data ^ ((checksum << 1) | fbmisr)); | |||
} | |||
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, | |||
0xE700, 0x8A44, 0xFFFE, 0x017B, | |||
0xE700, 0xF514, 0x8563, 0x8646, | |||
0x0020, 0x0014, 0x8646, 0x0080, | |||
0x0013, 0xF042, 0x0013, 0x8B40, | |||
0x2004, 0x8246, 0x0013, 0x0020, | |||
0xA967, 0x8B40, 0x1065, 0x8246, | |||
0x0013, 0x0010, 0xA961 | |||
0xE700, 0x8A44, 0xFFFE, 0x017B, | |||
0xE700, 0xF514, 0x8563, 0x8646, | |||
0x0020, 0x0014, 0x8646, 0x0080, | |||
0x0013, 0xF042, 0x0013, 0x8B40, | |||
0x2004, 0x8246, 0x0013, 0x0020, | |||
0xA967, 0x8B40, 0x1065, 0x8246, | |||
0x0013, 0x0010, 0xA961 | |||
}; | |||
const uint32_t pgm_write_pflash_length = 31; | |||
@@ -20,6 +20,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef DSP5680XX_H | |||
#define DSP5680XX_H | |||
@@ -29,12 +30,12 @@ | |||
* @file dsp5680xx.h | |||
* @author Rodrigo Rosa <rodrigorosa.LG@gmail.com> | |||
* @date Thu Jun 9 18:54:38 2011 | |||
* | |||
* | |||
* @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. | |||
* 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 | |||
@@ -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 | |||
/** ---------------------------------------------------------------- | |||
* 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. | |||
* This value was calculated using a spreadsheet tool available on the Freescale website under FAQ 25464. | |||
* | |||
* | |||
*/ | |||
#define HFM_CLK_DEFAULT 0x27 | |||
/* 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; | |||
} | |||
/** | |||
/** | |||
* 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. | |||
* 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. | |||
* | |||
* @param target | |||
* @param buffer | |||
* Does not check if flash is erased, it's up to the user to erase the flash before running | |||
* this function. | |||
* 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. | |||
* | |||
* @param target | |||
* @param buffer | |||
* @param address Word addressing. | |||
* @param count In bytes. | |||
* @param verify_flash Execute a CRC check after flashing. | |||
* | |||
* @return | |||
* @param count In bytes. | |||
* @param verify_flash Execute a CRC check after flashing. | |||
* | |||
* @return | |||
*/ | |||
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. | |||
* | |||
* @param target | |||
* @param erased | |||
* @param sector This parameter is ignored because the FM does not support checking if individual sectors are erased. | |||
* | |||
* @return | |||
/** | |||
* 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 sector This parameter is ignored because the FM does not support checking if | |||
* individual sectors are erased. | |||
* | |||
* @return | |||
*/ | |||
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. | |||
* | |||
* @param target | |||
* @param first | |||
* @param last | |||
* | |||
* @return | |||
/** | |||
* 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. | |||
* | |||
* @param target | |||
* @param first | |||
* @param last | |||
* | |||
* @return | |||
*/ | |||
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. | |||
* | |||
* @param target | |||
/** | |||
* Reads the memory mapped protection register. A 1 implies the sector is protected, | |||
* a 0 implies the sector is not protected. | |||
* | |||
* @param target | |||
* @param protected Data read from the protection register. | |||
* | |||
* @return | |||
* | |||
* @return | |||
*/ | |||
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. | |||
* | |||
* @param target | |||
* | |||
* @return | |||
/** | |||
* 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 | |||
* | |||
* @return | |||
*/ | |||
int dsp5680xx_f_lock(struct target *target); | |||
/** | |||
/** | |||
* 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. | |||
* The flash array will be unsecured (and erased) after the first reset following the execution of this function. | |||
* | |||
* @param target | |||
* | |||
* @return | |||
* It is up to the user to select the master tap (jtag tapenable dsp5680xx.chp) | |||
* before running this function. | |||
* The flash array will be unsecured (and erased) after the first reset following | |||
* the execution of this function. | |||
* | |||
* @param target | |||
* | |||
* @return | |||
*/ | |||
int dsp5680xx_f_unlock(struct target *target); | |||
#endif /* dsp5680xx.h */ | |||
#endif /* dsp5680xx.h */ |
@@ -23,6 +23,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -87,7 +88,7 @@ static const struct { | |||
.addr = 9, | |||
.width = 32, | |||
}, | |||
[EICE_W0_DATA_VALUE ] = { | |||
[EICE_W0_DATA_VALUE] = { | |||
.name = "watch_0_data_value", | |||
.addr = 10, | |||
.width = 32, | |||
@@ -145,14 +146,16 @@ static const struct { | |||
}, | |||
}; | |||
static int embeddedice_get_reg(struct reg *reg) | |||
{ | |||
int retval; | |||
if ((retval = embeddedice_read_reg(reg)) != ERROR_OK) | |||
int retval = embeddedice_read_reg(reg); | |||
if (retval != ERROR_OK) { | |||
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"); | |||
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 | |||
* hardware support for vector_catch, single stepping, and monitor mode. | |||
*/ | |||
struct reg_cache * | |||
embeddedice_build_reg_cache(struct target *target, struct arm7_9_common *arm7_9) | |||
struct reg_cache *embeddedice_build_reg_cache(struct target *target, | |||
struct arm7_9_common *arm7_9) | |||
{ | |||
int retval; | |||
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 */ | |||
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].size = eice_regs[i].width; | |||
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 */ | |||
embeddedice_read_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++) | |||
{ | |||
free(reg_list[i].value); | |||
} | |||
free(reg_list); | |||
free(reg_cache); | |||
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); | |||
LOG_INFO("Embedded ICE version %d", eice_version); | |||
switch (eice_version) | |||
{ | |||
switch (eice_version) { | |||
case 1: | |||
/* 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. | |||
*/ | |||
if (strcmp(target_type_name(target), "feroceon") == 0 || | |||
strcmp(target_type_name(target), "dragonite") == 0) | |||
strcmp(target_type_name(target), "dragonite") == 0) | |||
break; | |||
LOG_ERROR("unknown EmbeddedICE version " | |||
"(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 | |||
* 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]; | |||
embeddedice_read_reg(dbg_ctrl); | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
buf_set_u32(dbg_ctrl->value, 4, 1, 0); | |||
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) | |||
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) | |||
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); | |||
while (size > 0) | |||
{ | |||
while (size > 0) { | |||
/* when reading the last item, set the register address to the DCC control 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; | |||
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"); | |||
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; | |||
while (size > 0) | |||
{ | |||
while (size > 0) { | |||
buf_set_u32(field0_out, 0, 32, *data); | |||
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; | |||
else if (hsbit == EICE_COMM_CTRL_RBIT) | |||
hsact = 0; | |||
else | |||
{ | |||
else { | |||
LOG_ERROR("Invalid arguments"); | |||
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); | |||
do { | |||
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; | |||
if (buf_get_u32(field0_in, hsbit, 1) == hsact) | |||
@@ -640,8 +639,7 @@ void embeddedice_write_dcc(struct jtag_tap *tap, | |||
{ | |||
int i; | |||
for (i = 0; i < count; i++) | |||
{ | |||
for (i = 0; i < count; i++) { | |||
embeddedice_write_reg_inner(tap, reg_addr, | |||
fast_target_buffer_get_u32(buffer, little)); | |||
buffer += 4; | |||
@@ -23,13 +23,13 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef EMBEDDED_ICE_H | |||
#define EMBEDDED_ICE_H | |||
#include "arm7_9_common.h" | |||
enum | |||
{ | |||
enum { | |||
EICE_DBG_CTRL = 0, | |||
EICE_DBG_STAT = 1, | |||
EICE_COMMS_CTRL = 2, | |||
@@ -49,8 +49,7 @@ enum | |||
EICE_VEC_CATCH = 16 | |||
}; | |||
enum | |||
{ | |||
enum { | |||
EICE_DBG_CONTROL_ICEDIS = 5, | |||
EICE_DBG_CONTROL_MONEN = 4, | |||
EICE_DBG_CONTROL_INTDIS = 2, | |||
@@ -58,8 +57,7 @@ enum | |||
EICE_DBG_CONTROL_DBGACK = 0, | |||
}; | |||
enum | |||
{ | |||
enum { | |||
EICE_DBG_STATUS_IJBIT = 5, | |||
EICE_DBG_STATUS_ITBIT = 4, | |||
EICE_DBG_STATUS_SYSCOMP = 3, | |||
@@ -68,8 +66,7 @@ enum | |||
EICE_DBG_STATUS_DBGACK = 0 | |||
}; | |||
enum | |||
{ | |||
enum { | |||
EICE_W_CTRL_ENABLE = 0x100, | |||
EICE_W_CTRL_RANGE = 0x80, | |||
EICE_W_CTRL_CHAIN = 0x40, | |||
@@ -81,26 +78,24 @@ enum | |||
EICE_W_CTRL_nRW = 0x1 | |||
}; | |||
enum | |||
{ | |||
enum { | |||
EICE_COMM_CTRL_WBIT = 1, | |||
EICE_COMM_CTRL_RBIT = 0 | |||
}; | |||
struct embeddedice_reg | |||
{ | |||
struct embeddedice_reg { | |||
int addr; | |||
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); | |||
int embeddedice_setup(struct target *target); | |||
int embeddedice_read_reg(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_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); | |||
/* If many embeddedice_write_reg() follow eachother, then the >1 invocations can be this faster version of | |||
* embeddedice_write_reg | |||
/* If many embeddedice_write_reg() follow eachother, then the >1 invocations can be | |||
* 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}; | |||
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[1] = (1 << 5) | reg_addr; | |||
jtag_add_dr_out(tap, | |||
2, | |||
embeddedice_num_bits, | |||
values, | |||
TAP_IDLE); | |||
jtag_add_dr_out(tap, 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 */ |
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -26,9 +27,7 @@ | |||
#include "etb.h" | |||
#include "register.h" | |||
static char* etb_reg_list[] = | |||
{ | |||
static char *etb_reg_list[] = { | |||
"ETB_identification", | |||
"ETB_ram_depth", | |||
"ETB_ram_width", | |||
@@ -50,12 +49,11 @@ static int etb_set_instr(struct etb *etb, uint32_t new_instr) | |||
if (tap == NULL) | |||
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; | |||
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; | |||
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) | |||
{ | |||
if (etb->cur_scan_chain != new_scan_chain) | |||
{ | |||
if (etb->cur_scan_chain != new_scan_chain) { | |||
struct scan_field field; | |||
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; | |||
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; | |||
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"); | |||
return retval; | |||
} | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) { | |||
LOG_ERROR("ETB register read failed"); | |||
return retval; | |||
} | |||
@@ -126,7 +123,7 @@ static const struct reg_arch_type etb_reg_type = { | |||
.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 *reg_list = NULL; | |||
@@ -145,8 +142,7 @@ struct reg_cache* etb_build_reg_cache(struct etb *etb) | |||
reg_cache->num_regs = num_regs; | |||
/* 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].size = 32; | |||
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); | |||
for (i = 0; i < num_frames; i++) | |||
{ | |||
for (i = 0; i < num_frames; i++) { | |||
/* ensure nR/W reamins set to read */ | |||
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, | |||
uint8_t* check_value, uint8_t* check_mask) | |||
uint8_t *check_value, uint8_t *check_mask) | |||
{ | |||
struct etb_reg *etb_reg = reg->arch_info; | |||
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; | |||
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"); | |||
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)); | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) { | |||
LOG_ERROR("ETB: register write failed"); | |||
return retval; | |||
} | |||
@@ -341,34 +336,28 @@ COMMAND_HANDLER(handle_etb_config_command) | |||
struct arm *arm; | |||
if (CMD_ARGC != 2) | |||
{ | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
} | |||
target = get_target(CMD_ARGV[0]); | |||
if (!target) | |||
{ | |||
if (!target) { | |||
LOG_ERROR("ETB: target '%s' not defined", CMD_ARGV[0]); | |||
return ERROR_FAIL; | |||
} | |||
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]); | |||
return ERROR_FAIL; | |||
} | |||
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]); | |||
return ERROR_FAIL; | |||
} | |||
if (arm->etm) | |||
{ | |||
if (arm->etm) { | |||
struct etb *etb = malloc(sizeof(struct etb)); | |||
arm->etm->capture_driver_priv = etb; | |||
@@ -378,9 +367,7 @@ COMMAND_HANDLER(handle_etb_config_command) | |||
etb->reg_cache = NULL; | |||
etb->ram_width = 0; | |||
etb->ram_depth = 0; | |||
} | |||
else | |||
{ | |||
} else { | |||
LOG_ERROR("ETM: target has no ETM defined, ETB left unconfigured"); | |||
return ERROR_FAIL; | |||
} | |||
@@ -397,8 +384,7 @@ COMMAND_HANDLER(handle_etb_trigger_percent_command) | |||
target = get_current_target(CMD_CTX); | |||
arm = target_to_arm(target); | |||
if (!is_arm(arm)) | |||
{ | |||
if (!is_arm(arm)) { | |||
command_print(CMD_CTX, "ETB: current target isn't an ARM"); | |||
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", | |||
etb->trigger_percent); | |||
etb->trigger_percent); | |||
return ERROR_OK; | |||
} | |||
@@ -550,13 +536,13 @@ static int etb_read_trace(struct etm_context *etm_ctx) | |||
* i.e. don't read invalid entries | |||
*/ | |||
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, 0, 32); | |||
} | |||
first_frame = buf_get_u32(etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER].value, | |||
0, | |||
32); | |||
else | |||
{ | |||
num_frames = buf_get_u32(etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER].value, 0, 32); | |||
} | |||
num_frames = buf_get_u32(etb->reg_cache->reg_list[ETB_RAM_WRITE_POINTER].value, | |||
0, | |||
32); | |||
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); | |||
if (etm_ctx->trace_depth > 0) | |||
{ | |||
free(etm_ctx->trace_data); | |||
} | |||
if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_4BIT) | |||
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); | |||
for (i = 0, j = 0; i < num_frames; i++) | |||
{ | |||
if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_4BIT) | |||
{ | |||
for (i = 0, j = 0; i < num_frames; i++) { | |||
if ((etm_ctx->control & ETM_PORT_WIDTH_MASK) == ETM_PORT_4BIT) { | |||
/* trace word j */ | |||
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].flags = 0; | |||
if ((trace_data[i] & 0x80) >> 7) | |||
{ | |||
etm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE; | |||
} | |||
if (etm_ctx->trace_data[j].pipestat == STAT_TR) | |||
{ | |||
etm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet & 0x7; | |||
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].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].flags = 0; | |||
if ((trace_data[i] & 0x8000) >> 15) | |||
{ | |||
etm_ctx->trace_data[j + 1].flags |= ETMV1_TRACESYNC_CYCLE; | |||
} | |||
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; | |||
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].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].flags = 0; | |||
if ((trace_data[i] & 0x800000) >> 23) | |||
{ | |||
etm_ctx->trace_data[j + 2].flags |= ETMV1_TRACESYNC_CYCLE; | |||
} | |||
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; | |||
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].flags |= ETMV1_TRIGGER_CYCLE; | |||
} | |||
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 */ | |||
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].flags = 0; | |||
if ((trace_data[i] & 0x800) >> 11) | |||
{ | |||
etm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE; | |||
} | |||
if (etm_ctx->trace_data[j].pipestat == STAT_TR) | |||
{ | |||
etm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet & 0x7; | |||
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].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].flags = 0; | |||
if ((trace_data[i] & 0x800000) >> 23) | |||
{ | |||
etm_ctx->trace_data[j + 1].flags |= ETMV1_TRACESYNC_CYCLE; | |||
} | |||
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; | |||
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].flags |= ETMV1_TRIGGER_CYCLE; | |||
} | |||
j += 2; | |||
} | |||
else | |||
{ | |||
} else { | |||
/* trace word j */ | |||
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].flags = 0; | |||
if ((trace_data[i] & 0x80000) >> 19) | |||
{ | |||
etm_ctx->trace_data[j].flags |= ETMV1_TRACESYNC_CYCLE; | |||
} | |||
if (etm_ctx->trace_data[j].pipestat == STAT_TR) | |||
{ | |||
etm_ctx->trace_data[j].pipestat = etm_ctx->trace_data[j].packet & 0x7; | |||
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].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 trigger_count; | |||
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_MODE_MASK) == ETM_PORT_DEMUXED) { | |||
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"); | |||
return ERROR_ETM_PORTMODE_NOT_SUPPORTED; | |||
} | |||
@@ -731,8 +695,7 @@ static int etb_stop_capture(struct etm_context *etm_ctx) | |||
return ERROR_OK; | |||
} | |||
struct etm_capture_driver etb_capture_driver = | |||
{ | |||
struct etm_capture_driver etb_capture_driver = { | |||
.name = "etb", | |||
.commands = etb_command_handlers, | |||
.init = etb_init, | |||
@@ -17,12 +17,12 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef ETB_H | |||
#define ETB_H | |||
/* ETB registers */ | |||
enum | |||
{ | |||
enum { | |||
ETB_ID = 0x00, | |||
ETB_RAM_DEPTH = 0x01, | |||
ETB_RAM_WIDTH = 0x02, | |||
@@ -34,8 +34,7 @@ enum | |||
ETB_CTRL = 0x08, | |||
}; | |||
struct etb | |||
{ | |||
struct etb { | |||
struct etm_context *etm_ctx; | |||
struct jtag_tap *tap; | |||
uint32_t cur_scan_chain; | |||
@@ -49,14 +48,13 @@ struct etb | |||
unsigned trigger_percent; | |||
}; | |||
struct etb_reg | |||
{ | |||
struct etb_reg { | |||
uint32_t addr; | |||
struct etb *etb; | |||
}; | |||
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 */ |
@@ -20,6 +20,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef ETM_H | |||
#define ETM_H | |||
@@ -29,8 +30,7 @@ | |||
struct image; | |||
/* ETM registers (JTAG protocol) */ | |||
enum | |||
{ | |||
enum { | |||
ETM_CTRL = 0x00, | |||
ETM_CONFIG = 0x01, | |||
ETM_TRIG_EVENT = 0x02, | |||
@@ -71,8 +71,7 @@ enum | |||
ETM_ID = 0x79, | |||
}; | |||
struct etm_reg | |||
{ | |||
struct etm_reg { | |||
uint32_t value; | |||
const struct etm_reg_info *reg_info; | |||
struct arm_jtag *jtag_info; | |||
@@ -84,8 +83,7 @@ struct etm_reg | |||
* | |||
* NOTE that these have evolved since the ~v1.3 defns ... | |||
*/ | |||
enum | |||
{ | |||
enum { | |||
ETM_CTRL_POWERDOWN = (1 << 0), | |||
ETM_CTRL_MONITOR_CPRT = (1 << 1), | |||
@@ -118,7 +116,7 @@ enum | |||
ETM_PORT_HALF_CLOCK = (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_8 = (1 << 14), | |||
ETM_CTRL_CONTEXTID_16 = (2 << 14), | |||
@@ -131,14 +129,13 @@ enum | |||
ETM_PORT_DEMUXED = (2 << 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 */ | |||
struct etm_context; | |||
struct etm_capture_driver | |||
{ | |||
struct etm_capture_driver { | |||
const char *name; | |||
const struct command_registration *commands; | |||
int (*init)(struct etm_context *etm_ctx); | |||
@@ -148,14 +145,12 @@ struct etm_capture_driver | |||
int (*stop_capture)(struct etm_context *etm_ctx); | |||
}; | |||
enum | |||
{ | |||
enum { | |||
ETMV1_TRACESYNC_CYCLE = 0x1, | |||
ETMV1_TRIGGER_CYCLE = 0x2, | |||
}; | |||
struct etmv1_trace_data | |||
{ | |||
struct etmv1_trace_data { | |||
uint8_t pipestat; /* bits 0-2 pipeline status */ | |||
uint16_t packet; /* packet data (4, 8 or 16 bit) */ | |||
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 | |||
* and a version specific part | |||
*/ | |||
struct etm_context | |||
{ | |||
struct etm_context { | |||
struct target *target; /* target this ETM is connected to */ | |||
struct reg_cache *reg_cache; /* ETM register cache */ | |||
struct etm_capture_driver *capture_driver; /* driver used to access ETM data */ | |||
@@ -194,8 +188,7 @@ struct etm_context | |||
}; | |||
/* PIPESTAT values */ | |||
typedef enum | |||
{ | |||
typedef enum { | |||
STAT_IE = 0x0, | |||
STAT_ID = 0x1, | |||
STAT_IN = 0x2, | |||
@@ -207,8 +200,7 @@ typedef enum | |||
} etmv1_pipestat_t; | |||
/* branch reason values */ | |||
typedef enum | |||
{ | |||
typedef enum { | |||
BR_NORMAL = 0x0, /* Normal PC change : periodic synchro (ETMv1.1) */ | |||
BR_ENABLE = 0x1, /* Trace has been enabled */ | |||
BR_RESTART = 0x2, /* Trace restarted after a FIFO overflow */ | |||
@@ -219,7 +211,7 @@ typedef enum | |||
BR_RSVD7 = 0x7, /* reserved */ | |||
} 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); | |||
int etm_setup(struct target *target); | |||
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -24,7 +25,6 @@ | |||
#include "arm.h" | |||
#include "etm_dummy.h" | |||
COMMAND_HANDLER(handle_etm_dummy_config_command) | |||
{ | |||
struct target *target; | |||
@@ -32,25 +32,20 @@ COMMAND_HANDLER(handle_etm_dummy_config_command) | |||
target = get_target(CMD_ARGV[0]); | |||
if (!target) | |||
{ | |||
if (!target) { | |||
LOG_ERROR("target '%s' not defined", CMD_ARGV[0]); | |||
return ERROR_FAIL; | |||
} | |||
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]); | |||
return ERROR_FAIL; | |||
} | |||
if (arm->etm) | |||
{ | |||
arm->etm->capture_driver_priv = NULL; | |||
} | |||
else | |||
{ | |||
else { | |||
LOG_ERROR("target has no ETM defined, ETM dummy left unconfigured"); | |||
return ERROR_FAIL; | |||
} | |||
@@ -102,8 +97,7 @@ static int etm_dummy_stop_capture(struct etm_context *etm_ctx) | |||
return ERROR_OK; | |||
} | |||
struct etm_capture_driver etm_dummy_capture_driver = | |||
{ | |||
struct etm_capture_driver etm_dummy_capture_driver = { | |||
.name = "dummy", | |||
.commands = etm_dummy_command_handlers, | |||
.init = etm_dummy_init, | |||
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef ETM_DUMMY_H | |||
#define ETM_DUMMY_H | |||
@@ -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, | |||
uint32_t mask, uint32_t* core_regs[16]) | |||
uint32_t mask, uint32_t *core_regs[16]) | |||
{ | |||
int i; | |||
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) */ | |||
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)) | |||
/* nothing fetched, STM in MEMORY (i'th cycle) */ | |||
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, | |||
uint32_t mask, void* buffer, int size) | |||
uint32_t mask, void *buffer, int size) | |||
{ | |||
int i; | |||
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) */ | |||
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)) | |||
/* nothing fetched, STM in MEMORY (i'th cycle) */ | |||
switch (size) | |||
{ | |||
switch (size) { | |||
case 4: | |||
arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be); | |||
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); | |||
/* rot == 4 writes flags, which takes only one cycle */ | |||
if (rot != 4) | |||
{ | |||
if (rot != 4) { | |||
/* nothing fetched, MSR in EXECUTE (2) */ | |||
arm9tdmi_clock_out(jtag_info, ARMV4_5_NOP, 0, NULL, 0); | |||
/* 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) */ | |||
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)) | |||
/* nothing fetched, LDM still in EXECUTE (1 + i cycle) */ | |||
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) | |||
{ | |||
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); | |||
} | |||
/** Holds methods for FA526 targets. */ | |||
struct target_type fa526_target = | |||
{ | |||
struct target_type fa526_target = { | |||
.name = "fa526", | |||
.poll = arm7_9_poll, | |||
@@ -58,7 +58,6 @@ | |||
#include "register.h" | |||
#include "arm_opcodes.h" | |||
static int feroceon_assert_reset(struct target *target) | |||
{ | |||
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, | |||
uint32_t mask, uint32_t* core_regs[16]) | |||
uint32_t mask, uint32_t *core_regs[16]) | |||
{ | |||
int i; | |||
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, | |||
uint32_t mask, void* buffer, int size) | |||
uint32_t mask, void *buffer, int size) | |||
{ | |||
int i; | |||
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); | |||
for (i = 0; i <= 15; i++) | |||
{ | |||
for (i = 0; i <= 15; i++) { | |||
if (mask & (1 << i)) { | |||
switch (size) | |||
{ | |||
switch (size) { | |||
case 4: | |||
arm9tdmi_clock_data_in_endianness(jtag_info, buf_u32++, 4, be); | |||
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, 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_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 */ | |||
if (target->debug_reason != DBG_REASON_SINGLESTEP) | |||
{ | |||
target->debug_reason = DBG_REASON_DBGRQ; | |||
} | |||
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 | |||
* 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 */ | |||
0xe3a0301e, /* 1: mov r3, #30 */ | |||
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); | |||
/* 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]; | |||
/* 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"); | |||
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]); | |||
/* 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; | |||
} | |||
} | |||
/* backup clobbered processor state */ | |||
@@ -543,14 +535,12 @@ static int feroceon_bulk_write_memory(struct target *target, | |||
x = 0; | |||
flip = 0; | |||
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 z = (x >> 1) | (y >> shift) | (flip ^= 0x80000000); | |||
embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], z); | |||
x = y << (32 - shift); | |||
if (++shift >= 32 || i + 1 >= count) | |||
{ | |||
if (++shift >= 32 || i + 1 >= count) { | |||
z = (x >> 1) | (flip ^= 0x80000000); | |||
embeddedice_write_reg(&arm7_9->eice_cache->reg_list[EICE_COMMS_DATA], z); | |||
x = 0; | |||
@@ -563,20 +553,19 @@ static int feroceon_bulk_write_memory(struct target *target, | |||
if (retval == ERROR_OK) | |||
retval = target_wait_state(target, TARGET_HALTED, 500); | |||
if (retval == ERROR_OK) { | |||
uint32_t endaddress = | |||
uint32_t endaddress = | |||
buf_get_u32(arm->core_cache->reg_list[0].value, 0, 32); | |||
if (endaddress != address + count*4) { | |||
LOG_ERROR("DCC write failed," | |||
" expected end address 0x%08" PRIx32 | |||
" got 0x%0" PRIx32 "", | |||
address + count*4, endaddress); | |||
address + count*4, endaddress); | |||
retval = ERROR_FAIL; | |||
} | |||
} | |||
/* 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]); | |||
arm->core_cache->reg_list[i].valid = 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) | |||
{ | |||
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); | |||
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) | |||
{ | |||
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); | |||
feroceon_common_setup(target); | |||
@@ -687,8 +676,7 @@ static int feroceon_examine(struct target *target) | |||
return ERROR_OK; | |||
} | |||
struct target_type feroceon_target = | |||
{ | |||
struct target_type feroceon_target = { | |||
.name = "feroceon", | |||
.poll = arm7_9_poll, | |||
@@ -726,8 +714,7 @@ struct target_type feroceon_target = | |||
.examine = feroceon_examine, | |||
}; | |||
struct target_type dragonite_target = | |||
{ | |||
struct target_type dragonite_target = { | |||
.name = "dragonite", | |||
.poll = arm7_9_poll, | |||
@@ -764,4 +751,3 @@ struct target_type dragonite_target = | |||
.init_target = feroceon_init_target, | |||
.examine = feroceon_examine, | |||
}; | |||
@@ -23,6 +23,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef IMAGE_H | |||
#define IMAGE_H | |||
@@ -37,8 +38,7 @@ | |||
#define IMAGE_MEMORY_CACHE_SIZE (2048) | |||
enum image_type | |||
{ | |||
enum image_type { | |||
IMAGE_BINARY, /* plain binary */ | |||
IMAGE_IHEX, /* intel hex-record format */ | |||
IMAGE_MEMORY, /* target-memory pseudo-image */ | |||
@@ -47,16 +47,14 @@ enum image_type | |||
IMAGE_BUILDER, /* when building a new image */ | |||
}; | |||
struct imagesection | |||
{ | |||
struct imagesection { | |||
uint32_t base_address; | |||
uint32_t size; | |||
int flags; | |||
void *private; /* private data */ | |||
}; | |||
struct image | |||
{ | |||
struct image { | |||
enum image_type type; /* image type (plain, ihex, ...) */ | |||
void *type_private; /* type private data */ | |||
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 */ | |||
}; | |||
struct image_binary | |||
{ | |||
struct image_binary { | |||
struct fileio fileio; | |||
}; | |||
struct image_ihex | |||
{ | |||
struct image_ihex { | |||
struct fileio fileio; | |||
uint8_t *buffer; | |||
}; | |||
struct image_memory | |||
{ | |||
struct image_memory { | |||
struct target *target; | |||
uint8_t *cache; | |||
uint32_t cache_address; | |||
}; | |||
struct image_elf | |||
{ | |||
struct image_elf { | |||
struct fileio fileio; | |||
Elf32_Ehdr *header; | |||
Elf32_Phdr *segments; | |||
@@ -94,8 +88,7 @@ struct image_elf | |||
uint8_t endianness; | |||
}; | |||
struct image_mot | |||
{ | |||
struct image_mot { | |||
struct fileio fileio; | |||
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 flags, uint8_t *data); | |||
int image_calculate_checksum(uint8_t* buffer, uint32_t nbytes, | |||
uint32_t* checksum); | |||
int image_calculate_checksum(uint8_t *buffer, uint32_t nbytes, | |||
uint32_t *checksum); | |||
#define ERROR_IMAGE_FORMAT_ERROR (-1400) | |||
#define ERROR_IMAGE_TYPE_UNKNOWN (-1401) | |||
@@ -25,6 +25,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -34,8 +35,7 @@ | |||
#include "algorithm.h" | |||
#include "register.h" | |||
static char* mips32_core_reg_list[] = | |||
{ | |||
static char *mips32_core_reg_list[] = { | |||
"zero", "at", "v0", "v1", "a0", "a1", "a2", "a3", | |||
"t0", "t1", "t2", "t3", "t4", "t5", "t6", "t7", | |||
"s0", "s1", "s2", "s3", "s4", "s5", "s6", "s7", | |||
@@ -43,13 +43,11 @@ static char* mips32_core_reg_list[] = | |||
"status", "lo", "hi", "badvaddr", "cause", "pc" | |||
}; | |||
static const char *mips_isa_strings[] = | |||
{ | |||
static const char *mips_isa_strings[] = { | |||
"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}, | |||
{1, 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 | |||
* 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 struct reg mips32_gdb_dummy_fp_reg = | |||
{ | |||
static struct reg mips32_gdb_dummy_fp_reg = { | |||
.name = "GDB dummy floating-point register", | |||
.value = mips32_gdb_dummy_fp_value, | |||
.dirty = 0, | |||
@@ -116,9 +113,7 @@ static int mips32_get_core_reg(struct reg *reg) | |||
struct mips32_common *mips32_target = target_to_mips32(target); | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
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); | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
buf_set_u32(reg->value, 0, 32, value); | |||
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 */ | |||
*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++) | |||
{ | |||
(*reg_list)[i] = &mips32->core_cache->reg_list[i]; | |||
} | |||
/* add dummy floating points regs */ | |||
for (i = MIPS32NUMCOREREGS; i < (MIPS32NUMCOREREGS + MIPS32NUMFPREGS); i++) | |||
{ | |||
(*reg_list)[i] = &mips32_gdb_dummy_fp_reg; | |||
} | |||
return ERROR_OK; | |||
} | |||
@@ -215,12 +204,9 @@ int mips32_save_context(struct target *target) | |||
/* read core registers */ | |||
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) | |||
{ | |||
mips32->read_core_reg(target, i); | |||
} | |||
} | |||
return ERROR_OK; | |||
@@ -234,12 +220,9 @@ int mips32_restore_context(struct target *target) | |||
struct mips32_common *mips32 = target_to_mips32(target); | |||
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) | |||
{ | |||
mips32->write_core_reg(target, i); | |||
} | |||
} | |||
/* write core regs */ | |||
@@ -287,8 +270,7 @@ struct reg_cache *mips32_build_reg_cache(struct target *target) | |||
(*cache_p) = 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].target = target; | |||
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; | |||
/* 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 */ | |||
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; | |||
} | |||
retval = target_wait_state(target, TARGET_HALTED, timeout_ms); | |||
/* If the target fails to halt due to the breakpoint, force a halt */ | |||
if (retval != ERROR_OK || target->state != TARGET_HALTED) | |||
{ | |||
if ((retval = target_halt(target)) != ERROR_OK) | |||
if (retval != ERROR_OK || target->state != TARGET_HALTED) { | |||
retval = target_halt(target); | |||
if (retval != ERROR_OK) | |||
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 ERROR_TARGET_TIMEOUT; | |||
} | |||
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); | |||
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 | |||
* 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"); | |||
return ERROR_TARGET_INVALID; | |||
} | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
if (target->state != TARGET_HALTED) { | |||
LOG_WARNING("target not halted"); | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
/* refresh core register cache */ | |||
for (i = 0; i < MIPS32NUMCOREREGS; i++) | |||
{ | |||
for (i = 0; i < MIPS32NUMCOREREGS; i++) { | |||
if (!mips32->core_cache->reg_list[i].valid) | |||
mips32->read_core_reg(target, i); | |||
context[i] = buf_get_u32(mips32->core_cache->reg_list[i].value, 0, 32); | |||
} | |||
for (i = 0; i < num_mem_params; i++) | |||
{ | |||
if ((retval = target_write_buffer(target, mem_params[i].address, | |||
mem_params[i].size, mem_params[i].value)) != ERROR_OK) | |||
{ | |||
for (i = 0; i < num_mem_params; i++) { | |||
retval = target_write_buffer(target, mem_params[i].address, | |||
mem_params[i].size, mem_params[i].value); | |||
if (retval != ERROR_OK) | |||
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); | |||
if (!reg) | |||
{ | |||
if (!reg) { | |||
LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name); | |||
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", | |||
reg_params[i].reg_name); | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
@@ -431,31 +402,24 @@ int mips32_run_algorithm(struct target *target, int num_mem_params, | |||
if (retval != ERROR_OK) | |||
return retval; | |||
for (i = 0; i < num_mem_params; i++) | |||
{ | |||
if (mem_params[i].direction != PARAM_OUT) | |||
{ | |||
if ((retval = target_read_buffer(target, mem_params[i].address, mem_params[i].size, | |||
mem_params[i].value)) != ERROR_OK) | |||
{ | |||
for (i = 0; i < num_mem_params; i++) { | |||
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 != ERROR_OK) | |||
return retval; | |||
} | |||
} | |||
} | |||
for (i = 0; i < num_reg_params; i++) | |||
{ | |||
if (reg_params[i].direction != PARAM_OUT) | |||
{ | |||
for (i = 0; i < num_reg_params; i++) { | |||
if (reg_params[i].direction != PARAM_OUT) { | |||
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); | |||
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", | |||
reg_params[i].reg_name); | |||
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 */ | |||
for (i = 0; i < MIPS32NUMCOREREGS; i++) | |||
{ | |||
for (i = 0; i < MIPS32NUMCOREREGS; i++) { | |||
uint32_t regvalue; | |||
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, | |||
mips32->core_cache->reg_list[i].name, context[i]); | |||
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); | |||
if (!target_was_examined(target)) | |||
{ | |||
if (!target_was_examined(target)) { | |||
target_set_examined(target); | |||
/* we will configure later */ | |||
@@ -517,53 +478,50 @@ int mips32_configure_break_unit(struct target *target) | |||
return ERROR_OK; | |||
/* 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; | |||
if (dcr & EJTAG_DCR_IB) | |||
{ | |||
if (dcr & EJTAG_DCR_IB) { | |||
/* 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; | |||
mips32->num_inst_bpoints = (bpinfo >> 24) & 0x0F; | |||
mips32->num_inst_bpoints_avail = mips32->num_inst_bpoints; | |||
mips32->inst_break_list = calloc(mips32->num_inst_bpoints, sizeof(struct mips32_comparator)); | |||
for (i = 0; i < mips32->num_inst_bpoints; i++) | |||
{ | |||
mips32->inst_break_list[i].reg_address = EJTAG_IBA1 + (0x100 * i); | |||
} | |||
/* 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; | |||
} | |||
if (dcr & EJTAG_DCR_DB) | |||
{ | |||
if (dcr & EJTAG_DCR_DB) { | |||
/* 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; | |||
mips32->num_data_bpoints = (bpinfo >> 24) & 0x0F; | |||
mips32->num_data_bpoints_avail = mips32->num_data_bpoints; | |||
mips32->data_break_list = calloc(mips32->num_data_bpoints, sizeof(struct mips32_comparator)); | |||
for (i = 0; i < mips32->num_data_bpoints; i++) | |||
{ | |||
mips32->data_break_list[i].reg_address = EJTAG_DBA1 + (0x100 * i); | |||
} | |||
/* 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; | |||
} | |||
/* check if target endianness settings matches debug control register */ | |||
if ( ( (dcr & EJTAG_DCR_ENM) && (target->endianness == TARGET_LITTLE_ENDIAN) ) || | |||
( !(dcr & EJTAG_DCR_ENM) && (target->endianness == TARGET_BIG_ENDIAN) ) ) | |||
{ | |||
if (((dcr & EJTAG_DCR_ENM) && (target->endianness == TARGET_LITTLE_ENDIAN)) || | |||
(!(dcr & EJTAG_DCR_ENM) && (target->endianness == TARGET_BIG_ENDIAN))) | |||
LOG_WARNING("DCR endianness settings does not match target settings"); | |||
} | |||
LOG_DEBUG("DCR 0x%" PRIx32 " numinst %i numdata %i", dcr, mips32->num_inst_bpoints, | |||
mips32->num_data_bpoints); | |||
@@ -580,31 +538,27 @@ int mips32_enable_interrupts(struct target *target, int enable) | |||
uint32_t dcr; | |||
/* 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; | |||
if (enable) | |||
{ | |||
if (!(dcr & EJTAG_DCR_INTE)) | |||
{ | |||
if (enable) { | |||
if (!(dcr & EJTAG_DCR_INTE)) { | |||
/* enable interrupts */ | |||
dcr |= EJTAG_DCR_INTE; | |||
update = 1; | |||
} | |||
} | |||
else | |||
{ | |||
if (dcr & EJTAG_DCR_INTE) | |||
{ | |||
} else { | |||
if (dcr & EJTAG_DCR_INTE) { | |||
/* disable interrupts */ | |||
dcr &= ~EJTAG_DCR_INTE; | |||
update = 1; | |||
} | |||
} | |||
if (update) | |||
{ | |||
if ((retval = target_write_u32(target, EJTAG_DCR, dcr)) != ERROR_OK) | |||
if (update) { | |||
retval = target_write_u32(target, EJTAG_DCR, dcr); | |||
if (retval != ERROR_OK) | |||
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, | |||
uint32_t count, uint32_t* checksum) | |||
uint32_t count, uint32_t *checksum) | |||
{ | |||
struct working_area *crc_algorithm; | |||
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 */ | |||
static const uint32_t mips_crc_code[] = | |||
{ | |||
0x248C0000, /* addiu $t4, $a0, 0 */ | |||
static const uint32_t mips_crc_code[] = { | |||
0x248C0000, /* addiu $t4, $a0, 0 */ | |||
0x24AA0000, /* addiu $t2, $a1, 0 */ | |||
0x2404FFFF, /* addiu $a0, $zero, 0xffffffff */ | |||
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 */ | |||
if (target_alloc_working_area(target, sizeof(mips_crc_code), &crc_algorithm) != ERROR_OK) | |||
{ | |||
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; | |||
} | |||
/* convert flash writing code into a buffer in target endianness */ | |||
for (i = 0; i < 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))); | |||
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, | |||
&mips32_info)) != ERROR_OK) | |||
{ | |||
&mips32_info); | |||
if (retval != ERROR_OK) { | |||
destroy_reg_param(®_params[0]); | |||
destroy_reg_param(®_params[1]); | |||
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. */ | |||
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 reg_param reg_params[3]; | |||
@@ -703,8 +654,7 @@ int mips32_blank_check_memory(struct target *target, | |||
int retval; | |||
uint32_t i; | |||
static const uint32_t erase_check_code[] = | |||
{ | |||
static const uint32_t erase_check_code[] = { | |||
/* nbyte: */ | |||
0x80880000, /* lb $t0, ($a0) */ | |||
0x00C83024, /* and $a2, $a2, $t0 */ | |||
@@ -716,13 +666,10 @@ int mips32_blank_check_memory(struct target *target, | |||
/* make sure we have a working area */ | |||
if (target_alloc_working_area(target, sizeof(erase_check_code), &erase_check_algorithm) != ERROR_OK) | |||
{ | |||
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; | |||
} | |||
/* 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), | |||
erase_check_code[i]); | |||
} | |||
@@ -739,11 +686,11 @@ int mips32_blank_check_memory(struct target *target, | |||
init_reg_param(®_params[2], "a2", 32, PARAM_IN_OUT); | |||
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 + (sizeof(erase_check_code)-2), | |||
10000, &mips32_info)) != ERROR_OK) | |||
{ | |||
10000, &mips32_info); | |||
if (retval != ERROR_OK) { | |||
destroy_reg_param(®_params[0]); | |||
destroy_reg_param(®_params[1]); | |||
destroy_reg_param(®_params[2]); | |||
@@ -788,48 +735,40 @@ COMMAND_HANDLER(mips32_handle_cp0_command) | |||
if (retval != ERROR_OK) | |||
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); | |||
return ERROR_OK; | |||
} | |||
/* two or more argument, access a single register/select (write if third argument is given) */ | |||
if (CMD_ARGC < 2) | |||
{ | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
} | |||
else | |||
{ | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
else { | |||
uint32_t cp0_reg, cp0_sel; | |||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg); | |||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel); | |||
if (CMD_ARGC == 2) | |||
{ | |||
if (CMD_ARGC == 2) { | |||
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, | |||
"couldn't access reg %" PRIi32, | |||
cp0_reg); | |||
return ERROR_OK; | |||
} | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32, | |||
cp0_reg, cp0_sel, value); | |||
} | |||
else if (CMD_ARGC == 3) | |||
{ | |||
} else if (CMD_ARGC == 3) { | |||
uint32_t 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, | |||
"couldn't access cp0 reg %" PRIi32 ", select %" PRIi32, | |||
cp0_reg, cp0_sel); | |||
@@ -864,4 +803,3 @@ const struct command_registration mips32_command_handlers[] = { | |||
}, | |||
COMMAND_REGISTRATION_DONE | |||
}; | |||
@@ -64,27 +64,23 @@ | |||
#define MIPS32_ARCH_REL2 0x1 | |||
/* offsets into mips32 core register cache */ | |||
enum | |||
{ | |||
enum { | |||
MIPS32_PC = 37, | |||
MIPS32NUMCOREREGS | |||
}; | |||
enum mips32_isa_mode | |||
{ | |||
enum mips32_isa_mode { | |||
MIPS32_ISA_MIPS32 = 0, | |||
MIPS32_ISA_MIPS16E = 1, | |||
}; | |||
struct mips32_comparator | |||
{ | |||
struct mips32_comparator { | |||
int used; | |||
uint32_t bp_value; | |||
uint32_t reg_address; | |||
}; | |||
struct mips32_common | |||
{ | |||
struct mips32_common { | |||
uint32_t common_magic; | |||
void *arch_info; | |||
struct reg_cache *core_cache; | |||
@@ -114,15 +110,13 @@ target_to_mips32(struct target *target) | |||
return target->arch_info; | |||
} | |||
struct mips32_core_reg | |||
{ | |||
struct mips32_core_reg { | |||
uint32_t num; | |||
struct target *target; | |||
struct mips32_common *mips32_common; | |||
}; | |||
struct mips32_algorithm | |||
{ | |||
struct mips32_algorithm { | |||
int common_magic; | |||
enum mips32_isa_mode isa_mode; | |||
}; | |||
@@ -164,9 +158,11 @@ struct mips32_algorithm | |||
#define MIPS32_COP0_MF 0x00 | |||
#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_I_INST(opcode, rs, rt, immd) (((opcode) << 26) |((rs) << 21) | ((rt) << 16) | (immd)) | |||
#define MIPS32_J_INST(opcode, addr) (((opcode) << 26) |(addr)) | |||
#define MIPS32_R_INST(opcode, rs, rt, rd, shamt, funct) \ | |||
(((opcode) << 26) | ((rs) << 21) | ((rt) << 16) | ((rd) << 11) | ((shamt) << 6) | (funct)) | |||
#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_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_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_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_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) | |||
@@ -245,8 +241,8 @@ int mips32_register_commands(struct command_context *cmd_ctx); | |||
int mips32_get_gdb_reg_list(struct target *target, | |||
struct reg **reg_list[], int *reg_list_size); | |||
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, | |||
uint32_t address, uint32_t count, uint32_t* blank); | |||
uint32_t address, uint32_t count, uint32_t *blank); | |||
#endif /*MIPS32_H*/ |
@@ -22,6 +22,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -84,13 +85,11 @@ begin_ejtag_dma_read: | |||
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); | |||
ejtag_ctrl = 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--) { | |||
LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ (retrying)", addr); | |||
goto begin_ejtag_dma_read; | |||
} | |||
else | |||
} else | |||
LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ", addr); | |||
return ERROR_JTAG_DEVICE_ERROR; | |||
} | |||
@@ -113,7 +112,8 @@ begin_ejtag_dma_read_h: | |||
/* Initiate DMA Read & set DSTRT */ | |||
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); | |||
/* Wait for DSTRT to Clear */ | |||
@@ -130,13 +130,11 @@ begin_ejtag_dma_read_h: | |||
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); | |||
ejtag_ctrl = 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--) { | |||
LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ (retrying)", addr); | |||
goto begin_ejtag_dma_read_h; | |||
} | |||
else | |||
} else | |||
LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ", addr); | |||
return ERROR_JTAG_DEVICE_ERROR; | |||
} | |||
@@ -182,13 +180,11 @@ begin_ejtag_dma_read_b: | |||
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); | |||
ejtag_ctrl = 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--) { | |||
LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ (retrying)", addr); | |||
goto begin_ejtag_dma_read_b; | |||
} | |||
else | |||
} else | |||
LOG_ERROR("DMA Read Addr = %08" PRIx32 " Data = ERROR ON READ", addr); | |||
return ERROR_JTAG_DEVICE_ERROR; | |||
} | |||
@@ -245,13 +241,11 @@ begin_ejtag_dma_write: | |||
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); | |||
ejtag_ctrl = 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--) { | |||
LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE (retrying)", addr); | |||
goto begin_ejtag_dma_write; | |||
} | |||
else | |||
} else | |||
LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE", addr); | |||
return ERROR_JTAG_DEVICE_ERROR; | |||
} | |||
@@ -296,13 +290,11 @@ begin_ejtag_dma_write_h: | |||
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); | |||
ejtag_ctrl = 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--) { | |||
LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE (retrying)", addr); | |||
goto begin_ejtag_dma_write_h; | |||
} | |||
else | |||
} else | |||
LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE", addr); | |||
return ERROR_JTAG_DEVICE_ERROR; | |||
} | |||
@@ -348,13 +340,11 @@ begin_ejtag_dma_write_b: | |||
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL); | |||
ejtag_ctrl = 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--) { | |||
LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE (retrying)", addr); | |||
goto begin_ejtag_dma_write_b; | |||
} | |||
else | |||
} else | |||
LOG_ERROR("DMA Write Addr = %08" PRIx32 " Data = ERROR ON WRITE", addr); | |||
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) | |||
{ | |||
switch (size) | |||
{ | |||
switch (size) { | |||
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: | |||
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: | |||
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; | |||
@@ -383,7 +372,8 @@ static int mips32_dmaacc_read_mem32(struct mips_ejtag *ejtag_info, uint32_t addr | |||
int retval; | |||
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; | |||
} | |||
@@ -396,7 +386,8 @@ static int mips32_dmaacc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr | |||
int retval; | |||
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; | |||
} | |||
@@ -409,7 +400,8 @@ static int mips32_dmaacc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, | |||
int retval; | |||
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; | |||
} | |||
@@ -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) | |||
{ | |||
switch (size) | |||
{ | |||
switch (size) { | |||
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: | |||
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: | |||
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; | |||
@@ -437,7 +428,8 @@ static int mips32_dmaacc_write_mem32(struct mips_ejtag *ejtag_info, uint32_t add | |||
int retval; | |||
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; | |||
} | |||
@@ -450,7 +442,8 @@ static int mips32_dmaacc_write_mem16(struct mips_ejtag *ejtag_info, uint32_t add | |||
int retval; | |||
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; | |||
} | |||
@@ -463,7 +456,8 @@ static int mips32_dmaacc_write_mem8(struct mips_ejtag *ejtag_info, uint32_t addr | |||
int retval; | |||
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; | |||
} | |||
@@ -22,6 +22,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef MIPS32_DMAACC_H | |||
#define MIPS32_DMAACC_H | |||
@@ -22,6 +22,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef 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 | |||
*/ | |||
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 | |||
@@ -87,6 +88,6 @@ int mips32_cp0_read(struct mips_ejtag *ejtag_info, | |||
* @return ERROR_OK on Sucess, ERROR_FAIL otherwise | |||
*/ | |||
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 |
@@ -21,6 +21,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -35,8 +36,7 @@ void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, int new_instr) | |||
tap = ejtag_info->tap; | |||
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; | |||
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); | |||
int retval; | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) { | |||
LOG_ERROR("register read failed"); | |||
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); | |||
int retval; | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) { | |||
LOG_ERROR("register read failed"); | |||
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); | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) { | |||
LOG_ERROR("register read failed"); | |||
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); | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) { | |||
LOG_ERROR("register read failed"); | |||
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 const uint32_t code[] = { | |||
MIPS32_MTC0(1,31,0), /* move $1 to COP0 DeSave */ | |||
MIPS32_MFC0(1,23,0), /* move COP0 Debug to $1 */ | |||
MIPS32_ORI(1,1,0x0100), /* set SSt bit in debug reg */ | |||
MIPS32_MTC0(1,23,0), /* move $1 to COP0 Debug */ | |||
MIPS32_MTC0(1, 31, 0), /* move $1 to COP0 DeSave */ | |||
MIPS32_MFC0(1, 23, 0), /* move COP0 Debug to $1 */ | |||
MIPS32_ORI(1, 1, 0x0100), /* set SSt bit in debug reg */ | |||
MIPS32_MTC0(1, 23, 0), /* move $1 to COP0 Debug */ | |||
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, | |||
@@ -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 const uint32_t code[] = { | |||
MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */ | |||
MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */ | |||
MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)), | |||
MIPS32_SW(1,0,15), /* sw $1,($15) */ | |||
MIPS32_SW(2,0,15), /* sw $2,($15) */ | |||
MIPS32_MFC0(1,23,0), /* move COP0 Debug to $1 */ | |||
MIPS32_LUI(2,0xFFFF), /* $2 = 0xfffffeff */ | |||
MIPS32_ORI(2,2,0xFEFF), | |||
MIPS32_AND(1,1,2), | |||
MIPS32_MTC0(1,23,0), /* move $1 to COP0 Debug */ | |||
MIPS32_LW(2,0,15), | |||
MIPS32_LW(1,0,15), | |||
MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */ | |||
MIPS32_LUI(15, UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */ | |||
MIPS32_ORI(15, 15, LOWER16(MIPS32_PRACC_STACK)), | |||
MIPS32_SW(1, 0, 15), /* sw $1,($15) */ | |||
MIPS32_SW(2, 0, 15), /* sw $2,($15) */ | |||
MIPS32_MFC0(1, 23, 0), /* move COP0 Debug to $1 */ | |||
MIPS32_LUI(2, 0xFFFF), /* $2 = 0xfffffeff */ | |||
MIPS32_ORI(2, 2, 0xFEFF), | |||
MIPS32_AND(1, 1, 2), | |||
MIPS32_MTC0(1, 23, 0), /* move $1 to COP0 Debug */ | |||
MIPS32_LW(2, 0, 15), | |||
MIPS32_LW(1, 0, 15), | |||
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, | |||
@@ -248,8 +248,7 @@ int mips_ejtag_enter_debug(struct mips_ejtag *ejtag_info) | |||
ejtag_ctrl = ejtag_info->ejtag_ctrl; | |||
mips_ejtag_drscan_32(ejtag_info, &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!"); | |||
return ERROR_FAIL; | |||
} | |||
@@ -270,19 +269,19 @@ int mips_ejtag_read_debug(struct mips_ejtag *ejtag_info, uint32_t* debug_reg) | |||
{ | |||
/* read ejtag ECR */ | |||
static const uint32_t code[] = { | |||
MIPS32_MTC0(15,31,0), /* move $15 to COP0 DeSave */ | |||
MIPS32_LUI(15,UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */ | |||
MIPS32_ORI(15,15,LOWER16(MIPS32_PRACC_STACK)), | |||
MIPS32_SW(1,0,15), /* sw $1,($15) */ | |||
MIPS32_SW(2,0,15), /* sw $2,($15) */ | |||
MIPS32_LUI(1,UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $1 = MIPS32_PRACC_PARAM_OUT */ | |||
MIPS32_ORI(1,1,LOWER16(MIPS32_PRACC_PARAM_OUT)), | |||
MIPS32_MFC0(2,23,0), /* move COP0 Debug to $2 */ | |||
MIPS32_SW(2,0,1), | |||
MIPS32_LW(2,0,15), | |||
MIPS32_LW(1,0,15), | |||
MIPS32_MTC0(15, 31, 0), /* move $15 to COP0 DeSave */ | |||
MIPS32_LUI(15, UPPER16(MIPS32_PRACC_STACK)), /* $15 = MIPS32_PRACC_STACK */ | |||
MIPS32_ORI(15, 15, LOWER16(MIPS32_PRACC_STACK)), | |||
MIPS32_SW(1, 0, 15), /* sw $1,($15) */ | |||
MIPS32_SW(2, 0, 15), /* sw $2,($15) */ | |||
MIPS32_LUI(1, UPPER16(MIPS32_PRACC_PARAM_OUT)), /* $1 = MIPS32_PRACC_PARAM_OUT */ | |||
MIPS32_ORI(1, 1, LOWER16(MIPS32_PRACC_PARAM_OUT)), | |||
MIPS32_MFC0(2, 23, 0), /* move COP0 Debug to $2 */ | |||
MIPS32_SW(2, 0, 1), | |||
MIPS32_LW(2, 0, 15), | |||
MIPS32_LW(1, 0, 15), | |||
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, | |||
@@ -302,8 +301,7 @@ int mips_ejtag_init(struct mips_ejtag *ejtag_info) | |||
/* get ejtag version */ | |||
ejtag_version = ((ejtag_info->impcode >> 29) & 0x07); | |||
switch (ejtag_version) | |||
{ | |||
switch (ejtag_version) { | |||
case 0: | |||
LOG_DEBUG("EJTAG: Version 1 or 2.0 Detected"); | |||
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].out_value = t; | |||
if (write_t) | |||
{ | |||
if (write_t) { | |||
fields[1].in_value = NULL; | |||
buf_set_u32(t, 0, 32, *data); | |||
} | |||
else | |||
{ | |||
} else | |||
fields[1].in_value = (void *) data; | |||
} | |||
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_callback_data_t) data); | |||
@@ -122,8 +122,7 @@ | |||
#define EJTAG_DBCn_BLM_SHIFT 4 | |||
#define EJTAG_DBCn_BE (1 << 0) | |||
struct mips_ejtag | |||
{ | |||
struct mips_ejtag { | |||
struct jtag_tap *tap; | |||
uint32_t impcode; | |||
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_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; | |||
*((uint32_t *)arg) = le_to_h_u32(in); | |||
@@ -24,6 +24,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -48,26 +49,27 @@ static int mips_m4k_examine_debug_reason(struct target *target) | |||
int retval; | |||
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 */ | |||
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; | |||
if (break_status & 0x1f) | |||
{ | |||
if (break_status & 0x1f) { | |||
/* 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; | |||
target->debug_reason = DBG_REASON_BREAKPOINT; | |||
} | |||
/* 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; | |||
if (break_status & 0x1f) | |||
{ | |||
if (break_status & 0x1f) { | |||
/* 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; | |||
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); | |||
/* 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 */ | |||
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 */ | |||
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); | |||
} | |||
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), | |||
@@ -129,8 +129,7 @@ static int mips_m4k_poll(struct target *target) | |||
/* clear this bit before handling polling | |||
* 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 | |||
* otherwise ejtag will not work */ | |||
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 */ | |||
if (ejtag_ctrl & EJTAG_CTRL_BRKST) | |||
{ | |||
if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) | |||
{ | |||
if (ejtag_ctrl & EJTAG_CTRL_BRKST) { | |||
if ((target->state == TARGET_RUNNING) || (target->state == TARGET_RESET)) { | |||
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_NORMALBOOT); | |||
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; | |||
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; | |||
if ((retval = mips_m4k_debug_entry(target)) != ERROR_OK) | |||
retval = mips_m4k_debug_entry(target); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED); | |||
} | |||
} | |||
else | |||
{ | |||
} else | |||
target->state = TARGET_RUNNING; | |||
} | |||
// LOG_DEBUG("ctrl = 0x%08X", ejtag_ctrl); | |||
/* LOG_DEBUG("ctrl = 0x%08X", ejtag_ctrl); */ | |||
return ERROR_OK; | |||
} | |||
@@ -181,29 +175,21 @@ static int mips_m4k_halt(struct target *target) | |||
struct mips32_common *mips32 = target_to_mips32(target); | |||
struct mips_ejtag *ejtag_info = &mips32->ejtag_info; | |||
LOG_DEBUG("target->state: %s", | |||
target_state_name(target)); | |||
LOG_DEBUG("target->state: %s", target_state_name(target)); | |||
if (target->state == TARGET_HALTED) | |||
{ | |||
if (target->state == TARGET_HALTED) { | |||
LOG_DEBUG("target was already halted"); | |||
return ERROR_OK; | |||
} | |||
if (target->state == TARGET_UNKNOWN) | |||
{ | |||
LOG_WARNING("target was in unknown state when halt was requested"); | |||
} | |||
if (target->state == TARGET_RESET) | |||
{ | |||
if ((jtag_get_reset_config() & RESET_SRST_PULLS_TRST) && jtag_get_srst()) | |||
{ | |||
if (target->state == TARGET_RESET) { | |||
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"); | |||
return ERROR_TARGET_FAILURE; | |||
} | |||
else | |||
{ | |||
} else { | |||
/* we came here in a reset_halt or reset_init sequence | |||
* 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)) | |||
assert_srst = 0; | |||
if (target->reset_halt) | |||
{ | |||
if (target->reset_halt) { | |||
/* use hardware to catch reset */ | |||
mips_ejtag_set_instr(ejtag_info, EJTAG_INST_EJTAGBOOT); | |||
} | |||
else | |||
{ | |||
} else | |||
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 */ | |||
if (jtag_reset_config & RESET_SRST_PULLS_TRST) | |||
{ | |||
jtag_add_reset(1, 1); | |||
} | |||
else | |||
{ | |||
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..."); | |||
/* 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_DE_ASSERT_RST); | |||
mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP); | |||
} | |||
else | |||
{ | |||
} else { | |||
/* use ejtag reset - not supported by all cores */ | |||
uint32_t ejtag_ctrl = ejtag_info->ejtag_ctrl | EJTAG_CTRL_PRRST | EJTAG_CTRL_PERRST; | |||
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); | |||
if (target->reset_halt) | |||
{ | |||
int retval; | |||
if ((retval = target_halt(target)) != ERROR_OK) | |||
if (target->reset_halt) { | |||
int retval = target_halt(target); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
@@ -298,8 +269,7 @@ static int mips_m4k_assert_reset(struct target *target) | |||
static int mips_m4k_deassert_reset(struct target *target) | |||
{ | |||
LOG_DEBUG("target->state: %s", | |||
target_state_name(target)); | |||
LOG_DEBUG("target->state: %s", target_state_name(target)); | |||
/* deassert reset lines */ | |||
jtag_add_reset(0, 0); | |||
@@ -340,41 +310,36 @@ static int mips_m4k_resume(struct target *target, int current, | |||
struct breakpoint *breakpoint = NULL; | |||
uint32_t resume_pc; | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
if (target->state != TARGET_HALTED) { | |||
LOG_WARNING("target not halted"); | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
if (!debug_execution) | |||
{ | |||
if (!debug_execution) { | |||
target_free_all_working_areas(target); | |||
mips_m4k_enable_breakpoints(target); | |||
mips_m4k_enable_watchpoints(target); | |||
} | |||
/* 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); | |||
mips32->core_cache->reg_list[MIPS32_PC].dirty = 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); | |||
} | |||
resume_pc = buf_get_u32(mips32->core_cache->reg_list[MIPS32_PC].value, 0, 32); | |||
mips32_restore_context(target); | |||
/* the front-end may request us not to handle breakpoints */ | |||
if (handle_breakpoints) | |||
{ | |||
if (handle_breakpoints) { | |||
/* 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); | |||
mips_m4k_unset_breakpoint(target, breakpoint); | |||
mips_m4k_single_step_core(target); | |||
@@ -392,14 +357,11 @@ static int mips_m4k_resume(struct target *target, int current, | |||
/* registers are now invalid */ | |||
register_cache_invalidate(mips32->core_cache); | |||
if (!debug_execution) | |||
{ | |||
if (!debug_execution) { | |||
target->state = TARGET_RUNNING; | |||
target_call_event_callbacks(target, TARGET_EVENT_RESUMED); | |||
LOG_DEBUG("target resumed at 0x%" PRIx32 "", resume_pc); | |||
} | |||
else | |||
{ | |||
} else { | |||
target->state = TARGET_DEBUG_RUNNING; | |||
target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED); | |||
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 breakpoint *breakpoint = NULL; | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
if (target->state != TARGET_HALTED) { | |||
LOG_WARNING("target not halted"); | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
/* 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); | |||
mips32->core_cache->reg_list[MIPS32_PC].dirty = 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; | |||
/* set any pending breakpoints */ | |||
while (breakpoint) | |||
{ | |||
while (breakpoint) { | |||
if (breakpoint->set == 0) | |||
mips_m4k_set_breakpoint(target, breakpoint); | |||
breakpoint = breakpoint->next; | |||
@@ -485,85 +444,72 @@ static int mips_m4k_set_breakpoint(struct target *target, | |||
struct breakpoint *breakpoint) | |||
{ | |||
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; | |||
if (breakpoint->set) | |||
{ | |||
if (breakpoint->set) { | |||
LOG_WARNING("breakpoint already set"); | |||
return ERROR_OK; | |||
} | |||
if (breakpoint->type == BKPT_HARD) | |||
{ | |||
if (breakpoint->type == BKPT_HARD) { | |||
int bp_num = 0; | |||
while (comparator_list[bp_num].used && (bp_num < mips32->num_inst_bpoints)) | |||
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)", | |||
breakpoint->unique_id ); | |||
breakpoint->unique_id); | |||
return ERROR_TARGET_RESOURCE_NOT_AVAILABLE; | |||
} | |||
breakpoint->set = bp_num + 1; | |||
comparator_list[bp_num].used = 1; | |||
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 + 0x18, 1); | |||
LOG_DEBUG("bpid: %d, bp_num %i bp_value 0x%" PRIx32 "", | |||
breakpoint->unique_id, | |||
bp_num, comparator_list[bp_num].bp_value); | |||
} | |||
else if (breakpoint->type == BKPT_SOFT) | |||
{ | |||
LOG_DEBUG("bpid: %d", breakpoint->unique_id ); | |||
if (breakpoint->length == 4) | |||
{ | |||
} else if (breakpoint->type == BKPT_SOFT) { | |||
LOG_DEBUG("bpid: %d", breakpoint->unique_id); | |||
if (breakpoint->length == 4) { | |||
uint32_t verify = 0xffffffff; | |||
if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, | |||
breakpoint->orig_instr)) != ERROR_OK) | |||
{ | |||
retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, | |||
breakpoint->orig_instr); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
if ((retval = target_write_u32(target, breakpoint->address, MIPS32_SDBBP)) != ERROR_OK) | |||
{ | |||
retval = target_write_u32(target, breakpoint->address, MIPS32_SDBBP); | |||
if (retval != ERROR_OK) | |||
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; | |||
} | |||
if (verify != MIPS32_SDBBP) | |||
{ | |||
LOG_ERROR("Unable to set 32bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address); | |||
if (verify != MIPS32_SDBBP) { | |||
LOG_ERROR("Unable to set 32bit breakpoint at address %08" PRIx32 | |||
" - check that memory is read/writable", breakpoint->address); | |||
return ERROR_OK; | |||
} | |||
} | |||
else | |||
{ | |||
} else { | |||
uint16_t verify = 0xffff; | |||
if ((retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, | |||
breakpoint->orig_instr)) != ERROR_OK) | |||
{ | |||
retval = target_read_memory(target, breakpoint->address, breakpoint->length, 1, | |||
breakpoint->orig_instr); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
if ((retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP)) != ERROR_OK) | |||
{ | |||
retval = target_write_u16(target, breakpoint->address, MIPS16_SDBBP); | |||
if (retval != ERROR_OK) | |||
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; | |||
} | |||
if (verify != MIPS16_SDBBP) | |||
{ | |||
LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx32 " - check that memory is read/writable", breakpoint->address); | |||
if (verify != MIPS16_SDBBP) { | |||
LOG_ERROR("Unable to set 16bit breakpoint at address %08" PRIx32 | |||
" - check that memory is read/writable", breakpoint->address); | |||
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; | |||
int retval; | |||
if (!breakpoint->set) | |||
{ | |||
if (!breakpoint->set) { | |||
LOG_WARNING("breakpoint not set"); | |||
return ERROR_OK; | |||
} | |||
if (breakpoint->type == BKPT_HARD) | |||
{ | |||
if (breakpoint->type == BKPT_HARD) { | |||
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)", | |||
breakpoint->unique_id); | |||
return ERROR_OK; | |||
} | |||
LOG_DEBUG("bpid: %d - releasing hw: %d", | |||
breakpoint->unique_id, | |||
bp_num ); | |||
breakpoint->unique_id, | |||
bp_num); | |||
comparator_list[bp_num].used = 0; | |||
comparator_list[bp_num].bp_value = 0; | |||
target_write_u32(target, comparator_list[bp_num].reg_address + 0x18, 0); | |||
} | |||
else | |||
{ | |||
} else { | |||
/* restore original instruction (kept in target endianness) */ | |||
LOG_DEBUG("bpid: %d", breakpoint->unique_id); | |||
if (breakpoint->length == 4) | |||
{ | |||
if (breakpoint->length == 4) { | |||
uint32_t current_instr; | |||
/* check that user program has not modified breakpoint instruction */ | |||
if ((retval = target_read_memory(target, breakpoint->address, 4, 1, | |||
(uint8_t*)¤t_instr)) != ERROR_OK) | |||
{ | |||
retval = target_read_memory(target, breakpoint->address, 4, 1, | |||
(uint8_t *)¤t_instr); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
/** | |||
* 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 *)¤t_instr); | |||
if (current_instr == MIPS32_SDBBP) | |||
{ | |||
if ((retval = target_write_memory(target, breakpoint->address, 4, 1, | |||
breakpoint->orig_instr)) != ERROR_OK) | |||
{ | |||
if (current_instr == MIPS32_SDBBP) { | |||
retval = target_write_memory(target, breakpoint->address, 4, 1, | |||
breakpoint->orig_instr); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
} | |||
} | |||
else | |||
{ | |||
} else { | |||
uint16_t current_instr; | |||
/* check that user program has not modified breakpoint instruction */ | |||
if ((retval = target_read_memory(target, breakpoint->address, 2, 1, | |||
(uint8_t*)¤t_instr)) != ERROR_OK) | |||
{ | |||
retval = target_read_memory(target, breakpoint->address, 2, 1, | |||
(uint8_t *)¤t_instr); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
current_instr = target_buffer_get_u16(target, (uint8_t *)¤t_instr); | |||
if (current_instr == MIPS16_SDBBP) | |||
{ | |||
if ((retval = target_write_memory(target, breakpoint->address, 2, 1, | |||
breakpoint->orig_instr)) != ERROR_OK) | |||
{ | |||
if (current_instr == MIPS16_SDBBP) { | |||
retval = target_write_memory(target, breakpoint->address, 2, 1, | |||
breakpoint->orig_instr); | |||
if (retval != ERROR_OK) | |||
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); | |||
if (breakpoint->type == BKPT_HARD) | |||
{ | |||
if (mips32->num_inst_bpoints_avail < 1) | |||
{ | |||
if (breakpoint->type == BKPT_HARD) { | |||
if (mips32->num_inst_bpoints_avail < 1) { | |||
LOG_INFO("no hardware breakpoint 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 */ | |||
struct mips32_common *mips32 = target_to_mips32(target); | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
if (target->state != TARGET_HALTED) { | |||
LOG_WARNING("target not halted"); | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
if (breakpoint->set) | |||
{ | |||
mips_m4k_unset_breakpoint(target, breakpoint); | |||
} | |||
if (breakpoint->type == BKPT_HARD) | |||
mips32->num_inst_bpoints_avail++; | |||
@@ -715,36 +642,31 @@ static int mips_m4k_set_watchpoint(struct target *target, | |||
* condition evaluation | |||
*/ | |||
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"); | |||
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++; | |||
if (wp_num >= mips32->num_data_bpoints) | |||
{ | |||
if (wp_num >= mips32->num_data_bpoints) { | |||
LOG_ERROR("Can not find free FP Comparator"); | |||
return ERROR_FAIL; | |||
} | |||
if (watchpoint->length != 4) | |||
{ | |||
if (watchpoint->length != 4) { | |||
LOG_ERROR("Only watchpoints of length 4 are supported"); | |||
return ERROR_TARGET_UNALIGNED_ACCESS; | |||
} | |||
if (watchpoint->address % 4) | |||
{ | |||
if (watchpoint->address % 4) { | |||
LOG_ERROR("Watchpoints address should be word aligned"); | |||
return ERROR_TARGET_UNALIGNED_ACCESS; | |||
} | |||
switch (watchpoint->rw) | |||
{ | |||
switch (watchpoint->rw) { | |||
case WPT_READ: | |||
enable &= ~EJTAG_DBCn_NOLB; | |||
break; | |||
@@ -778,15 +700,13 @@ static int mips_m4k_unset_watchpoint(struct target *target, | |||
struct mips32_common *mips32 = target_to_mips32(target); | |||
struct mips32_comparator *comparator_list = mips32->data_break_list; | |||
if (!watchpoint->set) | |||
{ | |||
if (!watchpoint->set) { | |||
LOG_WARNING("watchpoint not set"); | |||
return ERROR_OK; | |||
} | |||
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"); | |||
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); | |||
if (mips32->num_data_bpoints_avail < 1) | |||
{ | |||
if (mips32->num_data_bpoints_avail < 1) { | |||
LOG_INFO("no hardware watchpoints 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 */ | |||
struct mips32_common *mips32 = target_to_mips32(target); | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
if (target->state != TARGET_HALTED) { | |||
LOG_WARNING("target not halted"); | |||
return ERROR_TARGET_NOT_HALTED; | |||
} | |||
if (watchpoint->set) | |||
{ | |||
mips_m4k_unset_watchpoint(target, watchpoint); | |||
} | |||
mips32->num_data_bpoints_avail++; | |||
@@ -841,8 +757,7 @@ static void mips_m4k_enable_watchpoints(struct target *target) | |||
struct watchpoint *watchpoint = target->watchpoints; | |||
/* set any pending watchpoints */ | |||
while (watchpoint) | |||
{ | |||
while (watchpoint) { | |||
if (watchpoint->set == 0) | |||
mips_m4k_set_watchpoint(target, watchpoint); | |||
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 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"); | |||
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 */ | |||
void *t = NULL; | |||
if (size > 1) | |||
{ | |||
if (size > 1) { | |||
t = malloc(count * size * sizeof(uint8_t)); | |||
if (t == NULL) | |||
{ | |||
if (t == NULL) { | |||
LOG_ERROR("Out of memory"); | |||
return ERROR_FAIL; | |||
} | |||
} | |||
else | |||
{ | |||
} else | |||
t = buffer; | |||
} | |||
/* if noDMA off, use DMAACC mode for memory read */ | |||
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 */ | |||
/* endianness, but byte array should represent target endianness */ | |||
if (ERROR_OK == retval) | |||
{ | |||
switch(size) | |||
{ | |||
if (ERROR_OK == retval) { | |||
switch (size) { | |||
case 4: | |||
target_buffer_set_u32_array(target,buffer,count,t); | |||
target_buffer_set_u32_array(target, buffer, count, t); | |||
break; | |||
case 2: | |||
target_buffer_set_u16_array(target,buffer,count,t); | |||
target_buffer_set_u16_array(target, buffer, count, t); | |||
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 "", | |||
address, size, count); | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
if (target->state != TARGET_HALTED) { | |||
LOG_WARNING("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 */ | |||
void *t = NULL; | |||
if (size > 1) | |||
{ | |||
if (size > 1) { | |||
/* mips32_..._write_mem with size 4/2 requires uint32_t/uint16_t in host */ | |||
/* endianness, but byte array represents target endianness */ | |||
t = malloc(count * size * sizeof(uint8_t)); | |||
if (t == NULL) | |||
{ | |||
if (t == NULL) { | |||
LOG_ERROR("Out of memory"); | |||
return ERROR_FAIL; | |||
} | |||
switch(size) | |||
{ | |||
switch (size) { | |||
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; | |||
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; | |||
} | |||
buffer = t; | |||
@@ -1016,15 +920,13 @@ static int mips_m4k_examine(struct target *target) | |||
struct mips_ejtag *ejtag_info = &mips_m4k->mips32.ejtag_info; | |||
uint32_t idcode = 0; | |||
if (!target_was_examined(target)) | |||
{ | |||
if (!target_was_examined(target)) { | |||
retval = mips_ejtag_get_idcode(ejtag_info, &idcode); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
ejtag_info->idcode = idcode; | |||
if (((idcode >> 1) & 0x7FF) == 0x29) | |||
{ | |||
if (((idcode >> 1) & 0x7FF) == 0x29) { | |||
/* we are using a pic32mx so select ejtag port | |||
* as it is not selected by default */ | |||
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 */ | |||
if ((retval = mips_ejtag_init(ejtag_info)) != ERROR_OK) | |||
retval = mips_ejtag_init(ejtag_info); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
if ((retval = mips32_examine(target)) != ERROR_OK) | |||
retval = mips32_examine(target); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
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); | |||
if (target->state != TARGET_HALTED) | |||
{ | |||
if (target->state != TARGET_HALTED) { | |||
LOG_WARNING("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) | |||
return ERROR_TARGET_UNALIGNED_ACCESS; | |||
if (mips32->fast_data_area == NULL) | |||
{ | |||
if (mips32->fast_data_area == NULL) { | |||
/* Get memory for block write handler | |||
* we preserve this area between calls and gain a speed increase | |||
* 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, | |||
MIPS32_FASTDATA_HANDLER_SIZE, | |||
&mips32->fast_data_area); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
LOG_WARNING("No working area available, falling back to non-bulk write"); | |||
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 */ | |||
uint32_t *t = NULL; | |||
t = malloc(count * sizeof(uint32_t)); | |||
if (t == NULL) | |||
{ | |||
if (t == NULL) { | |||
LOG_ERROR("Out of memory"); | |||
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, | |||
count, t); | |||
@@ -1100,8 +1000,7 @@ static int mips_m4k_bulk_write_memory(struct target *target, uint32_t address, | |||
if (t != NULL) | |||
free(t); | |||
if (retval != ERROR_OK) | |||
{ | |||
if (retval != ERROR_OK) { | |||
/* FASTDATA access failed, try normal memory write */ | |||
LOG_DEBUG("Fastdata access Failed, falling back to non-bulk write"); | |||
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) | |||
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); | |||
return ERROR_OK; | |||
} | |||
/* two or more argument, access a single register/select (write if third argument is given) */ | |||
if (CMD_ARGC < 2) | |||
{ | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
} | |||
else | |||
{ | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
else { | |||
uint32_t cp0_reg, cp0_sel; | |||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], cp0_reg); | |||
COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], cp0_sel); | |||
if (CMD_ARGC == 2) | |||
{ | |||
if (CMD_ARGC == 2) { | |||
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, | |||
"couldn't access reg %" PRIi32, | |||
cp0_reg); | |||
return ERROR_OK; | |||
} | |||
if ((retval = jtag_execute_queue()) != ERROR_OK) | |||
{ | |||
retval = jtag_execute_queue(); | |||
if (retval != ERROR_OK) | |||
return retval; | |||
} | |||
command_print(CMD_CTX, "cp0 reg %" PRIi32 ", select %" PRIi32 ": %8.8" PRIx32, | |||
cp0_reg, cp0_sel, value); | |||
} | |||
else if (CMD_ARGC == 3) | |||
{ | |||
} else if (CMD_ARGC == 3) { | |||
uint32_t 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, | |||
"couldn't access cp0 reg %" PRIi32 ", select %" PRIi32, | |||
cp0_reg, cp0_sel); | |||
@@ -1211,8 +1102,7 @@ const struct command_registration mips_m4k_command_handlers[] = { | |||
COMMAND_REGISTRATION_DONE | |||
}; | |||
struct target_type mips_m4k_target = | |||
{ | |||
struct target_type mips_m4k_target = { | |||
.name = "mips_m4k", | |||
.poll = mips_m4k_poll, | |||
@@ -32,8 +32,7 @@ struct target; | |||
#define MIPSM4K_COMMON_MAGIC 0xB321B321 | |||
struct mips_m4k_common | |||
{ | |||
struct mips_m4k_common { | |||
uint32_t common_magic; | |||
bool is_pic32mx; | |||
struct mips32_common mips32; | |||
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -30,7 +31,6 @@ | |||
* 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) | |||
{ | |||
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_to_read = 4; | |||
while (bytes_to_read > 0) | |||
{ | |||
bytes_read = read(oocd_trace->tty_fd, ((uint8_t*)value) + 4 - bytes_to_read, bytes_to_read); | |||
while (bytes_to_read > 0) { | |||
bytes_read = read(oocd_trace->tty_fd, ((uint8_t *)value) + 4 - bytes_to_read, bytes_to_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_to_read = size * 16; | |||
while (bytes_to_read > 0) | |||
{ | |||
if ((bytes_read = read(oocd_trace->tty_fd, | |||
((uint8_t*)data) + (size * 16) - bytes_to_read, bytes_to_read)) < 0) | |||
{ | |||
while (bytes_to_read > 0) { | |||
bytes_read = read(oocd_trace->tty_fd, | |||
((uint8_t *)data) + (size * 16) - bytes_to_read, bytes_to_read); | |||
if (bytes_read < 0) | |||
LOG_DEBUG("read() returned %zi (%s)", bytes_read, strerror(errno)); | |||
} | |||
else | |||
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); | |||
if (oocd_trace->tty_fd < 0) | |||
{ | |||
if (oocd_trace->tty_fd < 0) { | |||
LOG_ERROR("can't open tty"); | |||
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 | |||
* read up any leftover characters to ensure communication is in sync */ | |||
while ((bytes_read = read(oocd_trace->tty_fd, trash, sizeof(trash))) > 0) | |||
{ | |||
LOG_DEBUG("%zi bytes read", bytes_read); | |||
}; | |||
do { | |||
bytes_read = read(oocd_trace->tty_fd, trash, sizeof(trash)); | |||
if (bytes_read) | |||
LOG_DEBUG("%zi bytes read", bytes_read); | |||
} while (bytes_read > 0); | |||
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 (etm_ctx->capture_status == TRACE_IDLE) | |||
{ | |||
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 */ | |||
if (status & 0x4) | |||
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) | |||
etm_ctx->capture_status |= TRACE_TRIGGERED; | |||
if (status & 0x1) | |||
{ | |||
if (status & 0x1) { | |||
etm_ctx->capture_status &= ~TRACE_RUNNING; | |||
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); | |||
if (etm_ctx->trace_depth > 0) | |||
{ | |||
free(etm_ctx->trace_data); | |||
} | |||
etm_ctx->trace_depth = num_frames * 16; | |||
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].packet = (trace_data[i] & 0x78) >> 3; | |||
etm_ctx->trace_data[i].flags = 0; | |||
if ((trace_data[i] & 0x80) >> 7) | |||
{ | |||
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].flags |= ETMV1_TRIGGER_CYCLE; | |||
} | |||
@@ -239,16 +226,13 @@ static int oocd_trace_start_capture(struct etm_context *etm_ctx) | |||
uint32_t trigger_count; | |||
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"); | |||
return ERROR_ETM_PORTMODE_NOT_SUPPORTED; | |||
} | |||
if ((etm_ctx->control & ETM_PORT_CLOCK_MASK) == ETM_PORT_HALF_CLOCK) | |||
{ | |||
control |= 0x2; /* half rate clock, capture at twice the clock rate */ | |||
} | |||
/* OpenOCD + trace holds up to 16 million samples, | |||
* but trigger counts is set in multiples of 16 */ | |||
@@ -283,20 +267,16 @@ COMMAND_HANDLER(handle_oocd_trace_config_command) | |||
struct arm *arm; | |||
if (CMD_ARGC != 2) | |||
{ | |||
return ERROR_COMMAND_SYNTAX_ERROR; | |||
} | |||
target = get_current_target(CMD_CTX); | |||
arm = target_to_arm(target); | |||
if (!is_arm(arm)) | |||
{ | |||
if (!is_arm(arm)) { | |||
command_print(CMD_CTX, "current target isn't an ARM"); | |||
return ERROR_FAIL; | |||
} | |||
if (arm->etm) | |||
{ | |||
if (arm->etm) { | |||
struct oocd_trace *oocd_trace = malloc(sizeof(struct 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 */ | |||
oocd_trace->tty = strndup(CMD_ARGV[1], 256); | |||
} | |||
else | |||
{ | |||
} else | |||
LOG_ERROR("target has no ETM defined, OpenOCD + trace left unconfigured"); | |||
} | |||
return ERROR_OK; | |||
} | |||
@@ -323,25 +300,22 @@ COMMAND_HANDLER(handle_oocd_trace_status_command) | |||
target = get_current_target(CMD_CTX); | |||
arm = target_to_arm(target); | |||
if (!is_arm(arm)) | |||
{ | |||
if (!is_arm(arm)) { | |||
command_print(CMD_CTX, "current target isn't an ARM"); | |||
return ERROR_FAIL; | |||
} | |||
if (!arm->etm) | |||
{ | |||
if (!arm->etm) { | |||
command_print(CMD_CTX, "current target doesn't have an ETM configured"); | |||
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'"); | |||
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); | |||
@@ -364,25 +338,22 @@ COMMAND_HANDLER(handle_oocd_trace_resync_command) | |||
target = get_current_target(CMD_CTX); | |||
arm = target_to_arm(target); | |||
if (!is_arm(arm)) | |||
{ | |||
if (!is_arm(arm)) { | |||
command_print(CMD_CTX, "current target isn't an ARM"); | |||
return ERROR_FAIL; | |||
} | |||
if (!arm->etm) | |||
{ | |||
if (!arm->etm) { | |||
command_print(CMD_CTX, "current target doesn't have an ETM configured"); | |||
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'"); | |||
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; | |||
@@ -428,8 +399,7 @@ static const struct command_registration oocd_trace_command_handlers[] = { | |||
COMMAND_REGISTRATION_DONE | |||
}; | |||
struct etm_capture_driver oocd_trace_capture_driver = | |||
{ | |||
struct etm_capture_driver oocd_trace_capture_driver = { | |||
.name = "oocd_trace", | |||
.commands = oocd_trace_command_handlers, | |||
.init = oocd_trace_init, | |||
@@ -438,5 +408,3 @@ struct etm_capture_driver oocd_trace_capture_driver = | |||
.stop_capture = oocd_trace_stop_capture, | |||
.read_trace = oocd_trace_read_trace, | |||
}; | |||
@@ -17,14 +17,14 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef OOCD_TRACE_H | |||
#define OOCD_TRACE_H | |||
#include <termios.h> | |||
/* registers */ | |||
enum | |||
{ | |||
enum { | |||
OOCD_TRACE_ID = 0x7, | |||
OOCD_TRACE_ADDRESS = 0x0, | |||
OOCD_TRACE_TRIGGER_COUNTER = 0x01, | |||
@@ -34,8 +34,7 @@ enum | |||
}; | |||
/* commands */ | |||
enum | |||
{ | |||
enum { | |||
OOCD_TRACE_NOP = 0x0, | |||
OOCD_TRACE_READ_REG = 0x10, | |||
OOCD_TRACE_WRITE_REG = 0x18, | |||
@@ -44,8 +43,7 @@ enum | |||
OOCD_TRACE_RESYNC = 0xf0, | |||
}; | |||
struct oocd_trace | |||
{ | |||
struct oocd_trace { | |||
struct etm_context *etm_ctx; | |||
char *tty; | |||
int tty_fd; | |||
@@ -20,6 +20,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -38,16 +39,14 @@ | |||
* 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) | |||
{ | |||
unsigned i; | |||
struct reg_cache *cache = first; | |||
while (cache) | |||
{ | |||
for (i = 0; i < cache->num_regs; i++) | |||
{ | |||
while (cache) { | |||
for (i = 0; i < cache->num_regs; i++) { | |||
if (strcmp(cache->reg_list[i].name, name) == 0) | |||
return &(cache->reg_list[i]); | |||
} | |||
@@ -61,7 +60,7 @@ struct reg* register_get_by_name(struct reg_cache *first, | |||
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; | |||
@@ -20,13 +20,13 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef REGISTER_H | |||
#define REGISTER_H | |||
struct target; | |||
struct reg | |||
{ | |||
struct reg { | |||
const char *name; | |||
void *value; | |||
bool dirty; | |||
@@ -36,23 +36,21 @@ struct reg | |||
const struct reg_arch_type *type; | |||
}; | |||
struct reg_cache | |||
{ | |||
struct reg_cache { | |||
const char *name; | |||
struct reg_cache *next; | |||
struct reg *reg_list; | |||
unsigned num_regs; | |||
}; | |||
struct reg_arch_type | |||
{ | |||
struct reg_arch_type { | |||
int (*get)(struct reg *reg); | |||
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); | |||
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_init_dummy(struct reg *reg); | |||
@@ -17,6 +17,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#endif | |||
@@ -29,7 +30,6 @@ | |||
#include "server/gdb_server.h" | |||
#include "smp.h" | |||
/* implementation of new packet in gdb interface for smp feature */ | |||
/* */ | |||
/* j : smp status request */ | |||
@@ -53,9 +53,8 @@ | |||
/* Another way to test this packet is the usage of maintenance packet */ | |||
/* maint packet Jc01 */ | |||
/* maint packet jc */ | |||
static const char DIGITS[16] = "0123456789abcdef"; | |||
static const char DIGITS[16] = "0123456789abcdef"; | |||
/* packet j :smp status request */ | |||
int gdb_read_smp_packet(struct connection *connection, | |||
@@ -66,15 +65,12 @@ int gdb_read_smp_packet(struct connection *connection, | |||
uint8_t *buffer; | |||
char *hex_buffer; | |||
int retval = ERROR_OK; | |||
if (target->smp) | |||
{ | |||
if (strstr(packet, "jc")) | |||
{ | |||
if (target->smp) { | |||
if (strstr(packet, "jc")) { | |||
hex_buffer = malloc(len * 2 + 1); | |||
buffer = (uint8_t *)&target->gdb_service->core[0]; | |||
uint32_t i; | |||
for (i = 0; i < 4; i++) | |||
{ | |||
for (i = 0; i < 4; i++) { | |||
uint8_t t = buffer[i]; | |||
hex_buffer[2 * i] = DIGITS[(t >> 4) & 0xf]; | |||
hex_buffer[2 * i + 1] = DIGITS[t & 0xf]; | |||
@@ -84,9 +80,8 @@ int gdb_read_smp_packet(struct connection *connection, | |||
free(hex_buffer); | |||
} | |||
} | |||
else | |||
retval = gdb_put_packet(connection,"E01",3); | |||
} else | |||
retval = gdb_put_packet(connection, "E01", 3); | |||
return retval; | |||
} | |||
@@ -100,20 +95,15 @@ int gdb_write_smp_packet(struct connection *connection, | |||
int retval = ERROR_OK; | |||
/* skip command character */ | |||
if (target->smp) | |||
{ | |||
if (strstr(packet, "Jc")) | |||
{ | |||
packet+=2; | |||
if (target->smp) { | |||
if (strstr(packet, "Jc")) { | |||
packet += 2; | |||
coreid = strtoul(packet, &separator, 16); | |||
target->gdb_service->core[1] = coreid; | |||
retval = gdb_put_packet(connection, "OK", 2); | |||
} | |||
} | |||
else | |||
{ | |||
retval = gdb_put_packet(connection,"E01",3); | |||
} | |||
} else | |||
retval = gdb_put_packet(connection, "E01", 3); | |||
return retval; | |||
} |
@@ -17,7 +17,9 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#include "server/server.h" | |||
int gdb_read_smp_packet(struct connection *connection, | |||
char *packet, int packet_size); | |||
int gdb_write_smp_packet(struct connection *connection, | |||
@@ -20,6 +20,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifdef HAVE_CONFIG_H | |||
#include "config.h" | |||
#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, | |||
enum armv7m_regtype type, | |||
uint32_t num, uint32_t *value) | |||
enum armv7m_regtype type, | |||
uint32_t num, uint32_t *value) | |||
{ | |||
int retval; | |||
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) { | |||
case 0 ... 18: | |||
/* read a normal core register */ | |||
retval = | |||
stlink_if->layout->api->read_reg(stlink_if->fd, num, value); | |||
retval = stlink_if->layout->api->read_reg(stlink_if->fd, num, value); | |||
if (retval != ERROR_OK) { | |||
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; | |||
* it was removed from r1 docs, but still works. | |||
*/ | |||
retval = | |||
stlink_if->layout->api->read_reg(stlink_if->fd, 20, value); | |||
retval = stlink_if->layout->api->read_reg(stlink_if->fd, 20, value); | |||
switch (num) { | |||
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, | |||
enum armv7m_regtype type, | |||
uint32_t num, uint32_t value) | |||
enum armv7m_regtype type, | |||
uint32_t num, uint32_t value) | |||
{ | |||
int retval; | |||
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, | |||
Jim_Interp *interp) | |||
Jim_Interp *interp) | |||
{ | |||
LOG_DEBUG("%s", __func__); | |||
@@ -467,10 +466,8 @@ static int stm32_stlink_halt(struct target *target) | |||
return ERROR_OK; | |||
} | |||
if (target->state == TARGET_UNKNOWN) { | |||
LOG_WARNING | |||
("target was in unknown state when halt was requested"); | |||
} | |||
if (target->state == TARGET_UNKNOWN) | |||
LOG_WARNING("target was in unknown state when halt was requested"); | |||
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, | |||
uint32_t address, int handle_breakpoints, | |||
int debug_execution) | |||
uint32_t address, int handle_breakpoints, | |||
int debug_execution) | |||
{ | |||
int res; | |||
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; | |||
LOG_DEBUG("%s %d %x %d %d", __func__, current, address, | |||
handle_breakpoints, debug_execution); | |||
handle_breakpoints, debug_execution); | |||
if (target->state != TARGET_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); | |||
if (breakpoint) { | |||
LOG_DEBUG("unset breakpoint at 0x%8.8" PRIx32 " (ID: %d)", | |||
breakpoint->address, | |||
breakpoint->unique_id); | |||
breakpoint->address, | |||
breakpoint->unique_id); | |||
cortex_m3_unset_breakpoint(target, breakpoint); | |||
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, | |||
uint32_t address, int handle_breakpoints) | |||
uint32_t address, int handle_breakpoints) | |||
{ | |||
int res; | |||
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, | |||
uint32_t size, uint32_t count, | |||
uint8_t *buffer) | |||
uint32_t size, uint32_t count, | |||
uint8_t *buffer) | |||
{ | |||
int res; | |||
uint32_t buffer_threshold = 128; | |||
@@ -644,13 +641,11 @@ static int stm32_stlink_read_memory(struct target *target, uint32_t address, | |||
c = count; | |||
if (size != 4) | |||
res = | |||
stlink_if->layout->api->read_mem8(stlink_if->fd, address, | |||
c, dst); | |||
res = stlink_if->layout->api->read_mem8(stlink_if->fd, | |||
address, c, dst); | |||
else | |||
res = | |||
stlink_if->layout->api->read_mem32(stlink_if->fd, address, | |||
c, (uint32_t *)dst); | |||
res = stlink_if->layout->api->read_mem32(stlink_if->fd, | |||
address, c, (uint32_t *)dst); | |||
if (res != ERROR_OK) | |||
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, | |||
uint32_t size, uint32_t count, | |||
const uint8_t *buffer) | |||
uint32_t size, uint32_t count, | |||
const uint8_t *buffer) | |||
{ | |||
int res; | |||
uint32_t buffer_threshold = 128; | |||
@@ -695,13 +690,11 @@ static int stm32_stlink_write_memory(struct target *target, uint32_t address, | |||
c = count; | |||
if (size != 4) | |||
res = | |||
stlink_if->layout->api->write_mem8(stlink_if->fd, address, | |||
c, dst); | |||
res = stlink_if->layout->api->write_mem8(stlink_if->fd, | |||
address, c, dst); | |||
else | |||
res = | |||
stlink_if->layout->api->write_mem32(stlink_if->fd, address, | |||
c, (uint32_t *)dst); | |||
res = stlink_if->layout->api->write_mem32(stlink_if->fd, | |||
address, c, (uint32_t *)dst); | |||
if (res != ERROR_OK) | |||
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, | |||
uint32_t address, uint32_t count, | |||
const uint8_t *buffer) | |||
uint32_t address, uint32_t count, | |||
const uint8_t *buffer) | |||
{ | |||
return stm32_stlink_write_memory(target, address, 4, count, buffer); | |||
} | |||
@@ -29,6 +29,7 @@ | |||
* Free Software Foundation, Inc., * | |||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * | |||
***************************************************************************/ | |||
#ifndef TARGET_H | |||
#define TARGET_H | |||
@@ -57,8 +58,7 @@ struct target_list; | |||
*/ | |||
enum target_state | |||
{ | |||
enum target_state { | |||
TARGET_UNKNOWN = 0, | |||
TARGET_RUNNING = 1, | |||
TARGET_HALTED = 2, | |||
@@ -71,16 +71,14 @@ enum nvp_assert { | |||
NVP_ASSERT, | |||
}; | |||
enum target_reset_mode | |||
{ | |||
enum target_reset_mode { | |||
RESET_UNKNOWN = 0, | |||
RESET_RUN = 1, /* reset and let target run */ | |||
RESET_HALT = 2, /* reset and halt target out of reset */ | |||
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_BREAKPOINT = 1, | |||
DBG_REASON_WATCHPOINT = 2, | |||
@@ -90,14 +88,12 @@ enum target_debug_reason | |||
DBG_REASON_UNDEFINED = 6 | |||
}; | |||
enum target_endianness | |||
{ | |||
enum target_endianness { | |||
TARGET_ENDIAN_UNKNOWN = 0, | |||
TARGET_BIG_ENDIAN = 1, TARGET_LITTLE_ENDIAN = 2 | |||
}; | |||
struct working_area | |||
{ | |||
struct working_area { | |||
uint32_t address; | |||
uint32_t size; | |||
bool free; | |||
@@ -105,26 +101,23 @@ struct working_area | |||
struct working_area **user; | |||
struct working_area *next; | |||
}; | |||
struct gdb_service | |||
{ | |||
struct gdb_service { | |||
struct target *target; | |||
/* field for smp display */ | |||
/* element 0 coreid currently displayed ( 1 till n) */ | |||
/* element 1 coreid to be displayed at next resume 1 till n 0 means resume | |||
* all cores | |||
core displayed */ | |||
/* element 1 coreid to be displayed at next resume 1 till n 0 means resume | |||
* all cores core displayed */ | |||
int32_t core[2]; | |||
}; | |||
// target_type.h contains the full definitionof struct targe_type | |||
struct target | |||
{ | |||
struct target_type *type; /* target type definition (name, access functions) */ | |||
/* target_type.h contains the full definitionof struct targe_type */ | |||
struct target { | |||
struct target_type *type; /* target type definition (name, access functions) */ | |||
const char *cmd_name; /* tcl Name of target */ | |||
int target_number; /* DO NOT USE! field to be removed in 2010 */ | |||
struct jtag_tap *tap; /* where on the jtag chain is this */ | |||
int32_t coreid; /* which device on the TAP? */ | |||
struct jtag_tap *tap; /* where on the jtag chain is this */ | |||
int32_t coreid; /* which device on the TAP? */ | |||
const char *variant; /* what variant of this chip is it? */ | |||
/** | |||
@@ -146,25 +139,25 @@ struct target | |||
struct target_event_action *event_action; | |||
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. */ | |||
bool working_area_virt_spec; /* virtual address specified? */ | |||
uint32_t working_area_virt; /* virtual address */ | |||
bool working_area_phys_spec; /* virtual address specified? */ | |||
uint32_t working_area_phys; /* physical address */ | |||
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 */ | |||
enum target_debug_reason debug_reason;/* reason why the target entered debug state */ | |||
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, ...) */ | |||
struct reg_cache *reg_cache; /* the first register cache of the target (core regs) */ | |||
struct breakpoint *breakpoints; /* list of breakpoints */ | |||
struct watchpoint *watchpoints; /* list of watchpoints */ | |||
struct breakpoint *breakpoints; /* list of breakpoints */ | |||
struct watchpoint *watchpoints; /* list of watchpoints */ | |||
struct trace *trace_info; /* generic trace information */ | |||
struct debug_msg_receiver *dbgmsg;/* list of debug message receivers */ | |||
uint32_t dbg_msg_enabled; /* debug message status */ | |||
struct debug_msg_receiver *dbgmsg; /* list of debug message receivers */ | |||
uint32_t dbg_msg_enabled; /* debug message status */ | |||
void *arch_info; /* architecture specific information */ | |||
struct target *next; /* next target in list */ | |||
@@ -175,13 +168,13 @@ struct target | |||
bool dbgbase_set; /* By default the debug base is not set */ | |||
uint32_t dbgbase; /* Really a Cortex-A specific option, but there is no | |||
system in place to support target specific options | |||
currently. */ | |||
system in place to support target specific options | |||
currently. */ | |||
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" | |||
* and must be detected when symbols are offered */ | |||
bool rtos_auto_detect; /* A flag that indicates that the RTOS has been specified as "auto" | |||
* 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; | |||
/* the gdb service is there in case of smp , we have only one gdb server | |||
* for all smp target | |||
@@ -190,7 +183,6 @@ struct target | |||
struct gdb_service *gdb_service; | |||
}; | |||
struct target_list { | |||
struct target *target; | |||
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); | |||
enum target_event | |||
{ | |||
enum target_event { | |||
/* LD historical names | |||
* - Prior to the great TCL change | |||
* - June/July/Aug 2008 | |||
@@ -269,15 +260,13 @@ struct target_event_action { | |||
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); | |||
void *priv; | |||
struct target_event_callback *next; | |||
}; | |||
struct target_timer_callback | |||
{ | |||
struct target_timer_callback { | |||
int (*callback)(void *priv); | |||
int time_ms; | |||
int periodic; | |||
@@ -291,11 +280,11 @@ int target_examine(void); | |||
int target_register_event_callback( | |||
int (*callback)(struct target *target, | |||
enum target_event event, void *priv), | |||
enum target_event event, void *priv), | |||
void *priv); | |||
int target_unregister_event_callback( | |||
int (*callback)(struct target *target, | |||
enum target_event event, void *priv), | |||
enum target_event event, void *priv), | |||
void *priv); | |||
/* 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); | |||
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); | |||
/** | |||
@@ -348,14 +337,14 @@ const char *target_type_name(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) | |||
{ | |||
return target->examined; | |||
} | |||
/// Sets the @c examined flag for the given target. | |||
/// Use in target->type->examine() after one-time setup is done. | |||
/** Sets the @c examined flag for the given target. */ | |||
/** Use in target->type->examine() after one-time setup is done. */ | |||
static inline void target_set_examined(struct target *target) | |||
{ | |||
target->examined = true; | |||
@@ -520,13 +509,13 @@ int target_write_buffer(struct target *target, | |||
int target_read_buffer(struct target *target, | |||
uint32_t address, uint32_t size, uint8_t *buffer); | |||
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, | |||
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); | |||
/** 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!!!!! | |||
* | |||