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 ***************************************************************************/
28 #include "arm7_9_common.h"
31 static int str9xpec_erase_area(struct flash_bank_s
*bank
, int first
, int last
);
32 static int str9xpec_set_address(struct flash_bank_s
*bank
, uint8_t sector
);
33 static int str9xpec_write_options(struct flash_bank_s
*bank
);
35 int str9xpec_set_instr(jtag_tap_t
*tap
, uint32_t new_instr
, tap_state_t end_state
)
38 return ERROR_TARGET_INVALID
;
41 if (buf_get_u32(tap
->cur_instr
, 0, tap
->ir_length
) != new_instr
)
46 field
.num_bits
= tap
->ir_length
;
47 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
48 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
49 field
.in_value
= NULL
;
51 jtag_add_ir_scan(1, &field
, end_state
);
53 free(field
.out_value
);
59 static uint8_t str9xpec_isc_status(jtag_tap_t
*tap
)
64 if (str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
) != ERROR_OK
)
65 return ISC_STATUS_ERROR
;
69 field
.out_value
= NULL
;
70 field
.in_value
= &status
;
73 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
76 LOG_DEBUG("status: 0x%2.2x", status
);
78 if (status
& ISC_STATUS_SECURITY
)
79 LOG_INFO("Device Security Bit Set");
84 static int str9xpec_isc_enable(struct flash_bank_s
*bank
)
88 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
90 tap
= str9xpec_info
->tap
;
92 if (str9xpec_info
->isc_enable
)
96 if (str9xpec_set_instr(tap
, ISC_ENABLE
, TAP_IDLE
) != ERROR_OK
)
97 return ERROR_TARGET_INVALID
;
99 /* check ISC status */
100 status
= str9xpec_isc_status(tap
);
101 if (status
& ISC_STATUS_MODE
)
103 /* we have entered isc mode */
104 str9xpec_info
->isc_enable
= 1;
105 LOG_DEBUG("ISC_MODE Enabled");
111 static int str9xpec_isc_disable(struct flash_bank_s
*bank
)
115 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
117 tap
= str9xpec_info
->tap
;
119 if (!str9xpec_info
->isc_enable
)
122 if (str9xpec_set_instr(tap
, ISC_DISABLE
, TAP_IDLE
) != ERROR_OK
)
123 return ERROR_TARGET_INVALID
;
125 /* delay to handle aborts */
128 /* check ISC status */
129 status
= str9xpec_isc_status(tap
);
130 if (!(status
& ISC_STATUS_MODE
))
132 /* we have left isc mode */
133 str9xpec_info
->isc_enable
= 0;
134 LOG_DEBUG("ISC_MODE Disabled");
140 static int str9xpec_read_config(struct flash_bank_s
*bank
)
146 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
148 tap
= str9xpec_info
->tap
;
150 LOG_DEBUG("ISC_CONFIGURATION");
152 /* execute ISC_CONFIGURATION command */
153 str9xpec_set_instr(tap
, ISC_CONFIGURATION
, TAP_IRPAUSE
);
157 field
.out_value
= NULL
;
158 field
.in_value
= str9xpec_info
->options
;
161 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
162 jtag_execute_queue();
164 status
= str9xpec_isc_status(tap
);
169 static int str9xpec_build_block_list(struct flash_bank_s
*bank
)
171 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
175 int b0_sectors
= 0, b1_sectors
= 0;
177 int b1_size
= 0x2000;
201 LOG_ERROR("BUG: unknown bank->size encountered");
205 num_sectors
= b0_sectors
+ b1_sectors
;
207 bank
->num_sectors
= num_sectors
;
208 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
209 str9xpec_info
->sector_bits
= malloc(sizeof(uint32_t) * num_sectors
);
213 for (i
= 0; i
< b0_sectors
; i
++)
215 bank
->sectors
[num_sectors
].offset
= offset
;
216 bank
->sectors
[num_sectors
].size
= 0x10000;
217 offset
+= bank
->sectors
[i
].size
;
218 bank
->sectors
[num_sectors
].is_erased
= -1;
219 bank
->sectors
[num_sectors
].is_protected
= 1;
220 str9xpec_info
->sector_bits
[num_sectors
++] = i
;
223 for (i
= 0; i
< b1_sectors
; i
++)
225 bank
->sectors
[num_sectors
].offset
= offset
;
226 bank
->sectors
[num_sectors
].size
= b1_size
;
227 offset
+= bank
->sectors
[i
].size
;
228 bank
->sectors
[num_sectors
].is_erased
= -1;
229 bank
->sectors
[num_sectors
].is_protected
= 1;
230 str9xpec_info
->sector_bits
[num_sectors
++] = i
+ 32;
236 /* flash bank str9x <base> <size> 0 0 <target#>
238 static int str9xpec_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
240 str9xpec_flash_controller_t
*str9xpec_info
;
241 armv4_5_common_t
*armv4_5
= NULL
;
242 arm7_9_common_t
*arm7_9
= NULL
;
243 arm_jtag_t
*jtag_info
= NULL
;
247 LOG_WARNING("incomplete flash_bank str9x configuration");
248 return ERROR_FLASH_BANK_INVALID
;
251 str9xpec_info
= malloc(sizeof(str9xpec_flash_controller_t
));
252 bank
->driver_priv
= str9xpec_info
;
254 /* REVISIT verify that the jtag position of flash controller is
255 * right after *THIS* core, which must be a STR9xx core ...
257 armv4_5
= bank
->target
->arch_info
;
258 arm7_9
= armv4_5
->arch_info
;
259 jtag_info
= &arm7_9
->jtag_info
;
261 str9xpec_info
->tap
= bank
->target
->tap
;
262 str9xpec_info
->isc_enable
= 0;
264 str9xpec_build_block_list(bank
);
266 /* clear option byte register */
267 buf_set_u32(str9xpec_info
->options
, 0, 64, 0);
272 static int str9xpec_blank_check(struct flash_bank_s
*bank
, int first
, int last
)
278 uint8_t *buffer
= NULL
;
280 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
282 tap
= str9xpec_info
->tap
;
284 if (!str9xpec_info
->isc_enable
) {
285 str9xpec_isc_enable(bank
);
288 if (!str9xpec_info
->isc_enable
) {
289 return ERROR_FLASH_OPERATION_FAILED
;
292 buffer
= calloc(CEIL(64, 8), 1);
294 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first
, last
);
296 for (i
= first
; i
<= last
; i
++) {
297 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
300 /* execute ISC_BLANK_CHECK command */
301 str9xpec_set_instr(tap
, ISC_BLANK_CHECK
, TAP_IRPAUSE
);
305 field
.out_value
= buffer
;
306 field
.in_value
= NULL
;
308 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
309 jtag_add_sleep(40000);
311 /* read blank check result */
314 field
.out_value
= NULL
;
315 field
.in_value
= buffer
;
317 jtag_add_dr_scan(1, &field
, TAP_IRPAUSE
);
318 jtag_execute_queue();
320 status
= str9xpec_isc_status(tap
);
322 for (i
= first
; i
<= last
; i
++)
324 if (buf_get_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1))
325 bank
->sectors
[i
].is_erased
= 0;
327 bank
->sectors
[i
].is_erased
= 1;
332 str9xpec_isc_disable(bank
);
334 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
335 return ERROR_FLASH_OPERATION_FAILED
;
339 static int str9xpec_protect_check(struct flash_bank_s
*bank
)
344 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
346 status
= str9xpec_read_config(bank
);
348 for (i
= 0; i
< bank
->num_sectors
; i
++)
350 if (buf_get_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1))
351 bank
->sectors
[i
].is_protected
= 1;
353 bank
->sectors
[i
].is_protected
= 0;
356 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
357 return ERROR_FLASH_OPERATION_FAILED
;
361 static int str9xpec_erase_area(struct flash_bank_s
*bank
, int first
, int last
)
367 uint8_t *buffer
= NULL
;
369 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
371 tap
= str9xpec_info
->tap
;
373 if (!str9xpec_info
->isc_enable
) {
374 str9xpec_isc_enable(bank
);
377 if (!str9xpec_info
->isc_enable
) {
378 return ISC_STATUS_ERROR
;
381 buffer
= calloc(CEIL(64, 8), 1);
383 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first
, last
);
385 /* last bank: 0xFF signals a full erase (unlock complete device) */
386 /* last bank: 0xFE signals a option byte erase */
389 for (i
= 0; i
< 64; i
++) {
390 buf_set_u32(buffer
, i
, 1, 1);
393 else if (last
== 0xFE)
395 buf_set_u32(buffer
, 49, 1, 1);
399 for (i
= first
; i
<= last
; i
++) {
400 buf_set_u32(buffer
, str9xpec_info
->sector_bits
[i
], 1, 1);
404 LOG_DEBUG("ISC_ERASE");
406 /* execute ISC_ERASE command */
407 str9xpec_set_instr(tap
, ISC_ERASE
, TAP_IRPAUSE
);
411 field
.out_value
= buffer
;
412 field
.in_value
= NULL
;
414 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
415 jtag_execute_queue();
419 /* wait for erase completion */
420 while (!((status
= str9xpec_isc_status(tap
)) & ISC_STATUS_BUSY
)) {
426 str9xpec_isc_disable(bank
);
431 static int str9xpec_erase(struct flash_bank_s
*bank
, int first
, int last
)
435 status
= str9xpec_erase_area(bank
, first
, last
);
437 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
438 return ERROR_FLASH_OPERATION_FAILED
;
443 static int str9xpec_lock_device(struct flash_bank_s
*bank
)
448 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
450 str9xpec_info
= bank
->driver_priv
;
451 tap
= str9xpec_info
->tap
;
453 if (!str9xpec_info
->isc_enable
) {
454 str9xpec_isc_enable(bank
);
457 if (!str9xpec_info
->isc_enable
) {
458 return ISC_STATUS_ERROR
;
461 /* set security address */
462 str9xpec_set_address(bank
, 0x80);
464 /* execute ISC_PROGRAM command */
465 str9xpec_set_instr(tap
, ISC_PROGRAM_SECURITY
, TAP_IDLE
);
467 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
472 field
.out_value
= NULL
;
473 field
.in_value
= &status
;
475 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
476 jtag_execute_queue();
478 } while (!(status
& ISC_STATUS_BUSY
));
480 str9xpec_isc_disable(bank
);
485 static int str9xpec_unlock_device(struct flash_bank_s
*bank
)
489 status
= str9xpec_erase_area(bank
, 0, 255);
494 static int str9xpec_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
)
499 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
501 status
= str9xpec_read_config(bank
);
503 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
504 return ERROR_FLASH_OPERATION_FAILED
;
506 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first
, last
);
508 /* last bank: 0xFF signals a full device protect */
513 status
= str9xpec_lock_device(bank
);
517 /* perform full erase to unlock device */
518 status
= str9xpec_unlock_device(bank
);
523 for (i
= first
; i
<= last
; i
++)
526 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 1);
528 buf_set_u32(str9xpec_info
->options
, str9xpec_info
->sector_bits
[i
], 1, 0);
531 status
= str9xpec_write_options(bank
);
534 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
535 return ERROR_FLASH_OPERATION_FAILED
;
540 static int str9xpec_set_address(struct flash_bank_s
*bank
, uint8_t sector
)
544 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
546 tap
= str9xpec_info
->tap
;
548 /* set flash controller address */
549 str9xpec_set_instr(tap
, ISC_ADDRESS_SHIFT
, TAP_IRPAUSE
);
553 field
.out_value
= §or
;
554 field
.in_value
= NULL
;
556 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
561 static int str9xpec_write(struct flash_bank_s
*bank
, uint8_t *buffer
, uint32_t offset
, uint32_t count
)
563 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
564 uint32_t dwords_remaining
= (count
/ 8);
565 uint32_t bytes_remaining
= (count
& 0x00000007);
566 uint32_t bytes_written
= 0;
568 uint32_t check_address
= offset
;
573 int first_sector
= 0;
576 tap
= str9xpec_info
->tap
;
578 if (!str9xpec_info
->isc_enable
) {
579 str9xpec_isc_enable(bank
);
582 if (!str9xpec_info
->isc_enable
) {
583 return ERROR_FLASH_OPERATION_FAILED
;
588 LOG_WARNING("offset 0x%" PRIx32
" breaks required 8-byte alignment", offset
);
589 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
592 for (i
= 0; i
< bank
->num_sectors
; i
++)
594 uint32_t sec_start
= bank
->sectors
[i
].offset
;
595 uint32_t sec_end
= sec_start
+ bank
->sectors
[i
].size
;
597 /* check if destination falls within the current sector */
598 if ((check_address
>= sec_start
) && (check_address
< sec_end
))
600 /* check if destination ends in the current sector */
601 if (offset
+ count
< sec_end
)
602 check_address
= offset
+ count
;
604 check_address
= sec_end
;
607 if ((offset
>= sec_start
) && (offset
< sec_end
)) {
611 if ((offset
+ count
>= sec_start
) && (offset
+ count
< sec_end
)) {
616 if (check_address
!= offset
+ count
)
617 return ERROR_FLASH_DST_OUT_OF_BANK
;
619 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
621 scanbuf
= calloc(CEIL(64, 8), 1);
623 LOG_DEBUG("ISC_PROGRAM");
625 for (i
= first_sector
; i
<= last_sector
; i
++)
627 str9xpec_set_address(bank
, str9xpec_info
->sector_bits
[i
]);
629 dwords_remaining
= dwords_remaining
< (bank
->sectors
[i
].size
/8) ? dwords_remaining
: (bank
->sectors
[i
].size
/8);
631 while (dwords_remaining
> 0)
633 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
637 field
.out_value
= (buffer
+ bytes_written
);
638 field
.in_value
= NULL
;
640 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
642 /* small delay before polling */
645 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
650 field
.out_value
= NULL
;
651 field
.in_value
= scanbuf
;
653 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
654 jtag_execute_queue();
656 status
= buf_get_u32(scanbuf
, 0, 8);
658 } while (!(status
& ISC_STATUS_BUSY
));
660 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
661 return ERROR_FLASH_OPERATION_FAILED
;
663 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
664 return ERROR_FLASH_OPERATION_FAILED; */
673 uint8_t last_dword
[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
676 while (bytes_remaining
> 0)
678 last_dword
[i
++] = *(buffer
+ bytes_written
);
683 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
687 field
.out_value
= last_dword
;
688 field
.in_value
= NULL
;
690 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
692 /* small delay before polling */
695 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
700 field
.out_value
= NULL
;
701 field
.in_value
= scanbuf
;
703 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
704 jtag_execute_queue();
706 status
= buf_get_u32(scanbuf
, 0, 8);
708 } while (!(status
& ISC_STATUS_BUSY
));
710 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
711 return ERROR_FLASH_OPERATION_FAILED
;
713 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
714 return ERROR_FLASH_OPERATION_FAILED; */
719 str9xpec_isc_disable(bank
);
724 static int str9xpec_probe(struct flash_bank_s
*bank
)
729 static int str9xpec_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
732 uint8_t *buffer
= NULL
;
735 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
738 return ERROR_COMMAND_SYNTAX_ERROR
;
741 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
742 if (ERROR_OK
!= retval
)
745 str9xpec_info
= bank
->driver_priv
;
746 tap
= str9xpec_info
->tap
;
748 buffer
= calloc(CEIL(32, 8), 1);
750 str9xpec_set_instr(tap
, ISC_IDCODE
, TAP_IRPAUSE
);
754 field
.out_value
= NULL
;
755 field
.in_value
= buffer
;
757 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
758 jtag_execute_queue();
760 idcode
= buf_get_u32(buffer
, 0, 32);
762 command_print(cmd_ctx
, "str9xpec part id: 0x%8.8" PRIx32
"", idcode
);
769 static int str9xpec_erase_check(struct flash_bank_s
*bank
)
771 return str9xpec_blank_check(bank
, 0, bank
->num_sectors
- 1);
774 static int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
776 snprintf(buf
, buf_size
, "str9xpec flash driver info");
780 static int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
783 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
787 command_print(cmd_ctx
, "str9xpec options_read <bank>");
792 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
793 if (ERROR_OK
!= retval
)
796 str9xpec_info
= bank
->driver_priv
;
798 status
= str9xpec_read_config(bank
);
800 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
801 return ERROR_FLASH_OPERATION_FAILED
;
804 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1))
805 command_print(cmd_ctx
, "CS Map: bank1");
807 command_print(cmd_ctx
, "CS Map: bank0");
810 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_OTPBIT
, 1))
811 command_print(cmd_ctx
, "OTP Lock: OTP Locked");
813 command_print(cmd_ctx
, "OTP Lock: OTP Unlocked");
816 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1))
817 command_print(cmd_ctx
, "LVD Threshold: 2.7v");
819 command_print(cmd_ctx
, "LVD Threshold: 2.4v");
821 /* LVD reset warning */
822 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1))
823 command_print(cmd_ctx
, "LVD Reset Warning: VDD or VDDQ Inputs");
825 command_print(cmd_ctx
, "LVD Reset Warning: VDD Input Only");
827 /* LVD reset select */
828 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1))
829 command_print(cmd_ctx
, "LVD Reset Selection: VDD or VDDQ Inputs");
831 command_print(cmd_ctx
, "LVD Reset Selection: VDD Input Only");
836 static int str9xpec_write_options(struct flash_bank_s
*bank
)
841 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
843 str9xpec_info
= bank
->driver_priv
;
844 tap
= str9xpec_info
->tap
;
846 /* erase config options first */
847 status
= str9xpec_erase_area(bank
, 0xFE, 0xFE);
849 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
852 if (!str9xpec_info
->isc_enable
) {
853 str9xpec_isc_enable(bank
);
856 if (!str9xpec_info
->isc_enable
) {
857 return ISC_STATUS_ERROR
;
860 /* according to data 64th bit has to be set */
861 buf_set_u32(str9xpec_info
->options
, 63, 1, 1);
863 /* set option byte address */
864 str9xpec_set_address(bank
, 0x50);
866 /* execute ISC_PROGRAM command */
867 str9xpec_set_instr(tap
, ISC_PROGRAM
, TAP_IRPAUSE
);
871 field
.out_value
= str9xpec_info
->options
;
872 field
.in_value
= NULL
;
874 jtag_add_dr_scan(1, &field
, jtag_set_end_state(TAP_IDLE
));
876 /* small delay before polling */
879 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IRPAUSE
);
884 field
.out_value
= NULL
;
885 field
.in_value
= &status
;
887 jtag_add_dr_scan(1, &field
, jtag_get_end_state());
888 jtag_execute_queue();
890 } while (!(status
& ISC_STATUS_BUSY
));
892 str9xpec_isc_disable(bank
);
897 static int str9xpec_handle_flash_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
903 command_print(cmd_ctx
, "str9xpec options_write <bank>");
908 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
909 if (ERROR_OK
!= retval
)
912 status
= str9xpec_write_options(bank
);
914 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
915 return ERROR_FLASH_OPERATION_FAILED
;
920 static int str9xpec_handle_flash_options_cmap_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
922 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
926 command_print(cmd_ctx
, "str9xpec options_cmap <bank> <bank0 | bank1>");
931 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
932 if (ERROR_OK
!= retval
)
935 str9xpec_info
= bank
->driver_priv
;
937 if (strcmp(args
[1], "bank1") == 0)
939 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 1);
943 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1, 0);
949 static int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
951 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
955 command_print(cmd_ctx
, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
960 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
961 if (ERROR_OK
!= retval
)
964 str9xpec_info
= bank
->driver_priv
;
966 if (strcmp(args
[1], "2.7v") == 0)
968 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 1);
972 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1, 0);
978 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
980 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
984 command_print(cmd_ctx
, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
989 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
990 if (ERROR_OK
!= retval
)
993 str9xpec_info
= bank
->driver_priv
;
995 if (strcmp(args
[1], "vdd_vddq") == 0)
997 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 1);
1001 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1, 0);
1007 static int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1009 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1013 command_print(cmd_ctx
, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
1018 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1019 if (ERROR_OK
!= retval
)
1022 str9xpec_info
= bank
->driver_priv
;
1024 if (strcmp(args
[1], "vdd_vddq") == 0)
1026 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 1);
1030 buf_set_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1, 0);
1036 static int str9xpec_handle_flash_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1042 command_print(cmd_ctx
, "str9xpec lock <bank>");
1047 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1048 if (ERROR_OK
!= retval
)
1051 status
= str9xpec_lock_device(bank
);
1053 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1054 return ERROR_FLASH_OPERATION_FAILED
;
1059 static int str9xpec_handle_flash_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1065 command_print(cmd_ctx
, "str9xpec unlock <bank>");
1070 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1071 if (ERROR_OK
!= retval
)
1074 status
= str9xpec_unlock_device(bank
);
1076 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
1077 return ERROR_FLASH_OPERATION_FAILED
;
1082 static int str9xpec_handle_flash_enable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1087 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1091 command_print(cmd_ctx
, "str9xpec enable_turbo <bank>");
1096 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1097 if (ERROR_OK
!= retval
)
1100 str9xpec_info
= bank
->driver_priv
;
1102 tap0
= str9xpec_info
->tap
;
1104 /* remove arm core from chain - enter turbo mode */
1105 tap1
= tap0
->next_tap
;
1108 /* things are *WRONG* */
1109 command_print(cmd_ctx
,"**STR9FLASH** (tap1) invalid chain?");
1112 tap2
= tap1
->next_tap
;
1115 /* things are *WRONG* */
1116 command_print(cmd_ctx
,"**STR9FLASH** (tap2) invalid chain?");
1120 /* enable turbo mode - TURBO-PROG-ENABLE */
1121 str9xpec_set_instr(tap2
, 0xD, TAP_IDLE
);
1122 if ((retval
= jtag_execute_queue()) != ERROR_OK
)
1125 /* modify scan chain - str9 core has been removed */
1131 static int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1134 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1138 command_print(cmd_ctx
, "str9xpec disable_turbo <bank>");
1143 int retval
= flash_command_get_bank_by_num(cmd_ctx
, args
[0], &bank
);
1144 if (ERROR_OK
!= retval
)
1147 str9xpec_info
= bank
->driver_priv
;
1148 tap
= str9xpec_info
->tap
;
1153 /* exit turbo mode via RESET */
1154 str9xpec_set_instr(tap
, ISC_NOOP
, TAP_IDLE
);
1156 jtag_execute_queue();
1158 /* restore previous scan chain */
1159 if (tap
->next_tap
) {
1160 tap
->next_tap
->enabled
= 1;
1166 static int str9xpec_register_commands(struct command_context_s
*cmd_ctx
)
1168 command_t
*str9xpec_cmd
= register_command(cmd_ctx
, NULL
, "str9xpec",
1169 NULL
, COMMAND_ANY
, "str9xpec flash specific commands");
1171 register_command(cmd_ctx
, str9xpec_cmd
, "enable_turbo",
1172 str9xpec_handle_flash_enable_turbo_command
,
1173 COMMAND_EXEC
, "enable str9xpec turbo mode");
1174 register_command(cmd_ctx
, str9xpec_cmd
, "disable_turbo",
1175 str9xpec_handle_flash_disable_turbo_command
,
1176 COMMAND_EXEC
, "disable str9xpec turbo mode");
1177 register_command(cmd_ctx
, str9xpec_cmd
, "options_cmap",
1178 str9xpec_handle_flash_options_cmap_command
,
1179 COMMAND_EXEC
, "configure str9xpec boot sector");
1180 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdthd",
1181 str9xpec_handle_flash_options_lvdthd_command
,
1182 COMMAND_EXEC
, "configure str9xpec lvd threshold");
1183 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdsel",
1184 str9xpec_handle_flash_options_lvdsel_command
,
1185 COMMAND_EXEC
, "configure str9xpec lvd selection");
1186 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdwarn",
1187 str9xpec_handle_flash_options_lvdwarn_command
,
1188 COMMAND_EXEC
, "configure str9xpec lvd warning");
1189 register_command(cmd_ctx
, str9xpec_cmd
, "options_read",
1190 str9xpec_handle_flash_options_read_command
,
1191 COMMAND_EXEC
, "read str9xpec options");
1192 register_command(cmd_ctx
, str9xpec_cmd
, "options_write",
1193 str9xpec_handle_flash_options_write_command
,
1194 COMMAND_EXEC
, "write str9xpec options");
1195 register_command(cmd_ctx
, str9xpec_cmd
, "lock",
1196 str9xpec_handle_flash_lock_command
,
1197 COMMAND_EXEC
, "lock str9xpec device");
1198 register_command(cmd_ctx
, str9xpec_cmd
, "unlock",
1199 str9xpec_handle_flash_unlock_command
,
1200 COMMAND_EXEC
, "unlock str9xpec device");
1201 register_command(cmd_ctx
, str9xpec_cmd
, "part_id",
1202 str9xpec_handle_part_id_command
,
1203 COMMAND_EXEC
, "print part id of str9xpec flash bank <num>");
1208 flash_driver_t str9xpec_flash
= {
1210 .register_commands
= &str9xpec_register_commands
,
1211 .flash_bank_command
= &str9xpec_flash_bank_command
,
1212 .erase
= &str9xpec_erase
,
1213 .protect
= &str9xpec_protect
,
1214 .write
= &str9xpec_write
,
1215 .probe
= &str9xpec_probe
,
1216 .auto_probe
= &str9xpec_probe
,
1217 .erase_check
= &str9xpec_erase_check
,
1218 .protect_check
= &str9xpec_protect_check
,
1219 .info
= &str9xpec_info
,
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)