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 ***************************************************************************/
32 #include <target/arm966e.h>
33 #include <target/algorithm.h>
36 static uint32_t bank1start
= 0x00080000;
38 static int str9x_build_block_list(struct flash_bank
*bank
)
40 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
44 int b0_sectors
= 0, b1_sectors
= 0;
47 /* set if we have large flash str9 */
48 str9x_info
->variant
= 0;
49 str9x_info
->bank1
= 0;
60 bank1start
= 0x00100000;
61 str9x_info
->variant
= 1;
65 bank1start
= 0x00200000;
66 str9x_info
->variant
= 1;
70 str9x_info
->variant
= 1;
71 str9x_info
->bank1
= 1;
73 bank1start
= bank
->base
;
76 str9x_info
->bank1
= 1;
78 bank1start
= bank
->base
;
81 LOG_ERROR("BUG: unknown bank->size encountered");
85 num_sectors
= b0_sectors
+ b1_sectors
;
87 bank
->num_sectors
= num_sectors
;
88 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_sectors
);
89 str9x_info
->sector_bits
= malloc(sizeof(uint32_t) * num_sectors
);
93 for (i
= 0; i
< b0_sectors
; i
++)
95 bank
->sectors
[num_sectors
].offset
= offset
;
96 bank
->sectors
[num_sectors
].size
= 0x10000;
97 offset
+= bank
->sectors
[i
].size
;
98 bank
->sectors
[num_sectors
].is_erased
= -1;
99 bank
->sectors
[num_sectors
].is_protected
= 1;
100 str9x_info
->sector_bits
[num_sectors
++] = (1 << i
);
103 for (i
= 0; i
< b1_sectors
; i
++)
105 bank
->sectors
[num_sectors
].offset
= offset
;
106 bank
->sectors
[num_sectors
].size
= str9x_info
->variant
== 0 ? 0x2000 : 0x4000;
107 offset
+= bank
->sectors
[i
].size
;
108 bank
->sectors
[num_sectors
].is_erased
= -1;
109 bank
->sectors
[num_sectors
].is_protected
= 1;
110 if (str9x_info
->variant
)
111 str9x_info
->sector_bits
[num_sectors
++] = (1 << i
);
113 str9x_info
->sector_bits
[num_sectors
++] = (1 << (i
+ 8));
119 /* flash bank str9x <base> <size> 0 0 <target#>
121 FLASH_BANK_COMMAND_HANDLER(str9x_flash_bank_command
)
123 struct str9x_flash_bank
*str9x_info
;
127 LOG_WARNING("incomplete flash_bank str9x configuration");
128 return ERROR_FLASH_BANK_INVALID
;
131 str9x_info
= malloc(sizeof(struct str9x_flash_bank
));
132 bank
->driver_priv
= str9x_info
;
134 str9x_build_block_list(bank
);
136 str9x_info
->write_algorithm
= NULL
;
141 static int str9x_protect_check(struct flash_bank
*bank
)
144 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
145 struct target
*target
= bank
->target
;
150 uint16_t hstatus
= 0;
152 if (bank
->target
->state
!= TARGET_HALTED
)
154 LOG_ERROR("Target not halted");
155 return ERROR_TARGET_NOT_HALTED
;
158 /* read level one protection */
160 if (str9x_info
->variant
)
162 if (str9x_info
->bank1
)
164 adr
= bank1start
+ 0x18;
165 if ((retval
= target_write_u16(target
, adr
, 0x90)) != ERROR_OK
)
169 if ((retval
= target_read_u16(target
, adr
, &hstatus
)) != ERROR_OK
)
177 adr
= bank1start
+ 0x14;
178 if ((retval
= target_write_u16(target
, adr
, 0x90)) != ERROR_OK
)
182 if ((retval
= target_read_u32(target
, adr
, &status
)) != ERROR_OK
)
190 adr
= bank1start
+ 0x10;
191 if ((retval
= target_write_u16(target
, adr
, 0x90)) != ERROR_OK
)
195 if ((retval
= target_read_u16(target
, adr
, &hstatus
)) != ERROR_OK
)
202 /* read array command */
203 if ((retval
= target_write_u16(target
, adr
, 0xFF)) != ERROR_OK
)
208 for (i
= 0; i
< bank
->num_sectors
; i
++)
210 if (status
& str9x_info
->sector_bits
[i
])
211 bank
->sectors
[i
].is_protected
= 1;
213 bank
->sectors
[i
].is_protected
= 0;
219 static int str9x_erase(struct flash_bank
*bank
, int first
, int last
)
221 struct target
*target
= bank
->target
;
227 if (bank
->target
->state
!= TARGET_HALTED
)
229 LOG_ERROR("Target not halted");
230 return ERROR_TARGET_NOT_HALTED
;
233 /* Check if we erase whole bank */
234 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)))
236 /* Optimize to run erase bank command instead of sector */
241 /* Erase sector command */
245 for (i
= first
; i
<= last
; i
++)
248 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
251 if ((retval
= target_write_u16(target
, adr
, erase_cmd
)) != ERROR_OK
)
255 if ((retval
= target_write_u16(target
, adr
, 0xD0)) != ERROR_OK
)
261 if ((retval
= target_write_u16(target
, adr
, 0x70)) != ERROR_OK
)
267 for (timeout
= 0; timeout
< 1000; timeout
++) {
268 if ((retval
= target_read_u8(target
, adr
, &status
)) != ERROR_OK
)
278 LOG_ERROR("erase timed out");
282 /* clear status, also clear read array */
283 if ((retval
= target_write_u16(target
, adr
, 0x50)) != ERROR_OK
)
288 /* read array command */
289 if ((retval
= target_write_u16(target
, adr
, 0xFF)) != ERROR_OK
)
296 LOG_ERROR("error erasing flash bank, status: 0x%x", status
);
297 return ERROR_FLASH_OPERATION_FAILED
;
300 /* If we ran erase bank command, we are finished */
301 if (erase_cmd
== 0x80)
305 for (i
= first
; i
<= last
; i
++)
306 bank
->sectors
[i
].is_erased
= 1;
311 static int str9x_protect(struct flash_bank
*bank
,
312 int set
, int first
, int last
)
314 struct target
*target
= bank
->target
;
319 if (bank
->target
->state
!= TARGET_HALTED
)
321 LOG_ERROR("Target not halted");
322 return ERROR_TARGET_NOT_HALTED
;
325 for (i
= first
; i
<= last
; i
++)
327 /* Level One Protection */
329 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
331 target_write_u16(target
, adr
, 0x60);
333 target_write_u16(target
, adr
, 0x01);
335 target_write_u16(target
, adr
, 0xD0);
338 target_read_u8(target
, adr
, &status
);
340 /* clear status, also clear read array */
341 target_write_u16(target
, adr
, 0x50);
343 /* read array command */
344 target_write_u16(target
, adr
, 0xFF);
350 static int str9x_write_block(struct flash_bank
*bank
,
351 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
353 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
354 struct target
*target
= bank
->target
;
355 uint32_t buffer_size
= 8192;
356 struct working_area
*source
;
357 uint32_t address
= bank
->base
+ offset
;
358 struct reg_param reg_params
[4];
359 struct armv4_5_algorithm armv4_5_info
;
360 int retval
= ERROR_OK
;
362 uint32_t str9x_flash_write_code
[] = {
364 0xe3c14003, /* bic r4, r1, #3 */
365 0xe3a03040, /* mov r3, #0x40 */
366 0xe1c430b0, /* strh r3, [r4, #0] */
367 0xe0d030b2, /* ldrh r3, [r0], #2 */
368 0xe0c130b2, /* strh r3, [r1], #2 */
369 0xe3a03070, /* mov r3, #0x70 */
370 0xe1c430b0, /* strh r3, [r4, #0] */
372 0xe5d43000, /* ldrb r3, [r4, #0] */
373 0xe3130080, /* tst r3, #0x80 */
374 0x0afffffc, /* beq busy */
375 0xe3a05050, /* mov r5, #0x50 */
376 0xe1c450b0, /* strh r5, [r4, #0] */
377 0xe3a050ff, /* mov r5, #0xFF */
378 0xe1c450b0, /* strh r5, [r4, #0] */
379 0xe3130012, /* tst r3, #0x12 */
380 0x1a000001, /* bne exit */
381 0xe2522001, /* subs r2, r2, #1 */
382 0x1affffed, /* bne write */
384 0xeafffffe, /* b exit */
387 /* flash write code */
388 if (target_alloc_working_area(target
, 4 * 19, &str9x_info
->write_algorithm
) != ERROR_OK
)
390 LOG_WARNING("no working area available, can't do block memory writes");
391 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
394 target_write_buffer(target
, str9x_info
->write_algorithm
->address
, 19 * 4, (uint8_t*)str9x_flash_write_code
);
397 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
400 if (buffer_size
<= 256)
402 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
403 if (str9x_info
->write_algorithm
)
404 target_free_working_area(target
, str9x_info
->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 armv4_5_info
.common_magic
= ARMV4_5_COMMON_MAGIC
;
412 armv4_5_info
.core_mode
= ARM_MODE_SVC
;
413 armv4_5_info
.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
);
422 uint32_t thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
424 target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
426 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
427 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
428 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
430 if ((retval
= target_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
)
432 LOG_ERROR("error executing str9x flash write algorithm");
433 retval
= ERROR_FLASH_OPERATION_FAILED
;
437 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
, str9x_info
->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 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
)
475 LOG_ERROR("Target not halted");
476 return ERROR_TARGET_NOT_HALTED
;
481 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
482 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
485 for (i
= 0; i
< bank
->num_sectors
; i
++)
487 uint32_t sec_start
= bank
->sectors
[i
].offset
;
488 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
490 /* check if destination falls within the current sector */
491 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
493 /* check if destination ends in the current sector */
494 if (offset
+ count
< sec_end
)
495 check_address
= offset
+ count
;
497 check_address
= sec_end
;
501 if (check_address
!= offset
+ count
)
502 return ERROR_FLASH_DST_OUT_OF_BANK
;
504 /* multiple half words (2-byte) to be programmed? */
505 if (words_remaining
> 0)
507 /* try using a block write */
508 if ((retval
= str9x_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
510 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
512 /* if block write failed (no sufficient working area),
513 * we use normal (slow) single dword accesses */
514 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
516 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
518 LOG_ERROR("flash writing failed with error code: 0x%x", retval
);
519 return ERROR_FLASH_OPERATION_FAILED
;
524 buffer
+= words_remaining
* 2;
525 address
+= words_remaining
* 2;
530 while (words_remaining
> 0)
532 bank_adr
= address
& ~0x03;
534 /* write data command */
535 target_write_u16(target
, bank_adr
, 0x40);
536 target_write_memory(target
, address
, 2, 1, buffer
+ bytes_written
);
538 /* get status command */
539 target_write_u16(target
, bank_adr
, 0x70);
542 for (timeout
= 0; timeout
< 1000; timeout
++)
544 target_read_u8(target
, bank_adr
, &status
);
551 LOG_ERROR("write timed out");
555 /* clear status reg and read array */
556 target_write_u16(target
, bank_adr
, 0x50);
557 target_write_u16(target
, bank_adr
, 0xFF);
560 return ERROR_FLASH_OPERATION_FAILED
;
561 else if (status
& 0x02)
562 return ERROR_FLASH_OPERATION_FAILED
;
571 uint8_t last_halfword
[2] = {0xff, 0xff};
574 while (bytes_remaining
> 0)
576 last_halfword
[i
++] = *(buffer
+ bytes_written
);
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, last_halfword
);
587 /* query 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
;
617 static int str9x_probe(struct flash_bank
*bank
)
623 COMMAND_HANDLER(str9x_handle_part_id_command
)
629 static int str9x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
631 snprintf(buf
, buf_size
, "str9x flash driver info");
635 COMMAND_HANDLER(str9x_handle_flash_config_command
)
637 struct str9x_flash_bank
*str9x_info
;
638 struct target
*target
= NULL
;
642 return ERROR_COMMAND_SYNTAX_ERROR
;
645 struct flash_bank
*bank
;
646 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
647 if (ERROR_OK
!= retval
)
650 uint32_t bbsr
, nbbsr
, bbadr
, nbbadr
;
651 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], bbsr
);
652 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], nbbsr
);
653 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], bbadr
);
654 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[4], nbbadr
);
656 str9x_info
= bank
->driver_priv
;
658 target
= bank
->target
;
660 if (bank
->target
->state
!= TARGET_HALTED
)
662 LOG_ERROR("Target not halted");
663 return ERROR_TARGET_NOT_HALTED
;
666 /* config flash controller */
667 target_write_u32(target
, FLASH_BBSR
, bbsr
);
668 target_write_u32(target
, FLASH_NBBSR
, nbbsr
);
669 target_write_u32(target
, FLASH_BBADR
, bbadr
>> 2);
670 target_write_u32(target
, FLASH_NBBADR
, nbbadr
>> 2);
672 /* set bit 18 instruction TCM order as per flash programming manual */
673 arm966e_write_cp15(target
, 62, 0x40000);
675 /* enable flash bank 1 */
676 target_write_u32(target
, FLASH_CR
, 0x18);
680 static const struct command_registration str9x_config_command_handlers
[] = {
682 .name
= "disable_jtag",
683 .handler
= &str9x_handle_flash_config_command
,
684 .mode
= COMMAND_EXEC
,
685 .help
= "configure str9x flash controller",
686 .usage
= "<bank_id> <BBSR> <NBBSR> <BBADR> <NBBADR>",
688 COMMAND_REGISTRATION_DONE
690 static const struct command_registration str9x_command_handlers
[] = {
694 .help
= "str9x flash command group",
695 .chain
= str9x_config_command_handlers
,
697 COMMAND_REGISTRATION_DONE
700 struct flash_driver str9x_flash
= {
702 .commands
= str9x_command_handlers
,
703 .flash_bank_command
= &str9x_flash_bank_command
,
704 .erase
= &str9x_erase
,
705 .protect
= &str9x_protect
,
706 .write
= &str9x_write
,
707 .probe
= &str9x_probe
,
708 .auto_probe
= &str9x_probe
,
709 .erase_check
= &default_flash_blank_check
,
710 .protect_check
= &str9x_protect_check
,
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)