FLASH/NOR: Remove useless file avrf.h
[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 static 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 /* see contib/loaders/flash/str7x.s for src */
410
411 static const uint32_t str7x_flash_write_code[] = {
412 /* write: */
413 0xe3a04201, /* mov r4, #0x10000000 */
414 0xe5824000, /* str r4, [r2, #0x0] */
415 0xe5821010, /* str r1, [r2, #0x10] */
416 0xe4904004, /* ldr r4, [r0], #4 */
417 0xe5824008, /* str r4, [r2, #0x8] */
418 0xe4904004, /* ldr r4, [r0], #4 */
419 0xe582400c, /* str r4, [r2, #0xc] */
420 0xe3a04209, /* mov r4, #0x90000000 */
421 0xe5824000, /* str r4, [r2, #0x0] */
422 /* busy: */
423 0xe5924000, /* ldr r4, [r2, #0x0] */
424 0xe1140005, /* tst r4, r5 */
425 0x1afffffc, /* bne busy */
426 0xe5924014, /* ldr r4, [r2, #0x14] */
427 0xe31400ff, /* tst r4, #0xff */
428 0x03140c01, /* tsteq r4, #0x100 */
429 0x1a000002, /* bne exit */
430 0xe2811008, /* add r1, r1, #0x8 */
431 0xe2533001, /* subs r3, r3, #1 */
432 0x1affffec, /* bne write */
433 /* exit: */
434 0xeafffffe, /* b exit */
435 };
436
437 /* flash write code */
438 if (target_alloc_working_area_try(target, sizeof(str7x_flash_write_code),
439 &str7x_info->write_algorithm) != ERROR_OK)
440 {
441 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
442 };
443
444 target_write_buffer(target, str7x_info->write_algorithm->address,
445 sizeof(str7x_flash_write_code),
446 (uint8_t*)str7x_flash_write_code);
447
448 /* memory buffer */
449 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK)
450 {
451 buffer_size /= 2;
452 if (buffer_size <= 256)
453 {
454 /* if we already allocated the writing code, but failed to get a
455 * buffer, free the algorithm */
456 if (str7x_info->write_algorithm)
457 target_free_working_area(target, str7x_info->write_algorithm);
458
459 LOG_WARNING("no large enough working area available, can't do block memory writes");
460 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
461 }
462 }
463
464 armv4_5_info.common_magic = ARM_COMMON_MAGIC;
465 armv4_5_info.core_mode = ARM_MODE_SVC;
466 armv4_5_info.core_state = ARM_STATE_ARM;
467
468 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
469 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
470 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
471 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
472 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
473 init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
474
475 while (count > 0)
476 {
477 uint32_t thisrun_count = (count > (buffer_size / 8)) ? (buffer_size / 8) : count;
478
479 target_write_buffer(target, source->address, thisrun_count * 8, buffer);
480
481 buf_set_u32(reg_params[0].value, 0, 32, source->address);
482 buf_set_u32(reg_params[1].value, 0, 32, address);
483 buf_set_u32(reg_params[2].value, 0, 32, str7x_get_flash_adr(bank, FLASH_CR0));
484 buf_set_u32(reg_params[3].value, 0, 32, thisrun_count);
485 buf_set_u32(reg_params[5].value, 0, 32, str7x_info->busy_bits);
486
487 if ((retval = target_run_algorithm(target, 0, NULL, 6, reg_params,
488 str7x_info->write_algorithm->address,
489 str7x_info->write_algorithm->address + (sizeof(str7x_flash_write_code) - 4),
490 10000, &armv4_5_info)) != ERROR_OK)
491 {
492 break;
493 }
494
495 if (buf_get_u32(reg_params[4].value, 0, 32) != 0x00)
496 {
497 retval = str7x_result(bank);
498 break;
499 }
500
501 buffer += thisrun_count * 8;
502 address += thisrun_count * 8;
503 count -= thisrun_count;
504 }
505
506 target_free_working_area(target, source);
507 target_free_working_area(target, str7x_info->write_algorithm);
508
509 destroy_reg_param(&reg_params[0]);
510 destroy_reg_param(&reg_params[1]);
511 destroy_reg_param(&reg_params[2]);
512 destroy_reg_param(&reg_params[3]);
513 destroy_reg_param(&reg_params[4]);
514 destroy_reg_param(&reg_params[5]);
515
516 return retval;
517 }
518
519 static int str7x_write(struct flash_bank *bank, uint8_t *buffer,
520 uint32_t offset, uint32_t count)
521 {
522 struct target *target = bank->target;
523 uint32_t dwords_remaining = (count / 8);
524 uint32_t bytes_remaining = (count & 0x00000007);
525 uint32_t address = bank->base + offset;
526 uint32_t bytes_written = 0;
527 uint32_t cmd;
528 int retval;
529 uint32_t check_address = offset;
530 int i;
531
532 if (bank->target->state != TARGET_HALTED)
533 {
534 LOG_ERROR("Target not halted");
535 return ERROR_TARGET_NOT_HALTED;
536 }
537
538 if (offset & 0x7)
539 {
540 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
541 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
542 }
543
544 for (i = 0; i < bank->num_sectors; i++)
545 {
546 uint32_t sec_start = bank->sectors[i].offset;
547 uint32_t sec_end = sec_start + bank->sectors[i].size;
548
549 /* check if destination falls within the current sector */
550 if ((check_address >= sec_start) && (check_address < sec_end))
551 {
552 /* check if destination ends in the current sector */
553 if (offset + count < sec_end)
554 check_address = offset + count;
555 else
556 check_address = sec_end;
557 }
558 }
559
560 if (check_address != offset + count)
561 return ERROR_FLASH_DST_OUT_OF_BANK;
562
563 /* clear FLASH_ER register */
564 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
565
566 /* multiple dwords (8-byte) to be programmed? */
567 if (dwords_remaining > 0)
568 {
569 /* try using a block write */
570 if ((retval = str7x_write_block(bank, buffer, offset,
571 dwords_remaining)) != ERROR_OK)
572 {
573 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
574 {
575 /* if block write failed (no sufficient working area),
576 * we use normal (slow) single dword accesses */
577 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
578 } else
579 {
580 return retval;
581 }
582 }
583 else
584 {
585 buffer += dwords_remaining * 8;
586 address += dwords_remaining * 8;
587 dwords_remaining = 0;
588 }
589 }
590
591 while (dwords_remaining > 0)
592 {
593 /* command */
594 cmd = FLASH_DWPG;
595 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
596
597 /* address */
598 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
599
600 /* data word 1 */
601 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0),
602 4, 1, buffer + bytes_written);
603 bytes_written += 4;
604
605 /* data word 2 */
606 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1),
607 4, 1, buffer + bytes_written);
608 bytes_written += 4;
609
610 /* start programming cycle */
611 cmd = FLASH_DWPG | FLASH_WMS;
612 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
613
614 int err;
615 err = str7x_waitbusy(bank);
616 if (err != ERROR_OK)
617 return err;
618
619 err = str7x_result(bank);
620 if (err != ERROR_OK)
621 return err;
622
623 dwords_remaining--;
624 address += 8;
625 }
626
627 if (bytes_remaining)
628 {
629 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
630 i = 0;
631
632 while (bytes_remaining > 0)
633 {
634 last_dword[i++] = *(buffer + bytes_written);
635 bytes_remaining--;
636 bytes_written++;
637 }
638
639 /* command */
640 cmd = FLASH_DWPG;
641 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
642
643 /* address */
644 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
645
646 /* data word 1 */
647 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0),
648 4, 1, last_dword);
649 bytes_written += 4;
650
651 /* data word 2 */
652 target_write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1),
653 4, 1, last_dword + 4);
654 bytes_written += 4;
655
656 /* start programming cycle */
657 cmd = FLASH_DWPG | FLASH_WMS;
658 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
659
660 int err;
661 err = str7x_waitbusy(bank);
662 if (err != ERROR_OK)
663 return err;
664
665 err = str7x_result(bank);
666 if (err != ERROR_OK)
667 return err;
668 }
669
670 return ERROR_OK;
671 }
672
673 static int str7x_probe(struct flash_bank *bank)
674 {
675 return ERROR_OK;
676 }
677
678 #if 0
679 COMMAND_HANDLER(str7x_handle_part_id_command)
680 {
681 return ERROR_OK;
682 }
683 #endif
684
685 static int get_str7x_info(struct flash_bank *bank, char *buf, int buf_size)
686 {
687 snprintf(buf, buf_size, "str7x flash driver info");
688 /* STR7x flash doesn't support sector protection interrogation.
689 * FLASH_NVWPAR acts as a write only register; its read value
690 * doesn't reflect the actual protection state of the sectors.
691 */
692 LOG_WARNING("STR7x flash lock information might not be correct "
693 "due to hardware limitations.");
694 return ERROR_OK;
695 }
696
697 COMMAND_HANDLER(str7x_handle_disable_jtag_command)
698 {
699 struct target *target = NULL;
700 struct str7x_flash_bank *str7x_info = NULL;
701
702 uint32_t flash_cmd;
703 uint16_t ProtectionLevel = 0;
704 uint16_t ProtectionRegs;
705
706 if (CMD_ARGC < 1)
707 {
708 command_print(CMD_CTX, "str7x disable_jtag <bank>");
709 return ERROR_OK;
710 }
711
712 struct flash_bank *bank;
713 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
714 if (ERROR_OK != retval)
715 return retval;
716
717 str7x_info = bank->driver_priv;
718
719 target = bank->target;
720
721 if (target->state != TARGET_HALTED)
722 {
723 LOG_ERROR("Target not halted");
724 return ERROR_TARGET_NOT_HALTED;
725 }
726
727 /* first we get protection status */
728 uint32_t reg;
729 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), &reg);
730
731 if (!(reg & str7x_info->disable_bit))
732 {
733 ProtectionLevel = 1;
734 }
735
736 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), &reg);
737 ProtectionRegs = ~(reg >> 16);
738
739 while (((ProtectionRegs) != 0) && (ProtectionLevel < 16))
740 {
741 ProtectionRegs >>= 1;
742 ProtectionLevel++;
743 }
744
745 if (ProtectionLevel == 0)
746 {
747 flash_cmd = FLASH_SPR;
748 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
749 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFB8);
750 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), 0xFFFFFFFD);
751 flash_cmd = FLASH_SPR | FLASH_WMS;
752 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
753 }
754 else
755 {
756 flash_cmd = FLASH_SPR;
757 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
758 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFBC);
759 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0),
760 ~(1 << (15 + ProtectionLevel)));
761 flash_cmd = FLASH_SPR | FLASH_WMS;
762 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
763 }
764
765 return ERROR_OK;
766 }
767
768 static const struct command_registration str7x_exec_command_handlers[] = {
769 {
770 .name = "disable_jtag",
771 .handler = str7x_handle_disable_jtag_command,
772 .mode = COMMAND_EXEC,
773 .help = "disable jtag access",
774 },
775 COMMAND_REGISTRATION_DONE
776 };
777
778 static const struct command_registration str7x_command_handlers[] = {
779 {
780 .name = "str7x",
781 .mode = COMMAND_ANY,
782 .help = "str7x flash command group",
783 .chain = str7x_exec_command_handlers,
784 },
785 COMMAND_REGISTRATION_DONE
786 };
787
788 struct flash_driver str7x_flash = {
789 .name = "str7x",
790 .commands = str7x_command_handlers,
791 .flash_bank_command = str7x_flash_bank_command,
792 .erase = str7x_erase,
793 .protect = str7x_protect,
794 .write = str7x_write,
795 .read = default_flash_read,
796 .probe = str7x_probe,
797 .auto_probe = str7x_probe,
798 .erase_check = default_flash_blank_check,
799 .protect_check = str7x_protect_check,
800 .info = get_str7x_info,
801 };

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)