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 /*A slower but stable way of erasing*/
234 /* Erase sector command */
237 for (i
= first
; i
<= last
; i
++)
240 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
243 if ((retval
= target_write_u16(target
, adr
, erase_cmd
)) != ERROR_OK
)
247 if ((retval
= target_write_u16(target
, adr
, 0xD0)) != ERROR_OK
)
253 if ((retval
= target_write_u16(target
, adr
, 0x70)) != ERROR_OK
)
259 for (timeout
= 0; timeout
< 1000; timeout
++) {
260 if ((retval
= target_read_u8(target
, adr
, &status
)) != ERROR_OK
)
270 LOG_ERROR("erase timed out");
274 /* clear status, also clear read array */
275 if ((retval
= target_write_u16(target
, adr
, 0x50)) != ERROR_OK
)
280 /* read array command */
281 if ((retval
= target_write_u16(target
, adr
, 0xFF)) != ERROR_OK
)
288 LOG_ERROR("error erasing flash bank, status: 0x%x", status
);
289 return ERROR_FLASH_OPERATION_FAILED
;
293 for (i
= first
; i
<= last
; i
++)
294 bank
->sectors
[i
].is_erased
= 1;
299 static int str9x_protect(struct flash_bank
*bank
,
300 int set
, int first
, int last
)
302 struct target
*target
= bank
->target
;
307 if (bank
->target
->state
!= TARGET_HALTED
)
309 LOG_ERROR("Target not halted");
310 return ERROR_TARGET_NOT_HALTED
;
313 for (i
= first
; i
<= last
; i
++)
315 /* Level One Protection */
317 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
319 target_write_u16(target
, adr
, 0x60);
321 target_write_u16(target
, adr
, 0x01);
323 target_write_u16(target
, adr
, 0xD0);
326 target_read_u8(target
, adr
, &status
);
328 /* clear status, also clear read array */
329 target_write_u16(target
, adr
, 0x50);
331 /* read array command */
332 target_write_u16(target
, adr
, 0xFF);
338 static int str9x_write_block(struct flash_bank
*bank
,
339 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
341 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
342 struct target
*target
= bank
->target
;
343 uint32_t buffer_size
= 8192;
344 struct working_area
*source
;
345 uint32_t address
= bank
->base
+ offset
;
346 struct reg_param reg_params
[4];
347 struct arm_algorithm armv4_5_info
;
348 int retval
= ERROR_OK
;
350 uint32_t str9x_flash_write_code
[] = {
352 0xe3c14003, /* bic r4, r1, #3 */
353 0xe3a03040, /* mov r3, #0x40 */
354 0xe1c430b0, /* strh r3, [r4, #0] */
355 0xe0d030b2, /* ldrh r3, [r0], #2 */
356 0xe0c130b2, /* strh r3, [r1], #2 */
357 0xe3a03070, /* mov r3, #0x70 */
358 0xe1c430b0, /* strh r3, [r4, #0] */
360 0xe5d43000, /* ldrb r3, [r4, #0] */
361 0xe3130080, /* tst r3, #0x80 */
362 0x0afffffc, /* beq busy */
363 0xe3a05050, /* mov r5, #0x50 */
364 0xe1c450b0, /* strh r5, [r4, #0] */
365 0xe3a050ff, /* mov r5, #0xFF */
366 0xe1c450b0, /* strh r5, [r4, #0] */
367 0xe3130012, /* tst r3, #0x12 */
368 0x1a000001, /* bne exit */
369 0xe2522001, /* subs r2, r2, #1 */
370 0x1affffed, /* bne write */
372 0xeafffffe, /* b exit */
375 /* flash write code */
376 if (target_alloc_working_area(target
, 4 * 19, &str9x_info
->write_algorithm
) != ERROR_OK
)
378 LOG_WARNING("no working area available, can't do block memory writes");
379 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
382 target_write_buffer(target
, str9x_info
->write_algorithm
->address
, 19 * 4, (uint8_t*)str9x_flash_write_code
);
385 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
388 if (buffer_size
<= 256)
390 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
391 if (str9x_info
->write_algorithm
)
392 target_free_working_area(target
, str9x_info
->write_algorithm
);
394 LOG_WARNING("no large enough working area available, can't do block memory writes");
395 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
399 armv4_5_info
.common_magic
= ARM_COMMON_MAGIC
;
400 armv4_5_info
.core_mode
= ARM_MODE_SVC
;
401 armv4_5_info
.core_state
= ARM_STATE_ARM
;
403 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
404 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
405 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
406 init_reg_param(®_params
[3], "r3", 32, PARAM_IN
);
410 uint32_t thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
412 target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
414 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
415 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
416 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
418 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
)
420 LOG_ERROR("error executing str9x flash write algorithm");
421 retval
= ERROR_FLASH_OPERATION_FAILED
;
425 if (buf_get_u32(reg_params
[3].value
, 0, 32) != 0x80)
427 retval
= ERROR_FLASH_OPERATION_FAILED
;
431 buffer
+= thisrun_count
* 2;
432 address
+= thisrun_count
* 2;
433 count
-= thisrun_count
;
436 target_free_working_area(target
, source
);
437 target_free_working_area(target
, str9x_info
->write_algorithm
);
439 destroy_reg_param(®_params
[0]);
440 destroy_reg_param(®_params
[1]);
441 destroy_reg_param(®_params
[2]);
442 destroy_reg_param(®_params
[3]);
447 static int str9x_write(struct flash_bank
*bank
,
448 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
450 struct target
*target
= bank
->target
;
451 uint32_t words_remaining
= (count
/ 2);
452 uint32_t bytes_remaining
= (count
& 0x00000001);
453 uint32_t address
= bank
->base
+ offset
;
454 uint32_t bytes_written
= 0;
457 uint32_t check_address
= offset
;
461 if (bank
->target
->state
!= TARGET_HALTED
)
463 LOG_ERROR("Target not halted");
464 return ERROR_TARGET_NOT_HALTED
;
469 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
470 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
473 for (i
= 0; i
< bank
->num_sectors
; i
++)
475 uint32_t sec_start
= bank
->sectors
[i
].offset
;
476 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
478 /* check if destination falls within the current sector */
479 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
481 /* check if destination ends in the current sector */
482 if (offset
+ count
< sec_end
)
483 check_address
= offset
+ count
;
485 check_address
= sec_end
;
489 if (check_address
!= offset
+ count
)
490 return ERROR_FLASH_DST_OUT_OF_BANK
;
492 /* multiple half words (2-byte) to be programmed? */
493 if (words_remaining
> 0)
495 /* try using a block write */
496 if ((retval
= str9x_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
498 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
500 /* if block write failed (no sufficient working area),
501 * we use normal (slow) single dword accesses */
502 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
504 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
506 LOG_ERROR("flash writing failed with error code: 0x%x", retval
);
507 return ERROR_FLASH_OPERATION_FAILED
;
512 buffer
+= words_remaining
* 2;
513 address
+= words_remaining
* 2;
518 while (words_remaining
> 0)
520 bank_adr
= address
& ~0x03;
522 /* write data command */
523 target_write_u16(target
, bank_adr
, 0x40);
524 target_write_memory(target
, address
, 2, 1, buffer
+ bytes_written
);
526 /* get status command */
527 target_write_u16(target
, bank_adr
, 0x70);
530 for (timeout
= 0; timeout
< 1000; timeout
++)
532 target_read_u8(target
, bank_adr
, &status
);
539 LOG_ERROR("write timed out");
543 /* clear status reg and read array */
544 target_write_u16(target
, bank_adr
, 0x50);
545 target_write_u16(target
, bank_adr
, 0xFF);
548 return ERROR_FLASH_OPERATION_FAILED
;
549 else if (status
& 0x02)
550 return ERROR_FLASH_OPERATION_FAILED
;
559 uint8_t last_halfword
[2] = {0xff, 0xff};
562 while (bytes_remaining
> 0)
564 last_halfword
[i
++] = *(buffer
+ bytes_written
);
569 bank_adr
= address
& ~0x03;
571 /* write data command */
572 target_write_u16(target
, bank_adr
, 0x40);
573 target_write_memory(target
, address
, 2, 1, last_halfword
);
575 /* query status command */
576 target_write_u16(target
, bank_adr
, 0x70);
579 for (timeout
= 0; timeout
< 1000; timeout
++)
581 target_read_u8(target
, bank_adr
, &status
);
588 LOG_ERROR("write timed out");
592 /* clear status reg and read array */
593 target_write_u16(target
, bank_adr
, 0x50);
594 target_write_u16(target
, bank_adr
, 0xFF);
597 return ERROR_FLASH_OPERATION_FAILED
;
598 else if (status
& 0x02)
599 return ERROR_FLASH_OPERATION_FAILED
;
605 static int str9x_probe(struct flash_bank
*bank
)
611 COMMAND_HANDLER(str9x_handle_part_id_command
)
617 static int str9x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
619 snprintf(buf
, buf_size
, "str9x flash driver info");
623 COMMAND_HANDLER(str9x_handle_flash_config_command
)
625 struct str9x_flash_bank
*str9x_info
;
626 struct target
*target
= NULL
;
630 return ERROR_COMMAND_SYNTAX_ERROR
;
633 struct flash_bank
*bank
;
634 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
635 if (ERROR_OK
!= retval
)
638 uint32_t bbsr
, nbbsr
, bbadr
, nbbadr
;
639 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], bbsr
);
640 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], nbbsr
);
641 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], bbadr
);
642 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[4], nbbadr
);
644 str9x_info
= bank
->driver_priv
;
646 target
= bank
->target
;
648 if (bank
->target
->state
!= TARGET_HALTED
)
650 LOG_ERROR("Target not halted");
651 return ERROR_TARGET_NOT_HALTED
;
654 /* config flash controller */
655 target_write_u32(target
, FLASH_BBSR
, bbsr
);
656 target_write_u32(target
, FLASH_NBBSR
, nbbsr
);
657 target_write_u32(target
, FLASH_BBADR
, bbadr
>> 2);
658 target_write_u32(target
, FLASH_NBBADR
, nbbadr
>> 2);
660 /* set bit 18 instruction TCM order as per flash programming manual */
661 arm966e_write_cp15(target
, 62, 0x40000);
663 /* enable flash bank 1 */
664 target_write_u32(target
, FLASH_CR
, 0x18);
668 static const struct command_registration str9x_config_command_handlers
[] = {
670 .name
= "flash_config",
671 .handler
= str9x_handle_flash_config_command
,
672 .mode
= COMMAND_EXEC
,
673 .help
= "Configure str9x flash controller, prior to "
674 "programming the flash.",
675 .usage
= "bank_id BBSR NBBSR BBADR NBBADR",
677 COMMAND_REGISTRATION_DONE
679 static const struct command_registration str9x_command_handlers
[] = {
683 .help
= "str9x flash command group",
684 .chain
= str9x_config_command_handlers
,
686 COMMAND_REGISTRATION_DONE
689 struct flash_driver str9x_flash
= {
691 .commands
= str9x_command_handlers
,
692 .flash_bank_command
= str9x_flash_bank_command
,
693 .erase
= str9x_erase
,
694 .protect
= str9x_protect
,
695 .write
= str9x_write
,
696 .probe
= str9x_probe
,
697 .auto_probe
= str9x_probe
,
698 .erase_check
= default_flash_blank_check
,
699 .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)