target: add basic dsp563xx support
parent
4639366947
commit
646ce814b4
|
@ -3157,6 +3157,8 @@ This is fixed in Fury Rev B, DustDevil Rev B, Tempest; these revisions will
|
|||
be detected and the normal reset behaviour used.
|
||||
@end itemize
|
||||
@item @code{dragonite} -- resembles arm966e
|
||||
@item @code{dsp563xx} -- implements Freescale's 24-bit DSP.
|
||||
(Support for this is still incomplete.)
|
||||
@item @code{fa526} -- resembles arm920 (w/o Thumb)
|
||||
@item @code{feroceon} -- resembles arm926
|
||||
@item @code{mips_m4k} -- a MIPS core. This supports one variant:
|
||||
|
|
|
@ -33,7 +33,9 @@ libtarget_la_SOURCES = \
|
|||
$(ARMV7_SRC) \
|
||||
$(ARM_MISC_SRC) \
|
||||
$(MIPS32_SRC) \
|
||||
avrt.c
|
||||
avrt.c \
|
||||
dsp563xx.c \
|
||||
dsp563xx_once.c
|
||||
|
||||
TARGET_CORE_SRC = \
|
||||
algorithm.c \
|
||||
|
@ -120,6 +122,8 @@ noinst_HEADERS = \
|
|||
armv7a.h \
|
||||
armv7m.h \
|
||||
avrt.h \
|
||||
dsp563xx.h \
|
||||
dsp563xx_once.h \
|
||||
breakpoints.h \
|
||||
cortex_m3.h \
|
||||
cortex_a8.h \
|
||||
|
|
|
@ -0,0 +1,990 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2009 by Mathias Kuester *
|
||||
* mkdorg@users.sourceforge.net *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <helper/jim.h>
|
||||
|
||||
#include "target.h"
|
||||
#include "target_type.h"
|
||||
#include "register.h"
|
||||
#include "dsp563xx.h"
|
||||
#include "dsp563xx_once.h"
|
||||
|
||||
#define DSP563XX_JTAG_INS_LEN 4
|
||||
|
||||
#define JTAG_STATUS_NORMAL 0x01
|
||||
#define JTAG_STATUS_STOPWAIT 0x05
|
||||
#define JTAG_STATUS_BUSY 0x09
|
||||
#define JTAG_STATUS_DEBUG 0x0d
|
||||
|
||||
#define JTAG_INSTR_EXTEST 0x00
|
||||
#define JTAG_INSTR_SAMPLE_PRELOAD 0x01
|
||||
#define JTAG_INSTR_IDCODE 0x02
|
||||
#define JTAG_INSTR_CLAMP 0x03
|
||||
#define JTAG_INSTR_HIZ 0x04
|
||||
#define JTAG_INSTR_ENABLE_ONCE 0x06
|
||||
#define JTAG_INSTR_DEBUG_REQUEST 0x07
|
||||
#define JTAG_INSTR_BYPASS 0x0F
|
||||
|
||||
/* forward declarations */
|
||||
int dsp563xx_target_create(struct target *target, Jim_Interp * interp);
|
||||
int dsp563xx_init_target(struct command_context *cmd_ctx, struct target *target);
|
||||
|
||||
int dsp563xx_arch_state(struct target *target);
|
||||
int dsp563xx_poll(struct target *target);
|
||||
int dsp563xx_halt(struct target *target);
|
||||
int dsp563xx_resume(struct target *target, int current, uint32_t address,
|
||||
int handle_breakpoints, int debug_execution);
|
||||
int dsp563xx_step(struct target *target, int current, uint32_t address,
|
||||
int handle_breakpoints);
|
||||
|
||||
int dsp563xx_assert_reset(struct target *target);
|
||||
int dsp563xx_deassert_reset(struct target *target);
|
||||
int dsp563xx_soft_reset_halt(struct target *target);
|
||||
|
||||
/* IR and DR functions */
|
||||
int dsp563xx_jtag_sendinstr(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out);
|
||||
int dsp563xx_jtag_senddat(struct jtag_tap *tap, uint32_t * dr_in, uint32_t dr_out,
|
||||
int len);
|
||||
|
||||
int dsp563xx_read_memory_p(struct target *target, uint32_t address, uint32_t size,
|
||||
uint32_t count, uint8_t * buffer);
|
||||
int dsp563xx_write_memory_p(struct target *target, uint32_t address, uint32_t size,
|
||||
uint32_t count, uint8_t * buffer);
|
||||
|
||||
#define ASM_REG_R_R0 0x607000
|
||||
#define ASM_REG_R_R1 0x617000
|
||||
#define ASM_REG_R_R2 0x627000
|
||||
#define ASM_REG_R_R3 0x637000
|
||||
#define ASM_REG_R_R4 0x647000
|
||||
#define ASM_REG_R_R5 0x657000
|
||||
#define ASM_REG_R_R6 0x667000
|
||||
#define ASM_REG_R_R7 0x677000
|
||||
|
||||
#define ASM_REG_W_R0 0x60F400
|
||||
#define ASM_REG_W_R1 0x61F400
|
||||
#define ASM_REG_W_R2 0x62F400
|
||||
#define ASM_REG_W_R3 0x63F400
|
||||
#define ASM_REG_W_R4 0x64F400
|
||||
#define ASM_REG_W_R5 0x65F400
|
||||
#define ASM_REG_W_R6 0x66F400
|
||||
#define ASM_REG_W_R7 0x67F400
|
||||
|
||||
#define ASM_REG_R_N0 0x707000
|
||||
#define ASM_REG_R_N1 0x717000
|
||||
#define ASM_REG_R_N2 0x727000
|
||||
#define ASM_REG_R_N3 0x737000
|
||||
#define ASM_REG_R_N4 0x747000
|
||||
#define ASM_REG_R_N5 0x757000
|
||||
#define ASM_REG_R_N6 0x767000
|
||||
#define ASM_REG_R_N7 0x777000
|
||||
|
||||
#define ASM_REG_W_N0 0x70F400
|
||||
#define ASM_REG_W_N1 0x71F400
|
||||
#define ASM_REG_W_N2 0x72F400
|
||||
#define ASM_REG_W_N3 0x73F400
|
||||
#define ASM_REG_W_N4 0x74F400
|
||||
#define ASM_REG_W_N5 0x75F400
|
||||
#define ASM_REG_W_N6 0x76F400
|
||||
#define ASM_REG_W_N7 0x77F400
|
||||
|
||||
#define ASM_REG_R_M0 0x057020 /* control register m[0..7] */
|
||||
#define ASM_REG_R_M1 0x057021
|
||||
#define ASM_REG_R_M2 0x057022
|
||||
#define ASM_REG_R_M3 0x057023
|
||||
#define ASM_REG_R_M4 0x057024
|
||||
#define ASM_REG_R_M5 0x057025
|
||||
#define ASM_REG_R_M6 0x057026
|
||||
#define ASM_REG_R_M7 0x057027
|
||||
|
||||
#define ASM_REG_W_M0 0x05F420
|
||||
#define ASM_REG_W_M1 0x05F421
|
||||
#define ASM_REG_W_M2 0x05F422
|
||||
#define ASM_REG_W_M3 0x05F423
|
||||
#define ASM_REG_W_M4 0x05F424
|
||||
#define ASM_REG_W_M5 0x05F425
|
||||
#define ASM_REG_W_M6 0x05F426
|
||||
#define ASM_REG_W_M7 0x05F427
|
||||
|
||||
#define ASM_REG_R_X0 0x447000
|
||||
#define ASM_REG_R_X1 0x457000
|
||||
|
||||
#define ASM_REG_W_X0 0x44F400
|
||||
#define ASM_REG_W_X1 0x45F400
|
||||
|
||||
#define ASM_REG_R_Y0 0x467000
|
||||
#define ASM_REG_R_Y1 0x477000
|
||||
|
||||
#define ASM_REG_W_Y0 0x46F400
|
||||
#define ASM_REG_W_Y1 0x47F400
|
||||
|
||||
#define ASM_REG_R_A0 0x507000
|
||||
#define ASM_REG_R_A1 0x547000
|
||||
#define ASM_REG_R_A2 0x527000
|
||||
|
||||
#define ASM_REG_W_A0 0x50F400
|
||||
#define ASM_REG_W_A1 0x54F400
|
||||
#define ASM_REG_W_A2 0x52F400
|
||||
|
||||
#define ASM_REG_R_B0 0x517000
|
||||
#define ASM_REG_R_B1 0x557000
|
||||
#define ASM_REG_R_B2 0x537000
|
||||
|
||||
#define ASM_REG_W_B0 0x51F400
|
||||
#define ASM_REG_W_B1 0x55F400
|
||||
#define ASM_REG_W_B2 0x53F400
|
||||
|
||||
#define ASM_REG_R_VBA 0x057030 /* control register */
|
||||
#define ASM_REG_W_VBA 0x05F430
|
||||
|
||||
#define ASM_REG_R_OMR 0x05703A /* control register */
|
||||
#define ASM_REG_W_OMR 0x05F43A
|
||||
|
||||
#define ASM_REG_R_EP 0x05702A
|
||||
#define ASM_REG_W_EP 0x05F42A
|
||||
|
||||
#define ASM_REG_R_SC 0x057031 /* stack counter */
|
||||
#define ASM_REG_W_SC 0x05F431
|
||||
|
||||
#define ASM_REG_R_SZ 0x057038 /* stack size */
|
||||
#define ASM_REG_W_SZ 0x05F438
|
||||
|
||||
#define ASM_REG_R_SR 0x057039 /* control register, status register */
|
||||
#define ASM_REG_W_SR 0x05F439
|
||||
|
||||
#define ASM_REG_R_SP 0x05703B /* control register, stack pointer */
|
||||
#define ASM_REG_W_SP 0x05F43B
|
||||
|
||||
#define ASM_REG_R_SSH 0x05703C /* control register, system stack high */
|
||||
#define ASM_REG_W_SSH 0x05743C
|
||||
|
||||
#define ASM_REG_R_SSL 0x05703D /* control register, system stack low */
|
||||
#define ASM_REG_W_SSL 0x05F43D
|
||||
|
||||
#define ASM_REG_R_LA 0x05703E /* control register, loop address */
|
||||
#define ASM_REG_W_LA 0x05F43E
|
||||
|
||||
#define ASM_REG_R_LC 0x05703F /* control register, loop count */
|
||||
#define ASM_REG_W_LC 0x05F43F
|
||||
|
||||
#define ASM_REG_R_PC 0x000000
|
||||
#define ASM_REG_W_PC 0x000000
|
||||
|
||||
static const struct
|
||||
{
|
||||
unsigned id;
|
||||
char *name;
|
||||
unsigned bits;
|
||||
uint32_t r_cmd;
|
||||
uint32_t w_cmd;
|
||||
} dsp563xx_regs[] =
|
||||
{
|
||||
/* *INDENT-OFF* */
|
||||
{0, "r0", 24, ASM_REG_R_R0, ASM_REG_W_R0},
|
||||
{1, "r1", 24, ASM_REG_R_R1, ASM_REG_W_R1},
|
||||
{2, "r2", 24, ASM_REG_R_R2, ASM_REG_W_R2},
|
||||
{3, "r3", 24, ASM_REG_R_R3, ASM_REG_W_R3},
|
||||
{4, "r4", 24, ASM_REG_R_R4, ASM_REG_W_R4},
|
||||
{5, "r5", 24, ASM_REG_R_R5, ASM_REG_W_R5},
|
||||
{6, "r6", 24, ASM_REG_R_R6, ASM_REG_W_R6},
|
||||
{7, "r7", 24, ASM_REG_R_R7, ASM_REG_W_R7},
|
||||
{8, "n0", 24, ASM_REG_R_N0, ASM_REG_W_N0},
|
||||
{9, "n1", 24, ASM_REG_R_N1, ASM_REG_W_N1},
|
||||
{10, "n2", 24, ASM_REG_R_N2, ASM_REG_W_N2},
|
||||
{11, "n3", 24, ASM_REG_R_N3, ASM_REG_W_N3},
|
||||
{12, "n4", 24, ASM_REG_R_N4, ASM_REG_W_N4},
|
||||
{13, "n5", 24, ASM_REG_R_N5, ASM_REG_W_N5},
|
||||
{14, "n6", 24, ASM_REG_R_N6, ASM_REG_W_N6},
|
||||
{15, "n7", 24, ASM_REG_R_N7, ASM_REG_W_N7},
|
||||
{16, "m0", 24, ASM_REG_R_M0, ASM_REG_W_M0},
|
||||
{17, "m1", 24, ASM_REG_R_M1, ASM_REG_W_M1},
|
||||
{18, "m2", 24, ASM_REG_R_M2, ASM_REG_W_M2},
|
||||
{19, "m3", 24, ASM_REG_R_M3, ASM_REG_W_M3},
|
||||
{20, "m4", 24, ASM_REG_R_M4, ASM_REG_W_M4},
|
||||
{21, "m5", 24, ASM_REG_R_M5, ASM_REG_W_M5},
|
||||
{22, "m6", 24, ASM_REG_R_M6, ASM_REG_W_M6},
|
||||
{23, "m7", 24, ASM_REG_R_M7, ASM_REG_W_M7},
|
||||
{24, "x0", 24, ASM_REG_R_X0, ASM_REG_W_X0},
|
||||
{25, "x1", 24, ASM_REG_R_X1, ASM_REG_W_X1},
|
||||
{26, "y0", 24, ASM_REG_R_Y0, ASM_REG_W_Y0},
|
||||
{27, "y1", 24, ASM_REG_R_Y1, ASM_REG_W_Y1},
|
||||
{28, "a0", 24, ASM_REG_R_A0, ASM_REG_W_A0},
|
||||
{29, "a1", 24, ASM_REG_R_A1, ASM_REG_W_A1},
|
||||
{30, "a2", 8, ASM_REG_R_A2, ASM_REG_W_A2},
|
||||
{31, "b0", 24, ASM_REG_R_B0, ASM_REG_W_B0},
|
||||
{32, "b1", 24, ASM_REG_R_B1, ASM_REG_W_B1},
|
||||
{33, "b2", 8, ASM_REG_R_B2, ASM_REG_W_B2},
|
||||
{34, "omr", 24, ASM_REG_R_OMR, ASM_REG_W_OMR},
|
||||
{35, "vba", 24, ASM_REG_R_VBA, ASM_REG_W_VBA},
|
||||
{36, "ep", 24, ASM_REG_R_EP, ASM_REG_W_EP},
|
||||
{37, "sc", 24, ASM_REG_R_SC, ASM_REG_W_SC},
|
||||
{38, "sz", 24, ASM_REG_R_SZ, ASM_REG_W_SZ},
|
||||
{39, "sr", 24, ASM_REG_R_SR, ASM_REG_W_SR},
|
||||
{40, "sp", 24, ASM_REG_R_SP, ASM_REG_W_SP},
|
||||
{41, "la", 24, ASM_REG_R_LA, ASM_REG_W_LA},
|
||||
{42, "lc", 24, ASM_REG_R_LC, ASM_REG_W_LC},
|
||||
{43, "pc", 24, ASM_REG_R_PC, ASM_REG_W_PC}
|
||||
/* *INDENT-ON* */
|
||||
};
|
||||
|
||||
int dsp563xx_read_core_reg(struct target *target, int num)
|
||||
{
|
||||
uint32_t reg_value;
|
||||
struct dsp563xx_core_reg *dsp563xx_core_reg;
|
||||
struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
|
||||
|
||||
if ((num < 0) || (num >= DSP563XX_NUMCOREREGS))
|
||||
return ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
dsp563xx_core_reg = dsp563xx->core_cache->reg_list[num].arch_info;
|
||||
reg_value = dsp563xx->core_regs[num];
|
||||
buf_set_u32(dsp563xx->core_cache->reg_list[num].value, 0, 32, reg_value);
|
||||
dsp563xx->core_cache->reg_list[num].valid = 1;
|
||||
dsp563xx->core_cache->reg_list[num].dirty = 0;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_write_core_reg(struct target *target, int num)
|
||||
{
|
||||
uint32_t reg_value;
|
||||
struct dsp563xx_core_reg *dsp563xx_core_reg;
|
||||
struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
|
||||
|
||||
if ((num < 0) || (num >= DSP563XX_NUMCOREREGS))
|
||||
return ERROR_INVALID_ARGUMENTS;
|
||||
|
||||
reg_value = buf_get_u32(dsp563xx->core_cache->reg_list[num].value, 0, 32);
|
||||
dsp563xx_core_reg = dsp563xx->core_cache->reg_list[num].arch_info;
|
||||
dsp563xx->core_regs[num] = reg_value;
|
||||
dsp563xx->core_cache->reg_list[num].valid = 1;
|
||||
dsp563xx->core_cache->reg_list[num].dirty = 0;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_target_create(struct target *target, Jim_Interp * interp)
|
||||
{
|
||||
struct dsp563xx_common *dsp563xx = calloc(1, sizeof(struct dsp563xx_common));
|
||||
|
||||
dsp563xx->jtag_info.tap = target->tap;
|
||||
target->arch_info = dsp563xx;
|
||||
dsp563xx->read_core_reg = dsp563xx_read_core_reg;
|
||||
dsp563xx->write_core_reg = dsp563xx_write_core_reg;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_get_core_reg(struct reg *reg)
|
||||
{
|
||||
int retval = 0;
|
||||
|
||||
LOG_DEBUG("%s", __FUNCTION__);
|
||||
|
||||
struct dsp563xx_core_reg *dsp563xx_reg = reg->arch_info;
|
||||
struct target *target = dsp563xx_reg->target;
|
||||
struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
|
||||
|
||||
if (target->state != TARGET_HALTED)
|
||||
{
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
}
|
||||
|
||||
retval = dsp563xx->read_core_reg(target, dsp563xx_reg->num);
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
int dsp563xx_set_core_reg(struct reg *reg, uint8_t * buf)
|
||||
{
|
||||
LOG_DEBUG("%s", __FUNCTION__);
|
||||
|
||||
struct dsp563xx_core_reg *dsp563xx_reg = reg->arch_info;
|
||||
struct target *target = dsp563xx_reg->target;
|
||||
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, reg->size, value);
|
||||
reg->dirty = 1;
|
||||
reg->valid = 1;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_save_context(struct target *target)
|
||||
{
|
||||
int i;
|
||||
uint32_t data = 0;
|
||||
struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
|
||||
struct dsp563xx_core_reg *arch_info;
|
||||
|
||||
for (i = 0; i < DSP563XX_NUMCOREREGS - 1; i++)
|
||||
{
|
||||
|
||||
// if (!dsp563xx->core_cache->reg_list[i].valid)
|
||||
{
|
||||
arch_info = dsp563xx->core_cache->reg_list[i].arch_info;
|
||||
dsp563xx_once_execute_dw_ir(target->tap, arch_info->r_cmd,
|
||||
0xfffffc);
|
||||
dsp563xx_once_execute_sw_ir(target->tap, 0x000000);
|
||||
dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OGDBR,
|
||||
&data);
|
||||
dsp563xx->core_regs[i] = data;
|
||||
dsp563xx->read_core_reg(target, i);
|
||||
}
|
||||
}
|
||||
|
||||
/* read pc */
|
||||
dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPABEX, &data);
|
||||
dsp563xx->core_regs[i] = data;
|
||||
dsp563xx->read_core_reg(target, i);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_restore_context(struct target *target)
|
||||
{
|
||||
int i;
|
||||
struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
|
||||
struct dsp563xx_core_reg *arch_info;
|
||||
|
||||
for (i = 0; i < DSP563XX_NUMCOREREGS - 1; i++)
|
||||
{
|
||||
if (dsp563xx->core_cache->reg_list[i].dirty)
|
||||
{
|
||||
arch_info = dsp563xx->core_cache->reg_list[i].arch_info;
|
||||
|
||||
dsp563xx->write_core_reg(target, i);
|
||||
|
||||
dsp563xx_once_execute_dw_ir(target->tap, arch_info->w_cmd,
|
||||
dsp563xx->core_regs[i]);
|
||||
dsp563xx_once_execute_sw_ir(target->tap, 0x000000);
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
static const struct reg_arch_type dsp563xx_reg_type = {
|
||||
.get = dsp563xx_get_core_reg,
|
||||
.set = dsp563xx_set_core_reg,
|
||||
};
|
||||
|
||||
int dsp563xx_init_target(struct command_context *cmd_ctx, struct target *target)
|
||||
{
|
||||
/* get pointers to arch-specific information */
|
||||
struct dsp563xx_common *dsp563xx = target_to_dsp563xx(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) * DSP563XX_NUMCOREREGS);
|
||||
struct dsp563xx_core_reg *arch_info =
|
||||
malloc(sizeof(struct dsp563xx_core_reg) * DSP563XX_NUMCOREREGS);
|
||||
int i;
|
||||
|
||||
LOG_DEBUG("%s", __FUNCTION__);
|
||||
|
||||
/* Build the process context cache */
|
||||
cache->name = "dsp563xx registers";
|
||||
cache->next = NULL;
|
||||
cache->reg_list = reg_list;
|
||||
cache->num_regs = DSP563XX_NUMCOREREGS;
|
||||
(*cache_p) = cache;
|
||||
dsp563xx->core_cache = cache;
|
||||
|
||||
for (i = 0; i < DSP563XX_NUMCOREREGS; i++)
|
||||
{
|
||||
arch_info[i].num = dsp563xx_regs[i].id;
|
||||
arch_info[i].name = dsp563xx_regs[i].name;
|
||||
arch_info[i].size = dsp563xx_regs[i].bits;
|
||||
arch_info[i].r_cmd = dsp563xx_regs[i].r_cmd;
|
||||
arch_info[i].w_cmd = dsp563xx_regs[i].w_cmd;
|
||||
arch_info[i].target = target;
|
||||
arch_info[i].dsp563xx_common = dsp563xx;
|
||||
reg_list[i].name = dsp563xx_regs[i].name;
|
||||
reg_list[i].size = dsp563xx_regs[i].bits;
|
||||
reg_list[i].value = calloc(1, 4);
|
||||
reg_list[i].dirty = 0;
|
||||
reg_list[i].valid = 0;
|
||||
reg_list[i].type = &dsp563xx_reg_type;
|
||||
reg_list[i].arch_info = &arch_info[i];
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_arch_state(struct target *target)
|
||||
{
|
||||
LOG_DEBUG("%s", __FUNCTION__);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_jtag_status(struct target *target, uint8_t * status)
|
||||
{
|
||||
uint8_t ir_in;
|
||||
|
||||
ir_in = 0;
|
||||
|
||||
dsp563xx_jtag_sendinstr(target->tap, &ir_in, JTAG_INSTR_ENABLE_ONCE);
|
||||
dsp563xx_execute_queue();
|
||||
|
||||
*status = ir_in;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_jtag_debug_request(struct target *target)
|
||||
{
|
||||
uint8_t ir_in = 0;
|
||||
uint32_t retry = 0;
|
||||
|
||||
while (ir_in != JTAG_STATUS_DEBUG)
|
||||
{
|
||||
dsp563xx_jtag_sendinstr(target->tap, &ir_in,
|
||||
JTAG_INSTR_DEBUG_REQUEST);
|
||||
dsp563xx_execute_queue();
|
||||
LOG_DEBUG("JTAG CMD 7 res: %02X", ir_in);
|
||||
dsp563xx_jtag_sendinstr(target->tap, &ir_in, JTAG_INSTR_ENABLE_ONCE);
|
||||
dsp563xx_execute_queue();
|
||||
LOG_DEBUG("JTAG CMD 6 res: %02X", ir_in);
|
||||
|
||||
if (retry++ == 100)
|
||||
return ERROR_TARGET_FAILURE;
|
||||
}
|
||||
|
||||
if (ir_in != JTAG_STATUS_DEBUG)
|
||||
{
|
||||
return ERROR_TARGET_FAILURE;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_poll(struct target *target)
|
||||
{
|
||||
uint8_t jtag_status;
|
||||
uint32_t once_status;
|
||||
|
||||
dsp563xx_jtag_status(target, &jtag_status);
|
||||
|
||||
if ((jtag_status & 1) != 1)
|
||||
{
|
||||
target->state = TARGET_UNKNOWN;
|
||||
LOG_ERROR
|
||||
("jtag status contains invalid mode value - communication failure");
|
||||
return ERROR_TARGET_FAILURE;
|
||||
}
|
||||
|
||||
if (jtag_status != JTAG_STATUS_DEBUG)
|
||||
{
|
||||
target->state = TARGET_RUNNING;
|
||||
}
|
||||
|
||||
dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OSCR, &once_status);
|
||||
|
||||
if ((once_status & DSP563XX_ONCE_OSCR_DEBUG_M) == DSP563XX_ONCE_OSCR_DEBUG_M)
|
||||
{
|
||||
target->state = TARGET_HALTED;
|
||||
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_halt(struct target *target)
|
||||
{
|
||||
uint8_t jtag_status;
|
||||
uint32_t once_status;
|
||||
struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
|
||||
|
||||
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 ( jtag_status != 0x0d )
|
||||
{
|
||||
dsp563xx_jtag_debug_request(target);
|
||||
|
||||
/* store pipeline register */
|
||||
dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPILR,
|
||||
&dsp563xx->pipeline_context.once_opilr);
|
||||
dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPDBR,
|
||||
&dsp563xx->pipeline_context.once_opdbr);
|
||||
|
||||
dsp563xx_save_context(target);
|
||||
|
||||
dsp563xx_jtag_status(target, &jtag_status);
|
||||
LOG_DEBUG("%02X", jtag_status);
|
||||
dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OSCR,
|
||||
&once_status);
|
||||
LOG_DEBUG("%02X", once_status);
|
||||
}
|
||||
|
||||
LOG_DEBUG("target->state: %s", target_state_name(target));
|
||||
|
||||
LOG_DEBUG("%s", __FUNCTION__);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
#define DSP563XX_ASM_CMD_JUMP 0x0AF080
|
||||
|
||||
int dsp563xx_resume(struct target *target, int current, uint32_t address,
|
||||
int handle_breakpoints, int debug_execution)
|
||||
{
|
||||
struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
|
||||
|
||||
LOG_DEBUG("%s", __FUNCTION__);
|
||||
|
||||
dsp563xx_restore_context(target);
|
||||
|
||||
if (current)
|
||||
{
|
||||
/* restore pipeline registers and go */
|
||||
dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OPILR,
|
||||
dsp563xx->pipeline_context.once_opilr);
|
||||
dsp563xx_once_reg_write(target->tap,
|
||||
DSP563XX_ONCE_OPDBR | DSP563XX_ONCE_OCR_EX |
|
||||
DSP563XX_ONCE_OCR_GO,
|
||||
dsp563xx->pipeline_context.once_opdbr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set to go register and jump */
|
||||
dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OPDBR,
|
||||
DSP563XX_ASM_CMD_JUMP);
|
||||
dsp563xx_once_reg_write(target->tap,
|
||||
DSP563XX_ONCE_PDBGOTO | DSP563XX_ONCE_OCR_EX
|
||||
| DSP563XX_ONCE_OCR_GO, address);
|
||||
}
|
||||
|
||||
target->state = TARGET_RUNNING;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_step(struct target *target, int current, uint32_t address,
|
||||
int handle_breakpoints)
|
||||
{
|
||||
uint32_t once_status;
|
||||
uint32_t dr_in, cnt;
|
||||
struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
|
||||
|
||||
if (target->state != TARGET_HALTED)
|
||||
{
|
||||
LOG_DEBUG("target was not halted");
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
LOG_DEBUG("%s %08X %08X", __FUNCTION__, current, address);
|
||||
|
||||
dsp563xx_jtag_debug_request(target);
|
||||
|
||||
dsp563xx_restore_context(target);
|
||||
|
||||
/* reset trace mode */
|
||||
dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OSCR, 0x000000);
|
||||
/* enable trace mode */
|
||||
dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OSCR,
|
||||
DSP563XX_ONCE_OSCR_TME);
|
||||
|
||||
cnt = 0;
|
||||
|
||||
/* on JUMP we need one extra cycle */
|
||||
if (!current)
|
||||
cnt++;
|
||||
|
||||
/* load step counter with N-1 */
|
||||
dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OTC, cnt);
|
||||
|
||||
if (current)
|
||||
{
|
||||
/* restore pipeline registers and go */
|
||||
dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OPILR,
|
||||
dsp563xx->pipeline_context.once_opilr);
|
||||
dsp563xx_once_reg_write(target->tap,
|
||||
DSP563XX_ONCE_OPDBR | DSP563XX_ONCE_OCR_EX |
|
||||
DSP563XX_ONCE_OCR_GO,
|
||||
dsp563xx->pipeline_context.once_opdbr);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* set to go register and jump */
|
||||
dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OPDBR,
|
||||
DSP563XX_ASM_CMD_JUMP);
|
||||
dsp563xx_once_reg_write(target->tap,
|
||||
DSP563XX_ONCE_PDBGOTO | DSP563XX_ONCE_OCR_EX
|
||||
| DSP563XX_ONCE_OCR_GO, address);
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OSCR,
|
||||
&once_status);
|
||||
|
||||
if (once_status & DSP563XX_ONCE_OSCR_TO)
|
||||
{
|
||||
/* store pipeline register */
|
||||
dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPILR,
|
||||
&dsp563xx->pipeline_context.
|
||||
once_opilr);
|
||||
dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPDBR,
|
||||
&dsp563xx->pipeline_context.
|
||||
once_opdbr);
|
||||
|
||||
dsp563xx_save_context(target);
|
||||
|
||||
dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPABFR,
|
||||
&dr_in);
|
||||
LOG_DEBUG("%08X", dr_in);
|
||||
dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPABDR,
|
||||
&dr_in);
|
||||
LOG_DEBUG("%08X", dr_in);
|
||||
dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPABEX,
|
||||
&dr_in);
|
||||
LOG_DEBUG("%08X", dr_in);
|
||||
|
||||
/* reset trace mode */
|
||||
dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OSCR,
|
||||
0x000000);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_assert_reset(struct target *target)
|
||||
{
|
||||
target->state = TARGET_RESET;
|
||||
|
||||
LOG_DEBUG("%s", __FUNCTION__);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_deassert_reset(struct target *target)
|
||||
{
|
||||
target->state = TARGET_RUNNING;
|
||||
|
||||
LOG_DEBUG("%s", __FUNCTION__);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_soft_reset_halt(struct target *target)
|
||||
{
|
||||
LOG_DEBUG("%s", __FUNCTION__);
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 000000 nop
|
||||
* 46F400 AABBCC move #$aabbcc,y0
|
||||
* 60F400 AABBCC move #$aabbcc,r0
|
||||
* 467000 AABBCC move y0,x:AABBCC
|
||||
* 607000 AABBCC move r0,x:AABBCC
|
||||
|
||||
* 46E000 move x:(r0),y0
|
||||
* 4EE000 move y:(r0),y0
|
||||
* 07E086 move p:(r0),y0
|
||||
|
||||
* 0450B9 move sr,r0
|
||||
* 0446BA move omr,y0
|
||||
* 0446BC move ssh,y0
|
||||
* 0446BD move ssl,y0
|
||||
* 0446BE move la,y0
|
||||
* 0446BF move lc,y0
|
||||
*
|
||||
* 61F000 AABBCC move x:AABBCC,r1
|
||||
* 076190 movem r0,p:(r1)
|
||||
*
|
||||
*/
|
||||
int dsp563xx_read_memory_p(struct target *target, uint32_t address,
|
||||
uint32_t size, uint32_t count, uint8_t * buffer)
|
||||
{
|
||||
uint32_t i, x;
|
||||
uint32_t data;
|
||||
uint8_t *b;
|
||||
|
||||
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)
|
||||
{
|
||||
LOG_WARNING("target not halted");
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
}
|
||||
|
||||
x = count;
|
||||
|
||||
for (i = 0; i < x; i++)
|
||||
{
|
||||
dsp563xx_once_execute_dw_ir_nq(target->tap, 0x60F400, address + i);
|
||||
dsp563xx_once_execute_sw_ir_nq(target->tap, 0x07E086);
|
||||
dsp563xx_once_execute_dw_ir_nq(target->tap, 0x467000, 0xfffffc);
|
||||
dsp563xx_execute_queue();
|
||||
|
||||
dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OGDBR, &data);
|
||||
|
||||
b = buffer + 4 * i;
|
||||
if (size > 0)
|
||||
*b++ = data >> 0;
|
||||
if (size > 1)
|
||||
*b++ = data >> 8;
|
||||
if (size > 2)
|
||||
*b++ = data >> 16;
|
||||
if (size > 3)
|
||||
*b++ = 0x00;
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_write_memory_p(struct target *target, uint32_t address, uint32_t size,
|
||||
uint32_t count, uint8_t * buffer)
|
||||
{
|
||||
uint32_t i, x;
|
||||
uint32_t data;
|
||||
uint8_t *b;
|
||||
|
||||
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)
|
||||
{
|
||||
LOG_WARNING("target not halted");
|
||||
return ERROR_TARGET_NOT_HALTED;
|
||||
}
|
||||
|
||||
x = count;
|
||||
|
||||
for (i = 0; i < x; i++)
|
||||
{
|
||||
b = buffer + 4 * i;
|
||||
|
||||
data = 0;
|
||||
if (size > 0)
|
||||
data = *buffer++;
|
||||
if (size > 1)
|
||||
data |= (*buffer++) << 8;
|
||||
if (size > 2)
|
||||
data |= (*buffer++) << 16;
|
||||
if (size > 3)
|
||||
data |= (*buffer++) << 24;
|
||||
|
||||
// LOG_DEBUG("%08X", data);
|
||||
|
||||
dsp563xx_once_execute_dw_ir_nq(target->tap, 0x61F400, address + i);
|
||||
dsp563xx_once_execute_dw_ir_nq(target->tap, 0x60F400, data);
|
||||
dsp563xx_once_execute_sw_ir_nq(target->tap, 0x076190);
|
||||
dsp563xx_execute_queue();
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_jtag_senddat(struct jtag_tap *tap, uint32_t * dr_in, uint32_t dr_out,
|
||||
int len)
|
||||
{
|
||||
return dsp563xx_write_dr_u32(tap, dr_in, dr_out, len, 1);
|
||||
}
|
||||
|
||||
int dsp563xx_jtag_sendinstr(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out)
|
||||
{
|
||||
return dsp563xx_write_ir_u8(tap, ir_in, ir_out, DSP563XX_JTAG_INS_LEN, 1);
|
||||
}
|
||||
|
||||
/* IR and DR functions */
|
||||
int dsp563xx_write_ir(struct jtag_tap *tap, uint8_t * ir_in, uint8_t * ir_out,
|
||||
int ir_len, int rti)
|
||||
{
|
||||
if (NULL == tap)
|
||||
{
|
||||
LOG_ERROR("invalid tap");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
if (ir_len != tap->ir_length)
|
||||
{
|
||||
LOG_ERROR("invalid ir_len");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
{
|
||||
struct scan_field field[1];
|
||||
|
||||
field[0].tap = tap;
|
||||
field[0].num_bits = tap->ir_length;
|
||||
field[0].out_value = ir_out;
|
||||
field[0].in_value = ir_in;
|
||||
jtag_add_plain_ir_scan(ARRAY_SIZE(field), field,
|
||||
jtag_set_end_state(TAP_IDLE));
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_write_dr(struct jtag_tap *tap, uint8_t * dr_in, uint8_t * dr_out,
|
||||
int dr_len, int rti)
|
||||
{
|
||||
if (NULL == tap)
|
||||
{
|
||||
LOG_ERROR("invalid tap");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
{
|
||||
struct scan_field field[1];
|
||||
|
||||
field[0].tap = tap;
|
||||
field[0].num_bits = dr_len;
|
||||
field[0].out_value = dr_out;
|
||||
field[0].in_value = dr_in;
|
||||
jtag_add_plain_dr_scan(ARRAY_SIZE(field), field,
|
||||
jtag_set_end_state(TAP_IDLE));
|
||||
}
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_write_ir_u8(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out,
|
||||
int ir_len, int rti)
|
||||
{
|
||||
if (ir_len > 8)
|
||||
{
|
||||
LOG_ERROR("ir_len overflow, maxium is 8");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
dsp563xx_write_ir(tap, ir_in, &ir_out, ir_len, rti);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_write_dr_u8(struct jtag_tap *tap, uint8_t * dr_in, uint8_t dr_out,
|
||||
int dr_len, int rti)
|
||||
{
|
||||
if (dr_len > 8)
|
||||
{
|
||||
LOG_ERROR("dr_len overflow, maxium is 8");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
dsp563xx_write_dr(tap, dr_in, &dr_out, dr_len, rti);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_write_ir_u16(struct jtag_tap *tap, uint16_t * ir_in, uint16_t ir_out,
|
||||
int ir_len, int rti)
|
||||
{
|
||||
if (ir_len > 16)
|
||||
{
|
||||
LOG_ERROR("ir_len overflow, maxium is 16");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
dsp563xx_write_ir(tap, (uint8_t *) ir_in, (uint8_t *) & ir_out, ir_len, rti);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_write_dr_u16(struct jtag_tap *tap, uint16_t * dr_in, uint16_t dr_out,
|
||||
int dr_len, int rti)
|
||||
{
|
||||
if (dr_len > 16)
|
||||
{
|
||||
LOG_ERROR("dr_len overflow, maxium is 16");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
dsp563xx_write_dr(tap, (uint8_t *) dr_in, (uint8_t *) & dr_out, dr_len, rti);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_write_ir_u32(struct jtag_tap *tap, uint32_t * ir_in, uint32_t ir_out,
|
||||
int ir_len, int rti)
|
||||
{
|
||||
if (ir_len > 32)
|
||||
{
|
||||
LOG_ERROR("ir_len overflow, maxium is 32");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
dsp563xx_write_ir(tap, (uint8_t *) ir_in, (uint8_t *) & ir_out, ir_len, rti);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_write_dr_u32(struct jtag_tap *tap, uint32_t * dr_in, uint32_t dr_out,
|
||||
int dr_len, int rti)
|
||||
{
|
||||
if (dr_len > 32)
|
||||
{
|
||||
LOG_ERROR("dr_len overflow, maxium is 32");
|
||||
return ERROR_FAIL;
|
||||
}
|
||||
|
||||
dsp563xx_write_dr(tap, (uint8_t *) dr_in, (uint8_t *) & dr_out, dr_len, rti);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
int dsp563xx_execute_queue(void)
|
||||
{
|
||||
return jtag_execute_queue();
|
||||
}
|
||||
|
||||
/** Holds methods for DSP563XX targets. */
|
||||
struct target_type dsp563xx_target = {
|
||||
.name = "dsp563xx",
|
||||
|
||||
.poll = dsp563xx_poll,
|
||||
.arch_state = dsp563xx_arch_state,
|
||||
|
||||
.target_request_data = NULL,
|
||||
|
||||
.halt = dsp563xx_halt,
|
||||
.resume = dsp563xx_resume,
|
||||
.step = dsp563xx_step,
|
||||
|
||||
.assert_reset = dsp563xx_assert_reset,
|
||||
.deassert_reset = dsp563xx_deassert_reset,
|
||||
.soft_reset_halt = dsp563xx_soft_reset_halt,
|
||||
|
||||
.read_memory = dsp563xx_read_memory_p,
|
||||
.write_memory = dsp563xx_write_memory_p,
|
||||
|
||||
.target_create = dsp563xx_target_create,
|
||||
.init_target = dsp563xx_init_target,
|
||||
};
|
|
@ -0,0 +1,88 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2009 by Mathias Kuester *
|
||||
* mkdorg@users.sourceforge.net *
|
||||
* *
|
||||
* 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 DSP563XX_H
|
||||
#define DSP563XX_H
|
||||
|
||||
#include <jtag/jtag.h>
|
||||
|
||||
#define DSP563XX_NUMCOREREGS 44
|
||||
|
||||
struct mcu_jtag
|
||||
{
|
||||
struct jtag_tap *tap;
|
||||
};
|
||||
|
||||
struct dsp563xx_pipeline_context
|
||||
{
|
||||
/* PIL Register */
|
||||
uint32_t once_opilr;
|
||||
/* PDB Register */
|
||||
uint32_t once_opdbr;
|
||||
};
|
||||
|
||||
struct dsp563xx_common
|
||||
{
|
||||
struct mcu_jtag jtag_info;
|
||||
struct reg_cache *core_cache;
|
||||
uint32_t core_regs[DSP563XX_NUMCOREREGS];
|
||||
|
||||
struct dsp563xx_pipeline_context pipeline_context;
|
||||
|
||||
/* register cache to processor synchronization */
|
||||
int (*read_core_reg) (struct target * target, int num);
|
||||
int (*write_core_reg) (struct target * target, int num);
|
||||
};
|
||||
|
||||
struct dsp563xx_core_reg
|
||||
{
|
||||
uint32_t num;
|
||||
char *name;
|
||||
uint32_t size;
|
||||
uint32_t r_cmd;
|
||||
uint32_t w_cmd;
|
||||
struct target *target;
|
||||
struct dsp563xx_common *dsp563xx_common;
|
||||
};
|
||||
|
||||
static inline struct dsp563xx_common *target_to_dsp563xx(struct target *target)
|
||||
{
|
||||
return target->arch_info;
|
||||
}
|
||||
|
||||
int dsp563xx_write_ir(struct jtag_tap *tap, uint8_t * ir_in, uint8_t * ir_out,
|
||||
int ir_len, int rti);
|
||||
int dsp563xx_write_dr(struct jtag_tap *tap, uint8_t * dr_in, uint8_t * dr_out,
|
||||
int dr_len, int rti);
|
||||
int dsp563xx_write_ir_u8(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out,
|
||||
int ir_len, int rti);
|
||||
int dsp563xx_write_dr_u8(struct jtag_tap *tap, uint8_t * ir_in, uint8_t ir_out,
|
||||
int dr_len, int rti);
|
||||
int dsp563xx_write_ir_u16(struct jtag_tap *tap, uint16_t * ir_in, uint16_t ir_out,
|
||||
int ir_len, int rti);
|
||||
int dsp563xx_write_dr_u16(struct jtag_tap *tap, uint16_t * ir_in, uint16_t ir_out,
|
||||
int dr_len, int rti);
|
||||
int dsp563xx_write_ir_u32(struct jtag_tap *tap, uint32_t * ir_in, uint32_t ir_out,
|
||||
int ir_len, int rti);
|
||||
int dsp563xx_write_dr_u32(struct jtag_tap *tap, uint32_t * ir_in, uint32_t ir_out,
|
||||
int dr_len, int rti);
|
||||
|
||||
int dsp563xx_execute_queue(void);
|
||||
|
||||
#endif /* DSP563XX_H */
|
|
@ -0,0 +1,124 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2009 by Mathias Kuester *
|
||||
* mkdorg@users.sourceforge.net *
|
||||
* *
|
||||
* This program is free software; you can redistribute it and/or modify *
|
||||
* it under the terms of the GNU General Public License as published by *
|
||||
* the Free Software Foundation; either version 2 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* This program is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the GNU General Public License *
|
||||
* along with this program; if not, write to the *
|
||||
* Free Software Foundation, Inc., *
|
||||
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
|
||||
***************************************************************************/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
|
||||
#include <helper/jim.h>
|
||||
|
||||
#include "target.h"
|
||||
#include "target_type.h"
|
||||
#include "register.h"
|
||||
#include "dsp563xx.h"
|
||||
#include "dsp563xx_once.h"
|
||||
|
||||
/** single word instruction */
|
||||
int dsp563xx_once_ir_exec(struct jtag_tap *tap, uint8_t instr, uint8_t rw,
|
||||
uint8_t go, uint8_t ex)
|
||||
{
|
||||
dsp563xx_write_dr_u8(tap, 0,
|
||||
instr | (ex << 5) | (go << 6) | (rw << 7), 8, 0);
|
||||
dsp563xx_execute_queue();
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/** single word instruction */
|
||||
int dsp563xx_once_ir_exec_nq(struct jtag_tap *tap, uint8_t instr, uint8_t rw,
|
||||
uint8_t go, uint8_t ex)
|
||||
{
|
||||
dsp563xx_write_dr_u8(tap, 0,
|
||||
instr | (ex << 5) | (go << 6) | (rw << 7), 8, 0);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/** once read register */
|
||||
int dsp563xx_once_reg_read(struct jtag_tap *tap, uint8_t reg, uint32_t * data)
|
||||
{
|
||||
uint32_t dr_in;
|
||||
|
||||
dr_in = 0;
|
||||
|
||||
dsp563xx_once_ir_exec(tap, reg, 1, 0, 0);
|
||||
dsp563xx_write_dr_u32(tap, &dr_in, 0x00, 24, 0);
|
||||
dsp563xx_execute_queue();
|
||||
|
||||
*data = dr_in;
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/** once write register */
|
||||
int dsp563xx_once_reg_write(struct jtag_tap *tap, uint8_t reg, uint32_t data)
|
||||
{
|
||||
dsp563xx_once_ir_exec(tap, reg, 0, 0, 0);
|
||||
dsp563xx_write_dr_u32(tap, 0x00, data, 24, 0);
|
||||
dsp563xx_execute_queue();
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/** single word instruction */
|
||||
int dsp563xx_once_execute_sw_ir(struct jtag_tap *tap, uint32_t opcode)
|
||||
{
|
||||
dsp563xx_once_ir_exec(tap, DSP563XX_ONCE_OPDBR, 0, 1, 0);
|
||||
dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
|
||||
dsp563xx_execute_queue();
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/** double word instruction */
|
||||
int dsp563xx_once_execute_dw_ir(struct jtag_tap *tap, uint32_t opcode,
|
||||
uint32_t operand)
|
||||
{
|
||||
dsp563xx_once_ir_exec(tap, DSP563XX_ONCE_OPDBR, 0, 0, 0);
|
||||
dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
|
||||
dsp563xx_execute_queue();
|
||||
|
||||
dsp563xx_once_ir_exec(tap, DSP563XX_ONCE_OPDBR, 0, 1, 0);
|
||||
dsp563xx_write_dr_u32(tap, 0, operand, 24, 0);
|
||||
dsp563xx_execute_queue();
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/** single word instruction */
|
||||
int dsp563xx_once_execute_sw_ir_nq(struct jtag_tap *tap, uint32_t opcode)
|
||||
{
|
||||
dsp563xx_once_ir_exec_nq(tap, DSP563XX_ONCE_OPDBR, 0, 1, 0);
|
||||
dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
||||
|
||||
/** double word instruction */
|
||||
int dsp563xx_once_execute_dw_ir_nq(struct jtag_tap *tap, uint32_t opcode,
|
||||
uint32_t operand)
|
||||
{
|
||||
dsp563xx_once_ir_exec_nq(tap, DSP563XX_ONCE_OPDBR, 0, 0, 0);
|
||||
dsp563xx_write_dr_u32(tap, 0, opcode, 24, 0);
|
||||
|
||||
dsp563xx_once_ir_exec_nq(tap, DSP563XX_ONCE_OPDBR, 0, 1, 0);
|
||||
dsp563xx_write_dr_u32(tap, 0, operand, 24, 0);
|
||||
|
||||
return ERROR_OK;
|
||||
}
|
|
@ -0,0 +1,81 @@
|
|||
/***************************************************************************
|
||||
* Copyright (C) 2009 by Mathias Kuester *
|
||||
* mkdorg@users.sourceforge.net *
|
||||
* *
|
||||
* 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 DSP563XX_ONCE_H
|
||||
#define DSP563XX_ONCE_H
|
||||
|
||||
#include <jtag/jtag.h>
|
||||
|
||||
#define DSP563XX_ONCE_OCR_EX (1<<5)
|
||||
#define DSP563XX_ONCE_OCR_GO (1<<6)
|
||||
#define DSP563XX_ONCE_OCR_RW (1<<7)
|
||||
|
||||
#define DSP563XX_ONCE_OSCR_OS1 (1<<7)
|
||||
#define DSP563XX_ONCE_OSCR_OS0 (1<<6)
|
||||
#define DSP563XX_ONCE_OSCR_HIT (1<<5)
|
||||
#define DSP563XX_ONCE_OSCR_TO (1<<4)
|
||||
#define DSP563XX_ONCE_OSCR_MBO (1<<3)
|
||||
#define DSP563XX_ONCE_OSCR_SWO (1<<2)
|
||||
#define DSP563XX_ONCE_OSCR_IME (1<<1)
|
||||
#define DSP563XX_ONCE_OSCR_TME (1<<0)
|
||||
|
||||
#define DSP563XX_ONCE_OSCR_NORMAL_M (0)
|
||||
#define DSP563XX_ONCE_OSCR_STOPWAIT_M (DSP563XX_ONCE_OSCR_OS0)
|
||||
#define DSP563XX_ONCE_OSCR_BUSY_M (DSP563XX_ONCE_OSCR_OS1)
|
||||
#define DSP563XX_ONCE_OSCR_DEBUG_M (DSP563XX_ONCE_OSCR_OS0|DSP563XX_ONCE_OSCR_OS1)
|
||||
|
||||
#define DSP563XX_ONCE_OSCR 0x000 /* status/ctrl reg. */
|
||||
#define DSP563XX_ONCE_OMBC 0x001 /* memory breakp. reg. */
|
||||
#define DSP563XX_ONCE_OBCR 0x002 /* breakp. ctrl reg */
|
||||
#define DSP563XX_ONCE_OMLR0 0x005 /* memory limit reg */
|
||||
#define DSP563XX_ONCE_OMLR1 0x006 /* memory limit reg */
|
||||
#define DSP563XX_ONCE_OGDBR 0x009 /* gdb reg */
|
||||
#define DSP563XX_ONCE_OPDBR 0x00A /* pdb reg */
|
||||
#define DSP563XX_ONCE_OPILR 0x00B /* pil reg */
|
||||
#define DSP563XX_ONCE_PDBGOTO 0x00C /* pdb to go reg */
|
||||
#define DSP563XX_ONCE_OTC 0x00D /* trace cnt */
|
||||
#define DSP563XX_ONCE_TAGB 0x00E /* tags buffer */
|
||||
#define DSP563XX_ONCE_OPABFR 0x00F /* pab fetch reg */
|
||||
#define DSP563XX_ONCE_OPABDR 0x010 /* pab decode reg */
|
||||
#define DSP563XX_ONCE_OPABEX 0x011 /* pab exec reg */
|
||||
#define DSP563XX_ONCE_OPABEX 0x011 /* trace buffer/inc ptr */
|
||||
#define DSP563XX_ONCE_NOREG 0x01F /* no register selected */
|
||||
|
||||
/** single word instruction */
|
||||
int dsp563xx_once_ir_exec(struct jtag_tap *tap, uint8_t instr, uint8_t rw,
|
||||
uint8_t go, uint8_t ex);
|
||||
/** single word instruction */
|
||||
int dsp563xx_once_ir_exec_nq(struct jtag_tap *tap, uint8_t instr, uint8_t rw,
|
||||
uint8_t go, uint8_t ex);
|
||||
/** once read register */
|
||||
int dsp563xx_once_reg_read(struct jtag_tap *tap, uint8_t reg, uint32_t * data);
|
||||
/** once write register */
|
||||
int dsp563xx_once_reg_write(struct jtag_tap *tap, uint8_t reg, uint32_t data);
|
||||
/** single word instruction */
|
||||
int dsp563xx_once_execute_sw_ir(struct jtag_tap *tap, uint32_t opcode);
|
||||
/** double word instruction */
|
||||
int dsp563xx_once_execute_dw_ir(struct jtag_tap *tap, uint32_t opcode,
|
||||
uint32_t operand);
|
||||
/** single word instruction */
|
||||
int dsp563xx_once_execute_sw_ir_nq(struct jtag_tap *tap, uint32_t opcode);
|
||||
/** double word instruction */
|
||||
int dsp563xx_once_execute_dw_ir_nq(struct jtag_tap *tap, uint32_t opcode,
|
||||
uint32_t operand);
|
||||
|
||||
#endif /* DSP563XX_ONCE_H */
|
|
@ -64,6 +64,7 @@ extern struct target_type cortexa8_target;
|
|||
extern struct target_type arm11_target;
|
||||
extern struct target_type mips_m4k_target;
|
||||
extern struct target_type avr_target;
|
||||
extern struct target_type dsp563xx_target;
|
||||
extern struct target_type testee_target;
|
||||
|
||||
struct target_type *target_types[] =
|
||||
|
@ -83,6 +84,7 @@ struct target_type *target_types[] =
|
|||
&arm11_target,
|
||||
&mips_m4k_target,
|
||||
&avr_target,
|
||||
&dsp563xx_target,
|
||||
&testee_target,
|
||||
NULL,
|
||||
};
|
||||
|
|
|
@ -0,0 +1,10 @@
|
|||
#
|
||||
# Olimex ARM-USB-OCD-TINY
|
||||
#
|
||||
# http://www.olimex.com/dev/arm-usb-tiny.html
|
||||
#
|
||||
|
||||
interface ft2232
|
||||
ft2232_device_desc "Olimex OpenOCD JTAG TINY"
|
||||
ft2232_layout "olimex-jtag"
|
||||
ft2232_vid_pid 0x15ba 0x0004
|
|
@ -0,0 +1,38 @@
|
|||
# Script for freescale DSP56321
|
||||
#
|
||||
|
||||
if { [info exists CHIPNAME] } {
|
||||
set _CHIPNAME $CHIPNAME
|
||||
} else {
|
||||
set _CHIPNAME dsp56321
|
||||
}
|
||||
|
||||
if { [info exists ENDIAN] } {
|
||||
set _ENDIAN $ENDIAN
|
||||
} else {
|
||||
# this defaults to a big endian
|
||||
set _ENDIAN big
|
||||
}
|
||||
|
||||
if { [info exists CPUTAPID ] } {
|
||||
set _CPUTAPID $CPUTAPID
|
||||
} else {
|
||||
# force an error till we get a good number
|
||||
set _CPUTAPID 0x1181501d
|
||||
}
|
||||
|
||||
#jtag speed
|
||||
jtag_khz 4500
|
||||
|
||||
#has only srst
|
||||
reset_config srst_only
|
||||
|
||||
#jtag scan chain
|
||||
jtag newtap $_CHIPNAME cpu -irlen 4 -ircapture 1 -irmask 0x1 -expected-id $_CPUTAPID
|
||||
|
||||
#target configuration
|
||||
set _TARGETNAME $_CHIPNAME.cpu
|
||||
target create $_TARGETNAME dsp563xx -endian $_ENDIAN -chain-position $_TARGETNAME
|
||||
|
||||
#working area at base of ram
|
||||
$_TARGETNAME configure -work-area-virt 0
|
Loading…
Reference in New Issue