Hi,

Attached is a patch that vastly improves the pic32 programming speed.

comments and beta testers welcome.

The only gotcha at the moment is due to the mips memory map.
Each bank needs to support 2 virtual addresses:

 * virtual      physical
 * 0x9FC00000 - 0x1FC00000 Boot Flash - KSEG0
 * 0xBFC00000 - 0x1FC00000 Boot Flash - KSEG1
 * 0x9D000000 - 0x1D000000 Program Flash - KSEG0
 * 0xBD000000 - 0x1D000000 Program Flash - KSEG1

Not an issue if using binary file, but a problem if trying to use an elf to program.

Microchip use a utility to convert the run addresses to the programming address - pic32-bin2hex.exe. This is the utility i used during testing.

The solution i think is to add support to openocd for virtual addresses to the flash banks, so for example 0x9FC00000 points to 0x1FC00000.

Cheers
Spen
>From 6aedcf1d57106d91e7a1e2b3dddd732d25548386 Mon Sep 17 00:00:00 2001
From: Spencer Oliver <ntfr...@users.sourceforge.net>
Date: Mon, 8 Mar 2010 21:45:44 +0000
Subject: [PATCH] PIC32: add flash algorithm support

Add flash algorithm support for the PIC32MX.
Still a few things todo but this dramatically decreases
the programing time, eg. approx programming for 2.5k test file.
 - without fastload: 60secs
 - with fastload: 45secs
 - with fastload and algorithm: 2secs.

Add new devices to supported list.

Signed-off-by: Spencer Oliver <ntfr...@users.sourceforge.net>
---
 src/flash/nor/pic32mx.c   |  664 +++++++++++++++------------------------------
 src/flash/nor/pic32mx.h   |   31 +--
 src/target/mips32_pracc.c |    4 +-
 src/target/mips_ejtag.h   |    4 +
 src/target/mips_m4k.c     |    2 +-
 tcl/target/pic32mx.cfg    |   16 +-
 6 files changed, 246 insertions(+), 475 deletions(-)

diff --git a/src/flash/nor/pic32mx.c b/src/flash/nor/pic32mx.c
index 1f66346..cf39188 100644
--- a/src/flash/nor/pic32mx.c
+++ b/src/flash/nor/pic32mx.c
@@ -29,38 +29,40 @@
 
 #include "imp.h"
 #include "pic32mx.h"
+#include <target/algorithm.h>
 #include <target/mips32.h>
 
-
-static
-struct pic32mx_devs_s {
+static const struct pic32mx_devs_s {
        uint8_t devid;
-       char    *name;
-       uint32_t        pfm_size;
+       char *name;
 } pic32mx_devs[] = {
-       { 0x78, "460F512L USB", 512 },
-       { 0x74, "460F256L USB", 256 },
-       { 0x6D, "440F128L USB", 128 },
-       { 0x56, "440F512H USB", 512 },
-       { 0x52, "440F256H USB", 256 },
-       { 0x4D, "440F128H USB", 128 },
-       { 0x42, "420F032H USB",  32 },
-       { 0x38, "360F512L",     512 },
-       { 0x34, "360F256L",     256 },
-       { 0x2D, "340F128L",     128 },
-       { 0x2A, "320F128L",     128 },
-       { 0x16, "340F512H",     512 },
-       { 0x12, "340F256H",     256 },
-       { 0x0D, "340F128H",     128 },
-       { 0x0A, "320F128H",     128 },
-       { 0x06, "320F064H",      64 },
-       { 0x02, "320F032H",      32 },
-       { 0x00, NULL, 0 }
+       {0x38, "360F512L"},
+       {0x34, "360F256L"},
+       {0x2D, "340F128L"},
+       {0x2A, "320F128L"},
+       {0x16, "340F512H"},
+       {0x12, "340F256H"},
+       {0x0D, "340F128H"},
+       {0x0A, "320F128H"},
+       {0x06, "320F064H"},
+       {0x02, "320F032H"},
+       {0x07, "795F512L"},
+       {0x0E, "795F512H"},
+       {0x11, "675F512L"},
+       {0x0C, "675F512H"},
+       {0x0F, "575F512L"},
+       {0x09, "575F512H"},
+       {0x17, "575F256H"},
+       {0x78, "460F512L"},
+       {0x74, "460F256L"},
+       {0x6D, "440F128L"},
+       {0x56, "440F512H"},
+       {0x52, "440F256H"},
+       {0x4D, "440F128H"},
+       {0x42, "420F032H"},
+       {0x00, NULL}
 };
 
-static int pic32mx_write_row(struct flash_bank *bank, uint32_t address, 
uint32_t srcaddr);
-static int pic32mx_write_word(struct flash_bank *bank, uint32_t address, 
uint32_t word);
-
 /* flash bank pic32mx <base> <size> 0 0 <target#>
  */
 FLASH_BANK_COMMAND_HANDLER(pic32mx_flash_bank_command)
@@ -145,9 +147,10 @@ static int pic32mx_protect_check(struct flash_bank *bank)
        }
 
        target_read_u32(target, PIC32MX_DEVCFG0, &devcfg0);
+
        if ((devcfg0 & (1 << 28)) == 0) /* code protect bit */
                num_pages = 0xffff;  /* All pages protected */
-       else if (bank->base == PIC32MX_KSEG1_BOOT_FLASH)
+       else if (bank->base == PIC32MX_PHYS_BOOT_FLASH)
        {
                if (devcfg0 & (1 << 24))
                        num_pages = 0;       /* All pages unprotected */
@@ -156,6 +159,7 @@ static int pic32mx_protect_check(struct flash_bank *bank)
        }
        else /* pgm flash */
                num_pages = (~devcfg0 >> 12) & 0xff;
+
        for (s = 0; s < bank->num_sectors && s < num_pages; s++)
                bank->sectors[s].is_protected = 1;
        for (; s < bank->num_sectors; s++)
@@ -176,8 +180,11 @@ static int pic32mx_erase(struct flash_bank *bank, int 
first, int last)
                return ERROR_TARGET_NOT_HALTED;
        }
 
-       if ((first == 0) && (last == (bank->num_sectors - 1)) && (bank->base == 
PIC32MX_KSEG0_PGM_FLASH || bank->base == PIC32MX_KSEG1_PGM_FLASH))
+       if ((first == 0) && (last == (bank->num_sectors - 1))
+               && (bank->base == PIC32MX_PHYS_PGM_FLASH))
        {
+               /* this will only erase the Program Flash (PFM), not the Boot 
Flash (BFM)
+                * we need to use the MTAP to perform a full erase */
                LOG_DEBUG("Erasing entire program flash");
                status = pic32mx_nvm_exec(bank, NVMCON_OP_PFM_ERASE, 50);
                if (status & NVMCON_NVMERR)
@@ -189,10 +196,7 @@ static int pic32mx_erase(struct flash_bank *bank, int 
first, int last)
 
        for (i = first; i <= last; i++)
        {
-               if (bank->base >= PIC32MX_KSEG1_PGM_FLASH)
-                       target_write_u32(target, PIC32MX_NVMADDR, 
KS1Virt2Phys(bank->base + bank->sectors[i].offset));
-               else
-                       target_write_u32(target, PIC32MX_NVMADDR, 
KS0Virt2Phys(bank->base + bank->sectors[i].offset));
+               target_write_u32(target, PIC32MX_NVMADDR, Virt2Phys(bank->base 
+ bank->sectors[i].offset));
 
                status = pic32mx_nvm_exec(bank, NVMCON_OP_PAGE_ERASE, 10);
 
@@ -210,12 +214,6 @@ static int pic32mx_protect(struct flash_bank *bank, int 
set, int first, int last
 {
        struct pic32mx_flash_bank *pic32mx_info = NULL;
        struct target *target = bank->target;
-#if 0
-       uint16_t prot_reg[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF};
-       int i, reg, bit;
-       int status;
-       uint32_t protection;
-#endif
 
        pic32mx_info = bank->driver_priv;
 
@@ -225,205 +223,177 @@ static int pic32mx_protect(struct flash_bank *bank, int 
set, int first, int last
                return ERROR_TARGET_NOT_HALTED;
        }
 
-#if 0
-       if ((first && (first % pic32mx_info->ppage_size)) || ((last + 1) && 
(last + 1) % pic32mx_info->ppage_size))
-       {
-               LOG_WARNING("sector start/end incorrect - stm32 has %dK sector 
protection", pic32mx_info->ppage_size);
-               return ERROR_FLASH_SECTOR_INVALID;
-       }
-
-       /* medium density - each bit refers to a 4bank protection
-        * high density - each bit refers to a 2bank protection */
-       target_read_u32(target, PIC32MX_FLASH_WRPR, &protection);
-
-       prot_reg[0] = (uint16_t)protection;
-       prot_reg[1] = (uint16_t)(protection >> 8);
-       prot_reg[2] = (uint16_t)(protection >> 16);
-       prot_reg[3] = (uint16_t)(protection >> 24);
-
-       if (pic32mx_info->ppage_size == 2)
-       {
-               /* high density flash */
-
-               /* bit 7 controls sector 62 - 255 protection */
-               if (last > 61)
-               {
-                       if (set)
-                               prot_reg[3] &= ~(1 << 7);
-                       else
-                               prot_reg[3] |= (1 << 7);
-               }
-
-               if (first > 61)
-                       first = 62;
-               if (last > 61)
-                       last = 61;
-
-               for (i = first; i <= last; i++)
-               {
-                       reg = (i / pic32mx_info->ppage_size) / 8;
-                       bit = (i / pic32mx_info->ppage_size) - (reg * 8);
-
-                       if (set)
-                               prot_reg[reg] &= ~(1 << bit);
-                       else
-                               prot_reg[reg] |= (1 << bit);
-               }
-       }
-       else
-       {
-               /* medium density flash */
-               for (i = first; i <= last; i++)
-               {
-                       reg = (i / pic32mx_info->ppage_size) / 8;
-                       bit = (i / pic32mx_info->ppage_size) - (reg * 8);
-
-                       if (set)
-                               prot_reg[reg] &= ~(1 << bit);
-                       else
-                               prot_reg[reg] |= (1 << bit);
-               }
-       }
-
-       if ((status = pic32mx_erase_options(bank)) != ERROR_OK)
-               return status;
-
-       pic32mx_info->option_bytes.protection[0] = prot_reg[0];
-       pic32mx_info->option_bytes.protection[1] = prot_reg[1];
-       pic32mx_info->option_bytes.protection[2] = prot_reg[2];
-       pic32mx_info->option_bytes.protection[3] = prot_reg[3];
-
-       return pic32mx_write_options(bank);
-#else
        return ERROR_OK;
-#endif
 }
 
-static int pic32mx_write_block(struct flash_bank *bank, uint8_t *buffer, 
uint32_t offset, uint32_t count)
+static const uint32_t pic32mx_flash_write_code[] = {
+                                       /* write: */
+       0x3C08AA99,             /* lui $t0, 0xaa99 */
+       0x35086655,             /* ori $t0, 0x6655 */
+       0x3C095566,             /* lui $t1, 0x5566 */
+       0x352999AA,             /* ori $t1, 0x99aa */
+       0x3C0ABF80,             /* lui $t2, 0xbf80 */
+       0x354AF400,             /* ori $t2, 0xf400 */
+       0x340B4003,             /* ori $t3, $zero, 0x4003 */
+       0x340C8000,             /* ori $t4, $zero, 0x8000 */
+                                       /* write_row: */
+       0x2CD30080,             /* sltiu $s3, $a2, 128 */
+       0x16600008,             /* bne $s3, $zero, write_word */
+       0x340D4000,             /* ori $t5, $zero, 0x4000 */
+       0xAD450020,             /* sw $a1, 32($t2) */
+       0xAD440040,             /* sw $a0, 64($t2) */
+       0x04110016,             /* bal progflash */
+       0x24840200,             /* addiu $a0, $a0, 512 */
+       0x24A50200,             /* addiu $a1, $a1, 512 */
+       0x1000FFF7,             /* beq $zero, $zero, write_row */
+       0x24C6FF80,             /* addiu $a2, $a2, -128 */
+                                       /* write_word: */
+       0x3C15A000,             /* lui $s5, 0xa000 */
+       0x36B50000,             /* ori $s5, $s5, 0x0 */
+       0x00952025,             /* or $a0, $a0, $s5 */
+       0x10000008,             /* beq $zero, $zero, next_word */
+       0x340B4001,             /* ori $t3, $zero, 0x4001 */
+                                       /* prog_word: */
+       0x8C940000,             /* lw $s4, 0($a0) */
+       0xAD540030,             /* sw $s4, 48($t2) */
+       0xAD450020,             /* sw $a1, 32($t2) */
+       0x04110009,             /* bal progflash */
+       0x24840004,             /* addiu $a0, $a0, 4 */
+       0x24A50004,             /* addiu $a1, $a1, 4 */
+       0x24C6FFFF,             /* addiu $a2, $a2, -1 */
+                                       /* next_word: */
+       0x14C0FFF8,             /* bne $a2, $zero, prog_word */
+       0x00000000,             /* nop */
+                                       /* done: */
+       0x10000002,             /* beq $zero, $zero, exit */
+       0x24040000,             /* addiu $a0, $zero, 0 */
+                                       /* error: */
+       0x26240000,             /* addiu $a0, $s1, 0 */
+                                       /* exit: */
+       0x7000003F,             /* sdbbp */
+                                       /* progflash: */
+       0xAD4B0000,             /* sw $t3, 0($t2) */
+       0xAD480010,             /* sw $t0, 16($t2) */
+       0xAD490010,             /* sw $t1, 16($t2) */
+       0xAD4C0008,             /* sw $t4, 8($t2) */
+                                       /* waitflash: */
+       0x8D500000,             /* lw $s0, 0($t2) */
+       0x020C8024,             /* and $s0, $s0, $t4 */
+       0x1600FFFD,             /* bne $s0, $zero, waitflash */
+       0x00000000,             /* nop */
+       0x00000000,             /* nop */
+       0x00000000,     /* nop */
+       0x00000000,             /* nop */
+       0x00000000,             /* nop */
+       0x8D510000,             /* lw $s1, 0($t2) */
+       0x30113000,             /* andi $s1, $zero, 0x3000 */
+       0x1620FFEF,             /* bne $s1, $zero, error */
+       0xAD4D0004,             /* sw $t5, 4($t2) */
+       0x03E00008,             /* jr $ra */
+       0x00000000              /* nop */
+};
+
+static int pic32mx_write_block(struct flash_bank *bank, uint8_t *buffer,
+               uint32_t offset, uint32_t count)
 {
        struct target *target = bank->target;
-       uint32_t buffer_size = 512;
+       uint32_t buffer_size = 16384;
        struct working_area *source;
        uint32_t address = bank->base + offset;
+       struct reg_param reg_params[3];
        int retval = ERROR_OK;
-#if 0
+
        struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;
-       struct armv7m_algorithm armv7m_info;
-
-       uint8_t pic32mx_flash_write_code[] = {
-                                                                       /* 
write: */
-               0xDF, 0xF8, 0x24, 0x40,         /* ldr  r4, PIC32MX_FLASH_CR */
-               0x09, 0x4D,                                     /* ldr  r5, 
PIC32MX_FLASH_SR */
-               0x4F, 0xF0, 0x01, 0x03,         /* mov  r3, #1 */
-               0x23, 0x60,                                     /* str  r3, 
[r4, #0] */
-               0x30, 0xF8, 0x02, 0x3B,         /* ldrh r3, [r0], #2 */
-               0x21, 0xF8, 0x02, 0x3B,         /* strh r3, [r1], #2 */
-                                                                       /* 
busy: */
-               0x2B, 0x68,                                     /* ldr  r3, 
[r5, #0] */
-               0x13, 0xF0, 0x01, 0x0F,         /* tst  r3, #0x01 */
-               0xFB, 0xD0,                                     /* beq  busy */
-               0x13, 0xF0, 0x14, 0x0F,         /* tst  r3, #0x14 */
-               0x01, 0xD1,                                     /* bne  exit */
-               0x01, 0x3A,                                     /* subs r2, r2, 
#1 */
-               0xED, 0xD1,                                     /* bne  write */
-                                                                       /* 
exit: */
-               0xFE, 0xE7,                                     /* b exit */
-               0x10, 0x20, 0x02, 0x40,         /* PIC32MX_FLASH_CR:    .word 
0x40022010 */
-               0x0C, 0x20, 0x02, 0x40          /* PIC32MX_FLASH_SR:    .word 
0x4002200C */
-       };
+       struct mips32_algorithm mips32_info;
 
        /* flash write code */
-       if (target_alloc_working_area(target, sizeof(pic32mx_flash_write_code), 
&pic32mx_info->write_algorithm) != ERROR_OK)
+       if (target_alloc_working_area(target, sizeof(pic32mx_flash_write_code),
+                       &pic32mx_info->write_algorithm) != ERROR_OK)
        {
                LOG_WARNING("no working area available, can't do block memory 
writes");
                return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
        };
 
-       if ((retval = target_write_buffer(target, 
pic32mx_info->write_algorithm->address, sizeof(pic32mx_flash_write_code), 
pic32mx_flash_write_code)) != ERROR_OK)
+       if ((retval = target_write_buffer(target,
+                       pic32mx_info->write_algorithm->address,
+                       sizeof(pic32mx_flash_write_code),
+                       (uint8_t*)pic32mx_flash_write_code)) != ERROR_OK)
                return retval;
-#endif
 
        /* memory buffer */
-       if (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
+       while (target_alloc_working_area(target, buffer_size, &source) != 
ERROR_OK)
        {
-#if 0
-               /* if we already allocated the writing code, but failed to get 
a buffer, free the algorithm */
-               if (pic32mx_info->write_algorithm)
-                       target_free_working_area(target, 
pic32mx_info->write_algorithm);
-#endif
+               buffer_size /= 2;
+               if (buffer_size <= 256)
+               {
+                       /* if we already allocated the writing code, but failed 
to get a
+                        * buffer, free the algorithm */
+                       if (pic32mx_info->write_algorithm)
+                               target_free_working_area(target, 
pic32mx_info->write_algorithm);
 
-               LOG_WARNING("no large enough working area available, can't do 
block memory writes");
-               return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
-       }
+                       LOG_WARNING("no large enough working area available, 
can't do block memory writes");
+                       return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
+               }
+       };
+
+       mips32_info.common_magic = MIPS32_COMMON_MAGIC;
+       mips32_info.isa_mode = MIPS32_ISA_MIPS32;
 
-       while (count >= buffer_size/4)
+       init_reg_param(&reg_params[0], "a0", 32, PARAM_IN_OUT);
+       init_reg_param(&reg_params[1], "a1", 32, PARAM_OUT);
+       init_reg_param(&reg_params[2], "a2", 32, PARAM_OUT);
+
+       while (count > 0)
        {
                uint32_t status;
+               uint32_t thisrun_count = (count > (buffer_size / 4)) ?
+                               (buffer_size / 4) : count;
 
-               if ((retval = target_write_buffer(target, source->address, 
buffer_size, buffer)) != ERROR_OK) {
-                       LOG_ERROR("Failed to write row buffer (%d words) to 
RAM", (int)(buffer_size/4));
+               if ((retval = target_write_buffer(target, source->address,
+                               thisrun_count * 4, buffer)) != ERROR_OK)
                        break;
-               }
 
-#if 0
-               buf_set_u32(reg_params[0].value, 0, 32, source->address);
-               buf_set_u32(reg_params[1].value, 0, 32, address);
-               buf_set_u32(reg_params[2].value, 0, 32, buffer_size/4);
+               buf_set_u32(reg_params[0].value, 0, 32, 
Virt2Phys(source->address));
+               buf_set_u32(reg_params[1].value, 0, 32, Virt2Phys(address));
+               buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
 
-               if ((retval = target_run_algorithm(target, 0, NULL, 4, 
reg_params, pic32mx_info->write_algorithm->address, \
-                               pic32mx_info->write_algorithm->address + 
(sizeof(pic32mx_flash_write_code) - 10), 10000, &armv7m_info)) != ERROR_OK)
+               if ((retval = target_run_algorithm(target, 0, NULL, 3, 
reg_params,
+                               pic32mx_info->write_algorithm->address,
+                               pic32mx_info->write_algorithm->address + 
(sizeof(pic32mx_flash_write_code) - 76),
+                               10000, &mips32_info)) != ERROR_OK)
                {
                        LOG_ERROR("error executing pic32mx flash write 
algorithm");
                        retval = ERROR_FLASH_OPERATION_FAILED;
                        break;
                }
 
-               if (buf_get_u32(reg_params[3].value, 0, 32) & 0x14)
+               status = buf_get_u32(reg_params[0].value, 0, 32);
+
+               if (status & NVMCON_NVMERR)
                {
-                       retval = ERROR_FLASH_OPERATION_FAILED;
-                       break;
-               }
-#endif
-               status = pic32mx_write_row(bank, address, source->address);
-               if (status & NVMCON_NVMERR) {
                        LOG_ERROR("Flash write error NVMERR (status = 0x%08" 
PRIx32 ")", status);
                        retval = ERROR_FLASH_OPERATION_FAILED;
                        break;
                }
-               if (status & NVMCON_LVDERR) {
+
+               if (status & NVMCON_LVDERR)
+               {
                        LOG_ERROR("Flash write error LVDERR (status = 0x%08" 
PRIx32 ")", status);
                        retval = ERROR_FLASH_OPERATION_FAILED;
                        break;
                }
 
-               buffer  += buffer_size;
-               address += buffer_size;
-               count   -= buffer_size/4;
+               buffer += thisrun_count * 4;
+               address += thisrun_count * 4;
+               count -= thisrun_count;
        }
 
        target_free_working_area(target, source);
+       target_free_working_area(target, pic32mx_info->write_algorithm);
 
-       while (count > 0)
-       {
-               uint32_t value;
-               memcpy(&value, buffer, sizeof(uint32_t));
-
-               uint32_t status = pic32mx_write_word(bank, address, value);
-               if (status & NVMCON_NVMERR) {
-                       LOG_ERROR("Flash write error NVMERR (status = 0x%08" 
PRIx32 ")", status);
-                       retval = ERROR_FLASH_OPERATION_FAILED;
-                       break;
-               }
-               if (status & NVMCON_LVDERR) {
-                       LOG_ERROR("Flash write error LVDERR (status = 0x%08" 
PRIx32 ")", status);
-                       retval = ERROR_FLASH_OPERATION_FAILED;
-                       break;
-               }
-
-               buffer  += 4;
-               address += 4;
-               count--;
-       }
+       destroy_reg_param(&reg_params[0]);
+       destroy_reg_param(&reg_params[1]);
+       destroy_reg_param(&reg_params[2]);
 
        return retval;
 }
@@ -432,36 +402,12 @@ static int pic32mx_write_word(struct flash_bank *bank, 
uint32_t address, uint32_
 {
        struct target *target = bank->target;
 
-       if (bank->base >= PIC32MX_KSEG1_PGM_FLASH)
-               target_write_u32(target, PIC32MX_NVMADDR, 
KS1Virt2Phys(address));
-       else
-               target_write_u32(target, PIC32MX_NVMADDR, 
KS0Virt2Phys(address));
+       target_write_u32(target, PIC32MX_NVMADDR, Virt2Phys(address));
        target_write_u32(target, PIC32MX_NVMDATA, word);
 
        return pic32mx_nvm_exec(bank, NVMCON_OP_WORD_PROG, 5);
 }
 
-/*
- * Write a 128 word (512 byte) row to flash address from RAM srcaddr.
- */
-static int pic32mx_write_row(struct flash_bank *bank, uint32_t address, 
uint32_t srcaddr)
-{
-       struct target *target = bank->target;
-
-       LOG_DEBUG("addr: 0x%08" PRIx32 " srcaddr: 0x%08" PRIx32 "", address, 
srcaddr);
-
-       if (address >= PIC32MX_KSEG1_PGM_FLASH)
-               target_write_u32(target, PIC32MX_NVMADDR,    
KS1Virt2Phys(address));
-       else
-               target_write_u32(target, PIC32MX_NVMADDR,    
KS0Virt2Phys(address));
-       if (srcaddr >= PIC32MX_KSEG1_RAM)
-               target_write_u32(target, PIC32MX_NVMSRCADDR, 
KS1Virt2Phys(srcaddr));
-       else
-               target_write_u32(target, PIC32MX_NVMSRCADDR, 
KS0Virt2Phys(srcaddr));
-
-       return pic32mx_nvm_exec(bank, NVMCON_OP_ROW_PROG, 100);
-}
-
 static int pic32mx_write(struct flash_bank *bank, uint8_t *buffer, uint32_t 
offset, uint32_t count)
 {
        uint32_t words_remaining = (count / 4);
@@ -477,6 +423,9 @@ static int pic32mx_write(struct flash_bank *bank, uint8_t 
*buffer, uint32_t offs
                return ERROR_TARGET_NOT_HALTED;
        }
 
+       LOG_DEBUG("writing to flash at address 0x%08" PRIx32 " at offset 
0x%8.8" PRIx32
+                       " count: 0x%8.8" PRIx32 "", bank->base, offset, count);
+
        if (offset & 0x3)
        {
                LOG_WARNING("offset 0x%" PRIx32 "breaks required 4-byte 
alignment", offset);
@@ -515,10 +464,18 @@ static int pic32mx_write(struct flash_bank *bank, uint8_t 
*buffer, uint32_t offs
                memcpy(&value, buffer + bytes_written, sizeof(uint32_t));
 
                status = pic32mx_write_word(bank, address, value);
+
                if (status & NVMCON_NVMERR)
+               {
+                       LOG_ERROR("Flash write error NVMERR (status = 0x%08" 
PRIx32 ")", status);
                        return ERROR_FLASH_OPERATION_FAILED;
+               }
+
                if (status & NVMCON_LVDERR)
+               {
+                       LOG_ERROR("Flash write error LVDERR (status = 0x%08" 
PRIx32 ")", status);
                        return ERROR_FLASH_OPERATION_FAILED;
+               }
 
                bytes_written += 4;
                words_remaining--;
@@ -531,10 +488,18 @@ static int pic32mx_write(struct flash_bank *bank, uint8_t 
*buffer, uint32_t offs
                memcpy(&value, buffer + bytes_written, bytes_remaining);
 
                status = pic32mx_write_word(bank, address, value);
+
                if (status & NVMCON_NVMERR)
+               {
+                       LOG_ERROR("Flash write error NVMERR (status = 0x%08" 
PRIx32 ")", status);
                        return ERROR_FLASH_OPERATION_FAILED;
+               }
+
                if (status & NVMCON_LVDERR)
+               {
+                       LOG_ERROR("Flash write error LVDERR (status = 0x%08" 
PRIx32 ")", status);
                        return ERROR_FLASH_OPERATION_FAILED;
+               }
        }
 
        return ERROR_OK;
@@ -547,70 +512,60 @@ static int pic32mx_probe(struct flash_bank *bank)
        struct mips32_common *mips32 = target->arch_info;
        struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
        int i;
-       uint16_t num_pages = 0;
+       uint32_t num_pages = 0;
        uint32_t device_id;
        int page_size;
 
        pic32mx_info->probed = 0;
 
        device_id = ejtag_info->idcode;
-       LOG_INFO("device id = 0x%08" PRIx32 " (manuf 0x%03x dev 0x%02x, ver 
0x%03x)",
+       LOG_INFO("device id = 0x%08" PRIx32 " (manuf 0x%03x dev 0x%02x, ver 
0x%02x)",
                          device_id,
-                         (unsigned)((device_id >> 1)&0x7ff),
-                         (unsigned)((device_id >> 12)&0xff),
-                         (unsigned)((device_id >> 20)&0xfff));
+                         (unsigned)((device_id >> 1) & 0x7ff),
+                         (unsigned)((device_id >> 12) & 0xff),
+                         (unsigned)((device_id >> 28) & 0xf));
 
-       if (((device_id >> 1)&0x7ff) != PIC32MX_MANUF_ID) {
+       if (((device_id >> 1) & 0x7ff) != PIC32MX_MANUF_ID) {
                LOG_WARNING("Cannot identify target as a PIC32MX family.");
                return ERROR_FLASH_OPERATION_FAILED;
        }
 
        page_size = 4096;
-       if (bank->base == PIC32MX_KSEG1_BOOT_FLASH || bank->base == 1) {
-               /* 0xBFC00000: Boot flash size fixed at 12k */
-               num_pages = 12;
-       } else {
-               /* 0xBD000000: Program flash size varies with device */
-               for (i = 0; pic32mx_devs[i].name != NULL; i++)
-                       if (pic32mx_devs[i].devid == ((device_id >> 12) & 
0xff)) {
-                               num_pages = pic32mx_devs[i].pfm_size;
-                               break;
-                       }
-               if (pic32mx_devs[i].name == NULL) {
-                       LOG_WARNING("Cannot identify target as a PIC32MX 
family.");
-                       return ERROR_FLASH_OPERATION_FAILED;
-               }
-       }
 
-#if 0
-       if (bank->target->state != TARGET_HALTED)
+       if (bank->base == PIC32MX_PHYS_BOOT_FLASH)
        {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
+               /* 0x1FC00000: Boot flash size */
+#if 0
+               /* for some reason this register returns 8k for the boot bank 
size
+                * this does not match the docs, so for now set the boot bank 
at a
+                * fixed 12k */
+               if (target_read_u32(target, PIC32MX_BMXBOOTSZ, &num_pages) != 
ERROR_OK) {
+                       LOG_WARNING("PIC32MX flash size failed, probe 
inaccurate - assuming 12k flash");
+                       num_pages = (12 * 1024);
+               }
+#else
+               /* fixed 12k boot bank - see comments above */
+               num_pages = (12 * 1024);
+#endif
        }
-
-       /* get flash size from target */
-       if (target_read_u16(target, 0x1FFFF7E0, &num_pages) != ERROR_OK)
+       else
        {
-               /* failed reading flash size, default to max target family */
-               num_pages = 0xffff;
+               /* read the flash size from the device */
+               if (target_read_u32(target, PIC32MX_BMXPFMSZ, &num_pages) != 
ERROR_OK) {
+                       LOG_WARNING("PIC32MX flash size failed, probe 
inaccurate - assuming 512k flash");
+                       num_pages = (512 * 1024);
+               }
        }
-#endif
 
-       LOG_INFO("flash size = %dkbytes", num_pages);
+       LOG_INFO("flash size = %dkbytes", num_pages / 1024);
 
        /* calculate numbers of pages */
-       num_pages /= (page_size / 1024);
-
-       if (bank->base == 0) bank->base = PIC32MX_KSEG1_PGM_FLASH;
-       if (bank->base == 1) bank->base = PIC32MX_KSEG1_BOOT_FLASH;
+       num_pages /= page_size;
        bank->size = (num_pages * page_size);
        bank->num_sectors = num_pages;
-       bank->chip_width = 4;
-       bank->bus_width  = 4;
        bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
 
-       for (i = 0; i < num_pages; i++)
+       for (i = 0; i < (int)num_pages; i++)
        {
                bank->sectors[i].offset = i * page_size;
                bank->sectors[i].size = page_size;
@@ -631,13 +586,6 @@ static int pic32mx_auto_probe(struct flash_bank *bank)
        return pic32mx_probe(bank);
 }
 
-#if 0
-COMMAND_HANDLER(pic32mx_handle_part_id_command)
-{
-       return ERROR_OK;
-}
-#endif
-
 static int pic32mx_info(struct flash_bank *bank, char *buf, int buf_size)
 {
        struct target *target = bank->target;
@@ -648,198 +596,30 @@ static int pic32mx_info(struct flash_bank *bank, char 
*buf, int buf_size)
 
        device_id = ejtag_info->idcode;
 
-       if (((device_id >> 1)&0x7ff) != PIC32MX_MANUF_ID) {
+       if (((device_id >> 1) & 0x7ff) != PIC32MX_MANUF_ID) {
                snprintf(buf, buf_size,
                                 "Cannot identify target as a PIC32MX family 
(manufacturer 0x%03d != 0x%03d)\n",
-                                (unsigned)((device_id >> 1)&0x7ff),
+                                (unsigned)((device_id >> 1) & 0x7ff),
                                 PIC32MX_MANUF_ID);
                return ERROR_FLASH_OPERATION_FAILED;
        }
+
        for (i = 0; pic32mx_devs[i].name != NULL; i++)
+       {
                if (pic32mx_devs[i].devid == ((device_id >> 12) & 0xff)) {
                        printed = snprintf(buf, buf_size, "PIC32MX%s", 
pic32mx_devs[i].name);
                        break;
                }
-       if (pic32mx_devs[i].name == NULL) {
-               snprintf(buf, buf_size, "Cannot identify target as a PIC32MX 
family\n");
-               return ERROR_FLASH_OPERATION_FAILED;
        }
-       buf += printed;
-       buf_size -= printed;
-       printed = snprintf(buf, buf_size, "  Ver: 0x%03x",
-                                          (unsigned)((device_id >> 20)&0xfff));
-
-       return ERROR_OK;
-}
-
-#if 0
-COMMAND_HANDLER(pic32mx_handle_lock_command)
-{
-       struct target *target = NULL;
-       struct pic32mx_flash_bank *pic32mx_info = NULL;
-
-       if (CMD_ARGC < 1)
-       {
-               command_print(CMD_CTX, "pic32mx lock <bank>");
-               return ERROR_OK;
-       }
-
-       struct flash_bank *bank;
-       int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
-       if (ERROR_OK != retval)
-               return retval;
-
-       pic32mx_info = bank->driver_priv;
-
-       target = bank->target;
-
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
-       if (pic32mx_erase_options(bank) != ERROR_OK)
-       {
-               command_print(CMD_CTX, "pic32mx failed to erase options");
-               return ERROR_OK;
-       }
-
-       /* set readout protection */
-       pic32mx_info->option_bytes.RDP = 0;
-
-       if (pic32mx_write_options(bank) != ERROR_OK)
-       {
-               command_print(CMD_CTX, "pic32mx failed to lock device");
-               return ERROR_OK;
-       }
-
-       command_print(CMD_CTX, "pic32mx locked");
-
-       return ERROR_OK;
-}
-
-COMMAND_HANDLER(pic32mx_handle_unlock_command)
-{
-       struct target *target = NULL;
-       struct pic32mx_flash_bank *pic32mx_info = NULL;
-
-       if (CMD_ARGC < 1)
-       {
-               command_print(CMD_CTX, "pic32mx unlock <bank>");
-               return ERROR_OK;
-       }
-
-       struct flash_bank *bank;
-       int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
-       if (ERROR_OK != retval)
-               return retval;
 
-       pic32mx_info = bank->driver_priv;
-
-       target = bank->target;
-
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
-       if (pic32mx_erase_options(bank) != ERROR_OK)
-       {
-               command_print(CMD_CTX, "pic32mx failed to unlock device");
-               return ERROR_OK;
-       }
-
-       if (pic32mx_write_options(bank) != ERROR_OK)
-       {
-               command_print(CMD_CTX, "pic32mx failed to lock device");
-               return ERROR_OK;
-       }
-
-       command_print(CMD_CTX, "pic32mx unlocked");
-
-       return ERROR_OK;
-}
-#endif
-
-#if 0
-static int pic32mx_chip_erase(struct flash_bank *bank)
-{
-       struct target *target = bank->target;
-#if 0
-       uint32_t status;
-#endif
-
-       if (target->state != TARGET_HALTED)
-       {
-               LOG_ERROR("Target not halted");
-               return ERROR_TARGET_NOT_HALTED;
-       }
-
-       LOG_INFO("PIC32MX chip erase called");
-
-#if 0
-       /* unlock option flash registers */
-       target_write_u32(target, PIC32MX_FLASH_KEYR, KEY1);
-       target_write_u32(target, PIC32MX_FLASH_KEYR, KEY2);
-
-       /* chip erase flash memory */
-       target_write_u32(target, PIC32MX_FLASH_CR, FLASH_MER);
-       target_write_u32(target, PIC32MX_FLASH_CR, FLASH_MER | FLASH_STRT);
-
-       status = pic32mx_wait_status_busy(bank, 10);
-
-       target_write_u32(target, PIC32MX_FLASH_CR, FLASH_LOCK);
-
-       if (status & FLASH_WRPRTERR)
-       {
-               LOG_ERROR("pic32mx device protected");
-               return ERROR_OK;
-       }
-
-       if (status & FLASH_PGERR)
-       {
-               LOG_ERROR("pic32mx device programming failed");
-               return ERROR_OK;
-       }
-#endif
-
-       return ERROR_OK;
-}
-#endif
-
-COMMAND_HANDLER(pic32mx_handle_chip_erase_command)
-{
-#if 0
-       int i;
-
-       if (CMD_ARGC != 0)
-       {
-               command_print(CMD_CTX, "pic32mx chip_erase");
-               return ERROR_OK;
+       if (pic32mx_devs[i].name == NULL) {
+               printed = snprintf(buf, buf_size, "Unknown");
        }
 
-       struct flash_bank *bank;
-       int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
-       if (ERROR_OK != retval)
-               return retval;
-
-       if (pic32mx_chip_erase(bank) == ERROR_OK)
-       {
-               /* set all sectors as erased */
-               for (i = 0; i < bank->num_sectors; i++)
-               {
-                       bank->sectors[i].is_erased = 1;
-               }
-
-               command_print(CMD_CTX, "pic32mx chip erase complete");
-       }
-       else
-       {
-               command_print(CMD_CTX, "pic32mx chip erase failed");
-       }
-#endif
+       buf += printed;
+       buf_size -= printed;
+       printed = snprintf(buf, buf_size, "  Ver: 0x%02x",
+                       (unsigned)((device_id >> 28) & 0xf));
 
        return ERROR_OK;
 }
@@ -883,14 +663,9 @@ COMMAND_HANDLER(pic32mx_handle_pgm_word_command)
 
        return ERROR_OK;
 }
+
 static const struct command_registration pic32mx_exec_command_handlers[] = {
        {
-               .name = "chip_erase",
-               .handler = pic32mx_handle_chip_erase_command,
-               .mode = COMMAND_EXEC,
-               .help = "erase device",
-       },
-       {
                .name = "pgm_word",
                .handler = pic32mx_handle_pgm_word_command,
                .mode = COMMAND_EXEC,
@@ -898,6 +673,7 @@ static const struct command_registration 
pic32mx_exec_command_handlers[] = {
        },
        COMMAND_REGISTRATION_DONE
 };
+
 static const struct command_registration pic32mx_command_handlers[] = {
        {
                .name = "pic32mx",
diff --git a/src/flash/nor/pic32mx.h b/src/flash/nor/pic32mx.h
index b3bdad2..79fa40e 100644
--- a/src/flash/nor/pic32mx.h
+++ b/src/flash/nor/pic32mx.h
@@ -29,8 +29,6 @@
 struct pic32mx_flash_bank
 {
        struct working_area *write_algorithm;
-       int devid;
-       int ppage_size;
        int probed;
 };
 
@@ -38,18 +36,6 @@ struct pic32mx_flash_bank
 
 /* pic32mx memory locations */
 
-#define PIC32MX_KUSEG_PGM_FLASH                0x7D000000
-#define PIC32MX_KUSEG_RAM                      0x7F000000
-
-#define PIC32MX_KSEG0_RAM                      0x80000000
-#define PIC32MX_KSEG0_PGM_FLASH                0x9D000000
-#define PIC32MX_KSEG0_BOOT_FLASH       0x9FC00000
-
-#define PIC32MX_KSEG1_RAM                      0xA0000000
-#define PIC32MX_KSEG1_PGM_FLASH                0xBD000000
-#define PIC32MX_KSEG1_PERIPHERAL       0xBF800000
-#define PIC32MX_KSEG1_BOOT_FLASH       0xBFC00000
-
 #define PIC32MX_PHYS_RAM                       0x00000000
 #define PIC32MX_PHYS_PGM_FLASH         0x1D000000
 #define PIC32MX_PHYS_PERIPHERALS       0x1F800000
@@ -59,19 +45,21 @@ struct pic32mx_flash_bank
  * Translate Virtual and Physical addresses.
  * Note: These macros only work for KSEG0/KSEG1 addresses.
  */
-#define KS1Virt2Phys(vaddr)                    ((vaddr)-0xA0000000)
-#define Phys2KS1Virt(paddr)                    ((paddr) + 0xA0000000)
-#define KS0Virt2Phys(vaddr)                    ((vaddr)-0x80000000)
-#define Phys2KS0Virt(paddr)                    ((paddr) + 0x80000000)
+
+#define Virt2Phys(v)   ((v) & 0x1FFFFFFF)
 
 /* pic32mx configuration register locations */
 
 #define PIC32MX_DEVCFG0                0xBFC02FFC
 #define PIC32MX_DEVCFG1                0xBFC02FF8
 #define PIC32MX_DEVCFG2                0xBFC02FF4
-#define PIC32MX_DEVCFG3                0XBFC02FF0
+#define PIC32MX_DEVCFG3                0xBFC02FF0
 #define PIC32MX_DEVID          0xBF80F220
 
+#define PIC32MX_BMXPFMSZ       0xBF882060
+#define PIC32MX_BMXBOOTSZ      0xBF882070
+#define PIC32MX_BMXDRMSZ       0xBF882040
+
 /* pic32mx flash controller register locations */
 
 #define PIC32MX_NVMCON         0xBF80F400
@@ -102,10 +90,5 @@ struct pic32mx_flash_bank
 #define NVMKEY1                        0xAA996655
 #define NVMKEY2                        0x556699AA
 
-struct pic32mx_mem_layout {
-       uint32_t sector_start;
-       uint32_t sector_size;
-};
-
 #endif /* PIC32MX_H */
 
diff --git a/src/target/mips32_pracc.c b/src/target/mips32_pracc.c
index f20c69e..bcba0f1 100644
--- a/src/target/mips32_pracc.c
+++ b/src/target/mips32_pracc.c
@@ -969,7 +969,7 @@ 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);
 
-       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);
@@ -1030,7 +1030,7 @@ int mips32_pracc_fastdata_xfer(struct mips_ejtag 
*ejtag_info, struct working_are
        mips_ejtag_drscan_32(ejtag_info, &address);
 
        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;
 }
diff --git a/src/target/mips_ejtag.h b/src/target/mips_ejtag.h
index 2f62f2b..5c1f245 100644
--- a/src/target/mips_ejtag.h
+++ b/src/target/mips_ejtag.h
@@ -40,6 +40,10 @@
 #define EJTAG_INST_TCBDATA             0x12
 #define EJTAG_INST_BYPASS              0xFF
 
+/* microchip PIC32MX specific instructions */
+#define MTAP_SW_MTAP                   0x04
+#define MTAP_SW_ETAP                   0x05
+
 /* ejtag control register bits ECR */
 #define EJTAG_CTRL_TOF                 (1 << 1)
 #define EJTAG_CTRL_TIF                 (1 << 2)
diff --git a/src/target/mips_m4k.c b/src/target/mips_m4k.c
index f581ddf..389daf9 100644
--- a/src/target/mips_m4k.c
+++ b/src/target/mips_m4k.c
@@ -914,7 +914,7 @@ int mips_m4k_examine(struct target *target)
                {
                        /* we are using a pic32mx so select ejtag port
                         * as it is not selected by default */
-                       mips_ejtag_set_instr(ejtag_info, 0x05, NULL);
+                       mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP, NULL);
                        LOG_DEBUG("PIC32MX Detected - using EJTAG Interface");
                }
        }
diff --git a/tcl/target/pic32mx.cfg b/tcl/target/pic32mx.cfg
index 1561d73..0f1fa66 100644
--- a/tcl/target/pic32mx.cfg
+++ b/tcl/target/pic32mx.cfg
@@ -18,6 +18,14 @@ if { [info exists CPUTAPID ] } {
    set _CPUTAPID 0x30938053
 }
 
+# working area is 16384 - 2048
+# loose first 2048 bytes due to BMXDKPBA reg
+if { [info exists WORKAREASIZE] } {
+   set  _WORKAREASIZE $WORKAREASIZE
+} else {
+   set  _WORKAREASIZE [expr (16384 - 2048)]
+}
+
 jtag_nsrst_delay 100
 jtag_ntrst_delay 100
 
@@ -26,12 +34,12 @@ reset_config srst_only
 
 #jtag scan chain
 #format L IRC IRCM IDCODE (Length, IR Capture, IR Capture Mask, IDCODE)
-jtag newtap $_CHIPNAME cpu -irlen 5  -ircapture 0x1 -irmask 0x1f -expected-id 
$_CPUTAPID
+jtag newtap $_CHIPNAME cpu -irlen 5 -ircapture 0x1 -irmask 0x1f -expected-id 
$_CPUTAPID
 
 set _TARGETNAME $_CHIPNAME.cpu
 target create $_TARGETNAME mips_m4k -endian $_ENDIAN -chain-position 
$_TARGETNAME
 
-$_TARGETNAME configure -work-area-phys 0xa0000800 -work-area-size 16384 
-work-area-backup 0
+$_TARGETNAME configure -work-area-phys 0xa0000800 -work-area-size 
$_WORKAREASIZE -work-area-backup 0
 
 $_TARGETNAME configure -event reset-init {
        #
@@ -50,9 +58,9 @@ $_TARGETNAME configure -event reset-init {
 }
 
 set _FLASHNAME $_CHIPNAME.flash
-flash bank $_FLASHNAME pic32mx 0xbd000000 0 0 0 $_TARGETNAME
+flash bank $_FLASHNAME pic32mx 0x1fc00000 0 0 0 $_TARGETNAME
 set _FLASHNAME $_CHIPNAME.flash
-flash bank $_FLASHNAME pic32mx 0xbfc00000 0 0 0 $_TARGETNAME
+flash bank $_FLASHNAME pic32mx 0x1d000000 0 0 0 $_TARGETNAME
 
 # For more information about the configuration files, take a look at:
 # openocd.texi
-- 
1.6.6.1

_______________________________________________
Openocd-development mailing list
Openocd-development@lists.berlios.de
https://lists.berlios.de/mailman/listinfo/openocd-development

Reply via email to