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 /* this is so the compiler can *know* */
284 assert(total_timeout
> 0);
286 for (i
= first
; i
<= last
; i
++)
289 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
291 /* erase sectors or block */
292 if ((retval
= target_write_u16(target
, adr
, erase_cmd
)) != ERROR_OK
)
296 if ((retval
= target_write_u16(target
, adr
, 0xD0)) != ERROR_OK
)
302 if ((retval
= target_write_u16(target
, adr
, 0x70)) != ERROR_OK
)
308 for (timeout
= 0; timeout
< total_timeout
; timeout
++)
310 if ((retval
= target_read_u8(target
, adr
, &status
)) != ERROR_OK
)
318 if (timeout
== total_timeout
)
320 LOG_ERROR("erase timed out");
324 /* clear status, also clear read array */
325 if ((retval
= target_write_u16(target
, adr
, 0x50)) != ERROR_OK
)
330 /* read array command */
331 if ((retval
= target_write_u16(target
, adr
, 0xFF)) != ERROR_OK
)
338 LOG_ERROR("error erasing flash bank, status: 0x%x", status
);
339 return ERROR_FLASH_OPERATION_FAILED
;
342 /* If we ran erase bank command, we are finished */
343 if (erase_cmd
== 0x80)
347 for (i
= first
; i
<= last
; i
++)
348 bank
->sectors
[i
].is_erased
= 1;
353 static int str9x_protect(struct flash_bank
*bank
,
354 int set
, int first
, int last
)
356 struct target
*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 static int str9x_write_block(struct flash_bank
*bank
,
393 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
395 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
396 struct target
*target
= bank
->target
;
397 uint32_t buffer_size
= 32768;
398 struct working_area
*source
;
399 uint32_t address
= bank
->base
+ offset
;
400 struct reg_param reg_params
[4];
401 struct arm_algorithm armv4_5_info
;
402 int retval
= ERROR_OK
;
404 /* see contib/loaders/flash/str9x.s for src */
406 static const uint32_t str9x_flash_write_code
[] = {
408 0xe3c14003, /* bic r4, r1, #3 */
409 0xe3a03040, /* mov r3, #0x40 */
410 0xe1c430b0, /* strh r3, [r4, #0] */
411 0xe0d030b2, /* ldrh r3, [r0], #2 */
412 0xe0c130b2, /* strh r3, [r1], #2 */
413 0xe3a03070, /* mov r3, #0x70 */
414 0xe1c430b0, /* strh r3, [r4, #0] */
416 0xe5d43000, /* ldrb r3, [r4, #0] */
417 0xe3130080, /* tst r3, #0x80 */
418 0x0afffffc, /* beq busy */
419 0xe3a05050, /* mov r5, #0x50 */
420 0xe1c450b0, /* strh r5, [r4, #0] */
421 0xe3a050ff, /* mov r5, #0xFF */
422 0xe1c450b0, /* strh r5, [r4, #0] */
423 0xe3130012, /* tst r3, #0x12 */
424 0x1a000001, /* bne exit */
425 0xe2522001, /* subs r2, r2, #1 */
426 0x1affffed, /* bne write */
428 0xe1200070, /* bkpt #0 */
431 /* flash write code */
432 if (target_alloc_working_area(target
, sizeof(str9x_flash_write_code
),
433 &str9x_info
->write_algorithm
) != ERROR_OK
)
435 LOG_WARNING("no working area available, can't do block memory writes");
436 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
439 target_write_buffer(target
, str9x_info
->write_algorithm
->address
,
440 sizeof(str9x_flash_write_code
),
441 (uint8_t*)str9x_flash_write_code
);
444 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
)
447 if (buffer_size
<= 256)
449 /* if we already allocated the writing code, but failed to get a
450 * buffer, free the algorithm */
451 if (str9x_info
->write_algorithm
)
452 target_free_working_area(target
, str9x_info
->write_algorithm
);
454 LOG_WARNING("no large enough working area available, can't do block memory writes");
455 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
459 armv4_5_info
.common_magic
= ARM_COMMON_MAGIC
;
460 armv4_5_info
.core_mode
= ARM_MODE_SVC
;
461 armv4_5_info
.core_state
= ARM_STATE_ARM
;
463 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
464 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
465 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
466 init_reg_param(®_params
[3], "r3", 32, PARAM_IN
);
470 uint32_t thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
472 target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
474 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
475 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
476 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
478 if ((retval
= target_run_algorithm(target
, 0, NULL
, 4, reg_params
,
479 str9x_info
->write_algorithm
->address
,
480 0, 10000, &armv4_5_info
)) != ERROR_OK
)
482 LOG_ERROR("error executing str9x flash write algorithm");
483 retval
= ERROR_FLASH_OPERATION_FAILED
;
487 if (buf_get_u32(reg_params
[3].value
, 0, 32) != 0x80)
489 retval
= ERROR_FLASH_OPERATION_FAILED
;
493 buffer
+= thisrun_count
* 2;
494 address
+= thisrun_count
* 2;
495 count
-= thisrun_count
;
498 target_free_working_area(target
, source
);
499 target_free_working_area(target
, str9x_info
->write_algorithm
);
501 destroy_reg_param(®_params
[0]);
502 destroy_reg_param(®_params
[1]);
503 destroy_reg_param(®_params
[2]);
504 destroy_reg_param(®_params
[3]);
509 static int str9x_write(struct flash_bank
*bank
,
510 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
512 struct target
*target
= bank
->target
;
513 uint32_t words_remaining
= (count
/ 2);
514 uint32_t bytes_remaining
= (count
& 0x00000001);
515 uint32_t address
= bank
->base
+ offset
;
516 uint32_t bytes_written
= 0;
519 uint32_t check_address
= offset
;
523 if (bank
->target
->state
!= TARGET_HALTED
)
525 LOG_ERROR("Target not halted");
526 return ERROR_TARGET_NOT_HALTED
;
531 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
532 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
535 for (i
= 0; i
< bank
->num_sectors
; i
++)
537 uint32_t sec_start
= bank
->sectors
[i
].offset
;
538 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
540 /* check if destination falls within the current sector */
541 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
543 /* check if destination ends in the current sector */
544 if (offset
+ count
< sec_end
)
545 check_address
= offset
+ count
;
547 check_address
= sec_end
;
551 if (check_address
!= offset
+ count
)
552 return ERROR_FLASH_DST_OUT_OF_BANK
;
554 /* multiple half words (2-byte) to be programmed? */
555 if (words_remaining
> 0)
557 /* try using a block write */
558 if ((retval
= str9x_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
560 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
562 /* if block write failed (no sufficient working area),
563 * we use normal (slow) single dword accesses */
564 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
566 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
568 LOG_ERROR("flash writing failed");
569 return ERROR_FLASH_OPERATION_FAILED
;
574 buffer
+= words_remaining
* 2;
575 address
+= words_remaining
* 2;
580 while (words_remaining
> 0)
582 bank_adr
= address
& ~0x03;
584 /* write data command */
585 target_write_u16(target
, bank_adr
, 0x40);
586 target_write_memory(target
, address
, 2, 1, buffer
+ bytes_written
);
588 /* get status command */
589 target_write_u16(target
, bank_adr
, 0x70);
592 for (timeout
= 0; timeout
< 1000; timeout
++)
594 target_read_u8(target
, bank_adr
, &status
);
601 LOG_ERROR("write timed out");
605 /* clear status reg and read array */
606 target_write_u16(target
, bank_adr
, 0x50);
607 target_write_u16(target
, bank_adr
, 0xFF);
610 return ERROR_FLASH_OPERATION_FAILED
;
611 else if (status
& 0x02)
612 return ERROR_FLASH_OPERATION_FAILED
;
621 uint8_t last_halfword
[2] = {0xff, 0xff};
624 while (bytes_remaining
> 0)
626 last_halfword
[i
++] = *(buffer
+ bytes_written
);
631 bank_adr
= address
& ~0x03;
633 /* write data command */
634 target_write_u16(target
, bank_adr
, 0x40);
635 target_write_memory(target
, address
, 2, 1, last_halfword
);
637 /* query status command */
638 target_write_u16(target
, bank_adr
, 0x70);
641 for (timeout
= 0; timeout
< 1000; timeout
++)
643 target_read_u8(target
, bank_adr
, &status
);
650 LOG_ERROR("write timed out");
654 /* clear status reg and read array */
655 target_write_u16(target
, bank_adr
, 0x50);
656 target_write_u16(target
, bank_adr
, 0xFF);
659 return ERROR_FLASH_OPERATION_FAILED
;
660 else if (status
& 0x02)
661 return ERROR_FLASH_OPERATION_FAILED
;
667 static int str9x_probe(struct flash_bank
*bank
)
673 COMMAND_HANDLER(str9x_handle_part_id_command
)
679 static int get_str9x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
681 snprintf(buf
, buf_size
, "str9x flash driver info");
685 COMMAND_HANDLER(str9x_handle_flash_config_command
)
687 struct target
*target
= NULL
;
691 return ERROR_COMMAND_SYNTAX_ERROR
;
694 struct flash_bank
*bank
;
695 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
696 if (ERROR_OK
!= retval
)
699 uint32_t bbsr
, nbbsr
, bbadr
, nbbadr
;
700 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], bbsr
);
701 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], nbbsr
);
702 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], bbadr
);
703 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[4], nbbadr
);
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)