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

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)