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

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)