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 int str9xpec_register_commands(struct command_context_s
*cmd_ctx
);
44 int str9xpec_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
45 int str9xpec_erase(struct flash_bank_s
*bank
, int first
, int last
);
46 int str9xpec_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
47 int str9xpec_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
48 int str9xpec_probe(struct flash_bank_s
*bank
);
49 int str9xpec_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
50 int str9xpec_protect_check(struct flash_bank_s
*bank
);
51 int str9xpec_erase_check(struct flash_bank_s
*bank
);
52 int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
54 int str9xpec_erase_area(struct flash_bank_s
*bank
, int first
, int last
);
55 int str9xpec_set_address(struct flash_bank_s
*bank
, u8 sector
);
56 int str9xpec_write_options(struct flash_bank_s
*bank
);
58 int str9xpec_handle_flash_options_cmap_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
59 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
60 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
61 int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
62 int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
63 int str9xpec_handle_flash_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
64 int str9xpec_handle_flash_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
65 int str9xpec_handle_flash_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
66 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
67 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 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(int chain_pos
, u32 new_instr
, enum tap_state end_state
)
116 jtag_device_t
*device
= jtag_get_device(chain_pos
);
119 return ERROR_TARGET_INVALID
;
122 if (buf_get_u32(device
->cur_instr
, 0, device
->ir_length
) != new_instr
)
126 field
.device
= chain_pos
;
127 field
.num_bits
= device
->ir_length
;
128 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
129 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
130 field
.out_mask
= NULL
;
131 field
.in_value
= NULL
;
132 field
.in_check_value
= NULL
;
133 field
.in_check_mask
= NULL
;
134 field
.in_handler
= NULL
;
135 field
.in_handler_priv
= NULL
;
137 jtag_add_ir_scan(1, &field
, end_state
);
139 free(field
.out_value
);
145 u8
str9xpec_isc_status(int chain_pos
)
150 if (str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
) != ERROR_OK
)
151 return ISC_STATUS_ERROR
;
153 field
.device
= chain_pos
;
155 field
.out_value
= NULL
;
156 field
.out_mask
= NULL
;
157 field
.in_value
= &status
;
158 field
.in_check_value
= NULL
;
159 field
.in_check_mask
= NULL
;
160 field
.in_handler
= NULL
;
161 field
.in_handler_priv
= NULL
;
163 jtag_add_dr_scan(1, &field
, TAP_RTI
);
164 jtag_execute_queue();
166 LOG_DEBUG("status: 0x%2.2x", status
);
168 if (status
& ISC_STATUS_SECURITY
)
169 LOG_INFO("Device Security Bit Set");
174 int str9xpec_isc_enable(struct flash_bank_s
*bank
)
178 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
180 chain_pos
= str9xpec_info
->chain_pos
;
182 if (str9xpec_info
->isc_enable
)
186 if (str9xpec_set_instr(chain_pos
, ISC_ENABLE
, TAP_RTI
) != ERROR_OK
)
187 return ERROR_TARGET_INVALID
;
189 /* check ISC status */
190 status
= str9xpec_isc_status(chain_pos
);
191 if (status
& ISC_STATUS_MODE
)
193 /* we have entered isc mode */
194 str9xpec_info
->isc_enable
= 1;
195 LOG_DEBUG("ISC_MODE Enabled");
201 int str9xpec_isc_disable(struct flash_bank_s
*bank
)
205 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
207 chain_pos
= str9xpec_info
->chain_pos
;
209 if (!str9xpec_info
->isc_enable
)
212 if (str9xpec_set_instr(chain_pos
, ISC_DISABLE
, TAP_RTI
) != ERROR_OK
)
213 return ERROR_TARGET_INVALID
;
215 /* delay to handle aborts */
218 /* check ISC status */
219 status
= str9xpec_isc_status(chain_pos
);
220 if (!(status
& ISC_STATUS_MODE
))
222 /* we have left isc mode */
223 str9xpec_info
->isc_enable
= 0;
224 LOG_DEBUG("ISC_MODE Disabled");
230 int str9xpec_read_config(struct flash_bank_s
*bank
)
236 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
238 chain_pos
= str9xpec_info
->chain_pos
;
240 LOG_DEBUG("ISC_CONFIGURATION");
242 /* execute ISC_CONFIGURATION command */
243 str9xpec_set_instr(chain_pos
, ISC_CONFIGURATION
, TAP_PI
);
245 field
.device
= chain_pos
;
247 field
.out_value
= NULL
;
248 field
.out_mask
= NULL
;
249 field
.in_value
= str9xpec_info
->options
;
250 field
.in_check_value
= NULL
;
251 field
.in_check_mask
= NULL
;
252 field
.in_handler
= NULL
;
253 field
.in_handler_priv
= NULL
;
255 jtag_add_dr_scan(1, &field
, TAP_RTI
);
256 jtag_execute_queue();
258 status
= str9xpec_isc_status(chain_pos
);
263 int str9xpec_build_block_list(struct flash_bank_s
*bank
)
265 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
269 int b0_sectors
= 0, b1_sectors
= 0;
271 int b1_size
= 0x2000;
295 LOG_ERROR("BUG: unknown bank->size encountered");
299 num_sectors
= b0_sectors
+ b1_sectors
;
301 bank
->num_sectors
= num_sectors
;
302 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
303 str9xpec_info
->sector_bits
= malloc(sizeof(u32
) * num_sectors
);
307 for (i
= 0; i
< b0_sectors
; i
++)
309 bank
->sectors
[num_sectors
].offset
= offset
;
310 bank
->sectors
[num_sectors
].size
= 0x10000;
311 offset
+= bank
->sectors
[i
].size
;
312 bank
->sectors
[num_sectors
].is_erased
= -1;
313 bank
->sectors
[num_sectors
].is_protected
= 1;
314 str9xpec_info
->sector_bits
[num_sectors
++] = i
;
317 for (i
= 0; i
< b1_sectors
; i
++)
319 bank
->sectors
[num_sectors
].offset
= offset
;
320 bank
->sectors
[num_sectors
].size
= b1_size
;
321 offset
+= bank
->sectors
[i
].size
;
322 bank
->sectors
[num_sectors
].is_erased
= -1;
323 bank
->sectors
[num_sectors
].is_protected
= 1;
324 str9xpec_info
->sector_bits
[num_sectors
++] = i
+ 32;
330 /* flash bank str9x <base> <size> 0 0 <target#>
332 int str9xpec_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
334 str9xpec_flash_controller_t
*str9xpec_info
;
335 armv4_5_common_t
*armv4_5
= NULL
;
336 arm7_9_common_t
*arm7_9
= NULL
;
337 arm_jtag_t
*jtag_info
= NULL
;
341 LOG_WARNING("incomplete flash_bank str9x configuration");
342 return ERROR_FLASH_BANK_INVALID
;
345 str9xpec_info
= malloc(sizeof(str9xpec_flash_controller_t
));
346 bank
->driver_priv
= str9xpec_info
;
348 /* find out jtag position of flash controller
349 * it is always after the arm966 core */
351 armv4_5
= bank
->target
->arch_info
;
352 arm7_9
= armv4_5
->arch_info
;
353 jtag_info
= &arm7_9
->jtag_info
;
355 str9xpec_info
->chain_pos
= (jtag_info
->chain_pos
- 1);
356 str9xpec_info
->isc_enable
= 0;
357 str9xpec_info
->devarm
= NULL
;
359 str9xpec_build_block_list(bank
);
361 /* clear option byte register */
362 buf_set_u32(str9xpec_info
->options
, 0, 64, 0);
367 int str9xpec_blank_check(struct flash_bank_s
*bank
, int first
, int last
)
375 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
377 chain_pos
= str9xpec_info
->chain_pos
;
379 if (!str9xpec_info
->isc_enable
) {
380 str9xpec_isc_enable( bank
);
383 if (!str9xpec_info
->isc_enable
) {
384 return ERROR_FLASH_OPERATION_FAILED
;
387 buffer
= calloc(CEIL(64, 8), 1);
389 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first
, last
);
391 for (i
= first
; i
<= last
; i
++) {
392 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
395 /* execute ISC_BLANK_CHECK command */
396 str9xpec_set_instr(chain_pos
, ISC_BLANK_CHECK
, TAP_PI
);
398 field
.device
= chain_pos
;
400 field
.out_value
= buffer
;
401 field
.out_mask
= NULL
;
402 field
.in_value
= NULL
;
403 field
.in_check_value
= NULL
;
404 field
.in_check_mask
= NULL
;
405 field
.in_handler
= NULL
;
406 field
.in_handler_priv
= NULL
;
408 jtag_add_dr_scan(1, &field
, TAP_RTI
);
409 jtag_add_sleep(40000);
411 /* read blank check result */
412 field
.device
= chain_pos
;
414 field
.out_value
= NULL
;
415 field
.out_mask
= NULL
;
416 field
.in_value
= buffer
;
417 field
.in_check_value
= NULL
;
418 field
.in_check_mask
= NULL
;
419 field
.in_handler
= NULL
;
420 field
.in_handler_priv
= NULL
;
422 jtag_add_dr_scan(1, &field
, TAP_PI
);
423 jtag_execute_queue();
425 status
= str9xpec_isc_status(chain_pos
);
427 for (i
= first
; i
<= last
; i
++)
429 if (buf_get_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1))
430 bank
->sectors
[i
].is_erased
= 0;
432 bank
->sectors
[i
].is_erased
= 1;
437 str9xpec_isc_disable(bank
);
439 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
440 return ERROR_FLASH_OPERATION_FAILED
;
444 int str9xpec_protect_check(struct flash_bank_s
*bank
)
449 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
451 status
= str9xpec_read_config(bank
);
453 for (i
= 0; i
< bank
->num_sectors
; i
++)
455 if (buf_get_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1))
456 bank
->sectors
[i
].is_protected
= 1;
458 bank
->sectors
[i
].is_protected
= 0;
461 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
462 return ERROR_FLASH_OPERATION_FAILED
;
466 int str9xpec_erase_area(struct flash_bank_s
*bank
, int first
, int last
)
474 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
476 chain_pos
= str9xpec_info
->chain_pos
;
478 if (!str9xpec_info
->isc_enable
) {
479 str9xpec_isc_enable( bank
);
482 if (!str9xpec_info
->isc_enable
) {
483 return ISC_STATUS_ERROR
;
486 buffer
= calloc(CEIL(64, 8), 1);
488 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first
, last
);
490 /* last bank: 0xFF signals a full erase (unlock complete device) */
491 /* last bank: 0xFE signals a option byte erase */
494 for (i
= 0; i
< 64; i
++) {
495 buf_set_u32(buffer
, i
, 1, 1);
498 else if (last
== 0xFE)
500 buf_set_u32(buffer
, 49, 1, 1);
504 for (i
= first
; i
<= last
; i
++) {
505 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
509 LOG_DEBUG("ISC_ERASE");
511 /* execute ISC_ERASE command */
512 str9xpec_set_instr(chain_pos
, ISC_ERASE
, TAP_PI
);
514 field
.device
= chain_pos
;
516 field
.out_value
= buffer
;
517 field
.out_mask
= NULL
;
518 field
.in_value
= NULL
;
519 field
.in_check_value
= NULL
;
520 field
.in_check_mask
= NULL
;
521 field
.in_handler
= NULL
;
522 field
.in_handler_priv
= NULL
;
524 jtag_add_dr_scan(1, &field
, TAP_RTI
);
525 jtag_execute_queue();
529 /* wait for erase completion */
530 while (!((status
= str9xpec_isc_status(chain_pos
)) & ISC_STATUS_BUSY
)) {
536 str9xpec_isc_disable(bank
);
541 int str9xpec_erase(struct flash_bank_s
*bank
, int first
, int last
)
545 status
= str9xpec_erase_area(bank
, first
, last
);
547 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
548 return ERROR_FLASH_OPERATION_FAILED
;
553 int str9xpec_lock_device(struct flash_bank_s
*bank
)
558 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
560 str9xpec_info
= bank
->driver_priv
;
561 chain_pos
= str9xpec_info
->chain_pos
;
563 if (!str9xpec_info
->isc_enable
) {
564 str9xpec_isc_enable( bank
);
567 if (!str9xpec_info
->isc_enable
) {
568 return ISC_STATUS_ERROR
;
571 /* set security address */
572 str9xpec_set_address(bank
, 0x80);
574 /* execute ISC_PROGRAM command */
575 str9xpec_set_instr(chain_pos
, ISC_PROGRAM_SECURITY
, TAP_RTI
);
577 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
580 field
.device
= chain_pos
;
582 field
.out_value
= NULL
;
583 field
.out_mask
= NULL
;
584 field
.in_value
= &status
;
585 field
.in_check_value
= NULL
;
586 field
.in_check_mask
= NULL
;
587 field
.in_handler
= NULL
;
588 field
.in_handler_priv
= NULL
;
590 jtag_add_dr_scan(1, &field
, -1);
591 jtag_execute_queue();
593 } while(!(status
& ISC_STATUS_BUSY
));
595 str9xpec_isc_disable(bank
);
600 int str9xpec_unlock_device(struct flash_bank_s
*bank
)
604 status
= str9xpec_erase_area(bank
, 0, 255);
609 int str9xpec_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
614 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
616 status
= str9xpec_read_config(bank
);
618 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
619 return ERROR_FLASH_OPERATION_FAILED
;
621 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first
, last
);
623 /* last bank: 0xFF signals a full device protect */
628 status
= str9xpec_lock_device(bank
);
632 /* perform full erase to unlock device */
633 status
= str9xpec_unlock_device(bank
);
638 for (i
= first
; i
<= last
; i
++)
641 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 1);
643 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 0);
646 status
= str9xpec_write_options(bank
);
649 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
650 return ERROR_FLASH_OPERATION_FAILED
;
655 int str9xpec_set_address(struct flash_bank_s
*bank
, u8 sector
)
659 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
661 chain_pos
= str9xpec_info
->chain_pos
;
663 /* set flash controller address */
664 str9xpec_set_instr(chain_pos
, ISC_ADDRESS_SHIFT
, TAP_PI
);
666 field
.device
= chain_pos
;
668 field
.out_value
= §or
;
669 field
.out_mask
= NULL
;
670 field
.in_value
= NULL
;
671 field
.in_check_value
= NULL
;
672 field
.in_check_mask
= NULL
;
673 field
.in_handler
= NULL
;
674 field
.in_handler_priv
= NULL
;
676 jtag_add_dr_scan(1, &field
, -1);
681 int str9xpec_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
683 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
684 u32 dwords_remaining
= (count
/ 8);
685 u32 bytes_remaining
= (count
& 0x00000007);
686 u32 bytes_written
= 0;
688 u32 check_address
= offset
;
693 u32 first_sector
= 0;
696 chain_pos
= str9xpec_info
->chain_pos
;
698 if (!str9xpec_info
->isc_enable
) {
699 str9xpec_isc_enable(bank
);
702 if (!str9xpec_info
->isc_enable
) {
703 return ERROR_FLASH_OPERATION_FAILED
;
708 LOG_WARNING("offset 0x%x breaks required 8-byte alignment", offset
);
709 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
712 for (i
= 0; i
< bank
->num_sectors
; i
++)
714 u32 sec_start
= bank
->sectors
[i
].offset
;
715 u32 sec_end
= sec_start
+ bank
->sectors
[i
].size
;
717 /* check if destination falls within the current sector */
718 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
720 /* check if destination ends in the current sector */
721 if (offset
+ count
< sec_end
)
722 check_address
= offset
+ count
;
724 check_address
= sec_end
;
727 if ((offset
>= sec_start
) && (offset
< sec_end
)){
731 if ((offset
+ count
>= sec_start
) && (offset
+ count
< sec_end
)){
736 if (check_address
!= offset
+ count
)
737 return ERROR_FLASH_DST_OUT_OF_BANK
;
739 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
741 scanbuf
= calloc(CEIL(64, 8), 1);
743 LOG_DEBUG("ISC_PROGRAM");
745 for (i
= first_sector
; i
<= last_sector
; i
++)
747 str9xpec_set_address(bank
, str9xpec_info
->sector_bits
[i
]);
749 dwords_remaining
= dwords_remaining
< (bank
->sectors
[i
].size
/8) ? dwords_remaining
: (bank
->sectors
[i
].size
/8);
751 while (dwords_remaining
> 0)
753 str9xpec_set_instr(chain_pos
, ISC_PROGRAM
, TAP_PI
);
755 field
.device
= chain_pos
;
757 field
.out_value
= (buffer
+ bytes_written
);
758 field
.out_mask
= NULL
;
759 field
.in_value
= NULL
;
760 field
.in_check_value
= NULL
;
761 field
.in_check_mask
= NULL
;
762 field
.in_handler
= NULL
;
763 field
.in_handler_priv
= NULL
;
765 jtag_add_dr_scan(1, &field
, TAP_RTI
);
767 /* small delay before polling */
770 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
773 field
.device
= chain_pos
;
775 field
.out_value
= NULL
;
776 field
.out_mask
= NULL
;
777 field
.in_value
= scanbuf
;
778 field
.in_check_value
= NULL
;
779 field
.in_check_mask
= NULL
;
780 field
.in_handler
= NULL
;
781 field
.in_handler_priv
= NULL
;
783 jtag_add_dr_scan(1, &field
, -1);
784 jtag_execute_queue();
786 status
= buf_get_u32(scanbuf
, 0, 8);
788 } while(!(status
& ISC_STATUS_BUSY
));
790 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
791 return ERROR_FLASH_OPERATION_FAILED
;
793 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
794 return ERROR_FLASH_OPERATION_FAILED; */
803 u8 last_dword
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
806 while(bytes_remaining
> 0)
808 last_dword
[i
++] = *(buffer
+ bytes_written
);
813 str9xpec_set_instr(chain_pos
, ISC_PROGRAM
, TAP_PI
);
815 field
.device
= chain_pos
;
817 field
.out_value
= last_dword
;
818 field
.out_mask
= NULL
;
819 field
.in_value
= NULL
;
820 field
.in_check_value
= NULL
;
821 field
.in_check_mask
= NULL
;
822 field
.in_handler
= NULL
;
823 field
.in_handler_priv
= NULL
;
825 jtag_add_dr_scan(1, &field
, TAP_RTI
);
827 /* small delay before polling */
830 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
833 field
.device
= chain_pos
;
835 field
.out_value
= NULL
;
836 field
.out_mask
= NULL
;
837 field
.in_value
= scanbuf
;
838 field
.in_check_value
= NULL
;
839 field
.in_check_mask
= NULL
;
840 field
.in_handler
= NULL
;
841 field
.in_handler_priv
= NULL
;
843 jtag_add_dr_scan(1, &field
, -1);
844 jtag_execute_queue();
846 status
= buf_get_u32(scanbuf
, 0, 8);
848 } while(!(status
& ISC_STATUS_BUSY
));
850 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
851 return ERROR_FLASH_OPERATION_FAILED
;
853 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
854 return ERROR_FLASH_OPERATION_FAILED; */
859 str9xpec_isc_disable(bank
);
864 int str9xpec_probe(struct flash_bank_s
*bank
)
869 int str9xpec_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
876 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
880 return ERROR_COMMAND_SYNTAX_ERROR
;
883 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
886 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
890 str9xpec_info
= bank
->driver_priv
;
891 chain_pos
= str9xpec_info
->chain_pos
;
893 buffer
= calloc(CEIL(32, 8), 1);
895 str9xpec_set_instr(chain_pos
, ISC_IDCODE
, TAP_PI
);
897 field
.device
= chain_pos
;
899 field
.out_value
= NULL
;
900 field
.out_mask
= NULL
;
901 field
.in_value
= buffer
;
902 field
.in_check_value
= NULL
;
903 field
.in_check_mask
= NULL
;
904 field
.in_handler
= NULL
;
905 field
.in_handler_priv
= NULL
;
907 jtag_add_dr_scan(1, &field
, TAP_RTI
);
908 jtag_execute_queue();
910 idcode
= buf_get_u32(buffer
, 0, 32);
912 command_print(cmd_ctx
, "str9xpec part id: 0x%8.8x", idcode
);
919 int str9xpec_erase_check(struct flash_bank_s
*bank
)
921 return str9xpec_blank_check(bank
, 0, bank
->num_sectors
- 1);
924 int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
926 snprintf(buf
, buf_size
, "str9xpec flash driver info" );
930 int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
934 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
938 command_print(cmd_ctx
, "str9xpec options_read <bank>");
942 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
945 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
949 str9xpec_info
= bank
->driver_priv
;
951 status
= str9xpec_read_config(bank
);
953 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
954 return ERROR_FLASH_OPERATION_FAILED
;
957 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1))
958 command_print(cmd_ctx
, "CS Map: bank1");
960 command_print(cmd_ctx
, "CS Map: bank0");
963 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_OTPBIT
, 1))
964 command_print(cmd_ctx
, "OTP Lock: OTP Locked");
966 command_print(cmd_ctx
, "OTP Lock: OTP Unlocked");
969 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1))
970 command_print(cmd_ctx
, "LVD Threshold: 2.7v");
972 command_print(cmd_ctx
, "LVD Threshold: 2.4v");
974 /* LVD reset warning */
975 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1))
976 command_print(cmd_ctx
, "LVD Reset Warning: VDD or VDDQ Inputs");
978 command_print(cmd_ctx
, "LVD Reset Warning: VDD Input Only");
980 /* LVD reset select */
981 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1))
982 command_print(cmd_ctx
, "LVD Reset Selection: VDD or VDDQ Inputs");
984 command_print(cmd_ctx
, "LVD Reset Selection: VDD Input Only");
989 int str9xpec_write_options(struct flash_bank_s
*bank
)
994 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
996 str9xpec_info
= bank
->driver_priv
;
997 chain_pos
= str9xpec_info
->chain_pos
;
999 /* erase config options first */
1000 status
= str9xpec_erase_area( bank
, 0xFE, 0xFE );
1002 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1005 if (!str9xpec_info
->isc_enable
) {
1006 str9xpec_isc_enable( bank
);
1009 if (!str9xpec_info
->isc_enable
) {
1010 return ISC_STATUS_ERROR
;
1013 /* according to data 64th bit has to be set */
1014 buf_set_u32(str9xpec_info
->options
, 63, 1, 1);
1016 /* set option byte address */
1017 str9xpec_set_address(bank
, 0x50);
1019 /* execute ISC_PROGRAM command */
1020 str9xpec_set_instr(chain_pos
, ISC_PROGRAM
, TAP_PI
);
1022 field
.device
= chain_pos
;
1023 field
.num_bits
= 64;
1024 field
.out_value
= str9xpec_info
->options
;
1025 field
.out_mask
= NULL
;
1026 field
.in_value
= NULL
;
1027 field
.in_check_value
= NULL
;
1028 field
.in_check_mask
= NULL
;
1029 field
.in_handler
= NULL
;
1030 field
.in_handler_priv
= NULL
;
1032 jtag_add_dr_scan(1, &field
, TAP_RTI
);
1034 /* small delay before polling */
1037 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
1040 field
.device
= chain_pos
;
1042 field
.out_value
= NULL
;
1043 field
.out_mask
= NULL
;
1044 field
.in_value
= &status
;
1045 field
.in_check_value
= NULL
;
1046 field
.in_check_mask
= NULL
;
1047 field
.in_handler
= NULL
;
1048 field
.in_handler_priv
= NULL
;
1050 jtag_add_dr_scan(1, &field
, -1);
1051 jtag_execute_queue();
1053 } while(!(status
& ISC_STATUS_BUSY
));
1055 str9xpec_isc_disable(bank
);
1060 int str9xpec_handle_flash_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1067 command_print(cmd_ctx
, "str9xpec options_write <bank>");
1071 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1074 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1078 status
= str9xpec_write_options(bank
);
1080 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1081 return ERROR_FLASH_OPERATION_FAILED
;
1086 int str9xpec_handle_flash_options_cmap_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1089 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1093 command_print(cmd_ctx
, "str9xpec options_cmap <bank> <bank0|bank1>");
1097 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1100 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1104 str9xpec_info
= bank
->driver_priv
;
1106 if (strcmp(args
[1], "bank1") == 0)
1108 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 1);
1112 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 0);
1118 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1121 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1125 command_print(cmd_ctx
, "str9xpec options_lvdthd <bank> <2.4v|2.7v>");
1129 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1132 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1136 str9xpec_info
= bank
->driver_priv
;
1138 if (strcmp(args
[1], "2.7v") == 0)
1140 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 1);
1144 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 0);
1150 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1153 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1157 command_print(cmd_ctx
, "str9xpec options_lvdsel <bank> <vdd|vdd_vddq>");
1161 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1164 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1168 str9xpec_info
= bank
->driver_priv
;
1170 if (strcmp(args
[1], "vdd_vddq") == 0)
1172 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 1);
1176 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 0);
1182 int str9xpec_handle_flash_options_lvdwarn_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 options_lvdwarn <bank> <vdd|vdd_vddq>");
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 if (strcmp(args
[1], "vdd_vddq") == 0)
1204 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 1);
1208 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 0);
1214 int str9xpec_handle_flash_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1221 command_print(cmd_ctx
, "str9xpec lock <bank>");
1225 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1228 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1232 status
= str9xpec_lock_device(bank
);
1234 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1235 return ERROR_FLASH_OPERATION_FAILED
;
1240 int str9xpec_handle_flash_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1247 command_print(cmd_ctx
, "str9xpec unlock <bank>");
1251 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1254 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1258 status
= str9xpec_unlock_device(bank
);
1260 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1261 return ERROR_FLASH_OPERATION_FAILED
;
1266 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1271 jtag_device_t
* dev0
;
1272 jtag_device_t
* dev2
;
1273 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1277 command_print(cmd_ctx
, "str9xpec enable_turbo <bank>");
1281 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1284 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1288 str9xpec_info
= bank
->driver_priv
;
1290 chain_pos
= str9xpec_info
->chain_pos
;
1292 /* remove arm core from chain - enter turbo mode */
1294 str9xpec_set_instr(chain_pos
+2, 0xD, TAP_RTI
);
1295 if ((retval
=jtag_execute_queue())!=ERROR_OK
)
1298 /* modify scan chain - str9 core has been removed */
1299 dev0
= jtag_get_device(chain_pos
);
1302 str9xpec_info
->devarm
= jtag_get_device(chain_pos
+1);
1303 dev2
= jtag_get_device(chain_pos
+2);
1312 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1316 jtag_device_t
* dev0
;
1317 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1321 command_print(cmd_ctx
, "str9xpec disable_turbo <bank>");
1325 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1328 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1332 str9xpec_info
= bank
->driver_priv
;
1334 chain_pos
= str9xpec_info
->chain_pos
;
1336 dev0
= jtag_get_device(chain_pos
);
1341 /* exit turbo mode via TLR */
1342 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_TLR
);
1343 jtag_execute_queue();
1345 /* restore previous scan chain */
1346 if( str9xpec_info
->devarm
) {
1347 dev0
->next
= str9xpec_info
->devarm
;
1349 str9xpec_info
->devarm
= NULL
;
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)