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 /* REVISIT verify that the jtag position of flash controller is
322 * right after *THIS* core, which must be a STR9xx 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
= bank
->target
->tap
;
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
)
799 uint8_t *buffer
= NULL
;
802 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
805 return ERROR_COMMAND_SYNTAX_ERROR
;
808 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
809 if (ERROR_OK
!= retval
)
812 str9xpec_info
= bank
->driver_priv
;
813 tap
= str9xpec_info
->tap
;
815 buffer
= calloc(CEIL(32, 8), 1);
817 str9xpec_set_instr(tap
, ISC_IDCODE
, TAP_IRPAUSE
);
821 field
.out_value
= NULL
;
822 field
.in_value
= buffer
;
824 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
825 jtag_execute_queue();
827 idcode
= buf_get_u32(buffer
, 0, 32);
829 command_print(cmd_ctx
, "str9xpec part id: 0x%8.8" PRIx32
"", idcode
);
836 static int str9xpec_erase_check(struct flash_bank_s
*bank
)
838 return str9xpec_blank_check(bank
, 0, bank
->num_sectors
- 1);
841 static int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
843 snprintf(buf
, buf_size
, "str9xpec flash driver info");
847 static int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
850 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
854 command_print(cmd_ctx
, "str9xpec options_read <bank>");
859 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
860 if (ERROR_OK
!= retval
)
863 str9xpec_info
= bank
->driver_priv
;
865 status
= str9xpec_read_config(bank
);
867 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
868 return ERROR_FLASH_OPERATION_FAILED
;
871 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1))
872 command_print(cmd_ctx
, "CS Map: bank1");
874 command_print(cmd_ctx
, "CS Map: bank0");
877 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_OTPBIT
, 1))
878 command_print(cmd_ctx
, "OTP Lock: OTP Locked");
880 command_print(cmd_ctx
, "OTP Lock: OTP Unlocked");
883 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1))
884 command_print(cmd_ctx
, "LVD Threshold: 2.7v");
886 command_print(cmd_ctx
, "LVD Threshold: 2.4v");
888 /* LVD reset warning */
889 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1))
890 command_print(cmd_ctx
, "LVD Reset Warning: VDD or VDDQ Inputs");
892 command_print(cmd_ctx
, "LVD Reset Warning: VDD Input Only");
894 /* LVD reset select */
895 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1))
896 command_print(cmd_ctx
, "LVD Reset Selection: VDD or VDDQ Inputs");
898 command_print(cmd_ctx
, "LVD Reset Selection: VDD Input Only");
903 static int str9xpec_write_options(struct flash_bank_s
*bank
)
908 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
910 str9xpec_info
= bank
->driver_priv
;
911 tap
= str9xpec_info
->tap
;
913 /* erase config options first */
914 status
= str9xpec_erase_area(bank
, 0xFE, 0xFE);
916 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
919 if (!str9xpec_info
->isc_enable
) {
920 str9xpec_isc_enable(bank
);
923 if (!str9xpec_info
->isc_enable
) {
924 return ISC_STATUS_ERROR
;
927 /* according to data 64th bit has to be set */
928 buf_set_u32(str9xpec_info
->options
, 63, 1, 1);
930 /* set option byte address */
931 str9xpec_set_address(bank
, 0x50);
933 /* execute ISC_PROGRAM command */
934 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
938 field
.out_value
= str9xpec_info
->options
;
939 field
.in_value
= NULL
;
941 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
943 /* small delay before polling */
946 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
951 field
.out_value
= NULL
;
952 field
.in_value
= &status
;
954 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
955 jtag_execute_queue();
957 } while (!(status
& ISC_STATUS_BUSY
));
959 str9xpec_isc_disable(bank
);
964 static int str9xpec_handle_flash_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
970 command_print(cmd_ctx
, "str9xpec options_write <bank>");
975 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
976 if (ERROR_OK
!= retval
)
979 status
= str9xpec_write_options(bank
);
981 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
982 return ERROR_FLASH_OPERATION_FAILED
;
987 static int str9xpec_handle_flash_options_cmap_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
989 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
993 command_print(cmd_ctx
, "str9xpec options_cmap <bank> <bank0 | bank1>");
998 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
999 if (ERROR_OK
!= retval
)
1002 str9xpec_info
= bank
->driver_priv
;
1004 if (strcmp(args
[1], "bank1") == 0)
1006 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 1);
1010 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 0);
1016 static int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1018 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1022 command_print(cmd_ctx
, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
1027 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1028 if (ERROR_OK
!= retval
)
1031 str9xpec_info
= bank
->driver_priv
;
1033 if (strcmp(args
[1], "2.7v") == 0)
1035 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 1);
1039 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 0);
1045 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1047 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1051 command_print(cmd_ctx
, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
1056 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1057 if (ERROR_OK
!= retval
)
1060 str9xpec_info
= bank
->driver_priv
;
1062 if (strcmp(args
[1], "vdd_vddq") == 0)
1064 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 1);
1068 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 0);
1074 static int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1076 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1080 command_print(cmd_ctx
, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
1085 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1086 if (ERROR_OK
!= retval
)
1089 str9xpec_info
= bank
->driver_priv
;
1091 if (strcmp(args
[1], "vdd_vddq") == 0)
1093 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 1);
1097 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 0);
1103 static int str9xpec_handle_flash_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1109 command_print(cmd_ctx
, "str9xpec lock <bank>");
1114 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1115 if (ERROR_OK
!= retval
)
1118 status
= str9xpec_lock_device(bank
);
1120 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1121 return ERROR_FLASH_OPERATION_FAILED
;
1126 static int str9xpec_handle_flash_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1132 command_print(cmd_ctx
, "str9xpec unlock <bank>");
1137 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1138 if (ERROR_OK
!= retval
)
1141 status
= str9xpec_unlock_device(bank
);
1143 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1144 return ERROR_FLASH_OPERATION_FAILED
;
1149 static int str9xpec_handle_flash_enable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1154 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1158 command_print(cmd_ctx
, "str9xpec enable_turbo <bank>");
1163 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1164 if (ERROR_OK
!= retval
)
1167 str9xpec_info
= bank
->driver_priv
;
1169 tap0
= str9xpec_info
->tap
;
1171 /* remove arm core from chain - enter turbo mode */
1172 tap1
= tap0
->next_tap
;
1175 /* things are *WRONG* */
1176 command_print(cmd_ctx
,"**STR9FLASH** (tap1) invalid chain?");
1179 tap2
= tap1
->next_tap
;
1182 /* things are *WRONG* */
1183 command_print(cmd_ctx
,"**STR9FLASH** (tap2) invalid chain?");
1187 /* enable turbo mode - TURBO-PROG-ENABLE */
1188 str9xpec_set_instr(tap2
, 0xD, TAP_IDLE
);
1189 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1192 /* modify scan chain - str9 core has been removed */
1198 static int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1201 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1205 command_print(cmd_ctx
, "str9xpec disable_turbo <bank>");
1210 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1211 if (ERROR_OK
!= retval
)
1214 str9xpec_info
= bank
->driver_priv
;
1215 tap
= str9xpec_info
->tap
;
1220 /* exit turbo mode via RESET */
1221 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IDLE
);
1223 jtag_execute_queue();
1225 /* restore previous scan chain */
1226 if (tap
->next_tap
) {
1227 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)