aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRodrigo L. Rosa <rodrigorosa.lg@gmail.com>2011-06-10 12:24:27 -0700
committerØyvind Harboe <oyvind.harboe@zylin.com>2011-06-12 11:18:27 +0200
commitd343941386bfa274cd64f8f384fc51a695f9f626 (patch)
treeee7e66cf02753070cf8d2dcdf741ceaf9a0939ac /src
parentcbe201fe6bb2f004957ff8174b53c6d4ecd5bae6 (diff)
doxy & cleanup
Diffstat (limited to 'src')
-rw-r--r--src/flash/nor/dsp5680xx_flash.c92
-rw-r--r--src/target/dsp5680xx.c768
-rw-r--r--src/target/dsp5680xx.h79
3 files changed, 593 insertions, 346 deletions
diff --git a/src/flash/nor/dsp5680xx_flash.c b/src/flash/nor/dsp5680xx_flash.c
index b919f564..4ed72066 100644
--- a/src/flash/nor/dsp5680xx_flash.c
+++ b/src/flash/nor/dsp5680xx_flash.c
@@ -23,6 +23,19 @@
* 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
***************************************************************************/
+/**
+ * @file dsp5680xx_flash.c
+ * @author Rodrigo L. Rosa <rodrigorosa.LG@gmail.com>
+ * @date Thu Jun 9 18:21:58 2011
+ *
+ * @brief This file implements the basic functions to run flashing commands
+ * from the TCL interface.
+ * It allows the user to flash the Freescale 5680xx DSP.
+ *
+ *
+ */
+
+
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
@@ -71,6 +84,15 @@ FLASH_BANK_COMMAND_HANDLER(dsp5680xx_flash_bank_command){
return ERROR_OK;
}
+/**
+ * A memory mapped register (PROT) holds information regarding sector protection.
+ * Protection refers to undesired core access.
+ * The value in this register is loaded from flash upon reset.
+ *
+ * @param bank
+ *
+ * @return
+ */
static int dsp5680xx_flash_protect_check(struct flash_bank *bank){
int retval = ERROR_OK;
uint16_t protected = 0;
@@ -93,6 +115,18 @@ static int dsp5680xx_flash_protect_check(struct flash_bank *bank){
return retval;
}
+/**
+ * Protection funcionality is not implemented.
+ * The current implementation applies/removes security on the chip.
+ * The chip is effectively secured/unsecured after the first reset following the execution of this function.
+ *
+ * @param bank
+ * @param set Apply or remove security on the chip.
+ * @param first This parameter is ignored.
+ * @param last This parameter is ignored.
+ *
+ * @return
+ */
static int dsp5680xx_flash_protect(struct flash_bank *bank, int set, int first, int last){
// This applies security to flash module after next reset, it does not actually apply protection (protection refers to undesired access from the core)
int retval;
@@ -103,24 +137,16 @@ static int dsp5680xx_flash_protect(struct flash_bank *bank, int set, int first,
return retval;
}
-/*
-static int dsp5680xx_write_block(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count){
- LOG_USER("%s not implemented",__FUNCTION__);
- return ERROR_OK;
-}
-
-static int dsp5680xx_write_single(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count){
- LOG_USER("%s not implemented",__FUNCTION__);
- return ERROR_OK;
-}
-*/
-
-//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-// Flash stuff test
-//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-//-- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
-
+/**
+ * The dsp5680xx use word addressing. The "/2" that appear in the following code are a workaround for the fact that OpenOCD uses byte addressing.
+ *
+ * @param bank
+ * @param buffer Data to write to flash.
+ * @param offset
+ * @param count In bytes (2 bytes per address).
+ *
+ * @return
+ */
static int dsp5680xx_flash_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count){
int retval;
if((offset + count/2)>bank->size){
@@ -151,19 +177,17 @@ static int dsp5680xx_flash_info(struct flash_bank *bank, char *buf, int buf_size
snprintf(buf, buf_size, "\ndsp5680xx flash driver info:\n - Currently only full erase/lock/unlock are implemented. \n - Call with bank==0 and sector 0 to 0.\n - Protect requires arp_init-reset to complete. \n - Before removing protection the master tap must be selected, and arp_init-reset is required to complete unlocking.");
return ERROR_OK;
}
-/*
-static int dsp5680xx_set_write_enable(struct target *target, int enable){
- LOG_USER("%s not implemented",__FUNCTION__);
- return ERROR_OK;
-}
-
-
-static int dsp5680xx_check_flash_completion(struct target* target, unsigned int timeout_ms){
- LOG_USER("%s not implemented",__FUNCTION__);
- return ERROR_OK;
-}
-*/
+/**
+ * The flash module (FM) on the dsp5680xx supports both individual sector and mass erase of the flash memory.
+ * If this function is called with @first == @last == 0 or if @first is the first sector (#0) and @last is the last sector then the mass erase command is executed (much faster than erasing each sector individually).
+ *
+ * @param bank
+ * @param first
+ * @param last
+ *
+ * @return
+ */
static int dsp5680xx_flash_erase(struct flash_bank * bank, int first, int last){
int retval;
retval = dsp5680xx_f_erase(bank->target, (uint32_t) first, (uint32_t) last);
@@ -177,6 +201,14 @@ static int dsp5680xx_flash_erase(struct flash_bank * bank, int first, int last){
return retval;
}
+/**
+ * The flash module (FM) on the dsp5680xx support a blank check function.
+ * This function executes the FM's blank check functionality on each and every sector.
+ *
+ * @param bank
+ *
+ * @return
+ */
static int dsp5680xx_flash_erase_check(struct flash_bank * bank){
int retval = ERROR_OK;
uint8_t erased = 0;
diff --git a/src/target/dsp5680xx.c b/src/target/dsp5680xx.c
index f3f25a17..9afda424 100644
--- a/src/target/dsp5680xx.c
+++ b/src/target/dsp5680xx.c
@@ -31,18 +31,6 @@
#define err_check(retval,err_msg) if(retval != ERROR_OK){LOG_ERROR("%s: %d %s.",__FUNCTION__,__LINE__,err_msg);return retval;}
#define err_check_propagate(retval) if(retval!=ERROR_OK){return retval;}
-// Forward declarations, could try to optimize this.
-static int eonce_instruction_exec(struct target * target, uint8_t instr, uint8_t rw, uint8_t go, uint8_t ex, uint8_t * eonce_status);
-static int eonce_load_TX_RX_to_r0(struct target * target);
-static int eonce_enter_debug_mode(struct target * target, uint16_t * eonce_status);
-static int eonce_read_status_reg(struct target * target, uint16_t * data);
-static int eonce_pc_store(struct target * target);
-static int eonce_move_value_to_pc(struct target * target, uint32_t value);
-static int dsp5680xx_jtag_status(struct target *target, uint8_t * status);
-static int dsp5680xx_resume(struct target *target, int current, uint32_t address,int handle_breakpoints, int debug_execution);
-static int dsp5680xx_halt(struct target *target);
-static int dsp5680xx_write(struct target *target, uint32_t address, uint32_t size, uint32_t count, const uint8_t * buffer);
-
int dsp5680xx_execute_queue(void){
int retval;
retval = jtag_execute_queue();
@@ -50,14 +38,6 @@ int dsp5680xx_execute_queue(void){
return retval;
}
-static int eonce_exit_debug_mode(struct target * target,uint8_t * eonce_status){
- int retval;
- retval = eonce_instruction_exec(target,0x1F,0,0,1,eonce_status);
- err_check_propagate(retval);
- return retval;
-}
-
-
static int dsp5680xx_drscan(struct target * target, uint8_t * data_to_shift_into_dr, uint8_t * data_shifted_out_of_dr, int len){
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
//
@@ -115,116 +95,12 @@ static int dsp5680xx_irscan(struct target * target, uint32_t * data_to_shift_int
//is the casting necessary?
jtag_add_plain_ir_scan(ir_len,(uint8_t *)data_to_shift_into_ir,(uint8_t *)data_shifted_out_of_ir, TAP_IDLE);
if(context.flush){
- retval = dsp5680xx_execute_queue();
- err_check_propagate(retval);
+ retval = dsp5680xx_execute_queue();
+ err_check_propagate(retval);
}
return retval;
}
-static int dsp5680xx_read_core_reg(struct target * target, uint8_t reg_addr, uint16_t * data_read)
-{
- //TODO implement a general version of this which matches what openocd uses.
- int retval;
- uint32_t dummy_data_to_shift_into_dr;
- retval = eonce_instruction_exec(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 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_init_target(struct command_context *cmd_ctx, struct target *target){
- context.stored_pc = 0;
- context.flush = 1;
- 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_arch_state(struct target *target){
- LOG_USER("%s not implemented yet.",__FUNCTION__);
- return ERROR_OK;
-}
-
-int dsp5680xx_target_status(struct target * target, uint8_t * jtag_st, uint16_t * eonce_st){
- return target->state;
-}
-
-static int dsp5680xx_assert_reset(struct target *target){
- target->state = TARGET_RESET;
- return ERROR_OK;
-}
-
-static int dsp5680xx_deassert_reset(struct target *target){
- target->state = TARGET_RUNNING;
- return ERROR_OK;
-}
-
-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){
- LOG_WARNING("%s: Failed to put EOnCE in debug mode. Is flash locked?...",__FUNCTION__);
- 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){
- LOG_WARNING("%s: JTAG running, but cannot make EOnCE run. Try resetting...",__FUNCTION__);
- 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;
- }
- }
- target->state = TARGET_RUNNING;
- return ERROR_OK;
- }
- if(jtag_status == JTAG_STATUS_DEAD){
- LOG_ERROR("%s: Cannot communicate with JTAG. Check connection...",__FUNCTION__);
- target->state = TARGET_UNKNOWN;
- return ERROR_TARGET_FAILURE;
- };
- if (target->state == TARGET_UNKNOWN){
- LOG_ERROR("%s: Target status invalid - communication failure",__FUNCTION__);
- return ERROR_TARGET_FAILURE;
- };
- return ERROR_OK;
-}
-
static int dsp5680xx_jtag_status(struct target *target, uint8_t * status){
uint32_t read_from_ir;
uint32_t instr;
@@ -237,57 +113,6 @@ static int dsp5680xx_jtag_status(struct target *target, uint8_t * status){
return ERROR_OK;
}
-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 dsp5680xx_halt(struct target *target){
- int retval;
- uint16_t eonce_status;
- if(target->state == TARGET_HALTED){
- LOG_USER("Target already halted.");
- return ERROR_OK;
- }
- retval = eonce_enter_debug_mode(target,&eonce_status);
- err_check_propagate(retval);
- retval = eonce_pc_store(target);
- err_check_propagate(retval);
- //TODO is it useful to store the pc?
- return retval;
-}
-
-static int dsp5680xx_resume(struct target *target, int current, uint32_t address,int handle_breakpoints, int debug_execution){
- if(target->state == TARGET_RUNNING){
- LOG_USER("Target already running.");
- return ERROR_OK;
- }
- int retval;
- uint8_t eonce_status;
- if(!current){
- retval = eonce_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,"Failed to resume...");
- }else{
- target->state = TARGET_RUNNING;
- }
- LOG_DEBUG("EOnCE status: 0x%02X.",eonce_status);
- return ERROR_OK;
-}
-
static int jtag_data_read(struct target * target, uint32_t * data_read, int num_bits){
uint32_t bogus_instr;
int retval = dsp5680xx_drscan(target,(uint8_t *) & bogus_instr,(uint8_t *) data_read,num_bits);
@@ -314,37 +139,18 @@ static int jtag_data_write(struct target * target, uint32_t instr,int num_bits,
#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)
-static int eonce_enter_debug_mode(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);
- // 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.");
- target->state = TARGET_HALTED;
- return ERROR_OK;
- }else{
- retval = ERROR_TARGET_FAILURE;
- err_check(retval,"Failed to set EOnCE module to debug mode.");
- }
- if(eonce_status!=NULL)
- *eonce_status = data_read_from_dr;
- return ERROR_OK;
-}
+/**
+ * Executes DSP instruction.
+ *
+ * @param target
+ * @param instr Instruction to execute.
+ * @param rw
+ * @param go
+ * @param ex
+ * @param eonce_status Value read from the EOnCE status register.
+ *
+ * @return
+ */
static int eonce_instruction_exec(struct target * target, uint8_t instr, uint8_t rw, uint8_t go, uint8_t ex,uint8_t * eonce_status){
int retval;
@@ -357,15 +163,14 @@ static int eonce_instruction_exec(struct target * target, uint8_t instr, uint8_t
return retval;
}
-/* Executes DSP instruction */
-/* wrappers for parameter conversion between eonce_execute_instruction and eonce_execute_instructionX */
+///wrappers for parameter conversion between eonce_execute_instruction and eonce_execute_instructionX
+
#define eonce_execute_instruction_1(target,opcode1,opcode2,opcode3) eonce_execute_instruction1(target,opcode1)
#define eonce_execute_instruction_2(target,opcode1,opcode2,opcode3) eonce_execute_instruction2(target,opcode1,opcode2)
#define eonce_execute_instruction_3(target,opcode1,opcode2,opcode3) eonce_execute_instruction3(target,opcode1,opcode2,opcode3)
-/* the macro itself */
#define eonce_execute_instruction(target,words,opcode1,opcode2,opcode3) eonce_execute_instruction_##words(target,opcode1,opcode2,opcode3)
-/* Executes one word DSP instruction */
+/// Executes one word DSP instruction
static int eonce_execute_instruction1(struct target * target, uint16_t opcode){
int retval;
retval = eonce_instruction_exec(target,0x04,0,1,0,NULL);
@@ -375,7 +180,7 @@ static int eonce_execute_instruction1(struct target * target, uint16_t opcode){
return retval;
}
-/* Executes two word DSP instruction */
+/// Executes two word DSP instruction
static int eonce_execute_instruction2(struct target * target,uint16_t opcode1, uint16_t opcode2){
int retval;
retval = eonce_instruction_exec(target,0x04,0,0,0,NULL);
@@ -389,7 +194,7 @@ static int eonce_execute_instruction2(struct target * target,uint16_t opcode1, u
return retval;
}
-/* Executes three word DSP instruction */
+/// Executes three word DSP instruction
static int eonce_execute_instruction3(struct target * target, uint16_t opcode1,uint16_t opcode2,uint16_t opcode3){
int retval;
retval = eonce_instruction_exec(target,0x04,0,0,0,NULL);
@@ -407,15 +212,16 @@ static int eonce_execute_instruction3(struct target * target, uint16_t opcode1,u
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.
- 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
+/**
+ * --------------- 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 eonce_tx_upper_data(struct target * target, uint16_t data, uint32_t * eonce_status_low){
int retval;
retval = eonce_instruction_exec(target,DSP5680XX_ONCE_ORX1,0,0,0,NULL);
@@ -425,7 +231,7 @@ static int eonce_tx_upper_data(struct target * target, uint16_t data, uint32_t *
return retval;
}
-/* writes data into lower ORx register of the target */
+/// writes data into lower ORx register of the target
#define eonce_tx_lower_data(target,data) eonce_instruction_exec(target,DSP5680XX_ONCE_ORX,0,0,0,NULL);\
jtag_data_write16(target,data)
@@ -461,119 +267,124 @@ static int eonce_rx_lower_data(struct target * target,uint16_t * data_read)
return retval;
}
-/* -- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -*/
-/* -- -- -- -- --- -- -- -Core Instructions- -- -- -- --- -- -- -- --- -- -*/
-/* -- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -*/
-/* move.l #value,r0 */
+/**
+ * -- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- --
+ * -- -- -- -- --- -- -- -Core Instructions- -- -- -- --- -- -- -- --- --
+ * -- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- -- -- -- --- --
+ */
+
+/// move.l #value,r0
#define eonce_move_long_to_r0(target,value) eonce_execute_instruction(target,3,0xe418,value&0xffff,value>>16)
-/* move.l #value,n */
+/// move.l #value,n
#define eonce_move_long_to_n(target,value) eonce_execute_instruction(target,3,0xe41e,value&0xffff,value>>16)
-/* move x:(r0),y0 */
+/// move x:(r0),y0
#define eonce_move_at_r0_to_y0(target) eonce_execute_instruction(target,1,0xF514,0,0)
-/* move x:(r0),y1 */
+/// move x:(r0),y1
#define eonce_move_at_r0_to_y1(target) eonce_execute_instruction(target,1,0xF714,0,0)
-/* move.l x:(r0),y */
+/// move.l x:(r0),y
#define eonce_move_long_at_r0_y(target) eonce_execute_instruction(target,1,0xF734,0,0)
-/* move y0,x:(r0) */
+/// move y0,x:(r0)
#define eonce_move_y0_at_r0(target) eonce_execute_instruction(target,1,0xd514,0,0)
-/* bfclr #value,x:(r0) */
+/// bfclr #value,x:(r0)
#define eonce_bfclr_at_r0(target,value) eonce_execute_instruction(target,2,0x8040,value,0)
-/* move #value,y0 */
+/// move #value,y0
#define eonce_move_value_to_y0(target,value) eonce_execute_instruction(target,2,0x8745,value,0)
-/* move.w y0,x:(r0)+ */
+/// move.w y0,x:(r0)+
#define eonce_move_y0_at_r0_inc(target) eonce_execute_instruction(target,1,0xd500,0,0)
-/* move.w y0,p:(r0)+ */
+/// move.w y0,p:(r0)+
#define eonce_move_y0_at_pr0_inc(target) eonce_execute_instruction(target,1,0x8560,0,0)
-/* move.w p:(r0)+,y0 */
+/// move.w p:(r0)+,y0
#define eonce_move_at_pr0_inc_to_y0(target) eonce_execute_instruction(target,1,0x8568,0,0)
-/* move.w p:(r0)+,y1 */
+/// move.w p:(r0)+,y1
#define eonce_move_at_pr0_inc_to_y1(target) eonce_execute_instruction(target,1,0x8768,0,0)
-/* move.l #value,r2 */
+/// move.l #value,r2
#define eonce_move_long_to_r2(target,value) eonce_execute_instruction(target,3,0xe41A,value&0xffff,value>>16)
-/* move y0,x:(r2) */
+/// move y0,x:(r2)
#define eonce_move_y0_at_r2(target) eonce_execute_instruction(target,1,0xd516,0,0)
-/* move.w #<value>,x:(r2) */
+/// move.w #<value>,x:(r2)
#define eonce_move_value_at_r2(target,value) eonce_execute_instruction(target,2,0x8642,value,0)
-/* move.w #<value>,x:(r0) */
+/// move.w #<value>,x:(r0)
#define eonce_move_value_at_r0(target,value) eonce_execute_instruction(target,2,0x8640,value,0)
-/* move.w #<value>,x:(R2+<disp>) */
+/// move.w #<value>,x:(R2+<disp>)
#define eonce_move_value_at_r2_disp(target,value,disp) eonce_execute_instruction(target,3,0x8646,value,disp)
-/* move.w x:(r2),Y0 */
+/// move.w x:(r2),Y0
#define eonce_move_at_r2_to_y0(target) eonce_execute_instruction(target,1,0xF516,0,0)
-/* move.w p:(r2)+,y0 */
+/// move.w p:(r2)+,y0
#define eonce_move_at_pr2_inc_to_y0(target) eonce_execute_instruction(target,1,0x856A,0,0)
-/* move.l #value,r3 */
+/// move.l #value,r3
#define eonce_move_long_to_r1(target,value) eonce_execute_instruction(target,3,0xE419,value&0xffff,value>>16)
-/* move.l #value,r3 */
+/// move.l #value,r3
#define eonce_move_long_to_r3(target,value) eonce_execute_instruction(target,3,0xE41B,value&0xffff,value>>16)
-/* move.w y0,p:(r3)+ */
+/// move.w y0,p:(r3)+
#define eonce_move_y0_at_pr3_inc(target) eonce_execute_instruction(target,1,0x8563,0,0)
-/* move.w y0,x:(r3) */
+/// move.w y0,x:(r3)
#define eonce_move_y0_at_r3(target) eonce_execute_instruction(target,1,0xD503,0,0)
-/* move pc,r4 */
+/// move.l #value,r4
+#define eonce_move_long_to_r4(target,value) eonce_execute_instruction(target,3,0xE41C,value&0xffff,value>>16)
+
+/// move pc,r4
#define eonce_move_pc_to_r4(target) eonce_execute_instruction(target,1,0xE716,0,0)
-/* move.l r4,y */
+/// move.l r4,y
#define eonce_move_r4_to_y(target) eonce_execute_instruction(target,1,0xe764,0,0)
-/* move.w p:(r0)+,y0 */
+/// move.w p:(r0)+,y0
#define eonce_move_at_pr0_inc_to_y0(target) eonce_execute_instruction(target,1,0x8568,0,0)
-/* move.w x:(r0)+,y0 */
+/// move.w x:(r0)+,y0
#define eonce_move_at_r0_inc_to_y0(target) eonce_execute_instruction(target,1,0xf500,0,0)
-/* move x:(r0),y0 */
+/// move x:(r0),y0
#define eonce_move_at_r0_y0(target) eonce_execute_instruction(target,1,0xF514,0,0)
-/* nop */
+/// nop
#define eonce_nop(target) eonce_execute_instruction(target,1,0xe700,0,0)
-/* move.w x:(R2+<disp>),Y0 */
+/// move.w x:(R2+<disp>),Y0
#define eonce_move_at_r2_disp_to_y0(target,disp) eonce_execute_instruction(target,2,0xF542,disp,0)
-/* move.w y1,x:(r2) */
+/// move.w y1,x:(r2)
#define eonce_move_y1_at_r2(target) eonce_execute_instruction(target,1,0xd716,0,0)
-/* move.w y1,x:(r0) */
+/// move.w y1,x:(r0)
#define eonce_move_y1_at_r0(target) eonce_execute_instruction(target,1,0xd714,0,0)
-/* move.bp y0,x:(r0)+ */
+/// move.bp y0,x:(r0)+
#define eonce_move_byte_y0_at_r0(target) eonce_execute_instruction(target,1,0xd5a0,0,0)
-/* move.w y1,p:(r0)+ */
+/// move.w y1,p:(r0)+
#define eonce_move_y1_at_pr0_inc(target) eonce_execute_instruction(target,1,0x8760,0,0)
-/* move.w y1,x:(r0)+ */
+/// move.w y1,x:(r0)+
#define eonce_move_y1_at_r0_inc(target) eonce_execute_instruction(target,1,0xD700,0,0)
-/* move.l #value,y */
+/// move.l #value,y
#define eonce_move_long_to_y(target,value) eonce_execute_instruction(target,3,0xe417,value&0xffff,value>>16)
-static int eonce_move_value_to_pc(struct target * target, uint32_t value)
-{
+static int eonce_move_value_to_pc(struct target * target, uint32_t value){
if (!(target->state == TARGET_HALTED)){
LOG_ERROR("Target must be halted to move PC. Target state = %d.",target->state);
return ERROR_TARGET_NOT_HALTED;
@@ -598,6 +409,88 @@ static int eonce_load_TX_RX_high_to_r0(struct target * target)
return retval;
}
+static int dsp5680xx_read_core_reg(struct target * target, uint8_t reg_addr, uint16_t * data_read)
+{
+ //TODO implement a general version of this which matches what openocd uses.
+ int retval;
+ uint32_t dummy_data_to_shift_into_dr;
+ retval = eonce_instruction_exec(target,reg_addr,1,0,0,NULL);
+ err_check_propagate(retval);
+ retval = dsp5680xx_drscan(target,(uint8_t *)& dummy_data_to_shift_into_dr,(uint8_t *) data_read, 8);
+ err_check_propagate(retval);
+ LOG_DEBUG("Reg. data: 0x%02X.",*data_read);
+ return retval;
+}
+
+static int eonce_read_status_reg(struct target * target, uint16_t * data){
+ int retval;
+ retval = dsp5680xx_read_core_reg(target,DSP5680XX_ONCE_OSR,data);
+ err_check_propagate(retval);
+ return retval;
+}
+
+/**
+ * Takes the core out of debug mode.
+ *
+ * @param target
+ * @param eonce_status Data read from the EOnCE status register.
+ *
+ * @return
+ */
+static int eonce_exit_debug_mode(struct target * target,uint8_t * eonce_status){
+ int retval;
+ retval = eonce_instruction_exec(target,0x1F,0,0,1,eonce_status);
+ err_check_propagate(retval);
+ return retval;
+}
+
+/**
+ * Puts the core into debug mode, enabling the EOnCE module.
+ *
+ * @param target
+ * @param eonce_status Data read from the EOnCE status register.
+ *
+ * @return
+ */
+static int eonce_enter_debug_mode(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);
+ // 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.");
+ target->state = TARGET_HALTED;
+ return ERROR_OK;
+ }else{
+ retval = ERROR_TARGET_FAILURE;
+ err_check(retval,"Failed to set EOnCE module to debug mode.");
+ }
+ if(eonce_status!=NULL)
+ *eonce_status = data_read_from_dr;
+ return ERROR_OK;
+}
+
+/**
+ * Reads the current value of the program counter and stores it.
+ *
+ * @param target
+ *
+ * @return
+ */
static int eonce_pc_store(struct target * target){
uint32_t tmp = 0;
int retval;
@@ -616,6 +509,155 @@ static int eonce_pc_store(struct target * target){
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_init_target(struct command_context *cmd_ctx, struct target *target){
+ context.stored_pc = 0;
+ context.flush = 1;
+ 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_arch_state(struct target *target){
+ LOG_USER("%s not implemented yet.",__FUNCTION__);
+ return ERROR_OK;
+}
+
+int dsp5680xx_target_status(struct target * target, uint8_t * jtag_st, uint16_t * eonce_st){
+ return target->state;
+}
+
+static int dsp5680xx_assert_reset(struct target *target){
+ target->state = TARGET_RESET;
+ return ERROR_OK;
+}
+
+static int dsp5680xx_deassert_reset(struct target *target){
+ target->state = TARGET_RUNNING;
+ return ERROR_OK;
+}
+
+static int dsp5680xx_halt(struct target *target){
+ int retval;
+ uint16_t eonce_status;
+ if(target->state == TARGET_HALTED){
+ LOG_USER("Target already halted.");
+ return ERROR_OK;
+ }
+ retval = eonce_enter_debug_mode(target,&eonce_status);
+ err_check_propagate(retval);
+ retval = eonce_pc_store(target);
+ err_check_propagate(retval);
+ //TODO is it useful to store the pc?
+ 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){
+ LOG_WARNING("%s: Failed to put EOnCE in debug mode. Is flash locked?...",__FUNCTION__);
+ 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){
+ LOG_WARNING("%s: JTAG running, but cannot make EOnCE run. Try resetting...",__FUNCTION__);
+ 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;
+ }
+ }
+ target->state = TARGET_RUNNING;
+ return ERROR_OK;
+ }
+ if(jtag_status == JTAG_STATUS_DEAD){
+ LOG_ERROR("%s: Cannot communicate with JTAG. Check connection...",__FUNCTION__);
+ target->state = TARGET_UNKNOWN;
+ return ERROR_TARGET_FAILURE;
+ };
+ if (target->state == TARGET_UNKNOWN){
+ LOG_ERROR("%s: Target status invalid - communication failure",__FUNCTION__);
+ return ERROR_TARGET_FAILURE;
+ };
+ return ERROR_OK;
+}
+
+static int dsp5680xx_resume(struct target *target, int current, uint32_t address,int handle_breakpoints, int debug_execution){
+ if(target->state == TARGET_RUNNING){
+ LOG_USER("Target already running.");
+ return ERROR_OK;
+ }
+ int retval;
+ uint8_t eonce_status;
+ if(!current){
+ retval = eonce_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,"Failed to resume...");
+ }else{
+ target->state = TARGET_RUNNING;
+ }
+ LOG_DEBUG("EOnCE status: 0x%02X.",eonce_status);
+ return ERROR_OK;
+}
+
+
+
+
+
+
+/**
+ * The value of @address determines if it corresponds to P: (program) or X: (data) 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
+ *
+ * @return
+ */
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.
@@ -679,7 +721,7 @@ static int dsp5680xx_read_32_single(struct target * target, uint32_t address, ui
uint16_t tmp;
retval = eonce_rx_upper_data(target,&tmp);
err_check_propagate(retval);
- *data_read = ((tmp<<16) | (*data_read));//This enables opencd crc to succeed, even though it's very slow.
+ *data_read = ((tmp<<16) | (*data_read));//This enables OpenOCD crc to succeed (when it should)
return retval;
}
@@ -734,7 +776,6 @@ static int dsp5680xx_read(struct target * target, uint32_t address, unsigned siz
return retval;
}
-//TODO doxy
static int dsp5680xx_write_16_single(struct target *target, uint32_t address, uint16_t data, uint8_t w_pmem){
int retval = 0;
retval = eonce_move_long_to_r0(target,address);
@@ -751,7 +792,6 @@ static int dsp5680xx_write_16_single(struct target *target, uint32_t address, ui
return retval;
}
-//TODO doxy
static int dsp5680xx_write_32_single(struct target *target, uint32_t address, uint32_t data, int w_pmem){
int retval = 0;
retval = eonce_move_long_to_r0(target,address);
@@ -864,7 +904,18 @@ static int dsp5680xx_write_32(struct target * target, uint32_t address, uint32_t
return retval;
}
-//TODO doxy
+/**
+ * Writes @buffer to memory.
+ * The parameter @address determines whether @buffer should be written to P: (program) memory or X: (data) memory.
+ *
+ * @param target
+ * @param address
+ * @param size Bytes (1), Half words (2), Words (4).
+ * @param count In bytes.
+ * @param buffer
+ *
+ * @return
+ */
static int dsp5680xx_write(struct target *target, uint32_t address, uint32_t size, uint32_t count, const uint8_t * buffer){
//TODO Cannot write 32bit to odd address, will write 0x12345678 as 0x5678 0x0012
if(target->state != TARGET_HALTED){
@@ -888,7 +939,7 @@ static int dsp5680xx_write(struct target *target, uint32_t address, uint32_t siz
break;
default:
retval = ERROR_TARGET_DATA_ABORT;
- err_check(retval,"Invalid data size.")
+ err_check(retval,"Invalid data size.");
break;
}
return retval;
@@ -907,21 +958,49 @@ static int dsp5680xx_write_buffer(struct target * target, uint32_t address, uint
return dsp5680xx_write(target, address, 1, size, buffer);
}
+/**
+ * This function is called by verify_image, it is used to read data from memory.
+ *
+ * @param target
+ * @param address Word addressing.
+ * @param size In bytes.
+ * @param buffer
+ *
+ * @return
+ */
static int dsp5680xx_read_buffer(struct target * target, uint32_t address, uint32_t size, uint8_t * buffer){
if(target->state != TARGET_HALTED){
LOG_USER("Target must be halted.");
return ERROR_OK;
}
- // read_buffer is called when the verify_image command is executed.
// The "/2" solves the byte/word addressing issue.
return dsp5680xx_read(target,address,2,size/2,buffer);
}
+/**
+ * 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.
+ *
+ * @param target
+ * @param address Start address of the image.
+ * @param size In bytes.
+ * @param checksum
+ *
+ * @return
+ */
static int dsp5680xx_checksum_memory(struct target * target, uint32_t address, uint32_t size, uint32_t * checksum){
- return ERROR_FAIL;// This will make OpenOCD do the read out the data and verify it.
+ return ERROR_FAIL;
}
</