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 ***************************************************************************/
31 #include <target/arm966e.h>
32 #include <target/algorithm.h>
37 #define FLASH_BBSR 0x54000000 /* Boot Bank Size Register */
38 #define FLASH_NBBSR 0x54000004 /* Non-Boot Bank Size Register */
39 #define FLASH_BBADR 0x5400000C /* Boot Bank Base Address Register */
40 #define FLASH_NBBADR 0x54000010 /* Non-Boot Bank Base Address Register */
41 #define FLASH_CR 0x54000018 /* Control Register */
42 #define FLASH_SR 0x5400001C /* Status Register */
43 #define FLASH_BCE5ADDR 0x54000020 /* BC Fifth Entry Target Address Register */
46 struct str9x_flash_bank
48 uint32_t *sector_bits
;
51 struct working_area
*write_algorithm
;
54 enum str9x_status_codes
56 STR9X_CMD_SUCCESS
= 0,
57 STR9X_INVALID_COMMAND
= 1,
58 STR9X_SRC_ADDR_ERROR
= 2,
59 STR9X_DST_ADDR_ERROR
= 3,
60 STR9X_SRC_ADDR_NOT_MAPPED
= 4,
61 STR9X_DST_ADDR_NOT_MAPPED
= 5,
62 STR9X_COUNT_ERROR
= 6,
63 STR9X_INVALID_SECTOR
= 7,
64 STR9X_SECTOR_NOT_BLANK
= 8,
65 STR9X_SECTOR_NOT_PREPARED
= 9,
66 STR9X_COMPARE_ERROR
= 10,
70 static uint32_t bank1start
= 0x00080000;
72 static int str9x_build_block_list(struct flash_bank
*bank
)
74 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
78 int b0_sectors
= 0, b1_sectors
= 0;
81 /* set if we have large flash str9 */
82 str9x_info
->variant
= 0;
83 str9x_info
->bank1
= 0;
94 bank1start
= 0x00100000;
95 str9x_info
->variant
= 1;
99 bank1start
= 0x00200000;
100 str9x_info
->variant
= 1;
104 str9x_info
->variant
= 1;
105 str9x_info
->bank1
= 1;
107 bank1start
= bank
->base
;
110 str9x_info
->bank1
= 1;
112 bank1start
= bank
->base
;
115 LOG_ERROR("BUG: unknown bank->size encountered");
119 num_sectors
= b0_sectors
+ b1_sectors
;
121 bank
->num_sectors
= num_sectors
;
122 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_sectors
);
123 str9x_info
->sector_bits
= malloc(sizeof(uint32_t) * num_sectors
);
127 for (i
= 0; i
< b0_sectors
; i
++)
129 bank
->sectors
[num_sectors
].offset
= offset
;
130 bank
->sectors
[num_sectors
].size
= 0x10000;
131 offset
+= bank
->sectors
[i
].size
;
132 bank
->sectors
[num_sectors
].is_erased
= -1;
133 bank
->sectors
[num_sectors
].is_protected
= 1;
134 str9x_info
->sector_bits
[num_sectors
++] = (1 << i
);
137 for (i
= 0; i
< b1_sectors
; i
++)
139 bank
->sectors
[num_sectors
].offset
= offset
;
140 bank
->sectors
[num_sectors
].size
= str9x_info
->variant
== 0 ? 0x2000 : 0x4000;
141 offset
+= bank
->sectors
[i
].size
;
142 bank
->sectors
[num_sectors
].is_erased
= -1;
143 bank
->sectors
[num_sectors
].is_protected
= 1;
144 if (str9x_info
->variant
)
145 str9x_info
->sector_bits
[num_sectors
++] = (1 << i
);
147 str9x_info
->sector_bits
[num_sectors
++] = (1 << (i
+ 8));
153 /* flash bank str9x <base> <size> 0 0 <target#>
155 FLASH_BANK_COMMAND_HANDLER(str9x_flash_bank_command
)
157 struct str9x_flash_bank
*str9x_info
;
161 LOG_WARNING("incomplete flash_bank str9x configuration");
162 return ERROR_FLASH_BANK_INVALID
;
165 str9x_info
= malloc(sizeof(struct str9x_flash_bank
));
166 bank
->driver_priv
= str9x_info
;
168 str9x_build_block_list(bank
);
170 str9x_info
->write_algorithm
= NULL
;
175 static int str9x_protect_check(struct flash_bank
*bank
)
178 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
179 struct target
*target
= bank
->target
;
184 uint16_t hstatus
= 0;
186 if (bank
->target
->state
!= TARGET_HALTED
)
188 LOG_ERROR("Target not halted");
189 return ERROR_TARGET_NOT_HALTED
;
192 /* read level one protection */
194 if (str9x_info
->variant
)
196 if (str9x_info
->bank1
)
198 adr
= bank1start
+ 0x18;
199 if ((retval
= target_write_u16(target
, adr
, 0x90)) != ERROR_OK
)
203 if ((retval
= target_read_u16(target
, adr
, &hstatus
)) != ERROR_OK
)
211 adr
= bank1start
+ 0x14;
212 if ((retval
= target_write_u16(target
, adr
, 0x90)) != ERROR_OK
)
216 if ((retval
= target_read_u32(target
, adr
, &status
)) != ERROR_OK
)
224 adr
= bank1start
+ 0x10;
225 if ((retval
= target_write_u16(target
, adr
, 0x90)) != ERROR_OK
)
229 if ((retval
= target_read_u16(target
, adr
, &hstatus
)) != ERROR_OK
)
236 /* read array command */
237 if ((retval
= target_write_u16(target
, adr
, 0xFF)) != ERROR_OK
)
242 for (i
= 0; i
< bank
->num_sectors
; i
++)
244 if (status
& str9x_info
->sector_bits
[i
])
245 bank
->sectors
[i
].is_protected
= 1;
247 bank
->sectors
[i
].is_protected
= 0;
253 static int str9x_erase(struct flash_bank
*bank
, int first
, int last
)
255 struct target
*target
= bank
->target
;
262 if (bank
->target
->state
!= TARGET_HALTED
)
264 LOG_ERROR("Target not halted");
265 return ERROR_TARGET_NOT_HALTED
;
268 /* Check if we can erase whole bank */
269 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)))
271 /* Optimize to run erase bank command instead of sector */
273 /* Add timeout duration since erase bank takes more time */
274 total_timeout
= 1000 * bank
->num_sectors
;
278 /* Erase sector command */
280 total_timeout
= 1000;
283 for (i
= first
; i
<= last
; i
++)
286 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
288 /* erase sectors or block */
289 if ((retval
= target_write_u16(target
, adr
, erase_cmd
)) != ERROR_OK
)
293 if ((retval
= target_write_u16(target
, adr
, 0xD0)) != ERROR_OK
)
299 if ((retval
= target_write_u16(target
, adr
, 0x70)) != ERROR_OK
)
305 for (timeout
= 0; timeout
< total_timeout
; timeout
++)
307 if ((retval
= target_read_u8(target
, adr
, &status
)) != ERROR_OK
)
315 if (timeout
== total_timeout
)
317 LOG_ERROR("erase timed out");
321 /* clear status, also clear read array */
322 if ((retval
= target_write_u16(target
, adr
, 0x50)) != ERROR_OK
)
327 /* read array command */
328 if ((retval
= target_write_u16(target
, adr
, 0xFF)) != ERROR_OK
)
335 LOG_ERROR("error erasing flash bank, status: 0x%x", status
);
336 return ERROR_FLASH_OPERATION_FAILED
;
339 /* If we ran erase bank command, we are finished */
340 if (erase_cmd
== 0x80)
344 for (i
= first
; i
<= last
; i
++)
345 bank
->sectors
[i
].is_erased
= 1;
350 static int str9x_protect(struct flash_bank
*bank
,
351 int set
, int first
, int last
)
353 struct target
*target
= bank
->target
;
358 if (bank
->target
->state
!= TARGET_HALTED
)
360 LOG_ERROR("Target not halted");
361 return ERROR_TARGET_NOT_HALTED
;
364 for (i
= first
; i
<= last
; i
++)
366 /* Level One Protection */
368 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
370 target_write_u16(target
, adr
, 0x60);
372 target_write_u16(target
, adr
, 0x01);
374 target_write_u16(target
, adr
, 0xD0);
377 target_read_u8(target
, adr
, &status
);
379 /* clear status, also clear read array */
380 target_write_u16(target
, adr
, 0x50);
382 /* read array command */
383 target_write_u16(target
, adr
, 0xFF);
389 static int str9x_write_block(struct flash_bank
*bank
,
390 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
392 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
393 struct target
*target
= bank
->target
;
394 uint32_t buffer_size
= 32768;
395 struct working_area
*source
;
396 uint32_t address
= bank
->base
+ offset
;
397 struct reg_param reg_params
[4];
398 struct arm_algorithm armv4_5_info
;
399 int retval
= ERROR_OK
;
401 /* see contib/loaders/flash/str9x.s for src */
403 static const uint32_t 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 0xe1200070, /* bkpt #0 */
428 /* flash write code */
429 if (target_alloc_working_area(target
, sizeof(str9x_flash_write_code
),
430 &str9x_info
->write_algorithm
) != ERROR_OK
)
432 LOG_WARNING("no working area available, can't do block memory writes");
433 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
436 target_write_buffer(target
, str9x_info
->write_algorithm
->address
,
437 sizeof(str9x_flash_write_code
),
438 (uint8_t*)str9x_flash_write_code
);
441 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
)
444 if (buffer_size
<= 256)
446 /* if we already allocated the writing code, but failed to get a
447 * buffer, free the algorithm */
448 if (str9x_info
->write_algorithm
)
449 target_free_working_area(target
, str9x_info
->write_algorithm
);
451 LOG_WARNING("no large enough working area available, can't do block memory writes");
452 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
456 armv4_5_info
.common_magic
= ARM_COMMON_MAGIC
;
457 armv4_5_info
.core_mode
= ARM_MODE_SVC
;
458 armv4_5_info
.core_state
= ARM_STATE_ARM
;
460 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
461 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
462 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
463 init_reg_param(®_params
[3], "r3", 32, PARAM_IN
);
467 uint32_t thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
469 target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
471 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
472 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
473 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
475 if ((retval
= target_run_algorithm(target
, 0, NULL
, 4, reg_params
,
476 str9x_info
->write_algorithm
->address
,
477 0, 10000, &armv4_5_info
)) != ERROR_OK
)
479 LOG_ERROR("error executing str9x flash write algorithm");
480 retval
= ERROR_FLASH_OPERATION_FAILED
;
484 if (buf_get_u32(reg_params
[3].value
, 0, 32) != 0x80)
486 retval
= ERROR_FLASH_OPERATION_FAILED
;
490 buffer
+= thisrun_count
* 2;
491 address
+= thisrun_count
* 2;
492 count
-= thisrun_count
;
495 target_free_working_area(target
, source
);
496 target_free_working_area(target
, str9x_info
->write_algorithm
);
498 destroy_reg_param(®_params
[0]);
499 destroy_reg_param(®_params
[1]);
500 destroy_reg_param(®_params
[2]);
501 destroy_reg_param(®_params
[3]);
506 static int str9x_write(struct flash_bank
*bank
,
507 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
509 struct target
*target
= bank
->target
;
510 uint32_t words_remaining
= (count
/ 2);
511 uint32_t bytes_remaining
= (count
& 0x00000001);
512 uint32_t address
= bank
->base
+ offset
;
513 uint32_t bytes_written
= 0;
516 uint32_t check_address
= offset
;
520 if (bank
->target
->state
!= TARGET_HALTED
)
522 LOG_ERROR("Target not halted");
523 return ERROR_TARGET_NOT_HALTED
;
528 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
529 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
532 for (i
= 0; i
< bank
->num_sectors
; i
++)
534 uint32_t sec_start
= bank
->sectors
[i
].offset
;
535 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
537 /* check if destination falls within the current sector */
538 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
540 /* check if destination ends in the current sector */
541 if (offset
+ count
< sec_end
)
542 check_address
= offset
+ count
;
544 check_address
= sec_end
;
548 if (check_address
!= offset
+ count
)
549 return ERROR_FLASH_DST_OUT_OF_BANK
;
551 /* multiple half words (2-byte) to be programmed? */
552 if (words_remaining
> 0)
554 /* try using a block write */
555 if ((retval
= str9x_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
557 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
559 /* if block write failed (no sufficient working area),
560 * we use normal (slow) single dword accesses */
561 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
563 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
565 LOG_ERROR("flash writing failed");
566 return ERROR_FLASH_OPERATION_FAILED
;
571 buffer
+= words_remaining
* 2;
572 address
+= words_remaining
* 2;
577 while (words_remaining
> 0)
579 bank_adr
= address
& ~0x03;
581 /* write data command */
582 target_write_u16(target
, bank_adr
, 0x40);
583 target_write_memory(target
, address
, 2, 1, buffer
+ bytes_written
);
585 /* get status command */
586 target_write_u16(target
, bank_adr
, 0x70);
589 for (timeout
= 0; timeout
< 1000; timeout
++)
591 target_read_u8(target
, bank_adr
, &status
);
598 LOG_ERROR("write timed out");
602 /* clear status reg and read array */
603 target_write_u16(target
, bank_adr
, 0x50);
604 target_write_u16(target
, bank_adr
, 0xFF);
607 return ERROR_FLASH_OPERATION_FAILED
;
608 else if (status
& 0x02)
609 return ERROR_FLASH_OPERATION_FAILED
;
618 uint8_t last_halfword
[2] = {0xff, 0xff};
621 while (bytes_remaining
> 0)
623 last_halfword
[i
++] = *(buffer
+ bytes_written
);
628 bank_adr
= address
& ~0x03;
630 /* write data command */
631 target_write_u16(target
, bank_adr
, 0x40);
632 target_write_memory(target
, address
, 2, 1, last_halfword
);
634 /* query status command */
635 target_write_u16(target
, bank_adr
, 0x70);
638 for (timeout
= 0; timeout
< 1000; timeout
++)
640 target_read_u8(target
, bank_adr
, &status
);
647 LOG_ERROR("write timed out");
651 /* clear status reg and read array */
652 target_write_u16(target
, bank_adr
, 0x50);
653 target_write_u16(target
, bank_adr
, 0xFF);
656 return ERROR_FLASH_OPERATION_FAILED
;
657 else if (status
& 0x02)
658 return ERROR_FLASH_OPERATION_FAILED
;
664 static int str9x_probe(struct flash_bank
*bank
)
670 COMMAND_HANDLER(str9x_handle_part_id_command
)
676 static int get_str9x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
678 snprintf(buf
, buf_size
, "str9x flash driver info");
682 COMMAND_HANDLER(str9x_handle_flash_config_command
)
684 struct str9x_flash_bank
*str9x_info
;
685 struct target
*target
= NULL
;
689 return ERROR_COMMAND_SYNTAX_ERROR
;
692 struct flash_bank
*bank
;
693 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
694 if (ERROR_OK
!= retval
)
697 uint32_t bbsr
, nbbsr
, bbadr
, nbbadr
;
698 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], bbsr
);
699 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], nbbsr
);
700 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], bbadr
);
701 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[4], nbbadr
);
703 str9x_info
= bank
->driver_priv
;
705 target
= bank
->target
;
707 if (bank
->target
->state
!= TARGET_HALTED
)
709 LOG_ERROR("Target not halted");
710 return ERROR_TARGET_NOT_HALTED
;
713 /* config flash controller */
714 target_write_u32(target
, FLASH_BBSR
, bbsr
);
715 target_write_u32(target
, FLASH_NBBSR
, nbbsr
);
716 target_write_u32(target
, FLASH_BBADR
, bbadr
>> 2);
717 target_write_u32(target
, FLASH_NBBADR
, nbbadr
>> 2);
719 /* set bit 18 instruction TCM order as per flash programming manual */
720 arm966e_write_cp15(target
, 62, 0x40000);
722 /* enable flash bank 1 */
723 target_write_u32(target
, FLASH_CR
, 0x18);
727 static const struct command_registration str9x_config_command_handlers
[] = {
729 .name
= "flash_config",
730 .handler
= str9x_handle_flash_config_command
,
731 .mode
= COMMAND_EXEC
,
732 .help
= "Configure str9x flash controller, prior to "
733 "programming the flash.",
734 .usage
= "bank_id BBSR NBBSR BBADR NBBADR",
736 COMMAND_REGISTRATION_DONE
739 static const struct command_registration str9x_command_handlers
[] = {
743 .help
= "str9x flash command group",
744 .chain
= str9x_config_command_handlers
,
746 COMMAND_REGISTRATION_DONE
749 struct flash_driver str9x_flash
= {
751 .commands
= str9x_command_handlers
,
752 .flash_bank_command
= str9x_flash_bank_command
,
753 .erase
= str9x_erase
,
754 .protect
= str9x_protect
,
755 .write
= str9x_write
,
756 .read
= default_flash_read
,
757 .probe
= str9x_probe
,
758 .auto_probe
= str9x_probe
,
759 .erase_check
= default_flash_blank_check
,
760 .protect_check
= str9x_protect_check
,
761 .info
= get_str9x_info
,
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)