This patch adds Freescale DSP563xx and DSP563xx-ONCE (one chip emulation) 
support.

---
 src/target/dsp563xx.c      |  875 ++++++++++++++++++++++++++++++++++++++++++++
 src/target/dsp563xx.h      |   73 ++++
 src/target/dsp563xx_once.c |  116 ++++++
 src/target/dsp563xx_once.h |   71 ++++
 4 files changed, 1135 insertions(+), 0 deletions(-)
 create mode 100644 src/target/dsp563xx.c
 create mode 100644 src/target/dsp563xx.h
 create mode 100644 src/target/dsp563xx_once.c
 create mode 100644 src/target/dsp563xx_once.h

diff --git a/src/target/dsp563xx.c b/src/target/dsp563xx.c
new file mode 100644
index 0000000..e75137c
--- /dev/null
+++ b/src/target/dsp563xx.c
@@ -0,0 +1,875 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Mathias Kuester                                 *
+ *   [email protected]                                          *
+ *                                                                         *
+ *   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 "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);
+
+char* dsp563xx_core_reg_list[] =
+{
+       "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7","ep",
+       "n0", "n1", "n2", "n3", "n4", "n5", "n6", "n7",
+       "m0", "m1", "m2", "m3", "m4", "m5", "m6", "m7",
+       "x0", "x1", "y0", "y1",
+       "a0", "a1", "a2",
+       "b0", "b1", "b2",
+       "sr", "lc", "la", "ssh", "ssl", "omr", "pc"
+};
+
+#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_R_EP   0x05702A
+
+#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_R_M0   0x057020
+#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_R_X0   0x447000
+#define ASM_REG_R_X1   0x457000
+#define ASM_REG_R_Y0   0x467000
+#define ASM_REG_R_Y1   0x477000
+
+#define ASM_REG_R_A0   0x507000
+#define ASM_REG_R_A1   0x547000
+#define ASM_REG_R_A2   0x527000
+
+#define ASM_REG_R_B0   0x517000
+#define ASM_REG_R_B1   0x557000
+#define ASM_REG_R_B2   0x537000
+
+#define ASM_REG_R_SR   0x0450B9
+#define ASM_REG_R_LC   0x0446BF
+#define ASM_REG_R_LA   0x0446BE
+#define ASM_REG_R_SSH  0x0446BC
+#define ASM_REG_R_SSL  0x0446BD
+#define ASM_REG_R_OMR  0x0446BA
+#define ASM_REG_R_PC   0x000000
+
+struct dsp563xx_core_reg 
dsp563xx_core_reg_list_arch_info[DSP563XX_NUMCOREREGS] =
+{
+       {0, 24, ASM_REG_R_R0, NULL, NULL},
+       {1, 24, ASM_REG_R_R1, NULL, NULL},
+       {2, 24, ASM_REG_R_R2, NULL, NULL},
+       {3, 24, ASM_REG_R_R3, NULL, NULL},
+       {4, 24, ASM_REG_R_R4, NULL, NULL},
+       {5, 24, ASM_REG_R_R5, NULL, NULL},
+       {6, 24, ASM_REG_R_R6, NULL, NULL},
+       {7, 24, ASM_REG_R_R7, NULL, NULL},
+       {8, 24, ASM_REG_R_EP, NULL, NULL},
+       
+       {9, 24, ASM_REG_R_N0, NULL, NULL},
+       {10, 24, ASM_REG_R_N1, NULL, NULL},
+       {11, 24, ASM_REG_R_N2, NULL, NULL},
+       {12, 24, ASM_REG_R_N3, NULL, NULL},
+       {13, 24, ASM_REG_R_N4, NULL, NULL},
+       {14, 24, ASM_REG_R_N5, NULL, NULL},
+       {15, 24, ASM_REG_R_N6, NULL, NULL},
+       {16, 24, ASM_REG_R_N7, NULL, NULL},
+       
+       {17, 24, ASM_REG_R_M0, NULL, NULL},
+       {18, 24, ASM_REG_R_M1, NULL, NULL},
+       {19, 24, ASM_REG_R_M2, NULL, NULL},
+       {20, 24, ASM_REG_R_M3, NULL, NULL},
+       {21, 24, ASM_REG_R_M4, NULL, NULL},
+       {22, 24, ASM_REG_R_M5, NULL, NULL},
+       {23, 24, ASM_REG_R_M6, NULL, NULL},
+       {24, 24, ASM_REG_R_M7, NULL, NULL},
+       
+       {25, 24, ASM_REG_R_X0, NULL, NULL},
+       {26, 24, ASM_REG_R_X1, NULL, NULL},
+       {27, 24, ASM_REG_R_Y0, NULL, NULL},
+       {28, 24, ASM_REG_R_Y1, NULL, NULL},
+       
+       {29, 24, ASM_REG_R_A0, NULL, NULL},
+       {30, 24, ASM_REG_R_A1, NULL, NULL},
+       {31, 8, ASM_REG_R_A2, NULL, NULL},
+       
+       {32, 24, ASM_REG_R_B0, NULL, NULL},
+       {33, 24, ASM_REG_R_B1, NULL, NULL},
+       {34, 8, ASM_REG_R_B2, NULL, NULL},
+       
+       {35, 24, ASM_REG_R_SR, NULL, NULL},
+       {36, 24, ASM_REG_R_LC, NULL, NULL},
+       {37, 24, ASM_REG_R_LA, NULL, NULL},
+       {38, 24, ASM_REG_R_SSH, NULL, NULL},
+       {39, 24, ASM_REG_R_SSL, NULL, NULL},
+       {40, 24, ASM_REG_R_OMR, NULL, NULL},
+       {41, 24, ASM_REG_R_PC, NULL, NULL}
+};
+
+struct target_type dsp563xx_target =
+{
+       .name = "dsp56",
+
+       .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,
+       
+/*
+       .get_gdb_reg_list = dsp563xx_get_gdb_reg_list,
+
+       .write_memory = dsp563xx_write_memory,
+       .bulk_write_memory = dsp563xx_bulk_write_memory,
+       .checksum_memory = dsp563xx_checksum_memory,
+       .blank_check_memory = dsp563xx_blank_check_memory,
+
+       .run_algorithm = dsp563xx_run_algorithm,
+
+       .add_breakpoint = dsp563xx_add_breakpoint,
+       .remove_breakpoint = dsp563xx_remove_breakpoint,
+       .add_watchpoint = dsp563xx_add_watchpoint,
+       .remove_watchpoint = dsp563xx_remove_watchpoint,
+*/
+       .target_create = dsp563xx_target_create,
+       .init_target = dsp563xx_init_target,
+};
+
+int dsp563xx_read_core_reg(struct target *target, int num)
+{
+       uint32_t reg_value;
+       struct dsp563xx_core_reg *dsp563xx_core_reg;
+       
+       /* get pointers to arch-specific information */
+       struct dsp563xx_common *dsp563xx = target->arch_info;
+       
+       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;
+       
+       /* get pointers to arch-specific information */
+       struct dsp563xx_common *dsp563xx = target->arch_info;
+       
+       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->arch_info;
+       
+       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;
+       
+       /* get pointers to arch-specific information */
+       struct dsp563xx_common *dsp563xx = target->arch_info;
+       
+       for (i = 0; i < DSP563XX_NUMCOREREGS-1; i++)
+       {
+               
dsp563xx_once_execute_dw_ir(target->tap,dsp563xx_core_reg_list_arch_info[i].r_cmd,0xfffffc);
+               dsp563xx_once_execute_sw_ir(target->tap,0x000000);
+               dsp563xx_once_reg_read(target->tap,ONCE_OGDBR,&data);
+               dsp563xx->core_regs[i] = data;
+       }
+
+       /* read pc */
+       dsp563xx_once_reg_read(target->tap,ONCE_OPABEX,&data);
+       dsp563xx->core_regs[i] = data;
+       
+       /* read core registers */
+       for (i = 0; i < DSP563XX_NUMCOREREGS; i++)
+       {
+//             if (!dsp563xx->core_cache->reg_list[i].valid)
+               {
+                       dsp563xx->read_core_reg(target, i);
+               }
+       }
+       
+       return ERROR_OK;
+}
+
+int dsp563xx_restore_context(struct target *target)
+{
+       int i;
+       
+       /* get pointers to arch-specific information */
+       struct dsp563xx_common *dsp563xx = target->arch_info;
+       
+       for (i = 0; i < DSP563XX_NUMCOREREGS-1; i++)
+       {
+//             if (dsp563xx->core_cache->reg_list[i].dirty)
+               {
+                       dsp563xx->write_core_reg(target, i);
+               }
+       }
+       
+       /* TODO: store regs */
+       
+       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->arch_info;
+       
+       int num_regs = DSP563XX_NUMCOREREGS;
+       struct reg_cache **cache_p = 
register_get_last_cache_p(&target->reg_cache);
+       struct reg_cache *cache = malloc(sizeof(struct reg_cache));
+       struct reg *reg_list = malloc(sizeof(struct reg) * num_regs);
+       struct dsp563xx_core_reg *arch_info = malloc(sizeof(struct 
dsp563xx_core_reg) * num_regs);
+       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 = num_regs;
+       (*cache_p) = cache;
+       dsp563xx->core_cache = cache;
+       
+       for (i = 0; i < num_regs; i++)
+       {
+               arch_info[i] = dsp563xx_core_reg_list_arch_info[i];
+               arch_info[i].target = target;
+               arch_info[i].dsp563xx_common = dsp563xx;
+               reg_list[i].name = dsp563xx_core_reg_list[i];
+               reg_list[i].size = dsp563xx_core_reg_list_arch_info[i].size;
+               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 != 0x0d )
+       {
+               target->state = TARGET_RUNNING;
+       }
+
+       dsp563xx_once_reg_read(target->tap,ONCE_OSCR,&once_status);
+
+       if ( jtag_status == 0x0d )
+       {
+               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->arch_info;
+       
+       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);
+
+               
dsp563xx_once_reg_read(target->tap,ONCE_OPILR,&dsp563xx->pipeline_context.once_opilr);
+               
dsp563xx_once_reg_read(target->tap,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,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->arch_info;
+       
+       LOG_DEBUG("%s", __FUNCTION__);
+       
+       dsp563xx_restore_context(target);
+       
+       if ( current )
+       {
+               /* restore pipeline registers and go */
+               
dsp563xx_once_reg_write(target->tap,ONCE_OPILR,dsp563xx->pipeline_context.once_opilr);
+       
dsp563xx_once_reg_write(target->tap,ONCE_OPDBR|ONCE_OCR_EX|ONCE_OCR_GO,dsp563xx->pipeline_context.once_opdbr);
+       }
+       else
+       {
+               /* set to go register and jump */
+               
dsp563xx_once_reg_write(target->tap,ONCE_OPDBR,DSP563XX_ASM_CMD_JUMP);
+               
dsp563xx_once_reg_write(target->tap,ONCE_PDBGOTO|ONCE_OCR_EX|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;
+       struct dsp563xx_common *dsp563xx = target->arch_info;
+       
+       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,ONCE_OSCR,0x000000);
+       /* enable trace mode */
+       dsp563xx_once_reg_write(target->tap,ONCE_OSCR,ONCE_OSCR_TME);
+       /* load step counter with N-1 */
+       dsp563xx_once_reg_write(target->tap,ONCE_OTC,0x000000);
+       
+       if ( current )
+       {
+               /* restore pipeline registers and go */
+               
dsp563xx_once_reg_write(target->tap,ONCE_OPILR,dsp563xx->pipeline_context.once_opilr);
+       
dsp563xx_once_reg_write(target->tap,ONCE_OPDBR|ONCE_OCR_EX|ONCE_OCR_GO,dsp563xx->pipeline_context.once_opdbr);
+       }
+       else
+       {
+               /* set to go register and jump */
+               
dsp563xx_once_reg_write(target->tap,ONCE_OPDBR,DSP563XX_ASM_CMD_JUMP);
+               
dsp563xx_once_reg_write(target->tap,ONCE_PDBGOTO|ONCE_OCR_EX|ONCE_OCR_GO,address);
+       }
+       
+       while(1)
+       {
+               dsp563xx_once_reg_read(target->tap,ONCE_OSCR,&once_status);
+               
+               if ( once_status & (1<<4) )
+               {
+                       
dsp563xx_once_reg_read(target->tap,ONCE_OPILR,&dsp563xx->pipeline_context.once_opilr);
+                       
dsp563xx_once_reg_read(target->tap,ONCE_OPDBR,&dsp563xx->pipeline_context.once_opdbr);
+
+                       dsp563xx_save_context(target);
+                       
+                       dsp563xx_once_reg_read(target->tap,ONCE_OPABFR,&dr_in);
+                       LOG_DEBUG("%08X", dr_in);
+                       dsp563xx_once_reg_read(target->tap,ONCE_OPABDR,&dr_in);
+                       LOG_DEBUG("%08X", dr_in);
+                       dsp563xx_once_reg_read(target->tap,ONCE_OPABEX,&dr_in);
+                       LOG_DEBUG("%08X", dr_in);
+                       
+                       
+                       /* reset trace mode */
+                       dsp563xx_once_reg_write(target->tap,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 *buf32;
+       uint32_t i,x;
+       uint32_t data;
+       uint8_t *b;
+//     int retval;
+
+       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,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();
+}
diff --git a/src/target/dsp563xx.h b/src/target/dsp563xx.h
new file mode 100644
index 0000000..7ca8f03
--- /dev/null
+++ b/src/target/dsp563xx.h
@@ -0,0 +1,73 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Mathias Kuester                                 *
+ *   [email protected]                                          *
+ *                                                                         *
+ *   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.h"
+
+#define DSP563XX_NUMCOREREGS   42
+
+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;
+       uint32_t size;
+       uint32_t r_cmd;
+       struct target *target;
+       struct dsp563xx_common *dsp563xx_common;
+};
+
+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 0000000..5884dae
--- /dev/null
+++ b/src/target/dsp563xx_once.c
@@ -0,0 +1,116 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Mathias Kuester                                 *
+ *   [email protected]                                          *
+ *                                                                         *
+ *   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 "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,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,ONCE_OPDBR,0,0,0);
+       dsp563xx_write_dr_u32(tap,0,opcode,24,0);
+       dsp563xx_execute_queue();
+       
+       dsp563xx_once_ir_exec(tap,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,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,ONCE_OPDBR,0,0,0);
+       dsp563xx_write_dr_u32(tap,0,opcode,24,0);
+       
+       dsp563xx_once_ir_exec_nq(tap,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 0000000..5dbe01f
--- /dev/null
+++ b/src/target/dsp563xx_once.h
@@ -0,0 +1,71 @@
+/***************************************************************************
+ *   Copyright (C) 2009 by Mathias Kuester                                 *
+ *   [email protected]                                          *
+ *                                                                         *
+ *   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.h"
+
+#define ONCE_OCR_EX    (1<<5)
+#define ONCE_OCR_GO    (1<<6)
+#define ONCE_OCR_RW    (1<<7)
+
+#define ONCE_OSCR_OS1  (1<<7)
+#define ONCE_OSCR_OS0  (1<<6)
+#define ONCE_OSCR_HIT  (1<<5)
+#define ONCE_OSCR_TO   (1<<4)
+#define ONCE_OSCR_MBO  (1<<3)
+#define ONCE_OSCR_SWO  (1<<2)
+#define ONCE_OSCR_IME  (1<<1)
+#define ONCE_OSCR_TME  (1<<0)
+
+#define ONCE_OSCR      0x000
+#define ONCE_OMBC      0x001
+#define ONCE_OBCR      0x002
+#define ONCE_OMLR0     0x005
+#define ONCE_OMLR1     0x006
+#define ONCE_OGDBR     0x009
+#define ONCE_OPDBR     0x00A
+#define ONCE_OPILR     0x00B
+#define ONCE_PDBGOTO   0x00C
+#define ONCE_OTC       0x00D
+#define ONCE_TAGB      0x00E
+#define ONCE_OPABFR    0x00F
+#define ONCE_OPABDR    0x010
+#define ONCE_OPABEX    0x011
+#define ONCE_NOREG     0x01F
+
+/** 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 */
-- 1.6.5.4
_______________________________________________
Openocd-development mailing list
[email protected]
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to