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 .erase_check
= str7x_erase_check
,
74 .protect_check
= str7x_protect_check
,
78 int str7x_register_commands(struct command_context_s
*cmd_ctx
)
80 command_t
*str7x_cmd
= register_command(cmd_ctx
, NULL
, "str7x", NULL
, COMMAND_ANY
, NULL
);
82 register_command(cmd_ctx
, str7x_cmd
, "disable_jtag", str7x_handle_disable_jtag_command
, COMMAND_EXEC
,
83 "disable jtag access");
88 int str7x_get_flash_adr(struct flash_bank_s
*bank
, u32 reg
)
90 return (bank
->base
| reg
);
93 int str7x_build_block_list(struct flash_bank_s
*bank
)
95 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
98 int num_sectors
= 0, b0_sectors
= 0, b1_sectors
= 0;
115 ERROR("BUG: unknown bank->size encountered");
119 if( str7x_info
->bank1
== 1 )
124 num_sectors
= b0_sectors
+ b1_sectors
;
126 bank
->num_sectors
= num_sectors
;
127 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
128 str7x_info
->sector_bits
= malloc(sizeof(u32
) * num_sectors
);
129 str7x_info
->sector_bank
= malloc(sizeof(u32
) * num_sectors
);
133 for (i
= 0; i
< b0_sectors
; i
++)
135 bank
->sectors
[num_sectors
].offset
= mem_layout
[i
].sector_start
;
136 bank
->sectors
[num_sectors
].size
= mem_layout
[i
].sector_size
;
137 bank
->sectors
[num_sectors
].is_erased
= -1;
138 bank
->sectors
[num_sectors
].is_protected
= 1;
139 str7x_info
->sector_bank
[num_sectors
] = 0;
140 str7x_info
->sector_bits
[num_sectors
++] = mem_layout
[i
].sector_bit
;
145 for (i
= 8; i
< 10; i
++)
147 bank
->sectors
[num_sectors
].offset
= mem_layout
[i
].sector_start
;
148 bank
->sectors
[num_sectors
].size
= mem_layout
[i
].sector_size
;
149 bank
->sectors
[num_sectors
].is_erased
= -1;
150 bank
->sectors
[num_sectors
].is_protected
= 1;
151 str7x_info
->sector_bank
[num_sectors
] = 1;
152 str7x_info
->sector_bits
[num_sectors
++] = mem_layout
[i
].sector_bit
;
159 /* flash bank str7x <base> <size> 0 0 <target#> <str71_variant>
161 int str7x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
163 str7x_flash_bank_t
*str7x_info
;
167 WARNING("incomplete flash_bank str7x configuration");
168 return ERROR_FLASH_BANK_INVALID
;
171 str7x_info
= malloc(sizeof(str7x_flash_bank_t
));
172 bank
->driver_priv
= str7x_info
;
174 /* set default bits for str71x flash */
175 str7x_info
->bank1
= 1;
176 str7x_info
->busy_bits
= (FLASH_LOCK
|FLASH_BSYA1
|FLASH_BSYA0
);
177 str7x_info
->disable_bit
= (1<<1);
179 if (strcmp(args
[6], "STR71x") == 0)
181 if (bank
->base
!= 0x40000000)
183 WARNING("overriding flash base address for STR71x device with 0x40000000");
184 bank
->base
= 0x40000000;
187 else if (strcmp(args
[6], "STR73x") == 0)
189 str7x_info
->bank1
= 0;
190 str7x_info
->busy_bits
= (FLASH_LOCK
|FLASH_BSYA0
);
192 if (bank
->base
!= 0x80000000)
194 WARNING("overriding flash base address for STR73x device with 0x80000000");
195 bank
->base
= 0x80000000;
198 else if (strcmp(args
[6], "STR75x") == 0)
200 str7x_info
->disable_bit
= (1<<0);
202 if (bank
->base
!= 0x20000000)
204 WARNING("overriding flash base address for STR75x device with 0x20000000");
205 bank
->base
= 0x20000000;
210 ERROR("unknown STR7x variant: '%s'", args
[6]);
212 return ERROR_FLASH_BANK_INVALID
;
215 str7x_build_block_list(bank
);
217 str7x_info
->write_algorithm
= NULL
;
222 u32
str7x_status(struct flash_bank_s
*bank
)
224 target_t
*target
= bank
->target
;
227 target_read_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), &retval
);
232 u32
str7x_result(struct flash_bank_s
*bank
)
234 target_t
*target
= bank
->target
;
237 target_read_u32(target
, str7x_get_flash_adr(bank
, FLASH_ER
), &retval
);
242 int str7x_blank_check(struct flash_bank_s
*bank
, int first
, int last
)
244 target_t
*target
= bank
->target
;
249 if ((first
< 0) || (last
> bank
->num_sectors
))
250 return ERROR_FLASH_SECTOR_INVALID
;
252 if (bank
->target
->state
!= TARGET_HALTED
)
254 return ERROR_TARGET_NOT_HALTED
;
257 buffer
= malloc(256);
259 for (i
= first
; i
<= last
; i
++)
261 bank
->sectors
[i
].is_erased
= 1;
263 target
->type
->read_memory(target
, bank
->base
+ bank
->sectors
[i
].offset
, 4, 256/4, buffer
);
265 for (nBytes
= 0; nBytes
< 256; nBytes
++)
267 if (buffer
[nBytes
] != 0xFF)
269 bank
->sectors
[i
].is_erased
= 0;
280 int str7x_protect_check(struct flash_bank_s
*bank
)
282 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
283 target_t
*target
= bank
->target
;
288 if (bank
->target
->state
!= TARGET_HALTED
)
290 return ERROR_TARGET_NOT_HALTED
;
293 target_read_u32(target
, str7x_get_flash_adr(bank
, FLASH_NVWPAR
), &retval
);
295 for (i
= 0; i
< bank
->num_sectors
; i
++)
297 if (retval
& str7x_info
->sector_bits
[i
])
298 bank
->sectors
[i
].is_protected
= 0;
300 bank
->sectors
[i
].is_protected
= 1;
306 int str7x_erase(struct flash_bank_s
*bank
, int first
, int last
)
308 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
309 target_t
*target
= bank
->target
;
314 u32 b0_sectors
= 0, b1_sectors
= 0;
316 if (bank
->target
->state
!= TARGET_HALTED
)
318 return ERROR_TARGET_NOT_HALTED
;
321 for (i
= first
; i
<= last
; i
++)
323 if (str7x_info
->sector_bank
[i
] == 0)
324 b0_sectors
|= str7x_info
->sector_bits
[i
];
325 else if (str7x_info
->sector_bank
[i
] == 1)
326 b1_sectors
|= str7x_info
->sector_bits
[i
];
328 ERROR("BUG: str7x_info->sector_bank[i] neither 0 nor 1 (%i)", str7x_info
->sector_bank
[i
]);
333 DEBUG("b0_sectors: 0x%x", b0_sectors
);
335 /* clear FLASH_ER register */
336 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_ER
), 0x0);
339 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
342 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR1
), cmd
);
344 cmd
= FLASH_SER
|FLASH_WMS
;
345 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
347 while (((retval
= str7x_status(bank
)) & str7x_info
->busy_bits
)){
351 retval
= str7x_result(bank
);
355 ERROR("error erasing flash bank, FLASH_ER: 0x%x", retval
);
356 return ERROR_FLASH_OPERATION_FAILED
;
362 DEBUG("b1_sectors: 0x%x", b1_sectors
);
364 /* clear FLASH_ER register */
365 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_ER
), 0x0);
368 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
371 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR1
), cmd
);
373 cmd
= FLASH_SER
|FLASH_WMS
;
374 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
376 while (((retval
= str7x_status(bank
)) & str7x_info
->busy_bits
)){
380 retval
= str7x_result(bank
);
384 ERROR("error erasing flash bank, FLASH_ER: 0x%x", retval
);
385 return ERROR_FLASH_OPERATION_FAILED
;
389 for (i
= first
; i
<= last
; i
++)
390 bank
->sectors
[i
].is_erased
= 1;
395 int str7x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
397 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
398 target_t
*target
= bank
->target
;
404 if (bank
->target
->state
!= TARGET_HALTED
)
406 return ERROR_TARGET_NOT_HALTED
;
409 protect_blocks
= 0xFFFFFFFF;
413 for (i
= first
; i
<= last
; i
++)
414 protect_blocks
&= ~(str7x_info
->sector_bits
[i
]);
417 /* clear FLASH_ER register */
418 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_ER
), 0x0);
421 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
423 cmd
= str7x_get_flash_adr(bank
, FLASH_NVWPAR
);
424 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_AR
), cmd
);
426 cmd
= protect_blocks
;
427 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_DR0
), cmd
);
429 cmd
= FLASH_SPR
|FLASH_WMS
;
430 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
432 while (((retval
= str7x_status(bank
)) & str7x_info
->busy_bits
)){
436 retval
= str7x_result(bank
);
438 DEBUG("retval: 0x%8.8x", retval
);
440 if (retval
& FLASH_ERER
)
441 return ERROR_FLASH_SECTOR_NOT_ERASED
;
442 else if (retval
& FLASH_WPF
)
443 return ERROR_FLASH_OPERATION_FAILED
;
448 int str7x_write_block(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
450 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
451 target_t
*target
= bank
->target
;
452 u32 buffer_size
= 8192;
453 working_area_t
*source
;
454 u32 address
= bank
->base
+ offset
;
455 reg_param_t reg_params
[6];
456 armv4_5_algorithm_t armv4_5_info
;
457 int retval
= ERROR_OK
;
459 u32 str7x_flash_write_code
[] = {
461 0xe3a04201, /* mov r4, #0x10000000 */
462 0xe5824000, /* str r4, [r2, #0x0] */
463 0xe5821010, /* str r1, [r2, #0x10] */
464 0xe4904004, /* ldr r4, [r0], #4 */
465 0xe5824008, /* str r4, [r2, #0x8] */
466 0xe4904004, /* ldr r4, [r0], #4 */
467 0xe582400c, /* str r4, [r2, #0xc] */
468 0xe3a04209, /* mov r4, #0x90000000 */
469 0xe5824000, /* str r4, [r2, #0x0] */
471 0xe5924000, /* ldr r4, [r2, #0x0] */
472 0xe1140005, /* tst r4, r5 */
473 0x1afffffc, /* bne busy */
474 0xe5924014, /* ldr r4, [r2, #0x14] */
475 0xe31400ff, /* tst r4, #0xff */
476 0x03140c01, /* tsteq r4, #0x100 */
477 0x1a000002, /* bne exit */
478 0xe2811008, /* add r1, r1, #0x8 */
479 0xe2533001, /* subs r3, r3, #1 */
480 0x1affffec, /* bne write */
482 0xeafffffe, /* b exit */
485 /* flash write code */
486 if (target_alloc_working_area(target
, 4 * 20, &str7x_info
->write_algorithm
) != ERROR_OK
)
488 WARNING("no working area available, can't do block memory writes");
489 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
492 target_write_buffer(target
, str7x_info
->write_algorithm
->address
, 20 * 4, (u8
*)str7x_flash_write_code
);
495 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
498 if (buffer_size
<= 256)
500 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
501 if (str7x_info
->write_algorithm
)
502 target_free_working_area(target
, str7x_info
->write_algorithm
);
504 WARNING("no large enough working area available, can't do block memory writes");
505 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
509 armv4_5_info
.common_magic
= ARMV4_5_COMMON_MAGIC
;
510 armv4_5_info
.core_mode
= ARMV4_5_MODE_SVC
;
511 armv4_5_info
.core_state
= ARMV4_5_STATE_ARM
;
513 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
514 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
515 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
516 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
);
517 init_reg_param(®_params
[4], "r4", 32, PARAM_IN
);
518 init_reg_param(®_params
[5], "r5", 32, PARAM_OUT
);
522 u32 thisrun_count
= (count
> (buffer_size
/ 8)) ? (buffer_size
/ 8) : count
;
524 target_write_buffer(target
, source
->address
, thisrun_count
* 8, buffer
);
526 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
527 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
528 buf_set_u32(reg_params
[2].value
, 0, 32, str7x_get_flash_adr(bank
, FLASH_CR0
));
529 buf_set_u32(reg_params
[3].value
, 0, 32, thisrun_count
);
530 buf_set_u32(reg_params
[5].value
, 0, 32, str7x_info
->busy_bits
);
532 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
)
534 ERROR("error executing str7x flash write algorithm");
538 if (buf_get_u32(reg_params
[4].value
, 0, 32) != 0x00)
540 retval
= ERROR_FLASH_OPERATION_FAILED
;
544 buffer
+= thisrun_count
* 8;
545 address
+= thisrun_count
* 8;
546 count
-= thisrun_count
;
549 target_free_working_area(target
, source
);
550 target_free_working_area(target
, str7x_info
->write_algorithm
);
552 destroy_reg_param(®_params
[0]);
553 destroy_reg_param(®_params
[1]);
554 destroy_reg_param(®_params
[2]);
555 destroy_reg_param(®_params
[3]);
556 destroy_reg_param(®_params
[4]);
557 destroy_reg_param(®_params
[5]);
562 int str7x_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
564 target_t
*target
= bank
->target
;
565 str7x_flash_bank_t
*str7x_info
= bank
->driver_priv
;
566 u32 dwords_remaining
= (count
/ 8);
567 u32 bytes_remaining
= (count
& 0x00000007);
568 u32 address
= bank
->base
+ offset
;
569 u32 bytes_written
= 0;
572 u32 check_address
= offset
;
575 if (bank
->target
->state
!= TARGET_HALTED
)
577 return ERROR_TARGET_NOT_HALTED
;
582 WARNING("offset 0x%x breaks required 8-byte alignment", offset
);
583 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
586 for (i
= 0; i
< bank
->num_sectors
; i
++)
588 u32 sec_start
= bank
->sectors
[i
].offset
;
589 u32 sec_end
= sec_start
+ bank
->sectors
[i
].size
;
591 /* check if destination falls within the current sector */
592 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
594 /* check if destination ends in the current sector */
595 if (offset
+ count
< sec_end
)
596 check_address
= offset
+ count
;
598 check_address
= sec_end
;
602 if (check_address
!= offset
+ count
)
603 return ERROR_FLASH_DST_OUT_OF_BANK
;
605 /* clear FLASH_ER register */
606 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_ER
), 0x0);
608 /* multiple dwords (8-byte) to be programmed? */
609 if (dwords_remaining
> 0)
611 /* try using a block write */
612 if ((retval
= str7x_write_block(bank
, buffer
, offset
, dwords_remaining
)) != ERROR_OK
)
614 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
616 /* if block write failed (no sufficient working area),
617 * we use normal (slow) single dword accesses */
618 WARNING("couldn't use block writes, falling back to single memory accesses");
620 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
622 /* if an error occured, we examine the reason, and quit */
623 retval
= str7x_result(bank
);
625 ERROR("flash writing failed with error code: 0x%x", retval
);
626 return ERROR_FLASH_OPERATION_FAILED
;
631 buffer
+= dwords_remaining
* 8;
632 address
+= dwords_remaining
* 8;
633 dwords_remaining
= 0;
637 while (dwords_remaining
> 0)
641 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
644 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_AR
), address
);
647 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_DR0
), 4, 1, buffer
+ bytes_written
);
651 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_DR1
), 4, 1, buffer
+ bytes_written
);
654 /* start programming cycle */
655 cmd
= FLASH_DWPG
| FLASH_WMS
;
656 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
658 while (((retval
= str7x_status(bank
)) & str7x_info
->busy_bits
))
663 retval
= str7x_result(bank
);
665 if (retval
& FLASH_PGER
)
666 return ERROR_FLASH_OPERATION_FAILED
;
667 else if (retval
& FLASH_WPF
)
668 return ERROR_FLASH_OPERATION_FAILED
;
676 u8 last_dword
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
679 while(bytes_remaining
> 0)
681 last_dword
[i
++] = *(buffer
+ bytes_written
);
688 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
691 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_AR
), address
);
694 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_DR0
), 4, 1, last_dword
);
698 target
->type
->write_memory(target
, str7x_get_flash_adr(bank
, FLASH_DR1
), 4, 1, last_dword
+ 4);
701 /* start programming cycle */
702 cmd
= FLASH_DWPG
| FLASH_WMS
;
703 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), cmd
);
705 while (((retval
= str7x_status(bank
)) & str7x_info
->busy_bits
))
710 retval
= str7x_result(bank
);
712 if (retval
& FLASH_PGER
)
713 return ERROR_FLASH_OPERATION_FAILED
;
714 else if (retval
& FLASH_WPF
)
715 return ERROR_FLASH_OPERATION_FAILED
;
721 int str7x_probe(struct flash_bank_s
*bank
)
726 int str7x_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
731 int str7x_erase_check(struct flash_bank_s
*bank
)
733 return str7x_blank_check(bank
, 0, bank
->num_sectors
- 1);
736 int str7x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
738 snprintf(buf
, buf_size
, "str7x flash driver info" );
742 int str7x_handle_disable_jtag_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
745 target_t
*target
= NULL
;
746 str7x_flash_bank_t
*str7x_info
= NULL
;
750 u16 ProtectionLevel
= 0;
755 command_print(cmd_ctx
, "str7x disable_jtag <bank>");
759 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
762 command_print(cmd_ctx
, "str7x disable_jtag <bank> ok");
766 str7x_info
= bank
->driver_priv
;
768 target
= bank
->target
;
770 if (target
->state
!= TARGET_HALTED
)
772 return ERROR_TARGET_NOT_HALTED
;
775 /* first we get protection status */
776 target_read_u32(target
, str7x_get_flash_adr(bank
, FLASH_NVAPR0
), &retval
);
778 if (!(retval
& str7x_info
->disable_bit
))
783 target_read_u32(target
, str7x_get_flash_adr(bank
, FLASH_NVAPR1
), &retval
);
784 ProtectionRegs
= ~(retval
>> 16);
786 while (((ProtectionRegs
) != 0) && (ProtectionLevel
< 16))
788 ProtectionRegs
>>= 1;
792 if (ProtectionLevel
== 0)
794 flash_cmd
= FLASH_SPR
;
795 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), flash_cmd
);
796 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_AR
), 0x4010DFB8);
797 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_DR0
), 0xFFFFFFFD);
798 flash_cmd
= FLASH_SPR
| FLASH_WMS
;
799 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), flash_cmd
);
803 flash_cmd
= FLASH_SPR
;
804 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_CR0
), flash_cmd
);
805 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_AR
), 0x4010DFBC);
806 target_write_u32(target
, str7x_get_flash_adr(bank
, FLASH_DR0
), ~(1<<(15+ProtectionLevel
)));
807 flash_cmd
= FLASH_SPR
| FLASH_WMS
;
808 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)