flash/stm32l4x: fix dual bank support for STM32L552xC devices
[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
307 if (!erased) {
308 LOG_ERROR("All pages protected %u to %u", first, last);
309 max32xxx_flash_op_post(bank);
310 return ERROR_FAIL;
311 }
312
313 if (max32xxx_flash_op_post(bank) != ERROR_OK)
314 return ERROR_FAIL;
315
316 return ERROR_OK;
317 }
318
319 static int max32xxx_protect(struct flash_bank *bank, int set,
320 unsigned int first, unsigned int last)
321 {
322 struct max32xxx_flash_bank *info = bank->driver_priv;
323 struct target *target = bank->target;
324 uint32_t temp_reg;
325
326 if (bank->target->state != TARGET_HALTED) {
327 LOG_ERROR("Target not halted");
328 return ERROR_TARGET_NOT_HALTED;
329 }
330
331 if (!info->probed)
332 return ERROR_FLASH_BANK_NOT_PROBED;
333
334 if (!info->max326xx)
335 return ERROR_FLASH_OPER_UNSUPPORTED;
336
337 if ((last < first) || (last >= bank->num_sectors))
338 return ERROR_FLASH_SECTOR_INVALID;
339
340 /* Setup the protection on the pages given */
341 for (unsigned int page = first; page <= last; page++) {
342 if (set) {
343 /* Set the write/erase bit for this page */
344 target_read_u32(target, info->flc_base + FLSH_PROT + (page/32), &temp_reg);
345 temp_reg |= (0x1 << page%32);
346 target_write_u32(target, info->flc_base + FLSH_PROT + (page/32), temp_reg);
347 bank->sectors[page].is_protected = 1;
348 } else {
349 /* Clear the write/erase bit for this page */
350 target_read_u32(target, info->flc_base + FLSH_PROT + (page/32), &temp_reg);
351 temp_reg &= ~(0x1 << page%32);
352 target_write_u32(target, info->flc_base + FLSH_PROT + (page/32), temp_reg);
353 bank->sectors[page].is_protected = 0;
354 }
355 }
356
357 return ERROR_OK;
358 }
359
360 static int max32xxx_write_block(struct flash_bank *bank, const uint8_t *buffer,
361 uint32_t offset, uint32_t wcount)
362 {
363 struct max32xxx_flash_bank *info = bank->driver_priv;
364 struct target *target = bank->target;
365 uint32_t buffer_size = 16384;
366 struct working_area *source;
367 struct working_area *write_algorithm;
368 uint32_t address = bank->base + offset;
369 struct reg_param reg_params[5];
370 struct armv7m_algorithm armv7m_info;
371 int retval = ERROR_OK;
372 /* power of two, and multiple of word size */
373 static const unsigned buf_min = 128;
374
375 /* for small buffers it's faster not to download an algorithm */
376 if (wcount * 4 < buf_min)
377 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
378
379 LOG_DEBUG("(bank=%p buffer=%p offset=%08" PRIx32 " wcount=%08" PRIx32 "",
380 bank, buffer, offset, wcount);
381
382 /* flash write code */
383 if (target_alloc_working_area(target, sizeof(write_code), &write_algorithm) != ERROR_OK) {
384 LOG_DEBUG("no working area for block memory writes");
385 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
386 }
387
388 /* plus a buffer big enough for this data */
389 if (wcount * 4 < buffer_size)
390 buffer_size = wcount * 4;
391
392 /* memory buffer */
393 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
394 buffer_size /= 2;
395
396 if (buffer_size <= buf_min) {
397 target_free_working_area(target, write_algorithm);
398 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
399 }
400
401 LOG_DEBUG("retry target_alloc_working_area(%s, size=%u)",
402 target_name(target), (unsigned) buffer_size);
403 }
404
405 target_write_buffer(target, write_algorithm->address, sizeof(write_code),
406 write_code);
407
408 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
409 armv7m_info.core_mode = ARM_MODE_THREAD;
410 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
411 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
412 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
413 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
414 init_reg_param(&reg_params[4], "r4", 32, PARAM_OUT);
415
416 buf_set_u32(reg_params[0].value, 0, 32, source->address);
417 buf_set_u32(reg_params[1].value, 0, 32, source->address + source->size);
418 buf_set_u32(reg_params[2].value, 0, 32, address);
419 buf_set_u32(reg_params[3].value, 0, 32, wcount);
420 buf_set_u32(reg_params[4].value, 0, 32, info->flc_base);
421 retval = target_run_flash_async_algorithm(target, buffer, wcount, 4, 0, NULL,
422 5, reg_params, source->address, source->size, write_algorithm->address, 0, &armv7m_info);
423
424 if (retval == ERROR_FLASH_OPERATION_FAILED)
425 LOG_ERROR("error %d executing max32xxx flash write algorithm", retval);
426
427 target_free_working_area(target, write_algorithm);
428 target_free_working_area(target, source);
429 destroy_reg_param(&reg_params[0]);
430 destroy_reg_param(&reg_params[1]);
431 destroy_reg_param(&reg_params[2]);
432 destroy_reg_param(&reg_params[3]);
433 destroy_reg_param(&reg_params[4]);
434 return retval;
435 }
436
437 static int max32xxx_write(struct flash_bank *bank, const uint8_t *buffer,
438 uint32_t offset, uint32_t count)
439 {
440 struct max32xxx_flash_bank *info = bank->driver_priv;
441 struct target *target = bank->target;
442 uint32_t flsh_cn, flsh_int;
443 uint32_t address = offset;
444 uint32_t remaining = count;
445 uint32_t words_remaining;
446 int retval;
447 int retry;
448
449 if (bank->target->state != TARGET_HALTED) {
450 LOG_ERROR("Target not halted");
451 return ERROR_TARGET_NOT_HALTED;
452 }
453
454 LOG_DEBUG("bank=%p buffer=%p offset=%08" PRIx32 " count=%08" PRIx32 "",
455 bank, buffer, offset, count);
456
457 if (!info->probed)
458 return ERROR_FLASH_BANK_NOT_PROBED;
459
460 if (offset & 0x3) {
461 LOG_WARNING("offset size must be word aligned");
462 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
463 }
464
465 if (offset + count > bank->size)
466 return ERROR_FLASH_DST_OUT_OF_BANK;
467
468 /* Prepare to issue flash operation */
469 retval = max32xxx_flash_op_pre(bank);
470
471 if (retval != ERROR_OK)
472 return retval;
473
474 if (remaining >= 4) {
475 /* write in 32-bit units */
476 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
477 flsh_cn &= 0xF7FFFFFF;
478 flsh_cn |= 0x00000010;
479 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
480
481 /* try using a block write */
482 words_remaining = remaining / 4;
483 retval = max32xxx_write_block(bank, buffer, offset, words_remaining);
484
485 if (retval != ERROR_OK) {
486 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
487 LOG_DEBUG("writing flash word-at-a-time");
488 else {
489 max32xxx_flash_op_post(bank);
490 return ERROR_FLASH_OPERATION_FAILED;
491 }
492 } else {
493 /* all 32-bit words have been written */
494 buffer += words_remaining * 4;
495 address += words_remaining * 4;
496 remaining -= words_remaining * 4;
497 }
498 }
499
500 if ((remaining >= 4) && ((address & 0x1F) != 0)) {
501 /* write in 32-bit units until we are 128-bit aligned */
502 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
503 flsh_cn &= 0xF7FFFFFF;
504 flsh_cn |= 0x00000010;
505 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
506
507 while ((remaining >= 4) && ((address & 0x1F) != 0)) {
508 target_write_u32(target, info->flc_base + FLSH_ADDR, address);
509 target_write_buffer(target, info->flc_base + FLSH_DATA0, 4, buffer);
510 flsh_cn |= 0x00000001;
511 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
512 /* Wait until flash operation is complete */
513 retry = 10;
514
515 do {
516 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
517 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
518
519 if (retry <= 0) {
520 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32, address);
521 return ERROR_FLASH_OPERATION_FAILED;
522 }
523
524 buffer += 4;
525 address += 4;
526 remaining -= 4;
527 }
528 }
529
530 if ((info->burst_size_bits == 128) && (remaining >= 16)) {
531 /* write in 128-bit bursts while we can */
532 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
533
534 flsh_cn &= 0xFFFFFFEF;
535 flsh_cn |= 0x08000000;
536 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
537 target_write_u32(target, info->flc_base + FLSH_ADDR, address);
538
539 while (remaining >= 16) {
540 if ((address & 0xFFF) == 0)
541 LOG_DEBUG("Writing @ 0x%08" PRIx32, address);
542
543 target_write_buffer(target, info->flc_base + FLSH_DATA0, 16, buffer);
544 flsh_cn |= 0x00000001;
545 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
546 /* Wait until flash operation is complete */
547 retry = 10;
548
549 do {
550 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
551 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
552
553 if (retry <= 0) {
554 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32, address);
555 return ERROR_FLASH_OPERATION_FAILED;
556 }
557
558 buffer += 16;
559 address += 16;
560 remaining -= 16;
561 }
562 }
563
564 if (remaining >= 4) {
565
566 /* write in 32-bit units while we can */
567 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
568 flsh_cn &= 0xF7FFFFFF;
569 flsh_cn |= 0x00000010;
570 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
571
572 while (remaining >= 4) {
573 target_write_u32(target, info->flc_base + FLSH_ADDR, address);
574 target_write_buffer(target, info->flc_base + FLSH_DATA0, 4, buffer);
575 flsh_cn |= 0x00000001;
576 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
577 /* Wait until flash operation is complete */
578 retry = 10;
579
580 do {
581 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
582 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
583
584 if (retry <= 0) {
585 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32, address);
586 return ERROR_FLASH_OPERATION_FAILED;
587 }
588
589 buffer += 4;
590 address += 4;
591 remaining -= 4;
592 }
593 }
594
595 if (remaining > 0) {
596 /* write remaining bytes in a 32-bit unit */
597 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
598 flsh_cn &= 0xF7FFFFFF;
599 flsh_cn |= 0x00000010;
600 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
601
602 uint8_t last_word[4] = {0xff, 0xff, 0xff, 0xff};
603 int i = 0;
604
605 while (remaining > 0) {
606 last_word[i++] = *buffer;
607 buffer++;
608 remaining--;
609 }
610
611 target_write_u32(target, info->flc_base + FLSH_ADDR, address);
612 target_write_buffer(target, info->flc_base + FLSH_DATA0, 4, last_word);
613 flsh_cn |= 0x00000001;
614 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
615 /* Wait until flash operation is complete */
616 retry = 10;
617
618 do {
619 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
620 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
621
622 if (retry <= 0) {
623 LOG_ERROR("Timed out waiting for flash write @ 0x%08" PRIx32, address);
624 return ERROR_FLASH_OPERATION_FAILED;
625 }
626 }
627
628 /* Check access violations */
629 target_read_u32(target, info->flc_base + FLSH_INT, &flsh_int);
630 if (flsh_int & FLSH_INT_AF) {
631 LOG_ERROR("Flash Error writing 0x%" PRIx32 " bytes at 0x%08" PRIx32, count, offset);
632 max32xxx_flash_op_post(bank);
633 return ERROR_FLASH_OPERATION_FAILED;
634 }
635
636 if (max32xxx_flash_op_post(bank) != ERROR_OK)
637 return ERROR_FAIL;
638
639 return ERROR_OK;
640 }
641
642 static int max32xxx_probe(struct flash_bank *bank)
643 {
644 struct max32xxx_flash_bank *info = bank->driver_priv;
645 struct target *target = bank->target;
646 uint32_t arm_id[2];
647 uint16_t arm_pid;
648
649 free(bank->sectors);
650
651 /* provide this for the benefit of the NOR flash framework */
652 bank->size = info->flash_size;
653 bank->num_sectors = info->flash_size / info->sector_size;
654 bank->sectors = calloc(bank->num_sectors, sizeof(struct flash_sector));
655
656 for (unsigned int i = 0; i < bank->num_sectors; i++) {
657 bank->sectors[i].offset = i * info->sector_size;
658 bank->sectors[i].size = info->sector_size;
659 bank->sectors[i].is_erased = -1;
660 bank->sectors[i].is_protected = -1;
661 }
662
663 /* Probe to determine if this part is in the max326xx family */
664 info->max326xx = 0;
665 target_read_u32(target, ARM_PID_REG, &arm_id[0]);
666 target_read_u32(target, ARM_PID_REG+4, &arm_id[1]);
667 arm_pid = (arm_id[1] << 8) + arm_id[0];
668 LOG_DEBUG("arm_pid = 0x%x", arm_pid);
669
670 if ((arm_pid == ARM_PID_DEFAULT_CM3) || arm_pid == ARM_PID_DEFAULT_CM4) {
671 uint32_t max326xx_id;
672 target_read_u32(target, MAX326XX_ID_REG, &max326xx_id);
673 LOG_DEBUG("max326xx_id = 0x%" PRIx32, max326xx_id);
674 max326xx_id = ((max326xx_id & 0xFF000000) >> 24);
675 if (max326xx_id == MAX326XX_ID)
676 info->max326xx = 1;
677 }
678 LOG_DEBUG("info->max326xx = %d", info->max326xx);
679
680 /* Initialize the protection bits for each flash page */
681 if (max32xxx_protect_check(bank) == ERROR_FLASH_OPER_UNSUPPORTED)
682 LOG_WARNING("Flash protection not supported on this device");
683
684 info->probed = true;
685 return ERROR_OK;
686 }
687
688 static int max32xxx_mass_erase(struct flash_bank *bank)
689 {
690 struct target *target = NULL;
691 struct max32xxx_flash_bank *info = NULL;
692 uint32_t flsh_cn, flsh_int;
693 int retval;
694 int retry;
695 info = bank->driver_priv;
696 target = bank->target;
697
698 if (target->state != TARGET_HALTED) {
699 LOG_ERROR("Target not halted");
700 return ERROR_TARGET_NOT_HALTED;
701 }
702
703 if (!info->probed)
704 return ERROR_FLASH_BANK_NOT_PROBED;
705
706 int not_protected = 0;
707 for (unsigned int i = 0; i < bank->num_sectors; i++) {
708 if (bank->sectors[i].is_protected == 1)
709 LOG_WARNING("Flash sector %u is protected", i);
710 else
711 not_protected = 1;
712 }
713
714 if (!not_protected) {
715 LOG_ERROR("All pages protected");
716 return ERROR_FAIL;
717 }
718
719 /* Prepare to issue flash operation */
720 retval = max32xxx_flash_op_pre(bank);
721
722 if (retval != ERROR_OK)
723 return retval;
724
725 /* Write mass erase code */
726 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
727 flsh_cn |= FLSH_CN_ERASE_CODE_ME;
728 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
729
730 /* Issue mass erase command */
731 flsh_cn |= 0x2;
732 target_write_u32(target, info->flc_base + FLSH_CN, flsh_cn);
733
734 /* Wait until erase complete */
735 retry = 1000;
736 do {
737 target_read_u32(target, info->flc_base + FLSH_CN, &flsh_cn);
738 } while ((--retry > 0) && (flsh_cn & FLSH_CN_PEND));
739
740 if (retry <= 0) {
741 LOG_ERROR("Timed out waiting for flash mass erase");
742 return ERROR_FLASH_OPERATION_FAILED;
743 }
744
745 /* Check access violations */
746 target_read_u32(target, info->flc_base + FLSH_INT, &flsh_int);
747 if (flsh_int & FLSH_INT_AF) {
748 LOG_ERROR("Error mass erasing");
749 target_write_u32(target, info->flc_base + FLSH_INT, 0);
750 return ERROR_FLASH_OPERATION_FAILED;
751 }
752
753 if (max32xxx_flash_op_post(bank) != ERROR_OK)
754 return ERROR_FAIL;
755
756 return ERROR_OK;
757 }
758
759 COMMAND_HANDLER(max32xxx_handle_mass_erase_command)
760 {
761 struct flash_bank *bank;
762 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
763
764 if (CMD_ARGC < 1) {
765 command_print(CMD, "max32xxx mass_erase <bank>");
766 return ERROR_OK;
767 }
768
769 if (retval != ERROR_OK)
770 return retval;
771
772 if (max32xxx_mass_erase(bank) == ERROR_OK)
773 command_print(CMD, "max32xxx mass erase complete");
774 else
775 command_print(CMD, "max32xxx mass erase failed");
776
777 return ERROR_OK;
778 }
779
780 COMMAND_HANDLER(max32xxx_handle_protection_set_command)
781 {
782 struct flash_bank *bank;
783 int retval;
784 struct max32xxx_flash_bank *info;
785 uint32_t addr, len;
786
787 if (CMD_ARGC != 3) {
788 command_print(CMD, "max32xxx protection_set <bank> <addr> <size>");
789 return ERROR_OK;
790 }
791
792 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
793 if (retval != ERROR_OK)
794 return retval;
795 info = bank->driver_priv;
796
797 /* Convert the range to the page numbers */
798 if (sscanf(CMD_ARGV[1], "0x%"SCNx32, &addr) != 1) {
799 LOG_WARNING("Error parsing address");
800 command_print(CMD, "max32xxx protection_set <bank> <addr> <size>");
801 return ERROR_FAIL;
802 }
803 /* Mask off the top portion on the address */
804 addr = (addr & 0x0FFFFFFF);
805
806 if (sscanf(CMD_ARGV[2], "0x%"SCNx32, &len) != 1) {
807 LOG_WARNING("Error parsing length");
808 command_print(CMD, "max32xxx protection_set <bank> <addr> <size>");
809 return ERROR_FAIL;
810 }
811
812 /* Check the address is in the range of the flash */
813 if ((addr+len) >= info->flash_size)
814 return ERROR_FLASH_SECTOR_INVALID;
815
816 if (len == 0)
817 return ERROR_OK;
818
819 /* Convert the address and length to the page boundaries */
820 addr = addr - (addr % info->sector_size);
821 if (len % info->sector_size)
822 len = len + info->sector_size - (len % info->sector_size);
823
824 /* Convert the address and length to page numbers */
825 addr = (addr / info->sector_size);
826 len = addr + (len / info->sector_size) - 1;
827
828 if (max32xxx_protect(bank, 1, addr, len) == ERROR_OK)
829 command_print(CMD, "max32xxx protection set complete");
830 else
831 command_print(CMD, "max32xxx protection set failed");
832
833 return ERROR_OK;
834 }
835
836 COMMAND_HANDLER(max32xxx_handle_protection_clr_command)
837 {
838 struct flash_bank *bank;
839 int retval;
840 struct max32xxx_flash_bank *info;
841 uint32_t addr, len;
842
843 if (CMD_ARGC != 3) {
844 command_print(CMD, "max32xxx protection_clr <bank> <addr> <size>");
845 return ERROR_OK;
846 }
847
848 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
849 if (retval != ERROR_OK)
850 return retval;
851 info = bank->driver_priv;
852
853 /* Convert the range to the page numbers */
854 if (sscanf(CMD_ARGV[1], "0x%"SCNx32, &addr) != 1) {
855 LOG_WARNING("Error parsing address");
856 command_print(CMD, "max32xxx protection_clr <bank> <addr> <size>");
857 return ERROR_FAIL;
858 }
859 /* Mask off the top portion on the address */
860 addr = (addr & 0x0FFFFFFF);
861
862 if (sscanf(CMD_ARGV[2], "0x%"SCNx32, &len) != 1) {
863 LOG_WARNING("Error parsing length");
864 command_print(CMD, "max32xxx protection_clr <bank> <addr> <size>");
865 return ERROR_FAIL;
866 }
867
868 /* Check the address is in the range of the flash */
869 if ((addr+len) >= info->flash_size)
870 return ERROR_FLASH_SECTOR_INVALID;
871
872 if (len == 0)
873 return ERROR_OK;
874
875 /* Convert the address and length to the page boundaries */
876 addr = addr - (addr % info->sector_size);
877 if (len % info->sector_size)
878 len = len + info->sector_size - (len % info->sector_size);
879
880 /* Convert the address and length to page numbers */
881 addr = (addr / info->sector_size);
882 len = addr + (len / info->sector_size) - 1;
883
884 if (max32xxx_protect(bank, 0, addr, len) == ERROR_OK)
885 command_print(CMD, "max32xxx protection clear complete");
886 else
887 command_print(CMD, "max32xxx protection clear failed");
888
889 return ERROR_OK;
890 }
891
892 COMMAND_HANDLER(max32xxx_handle_protection_check_command)
893 {
894 struct flash_bank *bank;
895 int retval;
896 struct max32xxx_flash_bank *info;
897
898 if (CMD_ARGC < 1) {
899 command_print(CMD, "max32xxx protection_check <bank>");
900 return ERROR_OK;
901 }
902
903 retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
904 if (retval != ERROR_OK)
905 return retval;
906 info = bank->driver_priv;
907
908 /* Update the protection array */
909 retval = max32xxx_protect_check(bank);
910 if (retval != ERROR_OK) {
911 LOG_WARNING("Error updating the protection array");
912 return retval;
913 }
914
915 LOG_WARNING("s:<sector number> a:<address> p:<protection bit>");
916 for (unsigned i = 0; i < bank->num_sectors; i += 4) {
917 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",
918 (i+0), (i+0)*info->sector_size, bank->sectors[(i+0)].is_protected,
919 (i+1), (i+1)*info->sector_size, bank->sectors[(i+1)].is_protected,
920 (i+2), (i+2)*info->sector_size, bank->sectors[(i+2)].is_protected,
921 (i+3), (i+3)*info->sector_size, bank->sectors[(i+3)].is_protected);
922 }
923
924 return ERROR_OK;
925 }
926
927 static const struct command_registration max32xxx_exec_command_handlers[] = {
928 {
929 .name = "mass_erase",
930 .handler = max32xxx_handle_mass_erase_command,
931 .mode = COMMAND_EXEC,
932 .usage = "bank_id",
933 .help = "mass erase flash",
934 },
935 {
936 .name = "protection_set",
937 .handler = max32xxx_handle_protection_set_command,
938 .mode = COMMAND_EXEC,
939 .usage = "bank_id addr size",
940 .help = "set flash protection for address range",
941 },
942 {
943 .name = "protection_clr",
944 .handler = max32xxx_handle_protection_clr_command,
945 .mode = COMMAND_EXEC,
946 .usage = "bank_id addr size",
947 .help = "clear flash protection for address range",
948 },
949 {
950 .name = "protection_check",
951 .handler = max32xxx_handle_protection_check_command,
952 .mode = COMMAND_EXEC,
953 .usage = "bank_id",
954 .help = "check flash protection",
955 },
956 COMMAND_REGISTRATION_DONE
957 };
958
959 static const struct command_registration max32xxx_command_handlers[] = {
960 {
961 .name = "max32xxx",
962 .mode = COMMAND_EXEC,
963 .help = "max32xxx flash command group",
964 .chain = max32xxx_exec_command_handlers,
965 .usage = "",
966 },
967 COMMAND_REGISTRATION_DONE
968 };
969
970 const struct flash_driver max32xxx_flash = {
971 .name = "max32xxx",
972 .commands = max32xxx_command_handlers,
973 .flash_bank_command = max32xxx_flash_bank_command,
974 .erase = max32xxx_erase,
975 .protect = max32xxx_protect,
976 .write = max32xxx_write,
977 .read = default_flash_read,
978 .probe = max32xxx_probe,
979 .auto_probe = max32xxx_probe,
980 .erase_check = default_flash_blank_check,
981 .protect_check = max32xxx_protect_check,
982 .info = get_info,
983 };

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)