flash/nor: improved API of flash_driver.info & fixed buffer overruns
[openocd.git] / src / flash / nor / max32xxx.c
1 /***************************************************************************
2 * Copyright (C) 2016 by Maxim Integrated *
3 * Kevin Gillespie <kevin.gillespie@maximintegrated.com> *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "imp.h"
24 #include <target/algorithm.h>
25 #include <target/armv7m.h>
26
27 /* Register Addresses */
28 #define FLSH_ADDR 0x000
29 #define FLSH_CLKDIV 0x004
30 #define FLSH_CN 0x008
31 #define PR1E_ADDR 0x00C
32 #define PR2S_ADDR 0x010
33 #define PR2E_ADDR 0x014
34 #define PR3S_ADDR 0x018
35 #define PR3E_ADDR 0x01C
36 #define FLSH_MD 0x020
37 #define FLSH_INT 0x024
38 #define FLSH_DATA0 0x030
39 #define FLSH_DATA1 0x034
40 #define FLSH_DATA2 0x038
41 #define FLSH_DATA3 0x03C
42 #define FLSH_BL_CTRL 0x170
43 #define FLSH_PROT 0x300
44
45 #define ARM_PID_REG 0xE00FFFE0
46 #define MAX326XX_ID_REG 0x40000838
47
48 /* Register settings */
49 #define FLSH_INT_AF 0x00000002
50
51 #define FLSH_CN_UNLOCK_MASK 0xF0000000
52 #define FLSH_CN_UNLOCK_VALUE 0x20000000
53
54 #define FLSH_CN_PEND 0x01000000
55
56 #define FLSH_CN_ERASE_CODE_MASK 0x0000FF00
57 #define FLSH_CN_ERASE_CODE_PGE 0x00005500
58 #define FLSH_CN_ERASE_CODE_ME 0x0000AA00
59
60 #define FLSH_CN_PGE 0x00000004
61 #define FLSH_CN_ME 0x00000002
62 #define FLSH_CN_WR 0x00000001
63 #define FLASH_BL_CTRL_23 0x00020000
64 #define FLASH_BL_CTRL_IFREN 0x00000001
65
66 #define ARM_PID_DEFAULT_CM3 0xB4C3
67 #define ARM_PID_DEFAULT_CM4 0xB4C4
68 #define MAX326XX_ID 0x4D
69
70 static int max32xxx_mass_erase(struct flash_bank *bank);
71
72 struct max32xxx_flash_bank {
73 bool probed;
74 int max326xx;
75 unsigned int flash_size;
76 unsigned int flc_base;
77 unsigned int sector_size;
78 unsigned int clkdiv_value;
79 uint32_t int_state;
80 unsigned int burst_size_bits;
81 };
82
83 /* see contrib/loaders/flash/max32xxx/max32xxx.s for src */
84 static const uint8_t write_code[] = {
85 #include "../../../contrib/loaders/flash/max32xxx/max32xxx.inc"
86 };
87
88 /* Config Command: flash bank name driver base size chip_width bus_width target [driver_option]
89 flash bank max32xxx <base> <size> 0 0 <target> <FLC base> <sector size> <clkdiv> [burst_bits]
90 */
91 FLASH_BANK_COMMAND_HANDLER(max32xxx_flash_bank_command)
92 {
93 struct max32xxx_flash_bank *info;
94
95 if (CMD_ARGC < 9) {
96 LOG_WARNING("incomplete flash bank max32xxx configuration: <base> <size> 0 0 <target> <FLC base> <sector size> <clkdiv> [burst_bits]");
97 return ERROR_FLASH_BANK_INVALID;
98 }
99
100 info = calloc(sizeof(struct max32xxx_flash_bank), 1);
101 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], info->flash_size);
102 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[6], info->flc_base);
103 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[7], info->sector_size);
104 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[8], info->clkdiv_value);
105
106 if (CMD_ARGC > 9)
107 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[9], info->burst_size_bits);
108 else
109 info->burst_size_bits = 32;
110
111 info->int_state = 0;
112 bank->driver_priv = info;
113 return ERROR_OK;
114 }
115
116 static int get_info(struct flash_bank *bank, struct command_invocation *cmd)
117 {
118 struct max32xxx_flash_bank *info = bank->driver_priv;
119
120 if (!info->probed)
121 return ERROR_FLASH_BANK_NOT_PROBED;
122
123 command_print_sameline(cmd, "\nMaxim Integrated max32xxx flash driver\n");
124 return ERROR_OK;
125 }
126
127 /***************************************************************************
128 * flash operations
129 ***************************************************************************/
130
131 static int max32xxx_flash_op_pre(struct flash_bank *bank)
132 {
133 struct target *target = bank->target;
134 struct max32xxx_flash_bank *info = bank->driver_priv;
135 uint32_t flsh_cn;
136 uint32_t bootloader;
137
138 /* Check if the flash controller is busy */
139 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
140 if (flsh_cn & (FLSH_CN_PEND | FLSH_CN_ERASE_CODE_MASK | FLSH_CN_PGE |
141 FLSH_CN_ME | FLSH_CN_WR))
142 return ERROR_FLASH_BUSY;
143
144 /* Refresh flash controller timing */
145 target_write_u32(target, info->flc_base + FLSH_CLKDIV, info->clkdiv_value);
146
147 /* Clear and disable flash programming interrupts */
148 target_read_u32(target, info->flc_base + FLSH_INT, &info->int_state);
149 target_write_u32(target, info->flc_base + FLSH_INT, 0x00000000);
150
151 /* Clear the lower bit in the bootloader configuration register in case flash page 0 has been replaced */
152 if (target_read_u32(target, info->flc_base + FLSH_BL_CTRL, &bootloader) != ERROR_OK) {
153 LOG_ERROR("Read failure on FLSH_BL_CTRL");
154 return ERROR_FAIL;
155 }
156 if (bootloader & FLASH_BL_CTRL_23) {
157 LOG_WARNING("FLSH_BL_CTRL indicates BL mode 2 or mode 3.");
158 if (bootloader & FLASH_BL_CTRL_IFREN) {
159 LOG_WARNING("Flash page 0 swapped out, attempting to swap back in for programming");
160 bootloader &= ~(FLASH_BL_CTRL_IFREN);
161 if (target_write_u32(target, info->flc_base + FLSH_BL_CTRL, bootloader) != ERROR_OK) {
162 LOG_ERROR("Write failure on FLSH_BL_CTRL");
163 return ERROR_FAIL;
164 }
165 if (target_read_u32(target, info->flc_base + FLSH_BL_CTRL, &bootloader) != ERROR_OK) {
166 LOG_ERROR("Read failure on FLSH_BL_CTRL");
167 return ERROR_FAIL;
168 }
169 if (bootloader & FLASH_BL_CTRL_IFREN) {
170 /* Bummer */
171 LOG_ERROR("Unable to swap flash page 0 back in. Writes to page 0 will fail.");
172 }
173 }
174 }
175
176 /* Unlock flash */
177 flsh_cn &= ~FLSH_CN_UNLOCK_MASK;
178 flsh_cn |= FLSH_CN_UNLOCK_VALUE;
179 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
180
181 /* Confirm flash is unlocked */
182 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
183 if ((flsh_cn & FLSH_CN_UNLOCK_VALUE) != FLSH_CN_UNLOCK_VALUE)
184 return ERROR_FAIL;
185
186 return ERROR_OK;
187 }
188
189 static int max32xxx_flash_op_post(struct flash_bank *bank)
190 {
191 struct target *target = bank->target;
192 struct max32xxx_flash_bank *info = bank->driver_priv;
193 uint32_t flsh_cn;
194
195 /* Restore flash programming interrupts */
196 target_write_u32(target, info->flc_base + FLSH_INT, info->int_state);
197
198 /* Lock flash */
199 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
200 flsh_cn &= ~FLSH_CN_UNLOCK_MASK;
201 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
202 return ERROR_OK;
203 }
204
205 static int max32xxx_protect_check(struct flash_bank *bank)
206 {
207 struct max32xxx_flash_bank *info = bank->driver_priv;
208 struct target *target = bank->target;
209 uint32_t temp_reg;
210
211 if (!info->probed)
212 return ERROR_FLASH_BANK_NOT_PROBED;
213
214 if (!info->max326xx) {
215 for (unsigned i = 0; i < bank->num_sectors; i++)
216 bank->sectors[i].is_protected = -1;
217
218 return ERROR_FLASH_OPER_UNSUPPORTED;
219 }
220
221 /* Check the protection */
222 for (unsigned i = 0; i < bank->num_sectors; i++) {
223 if (i%32 == 0)
224 target_read_u32(target, info->flc_base + FLSH_PROT + ((i/32)*4), &temp_reg);
225
226 if (temp_reg & (0x1 << i%32))
227 bank->sectors[i].is_protected = 1;
228 else
229 bank->sectors[i].is_protected = 0;
230 }
231 return ERROR_OK;
232 }
233
234 static int max32xxx_erase(struct flash_bank *bank, unsigned int first,
235 unsigned int last)
236 {
237 uint32_t flsh_cn, flsh_int;
238 struct max32xxx_flash_bank *info = bank->driver_priv;
239 struct target *target = bank->target;
240 int retval;
241 int retry;
242
243 if (bank->target->state != TARGET_HALTED) {
244 LOG_ERROR("Target not halted");
245 return ERROR_TARGET_NOT_HALTED;
246 }
247
248 if (!info->probed)
249 return ERROR_FLASH_BANK_NOT_PROBED;
250
251 if ((last < first) || (last >= bank->num_sectors))
252 return ERROR_FLASH_SECTOR_INVALID;
253
254 if ((first == 0) && (last == (bank->num_sectors - 1)))
255 return max32xxx_mass_erase(bank);
256
257 /* Prepare to issue flash operation */
258 retval = max32xxx_flash_op_pre(bank);
259
260 if (retval != ERROR_OK)
261 return retval;
262
263 int erased = 0;
264 for (unsigned int banknr = first; banknr <= last; banknr++) {
265
266 /* Check the protection */
267 if (bank->sectors[banknr].is_protected == 1) {
268 LOG_WARNING("Flash sector %u is protected", banknr);
269 continue;
270 } else
271 erased = 1;
272
273 /* Address is first word in page */
274 target_write_u32(target, info->flc_base + FLSH_ADDR, banknr * info->sector_size);
275
276 /* Write page erase code */
277 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
278 flsh_cn |= FLSH_CN_ERASE_CODE_PGE;
279 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
280
281 /* Issue page erase command */
282 flsh_cn |= 0x4;
283 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
284
285 /* Wait until erase complete */
286 retry = 1000;
287 do {
288 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
289 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
290
291 if (retry <= 0) {
292 LOG_ERROR("Timed out waiting for flash page erase @ 0x%08x",
293 banknr * info->sector_size);
294 return ERROR_FLASH_OPERATION_FAILED;
295 }
296
297 /* Check access violations */
298 target_read_u32(target, info->flc_base + FLSH_INT, &flsh_int);
299 if (flsh_int & FLSH_INT_AF) {
300 LOG_ERROR("Error erasing flash page %i", banknr);
301 target_write_u32(target, info->flc_base + FLSH_INT, 0);
302 max32xxx_flash_op_post(bank);
303 return ERROR_FLASH_OPERATION_FAILED;
304 }
305
306 bank->sectors[banknr].is_erased = 1;
307 }
308
309 if (!erased) {
310 LOG_ERROR("All pages protected %u to %u", first, last);
311 max32xxx_flash_op_post(bank);
312 return ERROR_FAIL;
313 }
314
315 if (max32xxx_flash_op_post(bank) != ERROR_OK)
316 return ERROR_FAIL;
317
318 return ERROR_OK;
319 }
320
321 static int max32xxx_protect(struct flash_bank *bank, int set,
322 unsigned int first, unsigned int last)
323 {
324 struct max32xxx_flash_bank *info = bank->driver_priv;
325 struct target *target = bank->target;
326 uint32_t temp_reg;
327
328 if (bank->target->state != TARGET_HALTED) {
329 LOG_ERROR("Target not halted");
330 return ERROR_TARGET_NOT_HALTED;
331 }
332
333 if (!info->probed)
334 return ERROR_FLASH_BANK_NOT_PROBED;
335
336 if (!info->max326xx)
337 return ERROR_FLASH_OPER_UNSUPPORTED;
338
339 if ((last < first) || (last >= bank->num_sectors))
340 return ERROR_FLASH_SECTOR_INVALID;
341
342 /* Setup the protection on the pages given */
343 for (unsigned int page = first; page <= last; page++) {
344 if (set) {
345 /* Set the write/erase bit for this page */
346 target_read_u32(target, info->flc_base + FLSH_PROT + (page/32), &temp_reg);
347 temp_reg |= (0x1 << page%32);
348 target_write_u32(target, info->flc_base + FLSH_PROT + (page/32), temp_reg);
349 bank->sectors[page].is_protected = 1;
350 } else {
351 /* Clear the write/erase bit for this page */
352 target_read_u32(target, info->flc_base + FLSH_PROT + (page/32), &temp_reg);
353 temp_reg &= ~(0x1 << page%32);
354 target_write_u32(target, info->flc_base + FLSH_PROT + (page/32), temp_reg);
355 bank->sectors[page].is_protected = 0;
356 }
357 }
358
359 return ERROR_OK;
360 }
361
362 static int max32xxx_write_block(struct flash_bank *bank, const uint8_t *buffer,
363 uint32_t offset, uint32_t wcount)
364 {
365 struct max32xxx_flash_bank *info = bank->driver_priv;
366 struct target *target = bank->target;
367 uint32_t buffer_size = 16384;
368 struct working_area *source;
369 struct working_area *write_algorithm;
370 uint32_t address = bank->base + offset;
371 struct reg_param reg_params[5];
372 struct armv7m_algorithm armv7m_info;
373 int retval = ERROR_OK;
374 /* power of two, and multiple of word size */
375 static const unsigned buf_min = 128;
376
377 /* for small buffers it's faster not to download an algorithm */
378 if (wcount * 4 < buf_min)
379 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
380
381 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32 " wcount=%08" PRIx32 "",
382 bank, buffer, offset, wcount);
383
384 /* flash write code */
385 if (target_alloc_working_area(target, sizeof(write_code), &write_algorithm) != ERROR_OK) {
386 LOG_DEBUG("no working area for block memory writes");
387 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
388 }
389
390 /* plus a buffer big enough for this data */
391 if (wcount * 4 < buffer_size)
392 buffer_size = wcount * 4;
393
394 /* memory buffer */
395 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
396 buffer_size /= 2;
397
398 if (buffer_size <= buf_min) {
399 target_free_working_area(target, write_algorithm);
400 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
401 }
402
403 LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
404 target_name(target), (unsigned) buffer_size);
405 }
406
407 target_write_buffer(target, write_algorithm->address, sizeof(write_code),
408 write_code);
409
410 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
411 armv7m_info.core_mode = ARM_MODE_THREAD;
412 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
413 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
414 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
415 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
416 init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT);
417
418 buf_set_u32(reg_params[0].value, 0, 32, source->address);
419 buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
420 buf_set_u32(reg_params[2].value, 0, 32, address);
421 buf_set_u32(reg_params[3].value, 0, 32, wcount);
422 buf_set_u32(reg_params[4].value, 0, 32, info->flc_base);
423 retval = target_run_flash_async_algorithm(target, buffer, wcount, 4, 0, NULL,
424 5, reg_params, source->address, source->size, write_algorithm->address, 0, &armv7m_info);
425
426 if (retval == ERROR_FLASH_OPERATION_FAILED)
427 LOG_ERROR("error %d executing max32xxx flash write algorithm", retval);
428
429 target_free_working_area(target, write_algorithm);
430 target_free_working_area(target, source);
431 destroy_reg_param(&reg_params[0]);
432 destroy_reg_param(&reg_params[1]);
433 destroy_reg_param(&reg_params[2]);
434 destroy_reg_param(&reg_params[3]);
435 destroy_reg_param(&reg_params[4]);
436 return retval;
437 }
438
439 static int max32xxx_write(struct flash_bank *bank, const uint8_t *buffer,
440 uint32_t offset, uint32_t count)
441 {
442 struct max32xxx_flash_bank *info = bank->driver_priv;
443 struct target *target = bank->target;
444 uint32_t flsh_cn, flsh_int;
445 uint32_t address = offset;
446 uint32_t remaining = count;
447 uint32_t words_remaining;
448 int retval;
449 int retry;
450
451 if (bank->target->state != TARGET_HALTED) {
452 LOG_ERROR("Target not halted");
453 return ERROR_TARGET_NOT_HALTED;
454 }
455
456 LOG_DEBUG("bank=%p buffer=%p offset=%08" PRIx32 " count=%08" PRIx32 "",
457 bank, buffer, offset, count);
458
459 if (!info->probed)
460 return ERROR_FLASH_BANK_NOT_PROBED;
461
462 if (offset & 0x3) {
463 LOG_WARNING("offset size must be word aligned");
464 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
465 }
466
467 if (offset + count > bank->size)
468 return ERROR_FLASH_DST_OUT_OF_BANK;
469
470 /* Prepare to issue flash operation */
471 retval = max32xxx_flash_op_pre(bank);
472
473 if (retval != ERROR_OK)
474 return retval;
475
476 if (remaining >= 4) {
477 /* write in 32-bit units */
478 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
479 flsh_cn &= 0xF7FFFFFF;
480 flsh_cn |= 0x00000010;
481 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
482
483 /* try using a block write */
484 words_remaining = remaining / 4;
485 retval = max32xxx_write_block(bank, buffer, offset, words_remaining);
486
487 if (retval != ERROR_OK) {
488 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
489 LOG_DEBUG("writing flash word-at-a-time");
490 else {
491 max32xxx_flash_op_post(bank);
492 return ERROR_FLASH_OPERATION_FAILED;
493 }
494 } else {
495 /* all 32-bit words have been written */
496 buffer += words_remaining * 4;
497 address += words_remaining * 4;
498 remaining -= words_remaining * 4;
499 }
500 }
501
502 if ((remaining >= 4) && ((address & 0x1F) != 0)) {
503 /* write in 32-bit units until we are 128-bit aligned */
504 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
505 flsh_cn &= 0xF7FFFFFF;
506 flsh_cn |= 0x00000010;
507 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
508
509 while ((remaining >= 4) && ((address & 0x1F) != 0)) {
510 target_write_u32(target, info->flc_base + FLSH_ADDR, address);
511 target_write_buffer(target, info->flc_base + FLSH_DATA0, 4, buffer);
512 flsh_cn |= 0x00000001;
513 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
514 /* Wait until flash operation is complete */
515 retry = 10;
516
517 do {
518 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
519 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
520
521 if (retry <= 0) {
522 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32, address);
523 return ERROR_FLASH_OPERATION_FAILED;
524 }
525
526 buffer += 4;
527 address += 4;
528 remaining -= 4;
529 }
530 }
531
532 if ((info->burst_size_bits == 128) && (remaining >= 16)) {
533 /* write in 128-bit bursts while we can */
534 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
535
536 flsh_cn &= 0xFFFFFFEF;
537 flsh_cn |= 0x08000000;
538 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
539 target_write_u32(target, info->flc_base + FLSH_ADDR, address);
540
541 while (remaining >= 16) {
542 if ((address & 0xFFF) == 0)
543 LOG_DEBUG("Writing @ 0x%08" PRIx32, address);
544
545 target_write_buffer(target, info->flc_base + FLSH_DATA0, 16, buffer);
546 flsh_cn |= 0x00000001;
547 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
548 /* Wait until flash operation is complete */
549 retry = 10;
550
551 do {
552 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
553 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
554
555 if (retry <= 0) {
556 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32, address);
557 return ERROR_FLASH_OPERATION_FAILED;
558 }
559
560 buffer += 16;
561 address += 16;
562 remaining -= 16;
563 }
564 }
565
566 if (remaining >= 4) {
567
568 /* write in 32-bit units while we can */
569 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
570 flsh_cn &= 0xF7FFFFFF;
571 flsh_cn |= 0x00000010;
572 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
573
574 while (remaining >= 4) {
575 target_write_u32(target, info->flc_base + FLSH_ADDR, address);
576 target_write_buffer(target, info->flc_base + FLSH_DATA0, 4, buffer);
577 flsh_cn |= 0x00000001;
578 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
579 /* Wait until flash operation is complete */
580 retry = 10;
581
582 do {
583 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
584 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
585
586 if (retry <= 0) {
587 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32, address);
588 return ERROR_FLASH_OPERATION_FAILED;
589 }
590
591 buffer += 4;
592 address += 4;
593 remaining -= 4;
594 }
595 }
596
597 if (remaining > 0) {
598 /* write remaining bytes in a 32-bit unit */
599 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
600 flsh_cn &= 0xF7FFFFFF;
601 flsh_cn |= 0x00000010;
602 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
603
604 uint8_t last_word[4] = {0xff, 0xff, 0xff, 0xff};
605 int i = 0;
606
607 while (remaining > 0) {
608 last_word[i++] = *buffer;
609 buffer++;
610 remaining--;
611 }
612
613 target_write_u32(target, info->flc_base + FLSH_ADDR, address);
614 target_write_buffer(target, info->flc_base + FLSH_DATA0, 4, last_word);
615 flsh_cn |= 0x00000001;
616 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
617 /* Wait until flash operation is complete */
618 retry = 10;
619
620 do {
621 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
622 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
623
624 if (retry <= 0) {
625 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32, address);
626 return ERROR_FLASH_OPERATION_FAILED;
627 }
628 }
629
630 /* Check access violations */
631 target_read_u32(target, info->flc_base + FLSH_INT, &flsh_int);
632 if (flsh_int & FLSH_INT_AF) {
633 LOG_ERROR("Flash Error writing 0x%" PRIx32 " bytes at 0x%08" PRIx32, count, offset);
634 max32xxx_flash_op_post(bank);
635 return ERROR_FLASH_OPERATION_FAILED;
636 }
637
638 if (max32xxx_flash_op_post(bank) != ERROR_OK)
639 return ERROR_FAIL;
640
641 return ERROR_OK;
642 }
643
644 static int max32xxx_probe(struct flash_bank *bank)
645 {
646 struct max32xxx_flash_bank *info = bank->driver_priv;
647 struct target *target = bank->target;
648 uint32_t arm_id[2];
649 uint16_t arm_pid;
650
651 free(bank->sectors);
652
653 /* provide this for the benefit of the NOR flash framework */
654 bank->size = info->flash_size;
655 bank->num_sectors = info->flash_size / info->sector_size;
656 bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector));
657
658 for (unsigned int i = 0; i < bank->num_sectors; i++) {
659 bank->sectors[i].offset = i * info->sector_size;
660 bank->sectors[i].size = info->sector_size;
661 bank->sectors[i].is_erased = -1;
662 bank->sectors[i].is_protected = -1;
663 }
664
665 /* Probe to determine if this part is in the max326xx family */
666 info->max326xx = 0;
667 target_read_u32(target, ARM_PID_REG, &arm_id[0]);
668 target_read_u32(target, ARM_PID_REG+4, &arm_id[1]);
669 arm_pid = (arm_id[1] << 8) + arm_id[0];
670 LOG_DEBUG("arm_pid = 0x%x", arm_pid);
671
672 if ((arm_pid == ARM_PID_DEFAULT_CM3) || arm_pid == ARM_PID_DEFAULT_CM4) {
673 uint32_t max326xx_id;
674 target_read_u32(target, MAX326XX_ID_REG, &max326xx_id);
675 LOG_DEBUG("max326xx_id = 0x%" PRIx32, max326xx_id);
676 max326xx_id = ((max326xx_id & 0xFF000000) >> 24);
677 if (max326xx_id == MAX326XX_ID)
678 info->max326xx = 1;
679 }
680 LOG_DEBUG("info->max326xx = %d", info->max326xx);
681
682 /* Initialize the protection bits for each flash page */
683 if (max32xxx_protect_check(bank) == ERROR_FLASH_OPER_UNSUPPORTED)
684 LOG_WARNING("Flash protection not supported on this device");
685
686 info->probed = true;
687 return ERROR_OK;
688 }
689
690 static int max32xxx_mass_erase(struct flash_bank *bank)
691 {
692 struct target *target = NULL;
693 struct max32xxx_flash_bank *info = NULL;
694 uint32_t flsh_cn, flsh_int;
695 int retval;
696 int retry;
697 info = bank->driver_priv;
698 target = bank->target;
699
700 if (target->state != TARGET_HALTED) {
701 LOG_ERROR("Target not halted");
702 return ERROR_TARGET_NOT_HALTED;
703 }
704
705 if (!info->probed)
706 return ERROR_FLASH_BANK_NOT_PROBED;
707
708 int not_protected = 0;
709 for (unsigned int i = 0; i < bank->num_sectors; i++) {
710 if (bank->sectors[i].is_protected == 1)
711 LOG_WARNING("Flash sector %u is protected", i);
712 else
713 not_protected = 1;
714 }
715
716 if (!not_protected) {
717 LOG_ERROR("All pages protected");
718 return ERROR_FAIL;
719 }
720
721 /* Prepare to issue flash operation */
722 retval = max32xxx_flash_op_pre(bank);
723
724 if (retval != ERROR_OK)
725 return retval;
726
727 /* Write mass erase code */
728 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
729 flsh_cn |= FLSH_CN_ERASE_CODE_ME;
730 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
731
732 /* Issue mass erase command */
733 flsh_cn |= 0x2;
734 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
735
736 /* Wait until erase complete */
737 retry = 1000;
738 do {
739 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
740 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
741
742 if (retry <= 0) {
743 LOG_ERROR("Timed out waiting for flash mass erase");
744 return ERROR_FLASH_OPERATION_FAILED;
745 }
746
747 /* Check access violations */
748 target_read_u32(target, info->flc_base + FLSH_INT, &flsh_int);
749 if (flsh_int & FLSH_INT_AF) {
750 LOG_ERROR("Error mass erasing");
751 target_write_u32(target, info->flc_base + FLSH_INT, 0);
752 return ERROR_FLASH_OPERATION_FAILED;
753 }
754
755 if (max32xxx_flash_op_post(bank) != ERROR_OK)
756 return ERROR_FAIL;
757
758 return ERROR_OK;
759 }
760
761 COMMAND_HANDLER(max32xxx_handle_mass_erase_command)
762 {
763 struct flash_bank *bank;
764 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
765
766 if (CMD_ARGC < 1) {
767 command_print(CMD, "max32xxx mass_erase <bank>");
768 return ERROR_OK;
769 }
770
771 if (ERROR_OK != retval)
772 return retval;
773
774 if (max32xxx_mass_erase(bank) == ERROR_OK) {
775 /* set all sectors as erased */
776 for (unsigned i = 0; i < bank->num_sectors; i++)
777 bank->sectors[i].is_erased = 1;
778
779 command_print(CMD, "max32xxx mass erase complete");
780 } else
781 command_print(CMD, "max32xxx mass erase failed");
782
783 return ERROR_OK;
784 }
785
786 COMMAND_HANDLER(max32xxx_handle_protection_set_command)
787 {
788 struct flash_bank *bank;
789 int retval;
790 struct max32xxx_flash_bank *info;
791 uint32_t addr, len;
792
793 if (CMD_ARGC != 3) {
794 command_print(CMD, "max32xxx protection_set <bank> <addr> <size>");
795 return ERROR_OK;
796 }
797
798 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
799 if (ERROR_OK != retval)
800 return retval;
801 info = bank->driver_priv;
802
803 /* Convert the range to the page numbers */
804 if (1 != sscanf(CMD_ARGV[1], "0x%"SCNx32, &addr)) {
805 LOG_WARNING("Error parsing address");
806 command_print(CMD, "max32xxx protection_set <bank> <addr> <size>");
807 return ERROR_FAIL;
808 }
809 /* Mask off the top portion on the address */
810 addr = (addr & 0x0FFFFFFF);
811
812 if (1 != sscanf(CMD_ARGV[2], "0x%"SCNx32, &len)) {
813 LOG_WARNING("Error parsing length");
814 command_print(CMD, "max32xxx protection_set <bank> <addr> <size>");
815 return ERROR_FAIL;
816 }
817
818 /* Check the address is in the range of the flash */
819 if ((addr+len) >= info->flash_size)
820 return ERROR_FLASH_SECTOR_INVALID;
821
822 if (len == 0)
823 return ERROR_OK;
824
825 /* Convert the address and length to the page boundaries */
826 addr = addr - (addr % info->sector_size);
827 if (len % info->sector_size)
828 len = len + info->sector_size - (len % info->sector_size);
829
830 /* Convert the address and length to page numbers */
831 addr = (addr / info->sector_size);
832 len = addr + (len / info->sector_size) - 1;
833
834 if (max32xxx_protect(bank, 1, addr, len) == ERROR_OK)
835 command_print(CMD, "max32xxx protection set complete");
836 else
837 command_print(CMD, "max32xxx protection set failed");
838
839 return ERROR_OK;
840 }
841
842 COMMAND_HANDLER(max32xxx_handle_protection_clr_command)
843 {
844 struct flash_bank *bank;
845 int retval;
846 struct max32xxx_flash_bank *info;
847 uint32_t addr, len;
848
849 if (CMD_ARGC != 3) {
850 command_print(CMD, "max32xxx protection_clr <bank> <addr> <size>");
851 return ERROR_OK;
852 }
853
854 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
855 if (ERROR_OK != retval)
856 return retval;
857 info = bank->driver_priv;
858
859 /* Convert the range to the page numbers */
860 if (1 != sscanf(CMD_ARGV[1], "0x%"SCNx32, &addr)) {
861 LOG_WARNING("Error parsing address");
862 command_print(CMD, "max32xxx protection_clr <bank> <addr> <size>");
863 return ERROR_FAIL;
864 }
865 /* Mask off the top portion on the address */
866 addr = (addr & 0x0FFFFFFF);
867
868 if (1 != sscanf(CMD_ARGV[2], "0x%"SCNx32, &len)) {
869 LOG_WARNING("Error parsing length");
870 command_print(CMD, "max32xxx protection_clr <bank> <addr> <size>");
871 return ERROR_FAIL;
872 }
873
874 /* Check the address is in the range of the flash */
875 if ((addr+len) >= info->flash_size)
876 return ERROR_FLASH_SECTOR_INVALID;
877
878 if (len == 0)
879 return ERROR_OK;
880
881 /* Convert the address and length to the page boundaries */
882 addr = addr - (addr % info->sector_size);
883 if (len % info->sector_size)
884 len = len + info->sector_size - (len % info->sector_size);
885
886 /* Convert the address and length to page numbers */
887 addr = (addr / info->sector_size);
888 len = addr + (len / info->sector_size) - 1;
889
890 if (max32xxx_protect(bank, 0, addr, len) == ERROR_OK)
891 command_print(CMD, "max32xxx protection clear complete");
892 else
893 command_print(CMD, "max32xxx protection clear failed");
894
895 return ERROR_OK;
896 }
897
898 COMMAND_HANDLER(max32xxx_handle_protection_check_command)
899 {
900 struct flash_bank *bank;
901 int retval;
902 struct max32xxx_flash_bank *info;
903
904 if (CMD_ARGC < 1) {
905 command_print(CMD, "max32xxx protection_check <bank>");
906 return ERROR_OK;
907 }
908
909 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
910 if (ERROR_OK != retval)
911 return retval;
912 info = bank->driver_priv;
913
914 /* Update the protection array */
915 retval = max32xxx_protect_check(bank);
916 if (ERROR_OK != retval) {
917 LOG_WARNING("Error updating the protection array");
918 return retval;
919 }
920
921 LOG_WARNING("s:<sector number> a:<address> p:<protection bit>");
922 for (unsigned i = 0; i < bank->num_sectors; i += 4) {
923 LOG_WARNING("s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d | s:%03d a:0x%06x p:%d",
924 (i+0), (i+0)*info->sector_size, bank->sectors[(i+0)].is_protected,
925 (i+1), (i+1)*info->sector_size, bank->sectors[(i+1)].is_protected,
926 (i+2), (i+2)*info->sector_size, bank->sectors[(i+2)].is_protected,
927 (i+3), (i+3)*info->sector_size, bank->sectors[(i+3)].is_protected);
928 }
929
930 return ERROR_OK;
931 }
932
933 static const struct command_registration max32xxx_exec_command_handlers[] = {
934 {
935 .name = "mass_erase",
936 .handler = max32xxx_handle_mass_erase_command,
937 .mode = COMMAND_EXEC,
938 .usage = "bank_id",
939 .help = "mass erase flash",
940 },
941 {
942 .name = "protection_set",
943 .handler = max32xxx_handle_protection_set_command,
944 .mode = COMMAND_EXEC,
945 .usage = "bank_id addr size",
946 .help = "set flash protection for address range",
947 },
948 {
949 .name = "protection_clr",
950 .handler = max32xxx_handle_protection_clr_command,
951 .mode = COMMAND_EXEC,
952 .usage = "bank_id addr size",
953 .help = "clear flash protection for address range",
954 },
955 {
956 .name = "protection_check",
957 .handler = max32xxx_handle_protection_check_command,
958 .mode = COMMAND_EXEC,
959 .usage = "bank_id",
960 .help = "check flash protection",
961 },
962 COMMAND_REGISTRATION_DONE
963 };
964
965 static const struct command_registration max32xxx_command_handlers[] = {
966 {
967 .name = "max32xxx",
968 .mode = COMMAND_EXEC,
969 .help = "max32xxx flash command group",
970 .chain = max32xxx_exec_command_handlers,
971 .usage = "",
972 },
973 COMMAND_REGISTRATION_DONE
974 };
975
976 const struct flash_driver max32xxx_flash = {
977 .name = "max32xxx",
978 .commands = max32xxx_command_handlers,
979 .flash_bank_command = max32xxx_flash_bank_command,
980 .erase = max32xxx_erase,
981 .protect = max32xxx_protect,
982 .write = max32xxx_write,
983 .read = default_flash_read,
984 .probe = max32xxx_probe,
985 .auto_probe = max32xxx_probe,
986 .erase_check = default_flash_blank_check,
987 .protect_check = max32xxx_protect_check,
988 .info = get_info,
989 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)