X-Git-Url: https://review.openocd.org/gitweb?p=openocd.git;a=blobdiff_plain;f=src%2Fflash%2Fnor%2Fpic32mx.c;h=6e51f1aa2d0e2c631f1477b141f9b3011d15dcbf;hp=c46264c5568698655057bad177661fe4d6b31d80;hb=2b546fdc45d33a7b407f49b3732d1a57afa60b72;hpb=257a764582f52235414b5c35717b0ee2b49d4b0d diff --git a/src/flash/nor/pic32mx.c b/src/flash/nor/pic32mx.c index c46264c556..6e51f1aa2d 100644 --- a/src/flash/nor/pic32mx.c +++ b/src/flash/nor/pic32mx.c @@ -31,6 +31,7 @@ #include "pic32mx.h" #include #include +#include static const struct pic32mx_devs_s { uint8_t devid; @@ -226,6 +227,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 */ @@ -321,7 +324,7 @@ static int pic32mx_write_block(struct flash_bank *bank, uint8_t *buffer, return retval; /* memory buffer */ - while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) + while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) { buffer_size /= 2; if (buffer_size <= 256) @@ -359,7 +362,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"); @@ -557,7 +560,13 @@ static int pic32mx_probe(struct flash_bank *bank) } } - LOG_INFO("flash size = %dkbytes", num_pages / 1024); + LOG_INFO("flash size = %" PRId32 "kbytes", num_pages / 1024); + + if (bank->sectors) + { + free(bank->sectors); + bank->sectors = NULL; + } /* calculate numbers of pages */ num_pages /= page_size; @@ -664,6 +673,73 @@ COMMAND_HANDLER(pic32mx_handle_pgm_word_command) return ERROR_OK; } +COMMAND_HANDLER(pic32mx_handle_unlock_command) +{ + uint32_t mchip_cmd; + struct target *target = NULL; + struct mips_m4k_common *mips_m4k; + struct mips_ejtag *ejtag_info; + int timeout = 10; + + if (CMD_ARGC < 1) + { + command_print(CMD_CTX, "pic32mx unlock "); + return ERROR_OK; + } + + struct flash_bank *bank; + int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank); + if (ERROR_OK != retval) + return retval; + + target = bank->target; + mips_m4k = target_to_m4k(target); + ejtag_info = &mips_m4k->mips32.ejtag_info; + + /* we have to use the MTAP to perform a full erase */ + mips_ejtag_set_instr(ejtag_info, MTAP_SW_MTAP); + mips_ejtag_set_instr(ejtag_info, MTAP_COMMAND); + + /* first check status of device */ + mchip_cmd = MCHP_STATUS; + mips_ejtag_drscan_8(ejtag_info, &mchip_cmd); + if (mchip_cmd & (1 << 7)) + { + /* device is not locked */ + command_print(CMD_CTX, "pic32mx is already unlocked, erasing anyway"); + } + + /* unlock/erase device */ + mchip_cmd = MCHP_ASERT_RST; + mips_ejtag_drscan_8(ejtag_info, &mchip_cmd); + + mchip_cmd = MCHP_ERASE; + mips_ejtag_drscan_8(ejtag_info, &mchip_cmd); + + do { + mchip_cmd = MCHP_STATUS; + mips_ejtag_drscan_8(ejtag_info, &mchip_cmd); + if (timeout-- == 0) + { + LOG_DEBUG("timeout waiting for unlock: 0x%" PRIx32 "", mchip_cmd); + break; + } + 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); + + /* select ejtag tap */ + mips_ejtag_set_instr(ejtag_info, MTAP_SW_ETAP); + + command_print(CMD_CTX, "pic32mx unlocked.\n" + "INFO: a reset or power cycle is required " + "for the new settings to take effect."); + + return ERROR_OK; +} + static const struct command_registration pic32mx_exec_command_handlers[] = { { .name = "pgm_word", @@ -671,6 +747,13 @@ static const struct command_registration pic32mx_exec_command_handlers[] = { .mode = COMMAND_EXEC, .help = "program a word", }, + { + .name = "unlock", + .handler = pic32mx_handle_unlock_command, + .mode = COMMAND_EXEC, + .usage = "[bank_id]", + .help = "Unlock/Erase entire device.", + }, COMMAND_REGISTRATION_DONE }; @@ -691,6 +774,7 @@ struct flash_driver pic32mx_flash = { .erase = pic32mx_erase, .protect = pic32mx_protect, .write = pic32mx_write, + .read = default_flash_read, .probe = pic32mx_probe, .auto_probe = pic32mx_auto_probe, .erase_check = default_flash_mem_blank_check,