dsp5680xx - separate debug from halt
i had assumed two possible halt/debug states: - halted + debug mode - running + not debug mode turns out this one also exists - halted + NOT in debug mode added code to handle this in an appropiate way. Change-Id: Ia0ddcd55d1890c90d100a9e6f5e84ed8dda812a3 Signed-off-by: Rodrigo L. Rosa <rodrigorosa.lg@gmail.com> Reviewed-on: http://openocd.zylin.com/220 Tested-by: jenkins Reviewed-by: Øyvind Harboe <oyvindharboe@gmail.com>
This commit is contained in:
parent
6461f7669a
commit
e2fdb1c864
|
@ -33,6 +33,13 @@ struct dsp5680xx_common dsp5680xx_context;
|
||||||
#define _E "DSP5680XX_ERROR:%d\nAt:%s:%d:%s"
|
#define _E "DSP5680XX_ERROR:%d\nAt:%s:%d:%s"
|
||||||
#define err_check(r, c, m) if (r != ERROR_OK) {LOG_ERROR(_E, c, __func__, __LINE__, m); return r; }
|
#define err_check(r, c, m) if (r != ERROR_OK) {LOG_ERROR(_E, c, __func__, __LINE__, m); return r; }
|
||||||
#define err_check_propagate(retval) if (retval != ERROR_OK) return retval;
|
#define err_check_propagate(retval) if (retval != ERROR_OK) return retval;
|
||||||
|
#define DEBUG_MSG "Debug mode be enabled to read mem."
|
||||||
|
#define DEBUG_FAIL { err_check(ERROR_FAIL, DSP5680XX_ERROR_NOT_IN_DEBUG, DEBUG_MSG) }
|
||||||
|
#define CHECK_DBG if (!dsp5680xx_context.debug_mode_enabled) DEBUG_FAIL
|
||||||
|
#define HALT_MSG "Target must be halted."
|
||||||
|
#define HALT_FAIL { err_check(ERROR_FAIL, DSP5680XX_ERROR_TARGET_RUNNING, HALT_MSG) }
|
||||||
|
#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 dsp5680xx_execute_queue(void){
|
||||||
int retval;
|
int retval;
|
||||||
|
@ -411,10 +418,7 @@ static int core_rx_lower_data(struct target * target,uint8_t * data_read)
|
||||||
#define core_move_long_to_y(target,value) dsp5680xx_exe_generic(target,3,0xe417,value&0xffff,value>>16)
|
#define core_move_long_to_y(target,value) dsp5680xx_exe_generic(target,3,0xe417,value&0xffff,value>>16)
|
||||||
|
|
||||||
static int core_move_value_to_pc(struct target * target, uint32_t value){
|
static int core_move_value_to_pc(struct target * target, uint32_t value){
|
||||||
if (!(target->state == TARGET_HALTED)){
|
check_halt_and_debug(target);
|
||||||
LOG_ERROR("Target must be halted to move PC. Target state = %d.",target->state);
|
|
||||||
return ERROR_TARGET_NOT_HALTED;
|
|
||||||
};
|
|
||||||
int retval;
|
int retval;
|
||||||
retval = dsp5680xx_exe_generic(target,3,0xE71E,value&0xffff,value>>16);
|
retval = dsp5680xx_exe_generic(target,3,0xE71E,value&0xffff,value>>16);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
|
@ -544,15 +548,20 @@ static int eonce_enter_debug_mode_without_reset(struct target * target, uint16_t
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
retval = dsp5680xx_irscan(target, & instr, & ir_out,DSP5680XX_JTAG_CORE_TAP_IRLEN);
|
retval = dsp5680xx_irscan(target, & instr, & ir_out,DSP5680XX_JTAG_CORE_TAP_IRLEN);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
|
if ((ir_out&JTAG_STATUS_MASK) == JTAG_STATUS_DEBUG)
|
||||||
|
target->state = TARGET_HALTED;
|
||||||
|
else
|
||||||
|
retval = ERROR_FAIL;
|
||||||
// Verify that debug mode is enabled
|
// Verify that debug mode is enabled
|
||||||
uint16_t data_read_from_dr;
|
uint16_t data_read_from_dr;
|
||||||
retval = eonce_read_status_reg(target, &data_read_from_dr);
|
retval = eonce_read_status_reg(target, &data_read_from_dr);
|
||||||
err_check_propagate(retval);
|
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.");
|
LOG_DEBUG("EOnCE successfully entered debug mode.");
|
||||||
target->state = TARGET_HALTED;
|
dsp5680xx_context.debug_mode_enabled = true;
|
||||||
retval = ERROR_OK;
|
retval = ERROR_OK;
|
||||||
} else {
|
} else {
|
||||||
|
dsp5680xx_context.debug_mode_enabled = false;
|
||||||
retval = ERROR_TARGET_FAILURE;
|
retval = ERROR_TARGET_FAILURE;
|
||||||
/**
|
/**
|
||||||
* No error msg here, since there is still hope with full halting sequence
|
* No error msg here, since there is still hope with full halting sequence
|
||||||
|
@ -642,6 +651,12 @@ static int eonce_enter_debug_mode(struct target * target, uint16_t * eonce_statu
|
||||||
retval = dsp5680xx_irscan(target, & instr, & ir_out,DSP5680XX_JTAG_CORE_TAP_IRLEN);
|
retval = dsp5680xx_irscan(target, & instr, & ir_out,DSP5680XX_JTAG_CORE_TAP_IRLEN);
|
||||||
err_check_propagate(retval);
|
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++){
|
for(int i = 0; i<3; i++){
|
||||||
instr_16 = 0x86;
|
instr_16 = 0x86;
|
||||||
|
@ -656,7 +671,7 @@ static int eonce_enter_debug_mode(struct target * target, uint16_t * eonce_statu
|
||||||
err_check_propagate(retval);
|
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.");
|
LOG_DEBUG("EOnCE successfully entered debug mode.");
|
||||||
target->state = TARGET_HALTED;
|
dsp5680xx_context.debug_mode_enabled = true;
|
||||||
retval = ERROR_OK;
|
retval = ERROR_OK;
|
||||||
}else{
|
}else{
|
||||||
const char *msg = "Failed to set EOnCE module to debug mode";
|
const char *msg = "Failed to set EOnCE module to debug mode";
|
||||||
|
@ -702,13 +717,14 @@ static int dsp5680xx_target_create(struct target *target, Jim_Interp * interp){
|
||||||
static int dsp5680xx_init_target(struct command_context *cmd_ctx, struct target *target){
|
static int dsp5680xx_init_target(struct command_context *cmd_ctx, struct target *target){
|
||||||
dsp5680xx_context.stored_pc = 0;
|
dsp5680xx_context.stored_pc = 0;
|
||||||
dsp5680xx_context.flush = 1;
|
dsp5680xx_context.flush = 1;
|
||||||
|
dsp5680xx_context.debug_mode_enabled = false;
|
||||||
LOG_DEBUG("target initiated!");
|
LOG_DEBUG("target initiated!");
|
||||||
//TODO core tap must be enabled before running these commands, currently this is done in the .cfg tcl script.
|
//TODO core tap must be enabled before running these commands, currently this is done in the .cfg tcl script.
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsp5680xx_arch_state(struct target *target){
|
static int dsp5680xx_arch_state(struct target *target){
|
||||||
LOG_USER("%s not implemented yet.",__FUNCTION__);
|
LOG_USER("%s not implemented yet.", __func__);
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -729,19 +745,26 @@ static int dsp5680xx_deassert_reset(struct target *target){
|
||||||
static int dsp5680xx_halt(struct target *target){
|
static int dsp5680xx_halt(struct target *target){
|
||||||
int retval;
|
int retval;
|
||||||
uint16_t eonce_status = 0xbeef;
|
uint16_t eonce_status = 0xbeef;
|
||||||
if(target->state == TARGET_HALTED){
|
if ((target->state == TARGET_HALTED) && (dsp5680xx_context.debug_mode_enabled)) {
|
||||||
LOG_USER("Target already halted.");
|
LOG_USER("Target already halted and in debug mode.");
|
||||||
return ERROR_OK;
|
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);
|
retval = eonce_enter_debug_mode(target,&eonce_status);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
retval = eonce_pc_store(target);
|
retval = eonce_pc_store(target);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
//TODO is it useful to store the pc?
|
if (dsp5680xx_context.debug_mode_enabled) {
|
||||||
|
retval = eonce_pc_store(target);
|
||||||
|
err_check_propagate(retval);
|
||||||
|
}
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsp5680xx_poll(struct target *target){
|
static int dsp5680xx_poll(struct target *target)
|
||||||
|
{
|
||||||
int retval;
|
int retval;
|
||||||
uint8_t jtag_status;
|
uint8_t jtag_status;
|
||||||
uint8_t eonce_status;
|
uint8_t eonce_status;
|
||||||
|
@ -754,7 +777,8 @@ static int dsp5680xx_poll(struct target *target){
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
eonce_status = (uint8_t) read_tmp;
|
eonce_status = (uint8_t) read_tmp;
|
||||||
if ((eonce_status&EONCE_STAT_MASK) != DSP5680XX_ONCE_OSCR_DEBUG_M) {
|
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__);
|
const char *msg = "%s: Failed to put EOnCE in debug mode.Flash locked?...";
|
||||||
|
LOG_WARNING(msg, __func__);
|
||||||
return ERROR_TARGET_FAILURE;
|
return ERROR_TARGET_FAILURE;
|
||||||
} else {
|
} else {
|
||||||
target->state = TARGET_HALTED;
|
target->state = TARGET_HALTED;
|
||||||
|
@ -768,7 +792,8 @@ static int dsp5680xx_poll(struct target *target){
|
||||||
retval = eonce_exit_debug_mode(target, &eonce_status);
|
retval = eonce_exit_debug_mode(target, &eonce_status);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
if ((eonce_status&EONCE_STAT_MASK) != DSP5680XX_ONCE_OSCR_NORMAL_M) {
|
if ((eonce_status&EONCE_STAT_MASK) != DSP5680XX_ONCE_OSCR_NORMAL_M) {
|
||||||
LOG_WARNING("%s: JTAG running, but cannot make EOnCE run. Try resetting...",__FUNCTION__);
|
const char *msg = "%s: JTAG running, but EOnCE run failed.Try resetting..";
|
||||||
|
LOG_WARNING(msg, __func__);
|
||||||
return ERROR_TARGET_FAILURE;
|
return ERROR_TARGET_FAILURE;
|
||||||
} else {
|
} else {
|
||||||
target->state = TARGET_RUNNING;
|
target->state = TARGET_RUNNING;
|
||||||
|
@ -788,24 +813,27 @@ static int dsp5680xx_poll(struct target *target){
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
if (jtag_status == JTAG_STATUS_DEAD) {
|
if (jtag_status == JTAG_STATUS_DEAD) {
|
||||||
LOG_ERROR("%s: Cannot communicate with JTAG. Check connection...",__FUNCTION__);
|
LOG_ERROR("%s: Cannot communicate with JTAG. Check connection...", __func__);
|
||||||
target->state = TARGET_UNKNOWN;
|
target->state = TARGET_UNKNOWN;
|
||||||
return ERROR_TARGET_FAILURE;
|
return ERROR_TARGET_FAILURE;
|
||||||
};
|
};
|
||||||
if (target->state == TARGET_UNKNOWN) {
|
if (target->state == TARGET_UNKNOWN) {
|
||||||
LOG_ERROR("%s: Target status invalid - communication failure",__FUNCTION__);
|
LOG_ERROR("%s: Target status invalid - communication failure", __func__);
|
||||||
return ERROR_TARGET_FAILURE;
|
return ERROR_TARGET_FAILURE;
|
||||||
};
|
};
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsp5680xx_resume(struct target *target, int current, uint32_t address,int handle_breakpoints, int debug_execution){
|
static int dsp5680xx_resume(struct target *target, int current, uint32_t address, int hb, int d)
|
||||||
|
{
|
||||||
if (target->state == TARGET_RUNNING) {
|
if (target->state == TARGET_RUNNING) {
|
||||||
LOG_USER("Target already running.");
|
LOG_USER("Target already running.");
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
int retval;
|
int retval;
|
||||||
uint8_t eonce_status;
|
uint8_t eonce_status;
|
||||||
|
uint8_t jtag_status;
|
||||||
|
if (dsp5680xx_context.debug_mode_enabled) {
|
||||||
if (!current) {
|
if (!current) {
|
||||||
retval = core_move_value_to_pc(target, address);
|
retval = core_move_value_to_pc(target, address);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
|
@ -820,11 +848,36 @@ static int dsp5680xx_resume(struct target *target, int current, uint32_t address
|
||||||
}
|
}
|
||||||
if (retry == 0) {
|
if (retry == 0) {
|
||||||
retval = ERROR_TARGET_FAILURE;
|
retval = ERROR_TARGET_FAILURE;
|
||||||
err_check(retval, DSP5680XX_ERROR_RESUME, "Failed to resume...");
|
err_check(retval, DSP5680XX_ERROR_EXIT_DEBUG_MODE, "Failed to exit debug mode...");
|
||||||
} else {
|
} else {
|
||||||
target->state = TARGET_RUNNING;
|
target->state = TARGET_RUNNING;
|
||||||
|
dsp5680xx_context.debug_mode_enabled = false;
|
||||||
}
|
}
|
||||||
LOG_DEBUG("EOnCE status: 0x%02X.", eonce_status);
|
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;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -834,7 +887,7 @@ static int dsp5680xx_resume(struct target *target, int current, uint32_t address
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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 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 special case of 0xFFXXXX is not modified, since it allows to read out the memory mapped EOnCE registers.
|
||||||
*
|
*
|
||||||
* @param address
|
* @param address
|
||||||
|
@ -842,9 +895,12 @@ static int dsp5680xx_resume(struct target *target, int current, uint32_t address
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static int dsp5680xx_convert_address(uint32_t * address, int * pmem){
|
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.
|
/**
|
||||||
|
* 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) {
|
if (*address >= S_FILE_DATA_OFFSET) {
|
||||||
*pmem = 0;
|
*pmem = 0;
|
||||||
if (((*address)&0xff0000) != 0xff0000)
|
if (((*address)&0xff0000) != 0xff0000)
|
||||||
|
@ -853,7 +909,10 @@ static int dsp5680xx_convert_address(uint32_t * address, int * pmem){
|
||||||
return ERROR_OK;
|
return ERROR_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsp5680xx_read_16_single(struct target * target, uint32_t address, 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;
|
int retval;
|
||||||
retval = core_move_long_to_r0(target,address);
|
retval = core_move_long_to_r0(target,address);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
|
@ -869,13 +928,16 @@ static int dsp5680xx_read_16_single(struct target * target, uint32_t address, ui
|
||||||
// at this point the data i want is at the reg eonce can read
|
// at this point the data i want is at the reg eonce can read
|
||||||
retval = core_rx_lower_data(target,data_read);
|
retval = core_rx_lower_data(target,data_read);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
LOG_DEBUG("%s: Data read from 0x%06X: 0x%02X%02X",__FUNCTION__, address,data_read[1],data_read[0]);
|
LOG_DEBUG("%s:Data read from 0x%06X: 0x%02X%02X", __func__, address, data_read[1], data_read[0]);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsp5680xx_read_32_single(struct target * target, uint32_t address, uint8_t * data_read, int r_pmem){
|
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;
|
int retval;
|
||||||
address = (address & 0xFFFFFE);
|
address = (address & 0xFFFFF);
|
||||||
// Get data to an intermediate register
|
// Get data to an intermediate register
|
||||||
retval = core_move_long_to_r0(target,address);
|
retval = core_move_long_to_r0(target,address);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
|
@ -906,11 +968,13 @@ static int dsp5680xx_read_32_single(struct target * target, uint32_t address, ui
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsp5680xx_read(struct target * target, uint32_t address, unsigned size, unsigned count, uint8_t * buffer){
|
static int dsp5680xx_read(struct target *t, uint32_t a, unsigned size, unsigned count, uint8_t *buf)
|
||||||
if(target->state != TARGET_HALTED){
|
{
|
||||||
LOG_USER("Target must be halted.");
|
struct target *target = t;
|
||||||
return ERROR_FAIL;
|
uint32_t address = a;
|
||||||
}
|
uint8_t *buffer = buf;
|
||||||
|
check_halt_and_debug(target);
|
||||||
|
|
||||||
int retval = ERROR_OK;
|
int retval = ERROR_OK;
|
||||||
int pmem = 1;
|
int pmem = 1;
|
||||||
|
|
||||||
|
@ -927,9 +991,8 @@ static int dsp5680xx_read(struct target * target, uint32_t address, unsigned siz
|
||||||
}
|
}
|
||||||
switch (size) {
|
switch (size) {
|
||||||
case 1:
|
case 1:
|
||||||
if(!(i%2)){
|
if (!(i%2))
|
||||||
retval = dsp5680xx_read_16_single(target, address + i/2, buffer + i, pmem);
|
retval = dsp5680xx_read_16_single(target, address + i/2, buffer + i, pmem);
|
||||||
}
|
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
retval = dsp5680xx_read_16_single(target, address + i, buffer+2*i, pmem);
|
retval = dsp5680xx_read_16_single(target, address + i, buffer+2*i, pmem);
|
||||||
|
@ -938,7 +1001,7 @@ static int dsp5680xx_read(struct target * target, uint32_t address, unsigned siz
|
||||||
retval = dsp5680xx_read_32_single(target, address + 2*i, buffer + 4*i, pmem);
|
retval = dsp5680xx_read_32_single(target, address + 2*i, buffer + 4*i, pmem);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
LOG_USER("%s: Invalid read size.",__FUNCTION__);
|
LOG_USER("%s: Invalid read size.", __func__);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
|
@ -952,7 +1015,10 @@ static int dsp5680xx_read(struct target * target, uint32_t address, unsigned siz
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsp5680xx_write_16_single(struct target *target, uint32_t address, uint16_t data, uint8_t w_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;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
retval = core_move_long_to_r0(target,address);
|
retval = core_move_long_to_r0(target,address);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
|
@ -968,8 +1034,11 @@ static int dsp5680xx_write_16_single(struct target *target, uint32_t address, ui
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsp5680xx_write_32_single(struct target *target, uint32_t address, uint32_t data, int w_pmem){
|
static int dsp5680xx_write_32_single(struct target *t, uint32_t a, uint32_t data, int w_pmem)
|
||||||
int retval = 0;
|
{
|
||||||
|
struct target *target = t;
|
||||||
|
uint32_t address = a;
|
||||||
|
int retval = ERROR_OK;
|
||||||
retval = core_move_long_to_r0(target, address);
|
retval = core_move_long_to_r0(target, address);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
retval = core_move_long_to_y(target, data);
|
retval = core_move_long_to_y(target, data);
|
||||||
|
@ -987,11 +1056,12 @@ static int dsp5680xx_write_32_single(struct target *target, uint32_t address, ui
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsp5680xx_write_8(struct target * target, uint32_t address, uint32_t count, const uint8_t * data, int pmem){
|
static int dsp5680xx_write_8(struct target *t, uint32_t a, uint32_t c, const uint8_t *d, int pmem)
|
||||||
if(target->state != TARGET_HALTED){
|
{
|
||||||
LOG_ERROR("%s: Target must be halted.",__FUNCTION__);
|
struct target *target = t;
|
||||||
return ERROR_OK;
|
uint32_t address = a;
|
||||||
};
|
uint32_t count = c;
|
||||||
|
const uint8_t *data = d;
|
||||||
int retval = 0;
|
int retval = 0;
|
||||||
uint16_t data_16;
|
uint16_t data_16;
|
||||||
uint32_t iter;
|
uint32_t iter;
|
||||||
|
@ -1005,7 +1075,7 @@ static int dsp5680xx_write_8(struct target * target, uint32_t address, uint32_t
|
||||||
data_16 = (data[2*iter]|(data[2*iter+1] << 8));
|
data_16 = (data[2*iter]|(data[2*iter+1] << 8));
|
||||||
retval = dsp5680xx_write_16_single(target, address+iter, data_16, pmem);
|
retval = dsp5680xx_write_16_single(target, address+iter, data_16, pmem);
|
||||||
if (retval != ERROR_OK) {
|
if (retval != ERROR_OK) {
|
||||||
LOG_ERROR("%s: Could not write to p:0x%04X",__FUNCTION__,address);
|
LOG_ERROR("%s: Could not write to p:0x%04X", __func__, address);
|
||||||
dsp5680xx_context.flush = 1;
|
dsp5680xx_context.flush = 1;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -1020,7 +1090,7 @@ static int dsp5680xx_write_8(struct target * target, uint32_t address, uint32_t
|
||||||
retval = dsp5680xx_read(target, address+iter, 1, 1, (uint8_t *)&data_old);
|
retval = dsp5680xx_read(target, address+iter, 1, 1, (uint8_t *)&data_old);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
if (count == 1)
|
if (count == 1)
|
||||||
data_old=(((data_old&0xff)<<8)|data[0]);// preserve upper byte
|
data_old = (((data_old&0xff)<<8)|data[0]);/* preserve upper byte */
|
||||||
else
|
else
|
||||||
data_old = (((data_old&0xff)<<8)|data[2*iter+1]);
|
data_old = (((data_old&0xff)<<8)|data[2*iter+1]);
|
||||||
retval = dsp5680xx_write_16_single(target, address+iter, data_old, pmem);
|
retval = dsp5680xx_write_16_single(target, address+iter, data_old, pmem);
|
||||||
|
@ -1029,12 +1099,13 @@ static int dsp5680xx_write_8(struct target * target, uint32_t address, uint32_t
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsp5680xx_write_16(struct target * target, uint32_t address, uint32_t count, const uint8_t * data, 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;
|
int retval = ERROR_OK;
|
||||||
if(target->state != TARGET_HALTED){
|
|
||||||
retval = ERROR_TARGET_NOT_HALTED;
|
|
||||||
err_check(retval, DSP5680XX_ERROR_WRITE_WITH_TARGET_RUNNING, "Target must be halted.");
|
|
||||||
};
|
|
||||||
uint32_t iter;
|
uint32_t iter;
|
||||||
int counter = FLUSH_COUNT_READ_WRITE;
|
int counter = FLUSH_COUNT_READ_WRITE;
|
||||||
|
|
||||||
|
@ -1045,7 +1116,7 @@ static int dsp5680xx_write_16(struct target * target, uint32_t address, uint32_t
|
||||||
}
|
}
|
||||||
retval = dsp5680xx_write_16_single(target, address+iter, data[iter], pmem);
|
retval = dsp5680xx_write_16_single(target, address+iter, data[iter], pmem);
|
||||||
if (retval != ERROR_OK) {
|
if (retval != ERROR_OK) {
|
||||||
LOG_ERROR("%s: Could not write to p:0x%04X",__FUNCTION__,address);
|
LOG_ERROR("%s: Could not write to p:0x%04X", __func__, address);
|
||||||
dsp5680xx_context.flush = 1;
|
dsp5680xx_context.flush = 1;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -1055,12 +1126,13 @@ static int dsp5680xx_write_16(struct target * target, uint32_t address, uint32_t
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsp5680xx_write_32(struct target * target, uint32_t address, uint32_t count, const uint8_t * data, int pmem){
|
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;
|
int retval = ERROR_OK;
|
||||||
if(target->state != TARGET_HALTED){
|
|
||||||
retval = ERROR_TARGET_NOT_HALTED;
|
|
||||||
err_check(retval, DSP5680XX_ERROR_WRITE_WITH_TARGET_RUNNING, "Target must be halted.");
|
|
||||||
};
|
|
||||||
uint32_t iter;
|
uint32_t iter;
|
||||||
int counter = FLUSH_COUNT_READ_WRITE;
|
int counter = FLUSH_COUNT_READ_WRITE;
|
||||||
|
|
||||||
|
@ -1071,7 +1143,7 @@ static int dsp5680xx_write_32(struct target * target, uint32_t address, uint32_t
|
||||||
}
|
}
|
||||||
retval = dsp5680xx_write_32_single(target, address+(iter<<1), data[iter], pmem);
|
retval = dsp5680xx_write_32_single(target, address+(iter<<1), data[iter], pmem);
|
||||||
if (retval != ERROR_OK) {
|
if (retval != ERROR_OK) {
|
||||||
LOG_ERROR("%s: Could not write to p:0x%04X",__FUNCTION__,address);
|
LOG_ERROR("%s: Could not write to p:0x%04X", __func__, address);
|
||||||
dsp5680xx_context.flush = 1;
|
dsp5680xx_context.flush = 1;
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -1083,7 +1155,8 @@ static int dsp5680xx_write_32(struct target * target, uint32_t address, uint32_t
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Writes @buffer to memory.
|
* Writes @buffer to memory.
|
||||||
* The parameter @address determines whether @buffer should be written to P: (program) memory or X: (data) memory.
|
* The parameter @address determines whether @buffer should be written to
|
||||||
|
* P: (program) memory or X: (dat) memory.
|
||||||
*
|
*
|
||||||
* @param target
|
* @param target
|
||||||
* @param address
|
* @param address
|
||||||
|
@ -1093,11 +1166,16 @@ static int dsp5680xx_write_32(struct target * target, uint32_t address, uint32_t
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static int dsp5680xx_write(struct target *target, uint32_t address, uint32_t size, uint32_t count, const uint8_t * buffer){
|
static int dsp5680xx_write(struct target *t, uint32_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
|
{
|
||||||
if(target->state != TARGET_HALTED){
|
/* TODO Cannot write 32bit to odd address, will write 0x12345678 as 0x5678 0x0012 */
|
||||||
err_check(ERROR_FAIL, DSP5680XX_ERROR_WRITE_WITH_TARGET_RUNNING, "Target must be halted.");
|
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 retval = 0;
|
||||||
int p_mem = 1;
|
int p_mem = 1;
|
||||||
retval = dsp5680xx_convert_address(&address, &p_mem);
|
retval = dsp5680xx_convert_address(&address, &p_mem);
|
||||||
|
@ -1121,17 +1199,16 @@ static int dsp5680xx_write(struct target *target, uint32_t address, uint32_t siz
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsp5680xx_bulk_write_memory(struct target * target,uint32_t address, uint32_t aligned, const uint8_t * buffer){
|
static int dsp5680xx_bulk_write_memory(struct target *t, uint32_t a, uint32_t al, const uint8_t *b)
|
||||||
|
{
|
||||||
LOG_ERROR("Not implemented yet.");
|
LOG_ERROR("Not implemented yet.");
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int dsp5680xx_write_buffer(struct target * target, uint32_t address, uint32_t size, const uint8_t * buffer){
|
static int dsp5680xx_write_buffer(struct target *t, uint32_t a, uint32_t size, const uint8_t *b)
|
||||||
if(target->state != TARGET_HALTED){
|
{
|
||||||
LOG_USER("Target must be halted.");
|
check_halt_and_debug(t);
|
||||||
return ERROR_OK;
|
return dsp5680xx_write(t, a, 1, size, b);
|
||||||
}
|
|
||||||
return dsp5680xx_write(target, address, 1, size, buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1144,13 +1221,11 @@ static int dsp5680xx_write_buffer(struct target * target, uint32_t address, uint
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static int dsp5680xx_read_buffer(struct target * target, uint32_t address, uint32_t size, uint8_t * buffer){
|
static int dsp5680xx_read_buffer(struct target *t, uint32_t a, uint32_t size, uint8_t *buf)
|
||||||
if(target->state != TARGET_HALTED){
|
{
|
||||||
LOG_USER("Target must be halted.");
|
check_halt_and_debug(t);
|
||||||
return ERROR_OK;
|
/* The "/2" solves the byte/word addressing issue.*/
|
||||||
}
|
return dsp5680xx_read(t, a, 2, size/2, buf);
|
||||||
// The "/2" solves the byte/word addressing issue.
|
|
||||||
return dsp5680xx_read(target,address,2,size/2,buffer);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1164,7 +1239,8 @@ static int dsp5680xx_read_buffer(struct target * target, uint32_t address, uint3
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static int dsp5680xx_checksum_memory(struct target * target, uint32_t address, uint32_t size, uint32_t * checksum){
|
static int dsp5680xx_checksum_memory(struct target *t, uint32_t a, uint32_t s, uint32_t *checksum)
|
||||||
|
{
|
||||||
return ERROR_FAIL;
|
return ERROR_FAIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1177,7 +1253,8 @@ static int dsp5680xx_checksum_memory(struct target * target, uint32_t address, u
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static int perl_crc(uint8_t * buff8,uint32_t word_count){
|
static int perl_crc(uint8_t *buff8, uint32_t word_count)
|
||||||
|
{
|
||||||
uint16_t checksum = 0xffff;
|
uint16_t checksum = 0xffff;
|
||||||
uint16_t data,fbmisr;
|
uint16_t data,fbmisr;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
@ -1196,13 +1273,14 @@ static int perl_crc(uint8_t * buff8,uint32_t word_count){
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resets the SIM. (System Integration Module).
|
* Resets the SIM. (System Integration Modul).
|
||||||
*
|
*
|
||||||
* @param target
|
* @param target
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
int dsp5680xx_f_SIM_reset(struct target * target){
|
int dsp5680xx_f_SIM_reset(struct target *target)
|
||||||
|
{
|
||||||
int retval = ERROR_OK;
|
int retval = ERROR_OK;
|
||||||
uint16_t sim_cmd = SIM_CMD_RESET;
|
uint16_t sim_cmd = SIM_CMD_RESET;
|
||||||
uint32_t sim_addr;
|
uint32_t sim_addr;
|
||||||
|
@ -1215,13 +1293,14 @@ int dsp5680xx_f_SIM_reset(struct target * target){
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Halts the core and resets the SIM. (System Integration Module).
|
* Halts the core and resets the SIM. (System Integration Modul).
|
||||||
*
|
*
|
||||||
* @param target
|
* @param target
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static int dsp5680xx_soft_reset_halt(struct target *target){
|
static int dsp5680xx_soft_reset_halt(struct target *target)
|
||||||
|
{
|
||||||
//TODO is this what this function is expected to do...?
|
//TODO is this what this function is expected to do...?
|
||||||
int retval;
|
int retval;
|
||||||
retval = dsp5680xx_halt(target);
|
retval = dsp5680xx_halt(target);
|
||||||
|
@ -1233,10 +1312,7 @@ static int dsp5680xx_soft_reset_halt(struct target *target){
|
||||||
|
|
||||||
int dsp5680xx_f_protect_check(struct target * target, uint16_t * protected) {
|
int dsp5680xx_f_protect_check(struct target * target, uint16_t * protected) {
|
||||||
int retval;
|
int retval;
|
||||||
if (dsp5680xx_target_status(target,NULL,NULL) != TARGET_HALTED){
|
check_halt_and_debug(target);
|
||||||
retval = dsp5680xx_halt(target);
|
|
||||||
err_check_propagate(retval);
|
|
||||||
}
|
|
||||||
if (protected == NULL) {
|
if (protected == NULL) {
|
||||||
const char *msg = "NULL pointer not valid.";
|
const char *msg = "NULL pointer not valid.";
|
||||||
err_check(ERROR_FAIL, DSP5680XX_ERROR_PROTECT_CHECK_INVALID_ARGS, msg);
|
err_check(ERROR_FAIL, DSP5680XX_ERROR_PROTECT_CHECK_INVALID_ARGS, msg);
|
||||||
|
@ -1247,18 +1323,26 @@ int dsp5680xx_f_protect_check(struct target * target, uint16_t * protected) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes a command on the FM module. Some commands use the parameters @address and @data, others ignore them.
|
* Executes a command on the FM module.
|
||||||
|
* Some commands use the parameters @address and @data, others ignore them.
|
||||||
*
|
*
|
||||||
* @param target
|
* @param target
|
||||||
* @param command Command to execute.
|
* @param command Command to execute.
|
||||||
* @param address Command parameter.
|
* @param address Command parameter.
|
||||||
* @param data Command parameter.
|
* @param data Command parameter.
|
||||||
* @param hfm_ustat FM status register.
|
* @param hfm_ustat FM status register.
|
||||||
* @param pmem Address is P: (program) memory (@pmem==1) or X: (data) memory (@pmem==0)
|
* @param pmem Address is P: (program) memory (@pmem==1) or X: (dat) memory (@pmem==0)
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static int dsp5680xx_f_execute_command(struct target * target, uint16_t command, uint32_t address, uint32_t data, uint16_t * hfm_ustat, int pmem){
|
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;
|
int retval;
|
||||||
retval = core_load_TX_RX_high_addr_to_r0(target);
|
retval = core_load_TX_RX_high_addr_to_r0(target);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
|
@ -1343,7 +1427,8 @@ static int dsp5680xx_f_execute_command(struct target * target, uint16_t command,
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static int set_fm_ck_div(struct target * target){
|
static int set_fm_ck_div(struct target *target)
|
||||||
|
{
|
||||||
uint8_t i[2];
|
uint8_t i[2];
|
||||||
int retval;
|
int retval;
|
||||||
retval = core_move_long_to_r2(target,HFM_BASE_ADDR);
|
retval = core_move_long_to_r2(target,HFM_BASE_ADDR);
|
||||||
|
@ -1391,30 +1476,41 @@ static int set_fm_ck_div(struct target * target){
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static int dsp5680xx_f_signature(struct target * target, uint32_t address, 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;
|
int retval;
|
||||||
uint16_t hfm_ustat;
|
uint16_t hfm_ustat;
|
||||||
if (dsp5680xx_target_status(target,NULL,NULL) != TARGET_HALTED){
|
if (!dsp5680xx_context.debug_mode_enabled) {
|
||||||
retval = eonce_enter_debug_mode_without_reset(target, NULL);
|
retval = eonce_enter_debug_mode_without_reset(target, NULL);
|
||||||
err_check_propagate(retval);
|
/**
|
||||||
|
* 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_execute_command(target,HFM_CALCULATE_DATA_SIGNATURE,address,words,&hfm_ustat,1);
|
retval = dsp5680xx_f_ex(target, HFM_CALCULATE_DATA_SIGNATURE, address, words, &hfm_ustat, 1);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
retval = dsp5680xx_read_16_single(target, HFM_BASE_ADDR|HFM_DATA, (uint8_t *)signature, 0);
|
retval = dsp5680xx_read_16_single(target, HFM_BASE_ADDR|HFM_DATA, (uint8_t *)signature, 0);
|
||||||
return retval;
|
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;
|
int retval;
|
||||||
uint16_t hfm_ustat;
|
uint16_t hfm_ustat;
|
||||||
if (dsp5680xx_target_status(target,NULL,NULL) != TARGET_HALTED){
|
uint32_t tmp;
|
||||||
|
if (!dsp5680xx_context.debug_mode_enabled) {
|
||||||
retval = dsp5680xx_halt(target);
|
retval = dsp5680xx_halt(target);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
}
|
}
|
||||||
retval = set_fm_ck_div(target);
|
retval = set_fm_ck_div(target);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
// Check if chip is already erased.
|
/**
|
||||||
retval = dsp5680xx_f_execute_command(target,HFM_ERASE_VERIFY,HFM_FLASH_BASE_ADDR+sector*HFM_SECTOR_SIZE/2,0,&hfm_ustat,1); // blank check
|
* 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);
|
err_check_propagate(retval);
|
||||||
if (erased != NULL)
|
if (erased != NULL)
|
||||||
*erased = (uint8_t)(hfm_ustat&HFM_USTAT_MASK_BLANK);
|
*erased = (uint8_t)(hfm_ustat&HFM_USTAT_MASK_BLANK);
|
||||||
|
@ -1430,9 +1526,11 @@ int dsp5680xx_f_erase_check(struct target * target, uint8_t * erased,uint32_t se
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static int erase_sector(struct target * target, int sector, uint16_t * hfm_ustat){
|
static int erase_sector(struct target *target, int sector, uint16_t *hfm_ustat)
|
||||||
|
{
|
||||||
int retval;
|
int retval;
|
||||||
retval = dsp5680xx_f_execute_command(target,HFM_PAGE_ERASE,HFM_FLASH_BASE_ADDR+sector*HFM_SECTOR_SIZE/2,0,hfm_ustat,1);
|
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);
|
err_check_propagate(retval);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
@ -1445,15 +1543,17 @@ static int erase_sector(struct target * target, int sector, uint16_t * hfm_ustat
|
||||||
*
|
*
|
||||||
* @return
|
* @return
|
||||||
*/
|
*/
|
||||||
static int mass_erase(struct target * target, uint16_t * hfm_ustat){
|
static int mass_erase(struct target *target, uint16_t *hfm_ustat)
|
||||||
|
{
|
||||||
int retval;
|
int retval;
|
||||||
retval = dsp5680xx_f_execute_command(target,HFM_MASS_ERASE,0,0,hfm_ustat,1);
|
retval = dsp5680xx_f_ex(target, HFM_MASS_ERASE, 0, 0, hfm_ustat, 1);
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dsp5680xx_f_erase(struct target * target, int first, int last){
|
int dsp5680xx_f_erase(struct target *target, int first, int last)
|
||||||
|
{
|
||||||
int retval;
|
int retval;
|
||||||
if (dsp5680xx_target_status(target,NULL,NULL) != TARGET_HALTED){
|
if (!dsp5680xx_context.debug_mode_enabled) {
|
||||||
retval = dsp5680xx_halt(target);
|
retval = dsp5680xx_halt(target);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
}
|
}
|
||||||
|
@ -1471,7 +1571,7 @@ int dsp5680xx_f_erase(struct target * target, int first, int last){
|
||||||
uint16_t hfm_ustat;
|
uint16_t hfm_ustat;
|
||||||
int do_mass_erase = ((!(first|last)) || ((first==0)&&(last == (HFM_SECTOR_COUNT-1))));
|
int do_mass_erase = ((!(first|last)) || ((first==0)&&(last == (HFM_SECTOR_COUNT-1))));
|
||||||
if (do_mass_erase) {
|
if (do_mass_erase) {
|
||||||
//Mass erase
|
/* Mass erase */
|
||||||
retval = mass_erase(target, &hfm_ustat);
|
retval = mass_erase(target, &hfm_ustat);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1535,18 +1635,27 @@ const uint16_t pgm_write_pflash[] = {0x8A46, 0x0013, 0x807D, 0xE700,\
|
||||||
0x0013, 0x0010, 0xA961};
|
0x0013, 0x0010, 0xA961};
|
||||||
const uint32_t pgm_write_pflash_length = 31;
|
const uint32_t pgm_write_pflash_length = 31;
|
||||||
|
|
||||||
int dsp5680xx_f_wr(struct target * target, uint8_t *buffer, uint32_t address, uint32_t count, int is_flash_lock){
|
int dsp5680xx_f_wr(struct target *t, 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;
|
int retval = ERROR_OK;
|
||||||
if (dsp5680xx_target_status(target,NULL,NULL) != TARGET_HALTED){
|
if (!dsp5680xx_context.debug_mode_enabled) {
|
||||||
retval = eonce_enter_debug_mode(target, NULL);
|
retval = eonce_enter_debug_mode(target, NULL);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
}
|
}
|
||||||
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||||
// Download the pgm that flashes.
|
// Download the pgm that flashes.
|
||||||
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||||
uint32_t my_favourite_ram_address = 0x8700; // This seems to be a safe address. This one is the one used by codewarrior in 56801x_flash.cfg
|
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) {
|
if (!is_flash_lock) {
|
||||||
retval = dsp5680xx_write(target, my_favourite_ram_address, 1, pgm_write_pflash_length*2,(uint8_t *) pgm_write_pflash);
|
retval = dsp5680xx_write(target, ram_addr, 1, len*2, (uint8_t *) pgm_write_pflash);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
retval = dsp5680xx_execute_queue();
|
retval = dsp5680xx_execute_queue();
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
|
@ -1584,7 +1693,7 @@ int dsp5680xx_f_wr(struct target * target, uint8_t *buffer, uint32_t address, ui
|
||||||
retval = core_move_value_at_r2_disp(target,0x00,HFM_PROTB);// write to HMF_PROTB, clear protection
|
retval = core_move_value_at_r2_disp(target,0x00,HFM_PROTB);// write to HMF_PROTB, clear protection
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
if (count%2) {
|
if (count%2) {
|
||||||
//TODO implement handling of odd number of words.
|
/* TODO implement handling of odd number of words. */
|
||||||
retval = ERROR_FAIL;
|
retval = ERROR_FAIL;
|
||||||
const char *msg = "Cannot handle odd number of words.";
|
const char *msg = "Cannot handle odd number of words.";
|
||||||
err_check(retval, DSP5680XX_ERROR_FLASHING_INVALID_WORD_COUNT, msg);
|
err_check(retval, DSP5680XX_ERROR_FLASHING_INVALID_WORD_COUNT, msg);
|
||||||
|
@ -1599,7 +1708,7 @@ int dsp5680xx_f_wr(struct target * target, uint8_t *buffer, uint32_t address, ui
|
||||||
retval = core_tx_upper_data(target, tmp, &drscan_data);
|
retval = core_tx_upper_data(target, tmp, &drscan_data);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
|
|
||||||
retval = dsp5680xx_resume(target,0,my_favourite_ram_address,0,0);
|
retval = dsp5680xx_resume(target, 0, ram_addr, 0, 0);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
|
|
||||||
int counter = FLUSH_COUNT_FLASH;
|
int counter = FLUSH_COUNT_FLASH;
|
||||||
|
@ -1620,9 +1729,10 @@ int dsp5680xx_f_wr(struct target * target, uint8_t *buffer, uint32_t address, ui
|
||||||
}
|
}
|
||||||
dsp5680xx_context.flush = 1;
|
dsp5680xx_context.flush = 1;
|
||||||
if (!is_flash_lock) {
|
if (!is_flash_lock) {
|
||||||
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
/** -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||||
// Verify flash (skip when exec lock sequence)
|
* Verify flash (skip when exec lock sequence)
|
||||||
// -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
* -- -- -- -- -- -- -- -- -- -- -- -- -- -- --
|
||||||
|
*/
|
||||||
uint16_t signature;
|
uint16_t signature;
|
||||||
uint16_t pc_crc;
|
uint16_t pc_crc;
|
||||||
retval = dsp5680xx_f_signature(target, address, i, &signature);
|
retval = dsp5680xx_f_signature(target, address, i, &signature);
|
||||||
|
@ -1637,13 +1747,12 @@ int dsp5680xx_f_wr(struct target * target, uint8_t *buffer, uint32_t address, ui
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dsp5680xx_f_unlock(struct target * target){
|
int dsp5680xx_f_unlock(struct target *target)
|
||||||
|
{
|
||||||
int retval = ERROR_OK;
|
int retval = ERROR_OK;
|
||||||
uint16_t eonce_status;
|
uint16_t eonce_status;
|
||||||
uint32_t instr;
|
uint32_t instr;
|
||||||
uint32_t ir_out;
|
uint32_t ir_out;
|
||||||
uint16_t instr_16;
|
|
||||||
uint16_t read_16;
|
|
||||||
struct jtag_tap * tap_chp;
|
struct jtag_tap * tap_chp;
|
||||||
struct jtag_tap * tap_cpu;
|
struct jtag_tap * tap_cpu;
|
||||||
tap_chp = jtag_tap_by_string("dsp568013.chp");
|
tap_chp = jtag_tap_by_string("dsp568013.chp");
|
||||||
|
@ -1657,10 +1766,9 @@ int dsp5680xx_f_unlock(struct target * target){
|
||||||
err_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_CORE, "Failed to get master tap.");
|
err_check(retval, DSP5680XX_ERROR_JTAG_TAP_ENABLE_CORE, "Failed to get master tap.");
|
||||||
}
|
}
|
||||||
|
|
||||||
retval = eonce_enter_debug_mode(target,&eonce_status);
|
retval = eonce_enter_debug_mode_without_reset(target, &eonce_status);
|
||||||
if(retval == ERROR_OK){
|
if (retval == ERROR_OK)
|
||||||
LOG_WARNING("Memory was not locked.");
|
LOG_WARNING("Memory was not locked.");
|
||||||
}
|
|
||||||
|
|
||||||
jtag_add_reset(0,1);
|
jtag_add_reset(0,1);
|
||||||
jtag_add_sleep(TIME_DIV_FREESCALE*200*1000);
|
jtag_add_sleep(TIME_DIV_FREESCALE*200*1000);
|
||||||
|
@ -1717,28 +1825,16 @@ int dsp5680xx_f_unlock(struct target * target){
|
||||||
|
|
||||||
tap_cpu->enabled = true;
|
tap_cpu->enabled = true;
|
||||||
tap_chp->enabled = false;
|
tap_chp->enabled = false;
|
||||||
|
target->state = TARGET_RUNNING;
|
||||||
instr = JTAG_INSTR_ENABLE_ONCE;
|
dsp5680xx_context.debug_mode_enabled = false;
|
||||||
//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);
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
int dsp5680xx_f_lock(struct target * target){
|
int dsp5680xx_f_lock(struct target *target)
|
||||||
|
{
|
||||||
int retval;
|
int retval;
|
||||||
|
struct jtag_tap *tap_chp;
|
||||||
|
struct jtag_tap *tap_cpu;
|
||||||
uint16_t lock_word[] = {HFM_LOCK_FLASH};
|
uint16_t lock_word[] = {HFM_LOCK_FLASH};
|
||||||
retval = dsp5680xx_f_wr(target,(uint8_t *)(lock_word),HFM_LOCK_ADDR_L,2,1);
|
retval = dsp5680xx_f_wr(target,(uint8_t *)(lock_word),HFM_LOCK_ADDR_L,2,1);
|
||||||
err_check_propagate(retval);
|
err_check_propagate(retval);
|
||||||
|
@ -1752,6 +1848,21 @@ int dsp5680xx_f_lock(struct target * target){
|
||||||
jtag_add_reset(0,0);
|
jtag_add_reset(0,0);
|
||||||
jtag_add_sleep(TIME_DIV_FREESCALE*300*1000);
|
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;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -256,6 +256,7 @@ struct dsp5680xx_common{
|
||||||
//TODO
|
//TODO
|
||||||
uint32_t stored_pc;
|
uint32_t stored_pc;
|
||||||
int flush;
|
int flush;
|
||||||
|
bool debug_mode_enabled;
|
||||||
};
|
};
|
||||||
|
|
||||||
extern struct dsp5680xx_common dsp5680xx_context;
|
extern struct dsp5680xx_common dsp5680xx_context;
|
||||||
|
|
Loading…
Reference in New Issue