command_handler: change 'args' to CMD_ARGV
[openocd/cmsis-dap.git] / src / flash / str9xpec.c
bloba87d0fff46402e6891f2435b79a428b06c7c3f73
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_erase_area(struct flash_bank *bank, int first, int last);
32 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector);
33 static int str9xpec_write_options(struct flash_bank *bank);
35 int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
37 if (tap == NULL) {
38 return ERROR_TARGET_INVALID;
41 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr)
43 struct scan_field field;
45 field.tap = tap;
46 field.num_bits = tap->ir_length;
47 field.out_value = calloc(DIV_ROUND_UP(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);
56 return ERROR_OK;
59 static uint8_t str9xpec_isc_status(struct jtag_tap *tap)
61 struct scan_field field;
62 uint8_t status;
64 if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
65 return ISC_STATUS_ERROR;
67 field.tap = tap;
68 field.num_bits = 8;
69 field.out_value = NULL;
70 field.in_value = &status;
73 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
74 jtag_execute_queue();
76 LOG_DEBUG("status: 0x%2.2x", status);
78 if (status & ISC_STATUS_SECURITY)
79 LOG_INFO("Device Security Bit Set");
81 return status;
84 static int str9xpec_isc_enable(struct flash_bank *bank)
86 uint8_t status;
87 struct jtag_tap *tap;
88 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
90 tap = str9xpec_info->tap;
92 if (str9xpec_info->isc_enable)
93 return ERROR_OK;
95 /* enter isc mode */
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");
108 return ERROR_OK;
111 static int str9xpec_isc_disable(struct flash_bank *bank)
113 uint8_t status;
114 struct jtag_tap *tap;
115 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
117 tap = str9xpec_info->tap;
119 if (!str9xpec_info->isc_enable)
120 return ERROR_OK;
122 if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)
123 return ERROR_TARGET_INVALID;
125 /* delay to handle aborts */
126 jtag_add_sleep(50);
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");
137 return ERROR_OK;
140 static int str9xpec_read_config(struct flash_bank *bank)
142 struct scan_field field;
143 uint8_t status;
144 struct jtag_tap *tap;
146 struct str9xpec_flash_controller *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);
155 field.tap = tap;
156 field.num_bits = 64;
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);
166 return status;
169 static int str9xpec_build_block_list(struct flash_bank *bank)
171 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
173 int i;
174 int num_sectors;
175 int b0_sectors = 0, b1_sectors = 0;
176 uint32_t offset = 0;
177 int b1_size = 0x2000;
179 switch (bank->size)
181 case (256 * 1024):
182 b0_sectors = 4;
183 break;
184 case (512 * 1024):
185 b0_sectors = 8;
186 break;
187 case (1024 * 1024):
188 b0_sectors = 16;
189 break;
190 case (2048 * 1024):
191 b0_sectors = 32;
192 break;
193 case (128 * 1024):
194 b1_size = 0x4000;
195 b1_sectors = 8;
196 break;
197 case (32 * 1024):
198 b1_sectors = 4;
199 break;
200 default:
201 LOG_ERROR("BUG: unknown bank->size encountered");
202 exit(-1);
205 num_sectors = b0_sectors + b1_sectors;
207 bank->num_sectors = num_sectors;
208 bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
209 str9xpec_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
211 num_sectors = 0;
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;
233 return ERROR_OK;
236 /* flash bank str9x <base> <size> 0 0 <target#>
238 FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)
240 struct str9xpec_flash_controller *str9xpec_info;
241 struct arm *armv4_5 = NULL;
242 struct arm7_9_common *arm7_9 = NULL;
243 struct arm_jtag *jtag_info = NULL;
245 if (CMD_ARGC < 6)
247 LOG_WARNING("incomplete flash_bank str9x configuration");
248 return ERROR_FLASH_BANK_INVALID;
251 str9xpec_info = malloc(sizeof(struct str9xpec_flash_controller));
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);
269 return ERROR_OK;
272 static int str9xpec_blank_check(struct flash_bank *bank, int first, int last)
274 struct scan_field field;
275 uint8_t status;
276 struct jtag_tap *tap;
277 int i;
278 uint8_t *buffer = NULL;
280 struct str9xpec_flash_controller *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(DIV_ROUND_UP(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);
303 field.tap = tap;
304 field.num_bits = 64;
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 */
312 field.tap = tap;
313 field.num_bits = 64;
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;
326 else
327 bank->sectors[i].is_erased = 1;
330 free(buffer);
332 str9xpec_isc_disable(bank);
334 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
335 return ERROR_FLASH_OPERATION_FAILED;
336 return ERROR_OK;
339 static int str9xpec_protect_check(struct flash_bank *bank)
341 uint8_t status;
342 int i;
344 struct str9xpec_flash_controller *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;
352 else
353 bank->sectors[i].is_protected = 0;
356 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
357 return ERROR_FLASH_OPERATION_FAILED;
358 return ERROR_OK;
361 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last)
363 struct scan_field field;
364 uint8_t status;
365 struct jtag_tap *tap;
366 int i;
367 uint8_t *buffer = NULL;
369 struct str9xpec_flash_controller *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(DIV_ROUND_UP(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 */
387 if (last == 0xFF)
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);
397 else
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);
409 field.tap = tap;
410 field.num_bits = 64;
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();
417 jtag_add_sleep(10);
419 /* wait for erase completion */
420 while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY)) {
421 alive_sleep(1);
424 free(buffer);
426 str9xpec_isc_disable(bank);
428 return status;
431 static int str9xpec_erase(struct flash_bank *bank, int first, int last)
433 int status;
435 status = str9xpec_erase_area(bank, first, last);
437 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
438 return ERROR_FLASH_OPERATION_FAILED;
440 return ERROR_OK;
443 static int str9xpec_lock_device(struct flash_bank *bank)
445 struct scan_field field;
446 uint8_t status;
447 struct jtag_tap *tap;
448 struct str9xpec_flash_controller *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);
469 do {
470 field.tap = tap;
471 field.num_bits = 8;
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);
482 return status;
485 static int str9xpec_unlock_device(struct flash_bank *bank)
487 uint8_t status;
489 status = str9xpec_erase_area(bank, 0, 255);
491 return status;
494 static int str9xpec_protect(struct flash_bank *bank, int set, int first, int last)
496 uint8_t status;
497 int i;
499 struct str9xpec_flash_controller *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 */
509 if (last == 0xFF)
511 if (set)
513 status = str9xpec_lock_device(bank);
515 else
517 /* perform full erase to unlock device */
518 status = str9xpec_unlock_device(bank);
521 else
523 for (i = first; i <= last; i++)
525 if (set)
526 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
527 else
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;
537 return ERROR_OK;
540 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector)
542 struct jtag_tap *tap;
543 struct scan_field field;
544 struct str9xpec_flash_controller *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);
551 field.tap = tap;
552 field.num_bits = 8;
553 field.out_value = &sector;
554 field.in_value = NULL;
556 jtag_add_dr_scan(1, &field, jtag_get_end_state());
558 return ERROR_OK;
561 static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
563 struct str9xpec_flash_controller *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;
567 uint8_t status;
568 uint32_t check_address = offset;
569 struct jtag_tap *tap;
570 struct scan_field field;
571 uint8_t *scanbuf;
572 int i;
573 int first_sector = 0;
574 int last_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;
586 if (offset & 0x7)
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;
603 else
604 check_address = sec_end;
607 if ((offset >= sec_start) && (offset < sec_end)) {
608 first_sector = i;
611 if ((offset + count >= sec_start) && (offset + count < sec_end)) {
612 last_sector = i;
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(DIV_ROUND_UP(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);
635 field.tap = tap;
636 field.num_bits = 64;
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 */
643 jtag_add_sleep(50);
645 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
647 do {
648 field.tap = tap;
649 field.num_bits = 8;
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; */
666 dwords_remaining--;
667 bytes_written += 8;
671 if (bytes_remaining)
673 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
674 int i = 0;
676 while (bytes_remaining > 0)
678 last_dword[i++] = *(buffer + bytes_written);
679 bytes_remaining--;
680 bytes_written++;
683 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
685 field.tap = tap;
686 field.num_bits = 64;
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 */
693 jtag_add_sleep(50);
695 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
697 do {
698 field.tap = tap;
699 field.num_bits = 8;
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; */
717 free(scanbuf);
719 str9xpec_isc_disable(bank);
721 return ERROR_OK;
724 static int str9xpec_probe(struct flash_bank *bank)
726 return ERROR_OK;
729 COMMAND_HANDLER(str9xpec_handle_part_id_command)
731 struct scan_field field;
732 uint8_t *buffer = NULL;
733 struct jtag_tap *tap;
734 uint32_t idcode;
735 struct str9xpec_flash_controller *str9xpec_info = NULL;
737 if (CMD_ARGC < 1)
738 return ERROR_COMMAND_SYNTAX_ERROR;
740 struct flash_bank *bank;
741 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank_by_num, 0, &bank);
742 if (ERROR_OK != retval)
743 return retval;
745 str9xpec_info = bank->driver_priv;
746 tap = str9xpec_info->tap;
748 buffer = calloc(DIV_ROUND_UP(32, 8), 1);
750 str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
752 field.tap = tap;
753 field.num_bits = 32;
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);
764 free(buffer);
766 return ERROR_OK;
769 static int str9xpec_erase_check(struct flash_bank *bank)
771 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
774 static int str9xpec_info(struct flash_bank *bank, char *buf, int buf_size)
776 snprintf(buf, buf_size, "str9xpec flash driver info");
777 return ERROR_OK;
780 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
782 uint8_t status;
783 struct str9xpec_flash_controller *str9xpec_info = NULL;
785 if (CMD_ARGC < 1)
787 command_print(cmd_ctx, "str9xpec options_read <bank>");
788 return ERROR_OK;
791 struct flash_bank *bank;
792 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank_by_num, 0, &bank);
793 if (ERROR_OK != retval)
794 return 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;
803 /* boot bank */
804 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
805 command_print(cmd_ctx, "CS Map: bank1");
806 else
807 command_print(cmd_ctx, "CS Map: bank0");
809 /* OTP lock */
810 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
811 command_print(cmd_ctx, "OTP Lock: OTP Locked");
812 else
813 command_print(cmd_ctx, "OTP Lock: OTP Unlocked");
815 /* LVD Threshold */
816 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
817 command_print(cmd_ctx, "LVD Threshold: 2.7v");
818 else
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");
824 else
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");
830 else
831 command_print(cmd_ctx, "LVD Reset Selection: VDD Input Only");
833 return ERROR_OK;
836 static int str9xpec_write_options(struct flash_bank *bank)
838 struct scan_field field;
839 uint8_t status;
840 struct jtag_tap *tap;
841 struct str9xpec_flash_controller *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)
850 return status;
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);
869 field.tap = tap;
870 field.num_bits = 64;
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 */
877 jtag_add_sleep(50);
879 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
881 do {
882 field.tap = tap;
883 field.num_bits = 8;
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);
894 return status;
897 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
899 uint8_t status;
901 if (CMD_ARGC < 1)
903 command_print(cmd_ctx, "str9xpec options_write <bank>");
904 return ERROR_OK;
907 struct flash_bank *bank;
908 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank_by_num, 0, &bank);
909 if (ERROR_OK != retval)
910 return retval;
912 status = str9xpec_write_options(bank);
914 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
915 return ERROR_FLASH_OPERATION_FAILED;
917 return ERROR_OK;
920 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
922 struct str9xpec_flash_controller *str9xpec_info = NULL;
924 if (CMD_ARGC < 2)
926 command_print(cmd_ctx, "str9xpec options_cmap <bank> <bank0 | bank1>");
927 return ERROR_OK;
930 struct flash_bank *bank;
931 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank_by_num, 0, &bank);
932 if (ERROR_OK != retval)
933 return retval;
935 str9xpec_info = bank->driver_priv;
937 if (strcmp(CMD_ARGV[1], "bank1") == 0)
939 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
941 else
943 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
946 return ERROR_OK;
949 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
951 struct str9xpec_flash_controller *str9xpec_info = NULL;
953 if (CMD_ARGC < 2)
955 command_print(cmd_ctx, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
956 return ERROR_OK;
959 struct flash_bank *bank;
960 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank_by_num, 0, &bank);
961 if (ERROR_OK != retval)
962 return retval;
964 str9xpec_info = bank->driver_priv;
966 if (strcmp(CMD_ARGV[1], "2.7v") == 0)
968 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
970 else
972 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
975 return ERROR_OK;
978 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
980 struct str9xpec_flash_controller *str9xpec_info = NULL;
982 if (CMD_ARGC < 2)
984 command_print(cmd_ctx, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
985 return ERROR_OK;
988 struct flash_bank *bank;
989 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank_by_num, 0, &bank);
990 if (ERROR_OK != retval)
991 return retval;
993 str9xpec_info = bank->driver_priv;
995 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
997 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
999 else
1001 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
1004 return ERROR_OK;
1007 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
1009 struct str9xpec_flash_controller *str9xpec_info = NULL;
1011 if (CMD_ARGC < 2)
1013 command_print(cmd_ctx, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
1014 return ERROR_OK;
1017 struct flash_bank *bank;
1018 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank_by_num, 0, &bank);
1019 if (ERROR_OK != retval)
1020 return retval;
1022 str9xpec_info = bank->driver_priv;
1024 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
1026 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
1028 else
1030 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1033 return ERROR_OK;
1036 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
1038 uint8_t status;
1040 if (CMD_ARGC < 1)
1042 command_print(cmd_ctx, "str9xpec lock <bank>");
1043 return ERROR_OK;
1046 struct flash_bank *bank;
1047 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank_by_num, 0, &bank);
1048 if (ERROR_OK != retval)
1049 return retval;
1051 status = str9xpec_lock_device(bank);
1053 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1054 return ERROR_FLASH_OPERATION_FAILED;
1056 return ERROR_OK;
1059 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
1061 uint8_t status;
1063 if (CMD_ARGC < 1)
1065 command_print(cmd_ctx, "str9xpec unlock <bank>");
1066 return ERROR_OK;
1069 struct flash_bank *bank;
1070 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank_by_num, 0, &bank);
1071 if (ERROR_OK != retval)
1072 return retval;
1074 status = str9xpec_unlock_device(bank);
1076 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1077 return ERROR_FLASH_OPERATION_FAILED;
1079 return ERROR_OK;
1082 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
1084 struct jtag_tap *tap0;
1085 struct jtag_tap *tap1;
1086 struct jtag_tap *tap2;
1087 struct str9xpec_flash_controller *str9xpec_info = NULL;
1089 if (CMD_ARGC < 1)
1091 command_print(cmd_ctx, "str9xpec enable_turbo <bank>");
1092 return ERROR_OK;
1095 struct flash_bank *bank;
1096 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank_by_num, 0, &bank);
1097 if (ERROR_OK != retval)
1098 return 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;
1106 if (tap1 == NULL)
1108 /* things are *WRONG* */
1109 command_print(cmd_ctx,"**STR9FLASH** (tap1) invalid chain?");
1110 return ERROR_OK;
1112 tap2 = tap1->next_tap;
1113 if (tap2 == NULL)
1115 /* things are *WRONG* */
1116 command_print(cmd_ctx,"**STR9FLASH** (tap2) invalid chain?");
1117 return ERROR_OK;
1120 /* enable turbo mode - TURBO-PROG-ENABLE */
1121 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1122 if ((retval = jtag_execute_queue()) != ERROR_OK)
1123 return retval;
1125 /* modify scan chain - str9 core has been removed */
1126 tap1->enabled = 0;
1128 return ERROR_OK;
1131 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1133 struct jtag_tap *tap;
1134 struct str9xpec_flash_controller *str9xpec_info = NULL;
1136 if (CMD_ARGC < 1)
1138 command_print(cmd_ctx, "str9xpec disable_turbo <bank>");
1139 return ERROR_OK;
1142 struct flash_bank *bank;
1143 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank_by_num, 0, &bank);
1144 if (ERROR_OK != retval)
1145 return retval;
1147 str9xpec_info = bank->driver_priv;
1148 tap = str9xpec_info->tap;
1150 if (tap == NULL)
1151 return ERROR_FAIL;
1153 /* exit turbo mode via RESET */
1154 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1155 jtag_add_tlr();
1156 jtag_execute_queue();
1158 /* restore previous scan chain */
1159 if (tap->next_tap) {
1160 tap->next_tap->enabled = 1;
1163 return ERROR_OK;
1166 static int str9xpec_register_commands(struct command_context *cmd_ctx)
1168 struct command *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>");
1205 return ERROR_OK;
1208 struct flash_driver str9xpec_flash = {
1209 .name = "str9xpec",
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,