24 #define PIC32MX_MANUF_ID 0x029
28 #define PIC32MX_PHYS_RAM 0x00000000
29 #define PIC32MX_PHYS_PGM_FLASH 0x1D000000
30 #define PIC32MX_PHYS_PERIPHERALS 0x1F800000
31 #define PIC32MX_PHYS_BOOT_FLASH 0x1FC00000
38 #define virt2phys(v) ((v) & 0x1FFFFFFF)
42 #define PIC32MX_DEVCFG0_1XX_2XX 0xBFC00BFC
43 #define PIC32MX_DEVCFG0 0xBFC02FFC
44 #define PIC32MX_DEVCFG1 0xBFC02FF8
45 #define PIC32MX_DEVCFG2 0xBFC02FF4
46 #define PIC32MX_DEVCFG3 0xBFC02FF0
47 #define PIC32MX_DEVID 0xBF80F220
49 #define PIC32MX_BMXPFMSZ 0xBF882060
50 #define PIC32MX_BMXBOOTSZ 0xBF882070
51 #define PIC32MX_BMXDRMSZ 0xBF882040
55 #define PIC32MX_NVMCON 0xBF80F400
56 #define PIC32MX_NVMCONCLR 0xBF80F404
57 #define PIC32MX_NVMCONSET 0xBF80F408
58 #define PIC32MX_NVMCONINV 0xBF80F40C
59 #define NVMCON_NVMWR (1 << 15)
60 #define NVMCON_NVMWREN (1 << 14)
61 #define NVMCON_NVMERR (1 << 13)
62 #define NVMCON_LVDERR (1 << 12)
63 #define NVMCON_LVDSTAT (1 << 11)
64 #define NVMCON_OP_PFM_ERASE 0x5
65 #define NVMCON_OP_PAGE_ERASE 0x4
66 #define NVMCON_OP_ROW_PROG 0x3
67 #define NVMCON_OP_WORD_PROG 0x1
68 #define NVMCON_OP_NOP 0x0
70 #define PIC32MX_NVMKEY 0xBF80F410
71 #define PIC32MX_NVMADDR 0xBF80F420
72 #define PIC32MX_NVMADDRCLR 0xBF80F424
73 #define PIC32MX_NVMADDRSET 0xBF80F428
74 #define PIC32MX_NVMADDRINV 0xBF80F42C
75 #define PIC32MX_NVMDATA 0xBF80F430
76 #define PIC32MX_NVMSRCADDR 0xBF80F440
80 #define NVMKEY1 0xAA996655
81 #define NVMKEY2 0x556699AA
99 {0x04A07053,
"110F016B"},
100 {0x04A09053,
"110F016C"},
101 {0x04A0B053,
"110F016D"},
102 {0x04A06053,
"120F032B"},
103 {0x04A08053,
"120F032C"},
104 {0x04A0A053,
"120F032D"},
105 {0x04D07053,
"130F064B"},
106 {0x04D09053,
"130F064C"},
107 {0x04D0B053,
"130F064D"},
108 {0x04D06053,
"150F128B"},
109 {0x04D08053,
"150F128C"},
110 {0x04D0A053,
"150F128D"},
111 {0x06610053,
"170F256B"},
112 {0x0661A053,
"170F256D"},
113 {0x04A01053,
"210F016B"},
114 {0x04A03053,
"210F016C"},
115 {0x04A05053,
"210F016D"},
116 {0x04A00053,
"220F032B"},
117 {0x04A02053,
"220F032C"},
118 {0x04A04053,
"220F032D"},
119 {0x04D01053,
"230F064B"},
120 {0x04D03053,
"230F064C"},
121 {0x04D05053,
"230F064D"},
122 {0x04D00053,
"250F128B"},
123 {0x04D02053,
"250F128C"},
124 {0x04D04053,
"250F128D"},
125 {0x06600053,
"270F256B"},
126 {0x0660A053,
"270F256D"},
127 {0x05600053,
"330F064H"},
128 {0x05601053,
"330F064L"},
129 {0x05602053,
"430F064H"},
130 {0x05603053,
"430F064L"},
131 {0x0570C053,
"350F128H"},
132 {0x0570D053,
"350F128L"},
133 {0x0570E053,
"450F128H"},
134 {0x0570F053,
"450F128L"},
135 {0x05704053,
"350F256H"},
136 {0x05705053,
"350F256L"},
137 {0x05706053,
"450F256H"},
138 {0x05707053,
"450F256L"},
139 {0x05808053,
"370F512H"},
140 {0x05809053,
"370F512L"},
141 {0x0580A053,
"470F512H"},
142 {0x0580B053,
"470F512L"},
143 {0x00938053,
"360F512L"},
144 {0x00934053,
"360F256L"},
145 {0x0092D053,
"340F128L"},
146 {0x0092A053,
"320F128L"},
147 {0x00916053,
"340F512H"},
148 {0x00912053,
"340F256H"},
149 {0x0090D053,
"340F128H"},
150 {0x0090A053,
"320F128H"},
151 {0x00906053,
"320F064H"},
152 {0x00902053,
"320F032H"},
153 {0x00978053,
"460F512L"},
154 {0x00974053,
"460F256L"},
155 {0x0096D053,
"440F128L"},
156 {0x00952053,
"440F256H"},
157 {0x00956053,
"440F512H"},
158 {0x0094D053,
"440F128H"},
159 {0x00942053,
"420F032H"},
160 {0x04307053,
"795F512L"},
161 {0x0430E053,
"795F512H"},
162 {0x04306053,
"775F512L"},
163 {0x0430D053,
"775F512H"},
164 {0x04312053,
"775F256L"},
165 {0x04303053,
"775F256H"},
166 {0x04417053,
"764F128L"},
167 {0x0440B053,
"764F128H"},
168 {0x04341053,
"695F512L"},
169 {0x04325053,
"695F512H"},
170 {0x04311053,
"675F512L"},
171 {0x0430C053,
"675F512H"},
172 {0x04305053,
"675F256L"},
173 {0x0430B053,
"675F256H"},
174 {0x04413053,
"664F128L"},
175 {0x04407053,
"664F128H"},
176 {0x04411053,
"664F064L"},
177 {0x04405053,
"664F064H"},
178 {0x0430F053,
"575F512L"},
179 {0x04309053,
"575F512H"},
180 {0x04333053,
"575F256L"},
181 {0x04317053,
"575F256H"},
182 {0x0440F053,
"564F128L"},
183 {0x04403053,
"564F128H"},
184 {0x0440D053,
"564F064L"},
185 {0x04401053,
"564F064H"},
186 {0x04400053,
"534F064H"},
187 {0x0440C053,
"534F064L"},
261 uint32_t config0_address;
263 unsigned int s, num_pages;
282 if ((devcfg0 & (1 << 28)) == 0)
285 if (devcfg0 & (1 << 24))
293 num_pages = (~devcfg0 >> 10) & 0x7f;
296 num_pages = (~devcfg0 >> 10) & 0x1ff;
299 num_pages = (~devcfg0 >> 12) & 0xff;
304 for (s = 0; s <
bank->num_sectors && s < num_pages; s++)
305 bank->sectors[s].is_protected = 1;
306 for (; s <
bank->num_sectors; s++)
307 bank->sectors[s].is_protected = 0;
323 if ((first == 0) && (last == (
bank->num_sectors - 1))
327 LOG_DEBUG(
"Erasing entire program flash");
336 for (
unsigned int i = first; i <= last; i++) {
436 uint32_t buffer_size = 16384;
450 LOG_WARNING(
"no working area available, can't do block memory writes");
485 if (buffer_size <= 256) {
490 LOG_WARNING(
"no large enough working area available, can't do block memory writes");
502 int row_offset =
offset % row_size;
503 uint8_t *new_buffer =
NULL;
504 if (row_offset && (
count >= (row_size / 4))) {
505 new_buffer = malloc(buffer_size);
510 memset(new_buffer, 0xff, row_offset);
511 address -= row_offset;
517 uint32_t thisrun_count;
520 thisrun_count = (
count > ((buffer_size - row_offset) / 4)) ?
521 ((buffer_size - row_offset) / 4) :
count;
523 memcpy(new_buffer + row_offset,
buffer, thisrun_count * 4);
526 row_offset + thisrun_count * 4, new_buffer);
530 thisrun_count = (
count > (buffer_size / 4)) ?
531 (buffer_size / 4) :
count;
534 thisrun_count * 4,
buffer);
541 buf_set_u32(reg_params[2].value, 0, 32, thisrun_count + row_offset / 4);
545 0, 10000, &mips32_info);
547 LOG_ERROR(
"error executing pic32mx flash write algorithm");
555 LOG_ERROR(
"Flash write error NVMERR (status = 0x%08" PRIx32
")",
status);
561 LOG_ERROR(
"Flash write error LVDERR (status = 0x%08" PRIx32
")",
status);
566 buffer += thisrun_count * 4;
567 address += thisrun_count * 4;
568 count -= thisrun_count;
570 address += row_offset;
598 uint32_t words_remaining = (
count / 4);
599 uint32_t bytes_remaining = (
count & 0x00000003);
601 uint32_t bytes_written = 0;
619 if (words_remaining > 0) {
626 LOG_WARNING(
"couldn't use block writes, falling back to single memory accesses");
632 buffer += words_remaining * 4;
633 address += words_remaining * 4;
638 while (words_remaining > 0) {
640 memcpy(&value,
buffer + bytes_written,
sizeof(uint32_t));
645 LOG_ERROR(
"Flash write error NVMERR (status = 0x%08" PRIx32
")",
status);
650 LOG_ERROR(
"Flash write error LVDERR (status = 0x%08" PRIx32
")",
status);
659 if (bytes_remaining) {
660 uint32_t value = 0xffffffff;
661 memcpy(&value,
buffer + bytes_written, bytes_remaining);
666 LOG_ERROR(
"Flash write error NVMERR (status = 0x%08" PRIx32
")",
status);
671 LOG_ERROR(
"Flash write error LVDERR (status = 0x%08" PRIx32
")",
status);
686 uint32_t num_pages = 0;
692 device_id = ejtag_info->
idcode;
693 LOG_INFO(
"device id = 0x%08" PRIx32
" (manuf 0x%03x dev 0x%04x, ver 0x%02x)",
695 (
unsigned)((device_id >> 1) & 0x7ff),
696 (
unsigned)((device_id >> 12) & 0xffff),
697 (
unsigned)((device_id >> 28) & 0xf));
700 LOG_WARNING(
"Cannot identify target as a PIC32MX family.");
706 if (
pic32mx_devs[i].devid == (device_id & 0x0fffffff)) {
730 LOG_WARNING(
"PIC32MX flash size failed, probe inaccurate - assuming 12k flash");
731 num_pages = (12 * 1024);
738 num_pages = (3 * 1024);
741 num_pages = (12 * 1024);
751 LOG_WARNING(
"PIC32MX flash size failed, probe inaccurate - assuming 32k flash");
752 num_pages = (32 * 1024);
755 LOG_WARNING(
"PIC32MX flash size failed, probe inaccurate - assuming 512k flash");
756 num_pages = (512 * 1024);
762 LOG_INFO(
"flash size = %" PRIu32
" KiB", num_pages / 1024);
767 num_pages /= page_size;
768 bank->size = (num_pages * page_size);
769 bank->num_sectors = num_pages;
772 for (i = 0; i < (int)num_pages; i++) {
773 bank->sectors[i].offset = i * page_size;
774 bank->sectors[i].size = page_size;
775 bank->sectors[i].is_erased = -1;
776 bank->sectors[i].is_protected = 1;
799 device_id = ejtag_info->
idcode;
803 "Cannot identify target as a PIC32MX family (manufacturer 0x%03x != 0x%03x)\n",
804 (
unsigned)((device_id >> 1) & 0x7ff),
811 if (
pic32mx_devs[i].devid == (device_id & 0x0fffffff)) {
821 (
unsigned)((device_id >> 28) & 0xf));
828 uint32_t address, value;
842 if (address < bank->
base || address >= (
bank->base +
bank->size)) {
888 if (mchip_cmd & (1 << 7)) {
903 LOG_DEBUG(
"timeout waiting for unlock: 0x%" PRIx8
"", mchip_cmd);
907 }
while ((mchip_cmd & (1 << 2)) || (!(mchip_cmd & (1 << 3))));
915 "INFO: a reset or power cycle is required "
916 "for the new settings to take effect.");
924 .usage =
"<addr> <value> <bank>",
925 .handler = pic32mx_handle_pgm_word_command,
927 .help =
"program a word",
931 .handler = pic32mx_handle_unlock_command,
934 .help =
"Unlock/Erase entire device.",
943 .help =
"pic32mx flash command group",
953 .flash_bank_command = pic32mx_flash_bank_command,
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
void destroy_reg_param(struct reg_param *param)
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned int first, unsigned int num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word.
static void buf_set_u32(uint8_t *_buffer, unsigned int first, unsigned int num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
void command_print(struct command_invocation *cmd, const char *format,...)
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
#define ERROR_COMMAND_SYNTAX_ERROR
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
#define COMMAND_PARSE_NUMBER(type, in, out)
parses the string in into out as a type, or prints a command error and passes the error code to the c...
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
#define ERROR_FLASH_OPERATION_FAILED
#define ERROR_FLASH_DST_BREAKS_ALIGNMENT
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
void default_flash_free_driver_priv(struct flash_bank *bank)
Deallocates bank->driver_priv.
void jtag_add_sleep(uint32_t us)
The JTAG interface can be implemented with a software or hardware fifo.
void alive_sleep(uint64_t ms)
#define LOG_WARNING(expr ...)
#define LOG_ERROR(expr ...)
#define LOG_INFO(expr ...)
#define LOG_DEBUG(expr ...)
#define MIPS32_COMMON_MAGIC
int mips_ejtag_drscan_8(struct mips_ejtag *ejtag_info, uint8_t *data)
void mips_ejtag_set_instr(struct mips_ejtag *ejtag_info, uint32_t new_instr)
void mips_ejtag_drscan_8_out(struct mips_ejtag *ejtag_info, uint8_t data)
#define MCHP_DE_ASSERT_RST
static struct mips_m4k_common * target_to_m4k(struct target *target)
static uint32_t pic32mx_wait_status_busy(struct flash_bank *bank, int timeout)
static const struct command_registration pic32mx_command_handlers[]
#define NVMCON_OP_PFM_ERASE
#define PIC32MX_NVMCONSET
static int pic32mx_write_block(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
#define NVMCON_OP_PAGE_ERASE
static int pic32mx_write_word(struct flash_bank *bank, uint32_t address, uint32_t word)
FLASH_BANK_COMMAND_HANDLER(pic32mx_flash_bank_command)
#define PIC32MX_BMXBOOTSZ
const struct flash_driver pic32mx_flash
static uint32_t pic32mx_get_flash_status(struct flash_bank *bank)
static int pic32mx_nvm_exec(struct flash_bank *bank, uint32_t op, uint32_t timeout)
#define NVMCON_OP_WORD_PROG
#define PIC32MX_NVMCONCLR
static const struct command_registration pic32mx_exec_command_handlers[]
#define PIC32MX_PHYS_PGM_FLASH
static int pic32mx_protect_check(struct flash_bank *bank)
static int pic32mx_probe(struct flash_bank *bank)
#define PIC32MX_PHYS_BOOT_FLASH
static int pic32mx_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
static int pic32mx_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
static uint32_t pic32mx_flash_write_code[]
#define PIC32MX_DEVCFG0_1XX_2XX
COMMAND_HANDLER(pic32mx_handle_pgm_word_command)
static int pic32mx_auto_probe(struct flash_bank *bank)
static int pic32mx_info(struct flash_bank *bank, struct command_invocation *cmd)
static int pic32mx_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Provides details of a flash bank, available either on-chip or through a major interface.
target_addr_t base
The base address of this bank.
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
Describes the geometry and status of a single flash sector within a flash bank.
enum mips32_isa_mode isa_mode
unsigned int common_magic
struct mips_ejtag ejtag_info
struct mips32_common mips32
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
int target_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, target_addr_t entry_point, target_addr_t exit_point, unsigned int timeout_ms, void *arch_info)
Downloads a target-specific native code algorithm to the target, and executes it.
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
int target_alloc_working_area_try(struct target *target, uint32_t size, struct working_area **area)
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
void target_buffer_set_u32_array(struct target *target, uint8_t *buffer, uint32_t count, const uint32_t *srcbuf)
#define ERROR_TARGET_NOT_HALTED
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.