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