diff --git a/doc/openocd.texi b/doc/openocd.texi index 01dfa76b6..9d5652315 100644 --- a/doc/openocd.texi +++ b/doc/openocd.texi @@ -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: diff --git a/src/target/Makefile.am b/src/target/Makefile.am index f1d4caa2f..df54a0341 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 000000000..d3fa4c3bb --- /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 + +#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 000000000..73050b6d3 --- /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 + +#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 000000000..0186751f0 --- /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 + +#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 000000000..871f62280 --- /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 + +#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 740db0f18..ebddbba82 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, }; diff --git a/tcl/interface/arm-usb-ocd-tiny.cfg b/tcl/interface/arm-usb-ocd-tiny.cfg new file mode 100644 index 000000000..34793f382 --- /dev/null +++ b/tcl/interface/arm-usb-ocd-tiny.cfg @@ -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 index 000000000..450683705 --- /dev/null +++ b/tcl/target/dsp56321.cfg @@ -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