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 0xeafffffe, /* b exit */
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 str9x_info
->write_algorithm
->address
+ (sizeof(str9x_flash_write_code
) - 4),
425 10000, &armv4_5_info
)) != ERROR_OK
)
427 LOG_ERROR("error executing str9x flash write algorithm");
428 retval
= ERROR_FLASH_OPERATION_FAILED
;
432 if (buf_get_u32(reg_params
[3].value
, 0, 32) != 0x80)
434 retval
= ERROR_FLASH_OPERATION_FAILED
;
438 buffer
+= thisrun_count
* 2;
439 address
+= thisrun_count
* 2;
440 count
-= thisrun_count
;
443 target_free_working_area(target
, source
);
444 target_free_working_area(target
, str9x_info
->write_algorithm
);
446 destroy_reg_param(®_params
[0]);
447 destroy_reg_param(®_params
[1]);
448 destroy_reg_param(®_params
[2]);
449 destroy_reg_param(®_params
[3]);
454 static int str9x_write(struct flash_bank
*bank
,
455 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
457 struct target
*target
= bank
->target
;
458 uint32_t words_remaining
= (count
/ 2);
459 uint32_t bytes_remaining
= (count
& 0x00000001);
460 uint32_t address
= bank
->base
+ offset
;
461 uint32_t bytes_written
= 0;
464 uint32_t check_address
= offset
;
468 if (bank
->target
->state
!= TARGET_HALTED
)
470 LOG_ERROR("Target not halted");
471 return ERROR_TARGET_NOT_HALTED
;
476 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
477 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
480 for (i
= 0; i
< bank
->num_sectors
; i
++)
482 uint32_t sec_start
= bank
->sectors
[i
].offset
;
483 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
485 /* check if destination falls within the current sector */
486 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
488 /* check if destination ends in the current sector */
489 if (offset
+ count
< sec_end
)
490 check_address
= offset
+ count
;
492 check_address
= sec_end
;
496 if (check_address
!= offset
+ count
)
497 return ERROR_FLASH_DST_OUT_OF_BANK
;
499 /* multiple half words (2-byte) to be programmed? */
500 if (words_remaining
> 0)
502 /* try using a block write */
503 if ((retval
= str9x_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
505 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
507 /* if block write failed (no sufficient working area),
508 * we use normal (slow) single dword accesses */
509 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
511 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
513 LOG_ERROR("flash writing failed with error code: 0x%x", retval
);
514 return ERROR_FLASH_OPERATION_FAILED
;
519 buffer
+= words_remaining
* 2;
520 address
+= words_remaining
* 2;
525 while (words_remaining
> 0)
527 bank_adr
= address
& ~0x03;
529 /* write data command */
530 target_write_u16(target
, bank_adr
, 0x40);
531 target_write_memory(target
, address
, 2, 1, buffer
+ bytes_written
);
533 /* get status command */
534 target_write_u16(target
, bank_adr
, 0x70);
537 for (timeout
= 0; timeout
< 1000; timeout
++)
539 target_read_u8(target
, bank_adr
, &status
);
546 LOG_ERROR("write timed out");
550 /* clear status reg and read array */
551 target_write_u16(target
, bank_adr
, 0x50);
552 target_write_u16(target
, bank_adr
, 0xFF);
555 return ERROR_FLASH_OPERATION_FAILED
;
556 else if (status
& 0x02)
557 return ERROR_FLASH_OPERATION_FAILED
;
566 uint8_t last_halfword
[2] = {0xff, 0xff};
569 while (bytes_remaining
> 0)
571 last_halfword
[i
++] = *(buffer
+ bytes_written
);
576 bank_adr
= address
& ~0x03;
578 /* write data command */
579 target_write_u16(target
, bank_adr
, 0x40);
580 target_write_memory(target
, address
, 2, 1, last_halfword
);
582 /* query status command */
583 target_write_u16(target
, bank_adr
, 0x70);
586 for (timeout
= 0; timeout
< 1000; timeout
++)
588 target_read_u8(target
, bank_adr
, &status
);
595 LOG_ERROR("write timed out");
599 /* clear status reg and read array */
600 target_write_u16(target
, bank_adr
, 0x50);
601 target_write_u16(target
, bank_adr
, 0xFF);
604 return ERROR_FLASH_OPERATION_FAILED
;
605 else if (status
& 0x02)
606 return ERROR_FLASH_OPERATION_FAILED
;
612 static int str9x_probe(struct flash_bank
*bank
)
618 COMMAND_HANDLER(str9x_handle_part_id_command
)
624 static int get_str9x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
626 snprintf(buf
, buf_size
, "str9x flash driver info");
630 COMMAND_HANDLER(str9x_handle_flash_config_command
)
632 struct str9x_flash_bank
*str9x_info
;
633 struct target
*target
= NULL
;
637 return ERROR_COMMAND_SYNTAX_ERROR
;
640 struct flash_bank
*bank
;
641 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
642 if (ERROR_OK
!= retval
)
645 uint32_t bbsr
, nbbsr
, bbadr
, nbbadr
;
646 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], bbsr
);
647 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], nbbsr
);
648 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], bbadr
);
649 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[4], nbbadr
);
651 str9x_info
= bank
->driver_priv
;
653 target
= bank
->target
;
655 if (bank
->target
->state
!= TARGET_HALTED
)
657 LOG_ERROR("Target not halted");
658 return ERROR_TARGET_NOT_HALTED
;
661 /* config flash controller */
662 target_write_u32(target
, FLASH_BBSR
, bbsr
);
663 target_write_u32(target
, FLASH_NBBSR
, nbbsr
);
664 target_write_u32(target
, FLASH_BBADR
, bbadr
>> 2);
665 target_write_u32(target
, FLASH_NBBADR
, nbbadr
>> 2);
667 /* set bit 18 instruction TCM order as per flash programming manual */
668 arm966e_write_cp15(target
, 62, 0x40000);
670 /* enable flash bank 1 */
671 target_write_u32(target
, FLASH_CR
, 0x18);
675 static const struct command_registration str9x_config_command_handlers
[] = {
677 .name
= "flash_config",
678 .handler
= str9x_handle_flash_config_command
,
679 .mode
= COMMAND_EXEC
,
680 .help
= "Configure str9x flash controller, prior to "
681 "programming the flash.",
682 .usage
= "bank_id BBSR NBBSR BBADR NBBADR",
684 COMMAND_REGISTRATION_DONE
687 static const struct command_registration str9x_command_handlers
[] = {
691 .help
= "str9x flash command group",
692 .chain
= str9x_config_command_handlers
,
694 COMMAND_REGISTRATION_DONE
697 struct flash_driver str9x_flash
= {
699 .commands
= str9x_command_handlers
,
700 .flash_bank_command
= str9x_flash_bank_command
,
701 .erase
= str9x_erase
,
702 .protect
= str9x_protect
,
703 .write
= str9x_write
,
704 .read
= default_flash_read
,
705 .probe
= str9x_probe
,
706 .auto_probe
= str9x_probe
,
707 .erase_check
= default_flash_blank_check
,
708 .protect_check
= str9x_protect_check
,
709 .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)