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

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)