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
;
228 if (bank
->target
->state
!= TARGET_HALTED
)
230 LOG_ERROR("Target not halted");
231 return ERROR_TARGET_NOT_HALTED
;
234 /* Check if we can erase whole bank */
235 if ((first
== 0) && (last
== (bank
->num_sectors
- 1)))
237 /* Optimize to run erase bank command instead of sector */
239 /* Add timeout duration since erase bank takes more time */
240 total_timeout
= 1000 * bank
->num_sectors
;
244 /* Erase sector command */
246 total_timeout
= 1000;
249 for (i
= first
; i
<= last
; i
++)
252 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
254 /* erase sectors or block */
255 if ((retval
= target_write_u16(target
, adr
, erase_cmd
)) != ERROR_OK
)
259 if ((retval
= target_write_u16(target
, adr
, 0xD0)) != ERROR_OK
)
265 if ((retval
= target_write_u16(target
, adr
, 0x70)) != ERROR_OK
)
271 for (timeout
= 0; timeout
< total_timeout
; timeout
++)
273 if ((retval
= target_read_u8(target
, adr
, &status
)) != ERROR_OK
)
281 if (timeout
== total_timeout
)
283 LOG_ERROR("erase timed out");
287 /* clear status, also clear read array */
288 if ((retval
= target_write_u16(target
, adr
, 0x50)) != ERROR_OK
)
293 /* read array command */
294 if ((retval
= target_write_u16(target
, adr
, 0xFF)) != ERROR_OK
)
301 LOG_ERROR("error erasing flash bank, status: 0x%x", status
);
302 return ERROR_FLASH_OPERATION_FAILED
;
305 /* If we ran erase bank command, we are finished */
306 if (erase_cmd
== 0x80)
310 for (i
= first
; i
<= last
; i
++)
311 bank
->sectors
[i
].is_erased
= 1;
316 static int str9x_protect(struct flash_bank
*bank
,
317 int set
, int first
, int last
)
319 struct target
*target
= bank
->target
;
324 if (bank
->target
->state
!= TARGET_HALTED
)
326 LOG_ERROR("Target not halted");
327 return ERROR_TARGET_NOT_HALTED
;
330 for (i
= first
; i
<= last
; i
++)
332 /* Level One Protection */
334 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
336 target_write_u16(target
, adr
, 0x60);
338 target_write_u16(target
, adr
, 0x01);
340 target_write_u16(target
, adr
, 0xD0);
343 target_read_u8(target
, adr
, &status
);
345 /* clear status, also clear read array */
346 target_write_u16(target
, adr
, 0x50);
348 /* read array command */
349 target_write_u16(target
, adr
, 0xFF);
355 static int str9x_write_block(struct flash_bank
*bank
,
356 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
358 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
359 struct target
*target
= bank
->target
;
360 uint32_t buffer_size
= 32768;
361 struct working_area
*source
;
362 uint32_t address
= bank
->base
+ offset
;
363 struct reg_param reg_params
[4];
364 struct arm_algorithm armv4_5_info
;
365 int retval
= ERROR_OK
;
367 static const uint32_t str9x_flash_write_code
[] = {
369 0xe3c14003, /* bic r4, r1, #3 */
370 0xe3a03040, /* mov r3, #0x40 */
371 0xe1c430b0, /* strh r3, [r4, #0] */
372 0xe0d030b2, /* ldrh r3, [r0], #2 */
373 0xe0c130b2, /* strh r3, [r1], #2 */
374 0xe3a03070, /* mov r3, #0x70 */
375 0xe1c430b0, /* strh r3, [r4, #0] */
377 0xe5d43000, /* ldrb r3, [r4, #0] */
378 0xe3130080, /* tst r3, #0x80 */
379 0x0afffffc, /* beq busy */
380 0xe3a05050, /* mov r5, #0x50 */
381 0xe1c450b0, /* strh r5, [r4, #0] */
382 0xe3a050ff, /* mov r5, #0xFF */
383 0xe1c450b0, /* strh r5, [r4, #0] */
384 0xe3130012, /* tst r3, #0x12 */
385 0x1a000001, /* bne exit */
386 0xe2522001, /* subs r2, r2, #1 */
387 0x1affffed, /* bne write */
389 0xe1200070, /* bkpt #0 */
392 /* flash write code */
393 if (target_alloc_working_area(target
, sizeof(str9x_flash_write_code
),
394 &str9x_info
->write_algorithm
) != ERROR_OK
)
396 LOG_WARNING("no working area available, can't do block memory writes");
397 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
400 target_write_buffer(target
, str9x_info
->write_algorithm
->address
,
401 sizeof(str9x_flash_write_code
),
402 (uint8_t*)str9x_flash_write_code
);
405 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
)
408 if (buffer_size
<= 256)
410 /* if we already allocated the writing code, but failed to get a
411 * buffer, free the algorithm */
412 if (str9x_info
->write_algorithm
)
413 target_free_working_area(target
, str9x_info
->write_algorithm
);
415 LOG_WARNING("no large enough working area available, can't do block memory writes");
416 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
420 armv4_5_info
.common_magic
= ARM_COMMON_MAGIC
;
421 armv4_5_info
.core_mode
= ARM_MODE_SVC
;
422 armv4_5_info
.core_state
= ARM_STATE_ARM
;
424 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
425 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
426 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
427 init_reg_param(®_params
[3], "r3", 32, PARAM_IN
);
431 uint32_t thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
433 target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
435 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
436 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
437 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
439 if ((retval
= target_run_algorithm(target
, 0, NULL
, 4, reg_params
,
440 str9x_info
->write_algorithm
->address
,
441 0, 10000, &armv4_5_info
)) != ERROR_OK
)
443 LOG_ERROR("error executing str9x flash write algorithm");
444 retval
= ERROR_FLASH_OPERATION_FAILED
;
448 if (buf_get_u32(reg_params
[3].value
, 0, 32) != 0x80)
450 retval
= ERROR_FLASH_OPERATION_FAILED
;
454 buffer
+= thisrun_count
* 2;
455 address
+= thisrun_count
* 2;
456 count
-= thisrun_count
;
459 target_free_working_area(target
, source
);
460 target_free_working_area(target
, str9x_info
->write_algorithm
);
462 destroy_reg_param(®_params
[0]);
463 destroy_reg_param(®_params
[1]);
464 destroy_reg_param(®_params
[2]);
465 destroy_reg_param(®_params
[3]);
470 static int str9x_write(struct flash_bank
*bank
,
471 uint8_t *buffer
, uint32_t offset
, uint32_t count
)
473 struct target
*target
= bank
->target
;
474 uint32_t words_remaining
= (count
/ 2);
475 uint32_t bytes_remaining
= (count
& 0x00000001);
476 uint32_t address
= bank
->base
+ offset
;
477 uint32_t bytes_written
= 0;
480 uint32_t check_address
= offset
;
484 if (bank
->target
->state
!= TARGET_HALTED
)
486 LOG_ERROR("Target not halted");
487 return ERROR_TARGET_NOT_HALTED
;
492 LOG_WARNING("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
493 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
496 for (i
= 0; i
< bank
->num_sectors
; i
++)
498 uint32_t sec_start
= bank
->sectors
[i
].offset
;
499 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
501 /* check if destination falls within the current sector */
502 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
504 /* check if destination ends in the current sector */
505 if (offset
+ count
< sec_end
)
506 check_address
= offset
+ count
;
508 check_address
= sec_end
;
512 if (check_address
!= offset
+ count
)
513 return ERROR_FLASH_DST_OUT_OF_BANK
;
515 /* multiple half words (2-byte) to be programmed? */
516 if (words_remaining
> 0)
518 /* try using a block write */
519 if ((retval
= str9x_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
521 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
523 /* if block write failed (no sufficient working area),
524 * we use normal (slow) single dword accesses */
525 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
527 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
529 LOG_ERROR("flash writing failed with error code: 0x%x", retval
);
530 return ERROR_FLASH_OPERATION_FAILED
;
535 buffer
+= words_remaining
* 2;
536 address
+= words_remaining
* 2;
541 while (words_remaining
> 0)
543 bank_adr
= address
& ~0x03;
545 /* write data command */
546 target_write_u16(target
, bank_adr
, 0x40);
547 target_write_memory(target
, address
, 2, 1, buffer
+ bytes_written
);
549 /* get status command */
550 target_write_u16(target
, bank_adr
, 0x70);
553 for (timeout
= 0; timeout
< 1000; timeout
++)
555 target_read_u8(target
, bank_adr
, &status
);
562 LOG_ERROR("write timed out");
566 /* clear status reg and read array */
567 target_write_u16(target
, bank_adr
, 0x50);
568 target_write_u16(target
, bank_adr
, 0xFF);
571 return ERROR_FLASH_OPERATION_FAILED
;
572 else if (status
& 0x02)
573 return ERROR_FLASH_OPERATION_FAILED
;
582 uint8_t last_halfword
[2] = {0xff, 0xff};
585 while (bytes_remaining
> 0)
587 last_halfword
[i
++] = *(buffer
+ bytes_written
);
592 bank_adr
= address
& ~0x03;
594 /* write data command */
595 target_write_u16(target
, bank_adr
, 0x40);
596 target_write_memory(target
, address
, 2, 1, last_halfword
);
598 /* query status command */
599 target_write_u16(target
, bank_adr
, 0x70);
602 for (timeout
= 0; timeout
< 1000; timeout
++)
604 target_read_u8(target
, bank_adr
, &status
);
611 LOG_ERROR("write timed out");
615 /* clear status reg and read array */
616 target_write_u16(target
, bank_adr
, 0x50);
617 target_write_u16(target
, bank_adr
, 0xFF);
620 return ERROR_FLASH_OPERATION_FAILED
;
621 else if (status
& 0x02)
622 return ERROR_FLASH_OPERATION_FAILED
;
628 static int str9x_probe(struct flash_bank
*bank
)
634 COMMAND_HANDLER(str9x_handle_part_id_command
)
640 static int get_str9x_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
642 snprintf(buf
, buf_size
, "str9x flash driver info");
646 COMMAND_HANDLER(str9x_handle_flash_config_command
)
648 struct str9x_flash_bank
*str9x_info
;
649 struct target
*target
= NULL
;
653 return ERROR_COMMAND_SYNTAX_ERROR
;
656 struct flash_bank
*bank
;
657 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
658 if (ERROR_OK
!= retval
)
661 uint32_t bbsr
, nbbsr
, bbadr
, nbbadr
;
662 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], bbsr
);
663 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], nbbsr
);
664 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], bbadr
);
665 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[4], nbbadr
);
667 str9x_info
= bank
->driver_priv
;
669 target
= bank
->target
;
671 if (bank
->target
->state
!= TARGET_HALTED
)
673 LOG_ERROR("Target not halted");
674 return ERROR_TARGET_NOT_HALTED
;
677 /* config flash controller */
678 target_write_u32(target
, FLASH_BBSR
, bbsr
);
679 target_write_u32(target
, FLASH_NBBSR
, nbbsr
);
680 target_write_u32(target
, FLASH_BBADR
, bbadr
>> 2);
681 target_write_u32(target
, FLASH_NBBADR
, nbbadr
>> 2);
683 /* set bit 18 instruction TCM order as per flash programming manual */
684 arm966e_write_cp15(target
, 62, 0x40000);
686 /* enable flash bank 1 */
687 target_write_u32(target
, FLASH_CR
, 0x18);
691 static const struct command_registration str9x_config_command_handlers
[] = {
693 .name
= "flash_config",
694 .handler
= str9x_handle_flash_config_command
,
695 .mode
= COMMAND_EXEC
,
696 .help
= "Configure str9x flash controller, prior to "
697 "programming the flash.",
698 .usage
= "bank_id BBSR NBBSR BBADR NBBADR",
700 COMMAND_REGISTRATION_DONE
703 static const struct command_registration str9x_command_handlers
[] = {
707 .help
= "str9x flash command group",
708 .chain
= str9x_config_command_handlers
,
710 COMMAND_REGISTRATION_DONE
713 struct flash_driver str9x_flash
= {
715 .commands
= str9x_command_handlers
,
716 .flash_bank_command
= str9x_flash_bank_command
,
717 .erase
= str9x_erase
,
718 .protect
= str9x_protect
,
719 .write
= str9x_write
,
720 .read
= default_flash_read
,
721 .probe
= str9x_probe
,
722 .auto_probe
= str9x_probe
,
723 .erase_check
= default_flash_blank_check
,
724 .protect_check
= str9x_protect_check
,
725 .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)