- remove pipeline context, use once register instead - fix wrong register write in...
[openocd.git] / src / target / dsp563xx.c
index 85d559a03e5062c0177efaaf1e053d9b0d78199b..5e307397ce15fe15a37462524d1f592171196bee 100644 (file)
@@ -29,8 +29,6 @@
 #include "dsp563xx.h"
 #include "dsp563xx_once.h"
 
-//#define DSP563XX_JTAG_INS_LEN         4
-
 #define ASM_REG_W_R0   0x60F400
 #define ASM_REG_W_R1   0x61F400
 #define ASM_REG_W_R2   0x62F400
 #define ASM_REG_W_AAR2 0xFFFFF7
 #define ASM_REG_W_AAR3 0xFFFFF6
 
+enum once_reg_idx {
+       ONCE_REG_IDX_OSCR=0,
+       ONCE_REG_IDX_OMBC=1,
+       ONCE_REG_IDX_OBCR=2,
+       ONCE_REG_IDX_OMLR0=3,
+       ONCE_REG_IDX_OMLR1=4,
+       ONCE_REG_IDX_OGDBR=5,
+       ONCE_REG_IDX_OPDBR=6,
+       ONCE_REG_IDX_OPILR=7,
+       ONCE_REG_IDX_PDB=8,
+       ONCE_REG_IDX_OTC=9,
+       ONCE_REG_IDX_OPABFR=10,
+       ONCE_REG_IDX_OPABDR=11,
+       ONCE_REG_IDX_OPABEX=12,
+       ONCE_REG_IDX_OPABF0=13,
+       ONCE_REG_IDX_OPABF1=14,
+       ONCE_REG_IDX_OPABF2=15,
+       ONCE_REG_IDX_OPABF3=16,
+       ONCE_REG_IDX_OPABF4=17,
+       ONCE_REG_IDX_OPABF5=18,
+       ONCE_REG_IDX_OPABF6=19,
+       ONCE_REG_IDX_OPABF7=20,
+       ONCE_REG_IDX_OPABF8=21,
+       ONCE_REG_IDX_OPABF9=22,
+       ONCE_REG_IDX_OPABF10=23,
+       ONCE_REG_IDX_OPABF11=24,
+};
+
 static struct once_reg once_regs[] = {
-       {0, 0x00, 24, "OSCR", 0},
-       {1, 0x01, 24, "OMBC", 0},
-       {2, 0x02, 24, "OBCR", 0},
-       {3, 0x05, 24, "OMLR0", 0},
-       {4, 0x06, 24, "OMLR1", 0},
-       {5, 0x09, 24, "OGDBR", 0},
-       {6, 0x0a, 24, "OPDBR", 0},
-       {7, 0x0b, 24, "OPILR", 0},
-       {8, 0x0c, 24, "PDB", 0},
-       {9, 0x0d, 24, "OTC", 0},
-       {10, 0x0f, 24, "OPABFR", 0},
-       {11, 0x10, 24, "OPABDR", 0},
-       {12, 0x11, 24, "OPABEX", 0},
-       {13, 0x12, 25, "OPABF0", 0},
-       {14, 0x12, 25, "OPABF1", 0},
-       {15, 0x12, 25, "OPABF2", 0},
-       {16, 0x12, 25, "OPABF3", 0},
-       {17, 0x12, 25, "OPABF4", 0},
-       {18, 0x12, 25, "OPABF5", 0},
-       {19, 0x12, 25, "OPABF6", 0},
-       {20, 0x12, 25, "OPABF7", 0},
-       {21, 0x12, 25, "OPABF8", 0},
-       {22, 0x12, 25, "OPABF9", 0},
-       {23, 0x12, 25, "OPABF10", 0},
-       {24, 0x12, 25, "OPABF11", 0},
+       {ONCE_REG_IDX_OSCR,    DSP563XX_ONCE_OSCR,    24, "OSCR",    0},
+       {ONCE_REG_IDX_OMBC,    DSP563XX_ONCE_OMBC,    24, "OMBC",    0},
+       {ONCE_REG_IDX_OBCR,    DSP563XX_ONCE_OBCR,    24, "OBCR",    0},
+       {ONCE_REG_IDX_OMLR0,   DSP563XX_ONCE_OMLR0,   24, "OMLR0",   0},
+       {ONCE_REG_IDX_OMLR1,   DSP563XX_ONCE_OMLR1,   24, "OMLR1",   0},
+       {ONCE_REG_IDX_OGDBR,   DSP563XX_ONCE_OGDBR,   24, "OGDBR",   0},
+       {ONCE_REG_IDX_OPDBR,   DSP563XX_ONCE_OPDBR,   24, "OPDBR",   0},
+       {ONCE_REG_IDX_OPILR,   DSP563XX_ONCE_OPILR,   24, "OPILR",   0},
+       {ONCE_REG_IDX_PDB,     DSP563XX_ONCE_PDBGOTO, 24, "PDB",     0},
+       {ONCE_REG_IDX_OTC,     DSP563XX_ONCE_OTC,     24, "OTC",     0},
+       {ONCE_REG_IDX_OPABFR,  DSP563XX_ONCE_OPABFR,  24, "OPABFR",  0},
+       {ONCE_REG_IDX_OPABDR,  DSP563XX_ONCE_OPABDR,  24, "OPABDR",  0},
+       {ONCE_REG_IDX_OPABEX,  DSP563XX_ONCE_OPABEX,  24, "OPABEX",  0},
+       {ONCE_REG_IDX_OPABF0,  DSP563XX_ONCE_OPABF11, 25, "OPABF0",  0},
+       {ONCE_REG_IDX_OPABF1,  DSP563XX_ONCE_OPABF11, 25, "OPABF1",  0},
+       {ONCE_REG_IDX_OPABF2,  DSP563XX_ONCE_OPABF11, 25, "OPABF2",  0},
+       {ONCE_REG_IDX_OPABF3,  DSP563XX_ONCE_OPABF11, 25, "OPABF3",  0},
+       {ONCE_REG_IDX_OPABF4,  DSP563XX_ONCE_OPABF11, 25, "OPABF4",  0},
+       {ONCE_REG_IDX_OPABF5,  DSP563XX_ONCE_OPABF11, 25, "OPABF5",  0},
+       {ONCE_REG_IDX_OPABF6,  DSP563XX_ONCE_OPABF11, 25, "OPABF6",  0},
+       {ONCE_REG_IDX_OPABF7,  DSP563XX_ONCE_OPABF11, 25, "OPABF7",  0},
+       {ONCE_REG_IDX_OPABF8,  DSP563XX_ONCE_OPABF11, 25, "OPABF8",  0},
+       {ONCE_REG_IDX_OPABF9,  DSP563XX_ONCE_OPABF11, 25, "OPABF9",  0},
+       {ONCE_REG_IDX_OPABF10, DSP563XX_ONCE_OPABF11, 25, "OPABF10", 0},
+       {ONCE_REG_IDX_OPABF11, DSP563XX_ONCE_OPABF11, 25, "OPABF11", 0},
 //      {25,0x1f,24,"NRSEL",0},
 };
 
@@ -201,6 +227,7 @@ static const struct
 };
 
 #define REG_NUM_R0     0
+#define REG_NUM_R1     1
 #define REG_NUM_N0     8
 #define REG_NUM_N1     9
 #define REG_NUM_M0     16
@@ -221,6 +248,13 @@ static const struct
 #define REG_NUM_AAR2   52
 #define REG_NUM_AAR3   53
 
+enum memory_type
+{
+       MEM_X = 0,
+       MEM_Y = 1,
+       MEM_P = 2,
+};
+
 #define INSTR_JUMP     0x0AF080
 /* Effective Addressing Mode Encoding */
 #define EAME_R0                0x10
@@ -359,15 +393,15 @@ static int dsp563xx_reg_read_high_io(struct target *target, uint32_t instr_mask,
                dsp563xx->read_core_reg(target, REG_NUM_R0);
 
        /* move source memory to r0 */
-       instr = INSTR_MOVEP_REG_HIO(0, 0, EAME_R0, instr_mask);
-       if ((err = dsp563xx_once_execute_sw_ir_nq(target->tap, instr)) != ERROR_OK)
+       instr = INSTR_MOVEP_REG_HIO(MEM_X, 0, EAME_R0, instr_mask);
+       if ((err = dsp563xx_once_execute_sw_ir(target->tap, 0, instr)) != ERROR_OK)
                return err;
        /* move r0 to debug register */
-       instr = INSTR_MOVEP_REG_HIO(0, 1, EAME_R0, 0xfffffc);
-       if ((err = dsp563xx_once_execute_sw_ir(target->tap, instr)) != ERROR_OK)
+       instr = INSTR_MOVEP_REG_HIO(MEM_X, 1, EAME_R0, 0xfffffc);
+       if ((err = dsp563xx_once_execute_sw_ir(target->tap, 1, instr)) != ERROR_OK)
                return err;
        /* read debug register */
-       if ((err = dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OGDBR, data)) != ERROR_OK)
+       if ((err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OGDBR, data)) != ERROR_OK)
                return err;
        /* r0 is no longer valid on target */
        dsp563xx->core_cache->reg_list[REG_NUM_R0].dirty = 1;
@@ -386,11 +420,11 @@ static int dsp563xx_reg_write_high_io(struct target *target, uint32_t instr_mask
                dsp563xx->read_core_reg(target, REG_NUM_R0);
 
        /* move data to r0 */
-       if ((err = dsp563xx_once_execute_dw_ir_nq(target->tap, 0x60F400, data)) != ERROR_OK)
+       if ((err = dsp563xx_once_execute_dw_ir(target->tap, 0, 0x60F400, data)) != ERROR_OK)
                return err;
        /* move r0 to destination memory */
-       instr = INSTR_MOVEP_REG_HIO(0, 1, EAME_R0, instr_mask);
-       if ((err = dsp563xx_once_execute_sw_ir(target->tap, instr)) != ERROR_OK)
+       instr = INSTR_MOVEP_REG_HIO(MEM_X, 1, EAME_R0, instr_mask);
+       if ((err = dsp563xx_once_execute_sw_ir(target->tap, 1, instr)) != ERROR_OK)
                return err;
 
        /* r0 is no longer valid on target */
@@ -404,57 +438,63 @@ static int dsp563xx_reg_read(struct target *target, uint32_t eame, uint32_t * da
        int err;
        uint32_t instr;
 
-       instr = INSTR_MOVEP_REG_HIO(0, 1, eame, 0xfffffc);
-       if ((err = dsp563xx_once_execute_sw_ir_nq(target->tap, instr)) != ERROR_OK)
+       instr = INSTR_MOVEP_REG_HIO(MEM_X, 1, eame, 0xfffffc);
+       if ((err = dsp563xx_once_execute_sw_ir(target->tap, 0, instr)) != ERROR_OK)
                return err;
        /* nop */
-       if ((err = dsp563xx_once_execute_sw_ir(target->tap, 0x000000)) != ERROR_OK)
+       if ((err = dsp563xx_once_execute_sw_ir(target->tap, 1, 0x000000)) != ERROR_OK)
                return err;
        /* read debug register */
-       return dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OGDBR, data);
+       return dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OGDBR, data);
 }
 
 static int dsp563xx_reg_write(struct target *target, uint32_t instr_mask, uint32_t data)
 {
        int err;
 
-       if ((err = dsp563xx_once_execute_dw_ir_nq(target->tap, instr_mask, data)) != ERROR_OK)
+       if ((err = dsp563xx_once_execute_dw_ir(target->tap, 0, instr_mask, data)) != ERROR_OK)
                return err;
        /* nop */
-       return dsp563xx_once_execute_sw_ir(target->tap, 0x000000);
+       return dsp563xx_once_execute_sw_ir(target->tap, 1, 0x000000);
 }
 
 static int dsp563xx_reg_pc_read(struct target *target)
 {
-       int err;
-       uint32_t opabdr, opabex;
        struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
 
        /* pc was changed, nothing todo */
        if (dsp563xx->core_cache->reg_list[REG_NUM_PC].dirty)
                return ERROR_OK;
 
-       if ((err = dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPABDR, &opabdr)) != ERROR_OK)
-               return err;
-       if ((err = dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPABEX, &opabex)) != ERROR_OK)
-               return err;
-
        /* conditional branch check */
-       if (opabdr == opabex)
+       if ( once_regs[ONCE_REG_IDX_OPABDR].reg == once_regs[ONCE_REG_IDX_OPABEX].reg )
        {
-               /* TODO: check the trace buffer and if a
-                * conditional branch is detected then decode
-                * the branch command and add the relative
-                * address to the current pc
-                */
-               LOG_DEBUG("%s conditional branch not supported yet", __FUNCTION__);
+               if ( (once_regs[ONCE_REG_IDX_OPABF11].reg & 1) == 0 )
+               {
+                       LOG_DEBUG("%s conditional branch not supported yet", __FUNCTION__);
+
+                       /* TODO: use disassembly to set correct pc offset */
+                       dsp563xx->core_regs[REG_NUM_PC] = (once_regs[ONCE_REG_IDX_OPABF11].reg >> 1) & 0x00FFFFFF;
+               }
+               else
+               {
+                       if ( once_regs[ONCE_REG_IDX_OPABEX].reg == once_regs[ONCE_REG_IDX_OPABFR].reg )
+                       {
+                               dsp563xx->core_regs[REG_NUM_PC] = once_regs[ONCE_REG_IDX_OPABEX].reg;
+                       }
+                       else
+                       {
+                               dsp563xx->core_regs[REG_NUM_PC] = once_regs[ONCE_REG_IDX_OPABEX].reg - 1;
+                       }
+               }
        }
        else
        {
-               dsp563xx->core_regs[REG_NUM_PC] = opabex;
-               dsp563xx->read_core_reg(target, REG_NUM_PC);
+               dsp563xx->core_regs[REG_NUM_PC] = once_regs[ONCE_REG_IDX_OPABEX].reg;
        }
 
+       dsp563xx->read_core_reg(target, REG_NUM_PC);
+
        return ERROR_OK;
 }
 
@@ -765,7 +805,7 @@ static int dsp563xx_arch_state(struct target *target)
 
 static int dsp563xx_debug_once_init(struct target *target)
 {
-       return dsp563xx_once_read_register(target->tap, once_regs, DSP563XX_NUMONCEREGS);
+       return dsp563xx_once_read_register(target->tap, 1, once_regs, DSP563XX_NUMONCEREGS);
 }
 
 static int dsp563xx_debug_init(struct target *target)
@@ -790,7 +830,7 @@ static int dsp563xx_debug_init(struct target *target)
        {
                sr &= ~(DSP563XX_SR_SA | DSP563XX_SR_SC);
 
-               if ((err = dsp563xx_once_execute_dw_ir(target->tap, arch_info->instr_mask, sr)) != ERROR_OK)
+               if ((err = dsp563xx_once_execute_dw_ir(target->tap, 1, arch_info->instr_mask, sr)) != ERROR_OK)
                        return err;
                dsp563xx->core_cache->reg_list[REG_NUM_SR].dirty = 1;
        }
@@ -862,7 +902,7 @@ static int dsp563xx_poll(struct target *target)
                return ERROR_TARGET_FAILURE;
        }
 
-       if ((err = dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OSCR, &once_status)) != ERROR_OK)
+       if ((err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OSCR, &once_status)) != ERROR_OK)
                return err;
 
        if ((once_status & DSP563XX_ONCE_OSCR_DEBUG_M) == DSP563XX_ONCE_OSCR_DEBUG_M)
@@ -883,7 +923,6 @@ static int dsp563xx_poll(struct target *target)
 static int dsp563xx_halt(struct target *target)
 {
        int err;
-       struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
 
        if (target->state == TARGET_HALTED)
        {
@@ -899,12 +938,6 @@ static int dsp563xx_halt(struct target *target)
        if ((err = dsp563xx_jtag_debug_request(target)) != ERROR_OK)
                return err;
 
-       /* store pipeline register */
-       if ((err = dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPILR, &dsp563xx->pipeline_context.once_opilr)) != ERROR_OK)
-               return err;
-       if ((err = dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPDBR, &dsp563xx->pipeline_context.once_opdbr)) != ERROR_OK)
-               return err;
-
        LOG_DEBUG("%s", __FUNCTION__);
 
        return ERROR_OK;
@@ -924,19 +957,19 @@ static int dsp563xx_resume(struct target *target, int current, uint32_t address,
        if (current)
        {
                /* restore pipeline registers and go */
-               if ((err = dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OPILR, dsp563xx->pipeline_context.once_opilr)) != ERROR_OK)
+               if ((err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR, once_regs[ONCE_REG_IDX_OPILR].reg)) != ERROR_OK)
                        return err;
                if ((err =
-                    dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OPDBR | DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO,
-                                            dsp563xx->pipeline_context.once_opdbr)) != ERROR_OK)
+                    dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR | DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO,
+                                            once_regs[ONCE_REG_IDX_OPDBR].reg)) != ERROR_OK)
                        return err;
        }
        else
        {
                /* set to go register and jump */
-               if ((err = dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OPDBR, INSTR_JUMP)) != ERROR_OK)
+               if ((err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR, INSTR_JUMP)) != ERROR_OK)
                        return err;
-               if ((err = dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_PDBGOTO | DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO, address)) != ERROR_OK)
+               if ((err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_PDBGOTO | DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO, address)) != ERROR_OK)
                        return err;
        }
 
@@ -966,10 +999,10 @@ static int dsp563xx_step_ex(struct target *target, int current, uint32_t address
                return err;
 
        /* reset trace mode */
-       if ((err = dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OSCR, 0x000000)) != ERROR_OK)
+       if ((err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OSCR, 0x000000)) != ERROR_OK)
                return err;
        /* enable trace mode */
-       if ((err = dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OSCR, DSP563XX_ONCE_OSCR_TME)) != ERROR_OK)
+       if ((err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OSCR, DSP563XX_ONCE_OSCR_TME)) != ERROR_OK)
                return err;
 
        cnt = steps;
@@ -979,53 +1012,47 @@ static int dsp563xx_step_ex(struct target *target, int current, uint32_t address
                cnt++;
 
        /* load step counter with N-1 */
-       if ((err = dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OTC, cnt)) != ERROR_OK)
+       if ((err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OTC, cnt)) != ERROR_OK)
                return err;
 
        if (current)
        {
                /* restore pipeline registers and go */
-               if ((err = dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OPILR, dsp563xx->pipeline_context.once_opilr)) != ERROR_OK)
+               if ((err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR, once_regs[ONCE_REG_IDX_OPILR].reg)) != ERROR_OK)
                        return err;
                if ((err =
-                    dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OPDBR | DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO,
-                                            dsp563xx->pipeline_context.once_opdbr)) != ERROR_OK)
+                    dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR | DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO,
+                                            once_regs[ONCE_REG_IDX_OPDBR].reg)) != ERROR_OK)
                        return err;
        }
        else
        {
                /* set to go register and jump */
-               if ((err = dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OPDBR, INSTR_JUMP)) != ERROR_OK)
+               if ((err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OPDBR, INSTR_JUMP)) != ERROR_OK)
                        return err;
-               if ((err = dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_PDBGOTO | DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO, address)) != ERROR_OK)
+               if ((err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_PDBGOTO | DSP563XX_ONCE_OCR_EX | DSP563XX_ONCE_OCR_GO, address)) != ERROR_OK)
                        return err;
        }
 
        while (1)
        {
-               if ((err = dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OSCR, &once_status)) != ERROR_OK)
+               if ((err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OSCR, &once_status)) != ERROR_OK)
                        return err;
 
                if (once_status & DSP563XX_ONCE_OSCR_TO)
                {
-                       /* store pipeline register */
-                       if ((err = dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPILR, &dsp563xx->pipeline_context.once_opilr)) != ERROR_OK)
+                       if ((err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OPABFR, &dr_in)) != ERROR_OK)
                                return err;
-                       if ((err = dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPDBR, &dsp563xx->pipeline_context.once_opdbr)) != ERROR_OK)
+                       LOG_DEBUG("fetch: %08X", (unsigned) dr_in&0x00ffffff);
+                       if ((err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OPABDR, &dr_in)) != ERROR_OK)
                                return err;
-
-                       if ((err = dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPABFR, &dr_in)) != ERROR_OK)
+                       LOG_DEBUG("decode: %08X", (unsigned) dr_in&0x00ffffff);
+                       if ((err = dsp563xx_once_reg_read(target->tap, 1, DSP563XX_ONCE_OPABEX, &dr_in)) != ERROR_OK)
                                return err;
-                       LOG_DEBUG("fetch: %08X", (unsigned) dr_in);
-                       if ((err = dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPABDR, &dr_in)) != ERROR_OK)
-                               return err;
-                       LOG_DEBUG("decode: %08X", (unsigned) dr_in);
-                       if ((err = dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OPABEX, &dr_in)) != ERROR_OK)
-                               return err;
-                       LOG_DEBUG("execute: %08X", (unsigned) dr_in);
+                       LOG_DEBUG("execute: %08X", (unsigned) dr_in&0x00ffffff);
 
                        /* reset trace mode */
-                       if ((err = dsp563xx_once_reg_write(target->tap, DSP563XX_ONCE_OSCR, 0x000000)) != ERROR_OK)
+                       if ((err = dsp563xx_once_reg_write(target->tap, 1, DSP563XX_ONCE_OSCR, 0x000000)) != ERROR_OK)
                                return err;
 
                        register_cache_invalidate(dsp563xx->core_cache);
@@ -1114,33 +1141,12 @@ static int dsp563xx_soft_reset_halt(struct target *target)
        return ERROR_OK;
 }
 
-/*
-* 000000                       nop
-* 46F400 AABBCC                move              #$aabbcc,y0
-* 60F400 AABBCC                move              #$aabbcc,r0
-* 467000 AABBCC                move              y0,x:AABBCC
-* 607000 AABBCC                move              r0,x:AABBCC
-
-* 46E000               move              x:(r0),y0
-* 4EE000               move              y:(r0),y0
-* 07E086               move              p:(r0),y0
-
-* 0450B9               move              sr,r0
-* 0446BA               move              omr,y0
-* 0446BC               move              ssh,y0
-* 0446BD               move              ssl,y0
-* 0446BE               move              la,y0
-* 0446BF               move              lc,y0
-*
-* 61F000 AABBCC                move              x:AABBCC,r1
-* 076190               movem             r0,p:(r1)
-*
-*/
-static int dsp563xx_read_memory_p(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t * buffer)
+static int dsp563xx_read_memory(struct target *target, int mem_type, uint32_t address, uint32_t size, uint32_t count, uint8_t * buffer)
 {
        int err;
+       struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
        uint32_t i, x;
-       uint32_t data;
+       uint32_t data, move_cmd;
        uint8_t *b;
 
        LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32, address, size, count);
@@ -1151,41 +1157,88 @@ static int dsp563xx_read_memory_p(struct target *target, uint32_t address, uint3
                return ERROR_TARGET_NOT_HALTED;
        }
 
+       /* we only support 4 byte aligned data */
+       if ( size != 4 )
+       {
+               return ERROR_INVALID_ARGUMENTS;
+       }
+
+       switch (mem_type)
+       {
+               case MEM_X:
+                       /* TODO: mark effected queued registers */
+                       move_cmd = 0x61d800;
+                       break;
+               case MEM_Y:
+                       move_cmd = 0x69d800;
+                       break;
+               case MEM_P:
+                       move_cmd = 0x07d891;
+                       break;
+               default:
+                       return ERROR_INVALID_ARGUMENTS;
+       }
+
+       /* we use r0 to store temporary data */
+       if (!dsp563xx->core_cache->reg_list[REG_NUM_R0].valid)
+               dsp563xx->read_core_reg(target, REG_NUM_R0);
+       /* we use r1 to store temporary data */
+       if (!dsp563xx->core_cache->reg_list[REG_NUM_R1].valid)
+               dsp563xx->read_core_reg(target, REG_NUM_R1);
+
+       /* r0 is no longer valid on target */
+       dsp563xx->core_cache->reg_list[REG_NUM_R0].dirty = 1;
+       /* r1 is no longer valid on target */
+       dsp563xx->core_cache->reg_list[REG_NUM_R1].dirty = 1;
+
        x = count;
+       b = buffer;
+
+       if ((err = dsp563xx_once_execute_dw_ir(target->tap, 1, 0x60F400, address)) != ERROR_OK)
+               return err;
 
        for (i = 0; i < x; i++)
        {
-               if ((err = dsp563xx_once_execute_dw_ir_nq(target->tap, 0x60F400, address + i)) != ERROR_OK)
-                       return err;
-               if ((err = dsp563xx_once_execute_sw_ir_nq(target->tap, 0x07E086)) != ERROR_OK)
+               if ((err = dsp563xx_once_execute_sw_ir(target->tap, 0, move_cmd)) != ERROR_OK)
                        return err;
-               if ((err = dsp563xx_once_execute_dw_ir_nq(target->tap, 0x467000, 0xfffffc)) != ERROR_OK)
+               if ((err = dsp563xx_once_execute_sw_ir(target->tap, 0, 0x08D13C)) != ERROR_OK)
                        return err;
-               if ((err = jtag_execute_queue()) != ERROR_OK)
+               if ((err = dsp563xx_once_reg_read(target->tap, 0, DSP563XX_ONCE_OGDBR, (uint32_t*)b)) != ERROR_OK)
                        return err;
+               b += 4;
+       }
 
-               if ((err = dsp563xx_once_reg_read(target->tap, DSP563XX_ONCE_OGDBR, &data)) != ERROR_OK)
-                       return err;
+       /* flush the jtag queue */
+       if ((err = jtag_execute_queue()) != ERROR_OK)
+       {
+               return err;
+       }
+
+       /* walk over the buffer and fix target endianness */
+       b = buffer;
 
-               b = buffer + 4 * i;
-               if (size > 0)
-                       *b++ = data >> 0;
-               if (size > 1)
-                       *b++ = data >> 8;
-               if (size > 2)
-                       *b++ = data >> 16;
-               if (size > 3)
-                       *b++ = 0x00;
+       for (i = 0; i < x; i++)
+       {
+               data = *((uint32_t*)b) & 0x00FFFFFF;
+//             LOG_DEBUG("R: %08X", *((uint32_t*)b));
+               target_buffer_set_u32(target, b, data);
+               b += 4;
        }
 
        return ERROR_OK;
 }
 
-static int dsp563xx_write_memory_p(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t * buffer)
+static int dsp563xx_read_memory_p(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t * buffer)
+{
+       return dsp563xx_read_memory(target, MEM_P, address, size, count, buffer);
+}
+
+static int dsp563xx_write_memory(struct target *target, int mem_type, uint32_t address, uint32_t size, uint32_t count, uint8_t * buffer)
 {
        int err;
+       struct dsp563xx_common *dsp563xx = target_to_dsp563xx(target);
        uint32_t i, x;
-       uint32_t data;
+       uint32_t data, move_cmd;
        uint8_t *b;
 
        LOG_DEBUG("address: 0x%8.8" PRIx32 ", size: 0x%8.8" PRIx32 ", count: 0x%8.8" PRIx32 "", address, size, count);
@@ -1196,37 +1249,277 @@ static int dsp563xx_write_memory_p(struct target *target, uint32_t address, uint
                return ERROR_TARGET_NOT_HALTED;
        }
 
+       /* we only support 4 byte aligned data */
+       if ( size != 4 )
+       {
+               return ERROR_INVALID_ARGUMENTS;
+       }
+
+       switch (mem_type)
+       {
+               case MEM_X:
+                       move_cmd = 0x615800;
+                       break;
+               case MEM_Y:
+                       move_cmd = 0x695800;
+                       break;
+               case MEM_P:
+                       move_cmd = 0x075891;
+                       break;
+               default:
+                       return ERROR_INVALID_ARGUMENTS;
+       }
+
+       /* we use r0 to store temporary data */
+       if (!dsp563xx->core_cache->reg_list[REG_NUM_R0].valid)
+               dsp563xx->read_core_reg(target, REG_NUM_R0);
+       /* we use r1 to store temporary data */
+       if (!dsp563xx->core_cache->reg_list[REG_NUM_R1].valid)
+               dsp563xx->read_core_reg(target, REG_NUM_R1);
+
+       /* r0 is no longer valid on target */
+       dsp563xx->core_cache->reg_list[REG_NUM_R0].dirty = 1;
+       /* r1 is no longer valid on target */
+       dsp563xx->core_cache->reg_list[REG_NUM_R1].dirty = 1;
+
        x = count;
+       b = buffer;
+
+       if ((err = dsp563xx_once_execute_dw_ir(target->tap, 1, 0x60F400, address)) != ERROR_OK)
+               return err;
 
        for (i = 0; i < x; i++)
        {
-               b = buffer + 4 * i;
+               data = target_buffer_get_u32(target, b);
 
-               data = 0;
-               if (size > 0)
-                       data = *buffer++;
-               if (size > 1)
-                       data |= (*buffer++) << 8;
-               if (size > 2)
-                       data |= (*buffer++) << 16;
-               if (size > 3)
-                       data |= (*buffer++) << 24;
+//             LOG_DEBUG("W: %08X", data);
 
-//              LOG_DEBUG("%08X", data);
+               data &= 0x00ffffff;
 
-               if ((err = dsp563xx_once_execute_dw_ir_nq(target->tap, 0x61F400, address + i)) != ERROR_OK)
-                       return err;
-               if ((err = dsp563xx_once_execute_dw_ir_nq(target->tap, 0x60F400, data)) != ERROR_OK)
+               if ((err = dsp563xx_once_execute_dw_ir(target->tap, 0, 0x61F400, data)) != ERROR_OK)
                        return err;
-               if ((err = dsp563xx_once_execute_sw_ir_nq(target->tap, 0x076190)) != ERROR_OK)
-                       return err;
-               if ((err = jtag_execute_queue()) != ERROR_OK)
+               if ((err = dsp563xx_once_execute_sw_ir(target->tap, 0, move_cmd)) != ERROR_OK)
                        return err;
+               b += 4;
+       }
+
+       /* flush the jtag queue */
+       if ((err = jtag_execute_queue()) != ERROR_OK)
+       {
+               return err;
        }
 
        return ERROR_OK;
 }
 
+static int dsp563xx_write_memory_p(struct target *target, uint32_t address, uint32_t size, uint32_t count, uint8_t * buffer)
+{
+       return dsp563xx_write_memory(target, MEM_P, address, size, count, buffer);
+}
+
+static int dsp563xx_bulk_write_memory_p(struct target *target, uint32_t address, uint32_t count, uint8_t *buffer)
+{
+       return dsp563xx_write_memory(target, MEM_P, address, 4, count, buffer);
+}
+
+static void handle_md_output(struct command_context *cmd_ctx, struct target *target, uint32_t address, unsigned size, unsigned count, const uint8_t * buffer)
+{
+       const unsigned line_bytecnt = 32;
+       unsigned line_modulo = line_bytecnt / size;
+
+       char output[line_bytecnt * 4 + 1];
+       unsigned output_len = 0;
+
+       const char *value_fmt;
+       switch (size)
+       {
+               case 4:
+                       value_fmt = "%8.8x ";
+                       break;
+               case 2:
+                       value_fmt = "%4.4x ";
+                       break;
+               case 1:
+                       value_fmt = "%2.2x ";
+                       break;
+               default:
+                       /* "can't happen", caller checked */
+                       LOG_ERROR("invalid memory read size: %u", size);
+                       return;
+       }
+
+       for (unsigned i = 0; i < count; i++)
+       {
+               if (i % line_modulo == 0)
+               {
+                       output_len += snprintf(output + output_len, sizeof(output) - output_len, "0x%8.8x: ", (unsigned) (address + (i * size)));
+               }
+
+               uint32_t value = 0;
+               const uint8_t *value_ptr = buffer + i * size;
+               switch (size)
+               {
+                       case 4:
+                               value = target_buffer_get_u32(target, value_ptr);
+                               break;
+                       case 2:
+                               value = target_buffer_get_u16(target, value_ptr);
+                               break;
+                       case 1:
+                               value = *value_ptr;
+               }
+               output_len += snprintf(output + output_len, sizeof(output) - output_len, value_fmt, value);
+
+               if ((i % line_modulo == line_modulo - 1) || (i == count - 1))
+               {
+                       command_print(cmd_ctx, "%s", output);
+                       output_len = 0;
+               }
+       }
+}
+
+COMMAND_HANDLER(dsp563xx_mem_command)
+{
+       struct target *target = get_current_target(CMD_CTX);
+       int err = ERROR_OK;
+       int read_mem;
+       uint32_t address = 0;
+       uint32_t count = 1, i;
+       uint32_t pattern = 0;
+       uint32_t mem_type;
+       uint8_t *buffer, *b;
+
+       switch (CMD_NAME[1])
+       {
+               case 'w':
+                       read_mem = 0;
+                       break;
+               case 'd':
+                       read_mem = 1;
+                       break;
+               default:
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       switch (CMD_NAME[3])
+       {
+               case 'x':
+                       mem_type = MEM_X;
+                       break;
+               case 'y':
+                       mem_type = MEM_Y;
+                       break;
+               case 'p':
+                       mem_type = MEM_P;
+                       break;
+               default:
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+       }
+
+       if (CMD_ARGC > 0)
+       {
+               COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
+       }
+
+       if (read_mem == 0)
+       {
+               if (CMD_ARGC < 2)
+               {
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               }
+               if (CMD_ARGC > 1)
+               {
+                       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], pattern);
+               }
+               if (CMD_ARGC > 2)
+               {
+                       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], count);
+               }
+       }
+
+       if (read_mem == 1)
+       {
+               if (CMD_ARGC < 1)
+               {
+                       return ERROR_COMMAND_SYNTAX_ERROR;
+               }
+               if (CMD_ARGC > 1)
+               {
+                       COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], count);
+               }
+       }
+
+       buffer = calloc(count, sizeof(uint32_t));
+
+       if (read_mem == 1)
+       {
+               if ((err = dsp563xx_read_memory(target, mem_type, address, sizeof(uint32_t), count, buffer)) == ERROR_OK)
+                       handle_md_output(CMD_CTX, target, address, sizeof(uint32_t), count, buffer);
+       }
+       else
+       {
+               b = buffer;
+
+               for (i = 0; i < count; i++)
+               {
+                       target_buffer_set_u32(target, b, pattern);
+                       b += 4;
+               }
+
+               err = dsp563xx_write_memory(target, mem_type, address, sizeof(uint32_t), count, buffer);
+       }
+
+       free(buffer);
+
+       return err;
+}
+
+static const struct command_registration dsp563xx_command_handlers[] = {
+       {
+        .name = "mwwx",
+        .handler = dsp563xx_mem_command,
+        .mode = COMMAND_EXEC,
+        .help = "write x memory words",
+        .usage = "mwwx address value [count]",
+        },
+       {
+        .name = "mwwy",
+        .handler = dsp563xx_mem_command,
+        .mode = COMMAND_EXEC,
+        .help = "write y memory words",
+        .usage = "mwwy address value [count]",
+        },
+       {
+        .name = "mwwp",
+        .handler = dsp563xx_mem_command,
+        .mode = COMMAND_EXEC,
+        .help = "write p memory words",
+        .usage = "mwwp address value [count]",
+        },
+       {
+        .name = "mdwx",
+        .handler = dsp563xx_mem_command,
+        .mode = COMMAND_EXEC,
+        .help = "display x memory words",
+        .usage = "mdwx address [count]",
+        },
+       {
+        .name = "mdwy",
+        .handler = dsp563xx_mem_command,
+        .mode = COMMAND_EXEC,
+        .help = "display y memory words",
+        .usage = "mdwy address [count]",
+        },
+       {
+        .name = "mdwp",
+        .handler = dsp563xx_mem_command,
+        .mode = COMMAND_EXEC,
+        .help = "display p memory words",
+        .usage = "mdwp address [count]",
+        },
+       COMMAND_REGISTRATION_DONE
+};
+
 /** Holds methods for DSP563XX targets. */
 struct target_type dsp563xx_target = {
        .name = "dsp563xx",
@@ -1248,7 +1541,9 @@ struct target_type dsp563xx_target = {
 
        .read_memory = dsp563xx_read_memory_p,
        .write_memory = dsp563xx_write_memory_p,
+       .bulk_write_memory = dsp563xx_bulk_write_memory_p,
 
+       .commands = dsp563xx_command_handlers,
        .target_create = dsp563xx_target_create,
        .init_target = dsp563xx_init_target,
 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)