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 ***************************************************************************/
27 #include "replacements.h"
34 #include "arm7_9_common.h"
36 #include "binarybuffer.h"
43 static int str9xpec_register_commands(struct command_context_s
*cmd_ctx
);
44 static int str9xpec_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
45 static int str9xpec_erase(struct flash_bank_s
*bank
, int first
, int last
);
46 static int str9xpec_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
47 static int str9xpec_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
48 static int str9xpec_probe(struct flash_bank_s
*bank
);
49 static int str9xpec_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
50 static int str9xpec_protect_check(struct flash_bank_s
*bank
);
51 static int str9xpec_erase_check(struct flash_bank_s
*bank
);
52 static int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
54 static int str9xpec_erase_area(struct flash_bank_s
*bank
, int first
, int last
);
55 static int str9xpec_set_address(struct flash_bank_s
*bank
, u8 sector
);
56 static int str9xpec_write_options(struct flash_bank_s
*bank
);
58 static int str9xpec_handle_flash_options_cmap_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
59 static int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
60 static int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
61 static int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
62 static int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
63 static int str9xpec_handle_flash_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
64 static int str9xpec_handle_flash_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
65 static int str9xpec_handle_flash_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
66 static int str9xpec_handle_flash_enable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
67 static int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
69 flash_driver_t str9xpec_flash
=
72 .register_commands
= str9xpec_register_commands
,
73 .flash_bank_command
= str9xpec_flash_bank_command
,
74 .erase
= str9xpec_erase
,
75 .protect
= str9xpec_protect
,
76 .write
= str9xpec_write
,
77 .probe
= str9xpec_probe
,
78 .auto_probe
= str9xpec_probe
,
79 .erase_check
= str9xpec_erase_check
,
80 .protect_check
= str9xpec_protect_check
,
84 static int str9xpec_register_commands(struct command_context_s
*cmd_ctx
)
86 command_t
*str9xpec_cmd
= register_command(cmd_ctx
, NULL
, "str9xpec", NULL
, COMMAND_ANY
, "str9xpec flash specific commands");
88 register_command(cmd_ctx
, str9xpec_cmd
, "enable_turbo", str9xpec_handle_flash_enable_turbo_command
, COMMAND_EXEC
,
89 "enable str9xpec turbo mode");
90 register_command(cmd_ctx
, str9xpec_cmd
, "disable_turbo", str9xpec_handle_flash_disable_turbo_command
, COMMAND_EXEC
,
91 "disable str9xpec turbo mode");
92 register_command(cmd_ctx
, str9xpec_cmd
, "options_cmap", str9xpec_handle_flash_options_cmap_command
, COMMAND_EXEC
,
93 "configure str9xpec boot sector");
94 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdthd", str9xpec_handle_flash_options_lvdthd_command
, COMMAND_EXEC
,
95 "configure str9xpec lvd threshold");
96 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdsel", str9xpec_handle_flash_options_lvdsel_command
, COMMAND_EXEC
,
97 "configure str9xpec lvd selection");
98 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdwarn", str9xpec_handle_flash_options_lvdwarn_command
, COMMAND_EXEC
,
99 "configure str9xpec lvd warning");
100 register_command(cmd_ctx
, str9xpec_cmd
, "options_read", str9xpec_handle_flash_options_read_command
, COMMAND_EXEC
,
101 "read str9xpec options");
102 register_command(cmd_ctx
, str9xpec_cmd
, "options_write", str9xpec_handle_flash_options_write_command
, COMMAND_EXEC
,
103 "write str9xpec options");
104 register_command(cmd_ctx
, str9xpec_cmd
, "lock", str9xpec_handle_flash_lock_command
, COMMAND_EXEC
,
105 "lock str9xpec device");
106 register_command(cmd_ctx
, str9xpec_cmd
, "unlock", str9xpec_handle_flash_unlock_command
, COMMAND_EXEC
,
107 "unlock str9xpec device");
108 register_command(cmd_ctx
, str9xpec_cmd
, "part_id", str9xpec_handle_part_id_command
, COMMAND_EXEC
,
109 "print part id of str9xpec flash bank <num>");
114 int str9xpec_set_instr(jtag_tap_t
*tap
, u32 new_instr
, tap_state_t end_state
)
117 return ERROR_TARGET_INVALID
;
120 if (buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
) != new_instr
)
125 field
.num_bits
= tap
->ir_length
;
126 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
127 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
128 field
.out_mask
= NULL
;
129 field
.in_value
= NULL
;
130 field
.in_check_value
= NULL
;
131 field
.in_check_mask
= NULL
;
132 field
.in_handler
= NULL
;
133 field
.in_handler_priv
= NULL
;
135 jtag_add_ir_scan(1, &field
, end_state
);
137 free(field
.out_value
);
143 static u8
str9xpec_isc_status(jtag_tap_t
*tap
)
148 if (str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
) != ERROR_OK
)
149 return ISC_STATUS_ERROR
;
153 field
.out_value
= NULL
;
154 field
.out_mask
= NULL
;
155 field
.in_value
= &status
;
156 field
.in_check_value
= NULL
;
157 field
.in_check_mask
= NULL
;
158 field
.in_handler
= NULL
;
159 field
.in_handler_priv
= NULL
;
161 jtag_add_dr_scan(1, &field
, TAP_IDLE
);
162 jtag_execute_queue();
164 LOG_DEBUG("status: 0x%2.2x", status
);
166 if (status
& ISC_STATUS_SECURITY
)
167 LOG_INFO("Device Security Bit Set");
172 static int str9xpec_isc_enable(struct flash_bank_s
*bank
)
176 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
178 tap
= str9xpec_info
->tap
;
180 if (str9xpec_info
->isc_enable
)
184 if (str9xpec_set_instr(tap
, ISC_ENABLE
, TAP_IDLE
) != ERROR_OK
)
185 return ERROR_TARGET_INVALID
;
187 /* check ISC status */
188 status
= str9xpec_isc_status(tap
);
189 if (status
& ISC_STATUS_MODE
)
191 /* we have entered isc mode */
192 str9xpec_info
->isc_enable
= 1;
193 LOG_DEBUG("ISC_MODE Enabled");
199 static int str9xpec_isc_disable(struct flash_bank_s
*bank
)
203 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
205 tap
= str9xpec_info
->tap
;
207 if (!str9xpec_info
->isc_enable
)
210 if (str9xpec_set_instr(tap
, ISC_DISABLE
, TAP_IDLE
) != ERROR_OK
)
211 return ERROR_TARGET_INVALID
;
213 /* delay to handle aborts */
216 /* check ISC status */
217 status
= str9xpec_isc_status(tap
);
218 if (!(status
& ISC_STATUS_MODE
))
220 /* we have left isc mode */
221 str9xpec_info
->isc_enable
= 0;
222 LOG_DEBUG("ISC_MODE Disabled");
228 static int str9xpec_read_config(struct flash_bank_s
*bank
)
234 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
236 tap
= str9xpec_info
->tap
;
238 LOG_DEBUG("ISC_CONFIGURATION");
240 /* execute ISC_CONFIGURATION command */
241 str9xpec_set_instr(tap
, ISC_CONFIGURATION
, TAP_IRPAUSE
);
245 field
.out_value
= NULL
;
246 field
.out_mask
= NULL
;
247 field
.in_value
= str9xpec_info
->options
;
248 field
.in_check_value
= NULL
;
249 field
.in_check_mask
= NULL
;
250 field
.in_handler
= NULL
;
251 field
.in_handler_priv
= NULL
;
253 jtag_add_dr_scan(1, &field
, TAP_IDLE
);
254 jtag_execute_queue();
256 status
= str9xpec_isc_status(tap
);
261 static int str9xpec_build_block_list(struct flash_bank_s
*bank
)
263 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
267 int b0_sectors
= 0, b1_sectors
= 0;
269 int b1_size
= 0x2000;
293 LOG_ERROR("BUG: unknown bank->size encountered");
297 num_sectors
= b0_sectors
+ b1_sectors
;
299 bank
->num_sectors
= num_sectors
;
300 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
301 str9xpec_info
->sector_bits
= malloc(sizeof(u32
) * num_sectors
);
305 for (i
= 0; i
< b0_sectors
; i
++)
307 bank
->sectors
[num_sectors
].offset
= offset
;
308 bank
->sectors
[num_sectors
].size
= 0x10000;
309 offset
+= bank
->sectors
[i
].size
;
310 bank
->sectors
[num_sectors
].is_erased
= -1;
311 bank
->sectors
[num_sectors
].is_protected
= 1;
312 str9xpec_info
->sector_bits
[num_sectors
++] = i
;
315 for (i
= 0; i
< b1_sectors
; i
++)
317 bank
->sectors
[num_sectors
].offset
= offset
;
318 bank
->sectors
[num_sectors
].size
= b1_size
;
319 offset
+= bank
->sectors
[i
].size
;
320 bank
->sectors
[num_sectors
].is_erased
= -1;
321 bank
->sectors
[num_sectors
].is_protected
= 1;
322 str9xpec_info
->sector_bits
[num_sectors
++] = i
+ 32;
328 /* flash bank str9x <base> <size> 0 0 <target#>
330 static int str9xpec_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
332 str9xpec_flash_controller_t
*str9xpec_info
;
333 armv4_5_common_t
*armv4_5
= NULL
;
334 arm7_9_common_t
*arm7_9
= NULL
;
335 arm_jtag_t
*jtag_info
= NULL
;
339 LOG_WARNING("incomplete flash_bank str9x configuration");
340 return ERROR_FLASH_BANK_INVALID
;
343 str9xpec_info
= malloc(sizeof(str9xpec_flash_controller_t
));
344 bank
->driver_priv
= str9xpec_info
;
346 /* find out jtag position of flash controller
347 * it is always after the arm966 core */
349 armv4_5
= bank
->target
->arch_info
;
350 arm7_9
= armv4_5
->arch_info
;
351 jtag_info
= &arm7_9
->jtag_info
;
353 str9xpec_info
->tap
= jtag_TapByAbsPosition( jtag_info
->tap
->abs_chain_position
- 1);
354 str9xpec_info
->isc_enable
= 0;
356 str9xpec_build_block_list(bank
);
358 /* clear option byte register */
359 buf_set_u32(str9xpec_info
->options
, 0, 64, 0);
364 static int str9xpec_blank_check(struct flash_bank_s
*bank
, int first
, int last
)
372 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
374 tap
= str9xpec_info
->tap
;
376 if (!str9xpec_info
->isc_enable
) {
377 str9xpec_isc_enable( bank
);
380 if (!str9xpec_info
->isc_enable
) {
381 return ERROR_FLASH_OPERATION_FAILED
;
384 buffer
= calloc(CEIL(64, 8), 1);
386 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first
, last
);
388 for (i
= first
; i
<= last
; i
++) {
389 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
392 /* execute ISC_BLANK_CHECK command */
393 str9xpec_set_instr(tap
, ISC_BLANK_CHECK
, TAP_IRPAUSE
);
397 field
.out_value
= buffer
;
398 field
.out_mask
= NULL
;
399 field
.in_value
= NULL
;
400 field
.in_check_value
= NULL
;
401 field
.in_check_mask
= NULL
;
402 field
.in_handler
= NULL
;
403 field
.in_handler_priv
= NULL
;
405 jtag_add_dr_scan(1, &field
, TAP_IDLE
);
406 jtag_add_sleep(40000);
408 /* read blank check result */
411 field
.out_value
= NULL
;
412 field
.out_mask
= NULL
;
413 field
.in_value
= buffer
;
414 field
.in_check_value
= NULL
;
415 field
.in_check_mask
= NULL
;
416 field
.in_handler
= NULL
;
417 field
.in_handler_priv
= NULL
;
419 jtag_add_dr_scan(1, &field
, TAP_IRPAUSE
);
420 jtag_execute_queue();
422 status
= str9xpec_isc_status(tap
);
424 for (i
= first
; i
<= last
; i
++)
426 if (buf_get_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1))
427 bank
->sectors
[i
].is_erased
= 0;
429 bank
->sectors
[i
].is_erased
= 1;
434 str9xpec_isc_disable(bank
);
436 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
437 return ERROR_FLASH_OPERATION_FAILED
;
441 static int str9xpec_protect_check(struct flash_bank_s
*bank
)
446 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
448 status
= str9xpec_read_config(bank
);
450 for (i
= 0; i
< bank
->num_sectors
; i
++)
452 if (buf_get_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1))
453 bank
->sectors
[i
].is_protected
= 1;
455 bank
->sectors
[i
].is_protected
= 0;
458 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
459 return ERROR_FLASH_OPERATION_FAILED
;
463 static int str9xpec_erase_area(struct flash_bank_s
*bank
, int first
, int last
)
471 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
473 tap
= str9xpec_info
->tap
;
475 if (!str9xpec_info
->isc_enable
) {
476 str9xpec_isc_enable( bank
);
479 if (!str9xpec_info
->isc_enable
) {
480 return ISC_STATUS_ERROR
;
483 buffer
= calloc(CEIL(64, 8), 1);
485 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first
, last
);
487 /* last bank: 0xFF signals a full erase (unlock complete device) */
488 /* last bank: 0xFE signals a option byte erase */
491 for (i
= 0; i
< 64; i
++) {
492 buf_set_u32(buffer
, i
, 1, 1);
495 else if (last
== 0xFE)
497 buf_set_u32(buffer
, 49, 1, 1);
501 for (i
= first
; i
<= last
; i
++) {
502 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
506 LOG_DEBUG("ISC_ERASE");
508 /* execute ISC_ERASE command */
509 str9xpec_set_instr(tap
, ISC_ERASE
, TAP_IRPAUSE
);
513 field
.out_value
= buffer
;
514 field
.out_mask
= NULL
;
515 field
.in_value
= NULL
;
516 field
.in_check_value
= NULL
;
517 field
.in_check_mask
= NULL
;
518 field
.in_handler
= NULL
;
519 field
.in_handler_priv
= NULL
;
521 jtag_add_dr_scan(1, &field
, TAP_IDLE
);
522 jtag_execute_queue();
526 /* wait for erase completion */
527 while (!((status
= str9xpec_isc_status(tap
)) & ISC_STATUS_BUSY
)) {
533 str9xpec_isc_disable(bank
);
538 static int str9xpec_erase(struct flash_bank_s
*bank
, int first
, int last
)
542 status
= str9xpec_erase_area(bank
, first
, last
);
544 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
545 return ERROR_FLASH_OPERATION_FAILED
;
550 static int str9xpec_lock_device(struct flash_bank_s
*bank
)
555 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
557 str9xpec_info
= bank
->driver_priv
;
558 tap
= str9xpec_info
->tap
;
560 if (!str9xpec_info
->isc_enable
) {
561 str9xpec_isc_enable( bank
);
564 if (!str9xpec_info
->isc_enable
) {
565 return ISC_STATUS_ERROR
;
568 /* set security address */
569 str9xpec_set_address(bank
, 0x80);
571 /* execute ISC_PROGRAM command */
572 str9xpec_set_instr(tap
, ISC_PROGRAM_SECURITY
, TAP_IDLE
);
574 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
579 field
.out_value
= NULL
;
580 field
.out_mask
= NULL
;
581 field
.in_value
= &status
;
582 field
.in_check_value
= NULL
;
583 field
.in_check_mask
= NULL
;
584 field
.in_handler
= NULL
;
585 field
.in_handler_priv
= NULL
;
587 jtag_add_dr_scan(1, &field
, -1);
588 jtag_execute_queue();
590 } while(!(status
& ISC_STATUS_BUSY
));
592 str9xpec_isc_disable(bank
);
597 static int str9xpec_unlock_device(struct flash_bank_s
*bank
)
601 status
= str9xpec_erase_area(bank
, 0, 255);
606 static int str9xpec_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
611 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
613 status
= str9xpec_read_config(bank
);
615 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
616 return ERROR_FLASH_OPERATION_FAILED
;
618 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first
, last
);
620 /* last bank: 0xFF signals a full device protect */
625 status
= str9xpec_lock_device(bank
);
629 /* perform full erase to unlock device */
630 status
= str9xpec_unlock_device(bank
);
635 for (i
= first
; i
<= last
; i
++)
638 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 1);
640 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 0);
643 status
= str9xpec_write_options(bank
);
646 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
647 return ERROR_FLASH_OPERATION_FAILED
;
652 static int str9xpec_set_address(struct flash_bank_s
*bank
, u8 sector
)
656 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
658 tap
= str9xpec_info
->tap
;
660 /* set flash controller address */
661 str9xpec_set_instr(tap
, ISC_ADDRESS_SHIFT
, TAP_IRPAUSE
);
665 field
.out_value
= §or
;
666 field
.out_mask
= NULL
;
667 field
.in_value
= NULL
;
668 field
.in_check_value
= NULL
;
669 field
.in_check_mask
= NULL
;
670 field
.in_handler
= NULL
;
671 field
.in_handler_priv
= NULL
;
673 jtag_add_dr_scan(1, &field
, -1);
678 static int str9xpec_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
680 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
681 u32 dwords_remaining
= (count
/ 8);
682 u32 bytes_remaining
= (count
& 0x00000007);
683 u32 bytes_written
= 0;
685 u32 check_address
= offset
;
690 int first_sector
= 0;
693 tap
= str9xpec_info
->tap
;
695 if (!str9xpec_info
->isc_enable
) {
696 str9xpec_isc_enable(bank
);
699 if (!str9xpec_info
->isc_enable
) {
700 return ERROR_FLASH_OPERATION_FAILED
;
705 LOG_WARNING("offset 0x%x breaks required 8-byte alignment", offset
);
706 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
709 for (i
= 0; i
< bank
->num_sectors
; i
++)
711 u32 sec_start
= bank
->sectors
[i
].offset
;
712 u32 sec_end
= sec_start
+ bank
->sectors
[i
].size
;
714 /* check if destination falls within the current sector */
715 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
717 /* check if destination ends in the current sector */
718 if (offset
+ count
< sec_end
)
719 check_address
= offset
+ count
;
721 check_address
= sec_end
;
724 if ((offset
>= sec_start
) && (offset
< sec_end
)){
728 if ((offset
+ count
>= sec_start
) && (offset
+ count
< sec_end
)){
733 if (check_address
!= offset
+ count
)
734 return ERROR_FLASH_DST_OUT_OF_BANK
;
736 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
738 scanbuf
= calloc(CEIL(64, 8), 1);
740 LOG_DEBUG("ISC_PROGRAM");
742 for (i
= first_sector
; i
<= last_sector
; i
++)
744 str9xpec_set_address(bank
, str9xpec_info
->sector_bits
[i
]);
746 dwords_remaining
= dwords_remaining
< (bank
->sectors
[i
].size
/8) ? dwords_remaining
: (bank
->sectors
[i
].size
/8);
748 while (dwords_remaining
> 0)
750 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
754 field
.out_value
= (buffer
+ bytes_written
);
755 field
.out_mask
= NULL
;
756 field
.in_value
= NULL
;
757 field
.in_check_value
= NULL
;
758 field
.in_check_mask
= NULL
;
759 field
.in_handler
= NULL
;
760 field
.in_handler_priv
= NULL
;
762 jtag_add_dr_scan(1, &field
, TAP_IDLE
);
764 /* small delay before polling */
767 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
772 field
.out_value
= NULL
;
773 field
.out_mask
= NULL
;
774 field
.in_value
= scanbuf
;
775 field
.in_check_value
= NULL
;
776 field
.in_check_mask
= NULL
;
777 field
.in_handler
= NULL
;
778 field
.in_handler_priv
= NULL
;
780 jtag_add_dr_scan(1, &field
, -1);
781 jtag_execute_queue();
783 status
= buf_get_u32(scanbuf
, 0, 8);
785 } while(!(status
& ISC_STATUS_BUSY
));
787 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
788 return ERROR_FLASH_OPERATION_FAILED
;
790 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
791 return ERROR_FLASH_OPERATION_FAILED; */
800 u8 last_dword
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
803 while(bytes_remaining
> 0)
805 last_dword
[i
++] = *(buffer
+ bytes_written
);
810 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
814 field
.out_value
= last_dword
;
815 field
.out_mask
= NULL
;
816 field
.in_value
= NULL
;
817 field
.in_check_value
= NULL
;
818 field
.in_check_mask
= NULL
;
819 field
.in_handler
= NULL
;
820 field
.in_handler_priv
= NULL
;
822 jtag_add_dr_scan(1, &field
, TAP_IDLE
);
824 /* small delay before polling */
827 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
832 field
.out_value
= NULL
;
833 field
.out_mask
= NULL
;
834 field
.in_value
= scanbuf
;
835 field
.in_check_value
= NULL
;
836 field
.in_check_mask
= NULL
;
837 field
.in_handler
= NULL
;
838 field
.in_handler_priv
= NULL
;
840 jtag_add_dr_scan(1, &field
, -1);
841 jtag_execute_queue();
843 status
= buf_get_u32(scanbuf
, 0, 8);
845 } while(!(status
& ISC_STATUS_BUSY
));
847 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
848 return ERROR_FLASH_OPERATION_FAILED
;
850 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
851 return ERROR_FLASH_OPERATION_FAILED; */
856 str9xpec_isc_disable(bank
);
861 static int str9xpec_probe(struct flash_bank_s
*bank
)
866 static int str9xpec_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
873 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
877 return ERROR_COMMAND_SYNTAX_ERROR
;
880 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
883 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
887 str9xpec_info
= bank
->driver_priv
;
888 tap
= str9xpec_info
->tap
;
890 buffer
= calloc(CEIL(32, 8), 1);
892 str9xpec_set_instr(tap
, ISC_IDCODE
, TAP_IRPAUSE
);
896 field
.out_value
= NULL
;
897 field
.out_mask
= NULL
;
898 field
.in_value
= buffer
;
899 field
.in_check_value
= NULL
;
900 field
.in_check_mask
= NULL
;
901 field
.in_handler
= NULL
;
902 field
.in_handler_priv
= NULL
;
904 jtag_add_dr_scan(1, &field
, TAP_IDLE
);
905 jtag_execute_queue();
907 idcode
= buf_get_u32(buffer
, 0, 32);
909 command_print(cmd_ctx
, "str9xpec part id: 0x%8.8x", idcode
);
916 static int str9xpec_erase_check(struct flash_bank_s
*bank
)
918 return str9xpec_blank_check(bank
, 0, bank
->num_sectors
- 1);
921 static int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
923 snprintf(buf
, buf_size
, "str9xpec flash driver info" );
927 static int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
931 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
935 command_print(cmd_ctx
, "str9xpec options_read <bank>");
939 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
942 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
946 str9xpec_info
= bank
->driver_priv
;
948 status
= str9xpec_read_config(bank
);
950 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
951 return ERROR_FLASH_OPERATION_FAILED
;
954 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1))
955 command_print(cmd_ctx
, "CS Map: bank1");
957 command_print(cmd_ctx
, "CS Map: bank0");
960 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_OTPBIT
, 1))
961 command_print(cmd_ctx
, "OTP Lock: OTP Locked");
963 command_print(cmd_ctx
, "OTP Lock: OTP Unlocked");
966 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1))
967 command_print(cmd_ctx
, "LVD Threshold: 2.7v");
969 command_print(cmd_ctx
, "LVD Threshold: 2.4v");
971 /* LVD reset warning */
972 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1))
973 command_print(cmd_ctx
, "LVD Reset Warning: VDD or VDDQ Inputs");
975 command_print(cmd_ctx
, "LVD Reset Warning: VDD Input Only");
977 /* LVD reset select */
978 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1))
979 command_print(cmd_ctx
, "LVD Reset Selection: VDD or VDDQ Inputs");
981 command_print(cmd_ctx
, "LVD Reset Selection: VDD Input Only");
986 static int str9xpec_write_options(struct flash_bank_s
*bank
)
991 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
993 str9xpec_info
= bank
->driver_priv
;
994 tap
= str9xpec_info
->tap
;
996 /* erase config options first */
997 status
= str9xpec_erase_area( bank
, 0xFE, 0xFE );
999 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1002 if (!str9xpec_info
->isc_enable
) {
1003 str9xpec_isc_enable( bank
);
1006 if (!str9xpec_info
->isc_enable
) {
1007 return ISC_STATUS_ERROR
;
1010 /* according to data 64th bit has to be set */
1011 buf_set_u32(str9xpec_info
->options
, 63, 1, 1);
1013 /* set option byte address */
1014 str9xpec_set_address(bank
, 0x50);
1016 /* execute ISC_PROGRAM command */
1017 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
1020 field
.num_bits
= 64;
1021 field
.out_value
= str9xpec_info
->options
;
1022 field
.out_mask
= NULL
;
1023 field
.in_value
= NULL
;
1024 field
.in_check_value
= NULL
;
1025 field
.in_check_mask
= NULL
;
1026 field
.in_handler
= NULL
;
1027 field
.in_handler_priv
= NULL
;
1029 jtag_add_dr_scan(1, &field
, TAP_IDLE
);
1031 /* small delay before polling */
1034 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
1039 field
.out_value
= NULL
;
1040 field
.out_mask
= NULL
;
1041 field
.in_value
= &status
;
1042 field
.in_check_value
= NULL
;
1043 field
.in_check_mask
= NULL
;
1044 field
.in_handler
= NULL
;
1045 field
.in_handler_priv
= NULL
;
1047 jtag_add_dr_scan(1, &field
, -1);
1048 jtag_execute_queue();
1050 } while(!(status
& ISC_STATUS_BUSY
));
1052 str9xpec_isc_disable(bank
);
1057 static int str9xpec_handle_flash_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1064 command_print(cmd_ctx
, "str9xpec options_write <bank>");
1068 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1071 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1075 status
= str9xpec_write_options(bank
);
1077 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1078 return ERROR_FLASH_OPERATION_FAILED
;
1083 static int str9xpec_handle_flash_options_cmap_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1086 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1090 command_print(cmd_ctx
, "str9xpec options_cmap <bank> <bank0|bank1>");
1094 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1097 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1101 str9xpec_info
= bank
->driver_priv
;
1103 if (strcmp(args
[1], "bank1") == 0)
1105 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 1);
1109 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 0);
1115 static int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1118 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1122 command_print(cmd_ctx
, "str9xpec options_lvdthd <bank> <2.4v|2.7v>");
1126 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1129 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1133 str9xpec_info
= bank
->driver_priv
;
1135 if (strcmp(args
[1], "2.7v") == 0)
1137 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 1);
1141 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 0);
1147 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1150 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1154 command_print(cmd_ctx
, "str9xpec options_lvdsel <bank> <vdd|vdd_vddq>");
1158 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1161 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1165 str9xpec_info
= bank
->driver_priv
;
1167 if (strcmp(args
[1], "vdd_vddq") == 0)
1169 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 1);
1173 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 0);
1179 static int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1182 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1186 command_print(cmd_ctx
, "str9xpec options_lvdwarn <bank> <vdd|vdd_vddq>");
1190 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1193 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1197 str9xpec_info
= bank
->driver_priv
;
1199 if (strcmp(args
[1], "vdd_vddq") == 0)
1201 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 1);
1205 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 0);
1211 static int str9xpec_handle_flash_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1218 command_print(cmd_ctx
, "str9xpec lock <bank>");
1222 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1225 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1229 status
= str9xpec_lock_device(bank
);
1231 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1232 return ERROR_FLASH_OPERATION_FAILED
;
1237 static int str9xpec_handle_flash_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1244 command_print(cmd_ctx
, "str9xpec unlock <bank>");
1248 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1251 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1255 status
= str9xpec_unlock_device(bank
);
1257 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1258 return ERROR_FLASH_OPERATION_FAILED
;
1263 static int str9xpec_handle_flash_enable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1270 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1274 command_print(cmd_ctx
, "str9xpec enable_turbo <bank>");
1278 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1281 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1285 str9xpec_info
= bank
->driver_priv
;
1287 tap0
= str9xpec_info
->tap
;
1289 /* remove arm core from chain - enter turbo mode */
1290 tap1
= tap0
->next_tap
;
1293 /* things are *WRONG* */
1294 command_print(cmd_ctx
,"**STR9FLASH** (tap1) invalid chain?");
1297 tap2
= tap1
->next_tap
;
1300 /* things are *WRONG* */
1301 command_print(cmd_ctx
,"**STR9FLASH** (tap2) invalid chain?");
1305 /* enable turbo mode - TURBO-PROG-ENABLE */
1306 str9xpec_set_instr(tap2
, 0xD, TAP_IDLE
);
1307 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1310 /* modify scan chain - str9 core has been removed */
1316 static int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1320 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1324 command_print(cmd_ctx
, "str9xpec disable_turbo <bank>");
1328 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1331 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1335 str9xpec_info
= bank
->driver_priv
;
1336 tap
= str9xpec_info
->tap
;
1341 /* exit turbo mode via RESET */
1342 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_RESET
);
1343 jtag_execute_queue();
1345 /* restore previous scan chain */
1346 if (tap
->next_tap
) {
1347 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)