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 if ((retval
=target_read_u8(target
, adr
, &status
))!=ERROR_OK
)
319 /* clear status, also clear read array */
320 if ((retval
=target_write_u16(target
, adr
, 0x50))!=ERROR_OK
)
325 /* read array command */
326 if ((retval
=target_write_u16(target
, adr
, 0xFF))!=ERROR_OK
)
333 LOG_ERROR("error erasing flash bank, status: 0x%x", status
);
334 return ERROR_FLASH_OPERATION_FAILED
;
337 /* If we ran erase bank command, we are finished */
338 if (erase_cmd
== 0x80)
342 for (i
= first
; i
<= last
; i
++)
343 bank
->sectors
[i
].is_erased
= 1;
348 int str9x_protect(struct flash_bank_s
*bank
, 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 int str9x_write_block(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
388 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
389 target_t
*target
= bank
->target
;
390 u32 buffer_size
= 8192;
391 working_area_t
*source
;
392 u32 address
= bank
->base
+ offset
;
393 reg_param_t reg_params
[4];
394 armv4_5_algorithm_t armv4_5_info
;
395 int retval
= ERROR_OK
;
397 u32 str9x_flash_write_code
[] = {
399 0xe3c14003, /* bic r4, r1, #3 */
400 0xe3a03040, /* mov r3, #0x40 */
401 0xe1c430b0, /* strh r3, [r4, #0] */
402 0xe0d030b2, /* ldrh r3, [r0], #2 */
403 0xe0c130b2, /* strh r3, [r1], #2 */
404 0xe3a03070, /* mov r3, #0x70 */
405 0xe1c430b0, /* strh r3, [r4, #0] */
407 0xe5d43000, /* ldrb r3, [r4, #0] */
408 0xe3130080, /* tst r3, #0x80 */
409 0x0afffffc, /* beq busy */
410 0xe3a05050, /* mov r5, #0x50 */
411 0xe1c450b0, /* strh r5, [r4, #0] */
412 0xe3a050ff, /* mov r5, #0xFF */
413 0xe1c450b0, /* strh r5, [r4, #0] */
414 0xe3130012, /* tst r3, #0x12 */
415 0x1a000001, /* bne exit */
416 0xe2522001, /* subs r2, r2, #1 */
417 0x1affffed, /* bne write */
419 0xeafffffe, /* b exit */
422 /* flash write code */
423 if (target_alloc_working_area(target
, 4 * 19, &str9x_info
->write_algorithm
) != ERROR_OK
)
425 LOG_WARNING("no working area available, can't do block memory writes");
426 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
429 target_write_buffer(target
, str9x_info
->write_algorithm
->address
, 19 * 4, (u8
*)str9x_flash_write_code
);
432 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
435 if (buffer_size
<= 256)
437 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
438 if (str9x_info
->write_algorithm
)
439 target_free_working_area(target
, str9x_info
->write_algorithm
);
441 LOG_WARNING("no large enough working area available, can't do block memory writes");
442 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
446 armv4_5_info
.common_magic
= ARMV4_5_COMMON_MAGIC
;
447 armv4_5_info
.core_mode
= ARMV4_5_MODE_SVC
;
448 armv4_5_info
.core_state
= ARMV4_5_STATE_ARM
;
450 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
451 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
452 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
453 init_reg_param(®_params
[3], "r3", 32, PARAM_IN
);
457 u32 thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
459 target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
461 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
462 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
463 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
465 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
)
467 LOG_ERROR("error executing str9x flash write algorithm");
468 retval
= ERROR_FLASH_OPERATION_FAILED
;
472 if (buf_get_u32(reg_params
[3].value
, 0, 32) != 0x80)
474 retval
= ERROR_FLASH_OPERATION_FAILED
;
478 buffer
+= thisrun_count
* 2;
479 address
+= thisrun_count
* 2;
480 count
-= thisrun_count
;
483 target_free_working_area(target
, source
);
484 target_free_working_area(target
, str9x_info
->write_algorithm
);
486 destroy_reg_param(®_params
[0]);
487 destroy_reg_param(®_params
[1]);
488 destroy_reg_param(®_params
[2]);
489 destroy_reg_param(®_params
[3]);
494 int str9x_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
496 target_t
*target
= bank
->target
;
497 u32 words_remaining
= (count
/ 2);
498 u32 bytes_remaining
= (count
& 0x00000001);
499 u32 address
= bank
->base
+ offset
;
500 u32 bytes_written
= 0;
503 u32 check_address
= offset
;
507 if (bank
->target
->state
!= TARGET_HALTED
)
509 LOG_ERROR("Target not halted");
510 return ERROR_TARGET_NOT_HALTED
;
515 LOG_WARNING("offset 0x%x breaks required 2-byte alignment", offset
);
516 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
519 for (i
= 0; i
< bank
->num_sectors
; i
++)
521 u32 sec_start
= bank
->sectors
[i
].offset
;
522 u32 sec_end
= sec_start
+ bank
->sectors
[i
].size
;
524 /* check if destination falls within the current sector */
525 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
527 /* check if destination ends in the current sector */
528 if (offset
+ count
< sec_end
)
529 check_address
= offset
+ count
;
531 check_address
= sec_end
;
535 if (check_address
!= offset
+ count
)
536 return ERROR_FLASH_DST_OUT_OF_BANK
;
538 /* multiple half words (2-byte) to be programmed? */
539 if (words_remaining
> 0)
541 /* try using a block write */
542 if ((retval
= str9x_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
544 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
546 /* if block write failed (no sufficient working area),
547 * we use normal (slow) single dword accesses */
548 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
550 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
552 LOG_ERROR("flash writing failed with error code: 0x%x", retval
);
553 return ERROR_FLASH_OPERATION_FAILED
;
558 buffer
+= words_remaining
* 2;
559 address
+= words_remaining
* 2;
564 while (words_remaining
> 0)
566 bank_adr
= address
& ~0x03;
568 /* write data command */
569 target_write_u16(target
, bank_adr
, 0x40);
570 target
->type
->write_memory(target
, address
, 2, 1, buffer
+ bytes_written
);
572 /* get status command */
573 target_write_u16(target
, bank_adr
, 0x70);
576 target_read_u8(target
, bank_adr
, &status
);
582 /* clear status reg and read array */
583 target_write_u16(target
, bank_adr
, 0x50);
584 target_write_u16(target
, bank_adr
, 0xFF);
587 return ERROR_FLASH_OPERATION_FAILED
;
588 else if (status
& 0x02)
589 return ERROR_FLASH_OPERATION_FAILED
;
598 u8 last_halfword
[2] = {0xff, 0xff};
601 while(bytes_remaining
> 0)
603 last_halfword
[i
++] = *(buffer
+ bytes_written
);
608 bank_adr
= address
& ~0x03;
610 /* write data comamnd */
611 target_write_u16(target
, bank_adr
, 0x40);
612 target
->type
->write_memory(target
, address
, 2, 1, last_halfword
);
614 /* query status command */
615 target_write_u16(target
, bank_adr
, 0x70);
618 target_read_u8(target
, bank_adr
, &status
);
624 /* clear status reg and read array */
625 target_write_u16(target
, bank_adr
, 0x50);
626 target_write_u16(target
, bank_adr
, 0xFF);
629 return ERROR_FLASH_OPERATION_FAILED
;
630 else if (status
& 0x02)
631 return ERROR_FLASH_OPERATION_FAILED
;
637 int str9x_probe(struct flash_bank_s
*bank
)
642 int str9x_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
647 int str9x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
649 snprintf(buf
, buf_size
, "str9x flash driver info" );
653 int str9x_handle_flash_config_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
655 str9x_flash_bank_t
*str9x_info
;
657 target_t
*target
= NULL
;
661 return ERROR_COMMAND_SYNTAX_ERROR
;
664 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
667 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
671 str9x_info
= bank
->driver_priv
;
673 target
= bank
->target
;
675 if (bank
->target
->state
!= TARGET_HALTED
)
677 LOG_ERROR("Target not halted");
678 return ERROR_TARGET_NOT_HALTED
;
681 /* config flash controller */
682 target_write_u32(target
, FLASH_BBSR
, strtoul(args
[1], NULL
, 0));
683 target_write_u32(target
, FLASH_NBBSR
, strtoul(args
[2], NULL
, 0));
684 target_write_u32(target
, FLASH_BBADR
, (strtoul(args
[3], NULL
, 0) >> 2));
685 target_write_u32(target
, FLASH_NBBADR
, (strtoul(args
[4], NULL
, 0) >> 2));
687 /* set bit 18 instruction TCM order as per flash programming manual */
688 arm966e_write_cp15(target
, 62, 0x40000);
690 /* enable flash bank 1 */
691 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)