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 ***************************************************************************/
34 static uint32_t bank1start
= 0x00080000;
36 static int str9x_register_commands(struct command_context_s
*cmd_ctx
);
37 static int str9x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
38 static int str9x_erase(struct flash_bank_s
*bank
, int first
, int last
);
39 static int str9x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
40 static int str9x_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
);
41 static int str9x_probe(struct flash_bank_s
*bank
);
42 //static int str9x_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
43 static int str9x_protect_check(struct flash_bank_s
*bank
);
44 static int str9x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
46 static int str9x_handle_flash_config_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
48 flash_driver_t str9x_flash
=
51 .register_commands
= str9x_register_commands
,
52 .flash_bank_command
= str9x_flash_bank_command
,
54 .protect
= str9x_protect
,
57 .auto_probe
= str9x_probe
,
58 .erase_check
= default_flash_blank_check
,
59 .protect_check
= str9x_protect_check
,
63 static int str9x_register_commands(struct command_context_s
*cmd_ctx
)
65 command_t
*str9x_cmd
= register_command(cmd_ctx
, NULL
, "str9x", NULL
, COMMAND_ANY
, NULL
);
67 register_command(cmd_ctx
, str9x_cmd
, "flash_config", str9x_handle_flash_config_command
, COMMAND_EXEC
,
68 "configure str9 flash controller");
73 static int str9x_build_block_list(struct flash_bank_s
*bank
)
75 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
79 int b0_sectors
= 0, b1_sectors
= 0;
82 /* set if we have large flash str9 */
83 str9x_info
->variant
= 0;
84 str9x_info
->bank1
= 0;
95 bank1start
= 0x00100000;
96 str9x_info
->variant
= 1;
100 bank1start
= 0x00200000;
101 str9x_info
->variant
= 1;
105 str9x_info
->variant
= 1;
106 str9x_info
->bank1
= 1;
108 bank1start
= bank
->base
;
111 str9x_info
->bank1
= 1;
113 bank1start
= bank
->base
;
116 LOG_ERROR("BUG: unknown bank->size encountered");
120 num_sectors
= b0_sectors
+ b1_sectors
;
122 bank
->num_sectors
= num_sectors
;
123 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
124 str9x_info
->sector_bits
= malloc(sizeof(uint32_t) * num_sectors
);
128 for (i
= 0; i
< b0_sectors
; i
++)
130 bank
->sectors
[num_sectors
].offset
= offset
;
131 bank
->sectors
[num_sectors
].size
= 0x10000;
132 offset
+= bank
->sectors
[i
].size
;
133 bank
->sectors
[num_sectors
].is_erased
= -1;
134 bank
->sectors
[num_sectors
].is_protected
= 1;
135 str9x_info
->sector_bits
[num_sectors
++] = (1<<i
);
138 for (i
= 0; i
< b1_sectors
; i
++)
140 bank
->sectors
[num_sectors
].offset
= offset
;
141 bank
->sectors
[num_sectors
].size
= str9x_info
->variant
== 0 ? 0x2000 : 0x4000;
142 offset
+= bank
->sectors
[i
].size
;
143 bank
->sectors
[num_sectors
].is_erased
= -1;
144 bank
->sectors
[num_sectors
].is_protected
= 1;
145 if (str9x_info
->variant
)
146 str9x_info
->sector_bits
[num_sectors
++] = (1<<i
);
148 str9x_info
->sector_bits
[num_sectors
++] = (1<<(i
+8));
154 /* flash bank str9x <base> <size> 0 0 <target#>
156 static int str9x_flash_bank_command(struct command_context_s
*cmd_ctx
,
157 char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
159 str9x_flash_bank_t
*str9x_info
;
163 LOG_WARNING("incomplete flash_bank str9x configuration");
164 return ERROR_FLASH_BANK_INVALID
;
167 str9x_info
= malloc(sizeof(str9x_flash_bank_t
));
168 bank
->driver_priv
= str9x_info
;
170 str9x_build_block_list(bank
);
172 str9x_info
->write_algorithm
= NULL
;
177 static int str9x_protect_check(struct flash_bank_s
*bank
)
180 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
181 target_t
*target
= bank
->target
;
186 uint16_t hstatus
= 0;
188 if (bank
->target
->state
!= TARGET_HALTED
)
190 LOG_ERROR("Target not halted");
191 return ERROR_TARGET_NOT_HALTED
;
194 /* read level one protection */
196 if (str9x_info
->variant
)
198 if (str9x_info
->bank1
)
200 adr
= bank1start
+ 0x18;
201 if ((retval
=target_write_u16(target
, adr
, 0x90))!=ERROR_OK
)
205 if ((retval
=target_read_u16(target
, adr
, &hstatus
))!=ERROR_OK
)
213 adr
= bank1start
+ 0x14;
214 if ((retval
=target_write_u16(target
, adr
, 0x90))!=ERROR_OK
)
218 if ((retval
=target_read_u32(target
, adr
, &status
))!=ERROR_OK
)
226 adr
= bank1start
+ 0x10;
227 if ((retval
=target_write_u16(target
, adr
, 0x90))!=ERROR_OK
)
231 if ((retval
=target_read_u16(target
, adr
, &hstatus
))!=ERROR_OK
)
238 /* read array command */
239 if ((retval
=target_write_u16(target
, adr
, 0xFF))!=ERROR_OK
)
244 for (i
= 0; i
< bank
->num_sectors
; i
++)
246 if (status
& str9x_info
->sector_bits
[i
])
247 bank
->sectors
[i
].is_protected
= 1;
249 bank
->sectors
[i
].is_protected
= 0;
255 static int str9x_erase(struct flash_bank_s
*bank
, int first
, int last
)
257 target_t
*target
= bank
->target
;
263 if (bank
->target
->state
!= TARGET_HALTED
)
265 LOG_ERROR("Target not halted");
266 return ERROR_TARGET_NOT_HALTED
;
269 /* Check if we erase whole bank */
270 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)))
272 /* Optimize to run erase bank command instead of sector */
277 /* Erase sector command */
281 for (i
= first
; i
<= last
; i
++)
284 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
287 if ((retval
=target_write_u16(target
, adr
, erase_cmd
))!=ERROR_OK
)
291 if ((retval
=target_write_u16(target
, adr
, 0xD0))!=ERROR_OK
)
297 if ((retval
=target_write_u16(target
, adr
, 0x70))!=ERROR_OK
)
303 for (timeout
=0; timeout
<1000; timeout
++) {
304 if ((retval
=target_read_u8(target
, adr
, &status
))!=ERROR_OK
)
314 LOG_ERROR("erase timed out");
318 /* clear status, also clear read array */
319 if ((retval
=target_write_u16(target
, adr
, 0x50))!=ERROR_OK
)
324 /* read array command */
325 if ((retval
=target_write_u16(target
, adr
, 0xFF))!=ERROR_OK
)
332 LOG_ERROR("error erasing flash bank, status: 0x%x", status
);
333 return ERROR_FLASH_OPERATION_FAILED
;
336 /* If we ran erase bank command, we are finished */
337 if (erase_cmd
== 0x80)
341 for (i
= first
; i
<= last
; i
++)
342 bank
->sectors
[i
].is_erased
= 1;
347 static int str9x_protect(struct flash_bank_s
*bank
,
348 int set
, int first
, int last
)
350 target_t
*target
= bank
->target
;
355 if (bank
->target
->state
!= TARGET_HALTED
)
357 LOG_ERROR("Target not halted");
358 return ERROR_TARGET_NOT_HALTED
;
361 for (i
= first
; i
<= last
; i
++)
363 /* Level One Protection */
365 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
367 target_write_u16(target
, adr
, 0x60);
369 target_write_u16(target
, adr
, 0x01);
371 target_write_u16(target
, adr
, 0xD0);
374 target_read_u8(target
, adr
, &status
);
376 /* clear status, also clear read array */
377 target_write_u16(target
, adr
, 0x50);
379 /* read array command */
380 target_write_u16(target
, adr
, 0xFF);
386 static int str9x_write_block(struct flash_bank_s
*bank
,
387 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
389 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
390 target_t
*target
= bank
->target
;
391 uint32_t buffer_size
= 8192;
392 working_area_t
*source
;
393 uint32_t address
= bank
->base
+ offset
;
394 reg_param_t reg_params
[4];
395 armv4_5_algorithm_t armv4_5_info
;
396 int retval
= ERROR_OK
;
398 uint32_t str9x_flash_write_code
[] = {
400 0xe3c14003, /* bic r4, r1, #3 */
401 0xe3a03040, /* mov r3, #0x40 */
402 0xe1c430b0, /* strh r3, [r4, #0] */
403 0xe0d030b2, /* ldrh r3, [r0], #2 */
404 0xe0c130b2, /* strh r3, [r1], #2 */
405 0xe3a03070, /* mov r3, #0x70 */
406 0xe1c430b0, /* strh r3, [r4, #0] */
408 0xe5d43000, /* ldrb r3, [r4, #0] */
409 0xe3130080, /* tst r3, #0x80 */
410 0x0afffffc, /* beq busy */
411 0xe3a05050, /* mov r5, #0x50 */
412 0xe1c450b0, /* strh r5, [r4, #0] */
413 0xe3a050ff, /* mov r5, #0xFF */
414 0xe1c450b0, /* strh r5, [r4, #0] */
415 0xe3130012, /* tst r3, #0x12 */
416 0x1a000001, /* bne exit */
417 0xe2522001, /* subs r2, r2, #1 */
418 0x1affffed, /* bne write */
420 0xeafffffe, /* b exit */
423 /* flash write code */
424 if (target_alloc_working_area(target
, 4 * 19, &str9x_info
->write_algorithm
) != ERROR_OK
)
426 LOG_WARNING("no working area available, can't do block memory writes");
427 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
430 target_write_buffer(target
, str9x_info
->write_algorithm
->address
, 19 * 4, (uint8_t*)str9x_flash_write_code
);
433 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
436 if (buffer_size
<= 256)
438 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
439 if (str9x_info
->write_algorithm
)
440 target_free_working_area(target
, str9x_info
->write_algorithm
);
442 LOG_WARNING("no large enough working area available, can't do block memory writes");
443 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
447 armv4_5_info
.common_magic
= ARMV4_5_COMMON_MAGIC
;
448 armv4_5_info
.core_mode
= ARMV4_5_MODE_SVC
;
449 armv4_5_info
.core_state
= ARMV4_5_STATE_ARM
;
451 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
452 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
453 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
454 init_reg_param(®_params
[3], "r3", 32, PARAM_IN
);
458 uint32_t thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
460 target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
462 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
463 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
464 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
466 if ((retval
= target_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
)
468 LOG_ERROR("error executing str9x flash write algorithm");
469 retval
= ERROR_FLASH_OPERATION_FAILED
;
473 if (buf_get_u32(reg_params
[3].value
, 0, 32) != 0x80)
475 retval
= ERROR_FLASH_OPERATION_FAILED
;
479 buffer
+= thisrun_count
* 2;
480 address
+= thisrun_count
* 2;
481 count
-= thisrun_count
;
484 target_free_working_area(target
, source
);
485 target_free_working_area(target
, str9x_info
->write_algorithm
);
487 destroy_reg_param(®_params
[0]);
488 destroy_reg_param(®_params
[1]);
489 destroy_reg_param(®_params
[2]);
490 destroy_reg_param(®_params
[3]);
495 static int str9x_write(struct flash_bank_s
*bank
,
496 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
498 target_t
*target
= bank
->target
;
499 uint32_t words_remaining
= (count
/ 2);
500 uint32_t bytes_remaining
= (count
& 0x00000001);
501 uint32_t address
= bank
->base
+ offset
;
502 uint32_t bytes_written
= 0;
505 uint32_t check_address
= offset
;
509 if (bank
->target
->state
!= TARGET_HALTED
)
511 LOG_ERROR("Target not halted");
512 return ERROR_TARGET_NOT_HALTED
;
517 LOG_WARNING("offset 0x%x breaks required 2-byte alignment", offset
);
518 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
521 for (i
= 0; i
< bank
->num_sectors
; i
++)
523 uint32_t sec_start
= bank
->sectors
[i
].offset
;
524 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
526 /* check if destination falls within the current sector */
527 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
529 /* check if destination ends in the current sector */
530 if (offset
+ count
< sec_end
)
531 check_address
= offset
+ count
;
533 check_address
= sec_end
;
537 if (check_address
!= offset
+ count
)
538 return ERROR_FLASH_DST_OUT_OF_BANK
;
540 /* multiple half words (2-byte) to be programmed? */
541 if (words_remaining
> 0)
543 /* try using a block write */
544 if ((retval
= str9x_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
546 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
548 /* if block write failed (no sufficient working area),
549 * we use normal (slow) single dword accesses */
550 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
552 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
554 LOG_ERROR("flash writing failed with error code: 0x%x", retval
);
555 return ERROR_FLASH_OPERATION_FAILED
;
560 buffer
+= words_remaining
* 2;
561 address
+= words_remaining
* 2;
566 while (words_remaining
> 0)
568 bank_adr
= address
& ~0x03;
570 /* write data command */
571 target_write_u16(target
, bank_adr
, 0x40);
572 target_write_memory(target
, address
, 2, 1, buffer
+ bytes_written
);
574 /* get status command */
575 target_write_u16(target
, bank_adr
, 0x70);
578 for (timeout
=0; timeout
<1000; timeout
++)
580 target_read_u8(target
, bank_adr
, &status
);
587 LOG_ERROR("write timed out");
591 /* clear status reg and read array */
592 target_write_u16(target
, bank_adr
, 0x50);
593 target_write_u16(target
, bank_adr
, 0xFF);
596 return ERROR_FLASH_OPERATION_FAILED
;
597 else if (status
& 0x02)
598 return ERROR_FLASH_OPERATION_FAILED
;
607 uint8_t last_halfword
[2] = {0xff, 0xff};
610 while(bytes_remaining
> 0)
612 last_halfword
[i
++] = *(buffer
+ bytes_written
);
617 bank_adr
= address
& ~0x03;
619 /* write data command */
620 target_write_u16(target
, bank_adr
, 0x40);
621 target_write_memory(target
, address
, 2, 1, last_halfword
);
623 /* query status command */
624 target_write_u16(target
, bank_adr
, 0x70);
627 for (timeout
=0; timeout
<1000; timeout
++)
629 target_read_u8(target
, bank_adr
, &status
);
636 LOG_ERROR("write timed out");
640 /* clear status reg and read array */
641 target_write_u16(target
, bank_adr
, 0x50);
642 target_write_u16(target
, bank_adr
, 0xFF);
645 return ERROR_FLASH_OPERATION_FAILED
;
646 else if (status
& 0x02)
647 return ERROR_FLASH_OPERATION_FAILED
;
653 static int str9x_probe(struct flash_bank_s
*bank
)
659 static int str9x_handle_part_id_command(struct command_context_s
*cmd_ctx
,
660 char *cmd
, char **args
, int argc
)
666 static int str9x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
668 snprintf(buf
, buf_size
, "str9x flash driver info" );
672 static int str9x_handle_flash_config_command(struct command_context_s
*cmd_ctx
,
673 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)