X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fpic32mx.c;h=a8392eb8137e82f0910c287452d413f58ad2b8b9;hb=5bd1f0bad4086072f9abffc5c7814511b1456b72;hp=2fe864d4f0fbf592d05b76164e28a3ad1a7b6cc7;hpb=86e851e1e263c79f19eb9db52553de99f19b8bb9;p=openocd.git diff --git a/src/flash/nor/pic32mx.c b/src/flash/nor/pic32mx.c index 2fe864d4f0..a8392eb813 100644 --- a/src/flash/nor/pic32mx.c +++ b/src/flash/nor/pic32mx.c @@ -28,40 +28,140 @@ #endif #include "imp.h" -#include "pic32mx.h" #include #include #include +#define PIC32MX_MANUF_ID 0x029 + +/* pic32mx memory locations */ + +#define PIC32MX_PHYS_RAM 0x00000000 +#define PIC32MX_PHYS_PGM_FLASH 0x1D000000 +#define PIC32MX_PHYS_PERIPHERALS 0x1F800000 +#define PIC32MX_PHYS_BOOT_FLASH 0x1FC00000 + +/* + * Translate Virtual and Physical addresses. + * Note: These macros only work for KSEG0/KSEG1 addresses. + */ + +#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_DEVID 0xBF80F220 + +#define PIC32MX_BMXPFMSZ 0xBF882060 +#define PIC32MX_BMXBOOTSZ 0xBF882070 +#define PIC32MX_BMXDRMSZ 0xBF882040 + +/* pic32mx flash controller register locations */ + +#define PIC32MX_NVMCON 0xBF80F400 +#define PIC32MX_NVMCONCLR 0xBF80F404 +#define PIC32MX_NVMCONSET 0xBF80F408 +#define PIC32MX_NVMCONINV 0xBF80F40C +#define NVMCON_NVMWR (1 << 15) +#define NVMCON_NVMWREN (1 << 14) +#define NVMCON_NVMERR (1 << 13) +#define NVMCON_LVDERR (1 << 12) +#define NVMCON_LVDSTAT (1 << 11) +#define NVMCON_OP_PFM_ERASE 0x5 +#define NVMCON_OP_PAGE_ERASE 0x4 +#define NVMCON_OP_ROW_PROG 0x3 +#define NVMCON_OP_WORD_PROG 0x1 +#define NVMCON_OP_NOP 0x0 + +#define PIC32MX_NVMKEY 0xBF80F410 +#define PIC32MX_NVMADDR 0xBF80F420 +#define PIC32MX_NVMADDRCLR 0xBF80F424 +#define PIC32MX_NVMADDRSET 0xBF80F428 +#define PIC32MX_NVMADDRINV 0xBF80F42C +#define PIC32MX_NVMDATA 0xBF80F430 +#define PIC32MX_NVMSRCADDR 0xBF80F440 + +/* flash unlock keys */ + +#define NVMKEY1 0xAA996655 +#define NVMKEY2 0x556699AA + +struct pic32mx_flash_bank +{ + struct working_area *write_algorithm; + int probed; +}; + +/* + * DEVID values as per PIC32MX Flash Programming Specification Rev H + */ + static const struct pic32mx_devs_s { - uint8_t devid; - char *name; + uint32_t devid; + const char *name; } pic32mx_devs[] = { - {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} + {0x04A07053, "110F016B"}, + {0x04A09053, "110F016C"}, + {0x04A0B053, "110F016D"}, + {0x04A06053, "120F032B"}, + {0x04A08053, "120F032C"}, + {0x04A0A053, "120F032D"}, + {0x04A01053, "210F016B"}, + {0x04A03053, "210F016C"}, + {0x04A05053, "210F016D"}, + {0x04A00053, "220F032B"}, + {0x04A02053, "220F032C"}, + {0x04A04053, "220F032D"}, + {0x00938053, "360F512L"}, + {0x00934053, "360F256L"}, + {0x0092D053, "340F128L"}, + {0x0092A053, "320F128L"}, + {0x00916053, "340F512H"}, + {0x00912053, "340F256H"}, + {0x0090D053, "340F128H"}, + {0x0090A053, "320F128H"}, + {0x00906053, "320F064H"}, + {0x00902053, "320F032H"}, + {0x00978053, "460F512L"}, + {0x00974053, "460F256L"}, + {0x0096D053, "440F128L"}, + {0x00952053, "440F256H"}, + {0x00956053, "440F512H"}, + {0x0094D053, "440F128H"}, + {0x00942053, "420F032H"}, + {0x04307053, "795F512L"}, + {0x0430E053, "795F512H"}, + {0x04306053, "775F512L"}, + {0x0430D053, "775F512H"}, + {0x04312053, "775F256L"}, + {0x04303053, "775F256H"}, + {0x04417053, "764F128L"}, + {0x0440B053, "764F128H"}, + {0x04341053, "695F512L"}, + {0x04325053, "695F512H"}, + {0x04311053, "675F512L"}, + {0x0430C053, "675F512H"}, + {0x04305053, "675F256L"}, + {0x0430B053, "675F256H"}, + {0x04413053, "664F128L"}, + {0x04407053, "664F128H"}, + {0x04411053, "664F064L"}, + {0x04405053, "664F064H"}, + {0x0430F053, "575F512L"}, + {0x04309053, "575F512H"}, + {0x04333053, "575F256L"}, + {0x04317053, "575F256H"}, + {0x0440F053, "564F128L"}, + {0x04403053, "564F128H"}, + {0x0440D053, "564F064L"}, + {0x04401053, "564F064H"}, + {0x04400053, "534F064H"}, + {0x0440C053, "534F064L"}, + {0x00000000, NULL} }; /* flash bank pic32mx 0 0 @@ -227,6 +327,8 @@ static int pic32mx_protect(struct flash_bank *bank, int set, int first, int last return ERROR_OK; } +/* see contib/loaders/flash/pic32mx.s for src */ + static const uint32_t pic32mx_flash_write_code[] = { /* write: */ 0x3C08AA99, /* lui $t0, 0xaa99 */ @@ -360,7 +462,7 @@ static int pic32mx_write_block(struct flash_bank *bank, uint8_t *buffer, 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), + 0, 10000, &mips32_info)) != ERROR_OK) { LOG_ERROR("error executing pic32mx flash write algorithm"); @@ -447,8 +549,8 @@ static int pic32mx_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offs } else if (retval == ERROR_FLASH_OPERATION_FAILED) { - LOG_ERROR("flash writing failed with error code: 0x%x", retval); - return ERROR_FLASH_OPERATION_FAILED; + LOG_ERROR("flash writing failed"); + return retval; } } else @@ -520,10 +622,10 @@ static int pic32mx_probe(struct flash_bank *bank) pic32mx_info->probed = 0; device_id = ejtag_info->idcode; - LOG_INFO("device id = 0x%08" PRIx32 " (manuf 0x%03x dev 0x%02x, ver 0x%02x)", + LOG_INFO("device id = 0x%08" PRIx32 " (manuf 0x%03x dev 0x%04x, ver 0x%02x)", device_id, (unsigned)((device_id >> 1) & 0x7ff), - (unsigned)((device_id >> 12) & 0xff), + (unsigned)((device_id >> 12) & 0xffff), (unsigned)((device_id >> 28) & 0xf)); if (((device_id >> 1) & 0x7ff) != PIC32MX_MANUF_ID) { @@ -613,7 +715,7 @@ static int pic32mx_info(struct flash_bank *bank, char *buf, int buf_size) for (i = 0; pic32mx_devs[i].name != NULL; i++) { - if (pic32mx_devs[i].devid == ((device_id >> 12) & 0xff)) { + if (pic32mx_devs[i].devid == (device_id & 0x0fffffff)) { printed = snprintf(buf, buf_size, "PIC32MX%s", pic32mx_devs[i].name); break; } @@ -625,7 +727,7 @@ static int pic32mx_info(struct flash_bank *bank, char *buf, int buf_size) buf += printed; buf_size -= printed; - printed = snprintf(buf, buf_size, " Ver: 0x%02x", + printed = snprintf(buf, buf_size, " Ver: 0x%02x", (unsigned)((device_id >> 28) & 0xf)); return ERROR_OK; @@ -708,11 +810,9 @@ COMMAND_HANDLER(pic32mx_handle_unlock_command) } /* unlock/erase device */ - mchip_cmd = MCHP_ASERT_RST; - mips_ejtag_drscan_8(ejtag_info, &mchip_cmd); + mips_ejtag_drscan_8_out(ejtag_info, MCHP_ASERT_RST); - mchip_cmd = MCHP_ERASE; - mips_ejtag_drscan_8(ejtag_info, &mchip_cmd); + mips_ejtag_drscan_8_out(ejtag_info, MCHP_ERASE); do { mchip_cmd = MCHP_STATUS; @@ -725,8 +825,7 @@ COMMAND_HANDLER(pic32mx_handle_unlock_command) alive_sleep(1); } while ((mchip_cmd & (1 << 2)) || (!(mchip_cmd & (1 << 3)))); - mchip_cmd = MCHP_DE_ASSERT_RST; - mips_ejtag_drscan_8(ejtag_info, &mchip_cmd); + mips_ejtag_drscan_8_out(ejtag_info, MCHP_DE_ASSERT_RST); /* select ejtag tap */ mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP);