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"
32 #include "algorithm.h"
33 #include "binarybuffer.h"
39 str9x_mem_layout_t mem_layout_str9
[] = {
40 {0x00000000, 0x10000, 0x01},
41 {0x00010000, 0x10000, 0x02},
42 {0x00020000, 0x10000, 0x04},
43 {0x00030000, 0x10000, 0x08},
44 {0x00040000, 0x10000, 0x10},
45 {0x00050000, 0x10000, 0x20},
46 {0x00060000, 0x10000, 0x40},
47 {0x00070000, 0x10000, 0x80},
48 {0x00080000, 0x02000, 0x100},
49 {0x00082000, 0x02000, 0x200},
50 {0x00084000, 0x02000, 0x400},
51 {0x00086000, 0x02000, 0x800}
54 int str9x_register_commands(struct command_context_s
*cmd_ctx
);
55 int str9x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
56 int str9x_erase(struct flash_bank_s
*bank
, int first
, int last
);
57 int str9x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
58 int str9x_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
59 int str9x_probe(struct flash_bank_s
*bank
);
60 int str9x_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
61 int str9x_protect_check(struct flash_bank_s
*bank
);
62 int str9x_erase_check(struct flash_bank_s
*bank
);
63 int str9x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
65 int str9x_handle_flash_config_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
67 flash_driver_t str9x_flash
=
70 .register_commands
= str9x_register_commands
,
71 .flash_bank_command
= str9x_flash_bank_command
,
73 .protect
= str9x_protect
,
76 .erase_check
= str9x_erase_check
,
77 .protect_check
= str9x_protect_check
,
81 int str9x_register_commands(struct command_context_s
*cmd_ctx
)
83 command_t
*str9x_cmd
= register_command(cmd_ctx
, NULL
, "str9x", NULL
, COMMAND_ANY
, NULL
);
85 register_command(cmd_ctx
, str9x_cmd
, "flash_config", str9x_handle_flash_config_command
, COMMAND_EXEC
,
86 "configure str9 flash controller");
91 int str9x_build_block_list(struct flash_bank_s
*bank
)
93 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
96 int num_sectors
= 0, b0_sectors
= 0;
107 ERROR("BUG: unknown bank->size encountered");
111 num_sectors
= b0_sectors
+ 4;
113 bank
->num_sectors
= num_sectors
;
114 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
115 str9x_info
->sector_bits
= malloc(sizeof(u32
) * num_sectors
);
119 for (i
= 0; i
< b0_sectors
; i
++)
121 bank
->sectors
[num_sectors
].offset
= mem_layout_str9
[i
].sector_start
;
122 bank
->sectors
[num_sectors
].size
= mem_layout_str9
[i
].sector_size
;
123 bank
->sectors
[num_sectors
].is_erased
= -1;
124 bank
->sectors
[num_sectors
].is_protected
= 1;
125 str9x_info
->sector_bits
[num_sectors
++] = mem_layout_str9
[i
].sector_bit
;
128 for (i
= 8; i
< 12; i
++)
130 bank
->sectors
[num_sectors
].offset
= mem_layout_str9
[i
].sector_start
;
131 bank
->sectors
[num_sectors
].size
= mem_layout_str9
[i
].sector_size
;
132 bank
->sectors
[num_sectors
].is_erased
= -1;
133 bank
->sectors
[num_sectors
].is_protected
= 1;
134 str9x_info
->sector_bits
[num_sectors
++] = mem_layout_str9
[i
].sector_bit
;
140 /* flash bank str9x <base> <size> 0 0 <target#>
142 int str9x_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
144 str9x_flash_bank_t
*str9x_info
;
148 WARNING("incomplete flash_bank str9x configuration");
149 return ERROR_FLASH_BANK_INVALID
;
152 str9x_info
= malloc(sizeof(str9x_flash_bank_t
));
153 bank
->driver_priv
= str9x_info
;
155 if (bank
->base
!= 0x00000000)
157 WARNING("overriding flash base address for STR91x device with 0x00000000");
158 bank
->base
= 0x00000000;
161 str9x_build_block_list(bank
);
163 str9x_info
->write_algorithm
= NULL
;
168 int str9x_blank_check(struct flash_bank_s
*bank
, int first
, int last
)
170 target_t
*target
= bank
->target
;
175 if ((first
< 0) || (last
> bank
->num_sectors
))
176 return ERROR_FLASH_SECTOR_INVALID
;
178 if (bank
->target
->state
!= TARGET_HALTED
)
180 return ERROR_TARGET_NOT_HALTED
;
183 buffer
= malloc(256);
185 for (i
= first
; i
<= last
; i
++)
187 bank
->sectors
[i
].is_erased
= 1;
189 target
->type
->read_memory(target
, bank
->base
+ bank
->sectors
[i
].offset
, 4, 256/4, buffer
);
191 for (nBytes
= 0; nBytes
< 256; nBytes
++)
193 if (buffer
[nBytes
] != 0xFF)
195 bank
->sectors
[i
].is_erased
= 0;
206 int str9x_protect_check(struct flash_bank_s
*bank
)
208 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
209 target_t
*target
= bank
->target
;
215 if (bank
->target
->state
!= TARGET_HALTED
)
217 return ERROR_TARGET_NOT_HALTED
;
220 /* read level one protection */
222 adr
= mem_layout_str9
[10].sector_start
+ 4;
224 target_write_u32(target
, adr
, 0x90);
225 target_read_u16(target
, adr
, &status
);
226 target_write_u32(target
, adr
, 0xFF);
228 for (i
= 0; i
< bank
->num_sectors
; i
++)
230 if (status
& str9x_info
->sector_bits
[i
])
231 bank
->sectors
[i
].is_protected
= 1;
233 bank
->sectors
[i
].is_protected
= 0;
239 int str9x_erase(struct flash_bank_s
*bank
, int first
, int last
)
241 target_t
*target
= bank
->target
;
246 if (bank
->target
->state
!= TARGET_HALTED
)
248 return ERROR_TARGET_NOT_HALTED
;
251 for (i
= first
; i
<= last
; i
++)
253 adr
= bank
->sectors
[i
].offset
;
256 target_write_u16(target
, adr
, 0x20);
257 target_write_u16(target
, adr
, 0xD0);
260 target_write_u16(target
, adr
, 0x70);
263 target_read_u8(target
, adr
, &status
);
269 /* clear status, also clear read array */
270 target_write_u16(target
, adr
, 0x50);
272 /* read array command */
273 target_write_u16(target
, adr
, 0xFF);
277 ERROR("error erasing flash bank, status: 0x%x", status
);
278 return ERROR_FLASH_OPERATION_FAILED
;
282 for (i
= first
; i
<= last
; i
++)
283 bank
->sectors
[i
].is_erased
= 1;
288 int str9x_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
290 target_t
*target
= bank
->target
;
295 if (bank
->target
->state
!= TARGET_HALTED
)
297 return ERROR_TARGET_NOT_HALTED
;
300 for (i
= first
; i
<= last
; i
++)
302 /* Level One Protection */
304 adr
= bank
->sectors
[i
].offset
;
306 target_write_u16(target
, adr
, 0x60);
308 target_write_u16(target
, adr
, 0x01);
310 target_write_u16(target
, adr
, 0xD0);
313 target_read_u8(target
, adr
, &status
);
319 int str9x_write_block(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
321 str9x_flash_bank_t
*str9x_info
= bank
->driver_priv
;
322 target_t
*target
= bank
->target
;
323 u32 buffer_size
= 8192;
324 working_area_t
*source
;
325 u32 address
= bank
->base
+ offset
;
326 reg_param_t reg_params
[4];
327 armv4_5_algorithm_t armv4_5_info
;
330 u32 str9x_flash_write_code
[] = {
332 0xe3c14003, /* bic r4, r1, #3 */
333 0xe3a03040, /* mov r3, #0x40 */
334 0xe1c430b0, /* strh r3, [r4, #0] */
335 0xe0d030b2, /* ldrh r3, [r0], #2 */
336 0xe0c130b2, /* strh r3, [r1], #2 */
337 0xe3a03070, /* mov r3, #0x70 */
338 0xe1c430b0, /* strh r3, [r4, #0] */
340 0xe5d43000, /* ldrb r3, [r4, #0] */
341 0xe3130080, /* tst r3, #0x80 */
342 0x0afffffc, /* beq busy */
343 0xe3a05050, /* mov r5, #0x50 */
344 0xe1c450b0, /* strh r5, [r4, #0] */
345 0xe3a050ff, /* mov r5, #0xFF */
346 0xe1c450b0, /* strh r5, [r4, #0] */
347 0xe3130012, /* tst r3, #0x12 */
348 0x1a000001, /* bne exit */
349 0xe2522001, /* subs r2, r2, #1 */
350 0x1affffed, /* bne write */
352 0xeafffffe, /* b exit */
355 /* flash write code */
356 if (target_alloc_working_area(target
, 4 * 19, &str9x_info
->write_algorithm
) != ERROR_OK
)
358 WARNING("no working area available, can't do block memory writes");
359 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
362 target_write_buffer(target
, str9x_info
->write_algorithm
->address
, 19 * 4, (u8
*)str9x_flash_write_code
);
365 while (target_alloc_working_area(target
, buffer_size
, &source
) != ERROR_OK
)
368 if (buffer_size
<= 256)
370 /* if we already allocated the writing code, but failed to get a buffer, free the algorithm */
371 if (str9x_info
->write_algorithm
)
372 target_free_working_area(target
, str9x_info
->write_algorithm
);
374 WARNING("no large enough working area available, can't do block memory writes");
375 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
379 armv4_5_info
.common_magic
= ARMV4_5_COMMON_MAGIC
;
380 armv4_5_info
.core_mode
= ARMV4_5_MODE_SVC
;
381 armv4_5_info
.core_state
= ARMV4_5_STATE_ARM
;
383 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
);
384 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
);
385 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
);
386 init_reg_param(®_params
[3], "r3", 32, PARAM_IN
);
390 u32 thisrun_count
= (count
> (buffer_size
/ 2)) ? (buffer_size
/ 2) : count
;
392 target_write_buffer(target
, source
->address
, thisrun_count
* 2, buffer
);
394 buf_set_u32(reg_params
[0].value
, 0, 32, source
->address
);
395 buf_set_u32(reg_params
[1].value
, 0, 32, address
);
396 buf_set_u32(reg_params
[2].value
, 0, 32, thisrun_count
);
398 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
)
400 target_free_working_area(target
, source
);
401 target_free_working_area(target
, str9x_info
->write_algorithm
);
402 ERROR("error executing str9x flash write algorithm");
403 return ERROR_FLASH_OPERATION_FAILED
;
406 if (buf_get_u32(reg_params
[3].value
, 0, 32) != 0x80)
408 return ERROR_FLASH_OPERATION_FAILED
;
411 buffer
+= thisrun_count
* 2;
412 address
+= thisrun_count
* 2;
413 count
-= thisrun_count
;
416 target_free_working_area(target
, source
);
417 target_free_working_area(target
, str9x_info
->write_algorithm
);
419 destroy_reg_param(®_params
[0]);
420 destroy_reg_param(®_params
[1]);
421 destroy_reg_param(®_params
[2]);
422 destroy_reg_param(®_params
[3]);
427 int str9x_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
429 target_t
*target
= bank
->target
;
430 u32 words_remaining
= (count
/ 2);
431 u32 bytes_remaining
= (count
& 0x00000001);
432 u32 address
= bank
->base
+ offset
;
433 u32 bytes_written
= 0;
436 u32 check_address
= offset
;
440 if (bank
->target
->state
!= TARGET_HALTED
)
442 return ERROR_TARGET_NOT_HALTED
;
447 WARNING("offset 0x%x breaks required 2-byte alignment", offset
);
448 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
451 for (i
= 0; i
< bank
->num_sectors
; i
++)
453 u32 sec_start
= bank
->sectors
[i
].offset
;
454 u32 sec_end
= sec_start
+ bank
->sectors
[i
].size
;
456 /* check if destination falls within the current sector */
457 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
459 /* check if destination ends in the current sector */
460 if (offset
+ count
< sec_end
)
461 check_address
= offset
+ count
;
463 check_address
= sec_end
;
467 if (check_address
!= offset
+ count
)
468 return ERROR_FLASH_DST_OUT_OF_BANK
;
470 /* multiple half words (2-byte) to be programmed? */
471 if (words_remaining
> 0)
473 /* try using a block write */
474 if ((retval
= str9x_write_block(bank
, buffer
, offset
, words_remaining
)) != ERROR_OK
)
476 if (retval
== ERROR_TARGET_RESOURCE_NOT_AVAILABLE
)
478 /* if block write failed (no sufficient working area),
479 * we use normal (slow) single dword accesses */
480 WARNING("couldn't use block writes, falling back to single memory accesses");
482 else if (retval
== ERROR_FLASH_OPERATION_FAILED
)
484 ERROR("flash writing failed with error code: 0x%x", retval
);
485 return ERROR_FLASH_OPERATION_FAILED
;
490 buffer
+= words_remaining
* 2;
491 address
+= words_remaining
* 2;
496 while (words_remaining
> 0)
498 bank_adr
= address
& ~0x03;
500 /* write data command */
501 target_write_u16(target
, bank_adr
, 0x40);
502 target
->type
->write_memory(target
, address
, 2, 1, buffer
+ bytes_written
);
504 /* get status command */
505 target_write_u16(target
, bank_adr
, 0x70);
508 target_read_u8(target
, bank_adr
, &status
);
514 /* clear status reg and read array */
515 target_write_u16(target
, bank_adr
, 0x50);
516 target_write_u16(target
, bank_adr
, 0xFF);
519 return ERROR_FLASH_OPERATION_FAILED
;
520 else if (status
& 0x02)
521 return ERROR_FLASH_OPERATION_FAILED
;
530 u8 last_halfword
[2] = {0xff, 0xff};
533 while(bytes_remaining
> 0)
535 last_halfword
[i
++] = *(buffer
+ bytes_written
);
540 bank_adr
= address
& ~0x03;
542 /* write data comamnd */
543 target_write_u16(target
, bank_adr
, 0x40);
544 target
->type
->write_memory(target
, address
, 2, 1, last_halfword
);
546 /* query status command */
547 target_write_u16(target
, bank_adr
, 0x70);
550 target_read_u8(target
, bank_adr
, &status
);
556 /* clear status reg and read array */
557 target_write_u16(target
, bank_adr
, 0x50);
558 target_write_u16(target
, bank_adr
, 0xFF);
561 return ERROR_FLASH_OPERATION_FAILED
;
562 else if (status
& 0x02)
563 return ERROR_FLASH_OPERATION_FAILED
;
569 int str9x_probe(struct flash_bank_s
*bank
)
574 int str9x_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
579 int str9x_erase_check(struct flash_bank_s
*bank
)
581 return str9x_blank_check(bank
, 0, bank
->num_sectors
- 1);
584 int str9x_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
586 snprintf(buf
, buf_size
, "str9x flash driver info" );
590 int str9x_handle_flash_config_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
592 str9x_flash_bank_t
*str9x_info
;
594 target_t
*target
= NULL
;
598 command_print(cmd_ctx
, "usage: str9x flash_config <b0size> <b1size> <b0start> <b1start>");
602 bank
= get_flash_bank_by_num(0);
603 str9x_info
= bank
->driver_priv
;
604 target
= bank
->target
;
606 if (bank
->target
->state
!= TARGET_HALTED
)
608 return ERROR_TARGET_NOT_HALTED
;
611 /* config flash controller */
612 target_write_u32(target
, FLASH_BBSR
, strtoul(args
[0], NULL
, 0));
613 target_write_u32(target
, FLASH_NBBSR
, strtoul(args
[1], NULL
, 0));
614 target_write_u32(target
, FLASH_BBADR
, (strtoul(args
[2], NULL
, 0) >> 2));
615 target_write_u32(target
, FLASH_NBBADR
, (strtoul(args
[3], NULL
, 0) >> 2));
617 /* set b18 instruction TCM order as per flash programming manual */
618 arm966e_write_cp15(target
, 62, 0x40000);
620 /* enable flash bank 1 */
621 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)