1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
24 #include "replacements.h"
31 #include "arm7_9_common.h"
33 #include "binarybuffer.h"
40 int str9xpec_register_commands(struct command_context_s
*cmd_ctx
);
41 int str9xpec_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
42 int str9xpec_erase(struct flash_bank_s
*bank
, int first
, int last
);
43 int str9xpec_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
44 int str9xpec_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
45 int str9xpec_probe(struct flash_bank_s
*bank
);
46 int str9xpec_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
47 int str9xpec_protect_check(struct flash_bank_s
*bank
);
48 int str9xpec_erase_check(struct flash_bank_s
*bank
);
49 int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
51 int str9xpec_erase_area(struct flash_bank_s
*bank
, int first
, int last
);
52 int str9xpec_set_address(struct flash_bank_s
*bank
, u8 sector
);
53 int str9xpec_write_options(struct flash_bank_s
*bank
);
55 int str9xpec_handle_flash_options_cmap_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
56 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
57 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
58 int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
59 int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
60 int str9xpec_handle_flash_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
61 int str9xpec_handle_flash_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
62 int str9xpec_handle_flash_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
63 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
64 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
66 flash_driver_t str9xpec_flash
=
69 .register_commands
= str9xpec_register_commands
,
70 .flash_bank_command
= str9xpec_flash_bank_command
,
71 .erase
= str9xpec_erase
,
72 .protect
= str9xpec_protect
,
73 .write
= str9xpec_write
,
74 .probe
= str9xpec_probe
,
75 .auto_probe
= str9xpec_probe
,
76 .erase_check
= str9xpec_erase_check
,
77 .protect_check
= str9xpec_protect_check
,
81 int str9xpec_register_commands(struct command_context_s
*cmd_ctx
)
83 command_t
*str9xpec_cmd
= register_command(cmd_ctx
, NULL
, "str9xpec", NULL
, COMMAND_ANY
, "str9xpec flash specific commands");
85 register_command(cmd_ctx
, str9xpec_cmd
, "enable_turbo", str9xpec_handle_flash_enable_turbo_command
, COMMAND_EXEC
,
86 "enable str9xpec turbo mode");
87 register_command(cmd_ctx
, str9xpec_cmd
, "disable_turbo", str9xpec_handle_flash_disable_turbo_command
, COMMAND_EXEC
,
88 "disable str9xpec turbo mode");
89 register_command(cmd_ctx
, str9xpec_cmd
, "options_cmap", str9xpec_handle_flash_options_cmap_command
, COMMAND_EXEC
,
90 "configure str9xpec boot sector");
91 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdthd", str9xpec_handle_flash_options_lvdthd_command
, COMMAND_EXEC
,
92 "configure str9xpec lvd threshold");
93 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdsel", str9xpec_handle_flash_options_lvdsel_command
, COMMAND_EXEC
,
94 "configure str9xpec lvd selection");
95 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdwarn", str9xpec_handle_flash_options_lvdwarn_command
, COMMAND_EXEC
,
96 "configure str9xpec lvd warning");
97 register_command(cmd_ctx
, str9xpec_cmd
, "options_read", str9xpec_handle_flash_options_read_command
, COMMAND_EXEC
,
98 "read str9xpec options");
99 register_command(cmd_ctx
, str9xpec_cmd
, "options_write", str9xpec_handle_flash_options_write_command
, COMMAND_EXEC
,
100 "write str9xpec options");
101 register_command(cmd_ctx
, str9xpec_cmd
, "lock", str9xpec_handle_flash_lock_command
, COMMAND_EXEC
,
102 "lock str9xpec device");
103 register_command(cmd_ctx
, str9xpec_cmd
, "unlock", str9xpec_handle_flash_unlock_command
, COMMAND_EXEC
,
104 "unlock str9xpec device");
105 register_command(cmd_ctx
, str9xpec_cmd
, "part_id", str9xpec_handle_part_id_command
, COMMAND_EXEC
,
106 "print part id of str9xpec flash bank <num>");
111 int str9xpec_set_instr(int chain_pos
, u32 new_instr
, enum tap_state end_state
)
113 jtag_device_t
*device
= jtag_get_device(chain_pos
);
117 LOG_DEBUG("Invalid Target");
118 return ERROR_TARGET_INVALID
;
121 if (buf_get_u32(device
->cur_instr
, 0, device
->ir_length
) != new_instr
)
125 field
.device
= chain_pos
;
126 field
.num_bits
= device
->ir_length
;
127 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
128 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
129 field
.out_mask
= NULL
;
130 field
.in_value
= NULL
;
131 field
.in_check_value
= NULL
;
132 field
.in_check_mask
= NULL
;
133 field
.in_handler
= NULL
;
134 field
.in_handler_priv
= NULL
;
136 jtag_add_ir_scan(1, &field
, end_state
);
138 free(field
.out_value
);
144 u8
str9xpec_isc_status(int chain_pos
)
149 if (str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
) != ERROR_OK
)
150 return ISC_STATUS_ERROR
;
152 field
.device
= chain_pos
;
154 field
.out_value
= NULL
;
155 field
.out_mask
= NULL
;
156 field
.in_value
= &status
;
157 field
.in_check_value
= NULL
;
158 field
.in_check_mask
= NULL
;
159 field
.in_handler
= NULL
;
160 field
.in_handler_priv
= NULL
;
162 jtag_add_dr_scan(1, &field
, TAP_RTI
);
163 jtag_execute_queue();
165 LOG_DEBUG("status: 0x%2.2x", status
);
167 if (status
& ISC_STATUS_SECURITY
)
168 LOG_INFO("Device Security Bit Set");
173 int str9xpec_isc_enable(struct flash_bank_s
*bank
)
177 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
179 chain_pos
= str9xpec_info
->chain_pos
;
181 if (str9xpec_info
->isc_enable
)
185 if (str9xpec_set_instr(chain_pos
, ISC_ENABLE
, TAP_RTI
) != ERROR_OK
)
186 return ERROR_TARGET_INVALID
;
188 /* check ISC status */
189 status
= str9xpec_isc_status(chain_pos
);
190 if (status
& ISC_STATUS_MODE
)
192 /* we have entered isc mode */
193 str9xpec_info
->isc_enable
= 1;
194 LOG_DEBUG("ISC_MODE Enabled");
200 int str9xpec_isc_disable(struct flash_bank_s
*bank
)
204 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
206 chain_pos
= str9xpec_info
->chain_pos
;
208 if (!str9xpec_info
->isc_enable
)
211 if (str9xpec_set_instr(chain_pos
, ISC_DISABLE
, TAP_RTI
) != ERROR_OK
)
212 return ERROR_TARGET_INVALID
;
214 /* delay to handle aborts */
217 /* check ISC status */
218 status
= str9xpec_isc_status(chain_pos
);
219 if (!(status
& ISC_STATUS_MODE
))
221 /* we have left isc mode */
222 str9xpec_info
->isc_enable
= 0;
223 LOG_DEBUG("ISC_MODE Disabled");
229 int str9xpec_read_config(struct flash_bank_s
*bank
)
235 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
237 chain_pos
= str9xpec_info
->chain_pos
;
239 LOG_DEBUG("ISC_CONFIGURATION");
241 /* execute ISC_CONFIGURATION command */
242 str9xpec_set_instr(chain_pos
, ISC_CONFIGURATION
, TAP_PI
);
244 field
.device
= chain_pos
;
246 field
.out_value
= NULL
;
247 field
.out_mask
= NULL
;
248 field
.in_value
= str9xpec_info
->options
;
249 field
.in_check_value
= NULL
;
250 field
.in_check_mask
= NULL
;
251 field
.in_handler
= NULL
;
252 field
.in_handler_priv
= NULL
;
254 jtag_add_dr_scan(1, &field
, TAP_RTI
);
255 jtag_execute_queue();
257 status
= str9xpec_isc_status(chain_pos
);
262 int str9xpec_build_block_list(struct flash_bank_s
*bank
)
264 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
268 int b0_sectors
= 0, b1_sectors
= 0;
270 int b1_size
= 0x2000;
294 LOG_ERROR("BUG: unknown bank->size encountered");
298 num_sectors
= b0_sectors
+ b1_sectors
;
300 bank
->num_sectors
= num_sectors
;
301 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
302 str9xpec_info
->sector_bits
= malloc(sizeof(u32
) * num_sectors
);
306 for (i
= 0; i
< b0_sectors
; i
++)
308 bank
->sectors
[num_sectors
].offset
= offset
;
309 bank
->sectors
[num_sectors
].size
= 0x10000;
310 offset
+= bank
->sectors
[i
].size
;
311 bank
->sectors
[num_sectors
].is_erased
= -1;
312 bank
->sectors
[num_sectors
].is_protected
= 1;
313 str9xpec_info
->sector_bits
[num_sectors
++] = i
;
316 for (i
= 0; i
< b1_sectors
; i
++)
318 bank
->sectors
[num_sectors
].offset
= offset
;
319 bank
->sectors
[num_sectors
].size
= b1_size
;
320 offset
+= bank
->sectors
[i
].size
;
321 bank
->sectors
[num_sectors
].is_erased
= -1;
322 bank
->sectors
[num_sectors
].is_protected
= 1;
323 str9xpec_info
->sector_bits
[num_sectors
++] = i
+ 32;
329 /* flash bank str9x <base> <size> 0 0 <target#>
331 int str9xpec_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
333 str9xpec_flash_controller_t
*str9xpec_info
;
334 armv4_5_common_t
*armv4_5
= NULL
;
335 arm7_9_common_t
*arm7_9
= NULL
;
336 arm_jtag_t
*jtag_info
= NULL
;
340 LOG_WARNING("incomplete flash_bank str9x configuration");
341 return ERROR_FLASH_BANK_INVALID
;
344 str9xpec_info
= malloc(sizeof(str9xpec_flash_controller_t
));
345 bank
->driver_priv
= str9xpec_info
;
347 /* find out jtag position of flash controller
348 * it is always after the arm966 core */
350 armv4_5
= bank
->target
->arch_info
;
351 arm7_9
= armv4_5
->arch_info
;
352 jtag_info
= &arm7_9
->jtag_info
;
354 str9xpec_info
->chain_pos
= (jtag_info
->chain_pos
- 1);
355 str9xpec_info
->isc_enable
= 0;
356 str9xpec_info
->devarm
= NULL
;
358 str9xpec_build_block_list(bank
);
360 /* clear option byte register */
361 buf_set_u32(str9xpec_info
->options
, 0, 64, 0);
366 int str9xpec_blank_check(struct flash_bank_s
*bank
, int first
, int last
)
374 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
376 chain_pos
= str9xpec_info
->chain_pos
;
378 if (!str9xpec_info
->isc_enable
) {
379 str9xpec_isc_enable( bank
);
382 if (!str9xpec_info
->isc_enable
) {
383 return ERROR_FLASH_OPERATION_FAILED
;
386 buffer
= calloc(CEIL(64, 8), 1);
388 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first
, last
);
390 for (i
= first
; i
<= last
; i
++) {
391 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
394 /* execute ISC_BLANK_CHECK command */
395 str9xpec_set_instr(chain_pos
, ISC_BLANK_CHECK
, TAP_PI
);
397 field
.device
= chain_pos
;
399 field
.out_value
= buffer
;
400 field
.out_mask
= NULL
;
401 field
.in_value
= NULL
;
402 field
.in_check_value
= NULL
;
403 field
.in_check_mask
= NULL
;
404 field
.in_handler
= NULL
;
405 field
.in_handler_priv
= NULL
;
407 jtag_add_dr_scan(1, &field
, TAP_RTI
);
408 jtag_add_sleep(40000);
410 /* read blank check result */
411 field
.device
= chain_pos
;
413 field
.out_value
= NULL
;
414 field
.out_mask
= NULL
;
415 field
.in_value
= buffer
;
416 field
.in_check_value
= NULL
;
417 field
.in_check_mask
= NULL
;
418 field
.in_handler
= NULL
;
419 field
.in_handler_priv
= NULL
;
421 jtag_add_dr_scan(1, &field
, TAP_PI
);
422 jtag_execute_queue();
424 status
= str9xpec_isc_status(chain_pos
);
426 for (i
= first
; i
<= last
; i
++)
428 if (buf_get_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1))
429 bank
->sectors
[i
].is_erased
= 0;
431 bank
->sectors
[i
].is_erased
= 1;
436 str9xpec_isc_disable(bank
);
438 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
439 return ERROR_FLASH_OPERATION_FAILED
;
443 int str9xpec_protect_check(struct flash_bank_s
*bank
)
448 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
450 status
= str9xpec_read_config(bank
);
452 for (i
= 0; i
< bank
->num_sectors
; i
++)
454 if (buf_get_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1))
455 bank
->sectors
[i
].is_protected
= 1;
457 bank
->sectors
[i
].is_protected
= 0;
460 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
461 return ERROR_FLASH_OPERATION_FAILED
;
465 int str9xpec_erase_area(struct flash_bank_s
*bank
, int first
, int last
)
473 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
475 chain_pos
= str9xpec_info
->chain_pos
;
477 if (!str9xpec_info
->isc_enable
) {
478 str9xpec_isc_enable( bank
);
481 if (!str9xpec_info
->isc_enable
) {
482 return ISC_STATUS_ERROR
;
485 buffer
= calloc(CEIL(64, 8), 1);
487 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first
, last
);
489 /* last bank: 0xFF signals a full erase (unlock complete device) */
490 /* last bank: 0xFE signals a option byte erase */
493 for (i
= 0; i
< 64; i
++) {
494 buf_set_u32(buffer
, i
, 1, 1);
497 else if (last
== 0xFE)
499 buf_set_u32(buffer
, 49, 1, 1);
503 for (i
= first
; i
<= last
; i
++) {
504 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
508 LOG_DEBUG("ISC_ERASE");
510 /* execute ISC_ERASE command */
511 str9xpec_set_instr(chain_pos
, ISC_ERASE
, TAP_PI
);
513 field
.device
= chain_pos
;
515 field
.out_value
= buffer
;
516 field
.out_mask
= NULL
;
517 field
.in_value
= NULL
;
518 field
.in_check_value
= NULL
;
519 field
.in_check_mask
= NULL
;
520 field
.in_handler
= NULL
;
521 field
.in_handler_priv
= NULL
;
523 jtag_add_dr_scan(1, &field
, TAP_RTI
);
524 jtag_execute_queue();
528 /* wait for erase completion */
529 while (!((status
= str9xpec_isc_status(chain_pos
)) & ISC_STATUS_BUSY
)) {
535 str9xpec_isc_disable(bank
);
540 int str9xpec_erase(struct flash_bank_s
*bank
, int first
, int last
)
544 status
= str9xpec_erase_area(bank
, first
, last
);
546 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
547 return ERROR_FLASH_OPERATION_FAILED
;
552 int str9xpec_lock_device(struct flash_bank_s
*bank
)
557 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
559 str9xpec_info
= bank
->driver_priv
;
560 chain_pos
= str9xpec_info
->chain_pos
;
562 if (!str9xpec_info
->isc_enable
) {
563 str9xpec_isc_enable( bank
);
566 if (!str9xpec_info
->isc_enable
) {
567 return ISC_STATUS_ERROR
;
570 /* set security address */
571 str9xpec_set_address(bank
, 0x80);
573 /* execute ISC_PROGRAM command */
574 str9xpec_set_instr(chain_pos
, ISC_PROGRAM_SECURITY
, TAP_RTI
);
576 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
579 field
.device
= chain_pos
;
581 field
.out_value
= NULL
;
582 field
.out_mask
= NULL
;
583 field
.in_value
= &status
;
584 field
.in_check_value
= NULL
;
585 field
.in_check_mask
= NULL
;
586 field
.in_handler
= NULL
;
587 field
.in_handler_priv
= NULL
;
589 jtag_add_dr_scan(1, &field
, -1);
590 jtag_execute_queue();
592 } while(!(status
& ISC_STATUS_BUSY
));
594 str9xpec_isc_disable(bank
);
599 int str9xpec_unlock_device(struct flash_bank_s
*bank
)
603 status
= str9xpec_erase_area(bank
, 0, 255);
608 int str9xpec_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
613 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
615 status
= str9xpec_read_config(bank
);
617 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
618 return ERROR_FLASH_OPERATION_FAILED
;
620 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first
, last
);
622 /* last bank: 0xFF signals a full device protect */
627 status
= str9xpec_lock_device(bank
);
631 /* perform full erase to unlock device */
632 status
= str9xpec_unlock_device(bank
);
637 for (i
= first
; i
<= last
; i
++)
640 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 1);
642 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 0);
645 status
= str9xpec_write_options(bank
);
648 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
649 return ERROR_FLASH_OPERATION_FAILED
;
654 int str9xpec_set_address(struct flash_bank_s
*bank
, u8 sector
)
658 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
660 chain_pos
= str9xpec_info
->chain_pos
;
662 /* set flash controller address */
663 str9xpec_set_instr(chain_pos
, ISC_ADDRESS_SHIFT
, TAP_PI
);
665 field
.device
= chain_pos
;
667 field
.out_value
= §or
;
668 field
.out_mask
= NULL
;
669 field
.in_value
= NULL
;
670 field
.in_check_value
= NULL
;
671 field
.in_check_mask
= NULL
;
672 field
.in_handler
= NULL
;
673 field
.in_handler_priv
= NULL
;
675 jtag_add_dr_scan(1, &field
, -1);
680 int str9xpec_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
682 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
683 u32 dwords_remaining
= (count
/ 8);
684 u32 bytes_remaining
= (count
& 0x00000007);
685 u32 bytes_written
= 0;
687 u32 check_address
= offset
;
692 u32 first_sector
= 0;
695 chain_pos
= str9xpec_info
->chain_pos
;
697 if (!str9xpec_info
->isc_enable
) {
698 str9xpec_isc_enable(bank
);
701 if (!str9xpec_info
->isc_enable
) {
702 return ERROR_FLASH_OPERATION_FAILED
;
707 LOG_WARNING("offset 0x%x breaks required 8-byte alignment", offset
);
708 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
711 for (i
= 0; i
< bank
->num_sectors
; i
++)
713 u32 sec_start
= bank
->sectors
[i
].offset
;
714 u32 sec_end
= sec_start
+ bank
->sectors
[i
].size
;
716 /* check if destination falls within the current sector */
717 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
719 /* check if destination ends in the current sector */
720 if (offset
+ count
< sec_end
)
721 check_address
= offset
+ count
;
723 check_address
= sec_end
;
726 if ((offset
>= sec_start
) && (offset
< sec_end
)){
730 if ((offset
+ count
>= sec_start
) && (offset
+ count
< sec_end
)){
735 if (check_address
!= offset
+ count
)
736 return ERROR_FLASH_DST_OUT_OF_BANK
;
738 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
740 scanbuf
= calloc(CEIL(64, 8), 1);
742 LOG_DEBUG("ISC_PROGRAM");
744 for (i
= first_sector
; i
<= last_sector
; i
++)
746 str9xpec_set_address(bank
, str9xpec_info
->sector_bits
[i
]);
748 dwords_remaining
= dwords_remaining
< (bank
->sectors
[i
].size
/8) ? dwords_remaining
: (bank
->sectors
[i
].size
/8);
750 while (dwords_remaining
> 0)
752 str9xpec_set_instr(chain_pos
, ISC_PROGRAM
, TAP_PI
);
754 field
.device
= chain_pos
;
756 field
.out_value
= (buffer
+ bytes_written
);
757 field
.out_mask
= NULL
;
758 field
.in_value
= NULL
;
759 field
.in_check_value
= NULL
;
760 field
.in_check_mask
= NULL
;
761 field
.in_handler
= NULL
;
762 field
.in_handler_priv
= NULL
;
764 jtag_add_dr_scan(1, &field
, TAP_RTI
);
766 /* small delay before polling */
769 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
772 field
.device
= chain_pos
;
774 field
.out_value
= NULL
;
775 field
.out_mask
= NULL
;
776 field
.in_value
= scanbuf
;
777 field
.in_check_value
= NULL
;
778 field
.in_check_mask
= NULL
;
779 field
.in_handler
= NULL
;
780 field
.in_handler_priv
= NULL
;
782 jtag_add_dr_scan(1, &field
, -1);
783 jtag_execute_queue();
785 status
= buf_get_u32(scanbuf
, 0, 8);
787 } while(!(status
& ISC_STATUS_BUSY
));
789 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
790 return ERROR_FLASH_OPERATION_FAILED
;
792 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
793 return ERROR_FLASH_OPERATION_FAILED; */
802 u8 last_dword
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
805 while(bytes_remaining
> 0)
807 last_dword
[i
++] = *(buffer
+ bytes_written
);
812 str9xpec_set_instr(chain_pos
, ISC_PROGRAM
, TAP_PI
);
814 field
.device
= chain_pos
;
816 field
.out_value
= last_dword
;
817 field
.out_mask
= NULL
;
818 field
.in_value
= NULL
;
819 field
.in_check_value
= NULL
;
820 field
.in_check_mask
= NULL
;
821 field
.in_handler
= NULL
;
822 field
.in_handler_priv
= NULL
;
824 jtag_add_dr_scan(1, &field
, TAP_RTI
);
826 /* small delay before polling */
829 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
832 field
.device
= chain_pos
;
834 field
.out_value
= NULL
;
835 field
.out_mask
= NULL
;
836 field
.in_value
= scanbuf
;
837 field
.in_check_value
= NULL
;
838 field
.in_check_mask
= NULL
;
839 field
.in_handler
= NULL
;
840 field
.in_handler_priv
= NULL
;
842 jtag_add_dr_scan(1, &field
, -1);
843 jtag_execute_queue();
845 status
= buf_get_u32(scanbuf
, 0, 8);
847 } while(!(status
& ISC_STATUS_BUSY
));
849 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
850 return ERROR_FLASH_OPERATION_FAILED
;
852 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
853 return ERROR_FLASH_OPERATION_FAILED; */
858 str9xpec_isc_disable(bank
);
863 int str9xpec_probe(struct flash_bank_s
*bank
)
868 int str9xpec_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
875 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
879 return ERROR_COMMAND_SYNTAX_ERROR
;
882 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
885 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
889 str9xpec_info
= bank
->driver_priv
;
890 chain_pos
= str9xpec_info
->chain_pos
;
892 buffer
= calloc(CEIL(32, 8), 1);
894 str9xpec_set_instr(chain_pos
, ISC_IDCODE
, TAP_PI
);
896 field
.device
= chain_pos
;
898 field
.out_value
= NULL
;
899 field
.out_mask
= NULL
;
900 field
.in_value
= buffer
;
901 field
.in_check_value
= NULL
;
902 field
.in_check_mask
= NULL
;
903 field
.in_handler
= NULL
;
904 field
.in_handler_priv
= NULL
;
906 jtag_add_dr_scan(1, &field
, TAP_RTI
);
907 jtag_execute_queue();
909 idcode
= buf_get_u32(buffer
, 0, 32);
911 command_print(cmd_ctx
, "str9xpec part id: 0x%8.8x", idcode
);
918 int str9xpec_erase_check(struct flash_bank_s
*bank
)
920 return str9xpec_blank_check(bank
, 0, bank
->num_sectors
- 1);
923 int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
925 snprintf(buf
, buf_size
, "str9xpec flash driver info" );
929 int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
933 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
937 command_print(cmd_ctx
, "str9xpec options_read <bank>");
941 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
944 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
948 str9xpec_info
= bank
->driver_priv
;
950 status
= str9xpec_read_config(bank
);
952 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
953 return ERROR_FLASH_OPERATION_FAILED
;
956 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1))
957 command_print(cmd_ctx
, "CS Map: bank1");
959 command_print(cmd_ctx
, "CS Map: bank0");
962 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_OTPBIT
, 1))
963 command_print(cmd_ctx
, "OTP Lock: OTP Locked");
965 command_print(cmd_ctx
, "OTP Lock: OTP Unlocked");
968 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1))
969 command_print(cmd_ctx
, "LVD Threshold: 2.7v");
971 command_print(cmd_ctx
, "LVD Threshold: 2.4v");
973 /* LVD reset warning */
974 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1))
975 command_print(cmd_ctx
, "LVD Reset Warning: VDD or VDDQ Inputs");
977 command_print(cmd_ctx
, "LVD Reset Warning: VDD Input Only");
979 /* LVD reset select */
980 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1))
981 command_print(cmd_ctx
, "LVD Reset Selection: VDD or VDDQ Inputs");
983 command_print(cmd_ctx
, "LVD Reset Selection: VDD Input Only");
988 int str9xpec_write_options(struct flash_bank_s
*bank
)
993 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
995 str9xpec_info
= bank
->driver_priv
;
996 chain_pos
= str9xpec_info
->chain_pos
;
998 /* erase config options first */
999 status
= str9xpec_erase_area( bank
, 0xFE, 0xFE );
1001 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1004 if (!str9xpec_info
->isc_enable
) {
1005 str9xpec_isc_enable( bank
);
1008 if (!str9xpec_info
->isc_enable
) {
1009 return ISC_STATUS_ERROR
;
1012 /* according to data 64th bit has to be set */
1013 buf_set_u32(str9xpec_info
->options
, 63, 1, 1);
1015 /* set option byte address */
1016 str9xpec_set_address(bank
, 0x50);
1018 /* execute ISC_PROGRAM command */
1019 str9xpec_set_instr(chain_pos
, ISC_PROGRAM
, TAP_PI
);
1021 field
.device
= chain_pos
;
1022 field
.num_bits
= 64;
1023 field
.out_value
= str9xpec_info
->options
;
1024 field
.out_mask
= NULL
;
1025 field
.in_value
= NULL
;
1026 field
.in_check_value
= NULL
;
1027 field
.in_check_mask
= NULL
;
1028 field
.in_handler
= NULL
;
1029 field
.in_handler_priv
= NULL
;
1031 jtag_add_dr_scan(1, &field
, TAP_RTI
);
1033 /* small delay before polling */
1036 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
1039 field
.device
= chain_pos
;
1041 field
.out_value
= NULL
;
1042 field
.out_mask
= NULL
;
1043 field
.in_value
= &status
;
1044 field
.in_check_value
= NULL
;
1045 field
.in_check_mask
= NULL
;
1046 field
.in_handler
= NULL
;
1047 field
.in_handler_priv
= NULL
;
1049 jtag_add_dr_scan(1, &field
, -1);
1050 jtag_execute_queue();
1052 } while(!(status
& ISC_STATUS_BUSY
));
1054 str9xpec_isc_disable(bank
);
1059 int str9xpec_handle_flash_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1066 command_print(cmd_ctx
, "str9xpec options_write <bank>");
1070 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1073 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1077 status
= str9xpec_write_options(bank
);
1079 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1080 return ERROR_FLASH_OPERATION_FAILED
;
1085 int str9xpec_handle_flash_options_cmap_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1088 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1092 command_print(cmd_ctx
, "str9xpec options_cmap <bank> <bank0|bank1>");
1096 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1099 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1103 str9xpec_info
= bank
->driver_priv
;
1105 if (strcmp(args
[1], "bank1") == 0)
1107 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 1);
1111 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 0);
1117 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1120 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1124 command_print(cmd_ctx
, "str9xpec options_lvdthd <bank> <2.4v|2.7v>");
1128 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1131 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1135 str9xpec_info
= bank
->driver_priv
;
1137 if (strcmp(args
[1], "2.7v") == 0)
1139 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 1);
1143 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 0);
1149 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1152 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1156 command_print(cmd_ctx
, "str9xpec options_lvdsel <bank> <vdd|vdd_vddq>");
1160 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1163 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1167 str9xpec_info
= bank
->driver_priv
;
1169 if (strcmp(args
[1], "vdd_vddq") == 0)
1171 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 1);
1175 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 0);
1181 int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1184 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1188 command_print(cmd_ctx
, "str9xpec options_lvdwarn <bank> <vdd|vdd_vddq>");
1192 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1195 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1199 str9xpec_info
= bank
->driver_priv
;
1201 if (strcmp(args
[1], "vdd_vddq") == 0)
1203 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 1);
1207 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 0);
1213 int str9xpec_handle_flash_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1220 command_print(cmd_ctx
, "str9xpec lock <bank>");
1224 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1227 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1231 status
= str9xpec_lock_device(bank
);
1233 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1234 return ERROR_FLASH_OPERATION_FAILED
;
1239 int str9xpec_handle_flash_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1246 command_print(cmd_ctx
, "str9xpec unlock <bank>");
1250 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1253 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1257 status
= str9xpec_unlock_device(bank
);
1259 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1260 return ERROR_FLASH_OPERATION_FAILED
;
1265 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1269 jtag_device_t
* dev0
;
1270 jtag_device_t
* dev2
;
1271 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1275 command_print(cmd_ctx
, "str9xpec enable_turbo <bank>");
1279 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1282 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1286 str9xpec_info
= bank
->driver_priv
;
1288 chain_pos
= str9xpec_info
->chain_pos
;
1290 /* remove arm core from chain - enter turbo mode */
1292 str9xpec_set_instr(chain_pos
+2, 0xD, TAP_RTI
);
1293 jtag_execute_queue();
1295 /* modify scan chain - str9 core has been removed */
1296 dev0
= jtag_get_device(chain_pos
);
1297 str9xpec_info
->devarm
= jtag_get_device(chain_pos
+1);
1298 dev2
= jtag_get_device(chain_pos
+2);
1305 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1309 jtag_device_t
* dev0
;
1310 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1314 command_print(cmd_ctx
, "str9xpec disable_turbo <bank>");
1318 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1321 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1325 str9xpec_info
= bank
->driver_priv
;
1327 chain_pos
= str9xpec_info
->chain_pos
;
1329 dev0
= jtag_get_device(chain_pos
);
1331 /* exit turbo mode via TLR */
1332 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_TLR
);
1333 jtag_execute_queue();
1335 /* restore previous scan chain */
1336 if( str9xpec_info
->devarm
) {
1337 dev0
->next
= str9xpec_info
->devarm
;
1339 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)