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 return ERROR_COMMAND_SYNTAX_ERROR
;
164 str9x_info
= malloc(sizeof(struct str9x_flash_bank
));
165 bank
->driver_priv
= str9x_info
;
167 str9x_build_block_list(bank
);
169 str9x_info
->write_algorithm
= NULL
;
174 static int str9x_protect_check(struct flash_bank
*bank
)
177 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
178 struct target
*target
= bank
->target
;
183 uint16_t hstatus
= 0;
185 if (bank
->target
->state
!= TARGET_HALTED
)
187 LOG_ERROR("Target not halted");
188 return ERROR_TARGET_NOT_HALTED
;
191 /* read level one protection */
193 if (str9x_info
->variant
)
195 if (str9x_info
->bank1
)
197 adr
= bank1start
+ 0x18;
198 if ((retval
= target_write_u16(target
, adr
, 0x90)) != ERROR_OK
)
202 if ((retval
= target_read_u16(target
, adr
, &hstatus
)) != ERROR_OK
)
210 adr
= bank1start
+ 0x14;
211 if ((retval
= target_write_u16(target
, adr
, 0x90)) != ERROR_OK
)
215 if ((retval
= target_read_u32(target
, adr
, &status
)) != ERROR_OK
)
223 adr
= bank1start
+ 0x10;
224 if ((retval
= target_write_u16(target
, adr
, 0x90)) != ERROR_OK
)
228 if ((retval
= target_read_u16(target
, adr
, &hstatus
)) != ERROR_OK
)
235 /* read array command */
236 if ((retval
= target_write_u16(target
, adr
, 0xFF)) != ERROR_OK
)
241 for (i
= 0; i
< bank
->num_sectors
; i
++)
243 if (status
& str9x_info
->sector_bits
[i
])
244 bank
->sectors
[i
].is_protected
= 1;
246 bank
->sectors
[i
].is_protected
= 0;
252 static int str9x_erase(struct flash_bank
*bank
, int first
, int last
)
254 struct target
*target
= bank
->target
;
261 if (bank
->target
->state
!= TARGET_HALTED
)
263 LOG_ERROR("Target not halted");
264 return ERROR_TARGET_NOT_HALTED
;
267 /* Check if we can erase whole bank */
268 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)))
270 /* Optimize to run erase bank command instead of sector */
272 /* Add timeout duration since erase bank takes more time */
273 total_timeout
= 1000 * bank
->num_sectors
;
277 /* Erase sector command */
279 total_timeout
= 1000;
282 /* this is so the compiler can *know* */
283 assert(total_timeout
> 0);
285 for (i
= first
; i
<= last
; i
++)
288 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
290 /* erase sectors or block */
291 if ((retval
= target_write_u16(target
, adr
, erase_cmd
)) != ERROR_OK
)
295 if ((retval
= target_write_u16(target
, adr
, 0xD0)) != ERROR_OK
)
301 if ((retval
= target_write_u16(target
, adr
, 0x70)) != ERROR_OK
)
307 for (timeout
= 0; timeout
< total_timeout
; timeout
++)
309 if ((retval
= target_read_u8(target
, adr
, &status
)) != ERROR_OK
)
317 if (timeout
== total_timeout
)
319 LOG_ERROR("erase timed out");
323 /* clear status, also clear read array */
324 if ((retval
= target_write_u16(target
, adr
, 0x50)) != ERROR_OK
)
329 /* read array command */
330 if ((retval
= target_write_u16(target
, adr
, 0xFF)) != ERROR_OK
)
337 LOG_ERROR("error erasing flash bank, status: 0x%x", status
);
338 return ERROR_FLASH_OPERATION_FAILED
;
341 /* If we ran erase bank command, we are finished */
342 if (erase_cmd
== 0x80)
346 for (i
= first
; i
<= last
; i
++)
347 bank
->sectors
[i
].is_erased
= 1;
352 static int str9x_protect(struct flash_bank
*bank
,
353 int set
, int first
, int last
)
355 struct target
*target
= bank
->target
;
360 if (bank
->target
->state
!= TARGET_HALTED
)
362 LOG_ERROR("Target not halted");
363 return ERROR_TARGET_NOT_HALTED
;
366 for (i
= first
; i
<= last
; i
++)
368 /* Level One Protection */
370 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
372 target_write_u16(target
, adr
, 0x60);
374 target_write_u16(target
, adr
, 0x01);
376 target_write_u16(target
, adr
, 0xD0);
379 target_read_u8(target
, adr
, &status
);
381 /* clear status, also clear read array */
382 target_write_u16(target
, adr
, 0x50);
384 /* read array command */
385 target_write_u16(target
, adr
, 0xFF);
391 static int str9x_write_block(struct flash_bank
*bank
,
392 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
394 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
395 struct target
*target
= bank
->target
;
396 uint32_t buffer_size
= 32768;
397 struct working_area
*source
;
398 uint32_t address
= bank
->base
+ offset
;
399 struct reg_param reg_params
[4];
400 struct arm_algorithm armv4_5_info
;
401 int retval
= ERROR_OK
;
403 /* see contib/loaders/flash/str9x.s for src */
405 static const uint32_t str9x_flash_write_code
[] = {
407 0xe3c14003, /* bic r4, r1, #3 */
408 0xe3a03040, /* mov r3, #0x40 */
409 0xe1c430b0, /* strh r3, [r4, #0] */
410 0xe0d030b2, /* ldrh r3, [r0], #2 */
411 0xe0c130b2, /* strh r3, [r1], #2 */
412 0xe3a03070, /* mov r3, #0x70 */
413 0xe1c430b0, /* strh r3, [r4, #0] */
415 0xe5d43000, /* ldrb r3, [r4, #0] */
416 0xe3130080, /* tst r3, #0x80 */
417 0x0afffffc, /* beq busy */
418 0xe3a05050, /* mov r5, #0x50 */
419 0xe1c450b0, /* strh r5, [r4, #0] */
420 0xe3a050ff, /* mov r5, #0xFF */
421 0xe1c450b0, /* strh r5, [r4, #0] */
422 0xe3130012, /* tst r3, #0x12 */
423 0x1a000001, /* bne exit */
424 0xe2522001, /* subs r2, r2, #1 */
425 0x1affffed, /* bne write */
427 0xe1200070, /* bkpt #0 */
430 /* flash write code */
431 if (target_alloc_working_area(target
, sizeof(str9x_flash_write_code
),
432 &str9x_info
->write_algorithm
) != ERROR_OK
)
434 LOG_WARNING("no working area available, can't do block memory writes");
435 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
438 target_write_buffer(target
, str9x_info
->write_algorithm
->address
,
439 sizeof(str9x_flash_write_code
),
440 (uint8_t*)str9x_flash_write_code
);
443 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
)
446 if (buffer_size
<= 256)
448 /* if we already allocated the writing code, but failed to get a
449 * buffer, free the algorithm */
450 if (str9x_info
->write_algorithm
)
451 target_free_working_area(target
, str9x_info
->write_algorithm
);
453 LOG_WARNING("no large enough working area available, can't do block memory writes");
454 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
458 armv4_5_info
.common_magic
= ARM_COMMON_MAGIC
;
459 armv4_5_info
.core_mode
= ARM_MODE_SVC
;
460 armv4_5_info
.core_state
= ARM_STATE_ARM
;
462 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
463 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
464 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
465 init_reg_param(®_params
[3], "r3", 32, PARAM_IN
);
469 uint32_t thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
471 target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
473 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
474 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
475 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
477 if ((retval
= target_run_algorithm(target
, 0, NULL
, 4, reg_params
,
478 str9x_info
->write_algorithm
->address
,
479 0, 10000, &armv4_5_info
)) != ERROR_OK
)
481 LOG_ERROR("error executing str9x flash write algorithm");
482 retval
= ERROR_FLASH_OPERATION_FAILED
;
486 if (buf_get_u32(reg_params
[3].value
, 0, 32) != 0x80)
488 retval
= ERROR_FLASH_OPERATION_FAILED
;
492 buffer
+= thisrun_count
* 2;
493 address
+= thisrun_count
* 2;
494 count
-= thisrun_count
;
497 target_free_working_area(target
, source
);
498 target_free_working_area(target
, str9x_info
->write_algorithm
);
500 destroy_reg_param(®_params
[0]);
501 destroy_reg_param(®_params
[1]);
502 destroy_reg_param(®_params
[2]);
503 destroy_reg_param(®_params
[3]);
508 static int str9x_write(struct flash_bank
*bank
,
509 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
511 struct target
*target
= bank
->target
;
512 uint32_t words_remaining
= (count
/ 2);
513 uint32_t bytes_remaining
= (count
& 0x00000001);
514 uint32_t address
= bank
->base
+ offset
;
515 uint32_t bytes_written
= 0;
518 uint32_t check_address
= offset
;
522 if (bank
->target
->state
!= TARGET_HALTED
)
524 LOG_ERROR("Target not halted");
525 return ERROR_TARGET_NOT_HALTED
;
530 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
531 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
534 for (i
= 0; i
< bank
->num_sectors
; i
++)
536 uint32_t sec_start
= bank
->sectors
[i
].offset
;
537 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
539 /* check if destination falls within the current sector */
540 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
542 /* check if destination ends in the current sector */
543 if (offset
+ count
< sec_end
)
544 check_address
= offset
+ count
;
546 check_address
= sec_end
;
550 if (check_address
!= offset
+ count
)
551 return ERROR_FLASH_DST_OUT_OF_BANK
;
553 /* multiple half words (2-byte) to be programmed? */
554 if (words_remaining
> 0)
556 /* try using a block write */
557 if ((retval
= str9x_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
559 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
561 /* if block write failed (no sufficient working area),
562 * we use normal (slow) single dword accesses */
563 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
565 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
567 LOG_ERROR("flash writing failed");
568 return ERROR_FLASH_OPERATION_FAILED
;
573 buffer
+= words_remaining
* 2;
574 address
+= words_remaining
* 2;
579 while (words_remaining
> 0)
581 bank_adr
= address
& ~0x03;
583 /* write data command */
584 target_write_u16(target
, bank_adr
, 0x40);
585 target_write_memory(target
, address
, 2, 1, buffer
+ bytes_written
);
587 /* get status command */
588 target_write_u16(target
, bank_adr
, 0x70);
591 for (timeout
= 0; timeout
< 1000; timeout
++)
593 target_read_u8(target
, bank_adr
, &status
);
600 LOG_ERROR("write timed out");
604 /* clear status reg and read array */
605 target_write_u16(target
, bank_adr
, 0x50);
606 target_write_u16(target
, bank_adr
, 0xFF);
609 return ERROR_FLASH_OPERATION_FAILED
;
610 else if (status
& 0x02)
611 return ERROR_FLASH_OPERATION_FAILED
;
620 uint8_t last_halfword
[2] = {0xff, 0xff};
622 /* copy the last remaining bytes into the write buffer */
623 memcpy(last_halfword
, buffer
+bytes_written
, bytes_remaining
);
625 bank_adr
= address
& ~0x03;
627 /* write data command */
628 target_write_u16(target
, bank_adr
, 0x40);
629 target_write_memory(target
, address
, 2, 1, last_halfword
);
631 /* query status command */
632 target_write_u16(target
, bank_adr
, 0x70);
635 for (timeout
= 0; timeout
< 1000; timeout
++)
637 target_read_u8(target
, bank_adr
, &status
);
644 LOG_ERROR("write timed out");
648 /* clear status reg and read array */
649 target_write_u16(target
, bank_adr
, 0x50);
650 target_write_u16(target
, bank_adr
, 0xFF);
653 return ERROR_FLASH_OPERATION_FAILED
;
654 else if (status
& 0x02)
655 return ERROR_FLASH_OPERATION_FAILED
;
661 static int str9x_probe(struct flash_bank
*bank
)
667 COMMAND_HANDLER(str9x_handle_part_id_command
)
673 static int get_str9x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
675 snprintf(buf
, buf_size
, "str9x flash driver info");
679 COMMAND_HANDLER(str9x_handle_flash_config_command
)
681 struct target
*target
= NULL
;
685 return ERROR_COMMAND_SYNTAX_ERROR
;
688 struct flash_bank
*bank
;
689 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
690 if (ERROR_OK
!= retval
)
693 uint32_t bbsr
, nbbsr
, bbadr
, nbbadr
;
694 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], bbsr
);
695 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], nbbsr
);
696 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], bbadr
);
697 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[4], nbbadr
);
699 target
= bank
->target
;
701 if (bank
->target
->state
!= TARGET_HALTED
)
703 LOG_ERROR("Target not halted");
704 return ERROR_TARGET_NOT_HALTED
;
707 /* config flash controller */
708 target_write_u32(target
, FLASH_BBSR
, bbsr
);
709 target_write_u32(target
, FLASH_NBBSR
, nbbsr
);
710 target_write_u32(target
, FLASH_BBADR
, bbadr
>> 2);
711 target_write_u32(target
, FLASH_NBBADR
, nbbadr
>> 2);
713 /* set bit 18 instruction TCM order as per flash programming manual */
714 arm966e_write_cp15(target
, 62, 0x40000);
716 /* enable flash bank 1 */
717 target_write_u32(target
, FLASH_CR
, 0x18);
721 static const struct command_registration str9x_config_command_handlers
[] = {
723 .name
= "flash_config",
724 .handler
= str9x_handle_flash_config_command
,
725 .mode
= COMMAND_EXEC
,
726 .help
= "Configure str9x flash controller, prior to "
727 "programming the flash.",
728 .usage
= "bank_id BBSR NBBSR BBADR NBBADR",
730 COMMAND_REGISTRATION_DONE
733 static const struct command_registration str9x_command_handlers
[] = {
737 .help
= "str9x flash command group",
738 .chain
= str9x_config_command_handlers
,
740 COMMAND_REGISTRATION_DONE
743 struct flash_driver str9x_flash
= {
745 .commands
= str9x_command_handlers
,
746 .flash_bank_command
= str9x_flash_bank_command
,
747 .erase
= str9x_erase
,
748 .protect
= str9x_protect
,
749 .write
= str9x_write
,
750 .read
= default_flash_read
,
751 .probe
= str9x_probe
,
752 .auto_probe
= str9x_probe
,
753 .erase_check
= default_flash_blank_check
,
754 .protect_check
= str9x_protect_check
,
755 .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)