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 "algorithm.h"
35 static uint32_t bank1start
= 0x00080000;
37 static int str9x_build_block_list(struct flash_bank
*bank
)
39 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
43 int b0_sectors
= 0, b1_sectors
= 0;
46 /* set if we have large flash str9 */
47 str9x_info
->variant
= 0;
48 str9x_info
->bank1
= 0;
59 bank1start
= 0x00100000;
60 str9x_info
->variant
= 1;
64 bank1start
= 0x00200000;
65 str9x_info
->variant
= 1;
69 str9x_info
->variant
= 1;
70 str9x_info
->bank1
= 1;
72 bank1start
= bank
->base
;
75 str9x_info
->bank1
= 1;
77 bank1start
= bank
->base
;
80 LOG_ERROR("BUG: unknown bank->size encountered");
84 num_sectors
= b0_sectors
+ b1_sectors
;
86 bank
->num_sectors
= num_sectors
;
87 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_sectors
);
88 str9x_info
->sector_bits
= malloc(sizeof(uint32_t) * num_sectors
);
92 for (i
= 0; i
< b0_sectors
; i
++)
94 bank
->sectors
[num_sectors
].offset
= offset
;
95 bank
->sectors
[num_sectors
].size
= 0x10000;
96 offset
+= bank
->sectors
[i
].size
;
97 bank
->sectors
[num_sectors
].is_erased
= -1;
98 bank
->sectors
[num_sectors
].is_protected
= 1;
99 str9x_info
->sector_bits
[num_sectors
++] = (1 << i
);
102 for (i
= 0; i
< b1_sectors
; i
++)
104 bank
->sectors
[num_sectors
].offset
= offset
;
105 bank
->sectors
[num_sectors
].size
= str9x_info
->variant
== 0 ? 0x2000 : 0x4000;
106 offset
+= bank
->sectors
[i
].size
;
107 bank
->sectors
[num_sectors
].is_erased
= -1;
108 bank
->sectors
[num_sectors
].is_protected
= 1;
109 if (str9x_info
->variant
)
110 str9x_info
->sector_bits
[num_sectors
++] = (1 << i
);
112 str9x_info
->sector_bits
[num_sectors
++] = (1 << (i
+ 8));
118 /* flash bank str9x <base> <size> 0 0 <target#>
120 FLASH_BANK_COMMAND_HANDLER(str9x_flash_bank_command
)
122 struct str9x_flash_bank
*str9x_info
;
126 LOG_WARNING("incomplete flash_bank str9x configuration");
127 return ERROR_FLASH_BANK_INVALID
;
130 str9x_info
= malloc(sizeof(struct str9x_flash_bank
));
131 bank
->driver_priv
= str9x_info
;
133 str9x_build_block_list(bank
);
135 str9x_info
->write_algorithm
= NULL
;
140 static int str9x_protect_check(struct flash_bank
*bank
)
143 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
144 struct target
*target
= bank
->target
;
149 uint16_t hstatus
= 0;
151 if (bank
->target
->state
!= TARGET_HALTED
)
153 LOG_ERROR("Target not halted");
154 return ERROR_TARGET_NOT_HALTED
;
157 /* read level one protection */
159 if (str9x_info
->variant
)
161 if (str9x_info
->bank1
)
163 adr
= bank1start
+ 0x18;
164 if ((retval
= target_write_u16(target
, adr
, 0x90)) != ERROR_OK
)
168 if ((retval
= target_read_u16(target
, adr
, &hstatus
)) != ERROR_OK
)
176 adr
= bank1start
+ 0x14;
177 if ((retval
= target_write_u16(target
, adr
, 0x90)) != ERROR_OK
)
181 if ((retval
= target_read_u32(target
, adr
, &status
)) != ERROR_OK
)
189 adr
= bank1start
+ 0x10;
190 if ((retval
= target_write_u16(target
, adr
, 0x90)) != ERROR_OK
)
194 if ((retval
= target_read_u16(target
, adr
, &hstatus
)) != ERROR_OK
)
201 /* read array command */
202 if ((retval
= target_write_u16(target
, adr
, 0xFF)) != ERROR_OK
)
207 for (i
= 0; i
< bank
->num_sectors
; i
++)
209 if (status
& str9x_info
->sector_bits
[i
])
210 bank
->sectors
[i
].is_protected
= 1;
212 bank
->sectors
[i
].is_protected
= 0;
218 static int str9x_erase(struct flash_bank
*bank
, int first
, int last
)
220 struct target
*target
= bank
->target
;
226 if (bank
->target
->state
!= TARGET_HALTED
)
228 LOG_ERROR("Target not halted");
229 return ERROR_TARGET_NOT_HALTED
;
232 /* Check if we erase whole bank */
233 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)))
235 /* Optimize to run erase bank command instead of sector */
240 /* Erase sector command */
244 for (i
= first
; i
<= last
; i
++)
247 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
250 if ((retval
= target_write_u16(target
, adr
, erase_cmd
)) != ERROR_OK
)
254 if ((retval
= target_write_u16(target
, adr
, 0xD0)) != ERROR_OK
)
260 if ((retval
= target_write_u16(target
, adr
, 0x70)) != ERROR_OK
)
266 for (timeout
= 0; timeout
< 1000; timeout
++) {
267 if ((retval
= target_read_u8(target
, adr
, &status
)) != ERROR_OK
)
277 LOG_ERROR("erase timed out");
281 /* clear status, also clear read array */
282 if ((retval
= target_write_u16(target
, adr
, 0x50)) != ERROR_OK
)
287 /* read array command */
288 if ((retval
= target_write_u16(target
, adr
, 0xFF)) != 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
)
320 LOG_ERROR("Target not halted");
321 return ERROR_TARGET_NOT_HALTED
;
324 for (i
= first
; i
<= last
; i
++)
326 /* Level One Protection */
328 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
330 target_write_u16(target
, adr
, 0x60);
332 target_write_u16(target
, adr
, 0x01);
334 target_write_u16(target
, adr
, 0xD0);
337 target_read_u8(target
, adr
, &status
);
339 /* clear status, also clear read array */
340 target_write_u16(target
, adr
, 0x50);
342 /* read array command */
343 target_write_u16(target
, adr
, 0xFF);
349 static int str9x_write_block(struct flash_bank
*bank
,
350 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
352 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
353 struct target
*target
= bank
->target
;
354 uint32_t buffer_size
= 8192;
355 struct working_area
*source
;
356 uint32_t address
= bank
->base
+ offset
;
357 struct reg_param reg_params
[4];
358 struct armv4_5_algorithm armv4_5_info
;
359 int retval
= ERROR_OK
;
361 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 0xeafffffe, /* b exit */
386 /* flash write code */
387 if (target_alloc_working_area(target
, 4 * 19, &str9x_info
->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 target_write_buffer(target
, str9x_info
->write_algorithm
->address
, 19 * 4, (uint8_t*)str9x_flash_write_code
);
396 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
399 if (buffer_size
<= 256)
401 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
402 if (str9x_info
->write_algorithm
)
403 target_free_working_area(target
, str9x_info
->write_algorithm
);
405 LOG_WARNING("no large enough working area available, can't do block memory writes");
406 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
410 armv4_5_info
.common_magic
= ARMV4_5_COMMON_MAGIC
;
411 armv4_5_info
.core_mode
= ARMV4_5_MODE_SVC
;
412 armv4_5_info
.core_state
= ARMV4_5_STATE_ARM
;
414 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
415 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
416 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
417 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 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
)
431 LOG_ERROR("error executing str9x flash write algorithm");
432 retval
= ERROR_FLASH_OPERATION_FAILED
;
436 if (buf_get_u32(reg_params
[3].value
, 0, 32) != 0x80)
438 retval
= ERROR_FLASH_OPERATION_FAILED
;
442 buffer
+= thisrun_count
* 2;
443 address
+= thisrun_count
* 2;
444 count
-= thisrun_count
;
447 target_free_working_area(target
, source
);
448 target_free_working_area(target
, str9x_info
->write_algorithm
);
450 destroy_reg_param(®_params
[0]);
451 destroy_reg_param(®_params
[1]);
452 destroy_reg_param(®_params
[2]);
453 destroy_reg_param(®_params
[3]);
458 static int str9x_write(struct flash_bank
*bank
,
459 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
461 struct target
*target
= bank
->target
;
462 uint32_t words_remaining
= (count
/ 2);
463 uint32_t bytes_remaining
= (count
& 0x00000001);
464 uint32_t address
= bank
->base
+ offset
;
465 uint32_t bytes_written
= 0;
468 uint32_t check_address
= offset
;
472 if (bank
->target
->state
!= TARGET_HALTED
)
474 LOG_ERROR("Target not halted");
475 return ERROR_TARGET_NOT_HALTED
;
480 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
481 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
484 for (i
= 0; i
< bank
->num_sectors
; i
++)
486 uint32_t sec_start
= bank
->sectors
[i
].offset
;
487 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
489 /* check if destination falls within the current sector */
490 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
492 /* check if destination ends in the current sector */
493 if (offset
+ count
< sec_end
)
494 check_address
= offset
+ count
;
496 check_address
= sec_end
;
500 if (check_address
!= offset
+ count
)
501 return ERROR_FLASH_DST_OUT_OF_BANK
;
503 /* multiple half words (2-byte) to be programmed? */
504 if (words_remaining
> 0)
506 /* try using a block write */
507 if ((retval
= str9x_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
509 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
511 /* if block write failed (no sufficient working area),
512 * we use normal (slow) single dword accesses */
513 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
515 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
517 LOG_ERROR("flash writing failed with error code: 0x%x", retval
);
518 return ERROR_FLASH_OPERATION_FAILED
;
523 buffer
+= words_remaining
* 2;
524 address
+= words_remaining
* 2;
529 while (words_remaining
> 0)
531 bank_adr
= address
& ~0x03;
533 /* write data command */
534 target_write_u16(target
, bank_adr
, 0x40);
535 target_write_memory(target
, address
, 2, 1, buffer
+ bytes_written
);
537 /* get status command */
538 target_write_u16(target
, bank_adr
, 0x70);
541 for (timeout
= 0; timeout
< 1000; timeout
++)
543 target_read_u8(target
, bank_adr
, &status
);
550 LOG_ERROR("write timed out");
554 /* clear status reg and read array */
555 target_write_u16(target
, bank_adr
, 0x50);
556 target_write_u16(target
, bank_adr
, 0xFF);
559 return ERROR_FLASH_OPERATION_FAILED
;
560 else if (status
& 0x02)
561 return ERROR_FLASH_OPERATION_FAILED
;
570 uint8_t last_halfword
[2] = {0xff, 0xff};
573 while (bytes_remaining
> 0)
575 last_halfword
[i
++] = *(buffer
+ bytes_written
);
580 bank_adr
= address
& ~0x03;
582 /* write data command */
583 target_write_u16(target
, bank_adr
, 0x40);
584 target_write_memory(target
, address
, 2, 1, last_halfword
);
586 /* query status command */
587 target_write_u16(target
, bank_adr
, 0x70);
590 for (timeout
= 0; timeout
< 1000; timeout
++)
592 target_read_u8(target
, bank_adr
, &status
);
599 LOG_ERROR("write timed out");
603 /* clear status reg and read array */
604 target_write_u16(target
, bank_adr
, 0x50);
605 target_write_u16(target
, bank_adr
, 0xFF);
608 return ERROR_FLASH_OPERATION_FAILED
;
609 else if (status
& 0x02)
610 return ERROR_FLASH_OPERATION_FAILED
;
616 static int str9x_probe(struct flash_bank
*bank
)
622 COMMAND_HANDLER(str9x_handle_part_id_command
)
628 static int str9x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
630 snprintf(buf
, buf_size
, "str9x flash driver info");
634 COMMAND_HANDLER(str9x_handle_flash_config_command
)
636 struct str9x_flash_bank
*str9x_info
;
637 struct target
*target
= NULL
;
641 return ERROR_COMMAND_SYNTAX_ERROR
;
644 struct flash_bank
*bank
;
645 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
646 if (ERROR_OK
!= retval
)
649 uint32_t bbsr
, nbbsr
, bbadr
, nbbadr
;
650 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], bbsr
);
651 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], nbbsr
);
652 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], bbadr
);
653 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[4], nbbadr
);
655 str9x_info
= bank
->driver_priv
;
657 target
= bank
->target
;
659 if (bank
->target
->state
!= TARGET_HALTED
)
661 LOG_ERROR("Target not halted");
662 return ERROR_TARGET_NOT_HALTED
;
665 /* config flash controller */
666 target_write_u32(target
, FLASH_BBSR
, bbsr
);
667 target_write_u32(target
, FLASH_NBBSR
, nbbsr
);
668 target_write_u32(target
, FLASH_BBADR
, bbadr
>> 2);
669 target_write_u32(target
, FLASH_NBBADR
, nbbadr
>> 2);
671 /* set bit 18 instruction TCM order as per flash programming manual */
672 arm966e_write_cp15(target
, 62, 0x40000);
674 /* enable flash bank 1 */
675 target_write_u32(target
, FLASH_CR
, 0x18);
679 static const struct command_registration str9x_config_command_handlers
[] = {
681 .name
= "disable_jtag",
682 .handler
= &str9x_handle_flash_config_command
,
683 .mode
= COMMAND_EXEC
,
684 .help
= "configure str9x flash controller",
685 .usage
= "<bank_id> <BBSR> <NBBSR> <BBADR> <NBBADR>",
687 COMMAND_REGISTRATION_DONE
689 static const struct command_registration str9x_command_handlers
[] = {
693 .help
= "str9x flash command group",
694 .chain
= str9x_config_command_handlers
,
696 COMMAND_REGISTRATION_DONE
699 struct flash_driver str9x_flash
= {
701 .commands
= str9x_command_handlers
,
702 .flash_bank_command
= &str9x_flash_bank_command
,
703 .erase
= &str9x_erase
,
704 .protect
= &str9x_protect
,
705 .write
= &str9x_write
,
706 .probe
= &str9x_probe
,
707 .auto_probe
= &str9x_probe
,
708 .erase_check
= &default_flash_blank_check
,
709 .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)