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 str9xpec_mem_layout_t mem_layout_str9pec
[] = {
41 {0x00000000, 0x10000, 0},
42 {0x00010000, 0x10000, 1},
43 {0x00020000, 0x10000, 2},
44 {0x00030000, 0x10000, 3},
45 {0x00040000, 0x10000, 4},
46 {0x00050000, 0x10000, 5},
47 {0x00060000, 0x10000, 6},
48 {0x00070000, 0x10000, 7},
49 {0x00080000, 0x02000, 32},
50 {0x00082000, 0x02000, 33},
51 {0x00084000, 0x02000, 34},
52 {0x00086000, 0x02000, 35}
55 int str9xpec_register_commands(struct command_context_s
*cmd_ctx
);
56 int str9xpec_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
);
57 int str9xpec_erase(struct flash_bank_s
*bank
, int first
, int last
);
58 int str9xpec_protect(struct flash_bank_s
*bank
, int set
, int first
, int last
);
59 int str9xpec_write(struct flash_bank_s
*bank
, u8
*buffer
, u32 offset
, u32 count
);
60 int str9xpec_probe(struct flash_bank_s
*bank
);
61 int str9xpec_handle_part_id_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
62 int str9xpec_protect_check(struct flash_bank_s
*bank
);
63 int str9xpec_erase_check(struct flash_bank_s
*bank
);
64 int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
);
66 int str9xpec_erase_area(struct flash_bank_s
*bank
, int first
, int last
);
67 int str9xpec_set_address(struct flash_bank_s
*bank
, u8 sector
);
68 int str9xpec_write_options(struct flash_bank_s
*bank
);
70 int str9xpec_handle_flash_options_cmap_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
71 int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
72 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
73 int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
74 int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
75 int str9xpec_handle_flash_options_write_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
76 int str9xpec_handle_flash_lock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
77 int str9xpec_handle_flash_unlock_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
78 int str9xpec_handle_flash_enable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
79 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
);
81 flash_driver_t str9xpec_flash
=
84 .register_commands
= str9xpec_register_commands
,
85 .flash_bank_command
= str9xpec_flash_bank_command
,
86 .erase
= str9xpec_erase
,
87 .protect
= str9xpec_protect
,
88 .write
= str9xpec_write
,
89 .probe
= str9xpec_probe
,
90 .erase_check
= str9xpec_erase_check
,
91 .protect_check
= str9xpec_protect_check
,
95 int str9xpec_register_commands(struct command_context_s
*cmd_ctx
)
97 command_t
*str9xpec_cmd
= register_command(cmd_ctx
, NULL
, "str9xpec", NULL
, COMMAND_ANY
, "str9xpec flash specific commands");
99 register_command(cmd_ctx
, str9xpec_cmd
, "enable_turbo", str9xpec_handle_flash_enable_turbo_command
, COMMAND_EXEC
,
100 "enable str9xpec turbo mode");
101 register_command(cmd_ctx
, str9xpec_cmd
, "disable_turbo", str9xpec_handle_flash_disable_turbo_command
, COMMAND_EXEC
,
102 "disable str9xpec turbo mode");
103 register_command(cmd_ctx
, str9xpec_cmd
, "options_cmap", str9xpec_handle_flash_options_cmap_command
, COMMAND_EXEC
,
104 "configure str9xpec boot sector");
105 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdthd", str9xpec_handle_flash_options_lvdthd_command
, COMMAND_EXEC
,
106 "configure str9xpec lvd threshold");
107 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdsel", str9xpec_handle_flash_options_lvdsel_command
, COMMAND_EXEC
,
108 "configure str9xpec lvd selection");
109 register_command(cmd_ctx
, str9xpec_cmd
, "options_lvdwarn", str9xpec_handle_flash_options_lvdwarn_command
, COMMAND_EXEC
,
110 "configure str9xpec lvd warning");
111 register_command(cmd_ctx
, str9xpec_cmd
, "options_read", str9xpec_handle_flash_options_read_command
, COMMAND_EXEC
,
112 "read str9xpec options");
113 register_command(cmd_ctx
, str9xpec_cmd
, "options_write", str9xpec_handle_flash_options_write_command
, COMMAND_EXEC
,
114 "write str9xpec options");
115 register_command(cmd_ctx
, str9xpec_cmd
, "lock", str9xpec_handle_flash_lock_command
, COMMAND_EXEC
,
116 "lock str9xpec device");
117 register_command(cmd_ctx
, str9xpec_cmd
, "unlock", str9xpec_handle_flash_unlock_command
, COMMAND_EXEC
,
118 "unlock str9xpec device");
119 register_command(cmd_ctx
, str9xpec_cmd
, "part_id", str9xpec_handle_part_id_command
, COMMAND_EXEC
,
120 "print part id of str9xpec flash bank <num>");
125 int str9xpec_set_instr(int chain_pos
, u32 new_instr
, enum tap_state end_state
)
127 jtag_device_t
*device
= jtag_get_device(chain_pos
);
129 if (buf_get_u32(device
->cur_instr
, 0, device
->ir_length
) != new_instr
)
133 field
.device
= chain_pos
;
134 field
.num_bits
= device
->ir_length
;
135 field
.out_value
= calloc(CEIL(field
.num_bits
, 8), 1);
136 buf_set_u32(field
.out_value
, 0, field
.num_bits
, new_instr
);
137 field
.out_mask
= NULL
;
138 field
.in_value
= NULL
;
139 field
.in_check_value
= NULL
;
140 field
.in_check_mask
= NULL
;
141 field
.in_handler
= NULL
;
142 field
.in_handler_priv
= NULL
;
144 jtag_add_ir_scan(1, &field
, end_state
, NULL
);
146 free(field
.out_value
);
152 u8
str9xpec_isc_status(int chain_pos
)
157 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
159 field
.device
= chain_pos
;
161 field
.out_value
= NULL
;
162 field
.out_mask
= NULL
;
163 field
.in_value
= &status
;
164 field
.in_check_value
= NULL
;
165 field
.in_check_mask
= NULL
;
166 field
.in_handler
= NULL
;
167 field
.in_handler_priv
= NULL
;
169 jtag_add_dr_scan(1, &field
, TAP_RTI
, NULL
);
170 jtag_execute_queue();
172 DEBUG("status: 0x%2.2x", status
);
174 if (status
& ISC_STATUS_SECURITY
)
175 INFO("Device Security Bit Set");
180 int str9xpec_isc_enable(struct flash_bank_s
*bank
)
184 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
186 chain_pos
= str9xpec_info
->chain_pos
;
188 if (str9xpec_info
->isc_enable
)
192 str9xpec_set_instr(chain_pos
, ISC_ENABLE
, TAP_RTI
);
194 /* check ISC status */
195 status
= str9xpec_isc_status(chain_pos
);
196 if (status
& ISC_STATUS_MODE
)
198 /* we have entered isc mode */
199 str9xpec_info
->isc_enable
= 1;
200 DEBUG("ISC_MODE Enabled");
206 int str9xpec_isc_disable(struct flash_bank_s
*bank
)
210 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
212 chain_pos
= str9xpec_info
->chain_pos
;
214 if (!str9xpec_info
->isc_enable
)
217 str9xpec_set_instr(chain_pos
, ISC_DISABLE
, TAP_RTI
);
219 /* delay to handle aborts */
222 /* check ISC status */
223 status
= str9xpec_isc_status(chain_pos
);
224 if (!(status
& ISC_STATUS_MODE
))
226 /* we have left isc mode */
227 str9xpec_info
->isc_enable
= 0;
228 DEBUG("ISC_MODE Disabled");
234 int str9xpec_read_config(struct flash_bank_s
*bank
)
240 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
242 chain_pos
= str9xpec_info
->chain_pos
;
244 DEBUG("ISC_CONFIGURATION");
246 /* execute ISC_CONFIGURATION command */
247 str9xpec_set_instr(chain_pos
, ISC_CONFIGURATION
, TAP_PI
);
249 field
.device
= chain_pos
;
251 field
.out_value
= NULL
;
252 field
.out_mask
= NULL
;
253 field
.in_value
= str9xpec_info
->options
;
254 field
.in_check_value
= NULL
;
255 field
.in_check_mask
= NULL
;
256 field
.in_handler
= NULL
;
257 field
.in_handler_priv
= NULL
;
259 jtag_add_dr_scan(1, &field
, TAP_RTI
, NULL
);
260 jtag_execute_queue();
262 status
= str9xpec_isc_status(chain_pos
);
267 int str9xpec_build_block_list(struct flash_bank_s
*bank
)
269 str9xpec_flash_controller_t
*str9xpec_info
= bank
->driver_priv
;
272 int num_sectors
= 0, b0_sectors
= 0;
283 ERROR("BUG: unknown bank->size encountered");
287 num_sectors
= b0_sectors
+ 4;
289 bank
->num_sectors
= num_sectors
;
290 bank
->sectors
= malloc(sizeof(flash_sector_t
) * num_sectors
);
291 str9xpec_info
->sector_bits
= malloc(sizeof(u32
) * num_sectors
);
295 for (i
= 0; i
< b0_sectors
; i
++)
297 bank
->sectors
[num_sectors
].offset
= mem_layout_str9pec
[i
].sector_start
;
298 bank
->sectors
[num_sectors
].size
= mem_layout_str9pec
[i
].sector_size
;
299 bank
->sectors
[num_sectors
].is_erased
= -1;
300 bank
->sectors
[num_sectors
].is_protected
= 1;
301 str9xpec_info
->sector_bits
[num_sectors
++] = mem_layout_str9pec
[i
].sector_bit
;
304 for (i
= 8; i
< 12; i
++)
306 bank
->sectors
[num_sectors
].offset
= mem_layout_str9pec
[i
].sector_start
;
307 bank
->sectors
[num_sectors
].size
= mem_layout_str9pec
[i
].sector_size
;
308 bank
->sectors
[num_sectors
].is_erased
= -1;
309 bank
->sectors
[num_sectors
].is_protected
= 1;
310 str9xpec_info
->sector_bits
[num_sectors
++] = mem_layout_str9pec
[i
].sector_bit
;
316 /* flash bank str9x <base> <size> 0 0 <target#>
318 int str9xpec_flash_bank_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
, struct flash_bank_s
*bank
)
320 str9xpec_flash_controller_t
*str9xpec_info
;
321 armv4_5_common_t
*armv4_5
= NULL
;
322 arm7_9_common_t
*arm7_9
= NULL
;
323 arm_jtag_t
*jtag_info
= NULL
;
327 WARNING("incomplete flash_bank str9x configuration");
328 return ERROR_FLASH_BANK_INVALID
;
331 str9xpec_info
= malloc(sizeof(str9xpec_flash_controller_t
));
332 bank
->driver_priv
= str9xpec_info
;
334 if (bank
->base
!= 0x00000000)
336 WARNING("overriding flash base address for STR91x device with 0x00000000");
337 bank
->base
= 0x00000000;
340 str9xpec_info
->target
= get_target_by_num(strtoul(args
[5], NULL
, 0));
341 if (!str9xpec_info
->target
)
343 ERROR("no target '%s' configured", args
[5]);
347 /* find out jtag position of flash controller
348 * it is always after the arm966 core */
350 armv4_5
= str9xpec_info
->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 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
, NULL
);
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
, NULL
);
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 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);
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
, NULL
);
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, NULL
);
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 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, NULL
);
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 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 DEBUG("first_sector: %i, last_sector: %i", first_sector
, last_sector
);
740 scanbuf
= calloc(CEIL(64, 8), 1);
742 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
, NULL
);
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, NULL
);
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
, NULL
);
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, NULL
);
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 command_print(cmd_ctx
, "usage: str9xpec part_id <num>");
883 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
886 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
890 str9xpec_info
= bank
->driver_priv
;
891 chain_pos
= str9xpec_info
->chain_pos
;
893 buffer
= calloc(CEIL(32, 8), 1);
895 str9xpec_set_instr(chain_pos
, ISC_IDCODE
, TAP_PI
);
897 field
.device
= chain_pos
;
899 field
.out_value
= NULL
;
900 field
.out_mask
= NULL
;
901 field
.in_value
= buffer
;
902 field
.in_check_value
= NULL
;
903 field
.in_check_mask
= NULL
;
904 field
.in_handler
= NULL
;
905 field
.in_handler_priv
= NULL
;
907 jtag_add_dr_scan(1, &field
, TAP_RTI
, NULL
);
908 jtag_execute_queue();
910 idcode
= buf_get_u32(buffer
, 0, 32);
912 command_print(cmd_ctx
, "str9xpec part id: 0x%8.8x", idcode
);
919 int str9xpec_erase_check(struct flash_bank_s
*bank
)
921 return str9xpec_blank_check(bank
, 0, bank
->num_sectors
- 1);
924 int str9xpec_info(struct flash_bank_s
*bank
, char *buf
, int buf_size
)
926 snprintf(buf
, buf_size
, "str9xpec flash driver info" );
930 int str9xpec_handle_flash_options_read_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
934 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
938 command_print(cmd_ctx
, "str9xpec options_read <bank>");
942 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
945 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
949 str9xpec_info
= bank
->driver_priv
;
951 status
= str9xpec_read_config(bank
);
953 if ((status
& ISC_STATUS_ERROR
) != STR9XPEC_ISC_SUCCESS
)
954 return ERROR_FLASH_OPERATION_FAILED
;
957 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_CSMAPBIT
, 1))
958 command_print(cmd_ctx
, "CS Map: bank1");
960 command_print(cmd_ctx
, "CS Map: bank0");
963 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_OTPBIT
, 1))
964 command_print(cmd_ctx
, "OTP Lock: OTP Locked");
966 command_print(cmd_ctx
, "OTP Lock: OTP Unlocked");
969 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDTHRESBIT
, 1))
970 command_print(cmd_ctx
, "LVD Threshold: 2.7v");
972 command_print(cmd_ctx
, "LVD Threshold: 2.4v");
974 /* LVD reset warning */
975 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDWARNBIT
, 1))
976 command_print(cmd_ctx
, "LVD Reset Warning: VDD or VDDQ Inputs");
978 command_print(cmd_ctx
, "LVD Reset Warning: VDD Input Only");
980 /* LVD reset select */
981 if (buf_get_u32(str9xpec_info
->options
, STR9XPEC_OPT_LVDSELBIT
, 1))
982 command_print(cmd_ctx
, "LVD Reset Selection: VDD or VDDQ Inputs");
984 command_print(cmd_ctx
, "LVD Reset Selection: VDD Input Only");
989 int str9xpec_write_options(struct flash_bank_s
*bank
)
994 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
996 str9xpec_info
= bank
->driver_priv
;
997 chain_pos
= str9xpec_info
->chain_pos
;
999 /* erase config options first */
1000 str9xpec_erase_area( bank
, 0xFE, 0xFE );
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(chain_pos
, ISC_PROGRAM
, TAP_PI
);
1019 field
.device
= chain_pos
;
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_RTI
, NULL
);
1031 /* small delay before polling */
1034 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_PI
);
1037 field
.device
= chain_pos
;
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, NULL
);
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
)
1267 jtag_device_t
* dev0
;
1268 jtag_device_t
* dev2
;
1269 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1273 command_print(cmd_ctx
, "str9xpec enable_turbo <bank>");
1277 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1280 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1284 str9xpec_info
= bank
->driver_priv
;
1286 chain_pos
= str9xpec_info
->chain_pos
;
1288 /* remove arm core from chain - enter turbo mode */
1290 str9xpec_set_instr(chain_pos
+2, 0xD, TAP_RTI
);
1291 jtag_execute_queue();
1293 /* modify scan chain - str9 core has been removed */
1294 dev0
= jtag_get_device(chain_pos
);
1295 str9xpec_info
->devarm
= jtag_get_device(chain_pos
+1);
1296 dev2
= jtag_get_device(chain_pos
+2);
1303 int str9xpec_handle_flash_disable_turbo_command(struct command_context_s
*cmd_ctx
, char *cmd
, char **args
, int argc
)
1307 jtag_device_t
* dev0
;
1308 str9xpec_flash_controller_t
*str9xpec_info
= NULL
;
1312 command_print(cmd_ctx
, "str9xpec disable_turbo <bank>");
1316 bank
= get_flash_bank_by_num(strtoul(args
[0], NULL
, 0));
1319 command_print(cmd_ctx
, "flash bank '#%s' is out of bounds", args
[0]);
1323 str9xpec_info
= bank
->driver_priv
;
1325 chain_pos
= str9xpec_info
->chain_pos
;
1327 dev0
= jtag_get_device(chain_pos
);
1329 /* exit turbo mode via TLR */
1330 str9xpec_set_instr(chain_pos
, ISC_NOOP
, TAP_TLR
);
1331 jtag_execute_queue();
1333 /* restore previous scan chain */
1334 if( str9xpec_info
->devarm
) {
1335 dev0
->next
= str9xpec_info
->devarm
;
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)