X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Ftarget%2Fdsp5680xx.c;h=a50f2cd4746b7b95169a60e296ee1437f77ae01a;hp=5b38f272605c474fa3e5d8d9b1def510e8b83cbf;hb=7a3eec2b4d9dbb9533acfb271dbe91afa0727c8e;hpb=c725167ba8e2aa9e43bc86e28b44b6cb444740a8 diff --git a/src/target/dsp5680xx.c b/src/target/dsp5680xx.c index 5b38f27260..a50f2cd474 100644 --- a/src/target/dsp5680xx.c +++ b/src/target/dsp5680xx.c @@ -1,25 +1,24 @@ /*************************************************************************** - * Copyright (C) 2011 by Rodrigo L. Rosa * - * rodrigorosa.LG@gmail.com * - * * - * Based on dsp563xx_once.h written 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. * + * Copyright (C) 2011 by Rodrigo L. Rosa * + * rodrigorosa.LG@gmail.com * + * * + * Based on dsp563xx_once.h written 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, see . * ***************************************************************************/ + #ifdef HAVE_CONFIG_H #include "config.h" #endif @@ -41,19 +40,25 @@ struct dsp5680xx_common dsp5680xx_context; #define CHECK_HALT(target) if (target->state != TARGET_HALTED) HALT_FAIL #define check_halt_and_debug(target) { CHECK_HALT(target); CHECK_DBG; } -int dsp5680xx_execute_queue(void){ - int retval; - retval = jtag_execute_queue(); - return retval; +int dsp5680xx_execute_queue(void) +{ + int retval; + + retval = jtag_execute_queue(); + return retval; } /** * Reset state machine */ -static int reset_jtag(void){ +static int reset_jtag(void) +{ int retval; + tap_state_t states[2]; + const char *cp = "RESET"; + states[0] = tap_state_by_name(cp); retval = jtag_add_statemove(states[0]); err_check_propagate(retval); @@ -64,117 +69,151 @@ static int reset_jtag(void){ return retval; } -static int dsp5680xx_drscan(struct target *target, uint8_t *d_in, uint8_t *d_out, int len) +static int dsp5680xx_drscan(struct target *target, uint8_t *d_in, + uint8_t *d_out, int len) { -/** -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -* -* Inputs: -* - d_in: This is the data that will be shifted into the JTAG DR reg. -* - d_out: The data that will be shifted out of the JTAG DR reg will stored here -* - len: Length of the data to be shifted to JTAG DR. -* -* Note: If d_out == NULL, discard incoming bits. -* -* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -*/ - int retval = ERROR_OK; -if (NULL == target->tap) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_INVALID_TAP, "Invalid tap"); -} - if (len > 32){ - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_DR_LEN_OVERFLOW, "dr_len overflow, maxium is 32"); - } - //TODO what values of len are valid for jtag_add_plain_dr_scan? - //can i send as many bits as i want? - //is the casting necessary? -jtag_add_plain_dr_scan(len, d_in, d_out, TAP_IDLE); - if(dsp5680xx_context.flush){ - retval = dsp5680xx_execute_queue(); - err_check(retval, DSP5680XX_ERROR_JTAG_DRSCAN, "drscan failed!"); - } -if (d_out != NULL) - LOG_DEBUG("Data read (%d bits): 0x%04X", len, *d_out); -else - LOG_DEBUG("Data read was discarded."); + /* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + * + *Inputs: + * - d_in: This is the data that will be shifted into the JTAG DR reg. + * - d_out: The data that will be shifted out of the JTAG DR reg will stored here + * - len: Length of the data to be shifted to JTAG DR. + * + *Note: If d_out == NULL, discard incoming bits. + * + *-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- + */ + int retval = ERROR_OK; + + if (NULL == target->tap) { + retval = ERROR_FAIL; + err_check(retval, DSP5680XX_ERROR_JTAG_INVALID_TAP, + "Invalid tap"); + } + if (len > 32) { + retval = ERROR_FAIL; + err_check(retval, DSP5680XX_ERROR_JTAG_DR_LEN_OVERFLOW, + "dr_len overflow, maxium is 32"); + } + /* TODO what values of len are valid for jtag_add_plain_dr_scan? */ + /* can i send as many bits as i want? */ + /* is the casting necessary? */ + jtag_add_plain_dr_scan(len, d_in, d_out, TAP_IDLE); + if (dsp5680xx_context.flush) { + retval = dsp5680xx_execute_queue(); + err_check(retval, DSP5680XX_ERROR_JTAG_DRSCAN, + "drscan failed!"); + } + if (d_out != NULL) + LOG_DEBUG("Data read (%d bits): 0x%04X", len, *d_out); + else + LOG_DEBUG("Data read was discarded."); return retval; } -/** -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -* Inputs: -* - data_to_shift_into_ir: This is the data that will be shifted into the JTAG IR reg. -* - data_shifted_out_of_ir: The data that will be shifted out of the JTAG IR reg will be -* stored here -* - len: Length of the data to be shifted to JTAG IR. -* -* -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -*/ -static int dsp5680xx_irscan(struct target *target, uint32_t *d_in, uint32_t *d_out, uint8_t ir_len) +/** + * Test func + * + * @param target + * @param d_in This is the data that will be shifted into the JTAG IR reg. + * @param d_out The data that will be shifted out of the JTAG IR reg will be stored here. + * @apram ir_len Length of the data to be shifted to JTAG IR. + * + */ +static int dsp5680xx_irscan(struct target *target, uint32_t *d_in, + uint32_t *d_out, uint8_t ir_len) { int retval = ERROR_OK; + uint16_t tap_ir_len = DSP5680XX_JTAG_MASTER_TAP_IRLEN; + if (NULL == target->tap) { retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_INVALID_TAP, "Invalid tap"); + err_check(retval, DSP5680XX_ERROR_JTAG_INVALID_TAP, + "Invalid tap"); } if (ir_len != target->tap->ir_length) { if (target->tap->enabled) { retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_INVALID_IR_LEN, "Invalid irlen"); + err_check(retval, DSP5680XX_ERROR_INVALID_IR_LEN, + "Invalid irlen"); } else { - struct jtag_tap *t = jtag_tap_by_string("dsp568013.chp"); - if ((t == NULL) || ((t->enabled) && (ir_len != tap_ir_len))) { + struct jtag_tap *t = + jtag_tap_by_string("dsp568013.chp"); + if ((t == NULL) + || ((t->enabled) && (ir_len != tap_ir_len))) { retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_INVALID_IR_LEN, "Invalid irlen"); + err_check(retval, + DSP5680XX_ERROR_INVALID_IR_LEN, + "Invalid irlen"); } } } - jtag_add_plain_ir_scan(ir_len, (uint8_t *)d_in, (uint8_t *)d_out, TAP_IDLE); + jtag_add_plain_ir_scan(ir_len, (uint8_t *) d_in, (uint8_t *) d_out, + TAP_IDLE); if (dsp5680xx_context.flush) { retval = dsp5680xx_execute_queue(); - err_check(retval, DSP5680XX_ERROR_JTAG_IRSCAN, "irscan failed!"); + err_check(retval, DSP5680XX_ERROR_JTAG_IRSCAN, + "irscan failed!"); } return retval; } -static int dsp5680xx_jtag_status(struct target *target, uint8_t * status){ - uint32_t read_from_ir; - uint32_t instr; - int retval; - instr = JTAG_INSTR_ENABLE_ONCE; - retval = dsp5680xx_irscan(target, &instr, &read_from_ir, DSP5680XX_JTAG_CORE_TAP_IRLEN); - err_check_propagate(retval); - if(status!=NULL) - *status = (uint8_t)read_from_ir; - return ERROR_OK; +static int dsp5680xx_jtag_status(struct target *target, uint8_t *status) +{ + uint32_t read_from_ir; + + uint32_t instr; + + int retval; + + instr = JTAG_INSTR_ENABLE_ONCE; + retval = + dsp5680xx_irscan(target, &instr, &read_from_ir, + DSP5680XX_JTAG_CORE_TAP_IRLEN); + err_check_propagate(retval); + if (status != NULL) + *status = (uint8_t) read_from_ir; + return ERROR_OK; } -static int jtag_data_read(struct target * target, uint8_t * data_read, int num_bits){ - uint32_t bogus_instr = 0; - int retval = dsp5680xx_drscan(target,(uint8_t *) & bogus_instr,data_read,num_bits); - LOG_DEBUG("Data read (%d bits): 0x%04X",num_bits,*data_read);//TODO remove this or move to jtagio? - return retval; +static int jtag_data_read(struct target *target, uint8_t *data_read, + int num_bits) +{ + uint32_t bogus_instr = 0; + + int retval = + dsp5680xx_drscan(target, (uint8_t *) &bogus_instr, data_read, + num_bits); + LOG_DEBUG("Data read (%d bits): 0x%04X", num_bits, *data_read); + /** TODO remove this or move to jtagio? */ + return retval; } -#define jtag_data_read8(target,data_read) jtag_data_read(target,data_read,8) -#define jtag_data_read16(target,data_read) jtag_data_read(target,data_read,16) -#define jtag_data_read32(target,data_read) jtag_data_read(target,data_read,32) +#define jtag_data_read8(target, data_read) jtag_data_read(target, data_read, 8) +#define jtag_data_read16(target, data_read) jtag_data_read(target, data_read, 16) +#define jtag_data_read32(target, data_read) jtag_data_read(target, data_read, 32) static uint32_t data_read_dummy; -static int jtag_data_write(struct target * target, uint32_t instr,int num_bits, uint32_t * data_read){ - int retval; - retval = dsp5680xx_drscan(target,(uint8_t *) & instr,(uint8_t *) & data_read_dummy,num_bits); - err_check_propagate(retval); - if(data_read != NULL) - *data_read = data_read_dummy; - return retval; + +static int jtag_data_write(struct target *target, uint32_t instr, int num_bits, + uint32_t *data_read) +{ + int retval; + + retval = + dsp5680xx_drscan(target, (uint8_t *) &instr, + (uint8_t *) &data_read_dummy, num_bits); + err_check_propagate(retval); + if (data_read != NULL) + *data_read = data_read_dummy; + return retval; } -#define jtag_data_write8(target,instr,data_read) jtag_data_write(target,instr,8,data_read) -#define jtag_data_write16(target,instr,data_read) jtag_data_write(target,instr,16,data_read) -#define jtag_data_write24(target,instr,data_read) jtag_data_write(target,instr,24,data_read) -#define jtag_data_write32(target,instr,data_read) jtag_data_write(target,instr,32,data_read) +#define jtag_data_write8(target, instr, data_read) jtag_data_write(target, instr, 8, data_read) +#define jtag_data_write16(target, instr, data_read) jtag_data_write(target, instr, 16, data_read) +#define jtag_data_write24(target, instr, data_read) jtag_data_write(target, instr, 24, data_read) +#define jtag_data_write32(target, instr, data_read) jtag_data_write(target, instr, 32, data_read) /** * Executes EOnCE instruction. @@ -188,87 +227,110 @@ static int jtag_data_write(struct target * target, uint32_t instr,int num_bits, * * @return */ -static int eonce_instruction_exec_single(struct target * target, uint8_t instr, uint8_t rw, uint8_t go, uint8_t ex,uint8_t * eonce_status){ - int retval; - uint32_t dr_out_tmp; - uint8_t instr_with_flags = instr|(rw<<7)|(go<<6)|(ex<<5); +static int eonce_instruction_exec_single(struct target *target, uint8_t instr, + uint8_t rw, uint8_t go, uint8_t ex, + uint8_t *eonce_status) +{ + int retval; + + uint32_t dr_out_tmp; + + uint8_t instr_with_flags = instr | (rw << 7) | (go << 6) | (ex << 5); + retval = jtag_data_write(target, instr_with_flags, 8, &dr_out_tmp); - err_check_propagate(retval); - if(eonce_status != NULL) - *eonce_status = (uint8_t) dr_out_tmp; - return retval; + err_check_propagate(retval); + if (eonce_status != NULL) + *eonce_status = (uint8_t) dr_out_tmp; + return retval; } -///wrappers for multi opcode instructions -#define dsp5680xx_exe_1(target,opcode1,opcode2,opcode3) dsp5680xx_exe1(target,opcode1) -#define dsp5680xx_exe_2(target,opcode1,opcode2,opcode3) dsp5680xx_exe2(target,opcode1,opcode2) -#define dsp5680xx_exe_3(target,opcode1,opcode2,opcode3) dsp5680xx_exe3(target,opcode1,opcode2,opcode3) -#define dsp5680xx_exe_generic(target,words,opcode1,opcode2,opcode3) dsp5680xx_exe_##words(target,opcode1,opcode2,opcode3) - -/// Executes one word DSP instruction -static int dsp5680xx_exe1(struct target * target, uint16_t opcode){ - int retval; - retval = eonce_instruction_exec_single(target,0x04,0,1,0,NULL); - err_check_propagate(retval); - retval = jtag_data_write16(target,opcode,NULL); - err_check_propagate(retval); - return retval; +/* wrappers for multi opcode instructions */ +#define dsp5680xx_exe_1(target, oc1, oc2, oc3) dsp5680xx_exe1(target, oc1) +#define dsp5680xx_exe_2(target, oc1, oc2, oc3) dsp5680xx_exe2(target, oc1, oc2) +#define dsp5680xx_exe_3(target, oc1, oc2, oc3) dsp5680xx_exe3(target, oc1, oc2, oc3) +#define dsp5680xx_exe_generic(t, words, oc1, oc2, oc3) dsp5680xx_exe_##words(t, oc1, oc2, oc3) + +/* Executes one word DSP instruction */ +static int dsp5680xx_exe1(struct target *target, uint16_t opcode) +{ + int retval; + + retval = eonce_instruction_exec_single(target, 0x04, 0, 1, 0, NULL); + err_check_propagate(retval); + retval = jtag_data_write16(target, opcode, NULL); + err_check_propagate(retval); + return retval; } -/// Executes two word DSP instruction -static int dsp5680xx_exe2(struct target * target,uint16_t opcode1, uint16_t opcode2){ - int retval; - retval = eonce_instruction_exec_single(target,0x04,0,0,0,NULL); - err_check_propagate(retval); - retval = jtag_data_write16(target,opcode1,NULL); - err_check_propagate(retval); - retval = eonce_instruction_exec_single(target,0x04,0,1,0,NULL); - err_check_propagate(retval); - retval = jtag_data_write16(target,opcode2,NULL); - err_check_propagate(retval); - return retval; +/* Executes two word DSP instruction */ +static int dsp5680xx_exe2(struct target *target, uint16_t opcode1, + uint16_t opcode2) +{ + int retval; + + retval = eonce_instruction_exec_single(target, 0x04, 0, 0, 0, NULL); + err_check_propagate(retval); + retval = jtag_data_write16(target, opcode1, NULL); + err_check_propagate(retval); + retval = eonce_instruction_exec_single(target, 0x04, 0, 1, 0, NULL); + err_check_propagate(retval); + retval = jtag_data_write16(target, opcode2, NULL); + err_check_propagate(retval); + return retval; } -/// Executes three word DSP instruction -static int dsp5680xx_exe3(struct target * target, uint16_t opcode1,uint16_t opcode2,uint16_t opcode3){ - int retval; - retval = eonce_instruction_exec_single(target,0x04,0,0,0,NULL); - err_check_propagate(retval); - retval = jtag_data_write16(target,opcode1,NULL); - err_check_propagate(retval); - retval = eonce_instruction_exec_single(target,0x04,0,0,0,NULL); - err_check_propagate(retval); - retval = jtag_data_write16(target,opcode2,NULL); - err_check_propagate(retval); - retval = eonce_instruction_exec_single(target,0x04,0,1,0,NULL); - err_check_propagate(retval); - retval = jtag_data_write16(target,opcode3,NULL); - err_check_propagate(retval); - return retval; +/* Executes three word DSP instruction */ +static int dsp5680xx_exe3(struct target *target, uint16_t opcode1, + uint16_t opcode2, uint16_t opcode3) +{ + int retval; + + retval = eonce_instruction_exec_single(target, 0x04, 0, 0, 0, NULL); + err_check_propagate(retval); + retval = jtag_data_write16(target, opcode1, NULL); + err_check_propagate(retval); + retval = eonce_instruction_exec_single(target, 0x04, 0, 0, 0, NULL); + err_check_propagate(retval); + retval = jtag_data_write16(target, opcode2, NULL); + err_check_propagate(retval); + retval = eonce_instruction_exec_single(target, 0x04, 0, 1, 0, NULL); + err_check_propagate(retval); + retval = jtag_data_write16(target, opcode3, NULL); + err_check_propagate(retval); + return retval; } -/** - * --------------- Real-time data exchange --------------- - * The EOnCE Transmit (OTX) and Receive (ORX) registers are data memory mapped, each with an upper and lower 16 bit word. +/* + *--------------- Real-time data exchange --------------- + * The EOnCE Transmit (OTX) and Receive (ORX) registers are data memory mapped, each with an upper + * and lower 16 bit word. * Transmit and receive directions are defined from the core’s perspective. - * The core writes to the Transmit register and reads the Receive register, and the host through JTAG writes to the Receive register and reads the Transmit register. - * Both registers have a combined data memory mapped OTXRXSR which provides indication when each may be accessed. - *ref: eonce_rev.1.0_0208081.pdf@36 -*/ - -/// writes data into upper ORx register of the target -static int core_tx_upper_data(struct target * target, uint16_t data, uint32_t * eonce_status_low){ - int retval; - retval = eonce_instruction_exec_single(target,DSP5680XX_ONCE_ORX1,0,0,0,NULL); - err_check_propagate(retval); - retval = jtag_data_write16(target,data,eonce_status_low); - err_check_propagate(retval); - return retval; + * The core writes to the Transmit register and reads the Receive register, and the host through + * JTAG writes to the Receive register and reads the Transmit register. + * Both registers have a combined data memory mapped OTXRXSR which provides indication when + * each may be accessed. + * ref: eonce_rev.1.0_0208081.pdf@36 + */ + +/* writes data into upper ORx register of the target */ +static int core_tx_upper_data(struct target *target, uint16_t data, + uint32_t *eonce_status_low) +{ + int retval; + + retval = + eonce_instruction_exec_single(target, DSP5680XX_ONCE_ORX1, 0, 0, 0, + NULL); + err_check_propagate(retval); + retval = jtag_data_write16(target, data, eonce_status_low); + err_check_propagate(retval); + return retval; } -/// writes data into lower ORx register of the target -#define core_tx_lower_data(target,data) eonce_instruction_exec_single(target,DSP5680XX_ONCE_ORX,0,0,0,NULL);\ - jtag_data_write16(target,data) +/* writes data into lower ORx register of the target */ +#define CMD1 eonce_instruction_exec_single(target, DSP5680XX_ONCE_ORX, 0, 0, 0, NULL); +#define CMD2 jtag_data_write16((t, data) +#define core_tx_lower_data(t, data) PT1\ PT2 /** * @@ -276,14 +338,17 @@ static int core_tx_upper_data(struct target * target, uint16_t data, uint32_t * * @param data_read: Returns the data read from the upper OTX register via JTAG. * @return: Returns an error code (see error code documentation) */ -static int core_rx_upper_data(struct target * target, uint8_t * data_read) +static int core_rx_upper_data(struct target *target, uint8_t *data_read) { - int retval; - retval = eonce_instruction_exec_single(target,DSP5680XX_ONCE_OTX1,1,0,0,NULL); - err_check_propagate(retval); - retval = jtag_data_read16(target,data_read); - err_check_propagate(retval); - return retval; + int retval; + + retval = + eonce_instruction_exec_single(target, DSP5680XX_ONCE_OTX1, 1, 0, 0, + NULL); + err_check_propagate(retval); + retval = jtag_data_read16(target, data_read); + err_check_propagate(retval); + return retval; } /** @@ -292,173 +357,197 @@ static int core_rx_upper_data(struct target * target, uint8_t * data_read) * @param data_read: Returns the data read from the lower OTX register via JTAG. * @return: Returns an error code (see error code documentation) */ -static int core_rx_lower_data(struct target * target,uint8_t * data_read) +static int core_rx_lower_data(struct target *target, uint8_t *data_read) { - int retval; - retval = eonce_instruction_exec_single(target,DSP5680XX_ONCE_OTX,1,0,0,NULL); - err_check_propagate(retval); - retval = jtag_data_read16(target,data_read); - err_check_propagate(retval); - return retval; + int retval; + + retval = + eonce_instruction_exec_single(target, DSP5680XX_ONCE_OTX, 1, 0, 0, + NULL); + err_check_propagate(retval); + retval = jtag_data_read16(target, data_read); + err_check_propagate(retval); + return retval; } -/** - * -- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- - * -- -- -- -- --- -- -- -Core Instructions- -- -- -- --- -- -- -- --- -- - * -- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- +/* + *-- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- + *-- -- -- -- --- -- -- -Core Instructions- -- -- -- --- -- -- -- --- -- + *-- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- */ -/// move.l #value,r0 -#define core_move_long_to_r0(target,value) dsp5680xx_exe_generic(target,3,0xe418,value&0xffff,value>>16) +#define exe(a, b, c, d, e) dsp5680xx_exe_generic(a, b, c, d, e) -/// move.l #value,n -#define core_move_long_to_n(target,value) dsp5680xx_exe_generic(target,3,0xe41e,value&0xffff,value>>16) +/* move.l #value, r0 */ +#define core_move_long_to_r0(target, value) exe(target, 3, 0xe418, value&0xffff, value>>16) -/// move x:(r0),y0 -#define core_move_at_r0_to_y0(target) dsp5680xx_exe_generic(target,1,0xF514,0,0) +/* move.l #value, n */ +#define core_move_long_to_n(target, value) exe(target, 3, 0xe41e, value&0xffff, value>>16) -/// move x:(r0),y1 -#define core_move_at_r0_to_y1(target) dsp5680xx_exe_generic(target,1,0xF714,0,0) +/* move x:(r0), y0 */ +#define core_move_at_r0_to_y0(target) exe(target, 1, 0xF514, 0, 0) -/// move.l x:(r0),y -#define core_move_long_at_r0_y(target) dsp5680xx_exe_generic(target,1,0xF734,0,0) +/* move x:(r0), y1 */ +#define core_move_at_r0_to_y1(target) exe(target, 1, 0xF714, 0, 0) -/// move y0,x:(r0) -#define core_move_y0_at_r0(target) dsp5680xx_exe_generic(target,1,0xd514,0,0) +/* move.l x:(r0), y */ +#define core_move_long_at_r0_y(target) exe(target, 1, 0xF734, 0, 0) -/// bfclr #value,x:(r0) -#define eonce_bfclr_at_r0(target,value) dsp5680xx_exe_generic(target,2,0x8040,value,0) +/* move y0, x:(r0) */ +#define core_move_y0_at_r0(target) exe(target, 1, 0xd514, 0, 0) -/// move #value,y0 -#define core_move_value_to_y0(target,value) dsp5680xx_exe_generic(target,2,0x8745,value,0) +/* bfclr #value, x:(r0) */ +#define eonce_bfclr_at_r0(target, value) exe(target, 2, 0x8040, value, 0) -/// move.w y0,x:(r0)+ -#define core_move_y0_at_r0_inc(target) dsp5680xx_exe_generic(target,1,0xd500,0,0) +/* move #value, y0 */ +#define core_move_value_to_y0(target, value) exe(target, 2, 0x8745, value, 0) -/// move.w y0,p:(r0)+ -#define core_move_y0_at_pr0_inc(target) dsp5680xx_exe_generic(target,1,0x8560,0,0) +/* move.w y0, x:(r0)+ */ +#define core_move_y0_at_r0_inc(target) exe(target, 1, 0xd500, 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 y0, p:(r0)+ */ +#define core_move_y0_at_pr0_inc(target) exe(target, 1, 0x8560, 0, 0) -/// move.w p:(r0)+,y1 -#define core_move_at_pr0_inc_to_y1(target) dsp5680xx_exe_generic(target,1,0x8768,0,0) +/* move.w p:(r0)+, y0 */ +#define core_move_at_pr0_inc_to_y0(target) exe(target, 1, 0x8568, 0, 0) -/// move.l #value,r2 -#define core_move_long_to_r2(target,value) dsp5680xx_exe_generic(target,3,0xe41A,value&0xffff,value>>16) +/* move.w p:(r0)+, y1 */ +#define core_move_at_pr0_inc_to_y1(target) exe(target, 1, 0x8768, 0, 0) -/// move y0,x:(r2) -#define core_move_y0_at_r2(target) dsp5680xx_exe_generic(target,1,0xd516,0,0) +/* move.l #value, r2 */ +#define core_move_long_to_r2(target, value) exe(target, 3, 0xe41A, value&0xffff, value>>16) -/// move.w #,x:(r2) -#define core_move_value_at_r2(target,value) dsp5680xx_exe_generic(target,2,0x8642,value,0) +/* move y0, x:(r2) */ +#define core_move_y0_at_r2(target) exe(target, 1, 0xd516, 0, 0) -/// move.w #,x:(r0) -#define core_move_value_at_r0(target,value) dsp5680xx_exe_generic(target,2,0x8640,value,0) +/* move.w #, x:(r2) */ +#define core_move_value_at_r2(target, value) exe(target, 2, 0x8642, value, 0) -/// move.w #,x:(R2+) -#define core_move_value_at_r2_disp(target,value,disp) dsp5680xx_exe_generic(target,3,0x8646,value,disp) +/* move.w #, x:(r0) */ +#define core_move_value_at_r0(target, value) exe(target, 2, 0x8640, value, 0) -/// move.w x:(r2),Y0 -#define core_move_at_r2_to_y0(target) dsp5680xx_exe_generic(target,1,0xF516,0,0) +/* move.w #, x:(R2+) */ +#define core_move_value_at_r2_disp(target, value, disp) exe(target, 3, 0x8646, value, disp) -/// move.w p:(r2)+,y0 -#define core_move_at_pr2_inc_to_y0(target) dsp5680xx_exe_generic(target,1,0x856A,0,0) +/* move.w x:(r2), Y0 */ +#define core_move_at_r2_to_y0(target) exe(target, 1, 0xF516, 0, 0) -/// move.l #value,r3 -#define core_move_long_to_r1(target,value) dsp5680xx_exe_generic(target,3,0xE419,value&0xffff,value>>16) +/* move.w p:(r2)+, y0 */ +#define core_move_at_pr2_inc_to_y0(target) exe(target, 1, 0x856A, 0, 0) -/// move.l #value,r3 -#define core_move_long_to_r3(target,value) dsp5680xx_exe_generic(target,3,0xE41B,value&0xffff,value>>16) +/* move.l #value, r3 */ +#define core_move_long_to_r1(target, value) exe(target, 3, 0xE419, value&0xffff, value>>16) -/// move.w y0,p:(r3)+ -#define core_move_y0_at_pr3_inc(target) dsp5680xx_exe_generic(target,1,0x8563,0,0) +/* move.l #value, r3 */ +#define core_move_long_to_r3(target, value) exe(target, 3, 0xE41B, value&0xffff, value>>16) -/// move.w y0,x:(r3) -#define core_move_y0_at_r3(target) dsp5680xx_exe_generic(target,1,0xD503,0,0) +/* move.w y0, p:(r3)+ */ +#define core_move_y0_at_pr3_inc(target) exe(target, 1, 0x8563, 0, 0) -/// move.l #value,r4 -#define core_move_long_to_r4(target,value) dsp5680xx_exe_generic(target,3,0xE41C,value&0xffff,value>>16) +/* move.w y0, x:(r3) */ +#define core_move_y0_at_r3(target) exe(target, 1, 0xD503, 0, 0) -/// move pc,r4 -#define core_move_pc_to_r4(target) dsp5680xx_exe_generic(target,1,0xE716,0,0) +/* move.l #value, r4 */ +#define core_move_long_to_r4(target, value) exe(target, 3, 0xE41C, value&0xffff, value>>16) -/// move.l r4,y -#define core_move_r4_to_y(target) dsp5680xx_exe_generic(target,1,0xe764,0,0) +/* move pc, r4 */ +#define core_move_pc_to_r4(target) exe(target, 1, 0xE716, 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.l r4, y */ +#define core_move_r4_to_y(target) exe(target, 1, 0xe764, 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.w p:(r0)+, y0 */ +#define core_move_at_pr0_inc_to_y0(target) exe(target, 1, 0x8568, 0, 0) -/// move x:(r0),y0 -#define core_move_at_r0_y0(target) dsp5680xx_exe_generic(target,1,0xF514,0,0) +/* move.w x:(r0)+, y0 */ +#define core_move_at_r0_inc_to_y0(target) exe(target, 1, 0xf500, 0, 0) -/// nop -#define eonce_nop(target) dsp5680xx_exe_generic(target,1,0xe700,0,0) +/* move x:(r0), y0 */ +#define core_move_at_r0_y0(target) exe(target, 1, 0xF514, 0, 0) -/// move.w x:(R2+),Y0 -#define core_move_at_r2_disp_to_y0(target,disp) dsp5680xx_exe_generic(target,2,0xF542,disp,0) +/* nop */ +#define eonce_nop(target) exe(target, 1, 0xe700, 0, 0) -/// move.w y1,x:(r2) -#define core_move_y1_at_r2(target) dsp5680xx_exe_generic(target,1,0xd716,0,0) +/* move.w x:(R2+), Y0 */ +#define core_move_at_r2_disp_to_y0(target, disp) exe(target, 2, 0xF542, disp, 0) -/// move.w y1,x:(r0) -#define core_move_y1_at_r0(target) dsp5680xx_exe_generic(target,1,0xd714,0,0) +/* move.w y1, x:(r2) */ +#define core_move_y1_at_r2(target) exe(target, 1, 0xd716, 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, x:(r0) */ +#define core_move_y1_at_r0(target) exe(target, 1, 0xd714, 0, 0) -/// move.w y1,p:(r0)+ -#define core_move_y1_at_pr0_inc(target) dsp5680xx_exe_generic(target,1,0x8760,0,0) +/* move.bp y0, x:(r0)+ */ +#define core_move_byte_y0_at_r0(target) exe(target, 1, 0xd5a0, 0, 0) -/// move.w y1,x:(r0)+ -#define core_move_y1_at_r0_inc(target) dsp5680xx_exe_generic(target,1,0xD700,0,0) +/* move.w y1, p:(r0)+ */ +#define core_move_y1_at_pr0_inc(target) exe(target, 1, 0x8760, 0, 0) -/// move.l #value,y -#define core_move_long_to_y(target,value) dsp5680xx_exe_generic(target,3,0xe417,value&0xffff,value>>16) +/* move.w y1, x:(r0)+ */ +#define core_move_y1_at_r0_inc(target) exe(target, 1, 0xD700, 0, 0) -static int core_move_value_to_pc(struct target * target, uint32_t value){ +/* move.l #value, y */ +#define core_move_long_to_y(target, value) exe(target, 3, 0xe417, value&0xffff, value>>16) + +static int core_move_value_to_pc(struct target *target, uint32_t value) +{ check_halt_and_debug(target); - int retval; - retval = dsp5680xx_exe_generic(target,3,0xE71E,value&0xffff,value>>16); - err_check_propagate(retval); - return retval; + 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) +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; + 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) +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; + 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) +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; + /* 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; +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; } /** @@ -469,57 +558,78 @@ static int eonce_read_status_reg(struct target * target, uint16_t * data){ * * @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 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"); +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) { - retval = ERROR_FAIL; - const char *msg = "Failed to get master tap."; - err_check(retval, DSP5680XX_ERROR_JTAG_TAP_FIND_MASTER, msg); + master_tap = jtag_tap_by_string("dsp568013.chp"); + if (master_tap == NULL) { + retval = ERROR_FAIL; + const char *msg = "Failed to get master tap."; + + err_check(retval, DSP5680XX_ERROR_JTAG_TAP_FIND_MASTER, + msg); + } } -} -if (core_tap == NULL) { - core_tap = jtag_tap_by_string("dsp568013.cpu"); if (core_tap == NULL) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_TAP_FIND_CORE, "Failed to get core tap."); + core_tap = jtag_tap_by_string("dsp568013.cpu"); + if (core_tap == NULL) { + retval = ERROR_FAIL; + err_check(retval, DSP5680XX_ERROR_JTAG_TAP_FIND_CORE, + "Failed to get core tap."); + } + } + + if (!(((int)master_tap->enabled) ^ ((int)core_tap->enabled))) { + LOG_WARNING + ("Master:%d\nCore:%d\nOnly 1 should be enabled.\n", + (int)master_tap->enabled, (int)core_tap->enabled); } -} - 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; + 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; + 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; } /** @@ -536,46 +646,58 @@ if (core_tap == NULL) { * * @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); - - // Enable EOnCE module - instr = JTAG_INSTR_ENABLE_ONCE; - //Two rounds of jtag 0x6 (enable eonce) to enable EOnCE. - retval = dsp5680xx_irscan(target, & instr, & ir_out,DSP5680XX_JTAG_CORE_TAP_IRLEN); - err_check_propagate(retval); - retval = dsp5680xx_irscan(target, & instr, & ir_out,DSP5680XX_JTAG_CORE_TAP_IRLEN); - err_check_propagate(retval); -if ((ir_out&JTAG_STATUS_MASK) == JTAG_STATUS_DEBUG) - target->state = TARGET_HALTED; -else{ - retval = ERROR_FAIL; +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); -} - // Verify that debug mode is enabled - uint16_t data_read_from_dr; + + /* Enable EOnCE module */ + instr = JTAG_INSTR_ENABLE_ONCE; + /* Two rounds of jtag 0x6 (enable eonce) to enable EOnCE. */ + retval = + dsp5680xx_irscan(target, &instr, &ir_out, + DSP5680XX_JTAG_CORE_TAP_IRLEN); + err_check_propagate(retval); + retval = + dsp5680xx_irscan(target, &instr, &ir_out, + DSP5680XX_JTAG_CORE_TAP_IRLEN); + err_check_propagate(retval); + if ((ir_out & JTAG_STATUS_MASK) == JTAG_STATUS_DEBUG) + target->state = TARGET_HALTED; + else { + retval = ERROR_FAIL; + err_check_propagate(retval); + } + /* Verify that debug mode is enabled */ + uint16_t data_read_from_dr; + retval = eonce_read_status_reg(target, &data_read_from_dr); err_check_propagate(retval); - if ((data_read_from_dr&0x30) == 0x30) { + if ((data_read_from_dr & 0x30) == 0x30) { LOG_DEBUG("EOnCE successfully entered debug mode."); dsp5680xx_context.debug_mode_enabled = true; retval = ERROR_OK; } else { dsp5680xx_context.debug_mode_enabled = false; retval = ERROR_TARGET_FAILURE; - /** - * No error msg here, since there is still hope with full halting sequence - */ - err_check_propagate(retval); + /** + *No error msg here, since there is still hope with full halting sequence + */ + err_check_propagate(retval); } -if (eonce_status != NULL) - *eonce_status = data_read_from_dr; -return retval; + if (eonce_status != NULL) + *eonce_status = data_read_from_dr; + return retval; } /** @@ -586,106 +708,134 @@ return retval; * * @return */ -static int eonce_enter_debug_mode(struct target * target, uint16_t * eonce_status){ - int retval = ERROR_OK; - uint32_t instr = JTAG_INSTR_DEBUG_REQUEST; - uint32_t ir_out;//not used, just to make jtag happy. - uint16_t instr_16; - uint16_t read_16; - - // First try the easy way - retval = eonce_enter_debug_mode_without_reset(target,eonce_status); -if (retval == ERROR_OK) - return retval; +static int eonce_enter_debug_mode(struct target *target, + uint16_t *eonce_status) +{ + int retval = ERROR_OK; - struct jtag_tap * tap_chp; - struct jtag_tap * tap_cpu; - tap_chp = jtag_tap_by_string("dsp568013.chp"); -if (tap_chp == NULL) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_TAP_FIND_MASTER, "Failed to get master tap."); -} - tap_cpu = jtag_tap_by_string("dsp568013.cpu"); -if (tap_cpu == NULL) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_TAP_FIND_CORE, "Failed to get master tap."); - } - - // Enable master tap - tap_chp->enabled = true; - tap_cpu->enabled = false; - - instr = MASTER_TAP_CMD_IDCODE; - retval = dsp5680xx_irscan(target, & instr, & ir_out,DSP5680XX_JTAG_MASTER_TAP_IRLEN); - err_check_propagate(retval); - jtag_add_sleep(TIME_DIV_FREESCALE*100*1000); - - // Enable EOnCE module - jtag_add_reset(0,1); - jtag_add_sleep(TIME_DIV_FREESCALE*200*1000); - instr = 0x0606ffff;// This was selected experimentally. - retval = dsp5680xx_drscan(target,(uint8_t *) & instr,(uint8_t *) & ir_out,32); - err_check_propagate(retval); - // ir_out now hold tap idcode - - // Enable core tap - tap_chp->enabled = true; - retval = switch_tap(target,tap_chp,tap_cpu); - err_check_propagate(retval); - - instr = JTAG_INSTR_ENABLE_ONCE; - //Two rounds of jtag 0x6 (enable eonce) to enable EOnCE. - retval = dsp5680xx_irscan(target, & instr, & ir_out,DSP5680XX_JTAG_CORE_TAP_IRLEN); - err_check_propagate(retval); - instr = JTAG_INSTR_DEBUG_REQUEST; - retval = dsp5680xx_irscan(target, & instr, & ir_out,DSP5680XX_JTAG_CORE_TAP_IRLEN); - err_check_propagate(retval); - instr_16 = 0x1; - retval = dsp5680xx_drscan(target,(uint8_t *) & instr_16,(uint8_t *) & read_16,8); - err_check_propagate(retval); - instr_16 = 0x20; - retval = dsp5680xx_drscan(target,(uint8_t *) & instr_16,(uint8_t *) & read_16,8); - err_check_propagate(retval); - jtag_add_sleep(TIME_DIV_FREESCALE*100*1000); - jtag_add_reset(0,0); - jtag_add_sleep(TIME_DIV_FREESCALE*300*1000); - - instr = JTAG_INSTR_ENABLE_ONCE; - //Two rounds of jtag 0x6 (enable eonce) to enable EOnCE. - for(int i = 0; i<3; i++){ - retval = dsp5680xx_irscan(target, & instr, & ir_out,DSP5680XX_JTAG_CORE_TAP_IRLEN); - err_check_propagate(retval); - } -if ((ir_out&JTAG_STATUS_MASK) == JTAG_STATUS_DEBUG) - target->state = TARGET_HALTED; -else { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_HALT, "Failed to halt target."); -} + uint32_t instr = JTAG_INSTR_DEBUG_REQUEST; - for(int i = 0; i<3; i++){ - instr_16 = 0x86; - dsp5680xx_drscan(target,(uint8_t *) & instr_16,(uint8_t *) & read_16,16); - instr_16 = 0xff; - dsp5680xx_drscan(target,(uint8_t *) & instr_16,(uint8_t *) & read_16,16); - } - - // Verify that debug mode is enabled - uint16_t data_read_from_dr; -retval = eonce_read_status_reg(target, &data_read_from_dr); - err_check_propagate(retval); -if ((data_read_from_dr&0x30) == 0x30) { - LOG_DEBUG("EOnCE successfully entered debug mode."); - dsp5680xx_context.debug_mode_enabled = true; - retval = ERROR_OK; -} else { - const char *msg = "Failed to set EOnCE module to debug mode"; - retval = ERROR_TARGET_FAILURE; - err_check(retval, DSP5680XX_ERROR_ENTER_DEBUG_MODE, msg); -} - if(eonce_status!=NULL) - *eonce_status = data_read_from_dr; - return retval; + uint32_t ir_out; /* not used, just to make jtag happy. */ + + uint16_t instr_16; + + uint16_t read_16; + + /* First try the easy way */ + retval = eonce_enter_debug_mode_without_reset(target, eonce_status); + if (retval == ERROR_OK) + return retval; + + struct jtag_tap *tap_chp; + + struct jtag_tap *tap_cpu; + + tap_chp = jtag_tap_by_string("dsp568013.chp"); + if (tap_chp == NULL) { + retval = ERROR_FAIL; + err_check(retval, DSP5680XX_ERROR_JTAG_TAP_FIND_MASTER, + "Failed to get master tap."); + } + tap_cpu = jtag_tap_by_string("dsp568013.cpu"); + if (tap_cpu == NULL) { + retval = ERROR_FAIL; + err_check(retval, DSP5680XX_ERROR_JTAG_TAP_FIND_CORE, + "Failed to get master tap."); + } + /* Enable master tap */ + tap_chp->enabled = true; + tap_cpu->enabled = false; + + instr = MASTER_TAP_CMD_IDCODE; + retval = + dsp5680xx_irscan(target, &instr, &ir_out, + DSP5680XX_JTAG_MASTER_TAP_IRLEN); + err_check_propagate(retval); + jtag_add_sleep(TIME_DIV_FREESCALE * 100 * 1000); + + /* Enable EOnCE module */ + jtag_add_reset(0, 1); + jtag_add_sleep(TIME_DIV_FREESCALE * 200 * 1000); + instr = 0x0606ffff; /* This was selected experimentally. */ + retval = + dsp5680xx_drscan(target, (uint8_t *) &instr, (uint8_t *) &ir_out, + 32); + err_check_propagate(retval); + /* ir_out now hold tap idcode */ + + /* Enable core tap */ + tap_chp->enabled = true; + retval = switch_tap(target, tap_chp, tap_cpu); + err_check_propagate(retval); + + instr = JTAG_INSTR_ENABLE_ONCE; + /* Two rounds of jtag 0x6 (enable eonce) to enable EOnCE. */ + retval = + dsp5680xx_irscan(target, &instr, &ir_out, + DSP5680XX_JTAG_CORE_TAP_IRLEN); + err_check_propagate(retval); + instr = JTAG_INSTR_DEBUG_REQUEST; + retval = + dsp5680xx_irscan(target, &instr, &ir_out, + DSP5680XX_JTAG_CORE_TAP_IRLEN); + err_check_propagate(retval); + instr_16 = 0x1; + retval = + dsp5680xx_drscan(target, (uint8_t *) &instr_16, + (uint8_t *) &read_16, 8); + err_check_propagate(retval); + instr_16 = 0x20; + retval = + dsp5680xx_drscan(target, (uint8_t *) &instr_16, + (uint8_t *) &read_16, 8); + err_check_propagate(retval); + jtag_add_sleep(TIME_DIV_FREESCALE * 100 * 1000); + jtag_add_reset(0, 0); + jtag_add_sleep(TIME_DIV_FREESCALE * 300 * 1000); + + instr = JTAG_INSTR_ENABLE_ONCE; + /* Two rounds of jtag 0x6 (enable eonce) to enable EOnCE. */ + for (int i = 0; i < 3; i++) { + retval = + dsp5680xx_irscan(target, &instr, &ir_out, + DSP5680XX_JTAG_CORE_TAP_IRLEN); + err_check_propagate(retval); + } + if ((ir_out & JTAG_STATUS_MASK) == JTAG_STATUS_DEBUG) + target->state = TARGET_HALTED; + else { + retval = ERROR_FAIL; + err_check(retval, DSP5680XX_ERROR_HALT, + "Failed to halt target."); + } + + for (int i = 0; i < 3; i++) { + instr_16 = 0x86; + dsp5680xx_drscan(target, (uint8_t *) &instr_16, + (uint8_t *) &read_16, 16); + instr_16 = 0xff; + dsp5680xx_drscan(target, (uint8_t *) &instr_16, + (uint8_t *) &read_16, 16); + } + + /* Verify that debug mode is enabled */ + uint16_t data_read_from_dr; + + retval = eonce_read_status_reg(target, &data_read_from_dr); + err_check_propagate(retval); + if ((data_read_from_dr & 0x30) == 0x30) { + LOG_DEBUG("EOnCE successfully entered debug mode."); + dsp5680xx_context.debug_mode_enabled = true; + retval = ERROR_OK; + } else { + const char *msg = "Failed to set EOnCE module to debug mode"; + + retval = ERROR_TARGET_FAILURE; + err_check(retval, DSP5680XX_ERROR_ENTER_DEBUG_MODE, msg); + } + if (eonce_status != NULL) + *eonce_status = data_read_from_dr; + return retval; } /** @@ -695,205 +845,241 @@ if ((data_read_from_dr&0x30) == 0x30) { * * @return */ -static int eonce_pc_store(struct target * target){ - uint8_t tmp[2]; - int retval; - retval = core_move_pc_to_r4(target); - err_check_propagate(retval); - retval = core_move_r4_to_y(target); - err_check_propagate(retval); - retval = eonce_load_TX_RX_to_r0(target); - err_check_propagate(retval); - retval = core_move_y0_at_r0(target); - err_check_propagate(retval); - retval = core_rx_lower_data(target,tmp); - err_check_propagate(retval); - LOG_USER("PC value: 0x%X%X\n",tmp[1],tmp[0]); - dsp5680xx_context.stored_pc = (tmp[0]|(tmp[1]<<8)); - return ERROR_OK; -} +static int eonce_pc_store(struct target *target) +{ + uint8_t tmp[2]; + + int retval; -static int dsp5680xx_target_create(struct target *target, Jim_Interp * interp){ - struct dsp5680xx_common *dsp5680xx = calloc(1, sizeof(struct dsp5680xx_common)); - target->arch_info = dsp5680xx; - return ERROR_OK; + retval = core_move_pc_to_r4(target); + err_check_propagate(retval); + retval = core_move_r4_to_y(target); + err_check_propagate(retval); + retval = eonce_load_TX_RX_to_r0(target); + err_check_propagate(retval); + retval = core_move_y0_at_r0(target); + err_check_propagate(retval); + retval = core_rx_lower_data(target, tmp); + err_check_propagate(retval); + LOG_USER("PC value: 0x%X%X\n", tmp[1], tmp[0]); + dsp5680xx_context.stored_pc = (tmp[0] | (tmp[1] << 8)); + return ERROR_OK; } -static int dsp5680xx_init_target(struct command_context *cmd_ctx, struct target *target){ - dsp5680xx_context.stored_pc = 0; - dsp5680xx_context.flush = 1; - dsp5680xx_context.debug_mode_enabled = false; - LOG_DEBUG("target initiated!"); - //TODO core tap must be enabled before running these commands, currently this is done in the .cfg tcl script. - return ERROR_OK; +static int dsp5680xx_target_create(struct target *target, Jim_Interp *interp) +{ + struct dsp5680xx_common *dsp5680xx = + calloc(1, sizeof(struct dsp5680xx_common)); + target->arch_info = dsp5680xx; + return ERROR_OK; } -static int dsp5680xx_arch_state(struct target *target){ -LOG_USER("%s not implemented yet.", __func__); -return ERROR_OK; +static int dsp5680xx_init_target(struct command_context *cmd_ctx, + struct target *target) +{ + dsp5680xx_context.stored_pc = 0; + dsp5680xx_context.flush = 1; + dsp5680xx_context.debug_mode_enabled = false; + LOG_DEBUG("target initiated!"); + /* TODO core tap must be enabled before running these commands, currently + * this is done in the .cfg tcl script. */ + return ERROR_OK; } -int dsp5680xx_target_status(struct target * target, uint8_t * jtag_st, uint16_t * eonce_st){ - return target->state; +static int dsp5680xx_arch_state(struct target *target) +{ + LOG_USER("%s not implemented yet.", __func__); + return ERROR_OK; } -static int dsp5680xx_assert_reset(struct target *target){ - target->state = TARGET_RESET; - return ERROR_OK; +int dsp5680xx_target_status(struct target *target, uint8_t *jtag_st, + uint16_t *eonce_st) +{ + return target->state; } -static int dsp5680xx_deassert_reset(struct target *target){ - target->state = TARGET_RUNNING; - return ERROR_OK; +static int dsp5680xx_assert_reset(struct target *target) +{ + target->state = TARGET_RESET; + return ERROR_OK; } -static int dsp5680xx_halt(struct target *target){ - int retval; - uint16_t eonce_status = 0xbeef; -if ((target->state == TARGET_HALTED) && (dsp5680xx_context.debug_mode_enabled)) { - LOG_USER("Target already halted and in debug mode."); +static int dsp5680xx_deassert_reset(struct target *target) +{ + target->state = TARGET_RUNNING; return ERROR_OK; -} else { - if (target->state == TARGET_HALTED) - LOG_USER("Target already halted, re attempting to enter debug mode."); } - retval = eonce_enter_debug_mode(target,&eonce_status); + +static int dsp5680xx_halt(struct target *target) +{ + int retval; + + uint16_t eonce_status = 0xbeef; + + if ((target->state == TARGET_HALTED) + && (dsp5680xx_context.debug_mode_enabled)) { + LOG_USER("Target already halted and in debug mode."); + return ERROR_OK; + } else { + if (target->state == TARGET_HALTED) + LOG_USER + ("Target already halted, re attempting to enter debug mode."); + } + retval = eonce_enter_debug_mode(target, &eonce_status); err_check_propagate(retval); - retval = eonce_pc_store(target); - err_check_propagate(retval); -if (dsp5680xx_context.debug_mode_enabled) { retval = eonce_pc_store(target); err_check_propagate(retval); -} - return retval; + if (dsp5680xx_context.debug_mode_enabled) { + retval = eonce_pc_store(target); + err_check_propagate(retval); + } + return retval; } static int dsp5680xx_poll(struct target *target) { - int retval; - uint8_t jtag_status; - uint8_t eonce_status; - uint16_t read_tmp; -retval = dsp5680xx_jtag_status(target, &jtag_status); -err_check_propagate(retval); -if (jtag_status == JTAG_STATUS_DEBUG) - if (target->state != TARGET_HALTED) { - retval = eonce_enter_debug_mode(target, &read_tmp); - err_check_propagate(retval); - eonce_status = (uint8_t) read_tmp; - if ((eonce_status&EONCE_STAT_MASK) != DSP5680XX_ONCE_OSCR_DEBUG_M) { - const char *msg = "%s: Failed to put EOnCE in debug mode.Flash locked?..."; - LOG_WARNING(msg, __func__); - return ERROR_TARGET_FAILURE; - } else { - target->state = TARGET_HALTED; - return ERROR_OK; + int retval; + + uint8_t jtag_status; + + uint8_t eonce_status; + + uint16_t read_tmp; + + retval = dsp5680xx_jtag_status(target, &jtag_status); + err_check_propagate(retval); + if (jtag_status == JTAG_STATUS_DEBUG) + if (target->state != TARGET_HALTED) { + retval = eonce_enter_debug_mode(target, &read_tmp); + err_check_propagate(retval); + eonce_status = (uint8_t) read_tmp; + if ((eonce_status & EONCE_STAT_MASK) != + DSP5680XX_ONCE_OSCR_DEBUG_M) { + const char *msg = + "%s: Failed to put EOnCE in debug mode.Flash locked?..."; + LOG_WARNING(msg, __func__); + return ERROR_TARGET_FAILURE; + } else { + target->state = TARGET_HALTED; + return ERROR_OK; + } } - } -if (jtag_status == JTAG_STATUS_NORMAL) { - if (target->state == TARGET_RESET) { - retval = dsp5680xx_halt(target); - err_check_propagate(retval); - retval = eonce_exit_debug_mode(target, &eonce_status); - err_check_propagate(retval); - if ((eonce_status&EONCE_STAT_MASK) != DSP5680XX_ONCE_OSCR_NORMAL_M) { - const char *msg = "%s: JTAG running, but EOnCE run failed.Try resetting.."; - LOG_WARNING(msg, __func__); - return ERROR_TARGET_FAILURE; - } else { - target->state = TARGET_RUNNING; - return ERROR_OK; + if (jtag_status == JTAG_STATUS_NORMAL) { + if (target->state == TARGET_RESET) { + retval = dsp5680xx_halt(target); + err_check_propagate(retval); + retval = eonce_exit_debug_mode(target, &eonce_status); + err_check_propagate(retval); + if ((eonce_status & EONCE_STAT_MASK) != + DSP5680XX_ONCE_OSCR_NORMAL_M) { + const char *msg = + "%s: JTAG running, but EOnCE run failed.Try resetting.."; + LOG_WARNING(msg, __func__); + return ERROR_TARGET_FAILURE; + } else { + target->state = TARGET_RUNNING; + return ERROR_OK; + } } - } - if (target->state != TARGET_RUNNING) { - retval = eonce_read_status_reg(target, &read_tmp); - err_check_propagate(retval); - eonce_status = (uint8_t) read_tmp; - if ((eonce_status&EONCE_STAT_MASK) != DSP5680XX_ONCE_OSCR_NORMAL_M) { - LOG_WARNING("Inconsistent target status. Restart!"); - return ERROR_TARGET_FAILURE; + if (target->state != TARGET_RUNNING) { + retval = eonce_read_status_reg(target, &read_tmp); + err_check_propagate(retval); + eonce_status = (uint8_t) read_tmp; + if ((eonce_status & EONCE_STAT_MASK) != + DSP5680XX_ONCE_OSCR_NORMAL_M) { + LOG_WARNING + ("Inconsistent target status. Restart!"); + return ERROR_TARGET_FAILURE; + } } + target->state = TARGET_RUNNING; + return ERROR_OK; + } + if (jtag_status == JTAG_STATUS_DEAD) { + LOG_ERROR + ("%s: Cannot communicate with JTAG. Check connection...", + __func__); + target->state = TARGET_UNKNOWN; + return ERROR_TARGET_FAILURE; + } + if (target->state == TARGET_UNKNOWN) { + LOG_ERROR("%s: Target status invalid - communication failure", + __func__); + return ERROR_TARGET_FAILURE; } - target->state = TARGET_RUNNING; return ERROR_OK; } -if (jtag_status == JTAG_STATUS_DEAD) { - LOG_ERROR("%s: Cannot communicate with JTAG. Check connection...", __func__); - target->state = TARGET_UNKNOWN; - return ERROR_TARGET_FAILURE; -}; -if (target->state == TARGET_UNKNOWN) { - LOG_ERROR("%s: Target status invalid - communication failure", __func__); - return ERROR_TARGET_FAILURE; -}; -return ERROR_OK; -} -static int dsp5680xx_resume(struct target *target, int current, uint32_t address, int hb, int d) +static int dsp5680xx_resume(struct target *target, int current, + target_addr_t address, int hb, int d) { -if (target->state == TARGET_RUNNING) { - LOG_USER("Target already running."); - return ERROR_OK; -} - int retval; - uint8_t eonce_status; -uint8_t jtag_status; -if (dsp5680xx_context.debug_mode_enabled) { - if (!current) { - retval = core_move_value_to_pc(target, address); - err_check_propagate(retval); - } - - int retry = 20; - while (retry-- > 1) { - retval = eonce_exit_debug_mode(target, &eonce_status); - err_check_propagate(retval); - if (eonce_status == DSP5680XX_ONCE_OSCR_NORMAL_M) - break; - } - if (retry == 0) { - retval = ERROR_TARGET_FAILURE; - err_check(retval, DSP5680XX_ERROR_EXIT_DEBUG_MODE, "Failed to exit debug mode..."); - } else { - target->state = TARGET_RUNNING; - dsp5680xx_context.debug_mode_enabled = false; + if (target->state == TARGET_RUNNING) { + LOG_USER("Target already running."); + return ERROR_OK; } - LOG_DEBUG("EOnCE status: 0x%02X.", eonce_status); -} else { - /** - * If debug mode was not enabled but target was halted, then it is most likely that - * access to eonce registers is locked. - * Reset target to make it run again. - */ - jtag_add_reset(0, 1); - jtag_add_sleep(TIME_DIV_FREESCALE*200*1000); - -retval = reset_jtag(); -err_check(retval, DSP5680XX_ERROR_JTAG_RESET, "Failed to reset JTAG state machine"); -jtag_add_sleep(TIME_DIV_FREESCALE*100*1000); -jtag_add_reset(0, 0); -jtag_add_sleep(TIME_DIV_FREESCALE*300*1000); -retval = dsp5680xx_jtag_status(target, &jtag_status); -err_check_propagate(retval); -if ((jtag_status&JTAG_STATUS_MASK) == JTAG_STATUS_NORMAL) { - target->state = TARGET_RUNNING; - dsp5680xx_context.debug_mode_enabled = false; - } else { - retval = ERROR_TARGET_FAILURE; - err_check(retval, DSP5680XX_ERROR_RESUME, "Failed to resume target"); - } -} -return ERROR_OK; -} + int retval; + uint8_t eonce_status; + uint8_t jtag_status; + if (dsp5680xx_context.debug_mode_enabled) { + if (!current) { + retval = core_move_value_to_pc(target, address); + err_check_propagate(retval); + } + int retry = 20; + while (retry-- > 1) { + retval = eonce_exit_debug_mode(target, &eonce_status); + err_check_propagate(retval); + if (eonce_status == DSP5680XX_ONCE_OSCR_NORMAL_M) + break; + } + if (retry == 0) { + retval = ERROR_TARGET_FAILURE; + err_check(retval, DSP5680XX_ERROR_EXIT_DEBUG_MODE, + "Failed to exit debug mode..."); + } else { + target->state = TARGET_RUNNING; + dsp5680xx_context.debug_mode_enabled = false; + } + LOG_DEBUG("EOnCE status: 0x%02X.", eonce_status); + } else { + /* + * If debug mode was not enabled but target was halted, then it is most likely that + * access to eonce registers is locked. + * Reset target to make it run again. + */ + jtag_add_reset(0, 1); + jtag_add_sleep(TIME_DIV_FREESCALE * 200 * 1000); + + retval = reset_jtag(); + err_check(retval, DSP5680XX_ERROR_JTAG_RESET, + "Failed to reset JTAG state machine"); + jtag_add_sleep(TIME_DIV_FREESCALE * 100 * 1000); + jtag_add_reset(0, 0); + jtag_add_sleep(TIME_DIV_FREESCALE * 300 * 1000); + retval = dsp5680xx_jtag_status(target, &jtag_status); + err_check_propagate(retval); + if ((jtag_status & JTAG_STATUS_MASK) == JTAG_STATUS_NORMAL) { + target->state = TARGET_RUNNING; + dsp5680xx_context.debug_mode_enabled = false; + } else { + retval = ERROR_TARGET_FAILURE; + err_check(retval, DSP5680XX_ERROR_RESUME, + "Failed to resume target"); + } + } + return ERROR_OK; +} /** - * The value of @address determines if it corresponds to P: (program) or X: (dat) memory. If the address is over 0x200000 then it is considered X: memory, and @pmem = 0. - * The special case of 0xFFXXXX is not modified, since it allows to read out the memory mapped EOnCE registers. + * The value of @address determines if it corresponds to P: (program) or X: (dat) memory. + * If the address is over 0x200000 then it is considered X: memory, and @pmem = 0. + * The special case of 0xFFXXXX is not modified, since it allows to read out the + * memory mapped EOnCE registers. * * @param address * @param pmem @@ -902,260 +1088,326 @@ return ERROR_OK; */ static int dsp5680xx_convert_address(uint32_t *address, int *pmem) { - /** - * Distinguish data memory (x) from program memory (p) by the address. - * Addresses over S_FILE_DATA_OFFSET are considered (x) memory. - */ -if (*address >= S_FILE_DATA_OFFSET) { - *pmem = 0; - if (((*address)&0xff0000) != 0xff0000) - *address -= S_FILE_DATA_OFFSET; -} -return ERROR_OK; + /* + * Distinguish data memory (x) from program memory (p) by the address. + * Addresses over S_FILE_DATA_OFFSET are considered (x) memory. + */ + if (*address >= S_FILE_DATA_OFFSET) { + *pmem = 0; + if (((*address) & 0xff0000) != 0xff0000) + *address -= S_FILE_DATA_OFFSET; + } + return ERROR_OK; } -static int dsp5680xx_read_16_single(struct target *t, uint32_t a, uint8_t *data_read, int r_pmem) +static int dsp5680xx_read_16_single(struct target *t, uint32_t a, + uint8_t *data_read, int r_pmem) { -struct target *target = t; -uint32_t address = a; - int retval; - retval = core_move_long_to_r0(target,address); - err_check_propagate(retval); -if (r_pmem) - retval = core_move_at_pr0_inc_to_y0(target); -else - retval = core_move_at_r0_to_y0(target); - err_check_propagate(retval); - retval = eonce_load_TX_RX_to_r0(target); - err_check_propagate(retval); - retval = core_move_y0_at_r0(target); - err_check_propagate(retval); - // at this point the data i want is at the reg eonce can read - retval = core_rx_lower_data(target,data_read); - err_check_propagate(retval); -LOG_DEBUG("%s:Data read from 0x%06X: 0x%02X%02X", __func__, address, data_read[1], data_read[0]); - return retval; -} + struct target *target = t; -static int dsp5680xx_read_32_single(struct target *t, uint32_t a, uint8_t *data_read, int r_pmem) -{ -struct target *target = t; -uint32_t address = a; - int retval; -address = (address & 0xFFFFF); - // Get data to an intermediate register - retval = core_move_long_to_r0(target,address); - err_check_propagate(retval); -if (r_pmem) { - retval = core_move_at_pr0_inc_to_y0(target); + uint32_t address = a; + + int retval; + + retval = core_move_long_to_r0(target, address); + err_check_propagate(retval); + if (r_pmem) + retval = core_move_at_pr0_inc_to_y0(target); + else + retval = core_move_at_r0_to_y0(target); err_check_propagate(retval); - retval = core_move_at_pr0_inc_to_y1(target); + retval = eonce_load_TX_RX_to_r0(target); err_check_propagate(retval); -} else { - retval = core_move_at_r0_inc_to_y0(target); + retval = core_move_y0_at_r0(target); err_check_propagate(retval); - retval = core_move_at_r0_to_y1(target); + /* at this point the data i want is at the reg eonce can read */ + retval = core_rx_lower_data(target, data_read); err_check_propagate(retval); -} - // Get lower part of data to TX/RX - retval = eonce_load_TX_RX_to_r0(target); - err_check_propagate(retval); - retval = core_move_y0_at_r0_inc(target); // This also load TX/RX high to r0 - err_check_propagate(retval); - // Get upper part of data to TX/RX - retval = core_move_y1_at_r0(target); - err_check_propagate(retval); - // at this point the data i want is at the reg eonce can read - retval = core_rx_lower_data(target,data_read); - err_check_propagate(retval); - retval = core_rx_upper_data(target,data_read+2); - err_check_propagate(retval); - return retval; + LOG_DEBUG("%s:Data read from 0x%06" PRIX32 ": 0x%02X%02X", __func__, address, + data_read[1], data_read[0]); + return retval; } -static int dsp5680xx_read(struct target *t, uint32_t a, unsigned size, unsigned count, uint8_t *buf) +static int dsp5680xx_read_32_single(struct target *t, uint32_t a, + uint8_t *data_read, int r_pmem) { -struct target *target = t; -uint32_t address = a; -uint8_t *buffer = buf; -check_halt_and_debug(target); - - int retval = ERROR_OK; - int pmem = 1; + struct target *target = t; - retval = dsp5680xx_convert_address(&address, &pmem); - err_check_propagate(retval); + uint32_t address = a; - dsp5680xx_context.flush = 0; - int counter = FLUSH_COUNT_READ_WRITE; + int retval; -for (unsigned i = 0; i < count; i++) { - if (--counter == 0) { - dsp5680xx_context.flush = 1; - counter = FLUSH_COUNT_READ_WRITE; - } - switch (size) { - case 1: - if (!(i%2)) - retval = dsp5680xx_read_16_single(target, address + i/2, buffer + i, pmem); - break; - case 2: - retval = dsp5680xx_read_16_single(target, address + i, buffer+2*i, pmem); - break; - case 4: - retval = dsp5680xx_read_32_single(target, address + 2*i, buffer + 4*i, pmem); - break; - default: - LOG_USER("%s: Invalid read size.", __func__); - break; + address = (address & 0xFFFFF); + /* Get data to an intermediate register */ + retval = core_move_long_to_r0(target, address); + err_check_propagate(retval); + if (r_pmem) { + retval = core_move_at_pr0_inc_to_y0(target); + err_check_propagate(retval); + retval = core_move_at_pr0_inc_to_y1(target); + err_check_propagate(retval); + } else { + retval = core_move_at_r0_inc_to_y0(target); + err_check_propagate(retval); + retval = core_move_at_r0_to_y1(target); + err_check_propagate(retval); } + /* Get lower part of data to TX/RX */ + retval = eonce_load_TX_RX_to_r0(target); err_check_propagate(retval); - dsp5680xx_context.flush = 0; + retval = core_move_y0_at_r0_inc(target); /* This also load TX/RX high to r0 */ + err_check_propagate(retval); + /* Get upper part of data to TX/RX */ + retval = core_move_y1_at_r0(target); + err_check_propagate(retval); + /* at this point the data i want is at the reg eonce can read */ + retval = core_rx_lower_data(target, data_read); + err_check_propagate(retval); + retval = core_rx_upper_data(target, data_read + 2); + err_check_propagate(retval); + return retval; } -dsp5680xx_context.flush = 1; -retval = dsp5680xx_execute_queue(); -err_check_propagate(retval); +static int dsp5680xx_read(struct target *t, target_addr_t a, uint32_t size, + uint32_t count, uint8_t *buf) +{ + struct target *target = t; -return retval; -} + uint32_t address = a; -static int dsp5680xx_write_16_single(struct target *t, uint32_t a, uint16_t data, uint8_t w_pmem) -{ -struct target *target = t; -uint32_t address = a; - int retval = 0; - retval = core_move_long_to_r0(target,address); - err_check_propagate(retval); -if (w_pmem) { - retval = core_move_value_to_y0(target, data); - err_check_propagate(retval); - retval = core_move_y0_at_pr0_inc(target); + uint8_t *buffer = buf; + + check_halt_and_debug(target); + + int retval = ERROR_OK; + + int pmem = 1; + + retval = dsp5680xx_convert_address(&address, &pmem); err_check_propagate(retval); -} else { - retval = core_move_value_at_r0(target, data); + + dsp5680xx_context.flush = 0; + int counter = FLUSH_COUNT_READ_WRITE; + + for (unsigned i = 0; i < count; i++) { + if (--counter == 0) { + dsp5680xx_context.flush = 1; + counter = FLUSH_COUNT_READ_WRITE; + } + switch (size) { + case 1: + if (!(i % 2)) + retval = + dsp5680xx_read_16_single(target, + address + i / 2, + buffer + i, pmem); + break; + case 2: + retval = + dsp5680xx_read_16_single(target, address + i, + buffer + 2 * i, pmem); + break; + case 4: + retval = + dsp5680xx_read_32_single(target, address + 2 * i, + buffer + 4 * i, pmem); + break; + default: + LOG_USER("%s: Invalid read size.", __func__); + break; + } + err_check_propagate(retval); + dsp5680xx_context.flush = 0; + } + + dsp5680xx_context.flush = 1; + retval = dsp5680xx_execute_queue(); err_check_propagate(retval); -} -return retval; -} -static int dsp5680xx_write_32_single(struct target *t, uint32_t a, uint32_t data, int w_pmem) -{ -struct target *target = t; -uint32_t address = a; -int retval = ERROR_OK; -retval = core_move_long_to_r0(target, address); -err_check_propagate(retval); -retval = core_move_long_to_y(target, data); -err_check_propagate(retval); -if (w_pmem) - retval = core_move_y0_at_pr0_inc(target); -else - retval = core_move_y0_at_r0_inc(target); -err_check_propagate(retval); -if (w_pmem) - retval = core_move_y1_at_pr0_inc(target); -else - retval = core_move_y1_at_r0_inc(target); -err_check_propagate(retval); -return retval; + return retval; } -static int dsp5680xx_write_8(struct target *t, uint32_t a, uint32_t c, const uint8_t *d, int pmem) +static int dsp5680xx_write_16_single(struct target *t, uint32_t a, + uint16_t data, uint8_t w_pmem) { -struct target *target = t; -uint32_t address = a; -uint32_t count = c; -const uint8_t *data = d; - int retval = 0; - uint16_t data_16; - uint32_t iter; - - int counter = FLUSH_COUNT_READ_WRITE; -for (iter = 0; iter < count/2; iter++) { - if (--counter == 0) { - dsp5680xx_context.flush = 1; - counter = FLUSH_COUNT_READ_WRITE; + struct target *target = t; + + uint32_t address = a; + + int retval = 0; + + retval = core_move_long_to_r0(target, address); + err_check_propagate(retval); + if (w_pmem) { + retval = core_move_value_to_y0(target, data); + err_check_propagate(retval); + retval = core_move_y0_at_pr0_inc(target); + err_check_propagate(retval); + } else { + retval = core_move_value_at_r0(target, data); + err_check_propagate(retval); } - data_16 = (data[2*iter]|(data[2*iter+1] << 8)); - retval = dsp5680xx_write_16_single(target, address+iter, data_16, pmem); - if (retval != ERROR_OK) { - LOG_ERROR("%s: Could not write to p:0x%04X", __func__, address); - dsp5680xx_context.flush = 1; return retval; - } - dsp5680xx_context.flush = 0; } -dsp5680xx_context.flush = 1; - // Only one byte left, let's not overwrite the other byte (mem is 16bit) - // Need to retrieve the part we do not want to overwrite. - uint16_t data_old; -if ((count == 1) || (count%2)) { - retval = dsp5680xx_read(target, address+iter, 1, 1, (uint8_t *)&data_old); +static int dsp5680xx_write_32_single(struct target *t, uint32_t a, + uint32_t data, int w_pmem) +{ + struct target *target = t; + + uint32_t address = a; + + int retval = ERROR_OK; + + retval = core_move_long_to_r0(target, address); err_check_propagate(retval); - if (count == 1) - data_old = (((data_old&0xff)<<8)|data[0]);/* preserve upper byte */ + retval = core_move_long_to_y(target, data); + err_check_propagate(retval); + if (w_pmem) + retval = core_move_y0_at_pr0_inc(target); else - data_old = (((data_old&0xff)<<8)|data[2*iter+1]); - retval = dsp5680xx_write_16_single(target, address+iter, data_old, pmem); + retval = core_move_y0_at_r0_inc(target); err_check_propagate(retval); -} -return retval; + if (w_pmem) + retval = core_move_y1_at_pr0_inc(target); + else + retval = core_move_y1_at_r0_inc(target); + err_check_propagate(retval); + return retval; } -static int dsp5680xx_write_16(struct target *t, uint32_t a, uint32_t c, const uint8_t *d, int pmem) +static int dsp5680xx_write_8(struct target *t, uint32_t a, uint32_t c, + const uint8_t *d, int pmem) { -struct target *target = t; -uint32_t address = a; -uint32_t count = c; -const uint8_t *data = d; - int retval = ERROR_OK; - uint32_t iter; - int counter = FLUSH_COUNT_READ_WRITE; - -for (iter = 0; iter < count; iter++) { - if (--counter == 0) { - dsp5680xx_context.flush = 1; - counter = FLUSH_COUNT_READ_WRITE; + struct target *target = t; + + uint32_t address = a; + + uint32_t count = c; + + const uint8_t *data = d; + + int retval = 0; + + uint16_t data_16; + + uint32_t iter; + + int counter = FLUSH_COUNT_READ_WRITE; + + for (iter = 0; iter < count / 2; iter++) { + if (--counter == 0) { + dsp5680xx_context.flush = 1; + counter = FLUSH_COUNT_READ_WRITE; + } + data_16 = (data[2 * iter] | (data[2 * iter + 1] << 8)); + retval = + dsp5680xx_write_16_single(target, address + iter, data_16, + pmem); + if (retval != ERROR_OK) { + LOG_ERROR("%s: Could not write to p:0x%04" PRIX32, __func__, + address); + dsp5680xx_context.flush = 1; + return retval; + } + dsp5680xx_context.flush = 0; } - retval = dsp5680xx_write_16_single(target, address+iter, data[iter], pmem); - if (retval != ERROR_OK) { - LOG_ERROR("%s: Could not write to p:0x%04X", __func__, address); - dsp5680xx_context.flush = 1; - return retval; + dsp5680xx_context.flush = 1; + + /* Only one byte left, let's not overwrite the other byte (mem is 16bit) */ + /* Need to retrieve the part we do not want to overwrite. */ + uint16_t data_old; + + if ((count == 1) || (count % 2)) { + retval = + dsp5680xx_read(target, address + iter, 1, 1, + (uint8_t *) &data_old); + err_check_propagate(retval); + if (count == 1) + data_old = (((data_old & 0xff) << 8) | data[0]); /* preserve upper byte */ + else + data_old = + (((data_old & 0xff) << 8) | data[2 * iter + 1]); + retval = + dsp5680xx_write_16_single(target, address + iter, data_old, + pmem); + err_check_propagate(retval); } - dsp5680xx_context.flush = 0; -} -dsp5680xx_context.flush = 1; -return retval; + return retval; } -static int dsp5680xx_write_32(struct target *t, uint32_t a, uint32_t c, const uint8_t *d, int pmem) +static int dsp5680xx_write_16(struct target *t, uint32_t a, uint32_t c, + const uint8_t *d, int pmem) { -struct target *target = t; -uint32_t address = a; -uint32_t count = c; -const uint8_t *data = d; - int retval = ERROR_OK; - uint32_t iter; - int counter = FLUSH_COUNT_READ_WRITE; - -for (iter = 0; iter < count; iter++) { - if (--counter == 0) { - dsp5680xx_context.flush = 1; - counter = FLUSH_COUNT_READ_WRITE; - } - retval = dsp5680xx_write_32_single(target, address+(iter<<1), data[iter], pmem); - if (retval != ERROR_OK) { - LOG_ERROR("%s: Could not write to p:0x%04X", __func__, address); - dsp5680xx_context.flush = 1; - return retval; + struct target *target = t; + + uint32_t address = a; + + uint32_t count = c; + + const uint8_t *data = d; + + int retval = ERROR_OK; + + uint32_t iter; + + int counter = FLUSH_COUNT_READ_WRITE; + + for (iter = 0; iter < count; iter++) { + if (--counter == 0) { + dsp5680xx_context.flush = 1; + counter = FLUSH_COUNT_READ_WRITE; + } + retval = + dsp5680xx_write_16_single(target, address + iter, + data[iter], pmem); + if (retval != ERROR_OK) { + LOG_ERROR("%s: Could not write to p:0x%04" PRIX32, __func__, + address); + dsp5680xx_context.flush = 1; + return retval; + } + dsp5680xx_context.flush = 0; } - dsp5680xx_context.flush = 0; + dsp5680xx_context.flush = 1; + return retval; } -dsp5680xx_context.flush = 1; -return retval; + +static int dsp5680xx_write_32(struct target *t, uint32_t a, uint32_t c, + const uint8_t *d, int pmem) +{ + struct target *target = t; + + uint32_t address = a; + + uint32_t count = c; + + const uint8_t *data = d; + + int retval = ERROR_OK; + + uint32_t iter; + + int counter = FLUSH_COUNT_READ_WRITE; + + for (iter = 0; iter < count; iter++) { + if (--counter == 0) { + dsp5680xx_context.flush = 1; + counter = FLUSH_COUNT_READ_WRITE; + } + retval = + dsp5680xx_write_32_single(target, address + (iter << 1), + data[iter], pmem); + if (retval != ERROR_OK) { + LOG_ERROR("%s: Could not write to p:0x%04" PRIX32, __func__, + address); + dsp5680xx_context.flush = 1; + return retval; + } + dsp5680xx_context.flush = 0; + } + dsp5680xx_context.flush = 1; + return retval; } /** @@ -1171,49 +1423,56 @@ return retval; * * @return */ -static int dsp5680xx_write(struct target *t, uint32_t a, uint32_t s, uint32_t c, const uint8_t *b) +static int dsp5680xx_write(struct target *t, target_addr_t a, uint32_t s, uint32_t c, + const uint8_t *b) { - /* TODO Cannot write 32bit to odd address, will write 0x12345678 as 0x5678 0x0012 */ -struct target *target = t; -uint32_t address = a; -uint32_t count = c; -uint8_t const *buffer = b; -uint32_t size = s; -check_halt_and_debug(target); - - int retval = 0; - int p_mem = 1; - retval = dsp5680xx_convert_address(&address, &p_mem); - err_check_propagate(retval); - -switch (size) { - case 1: - retval = dsp5680xx_write_8(target, address, count, buffer, p_mem); - break; - case 2: - retval = dsp5680xx_write_16(target, address, count, buffer, p_mem); - break; - case 4: - retval = dsp5680xx_write_32(target, address, count, buffer, p_mem); - break; - default: - retval = ERROR_TARGET_DATA_ABORT; - err_check(retval, DSP5680XX_ERROR_INVALID_DATA_SIZE_UNIT, "Invalid data size."); - break; - } - return retval; -} + /* TODO Cannot write 32bit to odd address, will write 0x12345678 as 0x5678 0x0012 */ + struct target *target = t; -static int dsp5680xx_bulk_write_memory(struct target *t, uint32_t a, uint32_t al, const uint8_t *b) -{ - LOG_ERROR("Not implemented yet."); - return ERROR_FAIL; + uint32_t address = a; + + uint32_t count = c; + + uint8_t const *buffer = b; + + uint32_t size = s; + + check_halt_and_debug(target); + + int retval = 0; + + int p_mem = 1; + + retval = dsp5680xx_convert_address(&address, &p_mem); + err_check_propagate(retval); + + switch (size) { + case 1: + retval = + dsp5680xx_write_8(target, address, count, buffer, p_mem); + break; + case 2: + retval = + dsp5680xx_write_16(target, address, count, buffer, p_mem); + break; + case 4: + retval = + dsp5680xx_write_32(target, address, count, buffer, p_mem); + break; + default: + retval = ERROR_TARGET_DATA_ABORT; + err_check(retval, DSP5680XX_ERROR_INVALID_DATA_SIZE_UNIT, + "Invalid data size."); + break; + } + return retval; } -static int dsp5680xx_write_buffer(struct target *t, uint32_t a, uint32_t size, const uint8_t *b) +static int dsp5680xx_write_buffer(struct target *t, target_addr_t a, uint32_t size, + const uint8_t *b) { -check_halt_and_debug(t); -return dsp5680xx_write(t, a, 1, size, b); + check_halt_and_debug(t); + return dsp5680xx_write(t, a, 1, size, b); } /** @@ -1226,16 +1485,18 @@ return dsp5680xx_write(t, a, 1, size, b); * * @return */ -static int dsp5680xx_read_buffer(struct target *t, uint32_t a, uint32_t size, uint8_t *buf) +static int dsp5680xx_read_buffer(struct target *t, target_addr_t a, uint32_t size, + uint8_t *buf) { -check_halt_and_debug(t); -/* The "/2" solves the byte/word addressing issue.*/ -return dsp5680xx_read(t, a, 2, size/2, buf); + check_halt_and_debug(t); + /* The "/2" solves the byte/word addressing issue.*/ + return dsp5680xx_read(t, a, 2, size / 2, buf); } /** * This function is not implemented. - * It returns an error in order to get OpenOCD to do read out the data and calculate the CRC, or try a binary comparison. + * It returns an error in order to get OpenOCD to do read out the data + * and calculate the CRC, or try a binary comparison. * * @param target * @param address Start address of the image. @@ -1244,13 +1505,16 @@ return dsp5680xx_read(t, a, 2, size/2, buf); * * @return */ -static int dsp5680xx_checksum_memory(struct target *t, uint32_t a, uint32_t s, uint32_t *checksum) +static int dsp5680xx_checksum_memory(struct target *t, target_addr_t a, uint32_t s, + uint32_t *checksum) { - return ERROR_FAIL; + return ERROR_FAIL; } /** - * Calculates a signature over @word_count words in the data from @buff16. The algorithm used is the same the FM uses, so the @return may be used to compare with the one generated by the FM module, and check if flashing was successful. + * Calculates a signature over @word_count words in the data from @buff16. + * The algorithm used is the same the FM uses, so the @return may be used to compare + * with the one generated by the FM module, and check if flashing was successful. * This algorithm is based on the perl script available from the Freescale website at FAQ 25630. * * @param buff16 @@ -1258,23 +1522,30 @@ static int dsp5680xx_checksum_memory(struct target *t, uint32_t a, uint32_t s, u * * @return */ -static int perl_crc(uint8_t *buff8, uint32_t word_count) +static int perl_crc(const uint8_t *buff8, uint32_t word_count) { - uint16_t checksum = 0xffff; - uint16_t data,fbmisr; - uint32_t i; -for (i = 0; i < word_count; i++) { - data = (buff8[2*i]|(buff8[2*i+1]<<8)); - fbmisr = (checksum & 2)>>1^(checksum & 4)>>2^(checksum & 16)>>4^(checksum & 0x8000)>>15; - checksum = (data ^ ((checksum << 1) | fbmisr)); -} - i--; -for (; !(i&0x80000000); i--) { - data = (buff8[2*i]|(buff8[2*i+1]<<8)); - fbmisr = (checksum & 2)>>1^(checksum & 4)>>2^(checksum & 16)>>4^(checksum & 0x8000)>>15; - checksum = (data ^ ((checksum << 1) | fbmisr)); -} - return checksum; + uint16_t checksum = 0xffff; + + uint16_t data, fbmisr; + + uint32_t i; + + for (i = 0; i < word_count; i++) { + data = (buff8[2 * i] | (buff8[2 * i + 1] << 8)); + fbmisr = + (checksum & 2) >> 1 ^ (checksum & 4) >> 2 ^ (checksum & 16) + >> 4 ^ (checksum & 0x8000) >> 15; + checksum = (data ^ ((checksum << 1) | fbmisr)); + } + i--; + for (; !(i & 0x80000000); i--) { + data = (buff8[2 * i] | (buff8[2 * i + 1] << 8)); + fbmisr = + (checksum & 2) >> 1 ^ (checksum & 4) >> 2 ^ (checksum & 16) + >> 4 ^ (checksum & 0x8000) >> 15; + checksum = (data ^ ((checksum << 1) | fbmisr)); + } + return checksum; } /** @@ -1286,15 +1557,20 @@ for (; !(i&0x80000000); i--) { */ int dsp5680xx_f_SIM_reset(struct target *target) { - int retval = ERROR_OK; - uint16_t sim_cmd = SIM_CMD_RESET; - uint32_t sim_addr; -if (strcmp(target->tap->chip, "dsp568013") == 0) { - sim_addr = MC568013_SIM_BASE_ADDR+S_FILE_DATA_OFFSET; - retval = dsp5680xx_write(target,sim_addr,1,2,(const uint8_t *)&sim_cmd); - err_check_propagate(retval); -} - return retval; + int retval = ERROR_OK; + + uint16_t sim_cmd = SIM_CMD_RESET; + + uint32_t sim_addr; + + if (strcmp(target->tap->chip, "dsp568013") == 0) { + sim_addr = MC568013_SIM_BASE_ADDR + S_FILE_DATA_OFFSET; + retval = + dsp5680xx_write(target, sim_addr, 1, 2, + (const uint8_t *)&sim_cmd); + err_check_propagate(retval); + } + return retval; } /** @@ -1306,25 +1582,32 @@ if (strcmp(target->tap->chip, "dsp568013") == 0) { */ static int dsp5680xx_soft_reset_halt(struct target *target) { - //TODO is this what this function is expected to do...? - int retval; - retval = dsp5680xx_halt(target); - err_check_propagate(retval); - retval = dsp5680xx_f_SIM_reset(target); -err_check_propagate(retval); - return retval; -} + /* TODO is this what this function is expected to do...? */ + int retval; -int dsp5680xx_f_protect_check(struct target * target, uint16_t * protected) { - int retval; -check_halt_and_debug(target); -if (protected == NULL) { - const char *msg = "NULL pointer not valid."; - err_check(ERROR_FAIL, DSP5680XX_ERROR_PROTECT_CHECK_INVALID_ARGS, msg); + retval = dsp5680xx_halt(target); + err_check_propagate(retval); + retval = dsp5680xx_f_SIM_reset(target); + err_check_propagate(retval); + return retval; } - retval = dsp5680xx_read_16_single(target,HFM_BASE_ADDR|HFM_PROT,(uint8_t *)protected,0); - err_check_propagate(retval); - return retval; + +int dsp5680xx_f_protect_check(struct target *target, uint16_t *protected) +{ + int retval; + + check_halt_and_debug(target); + if (protected == NULL) { + const char *msg = "NULL pointer not valid."; + + err_check(ERROR_FAIL, + DSP5680XX_ERROR_PROTECT_CHECK_INVALID_ARGS, msg); + } + retval = + dsp5680xx_read_16_single(target, HFM_BASE_ADDR | HFM_PROT, + (uint8_t *) protected, 0); + err_check_propagate(retval); + return retval; } /** @@ -1340,90 +1623,111 @@ if (protected == NULL) { * * @return */ -static int dsp5680xx_f_ex(struct target *t, uint16_t c, uint32_t a, uint32_t d, uint16_t *h, int p) +static int dsp5680xx_f_ex(struct target *t, uint16_t c, uint32_t a, uint32_t d, + uint16_t *h, int p) { -struct target *target = t; -uint32_t command = c; -uint32_t address = a; -uint32_t data = d; -uint16_t *hfm_ustat = h; -int pmem = p; - int retval; - retval = core_load_TX_RX_high_addr_to_r0(target); - err_check_propagate(retval); - retval = core_move_long_to_r2(target,HFM_BASE_ADDR); - err_check_propagate(retval); - uint8_t i[2]; - int watchdog = 100; - do{ - retval = core_move_at_r2_disp_to_y0(target,HFM_USTAT); // read HMF_USTAT - err_check_propagate(retval); - retval = core_move_y0_at_r0(target); - err_check_propagate(retval); - retval = core_rx_upper_data(target,i); - err_check_propagate(retval); -if ((watchdog--) == 1) { - retval = ERROR_TARGET_FAILURE; - const char *msg = "Timed out waiting for FM to finish old command."; - err_check(retval, DSP5680XX_ERROR_FM_BUSY, msg); - } - }while (!(i[0]&0x40)); // wait until current command is complete - - dsp5680xx_context.flush = 0; - - /* write to HFM_CNFG (lock=0, select bank) -- flash_desc.bank&0x03,0x01 == 0x00,0x01 ??? */ -retval = core_move_value_at_r2_disp(target, 0x00, HFM_CNFG); - err_check_propagate(retval); - retval = core_move_value_at_r2_disp(target,0x04,HFM_USTAT); // write to HMF_USTAT, clear PVIOL, ACCERR & BLANK bits - err_check_propagate(retval); - retval = core_move_value_at_r2_disp(target,0x10,HFM_USTAT); // clear only one bit at a time - err_check_propagate(retval); - retval = core_move_value_at_r2_disp(target,0x20,HFM_USTAT); - err_check_propagate(retval); - retval = core_move_value_at_r2_disp(target,0x00,HFM_PROT); // write to HMF_PROT, clear protection - err_check_propagate(retval); - retval = core_move_value_at_r2_disp(target,0x00,HFM_PROTB); // write to HMF_PROTB, clear protection - err_check_propagate(retval); - retval = core_move_value_to_y0(target,data); - err_check_propagate(retval); - retval = core_move_long_to_r3(target,address); // write to the flash block - err_check_propagate(retval); -if (pmem) { - retval = core_move_y0_at_pr3_inc(target); - err_check_propagate(retval); -} else { - retval = core_move_y0_at_r3(target); + struct target *target = t; + + uint32_t command = c; + + uint32_t address = a; + + uint32_t data = d; + + uint16_t *hfm_ustat = h; + + int pmem = p; + + int retval; + + retval = core_load_TX_RX_high_addr_to_r0(target); err_check_propagate(retval); -} - retval = core_move_value_at_r2_disp(target,command,HFM_CMD); // write command to the HFM_CMD reg - err_check_propagate(retval); - retval = core_move_value_at_r2_disp(target,0x80,HFM_USTAT); // start the command - err_check_propagate(retval); + retval = core_move_long_to_r2(target, HFM_BASE_ADDR); + err_check_propagate(retval); + uint8_t i[2]; + + int watchdog = 100; + + do { + retval = core_move_at_r2_disp_to_y0(target, HFM_USTAT); /* read HMF_USTAT */ + err_check_propagate(retval); + retval = core_move_y0_at_r0(target); + err_check_propagate(retval); + retval = core_rx_upper_data(target, i); + err_check_propagate(retval); + if ((watchdog--) == 1) { + retval = ERROR_TARGET_FAILURE; + const char *msg = + "Timed out waiting for FM to finish old command."; + err_check(retval, DSP5680XX_ERROR_FM_BUSY, msg); + } + } while (!(i[0] & 0x40)); /* wait until current command is complete */ - dsp5680xx_context.flush = 1; - retval = dsp5680xx_execute_queue(); - err_check_propagate(retval); + dsp5680xx_context.flush = 0; - watchdog = 100; - do{ - retval = core_move_at_r2_disp_to_y0(target,HFM_USTAT); // read HMF_USTAT + /* write to HFM_CNFG (lock=0,select bank) - flash_desc.bank&0x03, 0x01 == 0x00, 0x01 ??? */ + retval = core_move_value_at_r2_disp(target, 0x00, HFM_CNFG); + err_check_propagate(retval); + /* write to HMF_USTAT, clear PVIOL, ACCERR &BLANK bits */ + retval = core_move_value_at_r2_disp(target, 0x04, HFM_USTAT); + err_check_propagate(retval); + /* clear only one bit at a time */ + retval = core_move_value_at_r2_disp(target, 0x10, HFM_USTAT); err_check_propagate(retval); - retval = core_move_y0_at_r0(target); + retval = core_move_value_at_r2_disp(target, 0x20, HFM_USTAT); err_check_propagate(retval); - retval = core_rx_upper_data(target,i); + /* write to HMF_PROT, clear protection */ + retval = core_move_value_at_r2_disp(target, 0x00, HFM_PROT); err_check_propagate(retval); - if ((watchdog--) == 1) { + /* write to HMF_PROTB, clear protection */ + retval = core_move_value_at_r2_disp(target, 0x00, HFM_PROTB); + err_check_propagate(retval); + retval = core_move_value_to_y0(target, data); + err_check_propagate(retval); + /* write to the flash block */ + retval = core_move_long_to_r3(target, address); + err_check_propagate(retval); + if (pmem) { + retval = core_move_y0_at_pr3_inc(target); + err_check_propagate(retval); + } else { + retval = core_move_y0_at_r3(target); + err_check_propagate(retval); + } + /* write command to the HFM_CMD reg */ + retval = core_move_value_at_r2_disp(target, command, HFM_CMD); + err_check_propagate(retval); + /* start the command */ + retval = core_move_value_at_r2_disp(target, 0x80, HFM_USTAT); + err_check_propagate(retval); + + dsp5680xx_context.flush = 1; + retval = dsp5680xx_execute_queue(); + err_check_propagate(retval); + + watchdog = 100; + do { + /* read HMF_USTAT */ + retval = core_move_at_r2_disp_to_y0(target, HFM_USTAT); + err_check_propagate(retval); + retval = core_move_y0_at_r0(target); + err_check_propagate(retval); + retval = core_rx_upper_data(target, i); + err_check_propagate(retval); + if ((watchdog--) == 1) { + retval = ERROR_TARGET_FAILURE; + err_check(retval, DSP5680XX_ERROR_FM_CMD_TIMED_OUT, + "FM execution did not finish."); + } + } while (!(i[0] & 0x40)); /* wait until the command is complete */ + *hfm_ustat = ((i[0] << 8) | (i[1])); + if (i[0] & HFM_USTAT_MASK_PVIOL_ACCER) { retval = ERROR_TARGET_FAILURE; - err_check(retval, DSP5680XX_ERROR_FM_CMD_TIMED_OUT, "FM execution did not finish."); - } - }while (!(i[0]&0x40)); // wait until the command is complete - *hfm_ustat = ((i[0]<<8)|(i[1])); - if (i[0]&HFM_USTAT_MASK_PVIOL_ACCER){ - retval = ERROR_TARGET_FAILURE; - const char *msg = "pviol and/or accer bits set. HFM command execution error"; - err_check(retval, DSP5680XX_ERROR_FM_EXEC, msg); - } - return ERROR_OK; + const char *msg = + "pviol and/or accer bits set. HFM command execution error"; + err_check(retval, DSP5680XX_ERROR_FM_EXEC, msg); + } + return ERROR_OK; } /** @@ -1435,41 +1739,51 @@ if (pmem) { */ static int set_fm_ck_div(struct target *target) { - uint8_t i[2]; - int retval; - retval = core_move_long_to_r2(target,HFM_BASE_ADDR); - err_check_propagate(retval); - retval = core_load_TX_RX_high_addr_to_r0(target); - err_check_propagate(retval); - retval = core_move_at_r2_to_y0(target);// read HFM_CLKD - err_check_propagate(retval); - retval = core_move_y0_at_r0(target); - err_check_propagate(retval); - retval = core_rx_upper_data(target,i); - err_check_propagate(retval); - unsigned int hfm_at_wrong_value = 0; - if ((i[0]&0x7f)!=HFM_CLK_DEFAULT) { - LOG_DEBUG("HFM CLK divisor contained incorrect value (0x%02X).",i[0]&0x7f); - hfm_at_wrong_value = 1; -} else { - LOG_DEBUG("HFM CLK divisor was already set to correct value (0x%02X).",i[0]&0x7f); - return ERROR_OK; - } - retval = core_move_value_at_r2(target,HFM_CLK_DEFAULT); // write HFM_CLKD - err_check_propagate(retval); - retval = core_move_at_r2_to_y0(target); // verify HFM_CLKD - err_check_propagate(retval); - retval = core_move_y0_at_r0(target); - err_check_propagate(retval); - retval = core_rx_upper_data(target,i); - err_check_propagate(retval); - if (i[0]!=(0x80|(HFM_CLK_DEFAULT&0x7f))) { - retval = ERROR_TARGET_FAILURE; - err_check(retval, DSP5680XX_ERROR_FM_SET_CLK, "Unable to set HFM CLK divisor."); - } -if (hfm_at_wrong_value) - LOG_DEBUG("HFM CLK divisor set to 0x%02x.", i[0]&0x7f); -return ERROR_OK; + uint8_t i[2]; + + int retval; + + retval = core_move_long_to_r2(target, HFM_BASE_ADDR); + err_check_propagate(retval); + retval = core_load_TX_RX_high_addr_to_r0(target); + err_check_propagate(retval); + /* read HFM_CLKD */ + retval = core_move_at_r2_to_y0(target); + err_check_propagate(retval); + retval = core_move_y0_at_r0(target); + err_check_propagate(retval); + retval = core_rx_upper_data(target, i); + err_check_propagate(retval); + unsigned int hfm_at_wrong_value = 0; + + if ((i[0] & 0x7f) != HFM_CLK_DEFAULT) { + LOG_DEBUG("HFM CLK divisor contained incorrect value (0x%02X).", + i[0] & 0x7f); + hfm_at_wrong_value = 1; + } else { + LOG_DEBUG + ("HFM CLK divisor was already set to correct value (0x%02X).", + i[0] & 0x7f); + return ERROR_OK; + } + /* write HFM_CLKD */ + retval = core_move_value_at_r2(target, HFM_CLK_DEFAULT); + err_check_propagate(retval); + /* verify HFM_CLKD */ + retval = core_move_at_r2_to_y0(target); + err_check_propagate(retval); + retval = core_move_y0_at_r0(target); + err_check_propagate(retval); + retval = core_rx_upper_data(target, i); + err_check_propagate(retval); + if (i[0] != (0x80 | (HFM_CLK_DEFAULT & 0x7f))) { + retval = ERROR_TARGET_FAILURE; + err_check(retval, DSP5680XX_ERROR_FM_SET_CLK, + "Unable to set HFM CLK divisor."); + } + if (hfm_at_wrong_value) + LOG_DEBUG("HFM CLK divisor set to 0x%02x.", i[0] & 0x7f); + return ERROR_OK; } /** @@ -1482,44 +1796,59 @@ return ERROR_OK; * * @return */ -static int dsp5680xx_f_signature(struct target *t, uint32_t a, uint32_t words, uint16_t * signature) +static int dsp5680xx_f_signature(struct target *t, uint32_t a, uint32_t words, + uint16_t *signature) { -struct target *target = t; -uint32_t address = a; - int retval; - uint16_t hfm_ustat; -if (!dsp5680xx_context.debug_mode_enabled) { - retval = eonce_enter_debug_mode_without_reset(target, NULL); - /** - * Generate error here, since it is not done in eonce_enter_debug_mode_without_reset - */ - err_check(retval, DSP5680XX_ERROR_HALT, "Failed to halt target."); -} -retval = dsp5680xx_f_ex(target, HFM_CALCULATE_DATA_SIGNATURE, address, words, &hfm_ustat, 1); - err_check_propagate(retval); - retval = dsp5680xx_read_16_single(target, HFM_BASE_ADDR|HFM_DATA, (uint8_t *)signature, 0); - return retval; + struct target *target = t; + + uint32_t address = a; + + int retval; + + uint16_t hfm_ustat; + + if (!dsp5680xx_context.debug_mode_enabled) { + retval = eonce_enter_debug_mode_without_reset(target, NULL); + /* + * Generate error here, since it is not done in eonce_enter_debug_mode_without_reset + */ + err_check(retval, DSP5680XX_ERROR_HALT, + "Failed to halt target."); + } + retval = + dsp5680xx_f_ex(target, HFM_CALCULATE_DATA_SIGNATURE, address, words, + &hfm_ustat, 1); + err_check_propagate(retval); + retval = + dsp5680xx_read_16_single(target, HFM_BASE_ADDR | HFM_DATA, + (uint8_t *) signature, 0); + return retval; } -int dsp5680xx_f_erase_check(struct target *target, uint8_t *erased, uint32_t sector) +int dsp5680xx_f_erase_check(struct target *target, uint8_t *erased, + uint32_t sector) { - int retval; - uint16_t hfm_ustat; -uint32_t tmp; -if (!dsp5680xx_context.debug_mode_enabled) { - retval = dsp5680xx_halt(target); + int retval; + + uint16_t hfm_ustat; + + uint32_t tmp; + + if (!dsp5680xx_context.debug_mode_enabled) { + retval = dsp5680xx_halt(target); + err_check_propagate(retval); + } + retval = set_fm_ck_div(target); err_check_propagate(retval); -} - retval = set_fm_ck_div(target); - err_check_propagate(retval); - /** - * Check if chip is already erased. - */ -tmp = HFM_FLASH_BASE_ADDR+sector*HFM_SECTOR_SIZE/2; -retval = dsp5680xx_f_ex(target, HFM_ERASE_VERIFY, tmp, 0, &hfm_ustat, 1); - err_check_propagate(retval); -if (erased != NULL) - *erased = (uint8_t)(hfm_ustat&HFM_USTAT_MASK_BLANK); + /* + * Check if chip is already erased. + */ + tmp = HFM_FLASH_BASE_ADDR + sector * HFM_SECTOR_SIZE / 2; + retval = + dsp5680xx_f_ex(target, HFM_ERASE_VERIFY, tmp, 0, &hfm_ustat, 1); + err_check_propagate(retval); + if (erased != NULL) + *erased = (uint8_t) (hfm_ustat & HFM_USTAT_MASK_BLANK); return retval; } @@ -1534,11 +1863,13 @@ if (erased != NULL) */ static int erase_sector(struct target *target, int sector, uint16_t *hfm_ustat) { -int retval; -uint32_t tmp = HFM_FLASH_BASE_ADDR+sector*HFM_SECTOR_SIZE/2; -retval = dsp5680xx_f_ex(target, HFM_PAGE_ERASE, tmp, 0, hfm_ustat, 1); - err_check_propagate(retval); - return retval; + int retval; + + uint32_t tmp = HFM_FLASH_BASE_ADDR + sector * HFM_SECTOR_SIZE / 2; + + retval = dsp5680xx_f_ex(target, HFM_PAGE_ERASE, tmp, 0, hfm_ustat, 1); + err_check_propagate(retval); + return retval; } /** @@ -1551,357 +1882,416 @@ retval = dsp5680xx_f_ex(target, HFM_PAGE_ERASE, tmp, 0, hfm_ustat, 1); */ static int mass_erase(struct target *target, uint16_t *hfm_ustat) { - int retval; -retval = dsp5680xx_f_ex(target, HFM_MASS_ERASE, 0, 0, hfm_ustat, 1); - return retval; + int retval; + + retval = dsp5680xx_f_ex(target, HFM_MASS_ERASE, 0, 0, hfm_ustat, 1); + return retval; } int dsp5680xx_f_erase(struct target *target, int first, int last) { - int retval; -if (!dsp5680xx_context.debug_mode_enabled) { - retval = dsp5680xx_halt(target); + int retval; + + if (!dsp5680xx_context.debug_mode_enabled) { + retval = dsp5680xx_halt(target); + err_check_propagate(retval); + } + /* + * Reset SIM + * + */ + retval = dsp5680xx_f_SIM_reset(target); err_check_propagate(retval); -} - // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - // Reset SIM - // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - retval = dsp5680xx_f_SIM_reset(target); - err_check_propagate(retval); - // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - // Set hfmdiv - // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - retval = set_fm_ck_div(target); - err_check_propagate(retval); - - uint16_t hfm_ustat; - int do_mass_erase = ((!(first|last)) || ((first==0)&&(last == (HFM_SECTOR_COUNT-1)))); -if (do_mass_erase) { - /* Mass erase */ - retval = mass_erase(target, &hfm_ustat); - err_check_propagate(retval); -} else { - for (int i = first; i <= last; i++) { - retval = erase_sector(target, i, &hfm_ustat); + /* + * Set hfmdiv + * + */ + retval = set_fm_ck_div(target); + err_check_propagate(retval); + + uint16_t hfm_ustat; + + int do_mass_erase = ((!(first | last)) + || ((first == 0) + && (last == (HFM_SECTOR_COUNT - 1)))); + if (do_mass_erase) { + /* Mass erase */ + retval = mass_erase(target, &hfm_ustat); err_check_propagate(retval); + } else { + for (int i = first; i <= last; i++) { + retval = erase_sector(target, i, &hfm_ustat); + err_check_propagate(retval); + } } -} - return ERROR_OK; + return ERROR_OK; } -/** +/* * Algorithm for programming normal p: flash * Follow state machine from "56F801x Peripheral Reference Manual"@163. * Registers to set up before calling: -* r0: TX/RX high address. -* r2: FM module base address. -* r3: Destination address in flash. -* -* hfm_wait: // wait for buffer empty -* brclr #0x80,x:(r2+0x13),hfm_wait -* rx_check: // wait for input buffer full -* brclr #0x01,x:(r0-2),rx_check -* move.w x:(r0),y0 // read from Rx buffer -* move.w y0,p:(r3)+ -* move.w #0x20,x:(r2+0x14) // write PGM command -* move.w #0x80,x:(r2+0x13) // start the command -* move.w X:(R2+0x13),A // Read USTAT register -* brclr #0x20,A,accerr_check // protection violation check -* bfset #0x20,X:(R2+0x13) // clear pviol -* bra hfm_wait -* accerr_check: -* brclr #0x10,A,hfm_wait // access error check -* bfset #0x10,X:(R2+0x13) // clear accerr -* bra hfm_wait // loop -*0x00000000 0x8A460013807D brclr #0x80,X:(R2+0x13),*+0 -*0x00000003 0xE700 nop -*0x00000004 0xE700 nop -*0x00000005 0x8A44FFFE017B brclr #1,X:(R0-2),*-2 -*0x00000008 0xE700 nop -*0x00000009 0xF514 move.w X:(R0),Y0 -*0x0000000A 0x8563 move.w Y0,P:(R3)+ -*0x0000000B 0x864600200014 move.w #32,X:(R2+0x14) -*0x0000000E 0x864600800013 move.w #128,X:(R2+0x13) -*0x00000011 0xF0420013 move.w X:(R2+0x13),A -*0x00000013 0x8B402004 brclr #0x20,A,*+6 -*0x00000015 0x824600130020 bfset #0x20,X:(R2+0x13) -*0x00000018 0xA967 bra *-24 -*0x00000019 0x8B401065 brclr #0x10,A,*-25 -*0x0000001B 0x824600130010 bfset #0x10,X:(R2+0x13) -*0x0000001E 0xA961 bra *-30 -*/ - -const uint16_t pgm_write_pflash[] = {0x8A46, 0x0013, 0x807D, 0xE700,\ - 0xE700, 0x8A44, 0xFFFE, 0x017B,\ - 0xE700, 0xF514, 0x8563, 0x8646,\ - 0x0020, 0x0014, 0x8646, 0x0080,\ - 0x0013, 0xF042, 0x0013, 0x8B40,\ - 0x2004, 0x8246, 0x0013, 0x0020,\ - 0xA967, 0x8B40, 0x1065, 0x8246,\ - 0x0013, 0x0010, 0xA961}; + * r0: TX/RX high address. + * r2: FM module base address. + * r3: Destination address in flash. + * + * hfm_wait: // wait for buffer empty + * brclr #0x80, x:(r2+0x13), hfm_wait + * rx_check: // wait for input buffer full + * brclr #0x01, x:(r0-2), rx_check + * move.w x:(r0), y0 // read from Rx buffer + * move.w y0, p:(r3)+ + * move.w #0x20, x:(r2+0x14) // write PGM command + * move.w #0x80, x:(r2+0x13) // start the command + * move.w X:(R2+0x13), A // Read USTAT register + * brclr #0x20, A, accerr_check // protection violation check + * bfset #0x20, X:(R2+0x13) // clear pviol + * bra hfm_wait + * accerr_check: + * brclr #0x10, A, hfm_wait // access error check + * bfset #0x10, X:(R2+0x13) // clear accerr + * bra hfm_wait // loop + * 0x00000000 0x8A460013807D brclr #0x80, X:(R2+0x13),*+0 + * 0x00000003 0xE700 nop + * 0x00000004 0xE700 nop + * 0x00000005 0x8A44FFFE017B brclr #1, X:(R0-2),*-2 + * 0x00000008 0xE700 nop + * 0x00000009 0xF514 move.w X:(R0), Y0 + * 0x0000000A 0x8563 move.w Y0, P:(R3)+ + * 0x0000000B 0x864600200014 move.w #32, X:(R2+0x14) + * 0x0000000E 0x864600800013 move.w #128, X:(R2+0x13) + * 0x00000011 0xF0420013 move.w X:(R2+0x13), A + * 0x00000013 0x8B402004 brclr #0x20, A,*+6 + * 0x00000015 0x824600130020 bfset #0x20, X:(R2+0x13) + * 0x00000018 0xA967 bra *-24 + * 0x00000019 0x8B401065 brclr #0x10, A,*-25 + * 0x0000001B 0x824600130010 bfset #0x10, X:(R2+0x13) + * 0x0000001E 0xA961 bra *-30 + */ + +const uint16_t pgm_write_pflash[] = { 0x8A46, 0x0013, 0x807D, 0xE700, + 0xE700, 0x8A44, 0xFFFE, 0x017B, + 0xE700, 0xF514, 0x8563, 0x8646, + 0x0020, 0x0014, 0x8646, 0x0080, + 0x0013, 0xF042, 0x0013, 0x8B40, + 0x2004, 0x8246, 0x0013, 0x0020, + 0xA967, 0x8B40, 0x1065, 0x8246, + 0x0013, 0x0010, 0xA961 +}; + const uint32_t pgm_write_pflash_length = 31; -int dsp5680xx_f_wr(struct target *t, uint8_t *b, uint32_t a, uint32_t count, int is_flash_lock) +int dsp5680xx_f_wr(struct target *t, const uint8_t *b, uint32_t a, uint32_t count, + int is_flash_lock) { -struct target *target = t; -uint32_t address = a; -uint8_t *buffer = b; - int retval = ERROR_OK; -if (!dsp5680xx_context.debug_mode_enabled) { - retval = eonce_enter_debug_mode(target, NULL); + struct target *target = t; + + uint32_t address = a; + + const uint8_t *buffer = b; + + int retval = ERROR_OK; + + if (!dsp5680xx_context.debug_mode_enabled) { + retval = eonce_enter_debug_mode(target, NULL); + err_check_propagate(retval); + } + /* + * Download the pgm that flashes. + * + */ + const uint32_t len = pgm_write_pflash_length; + + uint32_t ram_addr = 0x8700; + + /* + * This seems to be a safe address. + * This one is the one used by codewarrior in 56801x_flash.cfg + */ + if (!is_flash_lock) { + retval = + dsp5680xx_write(target, ram_addr, 1, len * 2, + (uint8_t *) pgm_write_pflash); + err_check_propagate(retval); + retval = dsp5680xx_execute_queue(); + err_check_propagate(retval); + } + /* + * Set hfmdiv + * + */ + retval = set_fm_ck_div(target); err_check_propagate(retval); -} - // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - // Download the pgm that flashes. - // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -const uint32_t len = pgm_write_pflash_length; -uint32_t ram_addr = 0x8700; -/** - * This seems to be a safe address. - * This one is the one used by codewarrior in 56801x_flash.cfg - */ -if (!is_flash_lock) { - retval = dsp5680xx_write(target, ram_addr, 1, len*2, (uint8_t *) pgm_write_pflash); + /* + * Setup registers needed by pgm_write_pflash + * + */ + + dsp5680xx_context.flush = 0; + + retval = core_move_long_to_r3(target, address); /* Destination address to r3 */ err_check_propagate(retval); - retval = dsp5680xx_execute_queue(); + core_load_TX_RX_high_addr_to_r0(target); /* TX/RX reg address to r0 */ err_check_propagate(retval); -} - // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - // Set hfmdiv - // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - retval = set_fm_ck_div(target); - err_check_propagate(retval); - // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - // Setup registers needed by pgm_write_pflash - // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - - dsp5680xx_context.flush = 0; - - retval = core_move_long_to_r3(target,address); // Destination address to r3 - err_check_propagate(retval); - core_load_TX_RX_high_addr_to_r0(target); // TX/RX reg address to r0 - err_check_propagate(retval); - retval = core_move_long_to_r2(target,HFM_BASE_ADDR);// FM base address to r2 - err_check_propagate(retval); - // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - // Run flashing program. - // -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - retval = core_move_value_at_r2_disp(target,0x00,HFM_CNFG); // write to HFM_CNFG (lock=0, select bank) - err_check_propagate(retval); - retval = core_move_value_at_r2_disp(target,0x04,HFM_USTAT);// write to HMF_USTAT, clear PVIOL, ACCERR & BLANK bits - err_check_propagate(retval); - retval = core_move_value_at_r2_disp(target,0x10,HFM_USTAT);// clear only one bit at a time - err_check_propagate(retval); - retval = core_move_value_at_r2_disp(target,0x20,HFM_USTAT); - err_check_propagate(retval); - retval = core_move_value_at_r2_disp(target,0x00,HFM_PROT);// write to HMF_PROT, clear protection - err_check_propagate(retval); - retval = core_move_value_at_r2_disp(target,0x00,HFM_PROTB);// write to HMF_PROTB, clear protection - err_check_propagate(retval); -if (count%2) { - /* TODO implement handling of odd number of words. */ - retval = ERROR_FAIL; - const char *msg = "Cannot handle odd number of words."; - err_check(retval, DSP5680XX_ERROR_FLASHING_INVALID_WORD_COUNT, msg); -} + retval = core_move_long_to_r2(target, HFM_BASE_ADDR); /* FM base address to r2 */ + err_check_propagate(retval); + /* + * Run flashing program. + * + */ + /* write to HFM_CNFG (lock=0, select bank) */ + retval = core_move_value_at_r2_disp(target, 0x00, HFM_CNFG); + err_check_propagate(retval); + /* write to HMF_USTAT, clear PVIOL, ACCERR &BLANK bits */ + retval = core_move_value_at_r2_disp(target, 0x04, HFM_USTAT); + err_check_propagate(retval); + /* clear only one bit at a time */ + retval = core_move_value_at_r2_disp(target, 0x10, HFM_USTAT); + err_check_propagate(retval); + retval = core_move_value_at_r2_disp(target, 0x20, HFM_USTAT); + err_check_propagate(retval); + /* write to HMF_PROT, clear protection */ + retval = core_move_value_at_r2_disp(target, 0x00, HFM_PROT); + err_check_propagate(retval); + /* write to HMF_PROTB, clear protection */ + retval = core_move_value_at_r2_disp(target, 0x00, HFM_PROTB); + err_check_propagate(retval); + if (count % 2) { + /* TODO implement handling of odd number of words. */ + retval = ERROR_FAIL; + const char *msg = "Cannot handle odd number of words."; - dsp5680xx_context.flush = 1; - retval = dsp5680xx_execute_queue(); - err_check_propagate(retval); - - uint32_t drscan_data; - uint16_t tmp = (buffer[0]|(buffer[1]<<8)); -retval = core_tx_upper_data(target, tmp, &drscan_data); - err_check_propagate(retval); - -retval = dsp5680xx_resume(target, 0, ram_addr, 0, 0); - err_check_propagate(retval); - - int counter = FLUSH_COUNT_FLASH; - dsp5680xx_context.flush = 0; - uint32_t i; -for (i = 1; (i < count/2) && (i < HFM_SIZE_WORDS); i++) { - if (--counter == 0) { - dsp5680xx_context.flush = 1; - counter = FLUSH_COUNT_FLASH; + err_check(retval, DSP5680XX_ERROR_FLASHING_INVALID_WORD_COUNT, + msg); } - tmp = (buffer[2*i]|(buffer[2*i+1]<<8)); + + dsp5680xx_context.flush = 1; + retval = dsp5680xx_execute_queue(); + err_check_propagate(retval); + + uint32_t drscan_data; + + uint16_t tmp = (buffer[0] | (buffer[1] << 8)); + retval = core_tx_upper_data(target, tmp, &drscan_data); - if (retval != ERROR_OK) { - dsp5680xx_context.flush = 1; - err_check_propagate(retval); - } + err_check_propagate(retval); + + retval = dsp5680xx_resume(target, 0, ram_addr, 0, 0); + err_check_propagate(retval); + + int counter = FLUSH_COUNT_FLASH; + dsp5680xx_context.flush = 0; - } - dsp5680xx_context.flush = 1; -if (!is_flash_lock) { - /** -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - * Verify flash (skip when exec lock sequence) - * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- - */ - uint16_t signature; - uint16_t pc_crc; - retval = dsp5680xx_f_signature(target, address, i, &signature); - err_check_propagate(retval); - pc_crc = perl_crc(buffer, i); - if (pc_crc != signature) { - retval = ERROR_FAIL; - const char *msg = "Flashed data failed CRC check, flash again!"; - err_check(retval, DSP5680XX_ERROR_FLASHING_CRC, msg); + uint32_t i; + + for (i = 1; (i < count / 2) && (i < HFM_SIZE_WORDS); i++) { + if (--counter == 0) { + dsp5680xx_context.flush = 1; + counter = FLUSH_COUNT_FLASH; + } + tmp = (buffer[2 * i] | (buffer[2 * i + 1] << 8)); + retval = core_tx_upper_data(target, tmp, &drscan_data); + if (retval != ERROR_OK) { + dsp5680xx_context.flush = 1; + err_check_propagate(retval); + } + dsp5680xx_context.flush = 0; } -} -return retval; + dsp5680xx_context.flush = 1; + if (!is_flash_lock) { + /* + *Verify flash (skip when exec lock sequence) + * + */ + uint16_t signature; + + uint16_t pc_crc; + + retval = dsp5680xx_f_signature(target, address, i, &signature); + err_check_propagate(retval); + pc_crc = perl_crc(buffer, i); + if (pc_crc != signature) { + retval = ERROR_FAIL; + const char *msg = + "Flashed data failed CRC check, flash again!"; + err_check(retval, DSP5680XX_ERROR_FLASHING_CRC, msg); + } + } + return retval; } int dsp5680xx_f_unlock(struct target *target) { - int retval = ERROR_OK; - uint16_t eonce_status; - uint32_t instr; - uint32_t ir_out; - struct jtag_tap * tap_chp; - struct jtag_tap * tap_cpu; - tap_chp = jtag_tap_by_string("dsp568013.chp"); -if (tap_chp == NULL) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_MASTER, "Failed to get master tap."); -} - tap_cpu = jtag_tap_by_string("dsp568013.cpu"); -if (tap_cpu == NULL) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_CORE, "Failed to get master tap."); -} + int retval = ERROR_OK; + + uint16_t eonce_status; + + uint32_t instr; + + uint32_t ir_out; + + struct jtag_tap *tap_chp; + + struct jtag_tap *tap_cpu; + + tap_chp = jtag_tap_by_string("dsp568013.chp"); + if (tap_chp == NULL) { + retval = ERROR_FAIL; + err_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_MASTER, + "Failed to get master tap."); + } + tap_cpu = jtag_tap_by_string("dsp568013.cpu"); + if (tap_cpu == NULL) { + retval = ERROR_FAIL; + err_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_CORE, + "Failed to get master tap."); + } + + retval = eonce_enter_debug_mode_without_reset(target, &eonce_status); + if (retval == ERROR_OK) + LOG_WARNING("Memory was not locked."); + + jtag_add_reset(0, 1); + jtag_add_sleep(TIME_DIV_FREESCALE * 200 * 1000); + + retval = reset_jtag(); + err_check(retval, DSP5680XX_ERROR_JTAG_RESET, + "Failed to reset JTAG state machine"); + jtag_add_sleep(150); + + /* Enable core tap */ + tap_chp->enabled = true; + retval = switch_tap(target, tap_chp, tap_cpu); + err_check_propagate(retval); + + instr = JTAG_INSTR_DEBUG_REQUEST; + retval = + dsp5680xx_irscan(target, &instr, &ir_out, + DSP5680XX_JTAG_CORE_TAP_IRLEN); + err_check_propagate(retval); + jtag_add_sleep(TIME_DIV_FREESCALE * 100 * 1000); + jtag_add_reset(0, 0); + jtag_add_sleep(TIME_DIV_FREESCALE * 300 * 1000); + + /* Enable master tap */ + tap_chp->enabled = false; + retval = switch_tap(target, tap_chp, tap_cpu); + err_check_propagate(retval); + + /* Execute mass erase to unlock */ + instr = MASTER_TAP_CMD_FLASH_ERASE; + retval = + dsp5680xx_irscan(target, &instr, &ir_out, + DSP5680XX_JTAG_MASTER_TAP_IRLEN); + err_check_propagate(retval); + + instr = HFM_CLK_DEFAULT; + retval = dsp5680xx_drscan(target, (uint8_t *) &instr, (uint8_t *) &ir_out, 16); + err_check_propagate(retval); + + jtag_add_sleep(TIME_DIV_FREESCALE * 150 * 1000); + jtag_add_reset(0, 1); + jtag_add_sleep(TIME_DIV_FREESCALE * 200 * 1000); -retval = eonce_enter_debug_mode_without_reset(target, &eonce_status); -if (retval == ERROR_OK) - LOG_WARNING("Memory was not locked."); - - jtag_add_reset(0,1); - jtag_add_sleep(TIME_DIV_FREESCALE*200*1000); - - retval = reset_jtag(); - err_check(retval, DSP5680XX_ERROR_JTAG_RESET, "Failed to reset JTAG state machine"); - jtag_add_sleep(150); - - // Enable core tap - tap_chp->enabled = true; - retval = switch_tap(target,tap_chp,tap_cpu); - err_check_propagate(retval); - - instr = JTAG_INSTR_DEBUG_REQUEST; - retval = dsp5680xx_irscan(target, & instr, & ir_out,DSP5680XX_JTAG_CORE_TAP_IRLEN); - err_check_propagate(retval); - jtag_add_sleep(TIME_DIV_FREESCALE*100*1000); - jtag_add_reset(0,0); - jtag_add_sleep(TIME_DIV_FREESCALE*300*1000); - - // Enable master tap - tap_chp->enabled = false; - retval = switch_tap(target,tap_chp,tap_cpu); - err_check_propagate(retval); - - // Execute mass erase to unlock - instr = MASTER_TAP_CMD_FLASH_ERASE; - retval = dsp5680xx_irscan(target, & instr, & ir_out,DSP5680XX_JTAG_MASTER_TAP_IRLEN); - err_check_propagate(retval); - - instr = HFM_CLK_DEFAULT; - retval = dsp5680xx_drscan(target,(uint8_t *) & instr,(uint8_t *) & ir_out,16); - err_check_propagate(retval); - - jtag_add_sleep(TIME_DIV_FREESCALE*150*1000); - jtag_add_reset(0,1); - jtag_add_sleep(TIME_DIV_FREESCALE*200*1000); - - retval = reset_jtag(); - err_check(retval, DSP5680XX_ERROR_JTAG_RESET, "Failed to reset JTAG state machine"); - jtag_add_sleep(150); - - instr = 0x0606ffff; - retval = dsp5680xx_drscan(target,(uint8_t *) & instr,(uint8_t *) & ir_out,32); - err_check_propagate(retval); - - // enable core tap - 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); - - tap_cpu->enabled = true; - tap_chp->enabled = false; -target->state = TARGET_RUNNING; -dsp5680xx_context.debug_mode_enabled = false; - return retval; + retval = reset_jtag(); + err_check(retval, DSP5680XX_ERROR_JTAG_RESET, + "Failed to reset JTAG state machine"); + jtag_add_sleep(150); + + instr = 0x0606ffff; + retval = dsp5680xx_drscan(target, (uint8_t *) &instr, (uint8_t *) &ir_out, + 32); + err_check_propagate(retval); + + /* enable core tap */ + 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); + + tap_cpu->enabled = true; + tap_chp->enabled = false; + target->state = TARGET_RUNNING; + dsp5680xx_context.debug_mode_enabled = false; + return retval; } int dsp5680xx_f_lock(struct target *target) { - int retval; -struct jtag_tap *tap_chp; -struct jtag_tap *tap_cpu; - uint16_t lock_word[] = {HFM_LOCK_FLASH}; - retval = dsp5680xx_f_wr(target,(uint8_t *)(lock_word),HFM_LOCK_ADDR_L,2,1); - err_check_propagate(retval); - - jtag_add_reset(0,1); - jtag_add_sleep(TIME_DIV_FREESCALE*200*1000); - - retval = reset_jtag(); - err_check(retval, DSP5680XX_ERROR_JTAG_RESET, "Failed to reset JTAG state machine"); - jtag_add_sleep(TIME_DIV_FREESCALE*100*1000); - jtag_add_reset(0,0); - jtag_add_sleep(TIME_DIV_FREESCALE*300*1000); - -tap_chp = jtag_tap_by_string("dsp568013.chp"); -if (tap_chp == NULL) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_MASTER, "Failed to get master tap."); -} -tap_cpu = jtag_tap_by_string("dsp568013.cpu"); -if (tap_cpu == NULL) { - retval = ERROR_FAIL; - err_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_CORE, "Failed to get master tap."); -} -target->state = TARGET_RUNNING; -dsp5680xx_context.debug_mode_enabled = false; -tap_cpu->enabled = false; -tap_chp->enabled = true; -retval = switch_tap(target, tap_chp, tap_cpu); -return retval; + int retval; + + struct jtag_tap *tap_chp; + + struct jtag_tap *tap_cpu; + uint16_t lock_word[] = { HFM_LOCK_FLASH }; + retval = dsp5680xx_f_wr(target, (uint8_t *) (lock_word), HFM_LOCK_ADDR_L, 2, 1); + err_check_propagate(retval); + + jtag_add_reset(0, 1); + jtag_add_sleep(TIME_DIV_FREESCALE * 200 * 1000); + + retval = reset_jtag(); + err_check(retval, DSP5680XX_ERROR_JTAG_RESET, + "Failed to reset JTAG state machine"); + jtag_add_sleep(TIME_DIV_FREESCALE * 100 * 1000); + jtag_add_reset(0, 0); + jtag_add_sleep(TIME_DIV_FREESCALE * 300 * 1000); + + tap_chp = jtag_tap_by_string("dsp568013.chp"); + if (tap_chp == NULL) { + retval = ERROR_FAIL; + err_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_MASTER, + "Failed to get master tap."); + } + tap_cpu = jtag_tap_by_string("dsp568013.cpu"); + if (tap_cpu == NULL) { + retval = ERROR_FAIL; + err_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_CORE, + "Failed to get master tap."); + } + target->state = TARGET_RUNNING; + dsp5680xx_context.debug_mode_enabled = false; + tap_cpu->enabled = false; + tap_chp->enabled = true; + retval = switch_tap(target, tap_chp, tap_cpu); + return retval; } -static int dsp5680xx_step(struct target * target,int current, uint32_t address, int handle_breakpoints){ - err_check(ERROR_FAIL, DSP5680XX_ERROR_NOT_IMPLEMENTED_STEP, "Not implemented yet."); +static int dsp5680xx_step(struct target *target, int current, target_addr_t address, + int handle_breakpoints) +{ + err_check(ERROR_FAIL, DSP5680XX_ERROR_NOT_IMPLEMENTED_STEP, + "Not implemented yet."); } /** Holds methods for dsp5680xx targets. */ struct target_type dsp5680xx_target = { - .name = "dsp5680xx", - - .poll = dsp5680xx_poll, - .arch_state = dsp5680xx_arch_state, + .name = "dsp5680xx", - .target_request_data = NULL, + .poll = dsp5680xx_poll, + .arch_state = dsp5680xx_arch_state, - .halt = dsp5680xx_halt, - .resume = dsp5680xx_resume, - .step = dsp5680xx_step, + .halt = dsp5680xx_halt, + .resume = dsp5680xx_resume, + .step = dsp5680xx_step, - .write_buffer = dsp5680xx_write_buffer, - .read_buffer = dsp5680xx_read_buffer, + .write_buffer = dsp5680xx_write_buffer, + .read_buffer = dsp5680xx_read_buffer, - .assert_reset = dsp5680xx_assert_reset, - .deassert_reset = dsp5680xx_deassert_reset, - .soft_reset_halt = dsp5680xx_soft_reset_halt, + .assert_reset = dsp5680xx_assert_reset, + .deassert_reset = dsp5680xx_deassert_reset, + .soft_reset_halt = dsp5680xx_soft_reset_halt, - .read_memory = dsp5680xx_read, - .write_memory = dsp5680xx_write, - .bulk_write_memory = dsp5680xx_bulk_write_memory, + .read_memory = dsp5680xx_read, + .write_memory = dsp5680xx_write, - .checksum_memory = dsp5680xx_checksum_memory, + .checksum_memory = dsp5680xx_checksum_memory, - .target_create = dsp5680xx_target_create, - .init_target = dsp5680xx_init_target, + .target_create = dsp5680xx_target_create, + .init_target = dsp5680xx_init_target, };