summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authormkdorg@users.sourceforge.net <mkdorg@users.sourceforge.net>2009-12-15 18:30:59 +0100
committerØyvind Harboe <oyvind.harboe@zylin.com>2009-12-15 18:38:52 +0100
commit646ce814b4fb678b7d8d341afe0694c266112426 (patch)
treef47236c7e4e51f5125635bd562ba153bafac8544 /src
parent4639366947427da6face9cb6954b6603eb2e2fd3 (diff)
downloadopenocd+libswd-646ce814b4fb678b7d8d341afe0694c266112426.tar.gz
openocd+libswd-646ce814b4fb678b7d8d341afe0694c266112426.tar.bz2
openocd+libswd-646ce814b4fb678b7d8d341afe0694c266112426.tar.xz
openocd+libswd-646ce814b4fb678b7d8d341afe0694c266112426.zip
target: add basic dsp563xx support
Diffstat (limited to 'src')
-rw-r--r--src/target/Makefile.am6
-rw-r--r--src/target/dsp563xx.c990
-rw-r--r--src/target/dsp563xx.h88
-rw-r--r--src/target/dsp563xx_once.c124
-rw-r--r--src/target/dsp563xx_once.h81
-rw-r--r--src/target/target.c2
6 files changed, 1290 insertions, 1 deletions
diff --git a/src/target/Makefile.am b/src/target/Makefile.am
index f1d4caa2..df54a034 100644
--- a/src/target/Makefile.am
+++ b/src/target/Makefile.am
@@ -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
index 00000000..d3fa4c3b
--- /dev/null
+++ b/src/target/dsp563xx.c
@@ -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
index 00000000..73050b6d
--- /dev/null
+++ b/src/target/dsp563xx.h
@@ -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
index 00000000..0186751f
--- /dev/null
+++ b/src/target/dsp563xx_once.c
@@ -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
index 00000000..871f6228
--- /dev/null
+++ b/src/target/dsp563xx_once.h
@@ -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 */
diff --git a/src/target/target.c b/src/target/target.c
index 740db0f1..ebddbba8 100644
--- a/src/target/target.c
+++ b/src/target/target.c
@@ -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,
};