target: move regmaps to armv7m.c
[fw/openocd] / src / target / dsp563xx.c
index cdfa79b1c53e1027440bee3cc38311ddd92cda42..28f8bac02caf9cd3a4f9ec68fa8b9008bfcc0c07 100644 (file)
@@ -25,6 +25,7 @@
 
 #include "target.h"
 #include "target_type.h"
+#include "algorithm.h"
 #include "register.h"
 #include "dsp563xx.h"
 #include "dsp563xx_once.h"
@@ -335,7 +336,7 @@ static int dsp563xx_get_gdb_reg_list(struct target *target, struct reg **reg_lis
        *reg_list = malloc(sizeof(struct reg *) * (*reg_list_size));
 
        if (!*reg_list)
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        for (i = 0; i < DSP563XX_NUMCOREREGS; i++)
        {
@@ -349,13 +350,11 @@ static int dsp563xx_get_gdb_reg_list(struct target *target, struct reg **reg_lis
 static int dsp563xx_read_core_reg(struct target *target, int num)
 {
        uint32_t reg_value;
-       struct dsp563xx_core_reg *dsp563xx_core_reg;
        struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
 
        if ((num < 0) || (num >= DSP563XX_NUMCOREREGS))
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
-       dsp563xx_core_reg = dsp563xx->core_cache->reg_list[num].arch_info;
        reg_value = dsp563xx->core_regs[num];
        buf_set_u32(dsp563xx->core_cache->reg_list[num].value, 0, 32, reg_value);
        dsp563xx->core_cache->reg_list[num].valid = 1;
@@ -367,14 +366,12 @@ static int dsp563xx_read_core_reg(struct target *target, int num)
 static int dsp563xx_write_core_reg(struct target *target, int num)
 {
        uint32_t reg_value;
-       struct dsp563xx_core_reg *dsp563xx_core_reg;
        struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
 
        if ((num < 0) || (num >= DSP563XX_NUMCOREREGS))
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        reg_value = buf_get_u32(dsp563xx->core_cache->reg_list[num].value, 0, 32);
-       dsp563xx_core_reg = dsp563xx->core_cache->reg_list[num].arch_info;
        dsp563xx->core_regs[num] = reg_value;
        dsp563xx->core_cache->reg_list[num].valid = 1;
        dsp563xx->core_cache->reg_list[num].dirty = 0;
@@ -552,9 +549,14 @@ static int dsp563xx_reg_pc_read(struct target *target)
        {
                if ( (once_regs[ONCE_REG_IDX_OPABF11].reg & 1) == 0 )
                {
-                       LOG_DEBUG("%s conditional branch not supported yet", __FUNCTION__);
+                       LOG_DEBUG("%s conditional branch not supported yet (0x%x 0x%x 0x%x)", __FUNCTION__,
+                               (once_regs[ONCE_REG_IDX_OPABF11].reg >> 1),
+                               once_regs[ONCE_REG_IDX_OPABDR].reg,
+                               once_regs[ONCE_REG_IDX_OPABEX].reg);
 
-                       /* TODO: use disassembly to set correct pc offset */
+                       /* TODO: use disassembly to set correct pc offset
+                        * read 2 words from OPABF11 and disasm the instruction
+                        */
                        dsp563xx->core_regs[DSP563XX_REG_IDX_PC] = (once_regs[ONCE_REG_IDX_OPABF11].reg >> 1) & 0x00FFFFFF;
                }
                else
@@ -582,7 +584,7 @@ static int dsp563xx_reg_pc_read(struct target *target)
 static int dsp563xx_reg_ssh_read(struct target *target)
 {
        int err;
-       uint32_t sp, sc, ep;
+       uint32_t sp;
        struct dsp563xx_core_reg *arch_info;
        struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
 
@@ -598,14 +600,14 @@ static int dsp563xx_reg_ssh_read(struct target *target)
        /* get a valid stack count */
        if ((err = dsp563xx_read_register(target, DSP563XX_REG_IDX_SC, 0)) != ERROR_OK)
                return err;
-       sc = dsp563xx->core_regs[DSP563XX_REG_IDX_SC];
+
        if ((err = dsp563xx_write_register(target, DSP563XX_REG_IDX_SC, 0)) != ERROR_OK)
                return err;
 
        /* get a valid extended pointer */
        if ((err = dsp563xx_read_register(target, DSP563XX_REG_IDX_EP, 0)) != ERROR_OK)
                return err;
-       ep = dsp563xx->core_regs[DSP563XX_REG_IDX_EP];
+
        if ((err = dsp563xx_write_register(target, DSP563XX_REG_IDX_EP, 0)) != ERROR_OK)
                return err;
 
@@ -857,7 +859,7 @@ static int dsp563xx_target_create(struct target *target, Jim_Interp * interp)
        struct dsp563xx_common *dsp563xx = calloc(1, sizeof(struct dsp563xx_common));
 
        if (!dsp563xx)
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
 
        dsp563xx->jtag_info.tap = target->tap;
        target->arch_info = dsp563xx;
@@ -884,7 +886,7 @@ static int dsp563xx_examine(struct target *target)
        {
                LOG_ERROR("no IDCODE present on device");
 
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        if (!target_was_examined(target))
@@ -999,7 +1001,8 @@ static int dsp563xx_jtag_debug_request(struct target *target)
 static int dsp563xx_poll(struct target *target)
 {
        int err;
-       uint32_t once_status;
+       struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
+       uint32_t once_status=0;
        int state;
 
        state = dsp563xx_once_target_status(target->tap);
@@ -1023,9 +1026,18 @@ static int dsp563xx_poll(struct target *target)
                        if ((err = dsp563xx_debug_init(target)) != ERROR_OK)
                                return err;
 
-                       target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+                       if ( once_status & (DSP563XX_ONCE_OSCR_MBO|DSP563XX_ONCE_OSCR_SWO) )
+                       {
+                               target_call_event_callbacks(target, TARGET_EVENT_DEBUG_HALTED);
+                       }
+                       else
+                       {
+                               target_call_event_callbacks(target, TARGET_EVENT_HALTED);
+                       }
 
                        LOG_DEBUG("target->state: %s (%x)", target_state_name(target),once_status);
+
+                       LOG_INFO("halted: PC: 0x%x", dsp563xx->core_regs[DSP563XX_REG_IDX_PC] );
                }
        }
 
@@ -1060,7 +1072,6 @@ static int dsp563xx_halt(struct target *target)
 static int dsp563xx_resume(struct target *target, int current, uint32_t address, int handle_breakpoints, int debug_execution)
 {
        int err;
-       struct dsp563xx_core_reg *dsp563xx_core_reg;
        struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
 
        /* check if pc was changed and resume want to execute the next address
@@ -1072,7 +1083,6 @@ static int dsp563xx_resume(struct target *target, int current, uint32_t address,
        if ( current && dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_PC].dirty )
        {
                dsp563xx_write_core_reg(target,DSP563XX_REG_IDX_PC);
-               dsp563xx_core_reg = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_PC].arch_info;
                address = dsp563xx->core_regs[DSP563XX_REG_IDX_PC];
                current = 0;
        }
@@ -1104,6 +1114,8 @@ static int dsp563xx_resume(struct target *target, int current, uint32_t address,
 
        target->state = TARGET_RUNNING;
 
+       target_call_event_callbacks(target, TARGET_EVENT_DEBUG_RESUMED);
+
        return ERROR_OK;
 }
 
@@ -1112,7 +1124,6 @@ static int dsp563xx_step_ex(struct target *target, int current, uint32_t address
        int err;
        uint32_t once_status;
        uint32_t dr_in, cnt;
-       struct dsp563xx_core_reg *dsp563xx_core_reg;
        struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
 
        if (target->state != TARGET_HALTED)
@@ -1130,7 +1141,6 @@ static int dsp563xx_step_ex(struct target *target, int current, uint32_t address
        if ( current && dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_PC].dirty )
        {
                dsp563xx_write_core_reg(target,DSP563XX_REG_IDX_PC);
-               dsp563xx_core_reg = dsp563xx->core_cache->reg_list[DSP563XX_REG_IDX_PC].arch_info;
                address = dsp563xx->core_regs[DSP563XX_REG_IDX_PC];
                current = 0;
        }
@@ -1213,6 +1223,13 @@ static int dsp563xx_step_ex(struct target *target, int current, uint32_t address
 static int dsp563xx_step(struct target *target, int current, uint32_t address, int handle_breakpoints)
 {
        int err;
+       struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
+
+       if (target->state != TARGET_HALTED)
+       {
+               LOG_WARNING("target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
 
        if ( (err=dsp563xx_step_ex(target, current, address, handle_breakpoints, 0)) != ERROR_OK )
        {
@@ -1222,6 +1239,8 @@ static int dsp563xx_step(struct target *target, int current, uint32_t address, i
        target->debug_reason = DBG_REASON_SINGLESTEP;
        target_call_event_callbacks(target, TARGET_EVENT_HALTED);
 
+       LOG_INFO("halted: PC: 0x%x", dsp563xx->core_regs[DSP563XX_REG_IDX_PC] );
+
        return err;
 }
 
@@ -1282,8 +1301,10 @@ static int dsp563xx_deassert_reset(struct target *target)
                                return err;
                }
        }
-
-//      target->state = TARGET_RUNNING;
+       else
+       {
+               target->state = TARGET_RUNNING;
+       }
 
        LOG_DEBUG("%s", __FUNCTION__);
        return ERROR_OK;
@@ -1295,6 +1316,99 @@ static int dsp563xx_soft_reset_halt(struct target *target)
        return ERROR_OK;
 }
 
+static int dsp563xx_run_algorithm(struct target *target,
+               int num_mem_params, struct mem_param *mem_params,
+               int num_reg_params, struct reg_param *reg_params,
+               uint32_t entry_point, uint32_t exit_point,
+               int timeout_ms, void *arch_info)
+{
+       int i;
+       int retval = ERROR_OK;
+       struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
+
+       if (target->state != TARGET_HALTED)
+       {
+               LOG_WARNING("target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       for (i = 0; i < num_mem_params; i++)
+       {
+               if ((retval = target_write_buffer(target, mem_params[i].address, mem_params[i].size, mem_params[i].value)) != ERROR_OK)
+               {
+                       return retval;
+               }
+       }
+
+       for (i = 0; i < num_reg_params; i++)
+       {
+               struct reg *reg = register_get_by_name(dsp563xx->core_cache, reg_params[i].reg_name, 0);
+
+               if (!reg)
+               {
+                       LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
+                       continue;
+               }
+
+               if (reg->size != reg_params[i].size)
+               {
+                       LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
+                       continue;
+               }
+
+               if ((retval = dsp563xx_set_core_reg(reg, reg_params[i].value)) != ERROR_OK)
+               {
+                       return retval;
+               }
+       }
+
+       /* exec */
+       if ((retval = target_resume(target, 0, entry_point, 1, 1)) != ERROR_OK)
+       {
+               return retval;
+       }
+
+       if ((retval = target_wait_state(target, TARGET_HALTED, timeout_ms)) != ERROR_OK)
+       {
+               return retval;
+       }
+
+       for (i = 0; i < num_mem_params; i++)
+       {
+               if (mem_params[i].direction != PARAM_OUT)
+                       retval = target_read_buffer(target,
+                                       mem_params[i].address,
+                                       mem_params[i].size,
+                                       mem_params[i].value);
+                       if (retval != ERROR_OK)
+                               return retval;
+       }
+
+       for (i = 0; i < num_reg_params; i++)
+       {
+               if (reg_params[i].direction != PARAM_OUT)
+               {
+
+                       struct reg *reg = register_get_by_name(dsp563xx->core_cache, reg_params[i].reg_name, 0);
+                       if (!reg)
+                       {
+                               LOG_ERROR("BUG: register '%s' not found", reg_params[i].reg_name);
+                               continue;
+                       }
+
+                       if (reg->size != reg_params[i].size)
+                       {
+                               LOG_ERROR("BUG: register '%s' size doesn't match reg_params[i].size", reg_params[i].reg_name);
+                               continue;
+                       }
+
+                       buf_set_u32(reg_params[i].value, 0, 32, buf_get_u32(reg->value, 0, 32));
+               }
+       }
+
+       return ERROR_OK;
+}
+
 /* global command context from openocd.c */
 extern struct command_context *global_cmd_ctx;
 
@@ -1366,7 +1480,7 @@ static int dsp563xx_read_memory_core(struct target *target, int mem_type, uint32
                        move_cmd = 0x07d891;
                        break;
                default:
-                       return ERROR_INVALID_ARGUMENTS;
+                       return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        /* we use r0 to store temporary data */
@@ -1393,7 +1507,7 @@ static int dsp563xx_read_memory_core(struct target *target, int mem_type, uint32
                        return err;
                if ((err = dsp563xx_once_execute_sw_ir(target->tap, 0, 0x08D13C)) != ERROR_OK)
                        return err;
-               if ((err = dsp563xx_once_reg_read(target->tap, 0, DSP563XX_ONCE_OGDBR, (uint32_t*)b)) != ERROR_OK)
+               if ((err = dsp563xx_once_reg_read(target->tap, 0, DSP563XX_ONCE_OGDBR, (uint32_t*)(void *)b)) != ERROR_OK)
                        return err;
                b += 4;
        }
@@ -1409,7 +1523,7 @@ static int dsp563xx_read_memory_core(struct target *target, int mem_type, uint32
 
        for (i = 0; i < x; i++)
        {
-               data = *((uint32_t*)b) & 0x00FFFFFF;
+               data = buf_get_u32(b, 0, 32) & 0x00FFFFFF;
 //             LOG_DEBUG("R: %08X", *((uint32_t*)b));
                target_buffer_set_u32(target, b, data);
                b += 4;
@@ -1424,10 +1538,25 @@ static int dsp563xx_read_memory(struct target *target, int mem_type, uint32_t ad
        uint32_t i,i1;
        uint8_t *buffer_y,*buffer_x;
 
+       /* if size equals zero we are called from target read memory
+        * and have to handle the parameter here */
+       if ( (size == 0) && (count != 0) )
+       {
+               size = count % 4;
+
+               if ( size )
+               {
+                       LOG_DEBUG("size is not aligned to 4 byte");
+               }
+
+               count = (count - size) / 4;
+               size  = 4;
+       }
+
        /* we only support 4 byte aligned data */
        if ( (size != 4) || (!count) )
        {
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        if ( mem_type != MEM_L )
@@ -1437,13 +1566,13 @@ static int dsp563xx_read_memory(struct target *target, int mem_type, uint32_t ad
 
        if ( !(buffer_y = malloc(size*count)) )
        {
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        if ( !(buffer_x = malloc(size*count)) )
        {
                free(buffer_y);
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        err = dsp563xx_read_memory_core(target,MEM_Y,address,size,count/2,buffer_y);
@@ -1466,8 +1595,8 @@ static int dsp563xx_read_memory(struct target *target, int mem_type, uint32_t ad
 
        for(i=0,i1=0;i<count;i+=2,i1++)
        {
-               ((uint32_t*)buffer)[i] = ((uint32_t*)buffer_y)[i1];
-               ((uint32_t*)buffer)[i+1] = ((uint32_t*)buffer_x)[i1];
+               buf_set_u32(buffer + i*sizeof(uint32_t), 0, 32, buf_get_u32(buffer_y+i1*sizeof(uint32_t), 0, 32));
+               buf_set_u32(buffer + (i + 1) *sizeof(uint32_t), 0, 32, buf_get_u32(buffer_x+i1*sizeof(uint32_t), 0, 32));
        }
 
        free(buffer_y);
@@ -1482,13 +1611,19 @@ static int dsp563xx_read_memory_default(struct target *target, uint32_t address,
        return dsp563xx_read_memory(target, dsp563xx_get_default_memory(), address, size, count, buffer);
 }
 
-static int dsp563xx_write_memory_core(struct target *target, int mem_type, uint32_t address, uint32_t size, uint32_t count, uint8_t * buffer)
+static int dsp563xx_read_buffer_default(struct target *target, uint32_t address, uint32_t size, uint8_t * buffer)
+{
+
+       return dsp563xx_read_memory(target, dsp563xx_get_default_memory(), address, size, 0, buffer);
+}
+
+static int dsp563xx_write_memory_core(struct target *target, int mem_type, uint32_t address, uint32_t size, uint32_t count, const uint8_t * buffer)
 {
        int err;
        struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
        uint32_t i, x;
        uint32_t data, move_cmd = 0;
-       uint8_t *b;
+       const uint8_t *b;
 
        LOG_DEBUG("memtype: %d address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", mem_type,address, size, count);
 
@@ -1512,7 +1647,7 @@ static int dsp563xx_write_memory_core(struct target *target, int mem_type, uint3
                        move_cmd = 0x075891;
                        break;
                default:
-                       return ERROR_INVALID_ARGUMENTS;
+                       return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        /* we use r0 to store temporary data */
@@ -1557,16 +1692,31 @@ static int dsp563xx_write_memory_core(struct target *target, int mem_type, uint3
        return ERROR_OK;
 }
 
-static int dsp563xx_write_memory(struct target *target, int mem_type, uint32_t address, uint32_t size, uint32_t count, uint8_t * buffer)
+static int dsp563xx_write_memory(struct target *target, int mem_type, uint32_t address, uint32_t size, uint32_t count, const uint8_t * buffer)
 {
        int err;
        uint32_t i,i1;
        uint8_t *buffer_y,*buffer_x;
 
+       /* if size equals zero we are called from target write memory
+        * and have to handle the parameter here */
+       if ( (size == 0) && (count != 0) )
+       {
+               size = count % 4;
+
+               if ( size )
+               {
+                       LOG_DEBUG("size is not aligned to 4 byte");
+               }
+
+               count = (count - size) / 4;
+               size  = 4;
+       }
+
        /* we only support 4 byte aligned data */
        if ( (size != 4) || (!count) )
        {
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        if ( mem_type != MEM_L )
@@ -1576,19 +1726,19 @@ static int dsp563xx_write_memory(struct target *target, int mem_type, uint32_t a
 
        if ( !(buffer_y = malloc(size*count)) )
        {
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        if ( !(buffer_x = malloc(size*count)) )
        {
                free(buffer_y);
-               return ERROR_INVALID_ARGUMENTS;
+               return ERROR_COMMAND_SYNTAX_ERROR;
        }
 
        for(i=0,i1=0;i<count;i+=2,i1++)
        {
-               ((uint32_t*)buffer_y)[i1] = ((uint32_t*)buffer)[i];
-               ((uint32_t*)buffer_x)[i1] = ((uint32_t*)buffer)[i+1];
+               buf_set_u32(buffer_y + i1*sizeof(uint32_t), 0, 32, buf_get_u32(buffer+i*sizeof(uint32_t), 0, 32));
+               buf_set_u32(buffer_x + i1*sizeof(uint32_t), 0, 32, buf_get_u32(buffer+(i+1)*sizeof(uint32_t), 0, 32));
        }
 
        err = dsp563xx_write_memory_core(target,MEM_Y,address,size,count/2,buffer_y);
@@ -1615,12 +1765,17 @@ static int dsp563xx_write_memory(struct target *target, int mem_type, uint32_t a
        return ERROR_OK;
 }
 
-static int dsp563xx_write_memory_default(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t * buffer)
+static int dsp563xx_write_memory_default(struct target *target, uint32_t address, uint32_t size, uint32_t count, const uint8_t * buffer)
 {
        return dsp563xx_write_memory(target, dsp563xx_get_default_memory(), address, size, count, buffer);
 }
 
-static int dsp563xx_bulk_write_memory_default(struct target *target, uint32_t address, uint32_t count, uint8_t *buffer)
+static int dsp563xx_write_buffer_default(struct target *target, uint32_t address, uint32_t size, const uint8_t * buffer)
+{
+       return dsp563xx_write_memory(target, dsp563xx_get_default_memory(), address, size, 0, buffer);
+}
+
+static int dsp563xx_bulk_write_memory_default(struct target *target, uint32_t address, uint32_t count, const uint8_t *buffer)
 {
        return dsp563xx_write_memory(target, dsp563xx_get_default_memory(), address, 4, count, buffer);
 }
@@ -1675,7 +1830,7 @@ static void handle_md_output(struct command_context *cmd_ctx, struct target *tar
        {
                if (i % line_modulo == 0)
                {
-                       output_len += snprintf(output + output_len, sizeof(output) - output_len, "0x%8.8x: ", (unsigned) (address + (i * size)));
+                       output_len += snprintf(output + output_len, sizeof(output) - output_len, "0x%8.8x: ", (unsigned) (address + i));
                }
 
                uint32_t value = 0;
@@ -1866,6 +2021,11 @@ struct target_type dsp563xx_target = {
        .write_memory = dsp563xx_write_memory_default,
        .bulk_write_memory = dsp563xx_bulk_write_memory_default,
 
+       .read_buffer = dsp563xx_read_buffer_default,
+       .write_buffer = dsp563xx_write_buffer_default,
+
+       .run_algorithm = dsp563xx_run_algorithm,
+
        .add_breakpoint = dsp563xx_add_breakpoint,
        .remove_breakpoint = dsp563xx_remove_breakpoint,
        .add_watchpoint = dsp563xx_add_watchpoint,