1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 #include "replacements.h"
31 #include "algorithm.h"
32 #include "binarybuffer.h"
38 str7x_mem_layout_t mem_layout
[] = {
39 {0x00000000, 0x02000, 0x01},
40 {0x00002000, 0x02000, 0x02},
41 {0x00004000, 0x02000, 0x04},
42 {0x00006000, 0x02000, 0x08},
43 {0x00008000, 0x08000, 0x10},
44 {0x00010000, 0x10000, 0x20},
45 {0x00020000, 0x10000, 0x40},
46 {0x00030000, 0x10000, 0x80},
47 {0x000C0000, 0x02000, 0x10000},
48 {0x000C2000, 0x02000, 0x20000},
51 int str7x_register_commands(struct command_context_s
*cmd_ctx
);
52 int str7x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
53 int str7x_erase(struct flash_bank_s
*bank
, int first
, int last
);
54 int str7x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
55 int str7x_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
56 int str7x_probe(struct flash_bank_s
*bank
);
57 int str7x_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
58 int str7x_protect_check(struct flash_bank_s
*bank
);
59 int str7x_erase_check(struct flash_bank_s
*bank
);
60 int str7x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
62 int str7x_handle_disable_jtag_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
64 flash_driver_t str7x_flash
=
67 .register_commands
= str7x_register_commands
,
68 .flash_bank_command
= str7x_flash_bank_command
,
70 .protect
= str7x_protect
,
73 .auto_probe
= str7x_probe
,
74 .erase_check
= str7x_erase_check
,
75 .protect_check
= str7x_protect_check
,
79 int str7x_register_commands(struct command_context_s
*cmd_ctx
)
81 command_t
*str7x_cmd
= register_command(cmd_ctx
, NULL
, "str7x", NULL
, COMMAND_ANY
, NULL
);
83 register_command(cmd_ctx
, str7x_cmd
, "disable_jtag", str7x_handle_disable_jtag_command
, COMMAND_EXEC
,
84 "disable jtag access");
89 int str7x_get_flash_adr(struct flash_bank_s
*bank
, u32 reg
)
91 return (bank
->base
| reg
);
94 int str7x_build_block_list(struct flash_bank_s
*bank
)
96 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
99 int num_sectors
= 0, b0_sectors
= 0, b1_sectors
= 0;
116 LOG_ERROR("BUG: unknown bank->size encountered");
120 if( str7x_info
->bank1
== 1 )
125 num_sectors
= b0_sectors
+ b1_sectors
;
127 bank
->num_sectors
= num_sectors
;
128 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
129 str7x_info
->sector_bits
= malloc(sizeof(u32
) * num_sectors
);
130 str7x_info
->sector_bank
= malloc(sizeof(u32
) * num_sectors
);
134 for (i
= 0; i
< b0_sectors
; i
++)
136 bank
->sectors
[num_sectors
].offset
= mem_layout
[i
].sector_start
;
137 bank
->sectors
[num_sectors
].size
= mem_layout
[i
].sector_size
;
138 bank
->sectors
[num_sectors
].is_erased
= -1;
139 bank
->sectors
[num_sectors
].is_protected
= 1;
140 str7x_info
->sector_bank
[num_sectors
] = 0;
141 str7x_info
->sector_bits
[num_sectors
++] = mem_layout
[i
].sector_bit
;
146 for (i
= 8; i
< 10; i
++)
148 bank
->sectors
[num_sectors
].offset
= mem_layout
[i
].sector_start
;
149 bank
->sectors
[num_sectors
].size
= mem_layout
[i
].sector_size
;
150 bank
->sectors
[num_sectors
].is_erased
= -1;
151 bank
->sectors
[num_sectors
].is_protected
= 1;
152 str7x_info
->sector_bank
[num_sectors
] = 1;
153 str7x_info
->sector_bits
[num_sectors
++] = mem_layout
[i
].sector_bit
;
160 /* flash bank str7x <base> <size> 0 0 <target#> <str71_variant>
162 int str7x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
164 str7x_flash_bank_t
*str7x_info
;
168 LOG_WARNING("incomplete flash_bank str7x configuration");
169 return ERROR_FLASH_BANK_INVALID
;
172 str7x_info
= malloc(sizeof(str7x_flash_bank_t
));
173 bank
->driver_priv
= str7x_info
;
175 /* set default bits for str71x flash */
176 str7x_info
->bank1
= 1;
177 str7x_info
->busy_bits
= (FLASH_LOCK
|FLASH_BSYA1
|FLASH_BSYA0
);
178 str7x_info
->disable_bit
= (1<<1);
180 if (strcmp(args
[6], "STR71x") == 0)
182 if (bank
->base
!= 0x40000000)
184 LOG_WARNING("overriding flash base address for STR71x device with 0x40000000");
185 bank
->base
= 0x40000000;
188 else if (strcmp(args
[6], "STR73x") == 0)
190 str7x_info
->bank1
= 0;
191 str7x_info
->busy_bits
= (FLASH_LOCK
|FLASH_BSYA0
);
193 if (bank
->base
!= 0x80000000)
195 LOG_WARNING("overriding flash base address for STR73x device with 0x80000000");
196 bank
->base
= 0x80000000;
199 else if (strcmp(args
[6], "STR75x") == 0)
201 str7x_info
->disable_bit
= (1<<0);
203 if (bank
->base
!= 0x20000000)
205 LOG_WARNING("overriding flash base address for STR75x device with 0x20000000");
206 bank
->base
= 0x20000000;
211 LOG_ERROR("unknown STR7x variant: '%s'", args
[6]);
213 return ERROR_FLASH_BANK_INVALID
;
216 str7x_build_block_list(bank
);
218 str7x_info
->write_algorithm
= NULL
;
223 u32
str7x_status(struct flash_bank_s
*bank
)
225 target_t
*target
= bank
->target
;
228 target_read_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), &retval
);
233 u32
str7x_result(struct flash_bank_s
*bank
)
235 target_t
*target
= bank
->target
;
238 target_read_u32(target
, str7x_get_flash_adr(bank
, FLASH_ER
), &retval
);
243 int str7x_blank_check(struct flash_bank_s
*bank
, int first
, int last
)
245 target_t
*target
= bank
->target
;
250 if ((first
< 0) || (last
> bank
->num_sectors
))
251 return ERROR_FLASH_SECTOR_INVALID
;
253 if (bank
->target
->state
!= TARGET_HALTED
)
255 return ERROR_TARGET_NOT_HALTED
;
258 buffer
= malloc(256);
260 for (i
= first
; i
<= last
; i
++)
262 bank
->sectors
[i
].is_erased
= 1;
264 target
->type
->read_memory(target
, bank
->base
+ bank
->sectors
[i
].offset
, 4, 256/4, buffer
);
266 for (nBytes
= 0; nBytes
< 256; nBytes
++)
268 if (buffer
[nBytes
] != 0xFF)
270 bank
->sectors
[i
].is_erased
= 0;
281 int str7x_protect_check(struct flash_bank_s
*bank
)
283 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
284 target_t
*target
= bank
->target
;
289 if (bank
->target
->state
!= TARGET_HALTED
)
291 return ERROR_TARGET_NOT_HALTED
;
294 target_read_u32(target
, str7x_get_flash_adr(bank
, FLASH_NVWPAR
), &retval
);
296 for (i
= 0; i
< bank
->num_sectors
; i
++)
298 if (retval
& str7x_info
->sector_bits
[i
])
299 bank
->sectors
[i
].is_protected
= 0;
301 bank
->sectors
[i
].is_protected
= 1;
307 int str7x_erase(struct flash_bank_s
*bank
, int first
, int last
)
309 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
310 target_t
*target
= bank
->target
;
315 u32 b0_sectors
= 0, b1_sectors
= 0;
317 if (bank
->target
->state
!= TARGET_HALTED
)
319 return ERROR_TARGET_NOT_HALTED
;
322 for (i
= first
; i
<= last
; i
++)
324 if (str7x_info
->sector_bank
[i
] == 0)
325 b0_sectors
|= str7x_info
->sector_bits
[i
];
326 else if (str7x_info
->sector_bank
[i
] == 1)
327 b1_sectors
|= str7x_info
->sector_bits
[i
];
329 LOG_ERROR("BUG: str7x_info->sector_bank[i] neither 0 nor 1 (%i)", str7x_info
->sector_bank
[i
]);
334 LOG_DEBUG("b0_sectors: 0x%x", b0_sectors
);
336 /* clear FLASH_ER register */
337 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_ER
), 0x0);
340 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
343 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR1
), cmd
);
345 cmd
= FLASH_SER
|FLASH_WMS
;
346 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
348 while (((retval
= str7x_status(bank
)) & str7x_info
->busy_bits
)){
352 retval
= str7x_result(bank
);
356 LOG_ERROR("error erasing flash bank, FLASH_ER: 0x%x", retval
);
357 return ERROR_FLASH_OPERATION_FAILED
;
363 LOG_DEBUG("b1_sectors: 0x%x", b1_sectors
);
365 /* clear FLASH_ER register */
366 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_ER
), 0x0);
369 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
372 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR1
), cmd
);
374 cmd
= FLASH_SER
|FLASH_WMS
;
375 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
377 while (((retval
= str7x_status(bank
)) & str7x_info
->busy_bits
)){
381 retval
= str7x_result(bank
);
385 LOG_ERROR("error erasing flash bank, FLASH_ER: 0x%x", retval
);
386 return ERROR_FLASH_OPERATION_FAILED
;
390 for (i
= first
; i
<= last
; i
++)
391 bank
->sectors
[i
].is_erased
= 1;
396 int str7x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
398 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
399 target_t
*target
= bank
->target
;
405 if (bank
->target
->state
!= TARGET_HALTED
)
407 return ERROR_TARGET_NOT_HALTED
;
410 protect_blocks
= 0xFFFFFFFF;
414 for (i
= first
; i
<= last
; i
++)
415 protect_blocks
&= ~(str7x_info
->sector_bits
[i
]);
418 /* clear FLASH_ER register */
419 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_ER
), 0x0);
422 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
424 cmd
= str7x_get_flash_adr(bank
, FLASH_NVWPAR
);
425 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_AR
), cmd
);
427 cmd
= protect_blocks
;
428 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_DR0
), cmd
);
430 cmd
= FLASH_SPR
|FLASH_WMS
;
431 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
433 while (((retval
= str7x_status(bank
)) & str7x_info
->busy_bits
)){
437 retval
= str7x_result(bank
);
439 LOG_DEBUG("retval: 0x%8.8x", retval
);
441 if (retval
& FLASH_ERER
)
442 return ERROR_FLASH_SECTOR_NOT_ERASED
;
443 else if (retval
& FLASH_WPF
)
444 return ERROR_FLASH_OPERATION_FAILED
;
449 int str7x_write_block(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
451 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
452 target_t
*target
= bank
->target
;
453 u32 buffer_size
= 8192;
454 working_area_t
*source
;
455 u32 address
= bank
->base
+ offset
;
456 reg_param_t reg_params
[6];
457 armv4_5_algorithm_t armv4_5_info
;
458 int retval
= ERROR_OK
;
460 u32 str7x_flash_write_code
[] = {
462 0xe3a04201, /* mov r4, #0x10000000 */
463 0xe5824000, /* str r4, [r2, #0x0] */
464 0xe5821010, /* str r1, [r2, #0x10] */
465 0xe4904004, /* ldr r4, [r0], #4 */
466 0xe5824008, /* str r4, [r2, #0x8] */
467 0xe4904004, /* ldr r4, [r0], #4 */
468 0xe582400c, /* str r4, [r2, #0xc] */
469 0xe3a04209, /* mov r4, #0x90000000 */
470 0xe5824000, /* str r4, [r2, #0x0] */
472 0xe5924000, /* ldr r4, [r2, #0x0] */
473 0xe1140005, /* tst r4, r5 */
474 0x1afffffc, /* bne busy */
475 0xe5924014, /* ldr r4, [r2, #0x14] */
476 0xe31400ff, /* tst r4, #0xff */
477 0x03140c01, /* tsteq r4, #0x100 */
478 0x1a000002, /* bne exit */
479 0xe2811008, /* add r1, r1, #0x8 */
480 0xe2533001, /* subs r3, r3, #1 */
481 0x1affffec, /* bne write */
483 0xeafffffe, /* b exit */
486 /* flash write code */
487 if (target_alloc_working_area(target
, 4 * 20, &str7x_info
->write_algorithm
) != ERROR_OK
)
489 LOG_WARNING("no working area available, can't do block memory writes");
490 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
493 target_write_buffer(target
, str7x_info
->write_algorithm
->address
, 20 * 4, (u8
*)str7x_flash_write_code
);
496 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
499 if (buffer_size
<= 256)
501 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
502 if (str7x_info
->write_algorithm
)
503 target_free_working_area(target
, str7x_info
->write_algorithm
);
505 LOG_WARNING("no large enough working area available, can't do block memory writes");
506 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
510 armv4_5_info
.common_magic
= ARMV4_5_COMMON_MAGIC
;
511 armv4_5_info
.core_mode
= ARMV4_5_MODE_SVC
;
512 armv4_5_info
.core_state
= ARMV4_5_STATE_ARM
;
514 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
515 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
516 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
517 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
518 init_reg_param(®_params
[4], "r4", 32, PARAM_IN
);
519 init_reg_param(®_params
[5], "r5", 32, PARAM_OUT
);
523 u32 thisrun_count
= (count
> (buffer_size
/ 8)) ? (buffer_size
/ 8) : count
;
525 target_write_buffer(target
, source
->address
, thisrun_count
* 8, buffer
);
527 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
528 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
529 buf_set_u32(reg_params
[2].value
, 0, 32, str7x_get_flash_adr(bank
, FLASH_CR0
));
530 buf_set_u32(reg_params
[3].value
, 0, 32, thisrun_count
);
531 buf_set_u32(reg_params
[5].value
, 0, 32, str7x_info
->busy_bits
);
533 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
)
535 LOG_ERROR("error executing str7x flash write algorithm");
539 if (buf_get_u32(reg_params
[4].value
, 0, 32) != 0x00)
541 retval
= ERROR_FLASH_OPERATION_FAILED
;
545 buffer
+= thisrun_count
* 8;
546 address
+= thisrun_count
* 8;
547 count
-= thisrun_count
;
550 target_free_working_area(target
, source
);
551 target_free_working_area(target
, str7x_info
->write_algorithm
);
553 destroy_reg_param(®_params
[0]);
554 destroy_reg_param(®_params
[1]);
555 destroy_reg_param(®_params
[2]);
556 destroy_reg_param(®_params
[3]);
557 destroy_reg_param(®_params
[4]);
558 destroy_reg_param(®_params
[5]);
563 int str7x_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
565 target_t
*target
= bank
->target
;
566 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
567 u32 dwords_remaining
= (count
/ 8);
568 u32 bytes_remaining
= (count
& 0x00000007);
569 u32 address
= bank
->base
+ offset
;
570 u32 bytes_written
= 0;
573 u32 check_address
= offset
;
576 if (bank
->target
->state
!= TARGET_HALTED
)
578 return ERROR_TARGET_NOT_HALTED
;
583 LOG_WARNING("offset 0x%x breaks required 8-byte alignment", offset
);
584 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
587 for (i
= 0; i
< bank
->num_sectors
; i
++)
589 u32 sec_start
= bank
->sectors
[i
].offset
;
590 u32 sec_end
= sec_start
+ bank
->sectors
[i
].size
;
592 /* check if destination falls within the current sector */
593 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
595 /* check if destination ends in the current sector */
596 if (offset
+ count
< sec_end
)
597 check_address
= offset
+ count
;
599 check_address
= sec_end
;
603 if (check_address
!= offset
+ count
)
604 return ERROR_FLASH_DST_OUT_OF_BANK
;
606 /* clear FLASH_ER register */
607 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_ER
), 0x0);
609 /* multiple dwords (8-byte) to be programmed? */
610 if (dwords_remaining
> 0)
612 /* try using a block write */
613 if ((retval
= str7x_write_block(bank
, buffer
, offset
, dwords_remaining
)) != ERROR_OK
)
615 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
617 /* if block write failed (no sufficient working area),
618 * we use normal (slow) single dword accesses */
619 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
621 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
623 /* if an error occured, we examine the reason, and quit */
624 retval
= str7x_result(bank
);
626 LOG_ERROR("flash writing failed with error code: 0x%x", retval
);
627 return ERROR_FLASH_OPERATION_FAILED
;
632 buffer
+= dwords_remaining
* 8;
633 address
+= dwords_remaining
* 8;
634 dwords_remaining
= 0;
638 while (dwords_remaining
> 0)
642 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
645 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_AR
), address
);
648 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_DR0
), 4, 1, buffer
+ bytes_written
);
652 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_DR1
), 4, 1, buffer
+ bytes_written
);
655 /* start programming cycle */
656 cmd
= FLASH_DWPG
| FLASH_WMS
;
657 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
659 while (((retval
= str7x_status(bank
)) & str7x_info
->busy_bits
))
664 retval
= str7x_result(bank
);
666 if (retval
& FLASH_PGER
)
667 return ERROR_FLASH_OPERATION_FAILED
;
668 else if (retval
& FLASH_WPF
)
669 return ERROR_FLASH_OPERATION_FAILED
;
677 u8 last_dword
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
680 while(bytes_remaining
> 0)
682 last_dword
[i
++] = *(buffer
+ bytes_written
);
689 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
692 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_AR
), address
);
695 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_DR0
), 4, 1, last_dword
);
699 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_DR1
), 4, 1, last_dword
+ 4);
702 /* start programming cycle */
703 cmd
= FLASH_DWPG
| FLASH_WMS
;
704 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
706 while (((retval
= str7x_status(bank
)) & str7x_info
->busy_bits
))
711 retval
= str7x_result(bank
);
713 if (retval
& FLASH_PGER
)
714 return ERROR_FLASH_OPERATION_FAILED
;
715 else if (retval
& FLASH_WPF
)
716 return ERROR_FLASH_OPERATION_FAILED
;
722 int str7x_probe(struct flash_bank_s
*bank
)
727 int str7x_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
732 int str7x_erase_check(struct flash_bank_s
*bank
)
734 return str7x_blank_check(bank
, 0, bank
->num_sectors
- 1);
737 int str7x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
739 snprintf(buf
, buf_size
, "str7x flash driver info" );
743 int str7x_handle_disable_jtag_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
746 target_t
*target
= NULL
;
747 str7x_flash_bank_t
*str7x_info
= NULL
;
751 u16 ProtectionLevel
= 0;
756 command_print(cmd_ctx
, "str7x disable_jtag <bank>");
760 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
763 command_print(cmd_ctx
, "str7x disable_jtag <bank> ok");
767 str7x_info
= bank
->driver_priv
;
769 target
= bank
->target
;
771 if (target
->state
!= TARGET_HALTED
)
773 return ERROR_TARGET_NOT_HALTED
;
776 /* first we get protection status */
777 target_read_u32(target
, str7x_get_flash_adr(bank
, FLASH_NVAPR0
), &retval
);
779 if (!(retval
& str7x_info
->disable_bit
))
784 target_read_u32(target
, str7x_get_flash_adr(bank
, FLASH_NVAPR1
), &retval
);
785 ProtectionRegs
= ~(retval
>> 16);
787 while (((ProtectionRegs
) != 0) && (ProtectionLevel
< 16))
789 ProtectionRegs
>>= 1;
793 if (ProtectionLevel
== 0)
795 flash_cmd
= FLASH_SPR
;
796 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), flash_cmd
);
797 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_AR
), 0x4010DFB8);
798 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_DR0
), 0xFFFFFFFD);
799 flash_cmd
= FLASH_SPR
| FLASH_WMS
;
800 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), flash_cmd
);
804 flash_cmd
= FLASH_SPR
;
805 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), flash_cmd
);
806 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_AR
), 0x4010DFBC);
807 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_DR0
), ~(1<<(15+ProtectionLevel
)));
808 flash_cmd
= FLASH_SPR
| FLASH_WMS
;
809 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), flash_cmd
);
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)