- more fixes to high density stm32x flash driver
[openocd.git] / src / flash / 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 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
12 * *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
17 * *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "replacements.h"
28
29 #include "str7x.h"
30 #include "flash.h"
31 #include "target.h"
32 #include "log.h"
33 #include "armv4_5.h"
34 #include "algorithm.h"
35 #include "binarybuffer.h"
36
37 #include <stdlib.h>
38 #include <string.h>
39 #include <unistd.h>
40
41 str7x_mem_layout_t mem_layout_str7bank0[] = {
42 {0x00000000, 0x02000, 0x01},
43 {0x00002000, 0x02000, 0x02},
44 {0x00004000, 0x02000, 0x04},
45 {0x00006000, 0x02000, 0x08},
46 {0x00008000, 0x08000, 0x10},
47 {0x00010000, 0x10000, 0x20},
48 {0x00020000, 0x10000, 0x40},
49 {0x00030000, 0x10000, 0x80}
50 };
51
52 str7x_mem_layout_t mem_layout_str7bank1[] = {
53 {0x00000000, 0x02000, 0x10000},
54 {0x00002000, 0x02000, 0x20000}
55 };
56
57 int str7x_register_commands(struct command_context_s *cmd_ctx);
58 int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
59 int str7x_erase(struct flash_bank_s *bank, int first, int last);
60 int str7x_protect(struct flash_bank_s *bank, int set, int first, int last);
61 int str7x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count);
62 int str7x_probe(struct flash_bank_s *bank);
63 int str7x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
64 int str7x_protect_check(struct flash_bank_s *bank);
65 int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size);
66
67 int str7x_handle_disable_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
68
69 flash_driver_t str7x_flash =
70 {
71 .name = "str7x",
72 .register_commands = str7x_register_commands,
73 .flash_bank_command = str7x_flash_bank_command,
74 .erase = str7x_erase,
75 .protect = str7x_protect,
76 .write = str7x_write,
77 .probe = str7x_probe,
78 .auto_probe = str7x_probe,
79 .erase_check = default_flash_blank_check,
80 .protect_check = str7x_protect_check,
81 .info = str7x_info
82 };
83
84 int str7x_register_commands(struct command_context_s *cmd_ctx)
85 {
86 command_t *str7x_cmd = register_command(cmd_ctx, NULL, "str7x", NULL, COMMAND_ANY, NULL);
87
88 register_command(cmd_ctx, str7x_cmd, "disable_jtag", str7x_handle_disable_jtag_command, COMMAND_EXEC,
89 "disable jtag access");
90
91 return ERROR_OK;
92 }
93
94 int str7x_get_flash_adr(struct flash_bank_s *bank, u32 reg)
95 {
96 str7x_flash_bank_t *str7x_info = bank->driver_priv;
97 return (str7x_info->register_base | reg);
98 }
99
100 int str7x_build_block_list(struct flash_bank_s *bank)
101 {
102 str7x_flash_bank_t *str7x_info = bank->driver_priv;
103
104 int i;
105 int num_sectors;
106 int b0_sectors = 0, b1_sectors = 0;
107
108 switch (bank->size)
109 {
110 case 16 * 1024:
111 b1_sectors = 2;
112 break;
113 case 64 * 1024:
114 b0_sectors = 5;
115 break;
116 case 128 * 1024:
117 b0_sectors = 6;
118 break;
119 case 256 * 1024:
120 b0_sectors = 8;
121 break;
122 default:
123 LOG_ERROR("BUG: unknown bank->size encountered");
124 exit(-1);
125 }
126
127 num_sectors = b0_sectors + b1_sectors;
128
129 bank->num_sectors = num_sectors;
130 bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
131 str7x_info->sector_bits = malloc(sizeof(u32) * num_sectors);
132
133 num_sectors = 0;
134
135 for (i = 0; i < b0_sectors; i++)
136 {
137 bank->sectors[num_sectors].offset = mem_layout_str7bank0[i].sector_start;
138 bank->sectors[num_sectors].size = mem_layout_str7bank0[i].sector_size;
139 bank->sectors[num_sectors].is_erased = -1;
140 bank->sectors[num_sectors].is_protected = 1;
141 str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank0[i].sector_bit;
142 }
143
144 for (i = 0; i < b1_sectors; i++)
145 {
146 bank->sectors[num_sectors].offset = mem_layout_str7bank1[i].sector_start;
147 bank->sectors[num_sectors].size = mem_layout_str7bank1[i].sector_size;
148 bank->sectors[num_sectors].is_erased = -1;
149 bank->sectors[num_sectors].is_protected = 1;
150 str7x_info->sector_bits[num_sectors++] = mem_layout_str7bank1[i].sector_bit;
151 }
152
153 return ERROR_OK;
154 }
155
156 /* flash bank str7x <base> <size> 0 0 <target#> <str71_variant>
157 */
158 int str7x_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
159 {
160 str7x_flash_bank_t *str7x_info;
161
162 if (argc < 7)
163 {
164 LOG_WARNING("incomplete flash_bank str7x configuration");
165 return ERROR_FLASH_BANK_INVALID;
166 }
167
168 str7x_info = malloc(sizeof(str7x_flash_bank_t));
169 bank->driver_priv = str7x_info;
170
171 /* set default bits for str71x flash */
172 str7x_info->busy_bits = (FLASH_LOCK|FLASH_BSYA1|FLASH_BSYA0);
173 str7x_info->disable_bit = (1<<1);
174
175 if (strcmp(args[6], "STR71x") == 0)
176 {
177 str7x_info->register_base = 0x40100000;
178 }
179 else if (strcmp(args[6], "STR73x") == 0)
180 {
181 str7x_info->register_base = 0x80100000;
182 str7x_info->busy_bits = (FLASH_LOCK|FLASH_BSYA0);
183 }
184 else if (strcmp(args[6], "STR75x") == 0)
185 {
186 str7x_info->register_base = 0x20100000;
187 str7x_info->disable_bit = (1<<0);
188 }
189 else
190 {
191 LOG_ERROR("unknown STR7x variant: '%s'", args[6]);
192 free(str7x_info);
193 return ERROR_FLASH_BANK_INVALID;
194 }
195
196 str7x_build_block_list(bank);
197
198 str7x_info->write_algorithm = NULL;
199
200 return ERROR_OK;
201 }
202
203 u32 str7x_status(struct flash_bank_s *bank)
204 {
205 target_t *target = bank->target;
206 u32 retval;
207
208 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), &retval);
209
210 return retval;
211 }
212
213 u32 str7x_result(struct flash_bank_s *bank)
214 {
215 target_t *target = bank->target;
216 u32 retval;
217
218 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_ER), &retval);
219
220 return retval;
221 }
222
223 int str7x_protect_check(struct flash_bank_s *bank)
224 {
225 str7x_flash_bank_t *str7x_info = bank->driver_priv;
226 target_t *target = bank->target;
227
228 int i;
229 u32 retval;
230
231 if (bank->target->state != TARGET_HALTED)
232 {
233 return ERROR_TARGET_NOT_HALTED;
234 }
235
236 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVWPAR), &retval);
237
238 for (i = 0; i < bank->num_sectors; i++)
239 {
240 if (retval & str7x_info->sector_bits[i])
241 bank->sectors[i].is_protected = 0;
242 else
243 bank->sectors[i].is_protected = 1;
244 }
245
246 return ERROR_OK;
247 }
248
249 int str7x_erase(struct flash_bank_s *bank, int first, int last)
250 {
251 str7x_flash_bank_t *str7x_info = bank->driver_priv;
252 target_t *target = bank->target;
253
254 int i;
255 u32 cmd;
256 u32 retval;
257 u32 sectors = 0;
258
259 if (bank->target->state != TARGET_HALTED)
260 {
261 return ERROR_TARGET_NOT_HALTED;
262 }
263
264 for (i = first; i <= last; i++)
265 {
266 sectors |= str7x_info->sector_bits[i];
267 }
268
269 LOG_DEBUG("sectors: 0x%x", sectors);
270
271 /* clear FLASH_ER register */
272 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
273
274 cmd = FLASH_SER;
275 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
276
277 cmd = sectors;
278 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);
279
280 cmd = FLASH_SER|FLASH_WMS;
281 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
282
283 while (((retval = str7x_status(bank)) & str7x_info->busy_bits)){
284 usleep(1000);
285 }
286
287 retval = str7x_result(bank);
288
289 if (retval)
290 {
291 LOG_ERROR("error erasing flash bank, FLASH_ER: 0x%x", retval);
292 return ERROR_FLASH_OPERATION_FAILED;
293 }
294
295 for (i = first; i <= last; i++)
296 bank->sectors[i].is_erased = 1;
297
298 return ERROR_OK;
299 }
300
301 int str7x_protect(struct flash_bank_s *bank, int set, int first, int last)
302 {
303 str7x_flash_bank_t *str7x_info = bank->driver_priv;
304 target_t *target = bank->target;
305 int i;
306 u32 cmd;
307 u32 retval;
308 u32 protect_blocks;
309
310 if (bank->target->state != TARGET_HALTED)
311 {
312 return ERROR_TARGET_NOT_HALTED;
313 }
314
315 protect_blocks = 0xFFFFFFFF;
316
317 if (set)
318 {
319 for (i = first; i <= last; i++)
320 protect_blocks &= ~(str7x_info->sector_bits[i]);
321 }
322
323 /* clear FLASH_ER register */
324 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
325
326 cmd = FLASH_SPR;
327 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
328
329 cmd = str7x_get_flash_adr(bank, FLASH_NVWPAR);
330 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), cmd);
331
332 cmd = protect_blocks;
333 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), cmd);
334
335 cmd = FLASH_SPR|FLASH_WMS;
336 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
337
338 while (((retval = str7x_status(bank)) & str7x_info->busy_bits)){
339 usleep(1000);
340 }
341
342 retval = str7x_result(bank);
343
344 LOG_DEBUG("retval: 0x%8.8x", retval);
345
346 if (retval & FLASH_ERER)
347 return ERROR_FLASH_SECTOR_NOT_ERASED;
348 else if (retval & FLASH_WPF)
349 return ERROR_FLASH_OPERATION_FAILED;
350
351 return ERROR_OK;
352 }
353
354 int str7x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
355 {
356 str7x_flash_bank_t *str7x_info = bank->driver_priv;
357 target_t *target = bank->target;
358 u32 buffer_size = 8192;
359 working_area_t *source;
360 u32 address = bank->base + offset;
361 reg_param_t reg_params[6];
362 armv4_5_algorithm_t armv4_5_info;
363 int retval = ERROR_OK;
364
365 u32 str7x_flash_write_code[] = {
366 /* write: */
367 0xe3a04201, /* mov r4, #0x10000000 */
368 0xe5824000, /* str r4, [r2, #0x0] */
369 0xe5821010, /* str r1, [r2, #0x10] */
370 0xe4904004, /* ldr r4, [r0], #4 */
371 0xe5824008, /* str r4, [r2, #0x8] */
372 0xe4904004, /* ldr r4, [r0], #4 */
373 0xe582400c, /* str r4, [r2, #0xc] */
374 0xe3a04209, /* mov r4, #0x90000000 */
375 0xe5824000, /* str r4, [r2, #0x0] */
376 /* busy: */
377 0xe5924000, /* ldr r4, [r2, #0x0] */
378 0xe1140005, /* tst r4, r5 */
379 0x1afffffc, /* bne busy */
380 0xe5924014, /* ldr r4, [r2, #0x14] */
381 0xe31400ff, /* tst r4, #0xff */
382 0x03140c01, /* tsteq r4, #0x100 */
383 0x1a000002, /* bne exit */
384 0xe2811008, /* add r1, r1, #0x8 */
385 0xe2533001, /* subs r3, r3, #1 */
386 0x1affffec, /* bne write */
387 /* exit: */
388 0xeafffffe, /* b exit */
389 };
390
391 /* flash write code */
392 if (target_alloc_working_area(target, 4 * 20, &str7x_info->write_algorithm) != ERROR_OK)
393 {
394 LOG_WARNING("no working area available, can't do block memory writes");
395 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
396 };
397
398 target_write_buffer(target, str7x_info->write_algorithm->address, 20 * 4, (u8*)str7x_flash_write_code);
399
400 /* memory buffer */
401 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
402 {
403 buffer_size /= 2;
404 if (buffer_size <= 256)
405 {
406 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
407 if (str7x_info->write_algorithm)
408 target_free_working_area(target, str7x_info->write_algorithm);
409
410 LOG_WARNING("no large enough working area available, can't do block memory writes");
411 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
412 }
413 }
414
415 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
416 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
417 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
418
419 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
420 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
421 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
422 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
423 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
424 init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
425
426 while (count > 0)
427 {
428 u32 thisrun_count = (count > (buffer_size / 8)) ? (buffer_size / 8) : count;
429
430 target_write_buffer(target, source->address, thisrun_count * 8, buffer);
431
432 buf_set_u32(reg_params[0].value, 0, 32, source->address);
433 buf_set_u32(reg_params[1].value, 0, 32, address);
434 buf_set_u32(reg_params[2].value, 0, 32, str7x_get_flash_adr(bank, FLASH_CR0));
435 buf_set_u32(reg_params[3].value, 0, 32, thisrun_count);
436 buf_set_u32(reg_params[5].value, 0, 32, str7x_info->busy_bits);
437
438 if ((retval = target->type->run_algorithm(target, 0, NULL, 6, reg_params, str7x_info->write_algorithm->address, str7x_info->write_algorithm->address + (19 * 4), 10000, &armv4_5_info)) != ERROR_OK)
439 {
440 LOG_ERROR("error executing str7x flash write algorithm");
441 retval = ERROR_FLASH_OPERATION_FAILED;
442 break;
443 }
444
445 if (buf_get_u32(reg_params[4].value, 0, 32) != 0x00)
446 {
447 retval = ERROR_FLASH_OPERATION_FAILED;
448 break;
449 }
450
451 buffer += thisrun_count * 8;
452 address += thisrun_count * 8;
453 count -= thisrun_count;
454 }
455
456 target_free_working_area(target, source);
457 target_free_working_area(target, str7x_info->write_algorithm);
458
459 destroy_reg_param(&reg_params[0]);
460 destroy_reg_param(&reg_params[1]);
461 destroy_reg_param(&reg_params[2]);
462 destroy_reg_param(&reg_params[3]);
463 destroy_reg_param(&reg_params[4]);
464 destroy_reg_param(&reg_params[5]);
465
466 return retval;
467 }
468
469 int str7x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
470 {
471 target_t *target = bank->target;
472 str7x_flash_bank_t *str7x_info = bank->driver_priv;
473 u32 dwords_remaining = (count / 8);
474 u32 bytes_remaining = (count & 0x00000007);
475 u32 address = bank->base + offset;
476 u32 bytes_written = 0;
477 u32 cmd;
478 u32 retval;
479 u32 check_address = offset;
480 int i;
481
482 if (bank->target->state != TARGET_HALTED)
483 {
484 return ERROR_TARGET_NOT_HALTED;
485 }
486
487 if (offset & 0x7)
488 {
489 LOG_WARNING("offset 0x%x breaks required 8-byte alignment", offset);
490 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
491 }
492
493 for (i = 0; i < bank->num_sectors; i++)
494 {
495 u32 sec_start = bank->sectors[i].offset;
496 u32 sec_end = sec_start + bank->sectors[i].size;
497
498 /* check if destination falls within the current sector */
499 if ((check_address >= sec_start) && (check_address < sec_end))
500 {
501 /* check if destination ends in the current sector */
502 if (offset + count < sec_end)
503 check_address = offset + count;
504 else
505 check_address = sec_end;
506 }
507 }
508
509 if (check_address != offset + count)
510 return ERROR_FLASH_DST_OUT_OF_BANK;
511
512 /* clear FLASH_ER register */
513 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
514
515 /* multiple dwords (8-byte) to be programmed? */
516 if (dwords_remaining > 0)
517 {
518 /* try using a block write */
519 if ((retval = str7x_write_block(bank, buffer, offset, dwords_remaining)) != ERROR_OK)
520 {
521 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
522 {
523 /* if block write failed (no sufficient working area),
524 * we use normal (slow) single dword accesses */
525 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
526 }
527 else if (retval == ERROR_FLASH_OPERATION_FAILED)
528 {
529 /* if an error occured, we examine the reason, and quit */
530 retval = str7x_result(bank);
531
532 LOG_ERROR("flash writing failed with error code: 0x%x", retval);
533 return ERROR_FLASH_OPERATION_FAILED;
534 }
535 }
536 else
537 {
538 buffer += dwords_remaining * 8;
539 address += dwords_remaining * 8;
540 dwords_remaining = 0;
541 }
542 }
543
544 while (dwords_remaining > 0)
545 {
546 /* command */
547 cmd = FLASH_DWPG;
548 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
549
550 /* address */
551 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
552
553 /* data word 1 */
554 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, buffer + bytes_written);
555 bytes_written += 4;
556
557 /* data word 2 */
558 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, buffer + bytes_written);
559 bytes_written += 4;
560
561 /* start programming cycle */
562 cmd = FLASH_DWPG | FLASH_WMS;
563 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
564
565 while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
566 {
567 usleep(1000);
568 }
569
570 retval = str7x_result(bank);
571
572 if (retval & FLASH_PGER)
573 return ERROR_FLASH_OPERATION_FAILED;
574 else if (retval & FLASH_WPF)
575 return ERROR_FLASH_OPERATION_FAILED;
576
577 dwords_remaining--;
578 address += 8;
579 }
580
581 if (bytes_remaining)
582 {
583 u8 last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
584 int i = 0;
585
586 while(bytes_remaining > 0)
587 {
588 last_dword[i++] = *(buffer + bytes_written);
589 bytes_remaining--;
590 bytes_written++;
591 }
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->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, last_dword);
602 bytes_written += 4;
603
604 /* data word 2 */
605 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, last_dword + 4);
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 while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
613 {
614 usleep(1000);
615 }
616
617 retval = str7x_result(bank);
618
619 if (retval & FLASH_PGER)
620 return ERROR_FLASH_OPERATION_FAILED;
621 else if (retval & FLASH_WPF)
622 return ERROR_FLASH_OPERATION_FAILED;
623 }
624
625 return ERROR_OK;
626 }
627
628 int str7x_probe(struct flash_bank_s *bank)
629 {
630 return ERROR_OK;
631 }
632
633 int str7x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
634 {
635 return ERROR_OK;
636 }
637
638 int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size)
639 {
640 snprintf(buf, buf_size, "str7x flash driver info" );
641 return ERROR_OK;
642 }
643
644 int str7x_handle_disable_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
645 {
646 flash_bank_t *bank;
647 target_t *target = NULL;
648 str7x_flash_bank_t *str7x_info = NULL;
649
650 u32 flash_cmd;
651 u32 retval;
652 u16 ProtectionLevel = 0;
653 u16 ProtectionRegs;
654
655 if (argc < 1)
656 {
657 command_print(cmd_ctx, "str7x disable_jtag <bank>");
658 return ERROR_OK;
659 }
660
661 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
662 if (!bank)
663 {
664 command_print(cmd_ctx, "str7x disable_jtag <bank> ok");
665 return ERROR_OK;
666 }
667
668 str7x_info = bank->driver_priv;
669
670 target = bank->target;
671
672 if (target->state != TARGET_HALTED)
673 {
674 return ERROR_TARGET_NOT_HALTED;
675 }
676
677 /* first we get protection status */
678 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), &retval);
679
680 if (!(retval & str7x_info->disable_bit))
681 {
682 ProtectionLevel = 1;
683 }
684
685 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), &retval);
686 ProtectionRegs = ~(retval >> 16);
687
688 while (((ProtectionRegs) != 0) && (ProtectionLevel < 16))
689 {
690 ProtectionRegs >>= 1;
691 ProtectionLevel++;
692 }
693
694 if (ProtectionLevel == 0)
695 {
696 flash_cmd = FLASH_SPR;
697 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
698 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFB8);
699 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), 0xFFFFFFFD);
700 flash_cmd = FLASH_SPR | FLASH_WMS;
701 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
702 }
703 else
704 {
705 flash_cmd = FLASH_SPR;
706 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
707 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFBC);
708 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), ~(1<<(15+ProtectionLevel)));
709 flash_cmd = FLASH_SPR | FLASH_WMS;
710 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
711 }
712
713 return ERROR_OK;
714 }
715

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)