+/// move.l r4,y
+#define core_move_r4_to_y(target) dsp5680xx_exe_generic(target,1,0xe764,0,0)
+
+/// move.w p:(r0)+,y0
+#define core_move_at_pr0_inc_to_y0(target) dsp5680xx_exe_generic(target,1,0x8568,0,0)
+
+/// move.w x:(r0)+,y0
+#define core_move_at_r0_inc_to_y0(target) dsp5680xx_exe_generic(target,1,0xf500,0,0)
+
+/// move x:(r0),y0
+#define core_move_at_r0_y0(target) dsp5680xx_exe_generic(target,1,0xF514,0,0)
+
+/// nop
+#define eonce_nop(target) dsp5680xx_exe_generic(target,1,0xe700,0,0)
+
+/// move.w x:(R2+<disp>),Y0
+#define core_move_at_r2_disp_to_y0(target,disp) dsp5680xx_exe_generic(target,2,0xF542,disp,0)
+
+/// move.w y1,x:(r2)
+#define core_move_y1_at_r2(target) dsp5680xx_exe_generic(target,1,0xd716,0,0)
+
+/// move.w y1,x:(r0)
+#define core_move_y1_at_r0(target) dsp5680xx_exe_generic(target,1,0xd714,0,0)
+
+/// move.bp y0,x:(r0)+
+#define core_move_byte_y0_at_r0(target) dsp5680xx_exe_generic(target,1,0xd5a0,0,0)
+
+/// move.w y1,p:(r0)+
+#define core_move_y1_at_pr0_inc(target) dsp5680xx_exe_generic(target,1,0x8760,0,0)
+
+/// move.w y1,x:(r0)+
+#define core_move_y1_at_r0_inc(target) dsp5680xx_exe_generic(target,1,0xD700,0,0)
+
+/// move.l #value,y
+#define core_move_long_to_y(target,value) dsp5680xx_exe_generic(target,3,0xe417,value&0xffff,value>>16)
+
+static int core_move_value_to_pc(struct target * target, uint32_t value){
+ if (!(target->state == TARGET_HALTED)){
+ LOG_ERROR("Target must be halted to move PC. Target state = %d.",target->state);
+ return ERROR_TARGET_NOT_HALTED;
+ };
+ int retval;
+ retval = dsp5680xx_exe_generic(target,3,0xE71E,value&0xffff,value>>16);
+ err_check_propagate(retval);
+ return retval;
+}
+
+static int eonce_load_TX_RX_to_r0(struct target * target)
+{
+ int retval;
+ retval = core_move_long_to_r0(target,((MC568013_EONCE_TX_RX_ADDR)+(MC568013_EONCE_OBASE_ADDR<<16)));
+ return retval;
+}
+
+static int core_load_TX_RX_high_addr_to_r0(struct target * target)
+{
+ int retval = 0;
+ retval = core_move_long_to_r0(target,((MC568013_EONCE_TX1_RX1_HIGH_ADDR)+(MC568013_EONCE_OBASE_ADDR<<16)));
+ return retval;
+}
+
+static int dsp5680xx_read_core_reg(struct target * target, uint8_t reg_addr, uint16_t * data_read)
+{
+ //TODO implement a general version of this which matches what openocd uses.
+ int retval;
+ uint32_t dummy_data_to_shift_into_dr;
+ retval = eonce_instruction_exec_single(target,reg_addr,1,0,0,NULL);
+ err_check_propagate(retval);
+ retval = dsp5680xx_drscan(target,(uint8_t *)& dummy_data_to_shift_into_dr,(uint8_t *) data_read, 8);
+ err_check_propagate(retval);
+ LOG_DEBUG("Reg. data: 0x%02X.",*data_read);
+ return retval;
+}
+
+static int eonce_read_status_reg(struct target * target, uint16_t * data){
+ int retval;
+ retval = dsp5680xx_read_core_reg(target,DSP5680XX_ONCE_OSR,data);
+ err_check_propagate(retval);
+ return retval;
+}
+
+/**
+ * Takes the core out of debug mode.
+ *
+ * @param target
+ * @param eonce_status Data read from the EOnCE status register.
+ *
+ * @return
+ */
+static int eonce_exit_debug_mode(struct target * target,uint8_t * eonce_status){
+ int retval;
+ retval = eonce_instruction_exec_single(target,0x1F,0,0,1,eonce_status);
+ err_check_propagate(retval);
+ return retval;
+}
+
+static int switch_tap(struct target * target, struct jtag_tap * master_tap,struct jtag_tap * core_tap){
+ int retval = ERROR_OK;
+ uint32_t instr;
+ uint32_t ir_out;//not used, just to make jtag happy.
+ if(master_tap == NULL){
+ master_tap = jtag_tap_by_string("dsp568013.chp");
+ if(master_tap == NULL){
+ retval = ERROR_FAIL;
+ err_check(retval,"Failed to get master tap.");
+ }
+ }
+ if(core_tap == NULL){
+ core_tap = jtag_tap_by_string("dsp568013.cpu");
+ if(core_tap == NULL){
+ retval = ERROR_FAIL;
+ err_check(retval,"Failed to get core tap.");
+ }
+ }
+
+ if(!(((int)master_tap->enabled) ^ ((int)core_tap->enabled))){
+ LOG_WARNING("Wrong tap enabled/disabled status:\nMaster tap:%d\nCore Tap:%d\nOnly one tap should be enabled at a given time.\n",(int)master_tap->enabled,(int)core_tap->enabled);
+ }
+
+ if(master_tap->enabled){
+ instr = 0x5;
+ retval = dsp5680xx_irscan(target, & instr, & ir_out,DSP5680XX_JTAG_MASTER_TAP_IRLEN);
+ err_check_propagate(retval);
+ instr = 0x2;
+ retval = dsp5680xx_drscan(target,(uint8_t *) & instr,(uint8_t *) & ir_out,4);
+ err_check_propagate(retval);
+ core_tap->enabled = true;
+ master_tap->enabled = false;
+ }else{
+ instr = 0x08;
+ retval = dsp5680xx_irscan(target, & instr, & ir_out,DSP5680XX_JTAG_CORE_TAP_IRLEN);
+ err_check_propagate(retval);
+ instr = 0x1;
+ retval = dsp5680xx_drscan(target,(uint8_t *) & instr,(uint8_t *) & ir_out,4);
+ err_check_propagate(retval);
+ core_tap->enabled = false;
+ master_tap->enabled = true;
+ }
+ return retval;
+}
+
+/**
+ * Puts the core into debug mode, enabling the EOnCE module.
+ * This will not always work, eonce_enter_debug_mode executes much
+ * more complicated routine, which is guaranteed to work, but requires
+ * a reset. This will complicate comm with the flash module, since
+ * after a reset clock divisors must be set again.
+ * This implementation works most of the time, and is not accesible to the
+ * user.
+ *
+ * @param target
+ * @param eonce_status Data read from the EOnCE status register.
+ *
+ * @return
+ */
+static int eonce_enter_debug_mode_without_reset(struct target * target, uint16_t * eonce_status){
+ int retval;
+ uint32_t instr = JTAG_INSTR_DEBUG_REQUEST;
+ uint32_t ir_out;//not used, just to make jtag happy.
+ // Debug request #1
+ retval = dsp5680xx_irscan(target,& instr,& ir_out,DSP5680XX_JTAG_CORE_TAP_IRLEN);
+ err_check_propagate(retval);