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, see <http://www.gnu.org/licenses/>. *
23 ***************************************************************************/
30 #include <target/arm966e.h>
31 #include <target/algorithm.h>
35 #define FLASH_BBSR 0x54000000 /* Boot Bank Size Register */
36 #define FLASH_NBBSR 0x54000004 /* Non-Boot Bank Size Register */
37 #define FLASH_BBADR 0x5400000C /* Boot Bank Base Address Register */
38 #define FLASH_NBBADR 0x54000010 /* Non-Boot Bank Base Address Register */
39 #define FLASH_CR 0x54000018 /* Control Register */
40 #define FLASH_SR 0x5400001C /* Status Register */
41 #define FLASH_BCE5ADDR 0x54000020 /* BC Fifth Entry Target Address Register */
43 struct str9x_flash_bank
{
44 uint32_t *sector_bits
;
49 enum str9x_status_codes
{
50 STR9X_CMD_SUCCESS
= 0,
51 STR9X_INVALID_COMMAND
= 1,
52 STR9X_SRC_ADDR_ERROR
= 2,
53 STR9X_DST_ADDR_ERROR
= 3,
54 STR9X_SRC_ADDR_NOT_MAPPED
= 4,
55 STR9X_DST_ADDR_NOT_MAPPED
= 5,
56 STR9X_COUNT_ERROR
= 6,
57 STR9X_INVALID_SECTOR
= 7,
58 STR9X_SECTOR_NOT_BLANK
= 8,
59 STR9X_SECTOR_NOT_PREPARED
= 9,
60 STR9X_COMPARE_ERROR
= 10,
64 static uint32_t bank1start
= 0x00080000;
66 static int str9x_build_block_list(struct flash_bank
*bank
)
68 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
71 unsigned int num_sectors
;
72 int b0_sectors
= 0, b1_sectors
= 0;
75 /* set if we have large flash str9 */
76 str9x_info
->variant
= 0;
77 str9x_info
->bank1
= 0;
87 bank1start
= 0x00100000;
88 str9x_info
->variant
= 1;
92 bank1start
= 0x00200000;
93 str9x_info
->variant
= 1;
97 str9x_info
->variant
= 1;
98 str9x_info
->bank1
= 1;
100 bank1start
= bank
->base
;
103 str9x_info
->bank1
= 1;
105 bank1start
= bank
->base
;
108 LOG_ERROR("BUG: unknown bank->size encountered");
112 num_sectors
= b0_sectors
+ b1_sectors
;
114 bank
->num_sectors
= num_sectors
;
115 bank
->sectors
= malloc(sizeof(struct flash_sector
) * num_sectors
);
116 str9x_info
->sector_bits
= malloc(sizeof(uint32_t) * num_sectors
);
120 for (i
= 0; i
< b0_sectors
; i
++) {
121 bank
->sectors
[num_sectors
].offset
= offset
;
122 bank
->sectors
[num_sectors
].size
= 0x10000;
123 offset
+= bank
->sectors
[i
].size
;
124 bank
->sectors
[num_sectors
].is_erased
= -1;
125 bank
->sectors
[num_sectors
].is_protected
= 1;
126 str9x_info
->sector_bits
[num_sectors
++] = (1 << i
);
129 for (i
= 0; i
< b1_sectors
; i
++) {
130 bank
->sectors
[num_sectors
].offset
= offset
;
131 bank
->sectors
[num_sectors
].size
= str9x_info
->variant
== 0 ? 0x2000 : 0x4000;
132 offset
+= bank
->sectors
[i
].size
;
133 bank
->sectors
[num_sectors
].is_erased
= -1;
134 bank
->sectors
[num_sectors
].is_protected
= 1;
135 if (str9x_info
->variant
)
136 str9x_info
->sector_bits
[num_sectors
++] = (1 << i
);
138 str9x_info
->sector_bits
[num_sectors
++] = (1 << (i
+ 8));
144 /* flash bank str9x <base> <size> 0 0 <target#>
146 FLASH_BANK_COMMAND_HANDLER(str9x_flash_bank_command
)
148 struct str9x_flash_bank
*str9x_info
;
151 return ERROR_COMMAND_SYNTAX_ERROR
;
153 str9x_info
= malloc(sizeof(struct str9x_flash_bank
));
154 bank
->driver_priv
= str9x_info
;
156 str9x_build_block_list(bank
);
161 static int str9x_protect_check(struct flash_bank
*bank
)
164 struct str9x_flash_bank
*str9x_info
= bank
->driver_priv
;
165 struct target
*target
= bank
->target
;
169 uint16_t hstatus
= 0;
171 if (bank
->target
->state
!= TARGET_HALTED
) {
172 LOG_ERROR("Target not halted");
173 return ERROR_TARGET_NOT_HALTED
;
176 /* read level one protection */
178 if (str9x_info
->variant
) {
179 if (str9x_info
->bank1
) {
180 adr
= bank1start
+ 0x18;
181 retval
= target_write_u16(target
, adr
, 0x90);
182 if (retval
!= ERROR_OK
)
184 retval
= target_read_u16(target
, adr
, &hstatus
);
185 if (retval
!= ERROR_OK
)
189 adr
= bank1start
+ 0x14;
190 retval
= target_write_u16(target
, adr
, 0x90);
191 if (retval
!= ERROR_OK
)
193 retval
= target_read_u32(target
, adr
, &status
);
194 if (retval
!= ERROR_OK
)
198 adr
= bank1start
+ 0x10;
199 retval
= target_write_u16(target
, adr
, 0x90);
200 if (retval
!= ERROR_OK
)
202 retval
= target_read_u16(target
, adr
, &hstatus
);
203 if (retval
!= ERROR_OK
)
208 /* read array command */
209 retval
= target_write_u16(target
, adr
, 0xFF);
210 if (retval
!= ERROR_OK
)
213 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++) {
214 if (status
& str9x_info
->sector_bits
[i
])
215 bank
->sectors
[i
].is_protected
= 1;
217 bank
->sectors
[i
].is_protected
= 0;
223 static int str9x_erase(struct flash_bank
*bank
, unsigned int first
,
226 struct target
*target
= bank
->target
;
232 if (bank
->target
->state
!= TARGET_HALTED
) {
233 LOG_ERROR("Target not halted");
234 return ERROR_TARGET_NOT_HALTED
;
237 /* Check if we can erase whole bank */
238 if ((first
== 0) && (last
== (bank
->num_sectors
- 1))) {
239 /* Optimize to run erase bank command instead of sector */
241 /* Add timeout duration since erase bank takes more time */
242 total_timeout
= 1000 * bank
->num_sectors
;
244 /* Erase sector command */
246 total_timeout
= 1000;
249 /* this is so the compiler can *know* */
250 assert(total_timeout
> 0);
252 for (unsigned int i
= first
; i
<= last
; i
++) {
254 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
256 /* erase sectors or block */
257 retval
= target_write_u16(target
, adr
, erase_cmd
);
258 if (retval
!= ERROR_OK
)
260 retval
= target_write_u16(target
, adr
, 0xD0);
261 if (retval
!= ERROR_OK
)
265 retval
= target_write_u16(target
, adr
, 0x70);
266 if (retval
!= ERROR_OK
)
270 for (timeout
= 0; timeout
< total_timeout
; timeout
++) {
271 retval
= target_read_u8(target
, adr
, &status
);
272 if (retval
!= ERROR_OK
)
278 if (timeout
== total_timeout
) {
279 LOG_ERROR("erase timed out");
283 /* clear status, also clear read array */
284 retval
= target_write_u16(target
, adr
, 0x50);
285 if (retval
!= ERROR_OK
)
288 /* read array command */
289 retval
= target_write_u16(target
, adr
, 0xFF);
290 if (retval
!= ERROR_OK
)
294 LOG_ERROR("error erasing flash bank, status: 0x%x", status
);
295 return ERROR_FLASH_OPERATION_FAILED
;
298 /* If we ran erase bank command, we are finished */
299 if (erase_cmd
== 0x80)
303 for (unsigned int i
= first
; i
<= last
; i
++)
304 bank
->sectors
[i
].is_erased
= 1;
309 static int str9x_protect(struct flash_bank
*bank
, int set
, unsigned int first
,
312 struct target
*target
= bank
->target
;
316 if (bank
->target
->state
!= TARGET_HALTED
) {
317 LOG_ERROR("Target not halted");
318 return ERROR_TARGET_NOT_HALTED
;
321 for (unsigned int i
= first
; i
<= last
; i
++) {
322 /* Level One Protection */
324 adr
= bank
->base
+ bank
->sectors
[i
].offset
;
326 target_write_u16(target
, adr
, 0x60);
328 target_write_u16(target
, adr
, 0x01);
330 target_write_u16(target
, adr
, 0xD0);
333 target_read_u8(target
, adr
, &status
);
335 /* clear status, also clear read array */
336 target_write_u16(target
, adr
, 0x50);
338 /* read array command */
339 target_write_u16(target
, adr
, 0xFF);
345 static int str9x_write_block(struct flash_bank
*bank
,
346 const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
348 struct target
*target
= bank
->target
;
349 uint32_t buffer_size
= 32768;
350 struct working_area
*write_algorithm
;
351 struct working_area
*source
;
352 uint32_t address
= bank
->base
+ offset
;
353 struct reg_param reg_params
[4];
354 struct arm_algorithm arm_algo
;
355 int retval
= ERROR_OK
;
357 /* see contrib/loaders/flash/str9x.s for src */
359 static const uint32_t str9x_flash_write_code
[] = {
361 0xe3c14003, /* bic r4, r1, #3 */
362 0xe3a03040, /* mov r3, #0x40 */
363 0xe1c430b0, /* strh r3, [r4, #0] */
364 0xe0d030b2, /* ldrh r3, [r0], #2 */
365 0xe0c130b2, /* strh r3, [r1], #2 */
366 0xe3a03070, /* mov r3, #0x70 */
367 0xe1c430b0, /* strh r3, [r4, #0] */
369 0xe5d43000, /* ldrb r3, [r4, #0] */
370 0xe3130080, /* tst r3, #0x80 */
371 0x0afffffc, /* beq busy */
372 0xe3a05050, /* mov r5, #0x50 */
373 0xe1c450b0, /* strh r5, [r4, #0] */
374 0xe3a050ff, /* mov r5, #0xFF */
375 0xe1c450b0, /* strh r5, [r4, #0] */
376 0xe3130012, /* tst r3, #0x12 */
377 0x1a000001, /* bne exit */
378 0xe2522001, /* subs r2, r2, #1 */
379 0x1affffed, /* bne write */
381 0xe1200070, /* bkpt #0 */
384 /* flash write code */
385 if (target_alloc_working_area(target
, sizeof(str9x_flash_write_code
),
386 &write_algorithm
) != ERROR_OK
) {
387 LOG_WARNING("no working area available, can't do block memory writes");
388 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
391 uint8_t code
[sizeof(str9x_flash_write_code
)];
392 target_buffer_set_u32_array(target
, code
, ARRAY_SIZE(str9x_flash_write_code
),
393 str9x_flash_write_code
);
394 target_write_buffer(target
, write_algorithm
->address
, sizeof(code
), code
);
397 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
399 if (buffer_size
<= 256) {
400 /* we already allocated the writing code, but failed to get a
401 * buffer, free the algorithm */
402 target_free_working_area(target
, write_algorithm
);
404 LOG_WARNING("no large enough working area available, can't do block memory writes");
405 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
409 arm_algo
.common_magic
= ARM_COMMON_MAGIC
;
410 arm_algo
.core_mode
= ARM_MODE_SVC
;
411 arm_algo
.core_state
= ARM_STATE_ARM
;
413 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
414 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
415 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
416 init_reg_param(®_params
[3], "r3", 32, PARAM_IN
);
419 uint32_t thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
421 target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
423 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
424 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
425 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
427 retval
= target_run_algorithm(target
, 0, NULL
, 4, reg_params
,
428 write_algorithm
->address
,
429 0, 10000, &arm_algo
);
430 if (retval
!= 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) {
437 retval
= ERROR_FLASH_OPERATION_FAILED
;
441 buffer
+= thisrun_count
* 2;
442 address
+= thisrun_count
* 2;
443 count
-= thisrun_count
;
446 target_free_working_area(target
, source
);
447 target_free_working_area(target
, write_algorithm
);
449 destroy_reg_param(®_params
[0]);
450 destroy_reg_param(®_params
[1]);
451 destroy_reg_param(®_params
[2]);
452 destroy_reg_param(®_params
[3]);
457 static int str9x_write(struct flash_bank
*bank
,
458 const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
460 struct target
*target
= bank
->target
;
461 uint32_t words_remaining
= (count
/ 2);
462 uint32_t bytes_remaining
= (count
& 0x00000001);
463 uint32_t address
= bank
->base
+ offset
;
464 uint32_t bytes_written
= 0;
467 uint32_t check_address
= offset
;
470 if (bank
->target
->state
!= TARGET_HALTED
) {
471 LOG_ERROR("Target not halted");
472 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 (unsigned int 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
)) {
486 /* check if destination ends in the current sector */
487 if (offset
+ count
< sec_end
)
488 check_address
= offset
+ count
;
490 check_address
= sec_end
;
494 if (check_address
!= offset
+ count
)
495 return ERROR_FLASH_DST_OUT_OF_BANK
;
497 /* multiple half words (2-byte) to be programmed? */
498 if (words_remaining
> 0) {
499 /* try using a block write */
500 retval
= str9x_write_block(bank
, buffer
, offset
, words_remaining
);
501 if (retval
!= ERROR_OK
) {
502 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
) {
503 /* if block write failed (no sufficient working area),
504 * we use normal (slow) single dword accesses */
505 LOG_WARNING("couldn't use block writes, falling back to single memory accesses");
506 } else if (retval
== ERROR_FLASH_OPERATION_FAILED
) {
507 LOG_ERROR("flash writing failed");
508 return ERROR_FLASH_OPERATION_FAILED
;
511 buffer
+= words_remaining
* 2;
512 address
+= words_remaining
* 2;
517 while (words_remaining
> 0) {
518 bank_adr
= address
& ~0x03;
520 /* write data command */
521 target_write_u16(target
, bank_adr
, 0x40);
522 target_write_memory(target
, address
, 2, 1, buffer
+ bytes_written
);
524 /* get status command */
525 target_write_u16(target
, bank_adr
, 0x70);
528 for (timeout
= 0; timeout
< 1000; timeout
++) {
529 target_read_u8(target
, bank_adr
, &status
);
534 if (timeout
== 1000) {
535 LOG_ERROR("write timed out");
539 /* clear status reg and read array */
540 target_write_u16(target
, bank_adr
, 0x50);
541 target_write_u16(target
, bank_adr
, 0xFF);
544 return ERROR_FLASH_OPERATION_FAILED
;
545 else if (status
& 0x02)
546 return ERROR_FLASH_OPERATION_FAILED
;
553 if (bytes_remaining
) {
554 uint8_t last_halfword
[2] = {0xff, 0xff};
556 /* copy the last remaining bytes into the write buffer */
557 memcpy(last_halfword
, buffer
+bytes_written
, bytes_remaining
);
559 bank_adr
= address
& ~0x03;
561 /* write data command */
562 target_write_u16(target
, bank_adr
, 0x40);
563 target_write_memory(target
, address
, 2, 1, last_halfword
);
565 /* query status command */
566 target_write_u16(target
, bank_adr
, 0x70);
569 for (timeout
= 0; timeout
< 1000; timeout
++) {
570 target_read_u8(target
, bank_adr
, &status
);
575 if (timeout
== 1000) {
576 LOG_ERROR("write timed out");
580 /* clear status reg and read array */
581 target_write_u16(target
, bank_adr
, 0x50);
582 target_write_u16(target
, bank_adr
, 0xFF);
585 return ERROR_FLASH_OPERATION_FAILED
;
586 else if (status
& 0x02)
587 return ERROR_FLASH_OPERATION_FAILED
;
593 static int str9x_probe(struct flash_bank
*bank
)
599 COMMAND_HANDLER(str9x_handle_part_id_command
)
605 COMMAND_HANDLER(str9x_handle_flash_config_command
)
607 struct target
*target
= NULL
;
610 return ERROR_COMMAND_SYNTAX_ERROR
;
612 struct flash_bank
*bank
;
613 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
614 if (ERROR_OK
!= retval
)
617 uint32_t bbsr
, nbbsr
, bbadr
, nbbadr
;
618 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[1], bbsr
);
619 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[2], nbbsr
);
620 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[3], bbadr
);
621 COMMAND_PARSE_NUMBER(u32
, CMD_ARGV
[4], nbbadr
);
623 target
= bank
->target
;
625 if (bank
->target
->state
!= TARGET_HALTED
) {
626 LOG_ERROR("Target not halted");
627 return ERROR_TARGET_NOT_HALTED
;
630 /* config flash controller */
631 target_write_u32(target
, FLASH_BBSR
, bbsr
);
632 target_write_u32(target
, FLASH_NBBSR
, nbbsr
);
633 target_write_u32(target
, FLASH_BBADR
, bbadr
>> 2);
634 target_write_u32(target
, FLASH_NBBADR
, nbbadr
>> 2);
636 /* set bit 18 instruction TCM order as per flash programming manual */
637 arm966e_write_cp15(target
, 62, 0x40000);
639 /* enable flash bank 1 */
640 target_write_u32(target
, FLASH_CR
, 0x18);
644 static const struct command_registration str9x_config_command_handlers
[] = {
646 .name
= "flash_config",
647 .handler
= str9x_handle_flash_config_command
,
648 .mode
= COMMAND_EXEC
,
649 .help
= "Configure str9x flash controller, prior to "
650 "programming the flash.",
651 .usage
= "bank_id BBSR NBBSR BBADR NBBADR",
653 COMMAND_REGISTRATION_DONE
656 static const struct command_registration str9x_command_handlers
[] = {
660 .help
= "str9x flash command group",
662 .chain
= str9x_config_command_handlers
,
664 COMMAND_REGISTRATION_DONE
667 const struct flash_driver str9x_flash
= {
669 .commands
= str9x_command_handlers
,
670 .flash_bank_command
= str9x_flash_bank_command
,
671 .erase
= str9x_erase
,
672 .protect
= str9x_protect
,
673 .write
= str9x_write
,
674 .read
= default_flash_read
,
675 .probe
= str9x_probe
,
676 .auto_probe
= str9x_probe
,
677 .erase_check
= default_flash_blank_check
,
678 .protect_check
= str9x_protect_check
,
679 .free_driver_priv
= default_flash_free_driver_priv
,
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)