1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 #include "replacements.h"
31 #include "algorithm.h"
32 #include "binarybuffer.h"
38 str9x_mem_layout_t mem_layout_str9
[] = {
39 {0x00000000, 0x10000, 0x01},
40 {0x00010000, 0x10000, 0x02},
41 {0x00020000, 0x10000, 0x04},
42 {0x00030000, 0x10000, 0x08},
43 {0x00040000, 0x10000, 0x10},
44 {0x00050000, 0x10000, 0x20},
45 {0x00060000, 0x10000, 0x40},
46 {0x00070000, 0x10000, 0x80},
47 {0x00080000, 0x02000, 0x100},
48 {0x00082000, 0x02000, 0x200},
49 {0x00084000, 0x02000, 0x400},
50 {0x00086000, 0x02000, 0x800}
53 int str9x_register_commands(struct command_context_s
*cmd_ctx
);
54 int str9x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
55 int str9x_erase(struct flash_bank_s
*bank
, int first
, int last
);
56 int str9x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
57 int str9x_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
58 int str9x_probe(struct flash_bank_s
*bank
);
59 int str9x_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
60 int str9x_protect_check(struct flash_bank_s
*bank
);
61 int str9x_erase_check(struct flash_bank_s
*bank
);
62 int str9x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
64 int str9x_handle_flash_config_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
66 flash_driver_t str9x_flash
=
69 .register_commands
= str9x_register_commands
,
70 .flash_bank_command
= str9x_flash_bank_command
,
72 .protect
= str9x_protect
,
75 .erase_check
= str9x_erase_check
,
76 .protect_check
= str9x_protect_check
,
80 int str9x_register_commands(struct command_context_s
*cmd_ctx
)
82 command_t
*str9x_cmd
= register_command(cmd_ctx
, NULL
, "str9x", NULL
, COMMAND_ANY
, NULL
);
84 register_command(cmd_ctx
, str9x_cmd
, "flash_config", str9x_handle_flash_config_command
, COMMAND_EXEC
,
85 "configure str9 flash controller");
90 int str9x_build_block_list(struct flash_bank_s
*bank
)
92 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
95 int num_sectors
= 0, b0_sectors
= 0;
106 ERROR("BUG: unknown bank->size encountered");
110 num_sectors
= b0_sectors
+ 4;
112 bank
->num_sectors
= num_sectors
;
113 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
114 str9x_info
->sector_bits
= malloc(sizeof(u32
) * num_sectors
);
118 for (i
= 0; i
< b0_sectors
; i
++)
120 bank
->sectors
[num_sectors
].offset
= mem_layout_str9
[i
].sector_start
;
121 bank
->sectors
[num_sectors
].size
= mem_layout_str9
[i
].sector_size
;
122 bank
->sectors
[num_sectors
].is_erased
= -1;
123 bank
->sectors
[num_sectors
].is_protected
= 1;
124 str9x_info
->sector_bits
[num_sectors
++] = mem_layout_str9
[i
].sector_bit
;
127 for (i
= 8; i
< 12; i
++)
129 bank
->sectors
[num_sectors
].offset
= mem_layout_str9
[i
].sector_start
;
130 bank
->sectors
[num_sectors
].size
= mem_layout_str9
[i
].sector_size
;
131 bank
->sectors
[num_sectors
].is_erased
= -1;
132 bank
->sectors
[num_sectors
].is_protected
= 1;
133 str9x_info
->sector_bits
[num_sectors
++] = mem_layout_str9
[i
].sector_bit
;
139 /* flash bank str9x <base> <size> 0 0 <target#>
141 int str9x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
143 str9x_flash_bank_t
*str9x_info
;
147 WARNING("incomplete flash_bank str9x configuration");
148 return ERROR_FLASH_BANK_INVALID
;
151 str9x_info
= malloc(sizeof(str9x_flash_bank_t
));
152 bank
->driver_priv
= str9x_info
;
154 if (bank
->base
!= 0x00000000)
156 WARNING("overriding flash base address for STR91x device with 0x00000000");
157 bank
->base
= 0x00000000;
160 str9x_info
->target
= get_target_by_num(strtoul(args
[5], NULL
, 0));
161 if (!str9x_info
->target
)
163 ERROR("no target '%s' configured", args
[5]);
167 str9x_build_block_list(bank
);
169 str9x_info
->write_algorithm
= NULL
;
174 int str9x_blank_check(struct flash_bank_s
*bank
, int first
, int last
)
176 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
177 target_t
*target
= str9x_info
->target
;
182 if ((first
< 0) || (last
> bank
->num_sectors
))
183 return ERROR_FLASH_SECTOR_INVALID
;
185 if (str9x_info
->target
->state
!= TARGET_HALTED
)
187 return ERROR_TARGET_NOT_HALTED
;
190 buffer
= malloc(256);
192 for (i
= first
; i
<= last
; i
++)
194 bank
->sectors
[i
].is_erased
= 1;
196 target
->type
->read_memory(target
, bank
->base
+ bank
->sectors
[i
].offset
, 4, 256/4, buffer
);
198 for (nBytes
= 0; nBytes
< 256; nBytes
++)
200 if (buffer
[nBytes
] != 0xFF)
202 bank
->sectors
[i
].is_erased
= 0;
213 int str9x_protect_check(struct flash_bank_s
*bank
)
215 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
216 target_t
*target
= str9x_info
->target
;
222 if (str9x_info
->target
->state
!= TARGET_HALTED
)
224 return ERROR_TARGET_NOT_HALTED
;
227 /* read level one protection */
229 adr
= mem_layout_str9
[10].sector_start
+ 4;
231 target_write_u32(target
, adr
, 0x90);
232 target_read_u16(target
, adr
, &status
);
233 target_write_u32(target
, adr
, 0xFF);
235 for (i
= 0; i
< bank
->num_sectors
; i
++)
237 if (status
& str9x_info
->sector_bits
[i
])
238 bank
->sectors
[i
].is_protected
= 1;
240 bank
->sectors
[i
].is_protected
= 0;
246 int str9x_erase(struct flash_bank_s
*bank
, int first
, int last
)
248 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
249 target_t
*target
= str9x_info
->target
;
254 if (str9x_info
->target
->state
!= TARGET_HALTED
)
256 return ERROR_TARGET_NOT_HALTED
;
259 for (i
= first
; i
<= last
; i
++)
261 adr
= bank
->sectors
[i
].offset
;
264 target_write_u16(target
, adr
, 0x20);
265 target_write_u16(target
, adr
, 0xD0);
268 target_write_u16(target
, adr
, 0x70);
271 target_read_u8(target
, adr
, &status
);
277 /* clear status, also clear read array */
278 target_write_u16(target
, adr
, 0x50);
280 /* read array command */
281 target_write_u16(target
, adr
, 0xFF);
285 ERROR("error erasing flash bank, status: 0x%x", status
);
286 return ERROR_FLASH_OPERATION_FAILED
;
290 for (i
= first
; i
<= last
; i
++)
291 bank
->sectors
[i
].is_erased
= 1;
296 int str9x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
298 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
299 target_t
*target
= str9x_info
->target
;
304 if (str9x_info
->target
->state
!= TARGET_HALTED
)
306 return ERROR_TARGET_NOT_HALTED
;
309 for (i
= first
; i
<= last
; i
++)
311 /* Level One Protection */
313 adr
= bank
->sectors
[i
].offset
;
315 target_write_u16(target
, adr
, 0x60);
317 target_write_u16(target
, adr
, 0x01);
319 target_write_u16(target
, adr
, 0xD0);
322 target_read_u8(target
, adr
, &status
);
328 int str9x_write_block(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
330 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
331 target_t
*target
= str9x_info
->target
;
332 u32 buffer_size
= 8192;
333 working_area_t
*source
;
334 u32 address
= bank
->base
+ offset
;
335 reg_param_t reg_params
[4];
336 armv4_5_algorithm_t armv4_5_info
;
339 u32 str9x_flash_write_code
[] = {
341 0xe3c14003, /* bic r4, r1, #3 */
342 0xe3a03040, /* mov r3, #0x40 */
343 0xe1c430b0, /* strh r3, [r4, #0] */
344 0xe0d030b2, /* ldrh r3, [r0], #2 */
345 0xe0c130b2, /* strh r3, [r1], #2 */
346 0xe3a03070, /* mov r3, #0x70 */
347 0xe1c430b0, /* strh r3, [r4, #0] */
349 0xe5d43000, /* ldrb r3, [r4, #0] */
350 0xe3130080, /* tst r3, #0x80 */
351 0x0afffffc, /* beq busy */
352 0xe3a05050, /* mov r5, #0x50 */
353 0xe1c450b0, /* strh r5, [r4, #0] */
354 0xe3a050ff, /* mov r5, #0xFF */
355 0xe1c450b0, /* strh r5, [r4, #0] */
356 0xe3130012, /* tst r3, #0x12 */
357 0x1a000001, /* bne exit */
358 0xe2522001, /* subs r2, r2, #1 */
359 0x1affffed, /* bne write */
361 0xeafffffe, /* b exit */
364 u8 str9x_flash_write_code_buf
[76];
367 /* flash write code */
368 if (!str9x_info
->write_algorithm
)
370 if (target_alloc_working_area(target
, 4 * 19, &str9x_info
->write_algorithm
) != ERROR_OK
)
372 WARNING("no working area available, can't do block memory writes");
373 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
376 /* convert flash writing code into a buffer in target endianness */
377 for (i
= 0; i
< 19; i
++)
378 target_buffer_set_u32(target
, str9x_flash_write_code_buf
+ i
*4, str9x_flash_write_code
[i
]);
380 target_write_buffer(target
, str9x_info
->write_algorithm
->address
, 19 * 4, str9x_flash_write_code_buf
);
384 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
387 if (buffer_size
<= 256)
389 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
390 if (str9x_info
->write_algorithm
)
391 target_free_working_area(target
, str9x_info
->write_algorithm
);
393 WARNING("no large enough working area available, can't do block memory writes");
394 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
398 armv4_5_info
.common_magic
= ARMV4_5_COMMON_MAGIC
;
399 armv4_5_info
.core_mode
= ARMV4_5_MODE_SVC
;
400 armv4_5_info
.core_state
= ARMV4_5_STATE_ARM
;
402 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
403 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
404 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
405 init_reg_param(®_params
[3], "r3", 32, PARAM_IN
);
409 u32 thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
411 target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
413 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
414 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
415 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
417 if ((retval
= target
->type
->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
)
419 ERROR("error executing str9x flash write algorithm");
420 return ERROR_FLASH_OPERATION_FAILED
;
423 if (buf_get_u32(reg_params
[3].value
, 0, 32) != 0x80)
425 return ERROR_FLASH_OPERATION_FAILED
;
428 buffer
+= thisrun_count
* 2;
429 address
+= thisrun_count
* 2;
430 count
-= thisrun_count
;
433 destroy_reg_param(®_params
[0]);
434 destroy_reg_param(®_params
[1]);
435 destroy_reg_param(®_params
[2]);
436 destroy_reg_param(®_params
[3]);
441 int str9x_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
443 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
444 target_t
*target
= str9x_info
->target
;
445 u32 words_remaining
= (count
/ 2);
446 u32 bytes_remaining
= (count
& 0x00000001);
447 u32 address
= bank
->base
+ offset
;
448 u32 bytes_written
= 0;
451 u32 check_address
= offset
;
455 if (str9x_info
->target
->state
!= TARGET_HALTED
)
457 return ERROR_TARGET_NOT_HALTED
;
462 WARNING("offset 0x%x breaks required 2-byte alignment", offset
);
463 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
466 for (i
= 0; i
< bank
->num_sectors
; i
++)
468 u32 sec_start
= bank
->sectors
[i
].offset
;
469 u32 sec_end
= sec_start
+ bank
->sectors
[i
].size
;
471 /* check if destination falls within the current sector */
472 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
474 /* check if destination ends in the current sector */
475 if (offset
+ count
< sec_end
)
476 check_address
= offset
+ count
;
478 check_address
= sec_end
;
482 if (check_address
!= offset
+ count
)
483 return ERROR_FLASH_DST_OUT_OF_BANK
;
485 /* multiple half words (2-byte) to be programmed? */
486 if (words_remaining
> 0)
488 /* try using a block write */
489 if ((retval
= str9x_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
491 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
493 /* if block write failed (no sufficient working area),
494 * we use normal (slow) single dword accesses */
495 WARNING("couldn't use block writes, falling back to single memory accesses");
497 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
499 ERROR("flash writing failed with error code: 0x%x", retval
);
500 return ERROR_FLASH_OPERATION_FAILED
;
505 buffer
+= words_remaining
* 2;
506 address
+= words_remaining
* 2;
511 while (words_remaining
> 0)
513 bank_adr
= address
& ~0x03;
515 /* write data command */
516 target_write_u16(target
, bank_adr
, 0x40);
517 target
->type
->write_memory(target
, address
, 2, 1, buffer
+ bytes_written
);
519 /* get status command */
520 target_write_u16(target
, bank_adr
, 0x70);
523 target_read_u8(target
, bank_adr
, &status
);
529 /* clear status reg and read array */
530 target_write_u16(target
, bank_adr
, 0x50);
531 target_write_u16(target
, bank_adr
, 0xFF);
534 return ERROR_FLASH_OPERATION_FAILED
;
535 else if (status
& 0x02)
536 return ERROR_FLASH_OPERATION_FAILED
;
545 u8 last_halfword
[2] = {0xff, 0xff};
548 while(bytes_remaining
> 0)
550 last_halfword
[i
++] = *(buffer
+ bytes_written
);
555 bank_adr
= address
& ~0x03;
557 /* write data comamnd */
558 target_write_u16(target
, bank_adr
, 0x40);
559 target
->type
->write_memory(target
, address
, 2, 1, last_halfword
);
561 /* query status command */
562 target_write_u16(target
, bank_adr
, 0x70);
565 target_read_u8(target
, bank_adr
, &status
);
571 /* clear status reg and read array */
572 target_write_u16(target
, bank_adr
, 0x50);
573 target_write_u16(target
, bank_adr
, 0xFF);
576 return ERROR_FLASH_OPERATION_FAILED
;
577 else if (status
& 0x02)
578 return ERROR_FLASH_OPERATION_FAILED
;
584 int str9x_probe(struct flash_bank_s
*bank
)
589 int str9x_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
594 int str9x_erase_check(struct flash_bank_s
*bank
)
596 return str9x_blank_check(bank
, 0, bank
->num_sectors
- 1);
599 int str9x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
601 snprintf(buf
, buf_size
, "str9x flash driver info" );
605 int str9x_handle_flash_config_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
607 str9x_flash_bank_t
*str9x_info
;
609 target_t
*target
= NULL
;
613 command_print(cmd_ctx
, "usage: str9x flash_config b0size b1size b0start b1start");
617 bank
= get_flash_bank_by_num(0);
618 str9x_info
= bank
->driver_priv
;
619 target
= str9x_info
->target
;
621 if (str9x_info
->target
->state
!= TARGET_HALTED
)
623 return ERROR_TARGET_NOT_HALTED
;
626 /* config flash controller */
627 target_write_u32(target
, FLASH_BBSR
, strtoul(args
[0], NULL
, 0));
628 target_write_u32(target
, FLASH_NBBSR
, strtoul(args
[1], NULL
, 0));
629 target_write_u32(target
, FLASH_BBADR
, (strtoul(args
[2], NULL
, 0) >> 2));
630 target_write_u32(target
, FLASH_NBBADR
, (strtoul(args
[3], NULL
, 0) >> 2));
632 /* enable flash bank 1 */
633 target_write_u32(target
, FLASH_CR
, 0x18);
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)