Browse Source

build: cleanup src/target directory

Change-Id: Ia055b6d2b5f6449a38afd0539a8c66e7d7e0c059
Signed-off-by: Spencer Oliver <spen@spen-soft.co.uk>
Reviewed-on: http://openocd.zylin.com/430
Tested-by: jenkins
tags/v0.6.0-rc1
Spencer Oliver 12 years ago
parent
commit
374127301e
100 changed files with 8704 additions and 10798 deletions
  1. +18
    -24
      src/target/adi_v5_jtag.c
  2. +10
    -14
      src/target/adi_v5_swd.c
  3. +1
    -1
      src/target/algorithm.c
  4. +4
    -6
      src/target/algorithm.h
  5. +1
    -0
      src/target/arm.h
  6. +259
    -308
      src/target/arm11.c
  7. +24
    -29
      src/target/arm11.h
  8. +280
    -292
      src/target/arm11_dbgtap.c
  9. +26
    -5
      src/target/arm11_dbgtap.h
  10. +34
    -63
      src/target/arm720t.c
  11. +4
    -6
      src/target/arm720t.h
  12. +569
    -735
      src/target/arm7_9_common.c
  13. +44
    -24
      src/target/arm7_9_common.h
  14. +35
    -58
      src/target/arm7tdmi.c
  15. +1
    -0
      src/target/arm7tdmi.h
  16. +222
    -303
      src/target/arm920t.c
  17. +6
    -10
      src/target/arm920t.h
  18. +44
    -78
      src/target/arm926ejs.c
  19. +8
    -9
      src/target/arm926ejs.h
  20. +87
    -136
      src/target/arm946e.c
  21. +6
    -7
      src/target/arm946e.h
  22. +20
    -30
      src/target/arm966e.c
  23. +2
    -2
      src/target/arm966e.h
  24. +46
    -97
      src/target/arm9tdmi.c
  25. +2
    -1
      src/target/arm9tdmi.h
  26. +119
    -217
      src/target/arm_adi_v5.c
  27. +8
    -11
      src/target/arm_adi_v5.h
  28. +1669
    -1657
      src/target/arm_disassembler.c
  29. +9
    -16
      src/target/arm_disassembler.h
  30. +155
    -156
      src/target/arm_dpm.c
  31. +1
    -1
      src/target/arm_dpm.h
  32. +8
    -12
      src/target/arm_jtag.c
  33. +10
    -17
      src/target/arm_jtag.h
  34. +3
    -3
      src/target/arm_opcodes.h
  35. +7
    -15
      src/target/arm_semihosting.c
  36. +101
    -237
      src/target/arm_simulator.c
  37. +2
    -2
      src/target/arm_simulator.h
  38. +233
    -249
      src/target/armv4_5.c
  39. +2
    -1
      src/target/armv4_5.h
  40. +8
    -18
      src/target/armv4_5_cache.c
  41. +4
    -6
      src/target/armv4_5_cache.h
  42. +31
    -36
      src/target/armv4_5_mmu.c
  43. +3
    -4
      src/target/armv4_5_mmu.h
  44. +232
    -239
      src/target/armv7a.c
  45. +15
    -24
      src/target/armv7a.h
  46. +110
    -115
      src/target/armv7m.c
  47. +10
    -16
      src/target/armv7m.h
  48. +103
    -136
      src/target/avr32_ap7k.c
  49. +3
    -5
      src/target/avr32_ap7k.h
  50. +16
    -29
      src/target/avr32_jtag.c
  51. +2
    -4
      src/target/avr32_jtag.h
  52. +51
    -65
      src/target/avr32_mem.c
  53. +7
    -7
      src/target/avr32_mem.h
  54. +9
    -8
      src/target/avr32_regs.c
  55. +1
    -1
      src/target/avr32_regs.h
  56. +21
    -27
      src/target/avrt.c
  57. +3
    -4
      src/target/avrt.h
  58. +137
    -165
      src/target/breakpoints.c
  59. +7
    -10
      src/target/breakpoints.h
  60. +449
    -592
      src/target/cortex_a.c
  61. +5
    -7
      src/target/cortex_a.h
  62. +341
    -460
      src/target/cortex_m.c
  63. +6
    -11
      src/target/cortex_m.h
  64. +690
    -654
      src/target/dsp563xx.c
  65. +6
    -8
      src/target/dsp563xx.h
  66. +61
    -50
      src/target/dsp563xx_once.c
  67. +2
    -2
      src/target/dsp563xx_once.h
  68. +9
    -8
      src/target/dsp5680xx.c
  69. +67
    -53
      src/target/dsp5680xx.h
  70. +29
    -31
      src/target/embeddedice.c
  71. +15
    -23
      src/target/embeddedice.h
  72. +56
    -93
      src/target/etb.c
  73. +5
    -7
      src/target/etb.h
  74. +307
    -428
      src/target/etm.c
  75. +13
    -21
      src/target/etm.h
  76. +5
    -11
      src/target/etm_dummy.c
  77. +1
    -0
      src/target/etm_dummy.h
  78. +9
    -15
      src/target/fa526.c
  79. +20
    -34
      src/target/feroceon.c
  80. +245
    -364
      src/target/image.c
  81. +11
    -18
      src/target/image.h
  82. +86
    -148
      src/target/mips32.c
  83. +14
    -18
      src/target/mips32.h
  84. +35
    -41
      src/target/mips32_dmaacc.c
  85. +1
    -0
      src/target/mips32_dmaacc.h
  86. +495
    -540
      src/target/mips32_pracc.c
  87. +3
    -2
      src/target/mips32_pracc.h
  88. +45
    -51
      src/target/mips_ejtag.c
  89. +2
    -3
      src/target/mips_ejtag.h
  90. +159
    -269
      src/target/mips_m4k.c
  91. +1
    -2
      src/target/mips_m4k.h
  92. +30
    -62
      src/target/oocd_trace.c
  93. +4
    -6
      src/target/oocd_trace.h
  94. +5
    -6
      src/target/register.c
  95. +6
    -8
      src/target/register.h
  96. +12
    -22
      src/target/smp.c
  97. +2
    -0
      src/target/smp.h
  98. +30
    -37
      src/target/stm32_stlink.c
  99. +530
    -892
      src/target/target.c
  100. +39
    -50
      src/target/target.h

+ 18
- 24
src/target/adi_v5_jtag.c View File

@@ -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;
}


+ 10
- 14
src/target/adi_v5_swd.c View File

@@ -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?


+ 1
- 1
src/target/algorithm.c View File

@@ -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;


+ 4
- 6
src/target/algorithm.h View File

@@ -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;


+ 1
- 0
src/target/arm.h View File

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

#ifndef ARM_H
#define ARM_H



+ 259
- 308
src/target/arm11.c
File diff suppressed because it is too large
View File


+ 24
- 29
src/target/arm11.h View File

@@ -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 */

+ 280
- 292
src/target/arm11_dbgtap.c
File diff suppressed because it is too large
View File


+ 26
- 5
src/target/arm11_dbgtap.h View File

@@ -1,3 +1,25 @@
/***************************************************************************
* Copyright (C) 2008 digenius technology GmbH. *
* Michael Bruck *
* *
* Copyright (C) 2008,2009 Oyvind Harboe oyvind.harboe@zylin.com *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/

#ifndef ARM11_DBGTAP_H
#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 */

+ 34
- 63
src/target/arm720t.c View File

@@ -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,


+ 4
- 6
src/target/arm720t.h View File

@@ -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 */

+ 569
- 735
src/target/arm7_9_common.c
File diff suppressed because it is too large
View File


+ 44
- 24
src/target/arm7_9_common.h View File

@@ -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);


+ 35
- 58
src/target/arm7tdmi.c View File

@@ -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,


+ 1
- 0
src/target/arm7tdmi.h View File

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

#ifndef ARM7TDMI_H
#define ARM7TDMI_H



+ 222
- 303
src/target/arm920t.c
File diff suppressed because it is too large
View File


+ 6
- 10
src/target/arm920t.h View File

@@ -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;


+ 44
- 78
src/target/arm926ejs.c View File

@@ -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,


+ 8
- 9
src/target/arm926ejs.h View File

@@ -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);


+ 87
- 136
src/target/arm946e.c View File

@@ -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,


+ 6
- 7
src/target/arm946e.h View File

@@ -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
- 30
src/target/arm966e.c View File

@@ -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,


+ 2
- 2
src/target/arm966e.h View File

@@ -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;


+ 46
- 97
src/target/arm9tdmi.c View File

@@ -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,


+ 2
- 1
src/target/arm9tdmi.h View File

@@ -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]);



+ 119
- 217
src/target/arm_adi_v5.c View File

@@ -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
};



+ 8
- 11
src/target/arm_adi_v5.h View File

@@ -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);



+ 1669
- 1657
src/target/arm_disassembler.c
File diff suppressed because it is too large
View File


+ 9
- 16
src/target/arm_disassembler.h View File

@@ -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;


+ 155
- 156
src/target/arm_dpm.c View File

@@ -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...


+ 1
- 1
src/target/arm_dpm.h View File

@@ -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);


+ 8
- 12
src/target/arm_jtag.c View File

@@ -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;
}


+ 10
- 17
src/target/arm_jtag.h View File

@@ -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 */


+ 3
- 3
src/target/arm_opcodes.h View File

@@ -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


+ 7
- 15
src/target/arm_semihosting.c View File

@@ -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;
}


+ 101
- 237
src/target/arm_simulator.c View File

@@ -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);
}


+ 2
- 2
src/target/arm_simulator.h View File

@@ -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);


+ 233
- 249
src/target/armv4_5.c View File

@@ -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;


+ 2
- 1
src/target/armv4_5.h View File

@@ -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, };


+ 8
- 18
src/target/armv4_5_cache.c View File

@@ -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;
}


+ 4
- 6
src/target/armv4_5_cache.h View File

@@ -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,


+ 31
- 36
src/target/armv4_5_mmu.c View File

@@ -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;


+ 3
- 4
src/target/armv4_5_mmu.h View File

@@ -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,


+ 232
- 239
src/target/armv7a.c View File

@@ -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
};


+ 15
- 24
src/target/armv7a.h View File

@@ -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,


+ 110
- 115
src/target/armv7m.c View File

@@ -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, &reg_value);
retval = armv7m->load_core_reg_u32(target,
armv7m_core_reg->type,
armv7m_core_reg->num,
&reg_value);
buf_set_u32(armv7m->core_cache->reg_list[num].value, 0, 32, reg_value);
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(&reg_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;
}


+ 10
- 16
src/target/armv7m.h View File

@@ -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);



+ 103
- 136
src/target/avr32_ap7k.c View File

@@ -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,


+ 3
- 5
src/target/avr32_ap7k.h View File

@@ -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
- 29
src/target/avr32_jtag.c View File

@@ -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)
{


+ 2
- 4
src/target/avr32_jtag.h View File

@@ -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 */


+ 51
- 65
src/target/avr32_mem.c View File

@@ -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);


+ 7
- 7
src/target/avr32_mem.h View File

@@ -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 */


+ 9
- 8
src/target/avr32_regs.c View File

@@ -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;


+ 1
- 1
src/target/avr32_regs.h View File

@@ -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 */


+ 21
- 27
src/target/avrt.c View File

@@ -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;
}


+ 3
- 4
src/target/avrt.h View File

@@ -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;
};



+ 137
- 165
src/target/breakpoints.c View File

@@ -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);
}

+ 7
- 10
src/target/breakpoints.h View File

@@ -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,


+ 449
- 592
src/target/cortex_a.c
File diff suppressed because it is too large
View File


+ 5
- 7
src/target/cortex_a.h View File

@@ -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 */

+ 341
- 460
src/target/cortex_m.c
File diff suppressed because it is too large
View File


+ 6
- 11
src/target/cortex_m.h View File

@@ -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;



+ 690
- 654
src/target/dsp563xx.c
File diff suppressed because it is too large
View File


+ 6
- 8
src/target/dsp563xx.h View File

@@ -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;


+ 61
- 50
src/target/dsp563xx_once.c View File

@@ -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, &regs[i].reg)) != ERROR_OK)
for (i = 0; i < len; i++) {
err = dsp563xx_once_reg_read_ex(tap, flush, regs[i].addr, regs[i].len, &regs[i].reg);
if (err != 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;
}

+ 2
- 2
src/target/dsp563xx_once.h View File

@@ -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;


+ 9
- 8
src/target/dsp5680xx.c View File

@@ -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;


+ 67
- 53
src/target/dsp5680xx.h View File

@@ -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 */

+ 29
- 31
src/target/embeddedice.c View File

@@ -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(&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;


+ 15
- 23
src/target/embeddedice.h View File

@@ -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 */

+ 56
- 93
src/target/etb.c View File

@@ -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,


+ 5
- 7
src/target/etb.h View File

@@ -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 */

+ 307
- 428
src/target/etm.c
File diff suppressed because it is too large
View File


+ 13
- 21
src/target/etm.h View File

@@ -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);


+ 5
- 11
src/target/etm_dummy.c View File

@@ -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,


+ 1
- 0
src/target/etm_dummy.h View File

@@ -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



+ 9
- 15
src/target/fa526.c View File

@@ -41,7 +41,7 @@ static void fa526_change_to_arm(struct target *target, uint32_t *r0, uint32_t *p
}

static void fa526_read_core_regs(struct target *target,
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,


+ 20
- 34
src/target/feroceon.c View File

@@ -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,
};


+ 245
- 364
src/target/image.c
File diff suppressed because it is too large
View File


+ 11
- 18
src/target/image.h View File

@@ -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)


+ 86
- 148
src/target/mips32.c View File

@@ -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(&reg_params[0]);
destroy_reg_param(&reg_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(&reg_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(&reg_params[0]);
destroy_reg_param(&reg_params[1]);
destroy_reg_param(&reg_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
};


+ 14
- 18
src/target/mips32.h View File

@@ -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*/

+ 35
- 41
src/target/mips32_dmaacc.c View File

@@ -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;
}



+ 1
- 0
src/target/mips32_dmaacc.h View File

@@ -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



+ 495
- 540
src/target/mips32_pracc.c
File diff suppressed because it is too large
View File


+ 3
- 2
src/target/mips32_pracc.h View File

@@ -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

+ 45
- 51
src/target/mips_ejtag.c View File

@@ -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);



+ 2
- 3
src/target/mips_ejtag.h View File

@@ -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);


+ 159
- 269
src/target/mips_m4k.c View File

@@ -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*)&current_instr)) != ERROR_OK)
{
retval = target_read_memory(target, breakpoint->address, 4, 1,
(uint8_t *)&current_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 *)&current_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*)&current_instr)) != ERROR_OK)
{
retval = target_read_memory(target, breakpoint->address, 2, 1,
(uint8_t *)&current_instr);
if (retval != ERROR_OK)
return retval;
}
current_instr = target_buffer_get_u16(target, (uint8_t *)&current_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,


+ 1
- 2
src/target/mips_m4k.h View File

@@ -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;


+ 30
- 62
src/target/oocd_trace.c View File

@@ -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,
};



+ 4
- 6
src/target/oocd_trace.h View File

@@ -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;


+ 5
- 6
src/target/register.c View File

@@ -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;



+ 6
- 8
src/target/register.h View File

@@ -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);


+ 12
- 22
src/target/smp.c View File

@@ -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;
}

+ 2
- 0
src/target/smp.h View File

@@ -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,


+ 30
- 37
src/target/stm32_stlink.c View File

@@ -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);
}


+ 530
- 892
src/target/target.c
File diff suppressed because it is too large
View File


+ 39
- 50
src/target/target.h View File

@@ -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!!!!!
*


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

Loading…
Cancel
Save