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 * This program is free software; you can redistribute it and/or modify *
9 * it under the terms of the GNU General Public License as published by *
10 * the Free Software Foundation; either version 2 of the License, or *
11 * (at your option) any later version. *
13 * This program is distributed in the hope that it will be useful, *
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16 * GNU General Public License for more details. *
18 * You should have received a copy of the GNU General Public License *
19 * along with this program; if not, write to the *
20 * Free Software Foundation, Inc., *
21 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
28 #include "arm7_9_common.h"
31 static int str9xpec_register_commands(struct command_context_s
*cmd_ctx
);
32 static int str9xpec_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
33 static int str9xpec_erase(struct flash_bank_s
*bank
, int first
, int last
);
34 static int str9xpec_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
35 static int str9xpec_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
);
36 static int str9xpec_probe(struct flash_bank_s
*bank
);
37 static int str9xpec_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
38 static int str9xpec_protect_check(struct flash_bank_s
*bank
);
39 static int str9xpec_erase_check(struct flash_bank_s
*bank
);
40 static int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
42 static int str9xpec_erase_area(struct flash_bank_s
*bank
, int first
, int last
);
43 static int str9xpec_set_address(struct flash_bank_s
*bank
, uint8_t sector
);
44 static int str9xpec_write_options(struct flash_bank_s
*bank
);
46 static int str9xpec_handle_flash_options_cmap_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
47 static int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
48 static int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
49 static int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
50 static int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
51 static int str9xpec_handle_flash_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
52 static int str9xpec_handle_flash_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
53 static int str9xpec_handle_flash_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
54 static int str9xpec_handle_flash_enable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
55 static int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
57 flash_driver_t str9xpec_flash
=
60 .register_commands
= str9xpec_register_commands
,
61 .flash_bank_command
= str9xpec_flash_bank_command
,
62 .erase
= str9xpec_erase
,
63 .protect
= str9xpec_protect
,
64 .write
= str9xpec_write
,
65 .probe
= str9xpec_probe
,
66 .auto_probe
= str9xpec_probe
,
67 .erase_check
= str9xpec_erase_check
,
68 .protect_check
= str9xpec_protect_check
,
72 static int str9xpec_register_commands(struct command_context_s
*cmd_ctx
)
74 command_t
*str9xpec_cmd
= register_command(cmd_ctx
, NULL
, "str9xpec", NULL
, COMMAND_ANY
, "str9xpec flash specific commands");
76 register_command(cmd_ctx
, str9xpec_cmd
, "enable_turbo", str9xpec_handle_flash_enable_turbo_command
, COMMAND_EXEC
,
77 "enable str9xpec turbo mode");
78 register_command(cmd_ctx
, str9xpec_cmd
, "disable_turbo", str9xpec_handle_flash_disable_turbo_command
, COMMAND_EXEC
,
79 "disable str9xpec turbo mode");
80 register_command(cmd_ctx
, str9xpec_cmd
, "options_cmap", str9xpec_handle_flash_options_cmap_command
, COMMAND_EXEC
,
81 "configure str9xpec boot sector");
82 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdthd", str9xpec_handle_flash_options_lvdthd_command
, COMMAND_EXEC
,
83 "configure str9xpec lvd threshold");
84 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdsel", str9xpec_handle_flash_options_lvdsel_command
, COMMAND_EXEC
,
85 "configure str9xpec lvd selection");
86 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdwarn", str9xpec_handle_flash_options_lvdwarn_command
, COMMAND_EXEC
,
87 "configure str9xpec lvd warning");
88 register_command(cmd_ctx
, str9xpec_cmd
, "options_read", str9xpec_handle_flash_options_read_command
, COMMAND_EXEC
,
89 "read str9xpec options");
90 register_command(cmd_ctx
, str9xpec_cmd
, "options_write", str9xpec_handle_flash_options_write_command
, COMMAND_EXEC
,
91 "write str9xpec options");
92 register_command(cmd_ctx
, str9xpec_cmd
, "lock", str9xpec_handle_flash_lock_command
, COMMAND_EXEC
,
93 "lock str9xpec device");
94 register_command(cmd_ctx
, str9xpec_cmd
, "unlock", str9xpec_handle_flash_unlock_command
, COMMAND_EXEC
,
95 "unlock str9xpec device");
96 register_command(cmd_ctx
, str9xpec_cmd
, "part_id", str9xpec_handle_part_id_command
, COMMAND_EXEC
,
97 "print part id of str9xpec flash bank <num>");
102 int str9xpec_set_instr(jtag_tap_t
*tap
, uint32_t new_instr
, tap_state_t end_state
)
105 return ERROR_TARGET_INVALID
;
108 if (buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
) != new_instr
)
113 field
.num_bits
= tap
->ir_length
;
114 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
115 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
116 field
.in_value
= NULL
;
118 jtag_add_ir_scan(1, &field
, end_state
);
120 free(field
.out_value
);
126 static uint8_t str9xpec_isc_status(jtag_tap_t
*tap
)
131 if (str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
) != ERROR_OK
)
132 return ISC_STATUS_ERROR
;
136 field
.out_value
= NULL
;
137 field
.in_value
= &status
;
140 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
141 jtag_execute_queue();
143 LOG_DEBUG("status: 0x%2.2x", status
);
145 if (status
& ISC_STATUS_SECURITY
)
146 LOG_INFO("Device Security Bit Set");
151 static int str9xpec_isc_enable(struct flash_bank_s
*bank
)
155 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
157 tap
= str9xpec_info
->tap
;
159 if (str9xpec_info
->isc_enable
)
163 if (str9xpec_set_instr(tap
, ISC_ENABLE
, TAP_IDLE
) != ERROR_OK
)
164 return ERROR_TARGET_INVALID
;
166 /* check ISC status */
167 status
= str9xpec_isc_status(tap
);
168 if (status
& ISC_STATUS_MODE
)
170 /* we have entered isc mode */
171 str9xpec_info
->isc_enable
= 1;
172 LOG_DEBUG("ISC_MODE Enabled");
178 static int str9xpec_isc_disable(struct flash_bank_s
*bank
)
182 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
184 tap
= str9xpec_info
->tap
;
186 if (!str9xpec_info
->isc_enable
)
189 if (str9xpec_set_instr(tap
, ISC_DISABLE
, TAP_IDLE
) != ERROR_OK
)
190 return ERROR_TARGET_INVALID
;
192 /* delay to handle aborts */
195 /* check ISC status */
196 status
= str9xpec_isc_status(tap
);
197 if (!(status
& ISC_STATUS_MODE
))
199 /* we have left isc mode */
200 str9xpec_info
->isc_enable
= 0;
201 LOG_DEBUG("ISC_MODE Disabled");
207 static int str9xpec_read_config(struct flash_bank_s
*bank
)
213 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
215 tap
= str9xpec_info
->tap
;
217 LOG_DEBUG("ISC_CONFIGURATION");
219 /* execute ISC_CONFIGURATION command */
220 str9xpec_set_instr(tap
, ISC_CONFIGURATION
, TAP_IRPAUSE
);
224 field
.out_value
= NULL
;
225 field
.in_value
= str9xpec_info
->options
;
228 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
229 jtag_execute_queue();
231 status
= str9xpec_isc_status(tap
);
236 static int str9xpec_build_block_list(struct flash_bank_s
*bank
)
238 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
242 int b0_sectors
= 0, b1_sectors
= 0;
244 int b1_size
= 0x2000;
268 LOG_ERROR("BUG: unknown bank->size encountered");
272 num_sectors
= b0_sectors
+ b1_sectors
;
274 bank
->num_sectors
= num_sectors
;
275 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
276 str9xpec_info
->sector_bits
= malloc(sizeof(uint32_t) * num_sectors
);
280 for (i
= 0; i
< b0_sectors
; i
++)
282 bank
->sectors
[num_sectors
].offset
= offset
;
283 bank
->sectors
[num_sectors
].size
= 0x10000;
284 offset
+= bank
->sectors
[i
].size
;
285 bank
->sectors
[num_sectors
].is_erased
= -1;
286 bank
->sectors
[num_sectors
].is_protected
= 1;
287 str9xpec_info
->sector_bits
[num_sectors
++] = i
;
290 for (i
= 0; i
< b1_sectors
; i
++)
292 bank
->sectors
[num_sectors
].offset
= offset
;
293 bank
->sectors
[num_sectors
].size
= b1_size
;
294 offset
+= bank
->sectors
[i
].size
;
295 bank
->sectors
[num_sectors
].is_erased
= -1;
296 bank
->sectors
[num_sectors
].is_protected
= 1;
297 str9xpec_info
->sector_bits
[num_sectors
++] = i
+ 32;
303 /* flash bank str9x <base> <size> 0 0 <target#>
305 static int str9xpec_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
307 str9xpec_flash_controller_t
*str9xpec_info
;
308 armv4_5_common_t
*armv4_5
= NULL
;
309 arm7_9_common_t
*arm7_9
= NULL
;
310 arm_jtag_t
*jtag_info
= NULL
;
314 LOG_WARNING("incomplete flash_bank str9x configuration");
315 return ERROR_FLASH_BANK_INVALID
;
318 str9xpec_info
= malloc(sizeof(str9xpec_flash_controller_t
));
319 bank
->driver_priv
= str9xpec_info
;
321 /* find out jtag position of flash controller
322 * it is always after the arm966 core */
324 armv4_5
= bank
->target
->arch_info
;
325 arm7_9
= armv4_5
->arch_info
;
326 jtag_info
= &arm7_9
->jtag_info
;
328 str9xpec_info
->tap
= jtag_tap_by_position( jtag_info
->tap
->abs_chain_position
- 1);
329 str9xpec_info
->isc_enable
= 0;
331 str9xpec_build_block_list(bank
);
333 /* clear option byte register */
334 buf_set_u32(str9xpec_info
->options
, 0, 64, 0);
339 static int str9xpec_blank_check(struct flash_bank_s
*bank
, int first
, int last
)
345 uint8_t *buffer
= NULL
;
347 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
349 tap
= str9xpec_info
->tap
;
351 if (!str9xpec_info
->isc_enable
) {
352 str9xpec_isc_enable( bank
);
355 if (!str9xpec_info
->isc_enable
) {
356 return ERROR_FLASH_OPERATION_FAILED
;
359 buffer
= calloc(CEIL(64, 8), 1);
361 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first
, last
);
363 for (i
= first
; i
<= last
; i
++) {
364 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
367 /* execute ISC_BLANK_CHECK command */
368 str9xpec_set_instr(tap
, ISC_BLANK_CHECK
, TAP_IRPAUSE
);
372 field
.out_value
= buffer
;
373 field
.in_value
= NULL
;
375 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
376 jtag_add_sleep(40000);
378 /* read blank check result */
381 field
.out_value
= NULL
;
382 field
.in_value
= buffer
;
384 jtag_add_dr_scan(1, &field
, TAP_IRPAUSE
);
385 jtag_execute_queue();
387 status
= str9xpec_isc_status(tap
);
389 for (i
= first
; i
<= last
; i
++)
391 if (buf_get_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1))
392 bank
->sectors
[i
].is_erased
= 0;
394 bank
->sectors
[i
].is_erased
= 1;
399 str9xpec_isc_disable(bank
);
401 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
402 return ERROR_FLASH_OPERATION_FAILED
;
406 static int str9xpec_protect_check(struct flash_bank_s
*bank
)
411 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
413 status
= str9xpec_read_config(bank
);
415 for (i
= 0; i
< bank
->num_sectors
; i
++)
417 if (buf_get_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1))
418 bank
->sectors
[i
].is_protected
= 1;
420 bank
->sectors
[i
].is_protected
= 0;
423 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
424 return ERROR_FLASH_OPERATION_FAILED
;
428 static int str9xpec_erase_area(struct flash_bank_s
*bank
, int first
, int last
)
434 uint8_t *buffer
= NULL
;
436 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
438 tap
= str9xpec_info
->tap
;
440 if (!str9xpec_info
->isc_enable
) {
441 str9xpec_isc_enable( bank
);
444 if (!str9xpec_info
->isc_enable
) {
445 return ISC_STATUS_ERROR
;
448 buffer
= calloc(CEIL(64, 8), 1);
450 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first
, last
);
452 /* last bank: 0xFF signals a full erase (unlock complete device) */
453 /* last bank: 0xFE signals a option byte erase */
456 for (i
= 0; i
< 64; i
++) {
457 buf_set_u32(buffer
, i
, 1, 1);
460 else if (last
== 0xFE)
462 buf_set_u32(buffer
, 49, 1, 1);
466 for (i
= first
; i
<= last
; i
++) {
467 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
471 LOG_DEBUG("ISC_ERASE");
473 /* execute ISC_ERASE command */
474 str9xpec_set_instr(tap
, ISC_ERASE
, TAP_IRPAUSE
);
478 field
.out_value
= buffer
;
479 field
.in_value
= NULL
;
481 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
482 jtag_execute_queue();
486 /* wait for erase completion */
487 while (!((status
= str9xpec_isc_status(tap
)) & ISC_STATUS_BUSY
)) {
493 str9xpec_isc_disable(bank
);
498 static int str9xpec_erase(struct flash_bank_s
*bank
, int first
, int last
)
502 status
= str9xpec_erase_area(bank
, first
, last
);
504 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
505 return ERROR_FLASH_OPERATION_FAILED
;
510 static int str9xpec_lock_device(struct flash_bank_s
*bank
)
515 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
517 str9xpec_info
= bank
->driver_priv
;
518 tap
= str9xpec_info
->tap
;
520 if (!str9xpec_info
->isc_enable
) {
521 str9xpec_isc_enable( bank
);
524 if (!str9xpec_info
->isc_enable
) {
525 return ISC_STATUS_ERROR
;
528 /* set security address */
529 str9xpec_set_address(bank
, 0x80);
531 /* execute ISC_PROGRAM command */
532 str9xpec_set_instr(tap
, ISC_PROGRAM_SECURITY
, TAP_IDLE
);
534 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
539 field
.out_value
= NULL
;
540 field
.in_value
= &status
;
542 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
543 jtag_execute_queue();
545 } while(!(status
& ISC_STATUS_BUSY
));
547 str9xpec_isc_disable(bank
);
552 static int str9xpec_unlock_device(struct flash_bank_s
*bank
)
556 status
= str9xpec_erase_area(bank
, 0, 255);
561 static int str9xpec_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
566 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
568 status
= str9xpec_read_config(bank
);
570 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
571 return ERROR_FLASH_OPERATION_FAILED
;
573 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first
, last
);
575 /* last bank: 0xFF signals a full device protect */
580 status
= str9xpec_lock_device(bank
);
584 /* perform full erase to unlock device */
585 status
= str9xpec_unlock_device(bank
);
590 for (i
= first
; i
<= last
; i
++)
593 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 1);
595 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 0);
598 status
= str9xpec_write_options(bank
);
601 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
602 return ERROR_FLASH_OPERATION_FAILED
;
607 static int str9xpec_set_address(struct flash_bank_s
*bank
, uint8_t sector
)
611 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
613 tap
= str9xpec_info
->tap
;
615 /* set flash controller address */
616 str9xpec_set_instr(tap
, ISC_ADDRESS_SHIFT
, TAP_IRPAUSE
);
620 field
.out_value
= §or
;
621 field
.in_value
= NULL
;
623 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
628 static int str9xpec_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
630 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
631 uint32_t dwords_remaining
= (count
/ 8);
632 uint32_t bytes_remaining
= (count
& 0x00000007);
633 uint32_t bytes_written
= 0;
635 uint32_t check_address
= offset
;
640 int first_sector
= 0;
643 tap
= str9xpec_info
->tap
;
645 if (!str9xpec_info
->isc_enable
) {
646 str9xpec_isc_enable(bank
);
649 if (!str9xpec_info
->isc_enable
) {
650 return ERROR_FLASH_OPERATION_FAILED
;
655 LOG_WARNING("offset 0x%" PRIx32
" breaks required 8-byte alignment", offset
);
656 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
659 for (i
= 0; i
< bank
->num_sectors
; i
++)
661 uint32_t sec_start
= bank
->sectors
[i
].offset
;
662 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
664 /* check if destination falls within the current sector */
665 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
667 /* check if destination ends in the current sector */
668 if (offset
+ count
< sec_end
)
669 check_address
= offset
+ count
;
671 check_address
= sec_end
;
674 if ((offset
>= sec_start
) && (offset
< sec_end
)){
678 if ((offset
+ count
>= sec_start
) && (offset
+ count
< sec_end
)){
683 if (check_address
!= offset
+ count
)
684 return ERROR_FLASH_DST_OUT_OF_BANK
;
686 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
688 scanbuf
= calloc(CEIL(64, 8), 1);
690 LOG_DEBUG("ISC_PROGRAM");
692 for (i
= first_sector
; i
<= last_sector
; i
++)
694 str9xpec_set_address(bank
, str9xpec_info
->sector_bits
[i
]);
696 dwords_remaining
= dwords_remaining
< (bank
->sectors
[i
].size
/8) ? dwords_remaining
: (bank
->sectors
[i
].size
/8);
698 while (dwords_remaining
> 0)
700 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
704 field
.out_value
= (buffer
+ bytes_written
);
705 field
.in_value
= NULL
;
707 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
709 /* small delay before polling */
712 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
717 field
.out_value
= NULL
;
718 field
.in_value
= scanbuf
;
720 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
721 jtag_execute_queue();
723 status
= buf_get_u32(scanbuf
, 0, 8);
725 } while(!(status
& ISC_STATUS_BUSY
));
727 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
728 return ERROR_FLASH_OPERATION_FAILED
;
730 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
731 return ERROR_FLASH_OPERATION_FAILED; */
740 uint8_t last_dword
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
743 while(bytes_remaining
> 0)
745 last_dword
[i
++] = *(buffer
+ bytes_written
);
750 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
754 field
.out_value
= last_dword
;
755 field
.in_value
= NULL
;
757 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
759 /* small delay before polling */
762 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
767 field
.out_value
= NULL
;
768 field
.in_value
= scanbuf
;
770 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
771 jtag_execute_queue();
773 status
= buf_get_u32(scanbuf
, 0, 8);
775 } while(!(status
& ISC_STATUS_BUSY
));
777 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
778 return ERROR_FLASH_OPERATION_FAILED
;
780 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
781 return ERROR_FLASH_OPERATION_FAILED; */
786 str9xpec_isc_disable(bank
);
791 static int str9xpec_probe(struct flash_bank_s
*bank
)
796 static int str9xpec_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
800 uint8_t *buffer
= NULL
;
803 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
807 return ERROR_COMMAND_SYNTAX_ERROR
;
810 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
813 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
817 str9xpec_info
= bank
->driver_priv
;
818 tap
= str9xpec_info
->tap
;
820 buffer
= calloc(CEIL(32, 8), 1);
822 str9xpec_set_instr(tap
, ISC_IDCODE
, TAP_IRPAUSE
);
826 field
.out_value
= NULL
;
827 field
.in_value
= buffer
;
829 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
830 jtag_execute_queue();
832 idcode
= buf_get_u32(buffer
, 0, 32);
834 command_print(cmd_ctx
, "str9xpec part id: 0x%8.8" PRIx32
"", idcode
);
841 static int str9xpec_erase_check(struct flash_bank_s
*bank
)
843 return str9xpec_blank_check(bank
, 0, bank
->num_sectors
- 1);
846 static int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
848 snprintf(buf
, buf_size
, "str9xpec flash driver info" );
852 static int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
856 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
860 command_print(cmd_ctx
, "str9xpec options_read <bank>");
864 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
867 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
871 str9xpec_info
= bank
->driver_priv
;
873 status
= str9xpec_read_config(bank
);
875 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
876 return ERROR_FLASH_OPERATION_FAILED
;
879 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1))
880 command_print(cmd_ctx
, "CS Map: bank1");
882 command_print(cmd_ctx
, "CS Map: bank0");
885 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_OTPBIT
, 1))
886 command_print(cmd_ctx
, "OTP Lock: OTP Locked");
888 command_print(cmd_ctx
, "OTP Lock: OTP Unlocked");
891 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1))
892 command_print(cmd_ctx
, "LVD Threshold: 2.7v");
894 command_print(cmd_ctx
, "LVD Threshold: 2.4v");
896 /* LVD reset warning */
897 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1))
898 command_print(cmd_ctx
, "LVD Reset Warning: VDD or VDDQ Inputs");
900 command_print(cmd_ctx
, "LVD Reset Warning: VDD Input Only");
902 /* LVD reset select */
903 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1))
904 command_print(cmd_ctx
, "LVD Reset Selection: VDD or VDDQ Inputs");
906 command_print(cmd_ctx
, "LVD Reset Selection: VDD Input Only");
911 static int str9xpec_write_options(struct flash_bank_s
*bank
)
916 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
918 str9xpec_info
= bank
->driver_priv
;
919 tap
= str9xpec_info
->tap
;
921 /* erase config options first */
922 status
= str9xpec_erase_area( bank
, 0xFE, 0xFE );
924 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
927 if (!str9xpec_info
->isc_enable
) {
928 str9xpec_isc_enable( bank
);
931 if (!str9xpec_info
->isc_enable
) {
932 return ISC_STATUS_ERROR
;
935 /* according to data 64th bit has to be set */
936 buf_set_u32(str9xpec_info
->options
, 63, 1, 1);
938 /* set option byte address */
939 str9xpec_set_address(bank
, 0x50);
941 /* execute ISC_PROGRAM command */
942 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
946 field
.out_value
= str9xpec_info
->options
;
947 field
.in_value
= NULL
;
949 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
951 /* small delay before polling */
954 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
959 field
.out_value
= NULL
;
960 field
.in_value
= &status
;
962 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
963 jtag_execute_queue();
965 } while(!(status
& ISC_STATUS_BUSY
));
967 str9xpec_isc_disable(bank
);
972 static int str9xpec_handle_flash_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
979 command_print(cmd_ctx
, "str9xpec options_write <bank>");
983 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
986 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
990 status
= str9xpec_write_options(bank
);
992 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
993 return ERROR_FLASH_OPERATION_FAILED
;
998 static int str9xpec_handle_flash_options_cmap_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1001 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1005 command_print(cmd_ctx
, "str9xpec options_cmap <bank> <bank0|bank1>");
1009 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1012 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1016 str9xpec_info
= bank
->driver_priv
;
1018 if (strcmp(args
[1], "bank1") == 0)
1020 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 1);
1024 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 0);
1030 static int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1033 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1037 command_print(cmd_ctx
, "str9xpec options_lvdthd <bank> <2.4v|2.7v>");
1041 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1044 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1048 str9xpec_info
= bank
->driver_priv
;
1050 if (strcmp(args
[1], "2.7v") == 0)
1052 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 1);
1056 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 0);
1062 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1065 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1069 command_print(cmd_ctx
, "str9xpec options_lvdsel <bank> <vdd|vdd_vddq>");
1073 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1076 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1080 str9xpec_info
= bank
->driver_priv
;
1082 if (strcmp(args
[1], "vdd_vddq") == 0)
1084 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 1);
1088 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 0);
1094 static int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1097 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1101 command_print(cmd_ctx
, "str9xpec options_lvdwarn <bank> <vdd|vdd_vddq>");
1105 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1108 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1112 str9xpec_info
= bank
->driver_priv
;
1114 if (strcmp(args
[1], "vdd_vddq") == 0)
1116 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 1);
1120 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 0);
1126 static int str9xpec_handle_flash_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1133 command_print(cmd_ctx
, "str9xpec lock <bank>");
1137 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1140 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1144 status
= str9xpec_lock_device(bank
);
1146 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1147 return ERROR_FLASH_OPERATION_FAILED
;
1152 static int str9xpec_handle_flash_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1159 command_print(cmd_ctx
, "str9xpec unlock <bank>");
1163 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1166 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1170 status
= str9xpec_unlock_device(bank
);
1172 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1173 return ERROR_FLASH_OPERATION_FAILED
;
1178 static int str9xpec_handle_flash_enable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1185 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1189 command_print(cmd_ctx
, "str9xpec enable_turbo <bank>");
1193 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1196 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1200 str9xpec_info
= bank
->driver_priv
;
1202 tap0
= str9xpec_info
->tap
;
1204 /* remove arm core from chain - enter turbo mode */
1205 tap1
= tap0
->next_tap
;
1208 /* things are *WRONG* */
1209 command_print(cmd_ctx
,"**STR9FLASH** (tap1) invalid chain?");
1212 tap2
= tap1
->next_tap
;
1215 /* things are *WRONG* */
1216 command_print(cmd_ctx
,"**STR9FLASH** (tap2) invalid chain?");
1220 /* enable turbo mode - TURBO-PROG-ENABLE */
1221 str9xpec_set_instr(tap2
, 0xD, TAP_IDLE
);
1222 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1225 /* modify scan chain - str9 core has been removed */
1231 static int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1235 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1239 command_print(cmd_ctx
, "str9xpec disable_turbo <bank>");
1243 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1246 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1250 str9xpec_info
= bank
->driver_priv
;
1251 tap
= str9xpec_info
->tap
;
1256 /* exit turbo mode via RESET */
1257 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_RESET
);
1258 jtag_execute_queue();
1260 /* restore previous scan chain */
1261 if (tap
->next_tap
) {
1262 tap
->next_tap
->enabled
= 1;
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)