3d523413cdad2ebe5bd53dc165b6db130024ad3d
[openocd.git] / src / flash / nor / str7x.c
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
8 * Copyright (C) 2010 Øyvind Harboe *
9 * oyvind.harboe@zylin.com *
10 * *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
15 * *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
20 * *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
26 #ifdef HAVE_CONFIG_H
27 #include "config.h"
28 #endif
29
30 #include "imp.h"
31 #include "str7x.h"
32 #include <target/arm.h>
33 #include <helper/binarybuffer.h>
34 #include <target/algorithm.h>
35
36
37 static struct str7x_mem_layout mem_layout_str7bank0[] = {
38 {0x00000000, 0x02000, 0x01},
39 {0x00002000, 0x02000, 0x02},
40 {0x00004000, 0x02000, 0x04},
41 {0x00006000, 0x02000, 0x08},
42 {0x00008000, 0x08000, 0x10},
43 {0x00010000, 0x10000, 0x20},
44 {0x00020000, 0x10000, 0x40},
45 {0x00030000, 0x10000, 0x80}
46 };
47
48 static struct str7x_mem_layout mem_layout_str7bank1[] = {
49 {0x00000000, 0x02000, 0x10000},
50 {0x00002000, 0x02000, 0x20000}
51 };
52
53 static int str7x_get_flash_adr(struct flash_bank *bank, uint32_t reg)
54 {
55 struct str7x_flash_bank *str7x_info = bank->driver_priv;
56 return (str7x_info->register_base | reg);
57 }
58
59 static int str7x_build_block_list(struct flash_bank *bank)
60 {
61 struct str7x_flash_bank *str7x_info = bank->driver_priv;
62
63 int i;
64 int num_sectors;
65 int b0_sectors = 0, b1_sectors = 0;
66
67 switch (bank->size)
68 {
69 case 16 * 1024:
70 b1_sectors = 2;
71 break;
72 case 64 * 1024:
73 b0_sectors = 5;
74 break;
75 case 128 * 1024:
76 b0_sectors = 6;
77 break;
78 case 256 * 1024:
79 b0_sectors = 8;
80 break;
81 default:
82 LOG_ERROR("BUG: unknown bank->size encountered");
83 exit(-1);
84 }
85
86 num_sectors = b0_sectors + b1_sectors;
87
88 bank->num_sectors = num_sectors;
89 bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
90 str7x_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
91
92 num_sectors = 0;
93
94 for (i = 0; i < b0_sectors; i++)
95 {
96 bank->sectors[num_sectors].offset = mem_layout_str7bank0[i].sector_start;
97 bank->sectors[num_sectors].size = mem_layout_str7bank0[i].sector_size;
98 bank->sectors[num_sectors].is_erased = -1;
99 /* the reset_init handler marks all the sectors unprotected,
100 * matching hardware after reset; keep the driver in sync
101 */
102 bank->sectors[num_sectors].is_protected = 0;
103 str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank0[i].sector_bit;
104 }
105
106 for (i = 0; i < b1_sectors; i++)
107 {
108 bank->sectors[num_sectors].offset = mem_layout_str7bank1[i].sector_start;
109 bank->sectors[num_sectors].size = mem_layout_str7bank1[i].sector_size;
110 bank->sectors[num_sectors].is_erased = -1;
111 /* the reset_init handler marks all the sectors unprotected,
112 * matching hardware after reset; keep the driver in sync
113 */
114 bank->sectors[num_sectors].is_protected = 0;
115 str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank1[i].sector_bit;
116 }
117
118 return ERROR_OK;
119 }
120
121 /* flash bank str7x <base> <size> 0 0 <target#> <str71_variant>
122 */
123 FLASH_BANK_COMMAND_HANDLER(str7x_flash_bank_command)
124 {
125 struct str7x_flash_bank *str7x_info;
126
127 if (CMD_ARGC < 7)
128 {
129 LOG_WARNING("incomplete flash_bank str7x configuration");
130 return ERROR_FLASH_BANK_INVALID;
131 }
132
133 str7x_info = malloc(sizeof(struct str7x_flash_bank));
134 bank->driver_priv = str7x_info;
135
136 /* set default bits for str71x flash */
137 str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA1 | FLASH_BSYA0);
138 str7x_info->disable_bit = (1 << 1);
139
140 if (strcmp(CMD_ARGV[6], "STR71x") == 0)
141 {
142 str7x_info->register_base = 0x40100000;
143 }
144 else if (strcmp(CMD_ARGV[6], "STR73x") == 0)
145 {
146 str7x_info->register_base = 0x80100000;
147 str7x_info->busy_bits = (FLASH_LOCK | FLASH_BSYA0);
148 }
149 else if (strcmp(CMD_ARGV[6], "STR75x") == 0)
150 {
151 str7x_info->register_base = 0x20100000;
152 str7x_info->disable_bit = (1 << 0);
153 }
154 else
155 {
156 LOG_ERROR("unknown STR7x variant: '%s'", CMD_ARGV[6]);
157 free(str7x_info);
158 return ERROR_FLASH_BANK_INVALID;
159 }
160
161 str7x_build_block_list(bank);
162
163 str7x_info->write_algorithm = NULL;
164
165 return ERROR_OK;
166 }
167
168 /* wait for flash to become idle or report errors.
169
170 FIX!!! what's the maximum timeout??? The documentation doesn't
171 state any maximum time.... by inspection it seems > 1000ms is to be
172 expected.
173
174 10000ms is long enough that it should cover anything, yet not
175 quite be equivalent to an infinite loop.
176
177 */
178 static int str7x_waitbusy(struct flash_bank *bank)
179 {
180 int err;
181 int i;
182 struct target *target = bank->target;
183 struct str7x_flash_bank *str7x_info = bank->driver_priv;
184
185 for (i = 0 ; i < 10000; i++)
186 {
187 uint32_t retval;
188 err = target_read_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), &retval);
189 if (err != ERROR_OK)
190 return err;
191
192 if ((retval & str7x_info->busy_bits) == 0)
193 return ERROR_OK;
194
195 alive_sleep(1);
196 }
197 LOG_ERROR("Timed out waiting for str7x flash");
198 return ERROR_FAIL;
199 }
200
201
202 static int str7x_result(struct flash_bank *bank)
203 {
204 struct target *target = bank->target;
205 uint32_t retval;
206
207 int err;
208 err = target_read_u32(target, str7x_get_flash_adr(bank, FLASH_ER), &retval);
209 if (err != ERROR_OK)
210 return err;
211
212 if (retval & FLASH_WPF)
213 {
214 LOG_ERROR("str7x hw write protection set");
215 err = ERROR_FAIL;
216 }
217 if (retval & FLASH_RESER)
218 {
219 LOG_ERROR("str7x suspended program erase not resumed");
220 err = ERROR_FAIL;
221 }
222 if (retval & FLASH_10ER)
223 {
224 LOG_ERROR("str7x trying to set bit to 1 when it is already 0");
225 err = ERROR_FAIL;
226 }
227 if (retval & FLASH_PGER)
228 {
229 LOG_ERROR("str7x program error");
230 err = ERROR_FAIL;
231 }
232 if (retval & FLASH_ERER)
233 {
234 LOG_ERROR("str7x erase error");
235 err = ERROR_FAIL;
236 }
237 if (err == ERROR_OK)
238 {
239 if (retval & FLASH_ERR)
240 {
241 /* this should always be set if one of the others are set... */
242 LOG_ERROR("str7x write operation failed / bad setup");
243 err = ERROR_FAIL;
244 }
245 }
246 if (err != ERROR_OK)
247 {
248 LOG_ERROR("FLASH_ER register contents: 0x%" PRIx32, retval);
249 }
250
251 return retval;
252 }
253
254 static int str7x_protect_check(struct flash_bank *bank)
255 {
256 struct str7x_flash_bank *str7x_info = bank->driver_priv;
257 struct target *target = bank->target;
258
259 int i;
260 uint32_t retval;
261
262 if (bank->target->state != TARGET_HALTED)
263 {
264 LOG_ERROR("Target not halted");
265 return ERROR_TARGET_NOT_HALTED;
266 }
267
268 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVWPAR), &retval);
269
270 for (i = 0; i < bank->num_sectors; i++)
271 {
272 if (retval & str7x_info->sector_bits[i])
273 bank->sectors[i].is_protected = 0;
274 else
275 bank->sectors[i].is_protected = 1;
276 }
277
278 return ERROR_OK;
279 }
280
281 static int str7x_erase(struct flash_bank *bank, int first, int last)
282 {
283 struct str7x_flash_bank *str7x_info = bank->driver_priv;
284 struct target *target = bank->target;
285
286 int i;
287 uint32_t cmd;
288 uint32_t sectors = 0;
289 int err;
290
291 if (bank->target->state != TARGET_HALTED)
292 {
293 LOG_ERROR("Target not halted");
294 return ERROR_TARGET_NOT_HALTED;
295 }
296
297 for (i = first; i <= last; i++)
298 {
299 sectors |= str7x_info->sector_bits[i];
300 }
301
302 LOG_DEBUG("sectors: 0x%" PRIx32 "", sectors);
303
304 /* clear FLASH_ER register */
305 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
306 if (err != ERROR_OK)
307 return err;
308
309 cmd = FLASH_SER;
310 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
311 if (err != ERROR_OK)
312 return err;
313
314 cmd = sectors;
315 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);
316 if (err != ERROR_OK)
317 return err;
318
319 cmd = FLASH_SER | FLASH_WMS;
320 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
321 if (err != ERROR_OK)
322 return err;
323
324 err = str7x_waitbusy(bank);
325 if (err != ERROR_OK)
326 return err;
327
328 err = str7x_result(bank);
329 if (err != ERROR_OK)
330 return err;
331
332 for (i = first; i <= last; i++)
333 bank->sectors[i].is_erased = 1;
334
335 return ERROR_OK;
336 }
337
338 static int str7x_protect(struct flash_bank *bank, int set, int first, int last)
339 {
340 struct str7x_flash_bank *str7x_info = bank->driver_priv;
341 struct target *target = bank->target;
342 int i;
343 uint32_t cmd;
344 uint32_t protect_blocks;
345
346 if (bank->target->state != TARGET_HALTED)
347 {
348 LOG_ERROR("Target not halted");
349 return ERROR_TARGET_NOT_HALTED;
350 }
351
352 protect_blocks = 0xFFFFFFFF;
353
354 if (set)
355 {
356 for (i = first; i <= last; i++)
357 protect_blocks &= ~(str7x_info->sector_bits[i]);
358 }
359
360 /* clear FLASH_ER register */
361 int err;
362 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
363 if (err != ERROR_OK)
364 return err;
365
366 cmd = FLASH_SPR;
367 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
368 if (err != ERROR_OK)
369 return err;
370
371 cmd = str7x_get_flash_adr(bank, FLASH_NVWPAR);
372 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), cmd);
373 if (err != ERROR_OK)
374 return err;
375
376 cmd = protect_blocks;
377 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), cmd);
378 if (err != ERROR_OK)
379 return err;
380
381 cmd = FLASH_SPR | FLASH_WMS;
382 err = target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
383 if (err != ERROR_OK)
384 return err;
385
386 err = str7x_waitbusy(bank);
387 if (err != ERROR_OK)
388 return err;
389
390 err = str7x_result(bank);
391 if (err != ERROR_OK)
392 return err;
393
394 return ERROR_OK;
395 }
396
397 int str7x_write_block(struct flash_bank *bank, uint8_t *buffer,
398 uint32_t offset, uint32_t count)
399 {
400 struct str7x_flash_bank *str7x_info = bank->driver_priv;
401 struct target *target = bank->target;
402 uint32_t buffer_size = 32768;
403 struct working_area *source;
404 uint32_t address = bank->base + offset;
405 struct reg_param reg_params[6];
406 struct arm_algorithm armv4_5_info;
407 int retval = ERROR_OK;
408
409 static const uint32_t str7x_flash_write_code[] = {
410 /* write: */
411 0xe3a04201, /* mov r4, #0x10000000 */
412 0xe5824000, /* str r4, [r2, #0x0] */
413 0xe5821010, /* str r1, [r2, #0x10] */
414 0xe4904004, /* ldr r4, [r0], #4 */
415 0xe5824008, /* str r4, [r2, #0x8] */
416 0xe4904004, /* ldr r4, [r0], #4 */
417 0xe582400c, /* str r4, [r2, #0xc] */
418 0xe3a04209, /* mov r4, #0x90000000 */
419 0xe5824000, /* str r4, [r2, #0x0] */
420 /* busy: */
421 0xe5924000, /* ldr r4, [r2, #0x0] */
422 0xe1140005, /* tst r4, r5 */
423 0x1afffffc, /* bne busy */
424 0xe5924014, /* ldr r4, [r2, #0x14] */
425 0xe31400ff, /* tst r4, #0xff */
426 0x03140c01, /* tsteq r4, #0x100 */
427 0x1a000002, /* bne exit */
428 0xe2811008, /* add r1, r1, #0x8 */
429 0xe2533001, /* subs r3, r3, #1 */
430 0x1affffec, /* bne write */
431 /* exit: */
432 0xeafffffe, /* b exit */
433 };
434
435 /* flash write code */
436 if (target_alloc_working_area_try(target, sizeof(str7x_flash_write_code),
437 &str7x_info->write_algorithm) != ERROR_OK)
438 {
439 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
440 };
441
442 target_write_buffer(target, str7x_info->write_algorithm->address,
443 sizeof(str7x_flash_write_code),
444 (uint8_t*)str7x_flash_write_code);
445
446 /* memory buffer */
447 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK)
448 {
449 buffer_size /= 2;
450 if (buffer_size <= 256)
451 {
452 /* if we already allocated the writing code, but failed to get a
453 * buffer, free the algorithm */
454 if (str7x_info->write_algorithm)
455 target_free_working_area(target, str7x_info->write_algorithm);
456
457 LOG_WARNING("no large enough working area available, can't do block memory writes");
458 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
459 }
460 }
461
462 armv4_5_info.common_magic = ARM_COMMON_MAGIC;
463 armv4_5_info.core_mode = ARM_MODE_SVC;
464 armv4_5_info.core_state = ARM_STATE_ARM;
465
466 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
467 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
468 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
469 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
470 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
471 init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
472
473 while (count > 0)
474 {
475 uint32_t thisrun_count = (count > (buffer_size / 8)) ? (buffer_size / 8) : count;
476
477 target_write_buffer(target, source->address, thisrun_count * 8, buffer);
478
479 buf_set_u32(reg_params[0].value, 0, 32, source->address);
480 buf_set_u32(reg_params[1].value, 0, 32, address);
481 buf_set_u32(reg_params[2].value, 0, 32, str7x_get_flash_adr(bank, FLASH_CR0));
482 buf_set_u32(reg_params[3].value, 0, 32, thisrun_count);
483 buf_set_u32(reg_params[5].value, 0, 32, str7x_info->busy_bits);
484
485 if ((retval = target_run_algorithm(target, 0, NULL, 6, reg_params,
486 str7x_info->write_algorithm->address,
487 str7x_info->write_algorithm->address + (sizeof(str7x_flash_write_code) - 4),
488 10000, &armv4_5_info)) != ERROR_OK)
489 {
490 break;
491 }
492
493 if (buf_get_u32(reg_params[4].value, 0, 32) != 0x00)
494 {
495 retval = str7x_result(bank);
496 break;
497 }
498
499 buffer += thisrun_count * 8;
500 address += thisrun_count * 8;
501 count -= thisrun_count;
502 }
503
504 target_free_working_area(target, source);
505 target_free_working_area(target, str7x_info->write_algorithm);
506
507 destroy_reg_param(&reg_params[0]);
508 destroy_reg_param(&reg_params[1]);
509 destroy_reg_param(&reg_params[2]);
510 destroy_reg_param(&reg_params[3]);
511 destroy_reg_param(&reg_params[4]);
512 destroy_reg_param(&reg_params[5]);
513
514 return retval;
515 }
516
517 static int str7x_write(struct flash_bank *bank, uint8_t *buffer,
518 uint32_t offset, uint32_t count)
519 {
520 struct target *target = bank->target;
521 uint32_t dwords_remaining = (count / 8);
522 uint32_t bytes_remaining = (count & 0x00000007);
523 uint32_t address = bank->base + offset;
524 uint32_t bytes_written = 0;
525 uint32_t cmd;
526 int retval;
527 uint32_t check_address = offset;
528 int i;
529
530 if (bank->target->state != TARGET_HALTED)
531 {
532 LOG_ERROR("Target not halted");
533 return ERROR_TARGET_NOT_HALTED;
534 }
535
536 if (offset & 0x7)
537 {
538 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
539 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
540 }
541
542 for (i = 0; i < bank->num_sectors; i++)
543 {
544 uint32_t sec_start = bank->sectors[i].offset;
545 uint32_t sec_end = sec_start + bank->sectors[i].size;
546
547 /* check if destination falls within the current sector */
548 if ((check_address >= sec_start) && (check_address < sec_end))
549 {
550 /* check if destination ends in the current sector */
551 if (offset + count < sec_end)
552 check_address = offset + count;
553 else
554 check_address = sec_end;
555 }
556 }
557
558 if (check_address != offset + count)
559 return ERROR_FLASH_DST_OUT_OF_BANK;
560
561 /* clear FLASH_ER register */
562 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
563
564 /* multiple dwords (8-byte) to be programmed? */
565 if (dwords_remaining > 0)
566 {
567 /* try using a block write */
568 if ((retval = str7x_write_block(bank, buffer, offset,
569 dwords_remaining)) != ERROR_OK)
570 {
571 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
572 {
573 /* if block write failed (no sufficient working area),
574 * we use normal (slow) single dword accesses */
575 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
576 } else
577 {
578 return retval;
579 }
580 }
581 else
582 {
583 buffer += dwords_remaining * 8;
584 address += dwords_remaining * 8;
585 dwords_remaining = 0;
586 }
587 }
588
589 while (dwords_remaining > 0)
590 {
591 /* command */
592 cmd = FLASH_DWPG;
593 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
594
595 /* address */
596 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
597
598 /* data word 1 */
599 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0),
600 4, 1, buffer + bytes_written);
601 bytes_written += 4;
602
603 /* data word 2 */
604 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1),
605 4, 1, buffer + bytes_written);
606 bytes_written += 4;
607
608 /* start programming cycle */
609 cmd = FLASH_DWPG | FLASH_WMS;
610 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
611
612 int err;
613 err = str7x_waitbusy(bank);
614 if (err != ERROR_OK)
615 return err;
616
617 err = str7x_result(bank);
618 if (err != ERROR_OK)
619 return err;
620
621 dwords_remaining--;
622 address += 8;
623 }
624
625 if (bytes_remaining)
626 {
627 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
628 int i = 0;
629
630 while (bytes_remaining > 0)
631 {
632 last_dword[i++] = *(buffer + bytes_written);
633 bytes_remaining--;
634 bytes_written++;
635 }
636
637 /* command */
638 cmd = FLASH_DWPG;
639 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
640
641 /* address */
642 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
643
644 /* data word 1 */
645 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0),
646 4, 1, last_dword);
647 bytes_written += 4;
648
649 /* data word 2 */
650 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1),
651 4, 1, last_dword + 4);
652 bytes_written += 4;
653
654 /* start programming cycle */
655 cmd = FLASH_DWPG | FLASH_WMS;
656 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
657
658 int err;
659 err = str7x_waitbusy(bank);
660 if (err != ERROR_OK)
661 return err;
662
663 err = str7x_result(bank);
664 if (err != ERROR_OK)
665 return err;
666 }
667
668 return ERROR_OK;
669 }
670
671 static int str7x_probe(struct flash_bank *bank)
672 {
673 return ERROR_OK;
674 }
675
676 #if 0
677 COMMAND_HANDLER(str7x_handle_part_id_command)
678 {
679 return ERROR_OK;
680 }
681 #endif
682
683 static int str7x_info(struct flash_bank *bank, char *buf, int buf_size)
684 {
685 snprintf(buf, buf_size, "str7x flash driver info");
686 /* STR7x flash doesn't support sector protection interrogation.
687 * FLASH_NVWPAR acts as a write only register; its read value
688 * doesn't reflect the actual protection state of the sectors.
689 */
690 LOG_WARNING("STR7x flash lock information might not be correct "
691 "due to hardware limitations.");
692 return ERROR_OK;
693 }
694
695 COMMAND_HANDLER(str7x_handle_disable_jtag_command)
696 {
697 struct target *target = NULL;
698 struct str7x_flash_bank *str7x_info = NULL;
699
700 uint32_t flash_cmd;
701 uint16_t ProtectionLevel = 0;
702 uint16_t ProtectionRegs;
703
704 if (CMD_ARGC < 1)
705 {
706 command_print(CMD_CTX, "str7x disable_jtag <bank>");
707 return ERROR_OK;
708 }
709
710 struct flash_bank *bank;
711 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
712 if (ERROR_OK != retval)
713 return retval;
714
715 str7x_info = bank->driver_priv;
716
717 target = bank->target;
718
719 if (target->state != TARGET_HALTED)
720 {
721 LOG_ERROR("Target not halted");
722 return ERROR_TARGET_NOT_HALTED;
723 }
724
725 /* first we get protection status */
726 uint32_t reg;
727 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), &reg);
728
729 if (!(reg & str7x_info->disable_bit))
730 {
731 ProtectionLevel = 1;
732 }
733
734 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), &reg);
735 ProtectionRegs = ~(reg >> 16);
736
737 while (((ProtectionRegs) != 0) && (ProtectionLevel < 16))
738 {
739 ProtectionRegs >>= 1;
740 ProtectionLevel++;
741 }
742
743 if (ProtectionLevel == 0)
744 {
745 flash_cmd = FLASH_SPR;
746 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
747 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFB8);
748 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), 0xFFFFFFFD);
749 flash_cmd = FLASH_SPR | FLASH_WMS;
750 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
751 }
752 else
753 {
754 flash_cmd = FLASH_SPR;
755 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
756 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFBC);
757 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0),
758 ~(1 << (15 + ProtectionLevel)));
759 flash_cmd = FLASH_SPR | FLASH_WMS;
760 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
761 }
762
763 return ERROR_OK;
764 }
765
766 static const struct command_registration str7x_exec_command_handlers[] = {
767 {
768 .name = "disable_jtag",
769 .handler = str7x_handle_disable_jtag_command,
770 .mode = COMMAND_EXEC,
771 .help = "disable jtag access",
772 },
773 COMMAND_REGISTRATION_DONE
774 };
775
776 static const struct command_registration str7x_command_handlers[] = {
777 {
778 .name = "str7x",
779 .mode = COMMAND_ANY,
780 .help = "str7x flash command group",
781 .chain = str7x_exec_command_handlers,
782 },
783 COMMAND_REGISTRATION_DONE
784 };
785
786 struct flash_driver str7x_flash = {
787 .name = "str7x",
788 .commands = str7x_command_handlers,
789 .flash_bank_command = str7x_flash_bank_command,
790 .erase = str7x_erase,
791 .protect = str7x_protect,
792 .write = str7x_write,
793 .probe = str7x_probe,
794 .auto_probe = str7x_probe,
795 .erase_check = default_flash_blank_check,
796 .protect_check = str7x_protect_check,
797 .info = str7x_info,
798 };

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)