target: add basic dsp563xx support
authormkdorg@users.sourceforge.net <mkdorg@users.sourceforge.net>
Tue, 15 Dec 2009 17:30:59 +0000 (18:30 +0100)
committerØyvind Harboe <oyvind.harboe@zylin.com>
Tue, 15 Dec 2009 17:38:52 +0000 (18:38 +0100)
doc/openocd.texi
src/target/Makefile.am
src/target/dsp563xx.c [new file with mode: 0644]
src/target/dsp563xx.h [new file with mode: 0644]
src/target/dsp563xx_once.c [new file with mode: 0644]
src/target/dsp563xx_once.h [new file with mode: 0644]
src/target/target.c
tcl/interface/arm-usb-ocd-tiny.cfg [new file with mode: 0644]
tcl/target/dsp56321.cfg [new file with mode: 0644]

index 01dfa76..9d56523 100644 (file)
@@ -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:
index f1d4caa..df54a03 100644 (file)
@@ -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 \
diff --git a/src/target/dsp563xx.c b/src/target/dsp563xx.c
new file mode 100644 (file)
index 0000000..d3fa4c3
--- /dev/null
@@ -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,
+};
diff --git a/src/target/dsp563xx.h b/src/target/dsp563xx.h
new file mode 100644 (file)
index 0000000..73050b6
--- /dev/null
@@ -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 */
diff --git a/src/target/dsp563xx_once.c b/src/target/dsp563xx_once.c
new file mode 100644 (file)
index 0000000..0186751
--- /dev/null
@@ -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;
+}
diff --git a/src/target/dsp563xx_once.h b/src/target/dsp563xx_once.h
new file mode 100644 (file)
index 0000000..871f622
--- /dev/null
@@ -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 */
index 740db0f..ebddbba 100644 (file)
@@ -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,
 };
diff --git a/tcl/interface/arm-usb-ocd-tiny.cfg b/tcl/interface/arm-usb-ocd-tiny.cfg
new file mode 100644 (file)
index 0000000..34793f3
--- /dev/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
diff --git a/tcl/target/dsp56321.cfg b/tcl/target/dsp56321.cfg
new file mode 100644 (file)
index 0000000..4506837
--- /dev/null
@@ -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