09d3b81770af90c87b22c5c2ab40a55aec39ca13
[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 LOG_ERROR("Target not halted");
234 return ERROR_TARGET_NOT_HALTED;
235 }
236
237 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVWPAR), &retval);
238
239 for (i = 0; i < bank->num_sectors; i++)
240 {
241 if (retval & str7x_info->sector_bits[i])
242 bank->sectors[i].is_protected = 0;
243 else
244 bank->sectors[i].is_protected = 1;
245 }
246
247 return ERROR_OK;
248 }
249
250 int str7x_erase(struct flash_bank_s *bank, int first, int last)
251 {
252 str7x_flash_bank_t *str7x_info = bank->driver_priv;
253 target_t *target = bank->target;
254
255 int i;
256 u32 cmd;
257 u32 retval;
258 u32 sectors = 0;
259
260 if (bank->target->state != TARGET_HALTED)
261 {
262 LOG_ERROR("Target not halted");
263 return ERROR_TARGET_NOT_HALTED;
264 }
265
266 for (i = first; i <= last; i++)
267 {
268 sectors |= str7x_info->sector_bits[i];
269 }
270
271 LOG_DEBUG("sectors: 0x%x", sectors);
272
273 /* clear FLASH_ER register */
274 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
275
276 cmd = FLASH_SER;
277 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
278
279 cmd = sectors;
280 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR1), cmd);
281
282 cmd = FLASH_SER|FLASH_WMS;
283 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
284
285 while (((retval = str7x_status(bank)) & str7x_info->busy_bits)){
286 alive_sleep(1);
287 }
288
289 retval = str7x_result(bank);
290
291 if (retval)
292 {
293 LOG_ERROR("error erasing flash bank, FLASH_ER: 0x%x", retval);
294 return ERROR_FLASH_OPERATION_FAILED;
295 }
296
297 for (i = first; i <= last; i++)
298 bank->sectors[i].is_erased = 1;
299
300 return ERROR_OK;
301 }
302
303 int str7x_protect(struct flash_bank_s *bank, int set, int first, int last)
304 {
305 str7x_flash_bank_t *str7x_info = bank->driver_priv;
306 target_t *target = bank->target;
307 int i;
308 u32 cmd;
309 u32 retval;
310 u32 protect_blocks;
311
312 if (bank->target->state != TARGET_HALTED)
313 {
314 LOG_ERROR("Target not halted");
315 return ERROR_TARGET_NOT_HALTED;
316 }
317
318 protect_blocks = 0xFFFFFFFF;
319
320 if (set)
321 {
322 for (i = first; i <= last; i++)
323 protect_blocks &= ~(str7x_info->sector_bits[i]);
324 }
325
326 /* clear FLASH_ER register */
327 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
328
329 cmd = FLASH_SPR;
330 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
331
332 cmd = str7x_get_flash_adr(bank, FLASH_NVWPAR);
333 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), cmd);
334
335 cmd = protect_blocks;
336 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), cmd);
337
338 cmd = FLASH_SPR|FLASH_WMS;
339 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
340
341 while (((retval = str7x_status(bank)) & str7x_info->busy_bits)){
342 alive_sleep(1);
343 }
344
345 retval = str7x_result(bank);
346
347 LOG_DEBUG("retval: 0x%8.8x", retval);
348
349 if (retval & FLASH_ERER)
350 return ERROR_FLASH_SECTOR_NOT_ERASED;
351 else if (retval & FLASH_WPF)
352 return ERROR_FLASH_OPERATION_FAILED;
353
354 return ERROR_OK;
355 }
356
357 int str7x_write_block(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
358 {
359 str7x_flash_bank_t *str7x_info = bank->driver_priv;
360 target_t *target = bank->target;
361 u32 buffer_size = 8192;
362 working_area_t *source;
363 u32 address = bank->base + offset;
364 reg_param_t reg_params[6];
365 armv4_5_algorithm_t armv4_5_info;
366 int retval = ERROR_OK;
367
368 u32 str7x_flash_write_code[] = {
369 /* write: */
370 0xe3a04201, /* mov r4, #0x10000000 */
371 0xe5824000, /* str r4, [r2, #0x0] */
372 0xe5821010, /* str r1, [r2, #0x10] */
373 0xe4904004, /* ldr r4, [r0], #4 */
374 0xe5824008, /* str r4, [r2, #0x8] */
375 0xe4904004, /* ldr r4, [r0], #4 */
376 0xe582400c, /* str r4, [r2, #0xc] */
377 0xe3a04209, /* mov r4, #0x90000000 */
378 0xe5824000, /* str r4, [r2, #0x0] */
379 /* busy: */
380 0xe5924000, /* ldr r4, [r2, #0x0] */
381 0xe1140005, /* tst r4, r5 */
382 0x1afffffc, /* bne busy */
383 0xe5924014, /* ldr r4, [r2, #0x14] */
384 0xe31400ff, /* tst r4, #0xff */
385 0x03140c01, /* tsteq r4, #0x100 */
386 0x1a000002, /* bne exit */
387 0xe2811008, /* add r1, r1, #0x8 */
388 0xe2533001, /* subs r3, r3, #1 */
389 0x1affffec, /* bne write */
390 /* exit: */
391 0xeafffffe, /* b exit */
392 };
393
394 /* flash write code */
395 if (target_alloc_working_area(target, 4 * 20, &str7x_info->write_algorithm) != ERROR_OK)
396 {
397 LOG_WARNING("no working area available, can't do block memory writes");
398 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
399 };
400
401 target_write_buffer(target, str7x_info->write_algorithm->address, 20 * 4, (u8*)str7x_flash_write_code);
402
403 /* memory buffer */
404 while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK)
405 {
406 buffer_size /= 2;
407 if (buffer_size <= 256)
408 {
409 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
410 if (str7x_info->write_algorithm)
411 target_free_working_area(target, str7x_info->write_algorithm);
412
413 LOG_WARNING("no large enough working area available, can't do block memory writes");
414 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
415 }
416 }
417
418 armv4_5_info.common_magic = ARMV4_5_COMMON_MAGIC;
419 armv4_5_info.core_mode = ARMV4_5_MODE_SVC;
420 armv4_5_info.core_state = ARMV4_5_STATE_ARM;
421
422 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT);
423 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);
424 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);
425 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT);
426 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN);
427 init_reg_param(&reg_params[5], "r5", 32, PARAM_OUT);
428
429 while (count > 0)
430 {
431 u32 thisrun_count = (count > (buffer_size / 8)) ? (buffer_size / 8) : count;
432
433 target_write_buffer(target, source->address, thisrun_count * 8, buffer);
434
435 buf_set_u32(reg_params[0].value, 0, 32, source->address);
436 buf_set_u32(reg_params[1].value, 0, 32, address);
437 buf_set_u32(reg_params[2].value, 0, 32, str7x_get_flash_adr(bank, FLASH_CR0));
438 buf_set_u32(reg_params[3].value, 0, 32, thisrun_count);
439 buf_set_u32(reg_params[5].value, 0, 32, str7x_info->busy_bits);
440
441 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)
442 {
443 LOG_ERROR("error executing str7x flash write algorithm");
444 retval = ERROR_FLASH_OPERATION_FAILED;
445 break;
446 }
447
448 if (buf_get_u32(reg_params[4].value, 0, 32) != 0x00)
449 {
450 retval = ERROR_FLASH_OPERATION_FAILED;
451 break;
452 }
453
454 buffer += thisrun_count * 8;
455 address += thisrun_count * 8;
456 count -= thisrun_count;
457 }
458
459 target_free_working_area(target, source);
460 target_free_working_area(target, str7x_info->write_algorithm);
461
462 destroy_reg_param(&reg_params[0]);
463 destroy_reg_param(&reg_params[1]);
464 destroy_reg_param(&reg_params[2]);
465 destroy_reg_param(&reg_params[3]);
466 destroy_reg_param(&reg_params[4]);
467 destroy_reg_param(&reg_params[5]);
468
469 return retval;
470 }
471
472 int str7x_write(struct flash_bank_s *bank, u8 *buffer, u32 offset, u32 count)
473 {
474 target_t *target = bank->target;
475 str7x_flash_bank_t *str7x_info = bank->driver_priv;
476 u32 dwords_remaining = (count / 8);
477 u32 bytes_remaining = (count & 0x00000007);
478 u32 address = bank->base + offset;
479 u32 bytes_written = 0;
480 u32 cmd;
481 u32 retval;
482 u32 check_address = offset;
483 int i;
484
485 if (bank->target->state != TARGET_HALTED)
486 {
487 LOG_ERROR("Target not halted");
488 return ERROR_TARGET_NOT_HALTED;
489 }
490
491 if (offset & 0x7)
492 {
493 LOG_WARNING("offset 0x%x breaks required 8-byte alignment", offset);
494 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
495 }
496
497 for (i = 0; i < bank->num_sectors; i++)
498 {
499 u32 sec_start = bank->sectors[i].offset;
500 u32 sec_end = sec_start + bank->sectors[i].size;
501
502 /* check if destination falls within the current sector */
503 if ((check_address >= sec_start) && (check_address < sec_end))
504 {
505 /* check if destination ends in the current sector */
506 if (offset + count < sec_end)
507 check_address = offset + count;
508 else
509 check_address = sec_end;
510 }
511 }
512
513 if (check_address != offset + count)
514 return ERROR_FLASH_DST_OUT_OF_BANK;
515
516 /* clear FLASH_ER register */
517 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_ER), 0x0);
518
519 /* multiple dwords (8-byte) to be programmed? */
520 if (dwords_remaining > 0)
521 {
522 /* try using a block write */
523 if ((retval = str7x_write_block(bank, buffer, offset, dwords_remaining)) != ERROR_OK)
524 {
525 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE)
526 {
527 /* if block write failed (no sufficient working area),
528 * we use normal (slow) single dword accesses */
529 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
530 }
531 else if (retval == ERROR_FLASH_OPERATION_FAILED)
532 {
533 /* if an error occured, we examine the reason, and quit */
534 retval = str7x_result(bank);
535
536 LOG_ERROR("flash writing failed with error code: 0x%x", retval);
537 return ERROR_FLASH_OPERATION_FAILED;
538 }
539 }
540 else
541 {
542 buffer += dwords_remaining * 8;
543 address += dwords_remaining * 8;
544 dwords_remaining = 0;
545 }
546 }
547
548 while (dwords_remaining > 0)
549 {
550 /* command */
551 cmd = FLASH_DWPG;
552 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
553
554 /* address */
555 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
556
557 /* data word 1 */
558 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, buffer + bytes_written);
559 bytes_written += 4;
560
561 /* data word 2 */
562 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, buffer + bytes_written);
563 bytes_written += 4;
564
565 /* start programming cycle */
566 cmd = FLASH_DWPG | FLASH_WMS;
567 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
568
569 while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
570 {
571 alive_sleep(1);
572 }
573
574 retval = str7x_result(bank);
575
576 if (retval & FLASH_PGER)
577 return ERROR_FLASH_OPERATION_FAILED;
578 else if (retval & FLASH_WPF)
579 return ERROR_FLASH_OPERATION_FAILED;
580
581 dwords_remaining--;
582 address += 8;
583 }
584
585 if (bytes_remaining)
586 {
587 u8 last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
588 int i = 0;
589
590 while(bytes_remaining > 0)
591 {
592 last_dword[i++] = *(buffer + bytes_written);
593 bytes_remaining--;
594 bytes_written++;
595 }
596
597 /* command */
598 cmd = FLASH_DWPG;
599 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
600
601 /* address */
602 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), address);
603
604 /* data word 1 */
605 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR0), 4, 1, last_dword);
606 bytes_written += 4;
607
608 /* data word 2 */
609 target->type->write_memory(target, str7x_get_flash_adr(bank, FLASH_DR1), 4, 1, last_dword + 4);
610 bytes_written += 4;
611
612 /* start programming cycle */
613 cmd = FLASH_DWPG | FLASH_WMS;
614 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), cmd);
615
616 while (((retval = str7x_status(bank)) & str7x_info->busy_bits))
617 {
618 alive_sleep(1);
619 }
620
621 retval = str7x_result(bank);
622
623 if (retval & FLASH_PGER)
624 return ERROR_FLASH_OPERATION_FAILED;
625 else if (retval & FLASH_WPF)
626 return ERROR_FLASH_OPERATION_FAILED;
627 }
628
629 return ERROR_OK;
630 }
631
632 int str7x_probe(struct flash_bank_s *bank)
633 {
634 return ERROR_OK;
635 }
636
637 int str7x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
638 {
639 return ERROR_OK;
640 }
641
642 int str7x_info(struct flash_bank_s *bank, char *buf, int buf_size)
643 {
644 snprintf(buf, buf_size, "str7x flash driver info" );
645 return ERROR_OK;
646 }
647
648 int str7x_handle_disable_jtag_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
649 {
650 flash_bank_t *bank;
651 target_t *target = NULL;
652 str7x_flash_bank_t *str7x_info = NULL;
653
654 u32 flash_cmd;
655 u32 retval;
656 u16 ProtectionLevel = 0;
657 u16 ProtectionRegs;
658
659 if (argc < 1)
660 {
661 command_print(cmd_ctx, "str7x disable_jtag <bank>");
662 return ERROR_OK;
663 }
664
665 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
666 if (!bank)
667 {
668 command_print(cmd_ctx, "str7x disable_jtag <bank> ok");
669 return ERROR_OK;
670 }
671
672 str7x_info = bank->driver_priv;
673
674 target = bank->target;
675
676 if (target->state != TARGET_HALTED)
677 {
678 LOG_ERROR("Target not halted");
679 return ERROR_TARGET_NOT_HALTED;
680 }
681
682 /* first we get protection status */
683 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR0), &retval);
684
685 if (!(retval & str7x_info->disable_bit))
686 {
687 ProtectionLevel = 1;
688 }
689
690 target_read_u32(target, str7x_get_flash_adr(bank, FLASH_NVAPR1), &retval);
691 ProtectionRegs = ~(retval >> 16);
692
693 while (((ProtectionRegs) != 0) && (ProtectionLevel < 16))
694 {
695 ProtectionRegs >>= 1;
696 ProtectionLevel++;
697 }
698
699 if (ProtectionLevel == 0)
700 {
701 flash_cmd = FLASH_SPR;
702 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
703 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFB8);
704 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), 0xFFFFFFFD);
705 flash_cmd = FLASH_SPR | FLASH_WMS;
706 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
707 }
708 else
709 {
710 flash_cmd = FLASH_SPR;
711 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
712 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_AR), 0x4010DFBC);
713 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_DR0), ~(1<<(15+ProtectionLevel)));
714 flash_cmd = FLASH_SPR | FLASH_WMS;
715 target_write_u32(target, str7x_get_flash_adr(bank, FLASH_CR0), flash_cmd);
716 }
717
718 return ERROR_OK;
719 }
720

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)