mips32: Removed Unnecessary JTAG Queue Flush
[fw/openocd] / src / target / mips32_pracc.c
index 7d91d42ecade704405655245359f468441bb3ed6..cb8665c3aa79b3f44942371b900ddf600890244f 100644 (file)
@@ -74,6 +74,8 @@ Nico Coesel
 #include "config.h"
 #endif
 
+#include <helper/time_support.h>
+
 #include "mips32.h"
 #include "mips32_pracc.h"
 
@@ -90,19 +92,49 @@ struct mips32_pracc_context
        struct mips_ejtag *ejtag_info;
 };
 
+static int mips32_pracc_read_mem8(struct mips_ejtag *ejtag_info,
+               uint32_t addr, int count, uint8_t *buf);
+static int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info,
+               uint32_t addr, int count, uint16_t *buf);
+static int mips32_pracc_read_mem32(struct mips_ejtag *ejtag_info,
+               uint32_t addr, int count, uint32_t *buf);
+static int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info,
+               uint32_t addr, uint32_t *buf);
+
+static int mips32_pracc_write_mem8(struct mips_ejtag *ejtag_info,
+               uint32_t addr, int count, uint8_t *buf);
+static int mips32_pracc_write_mem16(struct mips_ejtag *ejtag_info,
+               uint32_t addr, int count, uint16_t *buf);
+static int mips32_pracc_write_mem32(struct mips_ejtag *ejtag_info,
+               uint32_t addr, int count, uint32_t *buf);
+static int mips32_pracc_write_u32(struct mips_ejtag *ejtag_info,
+               uint32_t addr, uint32_t *buf);
+
 static int wait_for_pracc_rw(struct mips_ejtag *ejtag_info, uint32_t *ctrl)
 {
        uint32_t ejtag_ctrl;
+       long long then = timeval_ms();
+       int timeout;
+       int retval;
+
+       /* wait for the PrAcc to become "1" */
+       mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
+       ejtag_ctrl = ejtag_info->ejtag_ctrl;
 
        while (1)
        {
-               mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
-               ejtag_ctrl = ejtag_info->ejtag_ctrl;
-               mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
+               retval = mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
+               if (retval != ERROR_OK)
+                       return retval;
+
                if (ejtag_ctrl & EJTAG_CTRL_PRACC)
                        break;
-               LOG_DEBUG("DEBUGMODULE: No memory access in progress!\n");
-               return ERROR_JTAG_DEVICE_ERROR;
+
+               if ( (timeout = timeval_ms()-then) > 1000 )
+               {
+                       LOG_DEBUG("DEBUGMODULE: No memory access in progress!");
+                       return ERROR_JTAG_DEVICE_ERROR;
+               }
        }
 
        *ctrl = ejtag_ctrl;
@@ -149,18 +181,15 @@ static int mips32_pracc_exec_read(struct mips32_pracc_context *ctx, uint32_t add
        }
 
        /* Send the data out */
-       mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA, NULL);
-       mips_ejtag_drscan_32(ctx->ejtag_info, &data);
+       mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA);
+       mips_ejtag_drscan_32_out(ctx->ejtag_info, data);
 
        /* Clear the access pending bit (let the processor eat!) */
        ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
-       mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL, NULL);
-       mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);
-
-       jtag_add_clocks(5);
-       jtag_execute_queue();
+       mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL);
+       mips_ejtag_drscan_32_out(ctx->ejtag_info, ejtag_ctrl);
 
-       return ERROR_OK;
+       return jtag_execute_queue();
 }
 
 static int mips32_pracc_exec_write(struct mips32_pracc_context *ctx, uint32_t address)
@@ -168,17 +197,21 @@ static int mips32_pracc_exec_write(struct mips32_pracc_context *ctx, uint32_t ad
        uint32_t ejtag_ctrl,data;
        int offset;
        struct mips_ejtag *ejtag_info = ctx->ejtag_info;
+       int retval;
 
-       mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA, NULL);
-       mips_ejtag_drscan_32(ctx->ejtag_info, &data);
+       mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_DATA);
+       retval = mips_ejtag_drscan_32(ctx->ejtag_info, &data);
+       if (retval != ERROR_OK)
+               return retval;
 
        /* Clear access pending bit */
        ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
-       mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL, NULL);
-       mips_ejtag_drscan_32(ctx->ejtag_info, &ejtag_ctrl);
+       mips_ejtag_set_instr(ctx->ejtag_info, EJTAG_INST_CONTROL);
+       mips_ejtag_drscan_32_out(ctx->ejtag_info, ejtag_ctrl);
 
-       jtag_add_clocks(5);
-       jtag_execute_queue();
+       retval = jtag_execute_queue();
+       if (retval != ERROR_OK)
+               return retval;
 
        if ((address >= MIPS32_PRACC_PARAM_IN)
                && (address <= MIPS32_PRACC_PARAM_IN + ctx->num_iparam * 4))
@@ -206,7 +239,8 @@ static int mips32_pracc_exec_write(struct mips32_pracc_context *ctx, uint32_t ad
        return ERROR_OK;
 }
 
-int mips32_pracc_exec(struct mips_ejtag *ejtag_info, int code_len, const uint32_t *code, int num_param_in, uint32_t *param_in, int num_param_out, uint32_t *param_out, int cycle)
+int mips32_pracc_exec(struct mips_ejtag *ejtag_info, int code_len, const uint32_t *code,
+               int num_param_in, uint32_t *param_in, int num_param_out, uint32_t *param_out, int cycle)
 {
        uint32_t ejtag_ctrl;
        uint32_t address, data;
@@ -229,8 +263,10 @@ int mips32_pracc_exec(struct mips_ejtag *ejtag_info, int code_len, const uint32_
                        return retval;
 
                address = data = 0;
-               mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
-               mips_ejtag_drscan_32(ejtag_info, &address);
+               mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
+               retval = mips_ejtag_drscan_32(ejtag_info, &address);
+               if (retval != ERROR_OK)
+                       return retval;
 
                /* Check for read or write */
                if (ejtag_ctrl & EJTAG_CTRL_PRNW)
@@ -283,7 +319,7 @@ int mips32_pracc_read_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size
        return ERROR_OK;
 }
 
-int mips32_pracc_read_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint32_t *buf)
+static int mips32_pracc_read_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint32_t *buf)
 {
        static const uint32_t code[] = {
                                                                                                                        /* start: */
@@ -353,7 +389,7 @@ int mips32_pracc_read_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int co
        return retval;
 }
 
-int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf)
+static int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf)
 {
        static const uint32_t code[] = {
                                                                                                                        /* start: */
@@ -386,7 +422,7 @@ int mips32_pracc_read_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t
        return retval;
 }
 
-int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf)
+static int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf)
 {
        static const uint32_t code[] = {
                                                                                                                        /* start: */
@@ -429,13 +465,10 @@ int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int co
        uint32_t *param_out = malloc(count * sizeof(uint32_t));
        int i;
 
-//     int retval;
+       int retval = ERROR_OK;
        int blocksize;
-       int bytesread;
        uint32_t param_in[2];
 
-       bytesread = 0;
-
        //while (count > 0)
        {
                blocksize = count;
@@ -445,12 +478,11 @@ int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int co
                param_in[0] = addr;
                param_in[1] = blocksize;
 
-               mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
+               retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
                        ARRAY_SIZE(param_in), param_in, count, param_out, 1);
 
 //             count -= blocksize;
 //             addr += blocksize;
-//             bytesread += blocksize;
        }
 
        for (i = 0; i < count; i++)
@@ -460,10 +492,10 @@ int mips32_pracc_read_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int co
 
        free(param_out);
 
-       return ERROR_OK;
+       return retval;
 }
 
-int mips32_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint8_t *buf)
+static int mips32_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint8_t *buf)
 {
        static const uint32_t code[] = {
                                                                                                                        /* start: */
@@ -506,13 +538,10 @@ int mips32_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int cou
        uint32_t *param_out = malloc(count * sizeof(uint32_t));
        int i;
 
-//     int retval;
+       int retval = ERROR_OK;
        int blocksize;
-       int bytesread;
        uint32_t param_in[2];
 
-       bytesread = 0;
-
 //     while (count > 0)
        {
                blocksize = count;
@@ -522,12 +551,11 @@ int mips32_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int cou
                param_in[0] = addr;
                param_in[1] = blocksize;
 
-               mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
+               retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
                        ARRAY_SIZE(param_in), param_in, count, param_out, 1);
 
 //             count -= blocksize;
 //             addr += blocksize;
-//             bytesread += blocksize;
        }
 
        for (i = 0; i < count; i++)
@@ -537,7 +565,7 @@ int mips32_pracc_read_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int cou
 
        free(param_out);
 
-       return ERROR_OK;
+       return retval;
 }
 
 int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int size, int count, void *buf)
@@ -558,7 +586,7 @@ int mips32_pracc_write_mem(struct mips_ejtag *ejtag_info, uint32_t addr, int siz
        return ERROR_OK;
 }
 
-int mips32_pracc_write_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint32_t *buf)
+static int mips32_pracc_write_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint32_t *buf)
 {
        static const uint32_t code[] = {
                                                                                                                        /* start: */
@@ -599,15 +627,16 @@ int mips32_pracc_write_mem32(struct mips_ejtag *ejtag_info, uint32_t addr, int c
 
        memcpy(&param_in[2], buf, count * sizeof(uint32_t));
 
-       mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
+       int retval;
+       retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
                count + 2, param_in, 0, NULL, 1);
 
        free(param_in);
 
-       return ERROR_OK;
+       return retval;
 }
 
-int mips32_pracc_write_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf)
+static int mips32_pracc_write_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_t *buf)
 {
        static const uint32_t code[] = {
                                                                                                                        /* start: */
@@ -633,13 +662,11 @@ int mips32_pracc_write_u32(struct mips_ejtag *ejtag_info, uint32_t addr, uint32_
        param_in[0] = addr;
        param_in[1] = *buf;
 
-       mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
+       return mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
                ARRAY_SIZE(param_in), param_in, 0, NULL, 1);
-
-       return ERROR_OK;
 }
 
-int mips32_pracc_write_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf)
+static int mips32_pracc_write_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint16_t *buf)
 {
        static const uint32_t code[] = {
                                                                                                                        /* start: */
@@ -689,15 +716,16 @@ int mips32_pracc_write_mem16(struct mips_ejtag *ejtag_info, uint32_t addr, int c
                param_in[i + 2] = buf[i];
        }
 
-       mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
+       int retval;
+       retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
                count + 2, param_in, 0, NULL, 1);
 
        free(param_in);
 
-       return ERROR_OK;
+       return retval;
 }
 
-int mips32_pracc_write_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint8_t *buf)
+static int mips32_pracc_write_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int count, uint8_t *buf)
 {
        static const uint32_t code[] = {
                                                                                                                        /* start: */
@@ -748,7 +776,7 @@ int mips32_pracc_write_mem8(struct mips_ejtag *ejtag_info, uint32_t addr, int co
                param_in[i + 2] = buf[i];
        }
 
-       retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
+       retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
                count + 2, param_in, 0, NULL, 1);
 
        free(param_in);
@@ -820,7 +848,7 @@ int mips32_pracc_write_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
 
        int retval;
 
-       retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
+       retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
                        MIPS32NUMCOREREGS, regs, 0, NULL, 1);
 
        return retval;
@@ -895,7 +923,7 @@ int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
 
        int retval;
 
-       retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code, \
+       retval = mips32_pracc_exec(ejtag_info, ARRAY_SIZE(code), code,
                0, NULL, MIPS32NUMCOREREGS, regs, 1);
 
        return retval;
@@ -909,7 +937,7 @@ int mips32_pracc_read_regs(struct mips_ejtag *ejtag_info, uint32_t *regs)
  * 3. data ...
  */
 int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_area *source,
-                                                               int write, uint32_t addr, int count, uint32_t *buf)
+                                                               int write_t, uint32_t addr, int count, uint32_t *buf)
 {
        uint32_t handler_code[] = {
                /* caution when editing, table is modified below */
@@ -954,7 +982,7 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
        if (source->size < MIPS32_FASTDATA_HANDLER_SIZE)
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
 
-       if (write)
+       if (write_t)
        {
                handler_code[8] = MIPS32_LW(11,0,8);    /* load data from probe at fastdata area */
                handler_code[9] = MIPS32_SW(11,0,9);    /* store data to RAM @ r9 */
@@ -966,9 +994,14 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
        }
 
        /* write program into RAM */
-       mips32_pracc_write_mem32(ejtag_info, source->address, ARRAY_SIZE(handler_code), handler_code);
+       if (write_t != ejtag_info->fast_access_save)
+       {
+               mips32_pracc_write_mem32(ejtag_info, source->address, ARRAY_SIZE(handler_code), handler_code);
+               /* save previous operation to speed to any consecutive read/writes */
+               ejtag_info->fast_access_save = write_t;
+       }
 
-       LOG_DEBUG("%s using 0x%.8" PRIx32 " for write handler\n", __func__, source->address);
+       LOG_DEBUG("%s using 0x%.8" PRIx32 " for write handler", __func__, source->address);
 
        jmp_code[1] |= UPPER16(source->address);
        jmp_code[2] |= LOWER16(source->address);
@@ -978,13 +1011,13 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
                if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
                        return retval;
 
-               mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA, NULL);
-               mips_ejtag_drscan_32(ejtag_info, &jmp_code[i]);
+               mips_ejtag_set_instr(ejtag_info, EJTAG_INST_DATA);
+               mips_ejtag_drscan_32_out(ejtag_info, jmp_code[i]);
 
                /* Clear the access pending bit (let the processor eat!) */
                ejtag_ctrl = ejtag_info->ejtag_ctrl & ~EJTAG_CTRL_PRACC;
-               mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL, NULL);
-               mips_ejtag_drscan_32(ejtag_info, &ejtag_ctrl);
+               mips_ejtag_set_instr(ejtag_info, EJTAG_INST_CONTROL);
+               mips_ejtag_drscan_32_out(ejtag_info, ejtag_ctrl);
        }
 
        if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
@@ -992,26 +1025,30 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
 
        /* next fetch to dmseg should be in FASTDATA_AREA, check */
        address = 0;
-       mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
-       mips_ejtag_drscan_32(ejtag_info, &address);
+       mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
+       retval = mips_ejtag_drscan_32(ejtag_info, &address);
+       if (retval != ERROR_OK)
+               return retval;
 
        if (address != MIPS32_PRACC_FASTDATA_AREA)
                return ERROR_FAIL;
 
+       /* wait PrAcc pending bit for FASTDATA write */
+       if ((retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl)) != ERROR_OK)
+               return retval;
+
        /* Send the load start address */
        val = addr;
-       mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA, NULL);
+       mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA);
        mips_ejtag_fastdata_scan(ejtag_info, 1, &val);
 
        /* Send the load end address */
        val = addr + (count - 1) * 4;
-       mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA, NULL);
        mips_ejtag_fastdata_scan(ejtag_info, 1, &val);
 
        for (i = 0; i < count; i++)
        {
-               /* Send the data out using fastdata (clears the access pending bit) */
-               if ((retval = mips_ejtag_fastdata_scan(ejtag_info, write, buf++)) != ERROR_OK)
+               if ((retval = mips_ejtag_fastdata_scan(ejtag_info, write_t, buf++)) != ERROR_OK)
                        return retval;
        }
 
@@ -1025,11 +1062,13 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag *ejtag_info, struct working_are
                return retval;
 
        address = 0;
-       mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS, NULL);
-       mips_ejtag_drscan_32(ejtag_info, &address);
+       mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
+       retval = mips_ejtag_drscan_32(ejtag_info, &address);
+       if (retval != ERROR_OK)
+               return retval;
 
        if (address != MIPS32_PRACC_TEXT)
-               LOG_ERROR("mini program did not return to start\n");
+               LOG_ERROR("mini program did not return to start");
 
        return retval;
 }