Transform 'u8' to 'uint8_t' in src/flash
[openocd.git] / src / flash / str9xpec.c
blob71f58c25769bebd96b53e09df29d6939fe895808
1 /***************************************************************************
2 * Copyright (C) 2005 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * *
5 * Copyright (C) 2008 by Spencer Oliver *
6 * spen@spen-soft.co.uk *
7 * *
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. *
12 * *
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. *
17 * *
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 ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
27 #include "str9xpec.h"
28 #include "arm7_9_common.h"
31 static int str9xpec_register_commands(struct command_context_s *cmd_ctx);
32 static int str9xpec_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank);
33 static int str9xpec_erase(struct flash_bank_s *bank, int first, int last);
34 static int str9xpec_protect(struct flash_bank_s *bank, int set, int first, int last);
35 static int str9xpec_write(struct flash_bank_s *bank, uint8_t *buffer, u32 offset, u32 count);
36 static int str9xpec_probe(struct flash_bank_s *bank);
37 static int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
38 static int str9xpec_protect_check(struct flash_bank_s *bank);
39 static int str9xpec_erase_check(struct flash_bank_s *bank);
40 static int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size);
42 static int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last);
43 static int str9xpec_set_address(struct flash_bank_s *bank, uint8_t sector);
44 static int str9xpec_write_options(struct flash_bank_s *bank);
46 static int str9xpec_handle_flash_options_cmap_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
47 static int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
48 static int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
49 static int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
50 static int str9xpec_handle_flash_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
51 static int str9xpec_handle_flash_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
52 static int str9xpec_handle_flash_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
53 static int str9xpec_handle_flash_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
54 static int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
55 static int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc);
57 flash_driver_t str9xpec_flash =
59 .name = "str9xpec",
60 .register_commands = str9xpec_register_commands,
61 .flash_bank_command = str9xpec_flash_bank_command,
62 .erase = str9xpec_erase,
63 .protect = str9xpec_protect,
64 .write = str9xpec_write,
65 .probe = str9xpec_probe,
66 .auto_probe = str9xpec_probe,
67 .erase_check = str9xpec_erase_check,
68 .protect_check = str9xpec_protect_check,
69 .info = str9xpec_info
72 static int str9xpec_register_commands(struct command_context_s *cmd_ctx)
74 command_t *str9xpec_cmd = register_command(cmd_ctx, NULL, "str9xpec", NULL, COMMAND_ANY, "str9xpec flash specific commands");
76 register_command(cmd_ctx, str9xpec_cmd, "enable_turbo", str9xpec_handle_flash_enable_turbo_command, COMMAND_EXEC,
77 "enable str9xpec turbo mode");
78 register_command(cmd_ctx, str9xpec_cmd, "disable_turbo", str9xpec_handle_flash_disable_turbo_command, COMMAND_EXEC,
79 "disable str9xpec turbo mode");
80 register_command(cmd_ctx, str9xpec_cmd, "options_cmap", str9xpec_handle_flash_options_cmap_command, COMMAND_EXEC,
81 "configure str9xpec boot sector");
82 register_command(cmd_ctx, str9xpec_cmd, "options_lvdthd", str9xpec_handle_flash_options_lvdthd_command, COMMAND_EXEC,
83 "configure str9xpec lvd threshold");
84 register_command(cmd_ctx, str9xpec_cmd, "options_lvdsel", str9xpec_handle_flash_options_lvdsel_command, COMMAND_EXEC,
85 "configure str9xpec lvd selection");
86 register_command(cmd_ctx, str9xpec_cmd, "options_lvdwarn", str9xpec_handle_flash_options_lvdwarn_command, COMMAND_EXEC,
87 "configure str9xpec lvd warning");
88 register_command(cmd_ctx, str9xpec_cmd, "options_read", str9xpec_handle_flash_options_read_command, COMMAND_EXEC,
89 "read str9xpec options");
90 register_command(cmd_ctx, str9xpec_cmd, "options_write", str9xpec_handle_flash_options_write_command, COMMAND_EXEC,
91 "write str9xpec options");
92 register_command(cmd_ctx, str9xpec_cmd, "lock", str9xpec_handle_flash_lock_command, COMMAND_EXEC,
93 "lock str9xpec device");
94 register_command(cmd_ctx, str9xpec_cmd, "unlock", str9xpec_handle_flash_unlock_command, COMMAND_EXEC,
95 "unlock str9xpec device");
96 register_command(cmd_ctx, str9xpec_cmd, "part_id", str9xpec_handle_part_id_command, COMMAND_EXEC,
97 "print part id of str9xpec flash bank <num>");
99 return ERROR_OK;
102 int str9xpec_set_instr(jtag_tap_t *tap, u32 new_instr, tap_state_t end_state)
104 if( tap == NULL ){
105 return ERROR_TARGET_INVALID;
108 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr)
110 scan_field_t field;
112 field.tap = tap;
113 field.num_bits = tap->ir_length;
114 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
115 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
116 field.in_value = NULL;
118 jtag_add_ir_scan(1, &field, end_state);
120 free(field.out_value);
123 return ERROR_OK;
126 static uint8_t str9xpec_isc_status(jtag_tap_t *tap)
128 scan_field_t field;
129 uint8_t status;
131 if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
132 return ISC_STATUS_ERROR;
134 field.tap = tap;
135 field.num_bits = 8;
136 field.out_value = NULL;
137 field.in_value = &status;
140 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
141 jtag_execute_queue();
143 LOG_DEBUG("status: 0x%2.2x", status);
145 if (status & ISC_STATUS_SECURITY)
146 LOG_INFO("Device Security Bit Set");
148 return status;
151 static int str9xpec_isc_enable(struct flash_bank_s *bank)
153 uint8_t status;
154 jtag_tap_t *tap;
155 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
157 tap = str9xpec_info->tap;
159 if (str9xpec_info->isc_enable)
160 return ERROR_OK;
162 /* enter isc mode */
163 if (str9xpec_set_instr(tap, ISC_ENABLE, TAP_IDLE) != ERROR_OK)
164 return ERROR_TARGET_INVALID;
166 /* check ISC status */
167 status = str9xpec_isc_status(tap);
168 if (status & ISC_STATUS_MODE)
170 /* we have entered isc mode */
171 str9xpec_info->isc_enable = 1;
172 LOG_DEBUG("ISC_MODE Enabled");
175 return ERROR_OK;
178 static int str9xpec_isc_disable(struct flash_bank_s *bank)
180 uint8_t status;
181 jtag_tap_t *tap;
182 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
184 tap = str9xpec_info->tap;
186 if (!str9xpec_info->isc_enable)
187 return ERROR_OK;
189 if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)
190 return ERROR_TARGET_INVALID;
192 /* delay to handle aborts */
193 jtag_add_sleep(50);
195 /* check ISC status */
196 status = str9xpec_isc_status(tap);
197 if (!(status & ISC_STATUS_MODE))
199 /* we have left isc mode */
200 str9xpec_info->isc_enable = 0;
201 LOG_DEBUG("ISC_MODE Disabled");
204 return ERROR_OK;
207 static int str9xpec_read_config(struct flash_bank_s *bank)
209 scan_field_t field;
210 uint8_t status;
211 jtag_tap_t *tap;
213 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
215 tap = str9xpec_info->tap;
217 LOG_DEBUG("ISC_CONFIGURATION");
219 /* execute ISC_CONFIGURATION command */
220 str9xpec_set_instr(tap, ISC_CONFIGURATION, TAP_IRPAUSE);
222 field.tap = tap;
223 field.num_bits = 64;
224 field.out_value = NULL;
225 field.in_value = str9xpec_info->options;
228 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
229 jtag_execute_queue();
231 status = str9xpec_isc_status(tap);
233 return status;
236 static int str9xpec_build_block_list(struct flash_bank_s *bank)
238 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
240 int i;
241 int num_sectors;
242 int b0_sectors = 0, b1_sectors = 0;
243 u32 offset = 0;
244 int b1_size = 0x2000;
246 switch (bank->size)
248 case (256 * 1024):
249 b0_sectors = 4;
250 break;
251 case (512 * 1024):
252 b0_sectors = 8;
253 break;
254 case (1024 * 1024):
255 b0_sectors = 16;
256 break;
257 case (2048 * 1024):
258 b0_sectors = 32;
259 break;
260 case (128 * 1024):
261 b1_size = 0x4000;
262 b1_sectors = 8;
263 break;
264 case (32 * 1024):
265 b1_sectors = 4;
266 break;
267 default:
268 LOG_ERROR("BUG: unknown bank->size encountered");
269 exit(-1);
272 num_sectors = b0_sectors + b1_sectors;
274 bank->num_sectors = num_sectors;
275 bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
276 str9xpec_info->sector_bits = malloc(sizeof(u32) * num_sectors);
278 num_sectors = 0;
280 for (i = 0; i < b0_sectors; i++)
282 bank->sectors[num_sectors].offset = offset;
283 bank->sectors[num_sectors].size = 0x10000;
284 offset += bank->sectors[i].size;
285 bank->sectors[num_sectors].is_erased = -1;
286 bank->sectors[num_sectors].is_protected = 1;
287 str9xpec_info->sector_bits[num_sectors++] = i;
290 for (i = 0; i < b1_sectors; i++)
292 bank->sectors[num_sectors].offset = offset;
293 bank->sectors[num_sectors].size = b1_size;
294 offset += bank->sectors[i].size;
295 bank->sectors[num_sectors].is_erased = -1;
296 bank->sectors[num_sectors].is_protected = 1;
297 str9xpec_info->sector_bits[num_sectors++] = i + 32;
300 return ERROR_OK;
303 /* flash bank str9x <base> <size> 0 0 <target#>
305 static int str9xpec_flash_bank_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc, struct flash_bank_s *bank)
307 str9xpec_flash_controller_t *str9xpec_info;
308 armv4_5_common_t *armv4_5 = NULL;
309 arm7_9_common_t *arm7_9 = NULL;
310 arm_jtag_t *jtag_info = NULL;
312 if (argc < 6)
314 LOG_WARNING("incomplete flash_bank str9x configuration");
315 return ERROR_FLASH_BANK_INVALID;
318 str9xpec_info = malloc(sizeof(str9xpec_flash_controller_t));
319 bank->driver_priv = str9xpec_info;
321 /* find out jtag position of flash controller
322 * it is always after the arm966 core */
324 armv4_5 = bank->target->arch_info;
325 arm7_9 = armv4_5->arch_info;
326 jtag_info = &arm7_9->jtag_info;
328 str9xpec_info->tap = jtag_tap_by_position( jtag_info->tap->abs_chain_position - 1);
329 str9xpec_info->isc_enable = 0;
331 str9xpec_build_block_list(bank);
333 /* clear option byte register */
334 buf_set_u32(str9xpec_info->options, 0, 64, 0);
336 return ERROR_OK;
339 static int str9xpec_blank_check(struct flash_bank_s *bank, int first, int last)
341 scan_field_t field;
342 uint8_t status;
343 jtag_tap_t *tap;
344 int i;
345 uint8_t *buffer = NULL;
347 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
349 tap = str9xpec_info->tap;
351 if (!str9xpec_info->isc_enable) {
352 str9xpec_isc_enable( bank );
355 if (!str9xpec_info->isc_enable) {
356 return ERROR_FLASH_OPERATION_FAILED;
359 buffer = calloc(CEIL(64, 8), 1);
361 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
363 for (i = first; i <= last; i++) {
364 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
367 /* execute ISC_BLANK_CHECK command */
368 str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);
370 field.tap = tap;
371 field.num_bits = 64;
372 field.out_value = buffer;
373 field.in_value = NULL;
375 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
376 jtag_add_sleep(40000);
378 /* read blank check result */
379 field.tap = tap;
380 field.num_bits = 64;
381 field.out_value = NULL;
382 field.in_value = buffer;
384 jtag_add_dr_scan(1, &field, TAP_IRPAUSE);
385 jtag_execute_queue();
387 status = str9xpec_isc_status(tap);
389 for (i = first; i <= last; i++)
391 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
392 bank->sectors[i].is_erased = 0;
393 else
394 bank->sectors[i].is_erased = 1;
397 free(buffer);
399 str9xpec_isc_disable(bank);
401 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
402 return ERROR_FLASH_OPERATION_FAILED;
403 return ERROR_OK;
406 static int str9xpec_protect_check(struct flash_bank_s *bank)
408 uint8_t status;
409 int i;
411 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
413 status = str9xpec_read_config(bank);
415 for (i = 0; i < bank->num_sectors; i++)
417 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
418 bank->sectors[i].is_protected = 1;
419 else
420 bank->sectors[i].is_protected = 0;
423 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
424 return ERROR_FLASH_OPERATION_FAILED;
425 return ERROR_OK;
428 static int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last)
430 scan_field_t field;
431 uint8_t status;
432 jtag_tap_t *tap;
433 int i;
434 uint8_t *buffer = NULL;
436 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
438 tap = str9xpec_info->tap;
440 if (!str9xpec_info->isc_enable) {
441 str9xpec_isc_enable( bank );
444 if (!str9xpec_info->isc_enable) {
445 return ISC_STATUS_ERROR;
448 buffer = calloc(CEIL(64, 8), 1);
450 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
452 /* last bank: 0xFF signals a full erase (unlock complete device) */
453 /* last bank: 0xFE signals a option byte erase */
454 if (last == 0xFF)
456 for (i = 0; i < 64; i++) {
457 buf_set_u32(buffer, i, 1, 1);
460 else if (last == 0xFE)
462 buf_set_u32(buffer, 49, 1, 1);
464 else
466 for (i = first; i <= last; i++) {
467 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
471 LOG_DEBUG("ISC_ERASE");
473 /* execute ISC_ERASE command */
474 str9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);
476 field.tap = tap;
477 field.num_bits = 64;
478 field.out_value = buffer;
479 field.in_value = NULL;
481 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
482 jtag_execute_queue();
484 jtag_add_sleep(10);
486 /* wait for erase completion */
487 while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY)) {
488 alive_sleep(1);
491 free(buffer);
493 str9xpec_isc_disable(bank);
495 return status;
498 static int str9xpec_erase(struct flash_bank_s *bank, int first, int last)
500 int status;
502 status = str9xpec_erase_area(bank, first, last);
504 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
505 return ERROR_FLASH_OPERATION_FAILED;
507 return ERROR_OK;
510 static int str9xpec_lock_device(struct flash_bank_s *bank)
512 scan_field_t field;
513 uint8_t status;
514 jtag_tap_t *tap;
515 str9xpec_flash_controller_t *str9xpec_info = NULL;
517 str9xpec_info = bank->driver_priv;
518 tap = str9xpec_info->tap;
520 if (!str9xpec_info->isc_enable) {
521 str9xpec_isc_enable( bank );
524 if (!str9xpec_info->isc_enable) {
525 return ISC_STATUS_ERROR;
528 /* set security address */
529 str9xpec_set_address(bank, 0x80);
531 /* execute ISC_PROGRAM command */
532 str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);
534 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
536 do {
537 field.tap = tap;
538 field.num_bits = 8;
539 field.out_value = NULL;
540 field.in_value = &status;
542 jtag_add_dr_scan(1, &field, jtag_get_end_state());
543 jtag_execute_queue();
545 } while(!(status & ISC_STATUS_BUSY));
547 str9xpec_isc_disable(bank);
549 return status;
552 static int str9xpec_unlock_device(struct flash_bank_s *bank)
554 uint8_t status;
556 status = str9xpec_erase_area(bank, 0, 255);
558 return status;
561 static int str9xpec_protect(struct flash_bank_s *bank, int set, int first, int last)
563 uint8_t status;
564 int i;
566 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
568 status = str9xpec_read_config(bank);
570 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
571 return ERROR_FLASH_OPERATION_FAILED;
573 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
575 /* last bank: 0xFF signals a full device protect */
576 if (last == 0xFF)
578 if( set )
580 status = str9xpec_lock_device(bank);
582 else
584 /* perform full erase to unlock device */
585 status = str9xpec_unlock_device(bank);
588 else
590 for (i = first; i <= last; i++)
592 if( set )
593 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
594 else
595 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
598 status = str9xpec_write_options(bank);
601 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
602 return ERROR_FLASH_OPERATION_FAILED;
604 return ERROR_OK;
607 static int str9xpec_set_address(struct flash_bank_s *bank, uint8_t sector)
609 jtag_tap_t *tap;
610 scan_field_t field;
611 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
613 tap = str9xpec_info->tap;
615 /* set flash controller address */
616 str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);
618 field.tap = tap;
619 field.num_bits = 8;
620 field.out_value = &sector;
621 field.in_value = NULL;
623 jtag_add_dr_scan(1, &field, jtag_get_end_state());
625 return ERROR_OK;
628 static int str9xpec_write(struct flash_bank_s *bank, uint8_t *buffer, u32 offset, u32 count)
630 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
631 u32 dwords_remaining = (count / 8);
632 u32 bytes_remaining = (count & 0x00000007);
633 u32 bytes_written = 0;
634 uint8_t status;
635 u32 check_address = offset;
636 jtag_tap_t *tap;
637 scan_field_t field;
638 uint8_t *scanbuf;
639 int i;
640 int first_sector = 0;
641 int last_sector = 0;
643 tap = str9xpec_info->tap;
645 if (!str9xpec_info->isc_enable) {
646 str9xpec_isc_enable(bank);
649 if (!str9xpec_info->isc_enable) {
650 return ERROR_FLASH_OPERATION_FAILED;
653 if (offset & 0x7)
655 LOG_WARNING("offset 0x%x breaks required 8-byte alignment", offset);
656 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
659 for (i = 0; i < bank->num_sectors; i++)
661 u32 sec_start = bank->sectors[i].offset;
662 u32 sec_end = sec_start + bank->sectors[i].size;
664 /* check if destination falls within the current sector */
665 if ((check_address >= sec_start) && (check_address < sec_end))
667 /* check if destination ends in the current sector */
668 if (offset + count < sec_end)
669 check_address = offset + count;
670 else
671 check_address = sec_end;
674 if ((offset >= sec_start) && (offset < sec_end)){
675 first_sector = i;
678 if ((offset + count >= sec_start) && (offset + count < sec_end)){
679 last_sector = i;
683 if (check_address != offset + count)
684 return ERROR_FLASH_DST_OUT_OF_BANK;
686 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
688 scanbuf = calloc(CEIL(64, 8), 1);
690 LOG_DEBUG("ISC_PROGRAM");
692 for (i = first_sector; i <= last_sector; i++)
694 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
696 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8) ? dwords_remaining : (bank->sectors[i].size/8);
698 while (dwords_remaining > 0)
700 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
702 field.tap = tap;
703 field.num_bits = 64;
704 field.out_value = (buffer + bytes_written);
705 field.in_value = NULL;
707 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
709 /* small delay before polling */
710 jtag_add_sleep(50);
712 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
714 do {
715 field.tap = tap;
716 field.num_bits = 8;
717 field.out_value = NULL;
718 field.in_value = scanbuf;
720 jtag_add_dr_scan(1, &field, jtag_get_end_state());
721 jtag_execute_queue();
723 status = buf_get_u32(scanbuf, 0, 8);
725 } while(!(status & ISC_STATUS_BUSY));
727 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
728 return ERROR_FLASH_OPERATION_FAILED;
730 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
731 return ERROR_FLASH_OPERATION_FAILED; */
733 dwords_remaining--;
734 bytes_written += 8;
738 if (bytes_remaining)
740 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
741 int i = 0;
743 while(bytes_remaining > 0)
745 last_dword[i++] = *(buffer + bytes_written);
746 bytes_remaining--;
747 bytes_written++;
750 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
752 field.tap = tap;
753 field.num_bits = 64;
754 field.out_value = last_dword;
755 field.in_value = NULL;
757 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
759 /* small delay before polling */
760 jtag_add_sleep(50);
762 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
764 do {
765 field.tap = tap;
766 field.num_bits = 8;
767 field.out_value = NULL;
768 field.in_value = scanbuf;
770 jtag_add_dr_scan(1, &field, jtag_get_end_state());
771 jtag_execute_queue();
773 status = buf_get_u32(scanbuf, 0, 8);
775 } while(!(status & ISC_STATUS_BUSY));
777 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
778 return ERROR_FLASH_OPERATION_FAILED;
780 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
781 return ERROR_FLASH_OPERATION_FAILED; */
784 free(scanbuf);
786 str9xpec_isc_disable(bank);
788 return ERROR_OK;
791 static int str9xpec_probe(struct flash_bank_s *bank)
793 return ERROR_OK;
796 static int str9xpec_handle_part_id_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
798 flash_bank_t *bank;
799 scan_field_t field;
800 uint8_t *buffer = NULL;
801 jtag_tap_t *tap;
802 u32 idcode;
803 str9xpec_flash_controller_t *str9xpec_info = NULL;
805 if (argc < 1)
807 return ERROR_COMMAND_SYNTAX_ERROR;
810 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
811 if (!bank)
813 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
814 return ERROR_OK;
817 str9xpec_info = bank->driver_priv;
818 tap = str9xpec_info->tap;
820 buffer = calloc(CEIL(32, 8), 1);
822 str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
824 field.tap = tap;
825 field.num_bits = 32;
826 field.out_value = NULL;
827 field.in_value = buffer;
829 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
830 jtag_execute_queue();
832 idcode = buf_get_u32(buffer, 0, 32);
834 command_print(cmd_ctx, "str9xpec part id: 0x%8.8x", idcode);
836 free(buffer);
838 return ERROR_OK;
841 static int str9xpec_erase_check(struct flash_bank_s *bank)
843 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
846 static int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size)
848 snprintf(buf, buf_size, "str9xpec flash driver info" );
849 return ERROR_OK;
852 static int str9xpec_handle_flash_options_read_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
854 flash_bank_t *bank;
855 uint8_t status;
856 str9xpec_flash_controller_t *str9xpec_info = NULL;
858 if (argc < 1)
860 command_print(cmd_ctx, "str9xpec options_read <bank>");
861 return ERROR_OK;
864 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
865 if (!bank)
867 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
868 return ERROR_OK;
871 str9xpec_info = bank->driver_priv;
873 status = str9xpec_read_config(bank);
875 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
876 return ERROR_FLASH_OPERATION_FAILED;
878 /* boot bank */
879 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
880 command_print(cmd_ctx, "CS Map: bank1");
881 else
882 command_print(cmd_ctx, "CS Map: bank0");
884 /* OTP lock */
885 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
886 command_print(cmd_ctx, "OTP Lock: OTP Locked");
887 else
888 command_print(cmd_ctx, "OTP Lock: OTP Unlocked");
890 /* LVD Threshold */
891 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
892 command_print(cmd_ctx, "LVD Threshold: 2.7v");
893 else
894 command_print(cmd_ctx, "LVD Threshold: 2.4v");
896 /* LVD reset warning */
897 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
898 command_print(cmd_ctx, "LVD Reset Warning: VDD or VDDQ Inputs");
899 else
900 command_print(cmd_ctx, "LVD Reset Warning: VDD Input Only");
902 /* LVD reset select */
903 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
904 command_print(cmd_ctx, "LVD Reset Selection: VDD or VDDQ Inputs");
905 else
906 command_print(cmd_ctx, "LVD Reset Selection: VDD Input Only");
908 return ERROR_OK;
911 static int str9xpec_write_options(struct flash_bank_s *bank)
913 scan_field_t field;
914 uint8_t status;
915 jtag_tap_t *tap;
916 str9xpec_flash_controller_t *str9xpec_info = NULL;
918 str9xpec_info = bank->driver_priv;
919 tap = str9xpec_info->tap;
921 /* erase config options first */
922 status = str9xpec_erase_area( bank, 0xFE, 0xFE );
924 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
925 return status;
927 if (!str9xpec_info->isc_enable) {
928 str9xpec_isc_enable( bank );
931 if (!str9xpec_info->isc_enable) {
932 return ISC_STATUS_ERROR;
935 /* according to data 64th bit has to be set */
936 buf_set_u32(str9xpec_info->options, 63, 1, 1);
938 /* set option byte address */
939 str9xpec_set_address(bank, 0x50);
941 /* execute ISC_PROGRAM command */
942 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
944 field.tap = tap;
945 field.num_bits = 64;
946 field.out_value = str9xpec_info->options;
947 field.in_value = NULL;
949 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
951 /* small delay before polling */
952 jtag_add_sleep(50);
954 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
956 do {
957 field.tap = tap;
958 field.num_bits = 8;
959 field.out_value = NULL;
960 field.in_value = &status;
962 jtag_add_dr_scan(1, &field, jtag_get_end_state());
963 jtag_execute_queue();
965 } while(!(status & ISC_STATUS_BUSY));
967 str9xpec_isc_disable(bank);
969 return status;
972 static int str9xpec_handle_flash_options_write_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
974 flash_bank_t *bank;
975 uint8_t status;
977 if (argc < 1)
979 command_print(cmd_ctx, "str9xpec options_write <bank>");
980 return ERROR_OK;
983 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
984 if (!bank)
986 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
987 return ERROR_OK;
990 status = str9xpec_write_options(bank);
992 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
993 return ERROR_FLASH_OPERATION_FAILED;
995 return ERROR_OK;
998 static int str9xpec_handle_flash_options_cmap_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1000 flash_bank_t *bank;
1001 str9xpec_flash_controller_t *str9xpec_info = NULL;
1003 if (argc < 2)
1005 command_print(cmd_ctx, "str9xpec options_cmap <bank> <bank0|bank1>");
1006 return ERROR_OK;
1009 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1010 if (!bank)
1012 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1013 return ERROR_OK;
1016 str9xpec_info = bank->driver_priv;
1018 if (strcmp(args[1], "bank1") == 0)
1020 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
1022 else
1024 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
1027 return ERROR_OK;
1030 static int str9xpec_handle_flash_options_lvdthd_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1032 flash_bank_t *bank;
1033 str9xpec_flash_controller_t *str9xpec_info = NULL;
1035 if (argc < 2)
1037 command_print(cmd_ctx, "str9xpec options_lvdthd <bank> <2.4v|2.7v>");
1038 return ERROR_OK;
1041 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1042 if (!bank)
1044 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1045 return ERROR_OK;
1048 str9xpec_info = bank->driver_priv;
1050 if (strcmp(args[1], "2.7v") == 0)
1052 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
1054 else
1056 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
1059 return ERROR_OK;
1062 int str9xpec_handle_flash_options_lvdsel_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1064 flash_bank_t *bank;
1065 str9xpec_flash_controller_t *str9xpec_info = NULL;
1067 if (argc < 2)
1069 command_print(cmd_ctx, "str9xpec options_lvdsel <bank> <vdd|vdd_vddq>");
1070 return ERROR_OK;
1073 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1074 if (!bank)
1076 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1077 return ERROR_OK;
1080 str9xpec_info = bank->driver_priv;
1082 if (strcmp(args[1], "vdd_vddq") == 0)
1084 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
1086 else
1088 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
1091 return ERROR_OK;
1094 static int str9xpec_handle_flash_options_lvdwarn_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1096 flash_bank_t *bank;
1097 str9xpec_flash_controller_t *str9xpec_info = NULL;
1099 if (argc < 2)
1101 command_print(cmd_ctx, "str9xpec options_lvdwarn <bank> <vdd|vdd_vddq>");
1102 return ERROR_OK;
1105 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1106 if (!bank)
1108 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1109 return ERROR_OK;
1112 str9xpec_info = bank->driver_priv;
1114 if (strcmp(args[1], "vdd_vddq") == 0)
1116 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
1118 else
1120 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1123 return ERROR_OK;
1126 static int str9xpec_handle_flash_lock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1128 uint8_t status;
1129 flash_bank_t *bank;
1131 if (argc < 1)
1133 command_print(cmd_ctx, "str9xpec lock <bank>");
1134 return ERROR_OK;
1137 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1138 if (!bank)
1140 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1141 return ERROR_OK;
1144 status = str9xpec_lock_device(bank);
1146 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1147 return ERROR_FLASH_OPERATION_FAILED;
1149 return ERROR_OK;
1152 static int str9xpec_handle_flash_unlock_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1154 uint8_t status;
1155 flash_bank_t *bank;
1157 if (argc < 1)
1159 command_print(cmd_ctx, "str9xpec unlock <bank>");
1160 return ERROR_OK;
1163 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1164 if (!bank)
1166 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1167 return ERROR_OK;
1170 status = str9xpec_unlock_device(bank);
1172 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1173 return ERROR_FLASH_OPERATION_FAILED;
1175 return ERROR_OK;
1178 static int str9xpec_handle_flash_enable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1180 int retval;
1181 flash_bank_t *bank;
1182 jtag_tap_t *tap0;
1183 jtag_tap_t *tap1;
1184 jtag_tap_t *tap2;
1185 str9xpec_flash_controller_t *str9xpec_info = NULL;
1187 if (argc < 1)
1189 command_print(cmd_ctx, "str9xpec enable_turbo <bank>");
1190 return ERROR_OK;
1193 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1194 if (!bank)
1196 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1197 return ERROR_OK;
1200 str9xpec_info = bank->driver_priv;
1202 tap0 = str9xpec_info->tap;
1204 /* remove arm core from chain - enter turbo mode */
1205 tap1 = tap0->next_tap;
1206 if (tap1 == NULL)
1208 /* things are *WRONG* */
1209 command_print(cmd_ctx,"**STR9FLASH** (tap1) invalid chain?");
1210 return ERROR_OK;
1212 tap2 = tap1->next_tap;
1213 if (tap2 == NULL)
1215 /* things are *WRONG* */
1216 command_print(cmd_ctx,"**STR9FLASH** (tap2) invalid chain?");
1217 return ERROR_OK;
1220 /* enable turbo mode - TURBO-PROG-ENABLE */
1221 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1222 if ((retval = jtag_execute_queue()) != ERROR_OK)
1223 return retval;
1225 /* modify scan chain - str9 core has been removed */
1226 tap1->enabled = 0;
1228 return ERROR_OK;
1231 static int str9xpec_handle_flash_disable_turbo_command(struct command_context_s *cmd_ctx, char *cmd, char **args, int argc)
1233 flash_bank_t *bank;
1234 jtag_tap_t *tap;
1235 str9xpec_flash_controller_t *str9xpec_info = NULL;
1237 if (argc < 1)
1239 command_print(cmd_ctx, "str9xpec disable_turbo <bank>");
1240 return ERROR_OK;
1243 bank = get_flash_bank_by_num(strtoul(args[0], NULL, 0));
1244 if (!bank)
1246 command_print(cmd_ctx, "flash bank '#%s' is out of bounds", args[0]);
1247 return ERROR_OK;
1250 str9xpec_info = bank->driver_priv;
1251 tap = str9xpec_info->tap;
1253 if (tap == NULL)
1254 return ERROR_FAIL;
1256 /* exit turbo mode via RESET */
1257 str9xpec_set_instr(tap, ISC_NOOP, TAP_RESET);
1258 jtag_execute_queue();
1260 /* restore previous scan chain */
1261 if (tap->next_tap) {
1262 tap->next_tap->enabled = 1;
1265 return ERROR_OK;