This is an automated email from Gerrit.

Salvador Arroyo ([email protected]) just uploaded a new patch set to Gerrit, 
which you can find at http://openocd.zylin.com/760

-- gerrit

commit b96a03938f640e5c65897d5fd01cbcd483778705
Author: Salvador Arroyo <[email protected]>
Date:   Mon Jul 23 01:05:01 2012 +0200

    Pic32mx_1_2: speed up fast data transfer
    
    Until now fast data transfer works up to 300Khz.
    Adding the new functions that scans to the all register
    the code works up to 600Khz.
    Adding some delay by clocking in TAP/IDLE state with the
    function jtag_add_clocks() it works up to 2000Khz.
    
    To test fast data trasfer for reading purposes the
    function mips_m4k_fast_read_memory() is added.
    The fuction mips_m4k_read_memory() is modified to
    use fast data transfer for reading words if count > 128.
    
    Reading works at any scan frequency up to 15Mhz.
    
    For testing purposes a mips_m4k_fast_blank_check_memory()
    and mips_m4k_fast_checksum_memory() are added.
    
    To make mips32_pracc_fastdata_xfer() work at any
    scan frecuency for writing, an additional delay must be
    added after the proccessor begin to scan at fastdada area.
    
    Another delay is added after proccessor leaves fast data
    area. If not pracc bit takes about 50 ms to becomes 1, at
    3000Khz or more.
    
    The new variable clk_delay is used as clock count
    to generate the delay. With clk_delay = 20 it is possible
    to scan up to 7500 khz with the proccessor working at 4Mhz
    and up to 15000 if the proccessor works at 8Mhz.
    With this settings fastdata transfer works up to
    500Kbyte/s at 8Mhz.
    
    Reading only works with ftdi driver for me.
    
    This code is much for testing than a real patch.
    
    Change-Id: I76a5bdf80320115fa09f685d5ff81b110de5f692
    Signed-off-by: Salvador Arroyo <[email protected]>

diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c
index abd658c..0a763e2 100644
--- a/src/target/mips32_pracc.c
+++ b/src/target/mips32_pracc.c
@@ -115,7 +115,7 @@ static int mips32_pracc_sync_cache(struct mips_ejtag 
*ejtag_info,
                uint32_t start_addr, uint32_t end_addr);
 static int mips32_pracc_clean_invalidate_cache(struct mips_ejtag *ejtag_info,
                uint32_t start_addr, uint32_t end_addr);
-
+#if 0
 static int wait_for_pracc_rw(struct mips_ejtag *ejtag_info, uint32_t *ctrl)
 {
        uint32_t ejtag_ctrl;
@@ -145,6 +145,7 @@ static int wait_for_pracc_rw(struct mips_ejtag *ejtag_info, 
uint32_t *ctrl)
        *ctrl = ejtag_ctrl;
        return ERROR_OK;
 }
+#endif
 
 static int wait_for_pracc_rw_all(struct mips_ejtag *ejtag_info, uint32_t 
*ctrl, uint32_t *data, uint32_t *addr)
 {
@@ -1297,7 +1298,10 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag 
*ejtag_info, struct working_are
        };
 
        int retval, i;
-       uint32_t val, ejtag_ctrl, address;
+       uint32_t ejtag_ctrl, val, address;
+
+       /*Delay in scan clocks*/
+       unsigned int clk_delay = 20;
 
        if (source->size < MIPS32_FASTDATA_HANDLER_SIZE)
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
@@ -1323,48 +1327,45 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag 
*ejtag_info, struct working_are
        jmp_code[2] |= LOWER16(source->address);
 
        for (i = 0; i < (int) ARRAY_SIZE(jmp_code); i++) {
-               retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl);
+               mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ALL);
+               retval = wait_for_pracc_rw_all(ejtag_info, &ejtag_ctrl, 
&jmp_code[i], &address);
                if (retval != ERROR_OK)
                        return retval;
 
-               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);
                mips_ejtag_drscan_32_out(ejtag_info, ejtag_ctrl);
        }
 
-       retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl);
-       if (retval != ERROR_OK)
-               return retval;
+       /* needed to work for full range of scan frequencies in Pic32mx_1_2 */
+       jtag_add_clocks(2 * clk_delay);
 
-       /* next fetch to dmseg should be in FASTDATA_AREA, check */
-       address = 0;
-       mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
-       retval = mips_ejtag_drscan_32(ejtag_info, &address);
+       val = 0;
+       mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ALL);
+       retval = wait_for_pracc_rw_all(ejtag_info, &ejtag_ctrl, &val, &address);
        if (retval != ERROR_OK)
                return retval;
 
+       /* next fetch to dmseg should be in FASTDATA_AREA, check */
        if (address != MIPS32_PRACC_FASTDATA_AREA)
                return ERROR_FAIL;
 
-       /* wait PrAcc pending bit for FASTDATA write */
-       retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl);
-       if (retval != ERROR_OK)
-               return retval;
+       LOG_DEBUG("start....");
 
        /* Send the load start address */
        val = addr;
        mips_ejtag_set_instr(ejtag_info, EJTAG_INST_FASTDATA);
        mips_ejtag_fastdata_scan(ejtag_info, 1, &val);
 
+       jtag_add_clocks(clk_delay);
+
        /* Send the load end address */
        val = addr + (count - 1) * 4;
        mips_ejtag_fastdata_scan(ejtag_info, 1, &val);
 
        for (i = 0; i < count; i++) {
+               jtag_add_clocks(clk_delay);
                retval = mips_ejtag_fastdata_scan(ejtag_info, write_t, buf++);
                if (retval != ERROR_OK)
                        return retval;
@@ -1376,13 +1377,14 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag 
*ejtag_info, struct working_are
                return retval;
        }
 
-       retval = wait_for_pracc_rw(ejtag_info, &ejtag_ctrl);
-       if (retval != ERROR_OK)
-               return retval;
+       LOG_DEBUG(".....end");
 
-       address = 0;
-       mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ADDRESS);
-       retval = mips_ejtag_drscan_32(ejtag_info, &address);
+       /* EJTAG_CTRL_PRACC becomes "1" faster in Pic32mx_1_2 */
+       jtag_add_clocks(2 * clk_delay);
+
+       val = 0;
+       mips_ejtag_set_instr(ejtag_info, EJTAG_INST_ALL);
+       retval = wait_for_pracc_rw_all(ejtag_info, &ejtag_ctrl, &val, &address);
        if (retval != ERROR_OK)
                return retval;
 
diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c
index 1a10d5a..5666960 100644
--- a/src/target/mips_m4k.c
+++ b/src/target/mips_m4k.c
@@ -35,6 +35,7 @@
 #include "mips32_dmaacc.h"
 #include "target_type.h"
 #include "register.h"
+#include "image.h"
 
 static void mips_m4k_enable_breakpoints(struct target *target);
 static void mips_m4k_enable_watchpoints(struct target *target);
@@ -782,6 +783,34 @@ static void mips_m4k_enable_watchpoints(struct target 
*target)
        }
 }
 
+static int mips_m4k_fast_read_memory(struct target *target, uint32_t address,
+               uint32_t count, const uint8_t *buffer)
+{
+       struct mips32_common *mips32 = target_to_mips32(target);
+       struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
+       int retval;
+       int write_t = 0;
+
+       if (mips32->fast_data_area == NULL) {
+               /* Get memory for block write handler
+                * we preserve this area between calls and gain a speed increase
+                * of about 3kb/sec when writing flash
+                * this will be released/nulled by the system when the target 
is resumed or reset */
+               retval = target_alloc_working_area(target,
+                               MIPS32_FASTDATA_HANDLER_SIZE,
+                               &mips32->fast_data_area);
+               if (retval != ERROR_OK) {
+                       LOG_WARNING("No working area available, falling back to 
non-fast read");
+                       return ERROR_FAIL;
+               }
+
+               /* reset fastadata state so the algo get reloaded */
+               ejtag_info->fast_access_save = -1;
+       }
+
+       return mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, 
write_t, address, count, (uint32_t *)buffer);
+}
+
 static int mips_m4k_read_memory(struct target *target, uint32_t address,
                uint32_t size, uint32_t count, uint8_t *buffer)
 {
@@ -817,9 +846,14 @@ static int mips_m4k_read_memory(struct target *target, 
uint32_t address,
 
        /* if noDMA off, use DMAACC mode for memory read */
        int retval;
-       if (ejtag_info->impcode & EJTAG_IMP_NODMA)
-               retval = mips32_pracc_read_mem(ejtag_info, address, size, 
count, t);
-       else
+       if (ejtag_info->impcode & EJTAG_IMP_NODMA) {
+               if (size == 4 && count > 128) {
+                       retval = mips_m4k_fast_read_memory(target, address, 
count, t);
+                       if (retval != ERROR_OK)
+                               retval = mips32_pracc_read_mem(ejtag_info, 
address, size, count, t);
+               } else
+                       retval = mips32_pracc_read_mem(ejtag_info, address, 
size, count, t);
+       } else
                retval = mips32_dmaacc_read_mem(ejtag_info, address, size, 
count, t);
 
        /* mips32_..._read_mem with size 4/2 returns uint32_t/uint16_t in host 
*/
@@ -1027,6 +1061,117 @@ static int mips_m4k_bulk_write_memory(struct target 
*target, uint32_t address,
        return retval;
 }
 
+static int mips_m4k_fast_blank_check_memory(struct target *target, uint32_t 
address,
+               uint32_t count, uint32_t *blank)
+{
+       struct mips32_common *mips32 = target_to_mips32(target);
+       struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
+       int retval;
+       int write_t = 0;
+
+       if (target->state != TARGET_HALTED) {
+               LOG_WARNING("target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       /* check alignment */
+       if ((address & 0x3u) || count%4)
+               return ERROR_TARGET_UNALIGNED_ACCESS;
+
+       count /= 4;
+       if (mips32->fast_data_area == NULL) {
+               retval = target_alloc_working_area(target,
+                               MIPS32_FASTDATA_HANDLER_SIZE,
+                               &mips32->fast_data_area);
+               if (retval != ERROR_OK) {
+                       LOG_WARNING("No working area available");
+                       return ERROR_FAIL;
+               }
+
+               /* reset fastadata state so the algo get reloaded */
+               ejtag_info->fast_access_save = -1;
+       }
+
+       uint32_t *t = NULL;
+       t = malloc(count * sizeof(uint32_t));
+       if (t == NULL) {
+               LOG_ERROR("Out of memory");
+               return ERROR_FAIL;
+       }
+
+       retval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, 
write_t, address,
+                       count, t);
+       uint32_t *val = t;
+       uint32_t check = 0xffffffff;
+       for (uint32_t i = 0; i != count; i++)
+               check &= *val++;
+
+       *blank = (check == 0xffffffff) ? 0xff : 0;
+
+       if (t != NULL)
+               free(t);
+
+       return retval;
+}
+
+static int mips_m4k_fast_checksum_memory(struct target *target, uint32_t 
address,
+               uint32_t count, uint32_t *checksum)
+{
+       struct mips32_common *mips32 = target_to_mips32(target);
+       struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
+       int retval;
+       int write_t = 0;
+
+       if (target->state != TARGET_HALTED) {
+               LOG_WARNING("target not halted");
+               return ERROR_TARGET_NOT_HALTED;
+       }
+
+       /* check alignment */
+       if ((address & 0x3u) || count%4)
+               return ERROR_TARGET_UNALIGNED_ACCESS;
+
+       count /= 4;
+
+       if (mips32->fast_data_area == NULL) {
+               retval = target_alloc_working_area(target,
+                               MIPS32_FASTDATA_HANDLER_SIZE,
+                               &mips32->fast_data_area);
+               if (retval != ERROR_OK) {
+                       LOG_WARNING("No working area available");
+                       return ERROR_FAIL;
+               }
+
+               /* reset fastadata state so the algo get reloaded */
+               ejtag_info->fast_access_save = -1;
+       }
+
+       /* mips32_pracc_fastdata_xfer requires uint32_t in host endianness, */
+       /* but byte array represents target endianness                      */
+       uint32_t *t = NULL;
+       t = malloc(count * sizeof(uint32_t));
+       if (t == NULL) {
+               LOG_ERROR("Out of memory");
+               return ERROR_FAIL;
+       }
+
+       retval = mips32_pracc_fastdata_xfer(ejtag_info, mips32->fast_data_area, 
write_t, address,
+                       count, t);
+       if (retval != ERROR_OK)
+               goto exit;
+
+       for (uint32_t i = 0; i < count; i++)
+               target_buffer_set_u32(target, (uint8_t *)&t[i], t[i]);
+
+       retval = image_calculate_checksum((uint8_t *)t, count * 4, checksum);
+
+exit:
+       if (t != NULL)
+               free(t);
+
+       return retval;
+}
+
 static int mips_m4k_verify_pointer(struct command_context *cmd_ctx,
                struct mips_m4k_common *mips_m4k)
 {
@@ -1141,8 +1286,8 @@ struct target_type mips_m4k_target = {
        .read_memory = mips_m4k_read_memory,
        .write_memory = mips_m4k_write_memory,
        .bulk_write_memory = mips_m4k_bulk_write_memory,
-       .checksum_memory = mips32_checksum_memory,
-       .blank_check_memory = mips32_blank_check_memory,
+       .checksum_memory = mips_m4k_fast_checksum_memory,
+       .blank_check_memory = mips_m4k_fast_blank_check_memory,
 
        .run_algorithm = mips32_run_algorithm,
 

-- 

------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to