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
= 32768;
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 static const 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 0xe1200070, /* bkpt #0 */
375 /* flash write code */
376 if (target_alloc_working_area(target
, sizeof(str9x_flash_write_code
),
377 &str9x_info
->write_algorithm
) != ERROR_OK
)
379 LOG_WARNING("no working area available, can't do block memory writes");
380 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
383 target_write_buffer(target
, str9x_info
->write_algorithm
->address
,
384 sizeof(str9x_flash_write_code
),
385 (uint8_t*)str9x_flash_write_code
);
388 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
)
391 if (buffer_size
<= 256)
393 /* if we already allocated the writing code, but failed to get a
394 * buffer, free the algorithm */
395 if (str9x_info
->write_algorithm
)
396 target_free_working_area(target
, str9x_info
->write_algorithm
);
398 LOG_WARNING("no large enough working area available, can't do block memory writes");
399 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
403 armv4_5_info
.common_magic
= ARM_COMMON_MAGIC
;
404 armv4_5_info
.core_mode
= ARM_MODE_SVC
;
405 armv4_5_info
.core_state
= ARM_STATE_ARM
;
407 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
408 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
409 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
410 init_reg_param(®_params
[3], "r3", 32, PARAM_IN
);
414 uint32_t thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
416 target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
418 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
419 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
420 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
422 if ((retval
= target_run_algorithm(target
, 0, NULL
, 4, reg_params
,
423 str9x_info
->write_algorithm
->address
,
424 0, 10000, &armv4_5_info
)) != ERROR_OK
)
426 LOG_ERROR("error executing str9x flash write algorithm");
427 retval
= ERROR_FLASH_OPERATION_FAILED
;
431 if (buf_get_u32(reg_params
[3].value
, 0, 32) != 0x80)
433 retval
= ERROR_FLASH_OPERATION_FAILED
;
437 buffer
+= thisrun_count
* 2;
438 address
+= thisrun_count
* 2;
439 count
-= thisrun_count
;
442 target_free_working_area(target
, source
);
443 target_free_working_area(target
, str9x_info
->write_algorithm
);
445 destroy_reg_param(®_params
[0]);
446 destroy_reg_param(®_params
[1]);
447 destroy_reg_param(®_params
[2]);
448 destroy_reg_param(®_params
[3]);
453 static int str9x_write(struct flash_bank
*bank
,
454 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
456 struct target
*target
= bank
->target
;
457 uint32_t words_remaining
= (count
/ 2);
458 uint32_t bytes_remaining
= (count
& 0x00000001);
459 uint32_t address
= bank
->base
+ offset
;
460 uint32_t bytes_written
= 0;
463 uint32_t check_address
= offset
;
467 if (bank
->target
->state
!= TARGET_HALTED
)
469 LOG_ERROR("Target not halted");
470 return ERROR_TARGET_NOT_HALTED
;
475 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
476 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
479 for (i
= 0; i
< bank
->num_sectors
; i
++)
481 uint32_t sec_start
= bank
->sectors
[i
].offset
;
482 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
484 /* check if destination falls within the current sector */
485 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
487 /* check if destination ends in the current sector */
488 if (offset
+ count
< sec_end
)
489 check_address
= offset
+ count
;
491 check_address
= sec_end
;
495 if (check_address
!= offset
+ count
)
496 return ERROR_FLASH_DST_OUT_OF_BANK
;
498 /* multiple half words (2-byte) to be programmed? */
499 if (words_remaining
> 0)
501 /* try using a block write */
502 if ((retval
= str9x_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
504 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");
510 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
512 LOG_ERROR("flash writing failed with error code: 0x%x", retval
);
513 return ERROR_FLASH_OPERATION_FAILED
;
518 buffer
+= words_remaining
* 2;
519 address
+= words_remaining
* 2;
524 while (words_remaining
> 0)
526 bank_adr
= address
& ~0x03;
528 /* write data command */
529 target_write_u16(target
, bank_adr
, 0x40);
530 target_write_memory(target
, address
, 2, 1, buffer
+ bytes_written
);
532 /* get status command */
533 target_write_u16(target
, bank_adr
, 0x70);
536 for (timeout
= 0; timeout
< 1000; timeout
++)
538 target_read_u8(target
, bank_adr
, &status
);
545 LOG_ERROR("write timed out");
549 /* clear status reg and read array */
550 target_write_u16(target
, bank_adr
, 0x50);
551 target_write_u16(target
, bank_adr
, 0xFF);
554 return ERROR_FLASH_OPERATION_FAILED
;
555 else if (status
& 0x02)
556 return ERROR_FLASH_OPERATION_FAILED
;
565 uint8_t last_halfword
[2] = {0xff, 0xff};
568 while (bytes_remaining
> 0)
570 last_halfword
[i
++] = *(buffer
+ bytes_written
);
575 bank_adr
= address
& ~0x03;
577 /* write data command */
578 target_write_u16(target
, bank_adr
, 0x40);
579 target_write_memory(target
, address
, 2, 1, last_halfword
);
581 /* query status command */
582 target_write_u16(target
, bank_adr
, 0x70);
585 for (timeout
= 0; timeout
< 1000; timeout
++)
587 target_read_u8(target
, bank_adr
, &status
);
594 LOG_ERROR("write timed out");
598 /* clear status reg and read array */
599 target_write_u16(target
, bank_adr
, 0x50);
600 target_write_u16(target
, bank_adr
, 0xFF);
603 return ERROR_FLASH_OPERATION_FAILED
;
604 else if (status
& 0x02)
605 return ERROR_FLASH_OPERATION_FAILED
;
611 static int str9x_probe(struct flash_bank
*bank
)
617 COMMAND_HANDLER(str9x_handle_part_id_command
)
623 static int get_str9x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
625 snprintf(buf
, buf_size
, "str9x flash driver info");
629 COMMAND_HANDLER(str9x_handle_flash_config_command
)
631 struct str9x_flash_bank
*str9x_info
;
632 struct target
*target
= NULL
;
636 return ERROR_COMMAND_SYNTAX_ERROR
;
639 struct flash_bank
*bank
;
640 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
641 if (ERROR_OK
!= retval
)
644 uint32_t bbsr
, nbbsr
, bbadr
, nbbadr
;
645 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], bbsr
);
646 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], nbbsr
);
647 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], bbadr
);
648 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[4], nbbadr
);
650 str9x_info
= bank
->driver_priv
;
652 target
= bank
->target
;
654 if (bank
->target
->state
!= TARGET_HALTED
)
656 LOG_ERROR("Target not halted");
657 return ERROR_TARGET_NOT_HALTED
;
660 /* config flash controller */
661 target_write_u32(target
, FLASH_BBSR
, bbsr
);
662 target_write_u32(target
, FLASH_NBBSR
, nbbsr
);
663 target_write_u32(target
, FLASH_BBADR
, bbadr
>> 2);
664 target_write_u32(target
, FLASH_NBBADR
, nbbadr
>> 2);
666 /* set bit 18 instruction TCM order as per flash programming manual */
667 arm966e_write_cp15(target
, 62, 0x40000);
669 /* enable flash bank 1 */
670 target_write_u32(target
, FLASH_CR
, 0x18);
674 static const struct command_registration str9x_config_command_handlers
[] = {
676 .name
= "flash_config",
677 .handler
= str9x_handle_flash_config_command
,
678 .mode
= COMMAND_EXEC
,
679 .help
= "Configure str9x flash controller, prior to "
680 "programming the flash.",
681 .usage
= "bank_id BBSR NBBSR BBADR NBBADR",
683 COMMAND_REGISTRATION_DONE
686 static const struct command_registration str9x_command_handlers
[] = {
690 .help
= "str9x flash command group",
691 .chain
= str9x_config_command_handlers
,
693 COMMAND_REGISTRATION_DONE
696 struct flash_driver str9x_flash
= {
698 .commands
= str9x_command_handlers
,
699 .flash_bank_command
= str9x_flash_bank_command
,
700 .erase
= str9x_erase
,
701 .protect
= str9x_protect
,
702 .write
= str9x_write
,
703 .read
= default_flash_read
,
704 .probe
= str9x_probe
,
705 .auto_probe
= str9x_probe
,
706 .erase_check
= default_flash_blank_check
,
707 .protect_check
= str9x_protect_check
,
708 .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)