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
);
120 LOG_DEBUG("Invalid Target");
121 return ERROR_TARGET_INVALID
;
124 if (buf_get_u32(device
->cur_instr
, 0, device
->ir_length
) != new_instr
)
128 field
.device
= chain_pos
;
129 field
.num_bits
= device
->ir_length
;
130 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
131 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
132 field
.out_mask
= NULL
;
133 field
.in_value
= NULL
;
134 field
.in_check_value
= NULL
;
135 field
.in_check_mask
= NULL
;
136 field
.in_handler
= NULL
;
137 field
.in_handler_priv
= NULL
;
139 jtag_add_ir_scan(1, &field
, end_state
);
141 free(field
.out_value
);
147 u8
str9xpec_isc_status(int chain_pos
)
152 if (str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
) != ERROR_OK
)
153 return ISC_STATUS_ERROR
;
155 field
.device
= chain_pos
;
157 field
.out_value
= NULL
;
158 field
.out_mask
= NULL
;
159 field
.in_value
= &status
;
160 field
.in_check_value
= NULL
;
161 field
.in_check_mask
= NULL
;
162 field
.in_handler
= NULL
;
163 field
.in_handler_priv
= NULL
;
165 jtag_add_dr_scan(1, &field
, TAP_RTI
);
166 jtag_execute_queue();
168 LOG_DEBUG("status: 0x%2.2x", status
);
170 if (status
& ISC_STATUS_SECURITY
)
171 LOG_INFO("Device Security Bit Set");
176 int str9xpec_isc_enable(struct flash_bank_s
*bank
)
180 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
182 chain_pos
= str9xpec_info
->chain_pos
;
184 if (str9xpec_info
->isc_enable
)
188 if (str9xpec_set_instr(chain_pos
, ISC_ENABLE
, TAP_RTI
) != ERROR_OK
)
189 return ERROR_TARGET_INVALID
;
191 /* check ISC status */
192 status
= str9xpec_isc_status(chain_pos
);
193 if (status
& ISC_STATUS_MODE
)
195 /* we have entered isc mode */
196 str9xpec_info
->isc_enable
= 1;
197 LOG_DEBUG("ISC_MODE Enabled");
203 int str9xpec_isc_disable(struct flash_bank_s
*bank
)
207 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
209 chain_pos
= str9xpec_info
->chain_pos
;
211 if (!str9xpec_info
->isc_enable
)
214 if (str9xpec_set_instr(chain_pos
, ISC_DISABLE
, TAP_RTI
) != ERROR_OK
)
215 return ERROR_TARGET_INVALID
;
217 /* delay to handle aborts */
220 /* check ISC status */
221 status
= str9xpec_isc_status(chain_pos
);
222 if (!(status
& ISC_STATUS_MODE
))
224 /* we have left isc mode */
225 str9xpec_info
->isc_enable
= 0;
226 LOG_DEBUG("ISC_MODE Disabled");
232 int str9xpec_read_config(struct flash_bank_s
*bank
)
238 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
240 chain_pos
= str9xpec_info
->chain_pos
;
242 LOG_DEBUG("ISC_CONFIGURATION");
244 /* execute ISC_CONFIGURATION command */
245 str9xpec_set_instr(chain_pos
, ISC_CONFIGURATION
, TAP_PI
);
247 field
.device
= chain_pos
;
249 field
.out_value
= NULL
;
250 field
.out_mask
= NULL
;
251 field
.in_value
= str9xpec_info
->options
;
252 field
.in_check_value
= NULL
;
253 field
.in_check_mask
= NULL
;
254 field
.in_handler
= NULL
;
255 field
.in_handler_priv
= NULL
;
257 jtag_add_dr_scan(1, &field
, TAP_RTI
);
258 jtag_execute_queue();
260 status
= str9xpec_isc_status(chain_pos
);
265 int str9xpec_build_block_list(struct flash_bank_s
*bank
)
267 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
271 int b0_sectors
= 0, b1_sectors
= 0;
273 int b1_size
= 0x2000;
297 LOG_ERROR("BUG: unknown bank->size encountered");
301 num_sectors
= b0_sectors
+ b1_sectors
;
303 bank
->num_sectors
= num_sectors
;
304 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
305 str9xpec_info
->sector_bits
= malloc(sizeof(u32
) * num_sectors
);
309 for (i
= 0; i
< b0_sectors
; i
++)
311 bank
->sectors
[num_sectors
].offset
= offset
;
312 bank
->sectors
[num_sectors
].size
= 0x10000;
313 offset
+= bank
->sectors
[i
].size
;
314 bank
->sectors
[num_sectors
].is_erased
= -1;
315 bank
->sectors
[num_sectors
].is_protected
= 1;
316 str9xpec_info
->sector_bits
[num_sectors
++] = i
;
319 for (i
= 0; i
< b1_sectors
; i
++)
321 bank
->sectors
[num_sectors
].offset
= offset
;
322 bank
->sectors
[num_sectors
].size
= b1_size
;
323 offset
+= bank
->sectors
[i
].size
;
324 bank
->sectors
[num_sectors
].is_erased
= -1;
325 bank
->sectors
[num_sectors
].is_protected
= 1;
326 str9xpec_info
->sector_bits
[num_sectors
++] = i
+ 32;
332 /* flash bank str9x <base> <size> 0 0 <target#>
334 int str9xpec_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
336 str9xpec_flash_controller_t
*str9xpec_info
;
337 armv4_5_common_t
*armv4_5
= NULL
;
338 arm7_9_common_t
*arm7_9
= NULL
;
339 arm_jtag_t
*jtag_info
= NULL
;
343 LOG_WARNING("incomplete flash_bank str9x configuration");
344 return ERROR_FLASH_BANK_INVALID
;
347 str9xpec_info
= malloc(sizeof(str9xpec_flash_controller_t
));
348 bank
->driver_priv
= str9xpec_info
;
350 /* find out jtag position of flash controller
351 * it is always after the arm966 core */
353 armv4_5
= bank
->target
->arch_info
;
354 arm7_9
= armv4_5
->arch_info
;
355 jtag_info
= &arm7_9
->jtag_info
;
357 str9xpec_info
->chain_pos
= (jtag_info
->chain_pos
- 1);
358 str9xpec_info
->isc_enable
= 0;
359 str9xpec_info
->devarm
= NULL
;
361 str9xpec_build_block_list(bank
);
363 /* clear option byte register */
364 buf_set_u32(str9xpec_info
->options
, 0, 64, 0);
369 int str9xpec_blank_check(struct flash_bank_s
*bank
, int first
, int last
)
377 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
379 chain_pos
= str9xpec_info
->chain_pos
;
381 if (!str9xpec_info
->isc_enable
) {
382 str9xpec_isc_enable( bank
);
385 if (!str9xpec_info
->isc_enable
) {
386 return ERROR_FLASH_OPERATION_FAILED
;
389 buffer
= calloc(CEIL(64, 8), 1);
391 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first
, last
);
393 for (i
= first
; i
<= last
; i
++) {
394 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
397 /* execute ISC_BLANK_CHECK command */
398 str9xpec_set_instr(chain_pos
, ISC_BLANK_CHECK
, TAP_PI
);
400 field
.device
= chain_pos
;
402 field
.out_value
= buffer
;
403 field
.out_mask
= NULL
;
404 field
.in_value
= NULL
;
405 field
.in_check_value
= NULL
;
406 field
.in_check_mask
= NULL
;
407 field
.in_handler
= NULL
;
408 field
.in_handler_priv
= NULL
;
410 jtag_add_dr_scan(1, &field
, TAP_RTI
);
411 jtag_add_sleep(40000);
413 /* read blank check result */
414 field
.device
= chain_pos
;
416 field
.out_value
= NULL
;
417 field
.out_mask
= NULL
;
418 field
.in_value
= buffer
;
419 field
.in_check_value
= NULL
;
420 field
.in_check_mask
= NULL
;
421 field
.in_handler
= NULL
;
422 field
.in_handler_priv
= NULL
;
424 jtag_add_dr_scan(1, &field
, TAP_PI
);
425 jtag_execute_queue();
427 status
= str9xpec_isc_status(chain_pos
);
429 for (i
= first
; i
<= last
; i
++)
431 if (buf_get_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1))
432 bank
->sectors
[i
].is_erased
= 0;
434 bank
->sectors
[i
].is_erased
= 1;
439 str9xpec_isc_disable(bank
);
441 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
442 return ERROR_FLASH_OPERATION_FAILED
;
446 int str9xpec_protect_check(struct flash_bank_s
*bank
)
451 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
453 status
= str9xpec_read_config(bank
);
455 for (i
= 0; i
< bank
->num_sectors
; i
++)
457 if (buf_get_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1))
458 bank
->sectors
[i
].is_protected
= 1;
460 bank
->sectors
[i
].is_protected
= 0;
463 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
464 return ERROR_FLASH_OPERATION_FAILED
;
468 int str9xpec_erase_area(struct flash_bank_s
*bank
, int first
, int last
)
476 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
478 chain_pos
= str9xpec_info
->chain_pos
;
480 if (!str9xpec_info
->isc_enable
) {
481 str9xpec_isc_enable( bank
);
484 if (!str9xpec_info
->isc_enable
) {
485 return ISC_STATUS_ERROR
;
488 buffer
= calloc(CEIL(64, 8), 1);
490 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first
, last
);
492 /* last bank: 0xFF signals a full erase (unlock complete device) */
493 /* last bank: 0xFE signals a option byte erase */
496 for (i
= 0; i
< 64; i
++) {
497 buf_set_u32(buffer
, i
, 1, 1);
500 else if (last
== 0xFE)
502 buf_set_u32(buffer
, 49, 1, 1);
506 for (i
= first
; i
<= last
; i
++) {
507 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
511 LOG_DEBUG("ISC_ERASE");
513 /* execute ISC_ERASE command */
514 str9xpec_set_instr(chain_pos
, ISC_ERASE
, TAP_PI
);
516 field
.device
= chain_pos
;
518 field
.out_value
= buffer
;
519 field
.out_mask
= NULL
;
520 field
.in_value
= NULL
;
521 field
.in_check_value
= NULL
;
522 field
.in_check_mask
= NULL
;
523 field
.in_handler
= NULL
;
524 field
.in_handler_priv
= NULL
;
526 jtag_add_dr_scan(1, &field
, TAP_RTI
);
527 jtag_execute_queue();
531 /* wait for erase completion */
532 while (!((status
= str9xpec_isc_status(chain_pos
)) & ISC_STATUS_BUSY
)) {
538 str9xpec_isc_disable(bank
);
543 int str9xpec_erase(struct flash_bank_s
*bank
, int first
, int last
)
547 status
= str9xpec_erase_area(bank
, first
, last
);
549 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
550 return ERROR_FLASH_OPERATION_FAILED
;
555 int str9xpec_lock_device(struct flash_bank_s
*bank
)
560 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
562 str9xpec_info
= bank
->driver_priv
;
563 chain_pos
= str9xpec_info
->chain_pos
;
565 if (!str9xpec_info
->isc_enable
) {
566 str9xpec_isc_enable( bank
);
569 if (!str9xpec_info
->isc_enable
) {
570 return ISC_STATUS_ERROR
;
573 /* set security address */
574 str9xpec_set_address(bank
, 0x80);
576 /* execute ISC_PROGRAM command */
577 str9xpec_set_instr(chain_pos
, ISC_PROGRAM_SECURITY
, TAP_RTI
);
579 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
582 field
.device
= chain_pos
;
584 field
.out_value
= NULL
;
585 field
.out_mask
= NULL
;
586 field
.in_value
= &status
;
587 field
.in_check_value
= NULL
;
588 field
.in_check_mask
= NULL
;
589 field
.in_handler
= NULL
;
590 field
.in_handler_priv
= NULL
;
592 jtag_add_dr_scan(1, &field
, -1);
593 jtag_execute_queue();
595 } while(!(status
& ISC_STATUS_BUSY
));
597 str9xpec_isc_disable(bank
);
602 int str9xpec_unlock_device(struct flash_bank_s
*bank
)
606 status
= str9xpec_erase_area(bank
, 0, 255);
611 int str9xpec_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
616 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
618 status
= str9xpec_read_config(bank
);
620 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
621 return ERROR_FLASH_OPERATION_FAILED
;
623 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first
, last
);
625 /* last bank: 0xFF signals a full device protect */
630 status
= str9xpec_lock_device(bank
);
634 /* perform full erase to unlock device */
635 status
= str9xpec_unlock_device(bank
);
640 for (i
= first
; i
<= last
; i
++)
643 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 1);
645 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 0);
648 status
= str9xpec_write_options(bank
);
651 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
652 return ERROR_FLASH_OPERATION_FAILED
;
657 int str9xpec_set_address(struct flash_bank_s
*bank
, u8 sector
)
661 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
663 chain_pos
= str9xpec_info
->chain_pos
;
665 /* set flash controller address */
666 str9xpec_set_instr(chain_pos
, ISC_ADDRESS_SHIFT
, TAP_PI
);
668 field
.device
= chain_pos
;
670 field
.out_value
= §or
;
671 field
.out_mask
= NULL
;
672 field
.in_value
= NULL
;
673 field
.in_check_value
= NULL
;
674 field
.in_check_mask
= NULL
;
675 field
.in_handler
= NULL
;
676 field
.in_handler_priv
= NULL
;
678 jtag_add_dr_scan(1, &field
, -1);
683 int str9xpec_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
)
685 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
686 u32 dwords_remaining
= (count
/ 8);
687 u32 bytes_remaining
= (count
& 0x00000007);
688 u32 bytes_written
= 0;
690 u32 check_address
= offset
;
695 u32 first_sector
= 0;
698 chain_pos
= str9xpec_info
->chain_pos
;
700 if (!str9xpec_info
->isc_enable
) {
701 str9xpec_isc_enable(bank
);
704 if (!str9xpec_info
->isc_enable
) {
705 return ERROR_FLASH_OPERATION_FAILED
;
710 LOG_WARNING("offset 0x%x breaks required 8-byte alignment", offset
);
711 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
714 for (i
= 0; i
< bank
->num_sectors
; i
++)
716 u32 sec_start
= bank
->sectors
[i
].offset
;
717 u32 sec_end
= sec_start
+ bank
->sectors
[i
].size
;
719 /* check if destination falls within the current sector */
720 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
722 /* check if destination ends in the current sector */
723 if (offset
+ count
< sec_end
)
724 check_address
= offset
+ count
;
726 check_address
= sec_end
;
729 if ((offset
>= sec_start
) && (offset
< sec_end
)){
733 if ((offset
+ count
>= sec_start
) && (offset
+ count
< sec_end
)){
738 if (check_address
!= offset
+ count
)
739 return ERROR_FLASH_DST_OUT_OF_BANK
;
741 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
743 scanbuf
= calloc(CEIL(64, 8), 1);
745 LOG_DEBUG("ISC_PROGRAM");
747 for (i
= first_sector
; i
<= last_sector
; i
++)
749 str9xpec_set_address(bank
, str9xpec_info
->sector_bits
[i
]);
751 dwords_remaining
= dwords_remaining
< (bank
->sectors
[i
].size
/8) ? dwords_remaining
: (bank
->sectors
[i
].size
/8);
753 while (dwords_remaining
> 0)
755 str9xpec_set_instr(chain_pos
, ISC_PROGRAM
, TAP_PI
);
757 field
.device
= chain_pos
;
759 field
.out_value
= (buffer
+ bytes_written
);
760 field
.out_mask
= NULL
;
761 field
.in_value
= NULL
;
762 field
.in_check_value
= NULL
;
763 field
.in_check_mask
= NULL
;
764 field
.in_handler
= NULL
;
765 field
.in_handler_priv
= NULL
;
767 jtag_add_dr_scan(1, &field
, TAP_RTI
);
769 /* small delay before polling */
772 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
775 field
.device
= chain_pos
;
777 field
.out_value
= NULL
;
778 field
.out_mask
= NULL
;
779 field
.in_value
= scanbuf
;
780 field
.in_check_value
= NULL
;
781 field
.in_check_mask
= NULL
;
782 field
.in_handler
= NULL
;
783 field
.in_handler_priv
= NULL
;
785 jtag_add_dr_scan(1, &field
, -1);
786 jtag_execute_queue();
788 status
= buf_get_u32(scanbuf
, 0, 8);
790 } while(!(status
& ISC_STATUS_BUSY
));
792 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
793 return ERROR_FLASH_OPERATION_FAILED
;
795 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
796 return ERROR_FLASH_OPERATION_FAILED; */
805 u8 last_dword
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
808 while(bytes_remaining
> 0)
810 last_dword
[i
++] = *(buffer
+ bytes_written
);
815 str9xpec_set_instr(chain_pos
, ISC_PROGRAM
, TAP_PI
);
817 field
.device
= chain_pos
;
819 field
.out_value
= last_dword
;
820 field
.out_mask
= NULL
;
821 field
.in_value
= NULL
;
822 field
.in_check_value
= NULL
;
823 field
.in_check_mask
= NULL
;
824 field
.in_handler
= NULL
;
825 field
.in_handler_priv
= NULL
;
827 jtag_add_dr_scan(1, &field
, TAP_RTI
);
829 /* small delay before polling */
832 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
835 field
.device
= chain_pos
;
837 field
.out_value
= NULL
;
838 field
.out_mask
= NULL
;
839 field
.in_value
= scanbuf
;
840 field
.in_check_value
= NULL
;
841 field
.in_check_mask
= NULL
;
842 field
.in_handler
= NULL
;
843 field
.in_handler_priv
= NULL
;
845 jtag_add_dr_scan(1, &field
, -1);
846 jtag_execute_queue();
848 status
= buf_get_u32(scanbuf
, 0, 8);
850 } while(!(status
& ISC_STATUS_BUSY
));
852 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
853 return ERROR_FLASH_OPERATION_FAILED
;
855 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
856 return ERROR_FLASH_OPERATION_FAILED; */
861 str9xpec_isc_disable(bank
);
866 int str9xpec_probe(struct flash_bank_s
*bank
)
871 int str9xpec_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
878 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
882 return ERROR_COMMAND_SYNTAX_ERROR
;
885 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
888 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
892 str9xpec_info
= bank
->driver_priv
;
893 chain_pos
= str9xpec_info
->chain_pos
;
895 buffer
= calloc(CEIL(32, 8), 1);
897 str9xpec_set_instr(chain_pos
, ISC_IDCODE
, TAP_PI
);
899 field
.device
= chain_pos
;
901 field
.out_value
= NULL
;
902 field
.out_mask
= NULL
;
903 field
.in_value
= buffer
;
904 field
.in_check_value
= NULL
;
905 field
.in_check_mask
= NULL
;
906 field
.in_handler
= NULL
;
907 field
.in_handler_priv
= NULL
;
909 jtag_add_dr_scan(1, &field
, TAP_RTI
);
910 jtag_execute_queue();
912 idcode
= buf_get_u32(buffer
, 0, 32);
914 command_print(cmd_ctx
, "str9xpec part id: 0x%8.8x", idcode
);
921 int str9xpec_erase_check(struct flash_bank_s
*bank
)
923 return str9xpec_blank_check(bank
, 0, bank
->num_sectors
- 1);
926 int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
928 snprintf(buf
, buf_size
, "str9xpec flash driver info" );
932 int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
936 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
940 command_print(cmd_ctx
, "str9xpec options_read <bank>");
944 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
947 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
951 str9xpec_info
= bank
->driver_priv
;
953 status
= str9xpec_read_config(bank
);
955 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
956 return ERROR_FLASH_OPERATION_FAILED
;
959 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1))
960 command_print(cmd_ctx
, "CS Map: bank1");
962 command_print(cmd_ctx
, "CS Map: bank0");
965 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_OTPBIT
, 1))
966 command_print(cmd_ctx
, "OTP Lock: OTP Locked");
968 command_print(cmd_ctx
, "OTP Lock: OTP Unlocked");
971 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1))
972 command_print(cmd_ctx
, "LVD Threshold: 2.7v");
974 command_print(cmd_ctx
, "LVD Threshold: 2.4v");
976 /* LVD reset warning */
977 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1))
978 command_print(cmd_ctx
, "LVD Reset Warning: VDD or VDDQ Inputs");
980 command_print(cmd_ctx
, "LVD Reset Warning: VDD Input Only");
982 /* LVD reset select */
983 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1))
984 command_print(cmd_ctx
, "LVD Reset Selection: VDD or VDDQ Inputs");
986 command_print(cmd_ctx
, "LVD Reset Selection: VDD Input Only");
991 int str9xpec_write_options(struct flash_bank_s
*bank
)
996 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
998 str9xpec_info
= bank
->driver_priv
;
999 chain_pos
= str9xpec_info
->chain_pos
;
1001 /* erase config options first */
1002 status
= str9xpec_erase_area( bank
, 0xFE, 0xFE );
1004 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1007 if (!str9xpec_info
->isc_enable
) {
1008 str9xpec_isc_enable( bank
);
1011 if (!str9xpec_info
->isc_enable
) {
1012 return ISC_STATUS_ERROR
;
1015 /* according to data 64th bit has to be set */
1016 buf_set_u32(str9xpec_info
->options
, 63, 1, 1);
1018 /* set option byte address */
1019 str9xpec_set_address(bank
, 0x50);
1021 /* execute ISC_PROGRAM command */
1022 str9xpec_set_instr(chain_pos
, ISC_PROGRAM
, TAP_PI
);
1024 field
.device
= chain_pos
;
1025 field
.num_bits
= 64;
1026 field
.out_value
= str9xpec_info
->options
;
1027 field
.out_mask
= NULL
;
1028 field
.in_value
= NULL
;
1029 field
.in_check_value
= NULL
;
1030 field
.in_check_mask
= NULL
;
1031 field
.in_handler
= NULL
;
1032 field
.in_handler_priv
= NULL
;
1034 jtag_add_dr_scan(1, &field
, TAP_RTI
);
1036 /* small delay before polling */
1039 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
1042 field
.device
= chain_pos
;
1044 field
.out_value
= NULL
;
1045 field
.out_mask
= NULL
;
1046 field
.in_value
= &status
;
1047 field
.in_check_value
= NULL
;
1048 field
.in_check_mask
= NULL
;
1049 field
.in_handler
= NULL
;
1050 field
.in_handler_priv
= NULL
;
1052 jtag_add_dr_scan(1, &field
, -1);
1053 jtag_execute_queue();
1055 } while(!(status
& ISC_STATUS_BUSY
));
1057 str9xpec_isc_disable(bank
);
1062 int str9xpec_handle_flash_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1069 command_print(cmd_ctx
, "str9xpec options_write <bank>");
1073 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1076 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1080 status
= str9xpec_write_options(bank
);
1082 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1083 return ERROR_FLASH_OPERATION_FAILED
;
1088 int str9xpec_handle_flash_options_cmap_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1091 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1095 command_print(cmd_ctx
, "str9xpec options_cmap <bank> <bank0|bank1>");
1099 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1102 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1106 str9xpec_info
= bank
->driver_priv
;
1108 if (strcmp(args
[1], "bank1") == 0)
1110 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 1);
1114 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 0);
1120 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1123 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1127 command_print(cmd_ctx
, "str9xpec options_lvdthd <bank> <2.4v|2.7v>");
1131 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1134 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1138 str9xpec_info
= bank
->driver_priv
;
1140 if (strcmp(args
[1], "2.7v") == 0)
1142 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 1);
1146 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 0);
1152 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1155 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1159 command_print(cmd_ctx
, "str9xpec options_lvdsel <bank> <vdd|vdd_vddq>");
1163 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1166 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1170 str9xpec_info
= bank
->driver_priv
;
1172 if (strcmp(args
[1], "vdd_vddq") == 0)
1174 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 1);
1178 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 0);
1184 int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1187 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1191 command_print(cmd_ctx
, "str9xpec options_lvdwarn <bank> <vdd|vdd_vddq>");
1195 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1198 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1202 str9xpec_info
= bank
->driver_priv
;
1204 if (strcmp(args
[1], "vdd_vddq") == 0)
1206 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 1);
1210 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 0);
1216 int str9xpec_handle_flash_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1223 command_print(cmd_ctx
, "str9xpec lock <bank>");
1227 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1230 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1234 status
= str9xpec_lock_device(bank
);
1236 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1237 return ERROR_FLASH_OPERATION_FAILED
;
1242 int str9xpec_handle_flash_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1249 command_print(cmd_ctx
, "str9xpec unlock <bank>");
1253 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1256 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1260 status
= str9xpec_unlock_device(bank
);
1262 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1263 return ERROR_FLASH_OPERATION_FAILED
;
1268 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1272 jtag_device_t
* dev0
;
1273 jtag_device_t
* dev2
;
1274 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1278 command_print(cmd_ctx
, "str9xpec enable_turbo <bank>");
1282 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1285 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1289 str9xpec_info
= bank
->driver_priv
;
1291 chain_pos
= str9xpec_info
->chain_pos
;
1293 /* remove arm core from chain - enter turbo mode */
1295 str9xpec_set_instr(chain_pos
+2, 0xD, TAP_RTI
);
1296 jtag_execute_queue();
1298 /* modify scan chain - str9 core has been removed */
1299 dev0
= jtag_get_device(chain_pos
);
1300 str9xpec_info
->devarm
= jtag_get_device(chain_pos
+1);
1301 dev2
= jtag_get_device(chain_pos
+2);
1308 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1312 jtag_device_t
* dev0
;
1313 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1317 command_print(cmd_ctx
, "str9xpec disable_turbo <bank>");
1321 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1324 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1328 str9xpec_info
= bank
->driver_priv
;
1330 chain_pos
= str9xpec_info
->chain_pos
;
1332 dev0
= jtag_get_device(chain_pos
);
1334 /* exit turbo mode via TLR */
1335 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_TLR
);
1336 jtag_execute_queue();
1338 /* restore previous scan chain */
1339 if( str9xpec_info
->devarm
) {
1340 dev0
->next
= str9xpec_info
->devarm
;
1342 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)