1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
8 * Copyright (C) 2008 by Oyvind Harboe *
9 * oyvind.harboe@zylin.com *
11 * This program is free software; you can redistribute it and/or modify *
12 * it under the terms of the GNU General Public License as published by *
13 * the Free Software Foundation; either version 2 of the License, or *
14 * (at your option) any later version. *
16 * This program is distributed in the hope that it will be useful, *
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
19 * GNU General Public License for more details. *
21 * You should have received a copy of the GNU General Public License *
22 * along with this program; if not, write to the *
23 * Free Software Foundation, Inc., *
24 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
25 ***************************************************************************/
30 #include "replacements.h"
38 #include "algorithm.h"
39 #include "binarybuffer.h"
45 static u32 bank1start
= 0x00080000;
47 int str9x_register_commands(struct command_context_s
*cmd_ctx
);
48 int str9x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
49 int str9x_erase(struct flash_bank_s
*bank
, int first
, int last
);
50 int str9x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
51 int str9x_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
52 int str9x_probe(struct flash_bank_s
*bank
);
53 int str9x_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
54 int str9x_protect_check(struct flash_bank_s
*bank
);
55 int str9x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
57 int str9x_handle_flash_config_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
59 flash_driver_t str9x_flash
=
62 .register_commands
= str9x_register_commands
,
63 .flash_bank_command
= str9x_flash_bank_command
,
65 .protect
= str9x_protect
,
68 .auto_probe
= str9x_probe
,
69 .erase_check
= default_flash_blank_check
,
70 .protect_check
= str9x_protect_check
,
74 int str9x_register_commands(struct command_context_s
*cmd_ctx
)
76 command_t
*str9x_cmd
= register_command(cmd_ctx
, NULL
, "str9x", NULL
, COMMAND_ANY
, NULL
);
78 register_command(cmd_ctx
, str9x_cmd
, "flash_config", str9x_handle_flash_config_command
, COMMAND_EXEC
,
79 "configure str9 flash controller");
84 int str9x_build_block_list(struct flash_bank_s
*bank
)
86 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
90 int b0_sectors
= 0, b1_sectors
= 0;
93 /* set if we have large flash str9 */
94 str9x_info
->variant
= 0;
95 str9x_info
->bank1
= 0;
106 bank1start
= 0x00100000;
107 str9x_info
->variant
= 1;
111 bank1start
= 0x00200000;
112 str9x_info
->variant
= 1;
116 str9x_info
->variant
= 1;
117 str9x_info
->bank1
= 1;
119 bank1start
= bank
->base
;
122 str9x_info
->bank1
= 1;
124 bank1start
= bank
->base
;
127 LOG_ERROR("BUG: unknown bank->size encountered");
131 num_sectors
= b0_sectors
+ b1_sectors
;
133 bank
->num_sectors
= num_sectors
;
134 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
135 str9x_info
->sector_bits
= malloc(sizeof(u32
) * num_sectors
);
139 for (i
= 0; i
< b0_sectors
; i
++)
141 bank
->sectors
[num_sectors
].offset
= offset
;
142 bank
->sectors
[num_sectors
].size
= 0x10000;
143 offset
+= bank
->sectors
[i
].size
;
144 bank
->sectors
[num_sectors
].is_erased
= -1;
145 bank
->sectors
[num_sectors
].is_protected
= 1;
146 str9x_info
->sector_bits
[num_sectors
++] = (1<<i
);
149 for (i
= 0; i
< b1_sectors
; i
++)
151 bank
->sectors
[num_sectors
].offset
= offset
;
152 bank
->sectors
[num_sectors
].size
= str9x_info
->variant
== 0 ? 0x2000 : 0x4000;
153 offset
+= bank
->sectors
[i
].size
;
154 bank
->sectors
[num_sectors
].is_erased
= -1;
155 bank
->sectors
[num_sectors
].is_protected
= 1;
156 if (str9x_info
->variant
)
157 str9x_info
->sector_bits
[num_sectors
++] = (1<<i
);
159 str9x_info
->sector_bits
[num_sectors
++] = (1<<(i
+8));
165 /* flash bank str9x <base> <size> 0 0 <target#>
167 int str9x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
169 str9x_flash_bank_t
*str9x_info
;
173 LOG_WARNING("incomplete flash_bank str9x configuration");
174 return ERROR_FLASH_BANK_INVALID
;
177 str9x_info
= malloc(sizeof(str9x_flash_bank_t
));
178 bank
->driver_priv
= str9x_info
;
180 str9x_build_block_list(bank
);
182 str9x_info
->write_algorithm
= NULL
;
187 int str9x_protect_check(struct flash_bank_s
*bank
)
190 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
191 target_t
*target
= bank
->target
;
197 if (bank
->target
->state
!= TARGET_HALTED
)
199 LOG_ERROR("Target not halted");
200 return ERROR_TARGET_NOT_HALTED
;
203 /* read level one protection */
205 if (str9x_info
->variant
)
207 if (str9x_info
->bank1
)
209 adr
= bank1start
+ 0x18;
210 if ((retval
=target_write_u16(target
, adr
, 0x90))!=ERROR_OK
)
214 if ((retval
=target_read_u16(target
, adr
, (u16
*)&status
))!=ERROR_OK
)
221 adr
= bank1start
+ 0x14;
222 if ((retval
=target_write_u16(target
, adr
, 0x90))!=ERROR_OK
)
226 if ((retval
=target_read_u32(target
, adr
, &status
))!=ERROR_OK
)
234 adr
= bank1start
+ 0x10;
235 if ((retval
=target_write_u16(target
, adr
, 0x90))!=ERROR_OK
)
239 if ((retval
=target_read_u16(target
, adr
, (u16
*)&status
))!=ERROR_OK
)
245 /* read array command */
246 if ((retval
=target_write_u16(target
, adr
, 0xFF))!=ERROR_OK
)
251 for (i
= 0; i
< bank
->num_sectors
; i
++)
253 if (status
& str9x_info
->sector_bits
[i
])
254 bank
->sectors
[i
].is_protected
= 1;
256 bank
->sectors
[i
].is_protected
= 0;
262 int str9x_erase(struct flash_bank_s
*bank
, int first
, int last
)
264 target_t
*target
= bank
->target
;
270 if (bank
->target
->state
!= TARGET_HALTED
)
272 LOG_ERROR("Target not halted");
273 return ERROR_TARGET_NOT_HALTED
;
276 /* Check if we erase whole bank */
277 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)))
279 /* Optimize to run erase bank command instead of sector */
284 /* Erase sector command */
288 for (i
= first
; i
<= last
; i
++)
291 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
294 if ((retval
=target_write_u16(target
, adr
, erase_cmd
))!=ERROR_OK
)
298 if ((retval
=target_write_u16(target
, adr
, 0xD0))!=ERROR_OK
)
304 if ((retval
=target_write_u16(target
, adr
, 0x70))!=ERROR_OK
)
310 for (timeout
=0; timeout
<1000; timeout
++) {
311 if ((retval
=target_read_u8(target
, adr
, &status
))!=ERROR_OK
)
321 LOG_ERROR("erase timed out");
325 /* clear status, also clear read array */
326 if ((retval
=target_write_u16(target
, adr
, 0x50))!=ERROR_OK
)
331 /* read array command */
332 if ((retval
=target_write_u16(target
, adr
, 0xFF))!=ERROR_OK
)
339 LOG_ERROR("error erasing flash bank, status: 0x%x", status
);
340 return ERROR_FLASH_OPERATION_FAILED
;
343 /* If we ran erase bank command, we are finished */
344 if (erase_cmd
== 0x80)
348 for (i
= first
; i
<= last
; i
++)
349 bank
->sectors
[i
].is_erased
= 1;
354 int str9x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
356 target_t
*target
= bank
->target
;
361 if (bank
->target
->state
!= TARGET_HALTED
)
363 LOG_ERROR("Target not halted");
364 return ERROR_TARGET_NOT_HALTED
;
367 for (i
= first
; i
<= last
; i
++)
369 /* Level One Protection */
371 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
373 target_write_u16(target
, adr
, 0x60);
375 target_write_u16(target
, adr
, 0x01);
377 target_write_u16(target
, adr
, 0xD0);
380 target_read_u8(target
, adr
, &status
);
382 /* clear status, also clear read array */
383 target_write_u16(target
, adr
, 0x50);
385 /* read array command */
386 target_write_u16(target
, adr
, 0xFF);
392 int str9x_write_block(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
394 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
395 target_t
*target
= bank
->target
;
396 u32 buffer_size
= 8192;
397 working_area_t
*source
;
398 u32 address
= bank
->base
+ offset
;
399 reg_param_t reg_params
[4];
400 armv4_5_algorithm_t armv4_5_info
;
401 int retval
= ERROR_OK
;
403 u32 str9x_flash_write_code
[] = {
405 0xe3c14003, /* bic r4, r1, #3 */
406 0xe3a03040, /* mov r3, #0x40 */
407 0xe1c430b0, /* strh r3, [r4, #0] */
408 0xe0d030b2, /* ldrh r3, [r0], #2 */
409 0xe0c130b2, /* strh r3, [r1], #2 */
410 0xe3a03070, /* mov r3, #0x70 */
411 0xe1c430b0, /* strh r3, [r4, #0] */
413 0xe5d43000, /* ldrb r3, [r4, #0] */
414 0xe3130080, /* tst r3, #0x80 */
415 0x0afffffc, /* beq busy */
416 0xe3a05050, /* mov r5, #0x50 */
417 0xe1c450b0, /* strh r5, [r4, #0] */
418 0xe3a050ff, /* mov r5, #0xFF */
419 0xe1c450b0, /* strh r5, [r4, #0] */
420 0xe3130012, /* tst r3, #0x12 */
421 0x1a000001, /* bne exit */
422 0xe2522001, /* subs r2, r2, #1 */
423 0x1affffed, /* bne write */
425 0xeafffffe, /* b exit */
428 /* flash write code */
429 if (target_alloc_working_area(target
, 4 * 19, &str9x_info
->write_algorithm
) != ERROR_OK
)
431 LOG_WARNING("no working area available, can't do block memory writes");
432 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
435 target_write_buffer(target
, str9x_info
->write_algorithm
->address
, 19 * 4, (u8
*)str9x_flash_write_code
);
438 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
441 if (buffer_size
<= 256)
443 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
444 if (str9x_info
->write_algorithm
)
445 target_free_working_area(target
, str9x_info
->write_algorithm
);
447 LOG_WARNING("no large enough working area available, can't do block memory writes");
448 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
452 armv4_5_info
.common_magic
= ARMV4_5_COMMON_MAGIC
;
453 armv4_5_info
.core_mode
= ARMV4_5_MODE_SVC
;
454 armv4_5_info
.core_state
= ARMV4_5_STATE_ARM
;
456 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
457 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
458 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
459 init_reg_param(®_params
[3], "r3", 32, PARAM_IN
);
463 u32 thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
465 target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
467 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
468 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
469 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
471 if ((retval
= target
->type
->run_algorithm(target
, 0, NULL
, 4, reg_params
, str9x_info
->write_algorithm
->address
, str9x_info
->write_algorithm
->address
+ (18 * 4), 10000, &armv4_5_info
)) != ERROR_OK
)
473 LOG_ERROR("error executing str9x flash write algorithm");
474 retval
= ERROR_FLASH_OPERATION_FAILED
;
478 if (buf_get_u32(reg_params
[3].value
, 0, 32) != 0x80)
480 retval
= ERROR_FLASH_OPERATION_FAILED
;
484 buffer
+= thisrun_count
* 2;
485 address
+= thisrun_count
* 2;
486 count
-= thisrun_count
;
489 target_free_working_area(target
, source
);
490 target_free_working_area(target
, str9x_info
->write_algorithm
);
492 destroy_reg_param(®_params
[0]);
493 destroy_reg_param(®_params
[1]);
494 destroy_reg_param(®_params
[2]);
495 destroy_reg_param(®_params
[3]);
500 int str9x_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
502 target_t
*target
= bank
->target
;
503 u32 words_remaining
= (count
/ 2);
504 u32 bytes_remaining
= (count
& 0x00000001);
505 u32 address
= bank
->base
+ offset
;
506 u32 bytes_written
= 0;
509 u32 check_address
= offset
;
513 if (bank
->target
->state
!= TARGET_HALTED
)
515 LOG_ERROR("Target not halted");
516 return ERROR_TARGET_NOT_HALTED
;
521 LOG_WARNING("offset 0x%x breaks required 2-byte alignment", offset
);
522 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
525 for (i
= 0; i
< bank
->num_sectors
; i
++)
527 u32 sec_start
= bank
->sectors
[i
].offset
;
528 u32 sec_end
= sec_start
+ bank
->sectors
[i
].size
;
530 /* check if destination falls within the current sector */
531 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
533 /* check if destination ends in the current sector */
534 if (offset
+ count
< sec_end
)
535 check_address
= offset
+ count
;
537 check_address
= sec_end
;
541 if (check_address
!= offset
+ count
)
542 return ERROR_FLASH_DST_OUT_OF_BANK
;
544 /* multiple half words (2-byte) to be programmed? */
545 if (words_remaining
> 0)
547 /* try using a block write */
548 if ((retval
= str9x_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
550 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
552 /* if block write failed (no sufficient working area),
553 * we use normal (slow) single dword accesses */
554 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
556 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
558 LOG_ERROR("flash writing failed with error code: 0x%x", retval
);
559 return ERROR_FLASH_OPERATION_FAILED
;
564 buffer
+= words_remaining
* 2;
565 address
+= words_remaining
* 2;
570 while (words_remaining
> 0)
572 bank_adr
= address
& ~0x03;
574 /* write data command */
575 target_write_u16(target
, bank_adr
, 0x40);
576 target
->type
->write_memory(target
, address
, 2, 1, buffer
+ bytes_written
);
578 /* get status command */
579 target_write_u16(target
, bank_adr
, 0x70);
582 for (timeout
=0; timeout
<1000; timeout
++)
584 target_read_u8(target
, bank_adr
, &status
);
591 LOG_ERROR("write timed out");
595 /* clear status reg and read array */
596 target_write_u16(target
, bank_adr
, 0x50);
597 target_write_u16(target
, bank_adr
, 0xFF);
600 return ERROR_FLASH_OPERATION_FAILED
;
601 else if (status
& 0x02)
602 return ERROR_FLASH_OPERATION_FAILED
;
611 u8 last_halfword
[2] = {0xff, 0xff};
614 while(bytes_remaining
> 0)
616 last_halfword
[i
++] = *(buffer
+ bytes_written
);
621 bank_adr
= address
& ~0x03;
623 /* write data comamnd */
624 target_write_u16(target
, bank_adr
, 0x40);
625 target
->type
->write_memory(target
, address
, 2, 1, last_halfword
);
627 /* query status command */
628 target_write_u16(target
, bank_adr
, 0x70);
631 for (timeout
=0; timeout
<1000; timeout
++)
633 target_read_u8(target
, bank_adr
, &status
);
640 LOG_ERROR("write timed out");
644 /* clear status reg and read array */
645 target_write_u16(target
, bank_adr
, 0x50);
646 target_write_u16(target
, bank_adr
, 0xFF);
649 return ERROR_FLASH_OPERATION_FAILED
;
650 else if (status
& 0x02)
651 return ERROR_FLASH_OPERATION_FAILED
;
657 int str9x_probe(struct flash_bank_s
*bank
)
662 int str9x_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
667 int str9x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
669 snprintf(buf
, buf_size
, "str9x flash driver info" );
673 int str9x_handle_flash_config_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
675 str9x_flash_bank_t
*str9x_info
;
677 target_t
*target
= NULL
;
681 return ERROR_COMMAND_SYNTAX_ERROR
;
684 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
687 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
691 str9x_info
= bank
->driver_priv
;
693 target
= bank
->target
;
695 if (bank
->target
->state
!= TARGET_HALTED
)
697 LOG_ERROR("Target not halted");
698 return ERROR_TARGET_NOT_HALTED
;
701 /* config flash controller */
702 target_write_u32(target
, FLASH_BBSR
, strtoul(args
[1], NULL
, 0));
703 target_write_u32(target
, FLASH_NBBSR
, strtoul(args
[2], NULL
, 0));
704 target_write_u32(target
, FLASH_BBADR
, (strtoul(args
[3], NULL
, 0) >> 2));
705 target_write_u32(target
, FLASH_NBBADR
, (strtoul(args
[4], NULL
, 0) >> 2));
707 /* set bit 18 instruction TCM order as per flash programming manual */
708 arm966e_write_cp15(target
, 62, 0x40000);
710 /* enable flash bank 1 */
711 target_write_u32(target
, FLASH_CR
, 0x18);
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)