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, see <http://www.gnu.org/licenses/>. *
23 ***************************************************************************/
30 #include <target/arm966e.h>
31 #include <target/algorithm.h>
35 #define FLASH_BBSR 0x54000000 /* Boot Bank Size Register */
36 #define FLASH_NBBSR 0x54000004 /* Non-Boot Bank Size Register */
37 #define FLASH_BBADR 0x5400000C /* Boot Bank Base Address Register */
38 #define FLASH_NBBADR 0x54000010 /* Non-Boot Bank Base Address Register */
39 #define FLASH_CR 0x54000018 /* Control Register */
40 #define FLASH_SR 0x5400001C /* Status Register */
41 #define FLASH_BCE5ADDR 0x54000020 /* BC Fifth Entry Target Address Register */
43 struct str9x_flash_bank
{
44 uint32_t *sector_bits
;
49 enum str9x_status_codes
{
50 STR9X_CMD_SUCCESS
= 0,
51 STR9X_INVALID_COMMAND
= 1,
52 STR9X_SRC_ADDR_ERROR
= 2,
53 STR9X_DST_ADDR_ERROR
= 3,
54 STR9X_SRC_ADDR_NOT_MAPPED
= 4,
55 STR9X_DST_ADDR_NOT_MAPPED
= 5,
56 STR9X_COUNT_ERROR
= 6,
57 STR9X_INVALID_SECTOR
= 7,
58 STR9X_SECTOR_NOT_BLANK
= 8,
59 STR9X_SECTOR_NOT_PREPARED
= 9,
60 STR9X_COMPARE_ERROR
= 10,
64 static uint32_t bank1start
= 0x00080000;
66 static int str9x_build_block_list(struct flash_bank
*bank
)
68 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
72 int b0_sectors
= 0, b1_sectors
= 0;
75 /* set if we have large flash str9 */
76 str9x_info
->variant
= 0;
77 str9x_info
->bank1
= 0;
87 bank1start
= 0x00100000;
88 str9x_info
->variant
= 1;
92 bank1start
= 0x00200000;
93 str9x_info
->variant
= 1;
97 str9x_info
->variant
= 1;
98 str9x_info
->bank1
= 1;
100 bank1start
= bank
->base
;
103 str9x_info
->bank1
= 1;
105 bank1start
= bank
->base
;
108 LOG_ERROR("BUG: unknown bank->size encountered");
112 num_sectors
= b0_sectors
+ b1_sectors
;
114 bank
->num_sectors
= num_sectors
;
115 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_sectors
);
116 str9x_info
->sector_bits
= malloc(sizeof(uint32_t) * num_sectors
);
120 for (i
= 0; i
< b0_sectors
; i
++) {
121 bank
->sectors
[num_sectors
].offset
= offset
;
122 bank
->sectors
[num_sectors
].size
= 0x10000;
123 offset
+= bank
->sectors
[i
].size
;
124 bank
->sectors
[num_sectors
].is_erased
= -1;
125 bank
->sectors
[num_sectors
].is_protected
= 1;
126 str9x_info
->sector_bits
[num_sectors
++] = (1 << i
);
129 for (i
= 0; i
< b1_sectors
; i
++) {
130 bank
->sectors
[num_sectors
].offset
= offset
;
131 bank
->sectors
[num_sectors
].size
= str9x_info
->variant
== 0 ? 0x2000 : 0x4000;
132 offset
+= bank
->sectors
[i
].size
;
133 bank
->sectors
[num_sectors
].is_erased
= -1;
134 bank
->sectors
[num_sectors
].is_protected
= 1;
135 if (str9x_info
->variant
)
136 str9x_info
->sector_bits
[num_sectors
++] = (1 << i
);
138 str9x_info
->sector_bits
[num_sectors
++] = (1 << (i
+ 8));
144 /* flash bank str9x <base> <size> 0 0 <target#>
146 FLASH_BANK_COMMAND_HANDLER(str9x_flash_bank_command
)
148 struct str9x_flash_bank
*str9x_info
;
151 return ERROR_COMMAND_SYNTAX_ERROR
;
153 str9x_info
= malloc(sizeof(struct str9x_flash_bank
));
154 bank
->driver_priv
= str9x_info
;
156 str9x_build_block_list(bank
);
161 static int str9x_protect_check(struct flash_bank
*bank
)
164 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
165 struct target
*target
= bank
->target
;
170 uint16_t hstatus
= 0;
172 if (bank
->target
->state
!= TARGET_HALTED
) {
173 LOG_ERROR("Target not halted");
174 return ERROR_TARGET_NOT_HALTED
;
177 /* read level one protection */
179 if (str9x_info
->variant
) {
180 if (str9x_info
->bank1
) {
181 adr
= bank1start
+ 0x18;
182 retval
= target_write_u16(target
, adr
, 0x90);
183 if (retval
!= ERROR_OK
)
185 retval
= target_read_u16(target
, adr
, &hstatus
);
186 if (retval
!= ERROR_OK
)
190 adr
= bank1start
+ 0x14;
191 retval
= target_write_u16(target
, adr
, 0x90);
192 if (retval
!= ERROR_OK
)
194 retval
= target_read_u32(target
, adr
, &status
);
195 if (retval
!= ERROR_OK
)
199 adr
= bank1start
+ 0x10;
200 retval
= target_write_u16(target
, adr
, 0x90);
201 if (retval
!= ERROR_OK
)
203 retval
= target_read_u16(target
, adr
, &hstatus
);
204 if (retval
!= ERROR_OK
)
209 /* read array command */
210 retval
= target_write_u16(target
, adr
, 0xFF);
211 if (retval
!= ERROR_OK
)
214 for (i
= 0; i
< bank
->num_sectors
; i
++) {
215 if (status
& str9x_info
->sector_bits
[i
])
216 bank
->sectors
[i
].is_protected
= 1;
218 bank
->sectors
[i
].is_protected
= 0;
224 static int str9x_erase(struct flash_bank
*bank
, int first
, int last
)
226 struct target
*target
= bank
->target
;
233 if (bank
->target
->state
!= TARGET_HALTED
) {
234 LOG_ERROR("Target not halted");
235 return ERROR_TARGET_NOT_HALTED
;
238 /* Check if we can erase whole bank */
239 if ((first
== 0) && (last
== (bank
->num_sectors
- 1))) {
240 /* Optimize to run erase bank command instead of sector */
242 /* Add timeout duration since erase bank takes more time */
243 total_timeout
= 1000 * bank
->num_sectors
;
245 /* Erase sector command */
247 total_timeout
= 1000;
250 /* this is so the compiler can *know* */
251 assert(total_timeout
> 0);
253 for (i
= first
; i
<= last
; i
++) {
255 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
257 /* erase sectors or block */
258 retval
= target_write_u16(target
, adr
, erase_cmd
);
259 if (retval
!= ERROR_OK
)
261 retval
= target_write_u16(target
, adr
, 0xD0);
262 if (retval
!= ERROR_OK
)
266 retval
= target_write_u16(target
, adr
, 0x70);
267 if (retval
!= ERROR_OK
)
271 for (timeout
= 0; timeout
< total_timeout
; timeout
++) {
272 retval
= target_read_u8(target
, adr
, &status
);
273 if (retval
!= ERROR_OK
)
279 if (timeout
== total_timeout
) {
280 LOG_ERROR("erase timed out");
284 /* clear status, also clear read array */
285 retval
= target_write_u16(target
, adr
, 0x50);
286 if (retval
!= ERROR_OK
)
289 /* read array command */
290 retval
= target_write_u16(target
, adr
, 0xFF);
291 if (retval
!= ERROR_OK
)
295 LOG_ERROR("error erasing flash bank, status: 0x%x", status
);
296 return ERROR_FLASH_OPERATION_FAILED
;
299 /* If we ran erase bank command, we are finished */
300 if (erase_cmd
== 0x80)
304 for (i
= first
; i
<= last
; i
++)
305 bank
->sectors
[i
].is_erased
= 1;
310 static int str9x_protect(struct flash_bank
*bank
,
311 int set
, int first
, int last
)
313 struct target
*target
= bank
->target
;
318 if (bank
->target
->state
!= TARGET_HALTED
) {
319 LOG_ERROR("Target not halted");
320 return ERROR_TARGET_NOT_HALTED
;
323 for (i
= first
; i
<= last
; i
++) {
324 /* Level One Protection */
326 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
328 target_write_u16(target
, adr
, 0x60);
330 target_write_u16(target
, adr
, 0x01);
332 target_write_u16(target
, adr
, 0xD0);
335 target_read_u8(target
, adr
, &status
);
337 /* clear status, also clear read array */
338 target_write_u16(target
, adr
, 0x50);
340 /* read array command */
341 target_write_u16(target
, adr
, 0xFF);
347 static int str9x_write_block(struct flash_bank
*bank
,
348 const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
350 struct target
*target
= bank
->target
;
351 uint32_t buffer_size
= 32768;
352 struct working_area
*write_algorithm
;
353 struct working_area
*source
;
354 uint32_t address
= bank
->base
+ offset
;
355 struct reg_param reg_params
[4];
356 struct arm_algorithm arm_algo
;
357 int retval
= ERROR_OK
;
359 /* see contib/loaders/flash/str9x.s for src */
361 static const uint32_t str9x_flash_write_code
[] = {
363 0xe3c14003, /* bic r4, r1, #3 */
364 0xe3a03040, /* mov r3, #0x40 */
365 0xe1c430b0, /* strh r3, [r4, #0] */
366 0xe0d030b2, /* ldrh r3, [r0], #2 */
367 0xe0c130b2, /* strh r3, [r1], #2 */
368 0xe3a03070, /* mov r3, #0x70 */
369 0xe1c430b0, /* strh r3, [r4, #0] */
371 0xe5d43000, /* ldrb r3, [r4, #0] */
372 0xe3130080, /* tst r3, #0x80 */
373 0x0afffffc, /* beq busy */
374 0xe3a05050, /* mov r5, #0x50 */
375 0xe1c450b0, /* strh r5, [r4, #0] */
376 0xe3a050ff, /* mov r5, #0xFF */
377 0xe1c450b0, /* strh r5, [r4, #0] */
378 0xe3130012, /* tst r3, #0x12 */
379 0x1a000001, /* bne exit */
380 0xe2522001, /* subs r2, r2, #1 */
381 0x1affffed, /* bne write */
383 0xe1200070, /* bkpt #0 */
386 /* flash write code */
387 if (target_alloc_working_area(target
, sizeof(str9x_flash_write_code
),
388 &write_algorithm
) != ERROR_OK
) {
389 LOG_WARNING("no working area available, can't do block memory writes");
390 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
393 uint8_t code
[sizeof(str9x_flash_write_code
)];
394 target_buffer_set_u32_array(target
, code
, ARRAY_SIZE(str9x_flash_write_code
),
395 str9x_flash_write_code
);
396 target_write_buffer(target
, write_algorithm
->address
, sizeof(code
), code
);
399 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
401 if (buffer_size
<= 256) {
402 /* we already allocated the writing code, but failed to get a
403 * buffer, free the algorithm */
404 target_free_working_area(target
, write_algorithm
);
406 LOG_WARNING("no large enough working area available, can't do block memory writes");
407 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
411 arm_algo
.common_magic
= ARM_COMMON_MAGIC
;
412 arm_algo
.core_mode
= ARM_MODE_SVC
;
413 arm_algo
.core_state
= ARM_STATE_ARM
;
415 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
416 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
417 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
418 init_reg_param(®_params
[3], "r3", 32, PARAM_IN
);
421 uint32_t thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
423 target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
425 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
426 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
427 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
429 retval
= target_run_algorithm(target
, 0, NULL
, 4, reg_params
,
430 write_algorithm
->address
,
431 0, 10000, &arm_algo
);
432 if (retval
!= ERROR_OK
) {
433 LOG_ERROR("error executing str9x flash write algorithm");
434 retval
= ERROR_FLASH_OPERATION_FAILED
;
438 if (buf_get_u32(reg_params
[3].value
, 0, 32) != 0x80) {
439 retval
= ERROR_FLASH_OPERATION_FAILED
;
443 buffer
+= thisrun_count
* 2;
444 address
+= thisrun_count
* 2;
445 count
-= thisrun_count
;
448 target_free_working_area(target
, source
);
449 target_free_working_area(target
, write_algorithm
);
451 destroy_reg_param(®_params
[0]);
452 destroy_reg_param(®_params
[1]);
453 destroy_reg_param(®_params
[2]);
454 destroy_reg_param(®_params
[3]);
459 static int str9x_write(struct flash_bank
*bank
,
460 const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
462 struct target
*target
= bank
->target
;
463 uint32_t words_remaining
= (count
/ 2);
464 uint32_t bytes_remaining
= (count
& 0x00000001);
465 uint32_t address
= bank
->base
+ offset
;
466 uint32_t bytes_written
= 0;
469 uint32_t check_address
= offset
;
473 if (bank
->target
->state
!= TARGET_HALTED
) {
474 LOG_ERROR("Target not halted");
475 return ERROR_TARGET_NOT_HALTED
;
479 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
480 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
483 for (i
= 0; i
< bank
->num_sectors
; i
++) {
484 uint32_t sec_start
= bank
->sectors
[i
].offset
;
485 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
487 /* check if destination falls within the current sector */
488 if ((check_address
>= sec_start
) && (check_address
< sec_end
)) {
489 /* check if destination ends in the current sector */
490 if (offset
+ count
< sec_end
)
491 check_address
= offset
+ count
;
493 check_address
= sec_end
;
497 if (check_address
!= offset
+ count
)
498 return ERROR_FLASH_DST_OUT_OF_BANK
;
500 /* multiple half words (2-byte) to be programmed? */
501 if (words_remaining
> 0) {
502 /* try using a block write */
503 retval
= str9x_write_block(bank
, buffer
, offset
, words_remaining
);
504 if (retval
!= ERROR_OK
) {
505 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
) {
506 /* if block write failed (no sufficient working area),
507 * we use normal (slow) single dword accesses */
508 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
509 } else if (retval
== ERROR_FLASH_OPERATION_FAILED
) {
510 LOG_ERROR("flash writing failed");
511 return ERROR_FLASH_OPERATION_FAILED
;
514 buffer
+= words_remaining
* 2;
515 address
+= words_remaining
* 2;
520 while (words_remaining
> 0) {
521 bank_adr
= address
& ~0x03;
523 /* write data command */
524 target_write_u16(target
, bank_adr
, 0x40);
525 target_write_memory(target
, address
, 2, 1, buffer
+ bytes_written
);
527 /* get status command */
528 target_write_u16(target
, bank_adr
, 0x70);
531 for (timeout
= 0; timeout
< 1000; timeout
++) {
532 target_read_u8(target
, bank_adr
, &status
);
537 if (timeout
== 1000) {
538 LOG_ERROR("write timed out");
542 /* clear status reg and read array */
543 target_write_u16(target
, bank_adr
, 0x50);
544 target_write_u16(target
, bank_adr
, 0xFF);
547 return ERROR_FLASH_OPERATION_FAILED
;
548 else if (status
& 0x02)
549 return ERROR_FLASH_OPERATION_FAILED
;
556 if (bytes_remaining
) {
557 uint8_t last_halfword
[2] = {0xff, 0xff};
559 /* copy the last remaining bytes into the write buffer */
560 memcpy(last_halfword
, buffer
+bytes_written
, bytes_remaining
);
562 bank_adr
= address
& ~0x03;
564 /* write data command */
565 target_write_u16(target
, bank_adr
, 0x40);
566 target_write_memory(target
, address
, 2, 1, last_halfword
);
568 /* query status command */
569 target_write_u16(target
, bank_adr
, 0x70);
572 for (timeout
= 0; timeout
< 1000; timeout
++) {
573 target_read_u8(target
, bank_adr
, &status
);
578 if (timeout
== 1000) {
579 LOG_ERROR("write timed out");
583 /* clear status reg and read array */
584 target_write_u16(target
, bank_adr
, 0x50);
585 target_write_u16(target
, bank_adr
, 0xFF);
588 return ERROR_FLASH_OPERATION_FAILED
;
589 else if (status
& 0x02)
590 return ERROR_FLASH_OPERATION_FAILED
;
596 static int str9x_probe(struct flash_bank
*bank
)
602 COMMAND_HANDLER(str9x_handle_part_id_command
)
608 COMMAND_HANDLER(str9x_handle_flash_config_command
)
610 struct target
*target
= NULL
;
613 return ERROR_COMMAND_SYNTAX_ERROR
;
615 struct flash_bank
*bank
;
616 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
617 if (ERROR_OK
!= retval
)
620 uint32_t bbsr
, nbbsr
, bbadr
, nbbadr
;
621 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], bbsr
);
622 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], nbbsr
);
623 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], bbadr
);
624 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[4], nbbadr
);
626 target
= bank
->target
;
628 if (bank
->target
->state
!= TARGET_HALTED
) {
629 LOG_ERROR("Target not halted");
630 return ERROR_TARGET_NOT_HALTED
;
633 /* config flash controller */
634 target_write_u32(target
, FLASH_BBSR
, bbsr
);
635 target_write_u32(target
, FLASH_NBBSR
, nbbsr
);
636 target_write_u32(target
, FLASH_BBADR
, bbadr
>> 2);
637 target_write_u32(target
, FLASH_NBBADR
, nbbadr
>> 2);
639 /* set bit 18 instruction TCM order as per flash programming manual */
640 arm966e_write_cp15(target
, 62, 0x40000);
642 /* enable flash bank 1 */
643 target_write_u32(target
, FLASH_CR
, 0x18);
647 static const struct command_registration str9x_config_command_handlers
[] = {
649 .name
= "flash_config",
650 .handler
= str9x_handle_flash_config_command
,
651 .mode
= COMMAND_EXEC
,
652 .help
= "Configure str9x flash controller, prior to "
653 "programming the flash.",
654 .usage
= "bank_id BBSR NBBSR BBADR NBBADR",
656 COMMAND_REGISTRATION_DONE
659 static const struct command_registration str9x_command_handlers
[] = {
663 .help
= "str9x flash command group",
665 .chain
= str9x_config_command_handlers
,
667 COMMAND_REGISTRATION_DONE
670 const struct flash_driver str9x_flash
= {
672 .commands
= str9x_command_handlers
,
673 .flash_bank_command
= str9x_flash_bank_command
,
674 .erase
= str9x_erase
,
675 .protect
= str9x_protect
,
676 .write
= str9x_write
,
677 .read
= default_flash_read
,
678 .probe
= str9x_probe
,
679 .auto_probe
= str9x_probe
,
680 .erase_check
= default_flash_blank_check
,
681 .protect_check
= str9x_protect_check
,
682 .free_driver_priv
= default_flash_free_driver_priv
,
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)