1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * Copyright (C) 2008 by John McCarthy *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
32 #include <target/algorithm.h>
33 #include <target/mips32.h>
35 static const struct pic32mx_devs_s {
66 /* flash bank pic32mx <base> <size> 0 0 <target#>
68 FLASH_BANK_COMMAND_HANDLER(pic32mx_flash_bank_command)
70 struct pic32mx_flash_bank *pic32mx_info;
74 LOG_WARNING("incomplete flash_bank pic32mx configuration");
75 return ERROR_FLASH_BANK_INVALID;
78 pic32mx_info = malloc(sizeof(struct pic32mx_flash_bank));
79 bank->driver_priv = pic32mx_info;
81 pic32mx_info->write_algorithm = NULL;
82 pic32mx_info->probed = 0;
87 static uint32_t pic32mx_get_flash_status(struct flash_bank *bank)
89 struct target *target = bank->target;
92 target_read_u32(target, PIC32MX_NVMCON, &status);
97 static uint32_t pic32mx_wait_status_busy(struct flash_bank *bank, int timeout)
101 /* wait for busy to clear */
102 while (((status = pic32mx_get_flash_status(bank)) & NVMCON_NVMWR) && (timeout-- > 0))
104 LOG_DEBUG("status: 0x%" PRIx32, status);
108 LOG_DEBUG("timeout: status: 0x%" PRIx32, status);
113 static int pic32mx_nvm_exec(struct flash_bank *bank, uint32_t op, uint32_t timeout)
115 struct target *target = bank->target;
118 target_write_u32(target, PIC32MX_NVMCON, NVMCON_NVMWREN | op);
120 /* unlock flash registers */
121 target_write_u32(target, PIC32MX_NVMKEY, NVMKEY1);
122 target_write_u32(target, PIC32MX_NVMKEY, NVMKEY2);
124 /* start operation */
125 target_write_u32(target, PIC32MX_NVMCONSET, NVMCON_NVMWR);
127 status = pic32mx_wait_status_busy(bank, timeout);
129 /* lock flash registers */
130 target_write_u32(target, PIC32MX_NVMCONCLR, NVMCON_NVMWREN);
135 static int pic32mx_protect_check(struct flash_bank *bank)
137 struct target *target = bank->target;
143 if (target->state != TARGET_HALTED)
145 LOG_ERROR("Target not halted");
146 return ERROR_TARGET_NOT_HALTED;
149 target_read_u32(target, PIC32MX_DEVCFG0, &devcfg0);
151 if ((devcfg0 & (1 << 28)) == 0) /* code protect bit */
152 num_pages = 0xffff; /* All pages protected */
153 else if (Virt2Phys(bank->base) == PIC32MX_PHYS_BOOT_FLASH)
155 if (devcfg0 & (1 << 24))
156 num_pages = 0; /* All pages unprotected */
158 num_pages = 0xffff; /* All pages protected */
161 num_pages = (~devcfg0 >> 12) & 0xff;
163 for (s = 0; s < bank->num_sectors && s < num_pages; s++)
164 bank->sectors[s].is_protected = 1;
165 for (; s < bank->num_sectors; s++)
166 bank->sectors[s].is_protected = 0;
171 static int pic32mx_erase(struct flash_bank *bank, int first, int last)
173 struct target *target = bank->target;
177 if (bank->target->state != TARGET_HALTED)
179 LOG_ERROR("Target not halted");
180 return ERROR_TARGET_NOT_HALTED;
183 if ((first == 0) && (last == (bank->num_sectors - 1))
184 && (Virt2Phys(bank->base) == PIC32MX_PHYS_PGM_FLASH))
186 /* this will only erase the Program Flash (PFM), not the Boot Flash (BFM)
187 * we need to use the MTAP to perform a full erase */
188 LOG_DEBUG("Erasing entire program flash");
189 status = pic32mx_nvm_exec(bank, NVMCON_OP_PFM_ERASE, 50);
190 if (status & NVMCON_NVMERR)
191 return ERROR_FLASH_OPERATION_FAILED;
192 if (status & NVMCON_LVDERR)
193 return ERROR_FLASH_OPERATION_FAILED;
197 for (i = first; i <= last; i++)
199 target_write_u32(target, PIC32MX_NVMADDR, Virt2Phys(bank->base + bank->sectors[i].offset));
201 status = pic32mx_nvm_exec(bank, NVMCON_OP_PAGE_ERASE, 10);
203 if (status & NVMCON_NVMERR)
204 return ERROR_FLASH_OPERATION_FAILED;
205 if (status & NVMCON_LVDERR)
206 return ERROR_FLASH_OPERATION_FAILED;
207 bank->sectors[i].is_erased = 1;
213 static int pic32mx_protect(struct flash_bank *bank, int set, int first, int last)
215 struct pic32mx_flash_bank *pic32mx_info = NULL;
216 struct target *target = bank->target;
218 pic32mx_info = bank->driver_priv;
220 if (target->state != TARGET_HALTED)
222 LOG_ERROR("Target not halted");
223 return ERROR_TARGET_NOT_HALTED;
229 static const uint32_t pic32mx_flash_write_code[] = {
231 0x3C08AA99, /* lui $t0, 0xaa99 */
232 0x35086655, /* ori $t0, 0x6655 */
233 0x3C095566, /* lui $t1, 0x5566 */
234 0x352999AA, /* ori $t1, 0x99aa */
235 0x3C0ABF80, /* lui $t2, 0xbf80 */
236 0x354AF400, /* ori $t2, 0xf400 */
237 0x340B4003, /* ori $t3, $zero, 0x4003 */
238 0x340C8000, /* ori $t4, $zero, 0x8000 */
240 0x2CD30080, /* sltiu $s3, $a2, 128 */
241 0x16600008, /* bne $s3, $zero, write_word */
242 0x340D4000, /* ori $t5, $zero, 0x4000 */
243 0xAD450020, /* sw $a1, 32($t2) */
244 0xAD440040, /* sw $a0, 64($t2) */
245 0x04110016, /* bal progflash */
246 0x24840200, /* addiu $a0, $a0, 512 */
247 0x24A50200, /* addiu $a1, $a1, 512 */
248 0x1000FFF7, /* beq $zero, $zero, write_row */
249 0x24C6FF80, /* addiu $a2, $a2, -128 */
251 0x3C15A000, /* lui $s5, 0xa000 */
252 0x36B50000, /* ori $s5, $s5, 0x0 */
253 0x00952025, /* or $a0, $a0, $s5 */
254 0x10000008, /* beq $zero, $zero, next_word */
255 0x340B4001, /* ori $t3, $zero, 0x4001 */
257 0x8C940000, /* lw $s4, 0($a0) */
258 0xAD540030, /* sw $s4, 48($t2) */
259 0xAD450020, /* sw $a1, 32($t2) */
260 0x04110009, /* bal progflash */
261 0x24840004, /* addiu $a0, $a0, 4 */
262 0x24A50004, /* addiu $a1, $a1, 4 */
263 0x24C6FFFF, /* addiu $a2, $a2, -1 */
265 0x14C0FFF8, /* bne $a2, $zero, prog_word */
266 0x00000000, /* nop */
268 0x10000002, /* beq $zero, $zero, exit */
269 0x24040000, /* addiu $a0, $zero, 0 */
271 0x26240000, /* addiu $a0, $s1, 0 */
273 0x7000003F, /* sdbbp */
275 0xAD4B0000, /* sw $t3, 0($t2) */
276 0xAD480010, /* sw $t0, 16($t2) */
277 0xAD490010, /* sw $t1, 16($t2) */
278 0xAD4C0008, /* sw $t4, 8($t2) */
280 0x8D500000, /* lw $s0, 0($t2) */
281 0x020C8024, /* and $s0, $s0, $t4 */
282 0x1600FFFD, /* bne $s0, $zero, waitflash */
283 0x00000000, /* nop */
284 0x00000000, /* nop */
285 0x00000000, /* nop */
286 0x00000000, /* nop */
287 0x00000000, /* nop */
288 0x8D510000, /* lw $s1, 0($t2) */
289 0x30113000, /* andi $s1, $zero, 0x3000 */
290 0x1620FFEF, /* bne $s1, $zero, error */
291 0xAD4D0004, /* sw $t5, 4($t2) */
292 0x03E00008, /* jr $ra */
296 static int pic32mx_write_block(struct flash_bank *bank, uint8_t *buffer,
297 uint32_t offset, uint32_t count)
299 struct target *target = bank->target;
300 uint32_t buffer_size = 16384;
301 struct working_area *source;
302 uint32_t address = bank->base + offset;
303 struct reg_param reg_params[3];
304 int retval = ERROR_OK;
306 struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;
307 struct mips32_algorithm mips32_info;
309 /* flash write code */
310 if (target_alloc_working_area(target, sizeof(pic32mx_flash_write_code),
311 &pic32mx_info->write_algorithm) != ERROR_OK)
313 LOG_WARNING("no working area available, can't do block memory writes");
314 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
317 if ((retval = target_write_buffer(target,
318 pic32mx_info->write_algorithm->address,
319 sizeof(pic32mx_flash_write_code),
320 (uint8_t*)pic32mx_flash_write_code)) != ERROR_OK)
324 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
327 if (buffer_size <= 256)
329 /* if we already allocated the writing code, but failed to get a
330 * buffer, free the algorithm */
331 if (pic32mx_info->write_algorithm)
332 target_free_working_area(target, pic32mx_info->write_algorithm);
334 LOG_WARNING("no large enough working area available, can't do block memory writes");
335 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
339 mips32_info.common_magic = MIPS32_COMMON_MAGIC;
340 mips32_info.isa_mode = MIPS32_ISA_MIPS32;
342 init_reg_param(®_params[0], "a0", 32, PARAM_IN_OUT);
343 init_reg_param(®_params[1], "a1", 32, PARAM_OUT);
344 init_reg_param(®_params[2], "a2", 32, PARAM_OUT);
349 uint32_t thisrun_count = (count > (buffer_size / 4)) ?
350 (buffer_size / 4) : count;
352 if ((retval = target_write_buffer(target, source->address,
353 thisrun_count * 4, buffer)) != ERROR_OK)
356 buf_set_u32(reg_params[0].value, 0, 32, Virt2Phys(source->address));
357 buf_set_u32(reg_params[1].value, 0, 32, Virt2Phys(address));
358 buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
360 if ((retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
361 pic32mx_info->write_algorithm->address,
362 pic32mx_info->write_algorithm->address + (sizeof(pic32mx_flash_write_code) - 76),
363 10000, &mips32_info)) != ERROR_OK)
365 LOG_ERROR("error executing pic32mx flash write algorithm");
366 retval = ERROR_FLASH_OPERATION_FAILED;
370 status = buf_get_u32(reg_params[0].value, 0, 32);
372 if (status & NVMCON_NVMERR)
374 LOG_ERROR("Flash write error NVMERR (status = 0x%08" PRIx32 ")", status);
375 retval = ERROR_FLASH_OPERATION_FAILED;
379 if (status & NVMCON_LVDERR)
381 LOG_ERROR("Flash write error LVDERR (status = 0x%08" PRIx32 ")", status);
382 retval = ERROR_FLASH_OPERATION_FAILED;
386 buffer += thisrun_count * 4;
387 address += thisrun_count * 4;
388 count -= thisrun_count;
391 target_free_working_area(target, source);
392 target_free_working_area(target, pic32mx_info->write_algorithm);
394 destroy_reg_param(®_params[0]);
395 destroy_reg_param(®_params[1]);
396 destroy_reg_param(®_params[2]);
401 static int pic32mx_write_word(struct flash_bank *bank, uint32_t address, uint32_t word)
403 struct target *target = bank->target;
405 target_write_u32(target, PIC32MX_NVMADDR, Virt2Phys(address));
406 target_write_u32(target, PIC32MX_NVMDATA, word);
408 return pic32mx_nvm_exec(bank, NVMCON_OP_WORD_PROG, 5);
411 static int pic32mx_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
413 uint32_t words_remaining = (count / 4);
414 uint32_t bytes_remaining = (count & 0x00000003);
415 uint32_t address = bank->base + offset;
416 uint32_t bytes_written = 0;
420 if (bank->target->state != TARGET_HALTED)
422 LOG_ERROR("Target not halted");
423 return ERROR_TARGET_NOT_HALTED;
426 LOG_DEBUG("writing to flash at address 0x%08" PRIx32 " at offset 0x%8.8" PRIx32
427 " count: 0x%8.8" PRIx32 "", bank->base, offset, count);
431 LOG_WARNING("offset 0x%" PRIx32 "breaks required 4-byte alignment", offset);
432 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
435 /* multiple words (4-byte) to be programmed? */
436 if (words_remaining > 0)
438 /* try using a block write */
439 if ((retval = pic32mx_write_block(bank, buffer, offset, words_remaining)) != ERROR_OK)
441 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
443 /* if block write failed (no sufficient working area),
444 * we use normal (slow) single dword accesses */
445 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
447 else if (retval == ERROR_FLASH_OPERATION_FAILED)
449 LOG_ERROR("flash writing failed with error code: 0x%x", retval);
450 return ERROR_FLASH_OPERATION_FAILED;
455 buffer += words_remaining * 4;
456 address += words_remaining * 4;
461 while (words_remaining > 0)
464 memcpy(&value, buffer + bytes_written, sizeof(uint32_t));
466 status = pic32mx_write_word(bank, address, value);
468 if (status & NVMCON_NVMERR)
470 LOG_ERROR("Flash write error NVMERR (status = 0x%08" PRIx32 ")", status);
471 return ERROR_FLASH_OPERATION_FAILED;
474 if (status & NVMCON_LVDERR)
476 LOG_ERROR("Flash write error LVDERR (status = 0x%08" PRIx32 ")", status);
477 return ERROR_FLASH_OPERATION_FAILED;
487 uint32_t value = 0xffffffff;
488 memcpy(&value, buffer + bytes_written, bytes_remaining);
490 status = pic32mx_write_word(bank, address, value);
492 if (status & NVMCON_NVMERR)
494 LOG_ERROR("Flash write error NVMERR (status = 0x%08" PRIx32 ")", status);
495 return ERROR_FLASH_OPERATION_FAILED;
498 if (status & NVMCON_LVDERR)
500 LOG_ERROR("Flash write error LVDERR (status = 0x%08" PRIx32 ")", status);
501 return ERROR_FLASH_OPERATION_FAILED;
508 static int pic32mx_probe(struct flash_bank *bank)
510 struct target *target = bank->target;
511 struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;
512 struct mips32_common *mips32 = target->arch_info;
513 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
515 uint32_t num_pages = 0;
519 pic32mx_info->probed = 0;
521 device_id = ejtag_info->idcode;
522 LOG_INFO("device id = 0x%08" PRIx32 " (manuf 0x%03x dev 0x%02x, ver 0x%02x)",
524 (unsigned)((device_id >> 1) & 0x7ff),
525 (unsigned)((device_id >> 12) & 0xff),
526 (unsigned)((device_id >> 28) & 0xf));
528 if (((device_id >> 1) & 0x7ff) != PIC32MX_MANUF_ID) {
529 LOG_WARNING("Cannot identify target as a PIC32MX family.");
530 return ERROR_FLASH_OPERATION_FAILED;
535 if (Virt2Phys(bank->base) == PIC32MX_PHYS_BOOT_FLASH)
537 /* 0x1FC00000: Boot flash size */
539 /* for some reason this register returns 8k for the boot bank size
540 * this does not match the docs, so for now set the boot bank at a
542 if (target_read_u32(target, PIC32MX_BMXBOOTSZ, &num_pages) != ERROR_OK) {
543 LOG_WARNING("PIC32MX flash size failed, probe inaccurate - assuming 12k flash");
544 num_pages = (12 * 1024);
547 /* fixed 12k boot bank - see comments above */
548 num_pages = (12 * 1024);
553 /* read the flash size from the device */
554 if (target_read_u32(target, PIC32MX_BMXPFMSZ, &num_pages) != ERROR_OK) {
555 LOG_WARNING("PIC32MX flash size failed, probe inaccurate - assuming 512k flash");
556 num_pages = (512 * 1024);
560 LOG_INFO("flash size = %dkbytes", num_pages / 1024);
562 /* calculate numbers of pages */
563 num_pages /= page_size;
564 bank->size = (num_pages * page_size);
565 bank->num_sectors = num_pages;
566 bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
568 for (i = 0; i < (int)num_pages; i++)
570 bank->sectors[i].offset = i * page_size;
571 bank->sectors[i].size = page_size;
572 bank->sectors[i].is_erased = -1;
573 bank->sectors[i].is_protected = 1;
576 pic32mx_info->probed = 1;
581 static int pic32mx_auto_probe(struct flash_bank *bank)
583 struct pic32mx_flash_bank *pic32mx_info = bank->driver_priv;
584 if (pic32mx_info->probed)
586 return pic32mx_probe(bank);
589 static int pic32mx_info(struct flash_bank *bank, char *buf, int buf_size)
591 struct target *target = bank->target;
592 struct mips32_common *mips32 = target->arch_info;
593 struct mips_ejtag *ejtag_info = &mips32->ejtag_info;
597 device_id = ejtag_info->idcode;
599 if (((device_id >> 1) & 0x7ff) != PIC32MX_MANUF_ID) {
600 snprintf(buf, buf_size,
601 "Cannot identify target as a PIC32MX family (manufacturer 0x%03d != 0x%03d)\n",
602 (unsigned)((device_id >> 1) & 0x7ff),
604 return ERROR_FLASH_OPERATION_FAILED;
607 for (i = 0; pic32mx_devs[i].name != NULL; i++)
609 if (pic32mx_devs[i].devid == ((device_id >> 12) & 0xff)) {
610 printed = snprintf(buf, buf_size, "PIC32MX%s", pic32mx_devs[i].name);
615 if (pic32mx_devs[i].name == NULL) {
616 printed = snprintf(buf, buf_size, "Unknown");
621 printed = snprintf(buf, buf_size, " Ver: 0x%02x",
622 (unsigned)((device_id >> 28) & 0xf));
627 COMMAND_HANDLER(pic32mx_handle_pgm_word_command)
629 uint32_t address, value;
634 command_print(CMD_CTX, "pic32mx pgm_word <addr> <value> <bank>");
638 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
639 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], value);
641 struct flash_bank *bank;
642 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 2, &bank);
643 if (ERROR_OK != retval)
646 if (address < bank->base || address >= (bank->base + bank->size))
648 command_print(CMD_CTX, "flash address '%s' is out of bounds", CMD_ARGV[0]);
653 status = pic32mx_write_word(bank, address, value);
654 if (status & NVMCON_NVMERR)
655 res = ERROR_FLASH_OPERATION_FAILED;
656 if (status & NVMCON_LVDERR)
657 res = ERROR_FLASH_OPERATION_FAILED;
660 command_print(CMD_CTX, "pic32mx pgm word complete");
662 command_print(CMD_CTX, "pic32mx pgm word failed (status = 0x%x)", status);
667 static const struct command_registration pic32mx_exec_command_handlers[] = {
670 .handler = pic32mx_handle_pgm_word_command,
671 .mode = COMMAND_EXEC,
672 .help = "program a word",
674 COMMAND_REGISTRATION_DONE
677 static const struct command_registration pic32mx_command_handlers[] = {
681 .help = "pic32mx flash command group",
682 .chain = pic32mx_exec_command_handlers,
684 COMMAND_REGISTRATION_DONE
687 struct flash_driver pic32mx_flash = {
689 .commands = pic32mx_command_handlers,
690 .flash_bank_command = pic32mx_flash_bank_command,
691 .erase = pic32mx_erase,
692 .protect = pic32mx_protect,
693 .write = pic32mx_write,
694 .probe = pic32mx_probe,
695 .auto_probe = pic32mx_auto_probe,
696 .erase_check = default_flash_mem_blank_check,
697 .protect_check = pic32mx_protect_check,
698 .info = pic32mx_info,