nrf51: Fix format string bugs in nrf51_info
[openocd.git] / src / flash / nor / str9xpec.c
blobe08495da05494b012fda61836b1178d33a2d111a
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 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
22 ***************************************************************************/
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
28 #include "imp.h"
29 #include <target/arm7_9_common.h>
31 /* ISC commands */
33 #define ISC_IDCODE 0xFE
34 #define ISC_MFG_READ 0x4C
35 #define ISC_CONFIGURATION 0x07
36 #define ISC_ENABLE 0x0C
37 #define ISC_DISABLE 0x0F
38 #define ISC_NOOP 0x10
39 #define ISC_ADDRESS_SHIFT 0x11
40 #define ISC_CLR_STATUS 0x13
41 #define ISC_PROGRAM 0x20
42 #define ISC_PROGRAM_SECURITY 0x22
43 #define ISC_PROGRAM_UC 0x23
44 #define ISC_ERASE 0x30
45 #define ISC_READ 0x50
46 #define ISC_BLANK_CHECK 0x60
48 /* ISC_DEFAULT bit definitions */
50 #define ISC_STATUS_SECURITY 0x40
51 #define ISC_STATUS_INT_ERROR 0x30
52 #define ISC_STATUS_MODE 0x08
53 #define ISC_STATUS_BUSY 0x04
54 #define ISC_STATUS_ERROR 0x03
56 /* Option bytes definitions */
58 #define STR9XPEC_OPT_CSMAPBIT 48
59 #define STR9XPEC_OPT_LVDTHRESBIT 49
60 #define STR9XPEC_OPT_LVDSELBIT 50
61 #define STR9XPEC_OPT_LVDWARNBIT 51
62 #define STR9XPEC_OPT_OTPBIT 63
64 enum str9xpec_status_codes {
65 STR9XPEC_INVALID_COMMAND = 1,
66 STR9XPEC_ISC_SUCCESS = 2,
67 STR9XPEC_ISC_DISABLED = 3,
68 STR9XPEC_ISC_INTFAIL = 32,
71 struct str9xpec_flash_controller {
72 struct jtag_tap *tap;
73 uint32_t *sector_bits;
74 int chain_pos;
75 int isc_enable;
76 uint8_t options[8];
79 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last);
80 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector);
81 static int str9xpec_write_options(struct flash_bank *bank);
83 static int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
85 if (tap == NULL)
86 return ERROR_TARGET_INVALID;
88 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {
89 struct scan_field field;
91 field.num_bits = tap->ir_length;
92 void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
93 field.out_value = t;
94 buf_set_u32(t, 0, field.num_bits, new_instr);
95 field.in_value = NULL;
97 jtag_add_ir_scan(tap, &field, end_state);
99 free(t);
102 return ERROR_OK;
105 static uint8_t str9xpec_isc_status(struct jtag_tap *tap)
107 struct scan_field field;
108 uint8_t status;
110 if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
111 return ISC_STATUS_ERROR;
113 field.num_bits = 8;
114 field.out_value = NULL;
115 field.in_value = &status;
118 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
119 jtag_execute_queue();
121 LOG_DEBUG("status: 0x%2.2x", status);
123 if (status & ISC_STATUS_SECURITY)
124 LOG_INFO("Device Security Bit Set");
126 return status;
129 static int str9xpec_isc_enable(struct flash_bank *bank)
131 uint8_t status;
132 struct jtag_tap *tap;
133 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
135 tap = str9xpec_info->tap;
137 if (str9xpec_info->isc_enable)
138 return ERROR_OK;
140 /* enter isc mode */
141 if (str9xpec_set_instr(tap, ISC_ENABLE, TAP_IDLE) != ERROR_OK)
142 return ERROR_TARGET_INVALID;
144 /* check ISC status */
145 status = str9xpec_isc_status(tap);
146 if (status & ISC_STATUS_MODE) {
147 /* we have entered isc mode */
148 str9xpec_info->isc_enable = 1;
149 LOG_DEBUG("ISC_MODE Enabled");
152 return ERROR_OK;
155 static int str9xpec_isc_disable(struct flash_bank *bank)
157 uint8_t status;
158 struct jtag_tap *tap;
159 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
161 tap = str9xpec_info->tap;
163 if (!str9xpec_info->isc_enable)
164 return ERROR_OK;
166 if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)
167 return ERROR_TARGET_INVALID;
169 /* delay to handle aborts */
170 jtag_add_sleep(50);
172 /* check ISC status */
173 status = str9xpec_isc_status(tap);
174 if (!(status & ISC_STATUS_MODE)) {
175 /* we have left isc mode */
176 str9xpec_info->isc_enable = 0;
177 LOG_DEBUG("ISC_MODE Disabled");
180 return ERROR_OK;
183 static int str9xpec_read_config(struct flash_bank *bank)
185 struct scan_field field;
186 uint8_t status;
187 struct jtag_tap *tap;
189 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
191 tap = str9xpec_info->tap;
193 LOG_DEBUG("ISC_CONFIGURATION");
195 /* execute ISC_CONFIGURATION command */
196 str9xpec_set_instr(tap, ISC_CONFIGURATION, TAP_IRPAUSE);
198 field.num_bits = 64;
199 field.out_value = NULL;
200 field.in_value = str9xpec_info->options;
202 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
203 jtag_execute_queue();
205 status = str9xpec_isc_status(tap);
207 return status;
210 static int str9xpec_build_block_list(struct flash_bank *bank)
212 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
214 int i;
215 int num_sectors;
216 int b0_sectors = 0, b1_sectors = 0;
217 uint32_t offset = 0;
218 int b1_size = 0x2000;
220 switch (bank->size) {
221 case (256 * 1024):
222 b0_sectors = 4;
223 break;
224 case (512 * 1024):
225 b0_sectors = 8;
226 break;
227 case (1024 * 1024):
228 b0_sectors = 16;
229 break;
230 case (2048 * 1024):
231 b0_sectors = 32;
232 break;
233 case (128 * 1024):
234 b1_size = 0x4000;
235 b1_sectors = 8;
236 break;
237 case (32 * 1024):
238 b1_sectors = 4;
239 break;
240 default:
241 LOG_ERROR("BUG: unknown bank->size encountered");
242 exit(-1);
245 num_sectors = b0_sectors + b1_sectors;
247 bank->num_sectors = num_sectors;
248 bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
249 str9xpec_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
251 num_sectors = 0;
253 for (i = 0; i < b0_sectors; i++) {
254 bank->sectors[num_sectors].offset = offset;
255 bank->sectors[num_sectors].size = 0x10000;
256 offset += bank->sectors[i].size;
257 bank->sectors[num_sectors].is_erased = -1;
258 bank->sectors[num_sectors].is_protected = 1;
259 str9xpec_info->sector_bits[num_sectors++] = i;
262 for (i = 0; i < b1_sectors; i++) {
263 bank->sectors[num_sectors].offset = offset;
264 bank->sectors[num_sectors].size = b1_size;
265 offset += bank->sectors[i].size;
266 bank->sectors[num_sectors].is_erased = -1;
267 bank->sectors[num_sectors].is_protected = 1;
268 str9xpec_info->sector_bits[num_sectors++] = i + 32;
271 return ERROR_OK;
274 /* flash bank str9x <base> <size> 0 0 <target#>
276 FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)
278 struct str9xpec_flash_controller *str9xpec_info;
279 struct arm *arm = NULL;
280 struct arm7_9_common *arm7_9 = NULL;
281 struct arm_jtag *jtag_info = NULL;
283 if (CMD_ARGC < 6)
284 return ERROR_COMMAND_SYNTAX_ERROR;
286 str9xpec_info = malloc(sizeof(struct str9xpec_flash_controller));
287 bank->driver_priv = str9xpec_info;
289 /* REVISIT verify that the jtag position of flash controller is
290 * right after *THIS* core, which must be a STR9xx core ...
292 arm = bank->target->arch_info;
293 arm7_9 = arm->arch_info;
294 jtag_info = &arm7_9->jtag_info;
296 /* The core is the next tap after the flash controller in the chain */
297 str9xpec_info->tap = jtag_tap_by_position(jtag_info->tap->abs_chain_position - 1);
298 str9xpec_info->isc_enable = 0;
300 str9xpec_build_block_list(bank);
302 /* clear option byte register */
303 buf_set_u32(str9xpec_info->options, 0, 64, 0);
305 return ERROR_OK;
308 static int str9xpec_blank_check(struct flash_bank *bank, int first, int last)
310 struct scan_field field;
311 uint8_t status;
312 struct jtag_tap *tap;
313 int i;
314 uint8_t *buffer = NULL;
316 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
318 tap = str9xpec_info->tap;
320 if (!str9xpec_info->isc_enable)
321 str9xpec_isc_enable(bank);
323 if (!str9xpec_info->isc_enable)
324 return ERROR_FLASH_OPERATION_FAILED;
326 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
328 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
330 for (i = first; i <= last; i++)
331 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
333 /* execute ISC_BLANK_CHECK command */
334 str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);
336 field.num_bits = 64;
337 field.out_value = buffer;
338 field.in_value = NULL;
340 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
341 jtag_add_sleep(40000);
343 /* read blank check result */
344 field.num_bits = 64;
345 field.out_value = NULL;
346 field.in_value = buffer;
348 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
349 jtag_execute_queue();
351 status = str9xpec_isc_status(tap);
353 for (i = first; i <= last; i++) {
354 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
355 bank->sectors[i].is_erased = 0;
356 else
357 bank->sectors[i].is_erased = 1;
360 free(buffer);
362 str9xpec_isc_disable(bank);
364 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
365 return ERROR_FLASH_OPERATION_FAILED;
366 return ERROR_OK;
369 static int str9xpec_protect_check(struct flash_bank *bank)
371 uint8_t status;
372 int i;
374 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
376 status = str9xpec_read_config(bank);
378 for (i = 0; i < bank->num_sectors; i++) {
379 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
380 bank->sectors[i].is_protected = 1;
381 else
382 bank->sectors[i].is_protected = 0;
385 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
386 return ERROR_FLASH_OPERATION_FAILED;
387 return ERROR_OK;
390 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last)
392 struct scan_field field;
393 uint8_t status;
394 struct jtag_tap *tap;
395 int i;
396 uint8_t *buffer = NULL;
398 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
400 tap = str9xpec_info->tap;
402 if (!str9xpec_info->isc_enable)
403 str9xpec_isc_enable(bank);
405 if (!str9xpec_info->isc_enable)
406 return ISC_STATUS_ERROR;
408 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
410 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
412 /* last bank: 0xFF signals a full erase (unlock complete device) */
413 /* last bank: 0xFE signals a option byte erase */
414 if (last == 0xFF) {
415 for (i = 0; i < 64; i++)
416 buf_set_u32(buffer, i, 1, 1);
417 } else if (last == 0xFE)
418 buf_set_u32(buffer, 49, 1, 1);
419 else {
420 for (i = first; i <= last; i++)
421 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
424 LOG_DEBUG("ISC_ERASE");
426 /* execute ISC_ERASE command */
427 str9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);
429 field.num_bits = 64;
430 field.out_value = buffer;
431 field.in_value = NULL;
433 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
434 jtag_execute_queue();
436 jtag_add_sleep(10);
438 /* wait for erase completion */
439 while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY))
440 alive_sleep(1);
442 free(buffer);
444 str9xpec_isc_disable(bank);
446 return status;
449 static int str9xpec_erase(struct flash_bank *bank, int first, int last)
451 int status;
453 status = str9xpec_erase_area(bank, first, last);
455 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
456 return ERROR_FLASH_OPERATION_FAILED;
458 return ERROR_OK;
461 static int str9xpec_lock_device(struct flash_bank *bank)
463 struct scan_field field;
464 uint8_t status;
465 struct jtag_tap *tap;
466 struct str9xpec_flash_controller *str9xpec_info = NULL;
468 str9xpec_info = bank->driver_priv;
469 tap = str9xpec_info->tap;
471 if (!str9xpec_info->isc_enable)
472 str9xpec_isc_enable(bank);
474 if (!str9xpec_info->isc_enable)
475 return ISC_STATUS_ERROR;
477 /* set security address */
478 str9xpec_set_address(bank, 0x80);
480 /* execute ISC_PROGRAM command */
481 str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);
483 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
485 do {
486 field.num_bits = 8;
487 field.out_value = NULL;
488 field.in_value = &status;
490 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
491 jtag_execute_queue();
493 } while (!(status & ISC_STATUS_BUSY));
495 str9xpec_isc_disable(bank);
497 return status;
500 static int str9xpec_unlock_device(struct flash_bank *bank)
502 uint8_t status;
504 status = str9xpec_erase_area(bank, 0, 255);
506 return status;
509 static int str9xpec_protect(struct flash_bank *bank, int set, int first, int last)
511 uint8_t status;
512 int i;
514 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
516 status = str9xpec_read_config(bank);
518 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
519 return ERROR_FLASH_OPERATION_FAILED;
521 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
523 /* last bank: 0xFF signals a full device protect */
524 if (last == 0xFF) {
525 if (set)
526 status = str9xpec_lock_device(bank);
527 else {
528 /* perform full erase to unlock device */
529 status = str9xpec_unlock_device(bank);
531 } else {
532 for (i = first; i <= last; i++) {
533 if (set)
534 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
535 else
536 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
539 status = str9xpec_write_options(bank);
542 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
543 return ERROR_FLASH_OPERATION_FAILED;
545 return ERROR_OK;
548 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector)
550 struct jtag_tap *tap;
551 struct scan_field field;
552 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
554 tap = str9xpec_info->tap;
556 /* set flash controller address */
557 str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);
559 field.num_bits = 8;
560 field.out_value = &sector;
561 field.in_value = NULL;
563 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
565 return ERROR_OK;
568 static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer,
569 uint32_t offset, uint32_t count)
571 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
572 uint32_t dwords_remaining = (count / 8);
573 uint32_t bytes_remaining = (count & 0x00000007);
574 uint32_t bytes_written = 0;
575 uint8_t status;
576 uint32_t check_address = offset;
577 struct jtag_tap *tap;
578 struct scan_field field;
579 uint8_t *scanbuf;
580 int i;
581 int first_sector = 0;
582 int last_sector = 0;
584 tap = str9xpec_info->tap;
586 if (!str9xpec_info->isc_enable)
587 str9xpec_isc_enable(bank);
589 if (!str9xpec_info->isc_enable)
590 return ERROR_FLASH_OPERATION_FAILED;
592 if (offset & 0x7) {
593 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
594 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
597 for (i = 0; i < bank->num_sectors; i++) {
598 uint32_t sec_start = bank->sectors[i].offset;
599 uint32_t sec_end = sec_start + bank->sectors[i].size;
601 /* check if destination falls within the current sector */
602 if ((check_address >= sec_start) && (check_address < sec_end)) {
603 /* check if destination ends in the current sector */
604 if (offset + count < sec_end)
605 check_address = offset + count;
606 else
607 check_address = sec_end;
610 if ((offset >= sec_start) && (offset < sec_end))
611 first_sector = i;
613 if ((offset + count >= sec_start) && (offset + count < sec_end))
614 last_sector = i;
617 if (check_address != offset + count)
618 return ERROR_FLASH_DST_OUT_OF_BANK;
620 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
622 scanbuf = calloc(DIV_ROUND_UP(64, 8), 1);
624 LOG_DEBUG("ISC_PROGRAM");
626 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)
630 ? dwords_remaining : (bank->sectors[i].size/8);
632 while (dwords_remaining > 0) {
633 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
635 field.num_bits = 64;
636 field.out_value = (buffer + bytes_written);
637 field.in_value = NULL;
639 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
641 /* small delay before polling */
642 jtag_add_sleep(50);
644 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
646 do {
647 field.num_bits = 8;
648 field.out_value = NULL;
649 field.in_value = scanbuf;
651 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
652 jtag_execute_queue();
654 status = buf_get_u32(scanbuf, 0, 8);
656 } while (!(status & ISC_STATUS_BUSY));
658 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
659 return ERROR_FLASH_OPERATION_FAILED;
661 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
662 return ERROR_FLASH_OPERATION_FAILED; */
664 dwords_remaining--;
665 bytes_written += 8;
669 if (bytes_remaining) {
670 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
672 /* copy the last remaining bytes into the write buffer */
673 memcpy(last_dword, buffer+bytes_written, bytes_remaining);
675 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
677 field.num_bits = 64;
678 field.out_value = last_dword;
679 field.in_value = NULL;
681 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
683 /* small delay before polling */
684 jtag_add_sleep(50);
686 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
688 do {
689 field.num_bits = 8;
690 field.out_value = NULL;
691 field.in_value = scanbuf;
693 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
694 jtag_execute_queue();
696 status = buf_get_u32(scanbuf, 0, 8);
698 } while (!(status & ISC_STATUS_BUSY));
700 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
701 return ERROR_FLASH_OPERATION_FAILED;
703 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
704 return ERROR_FLASH_OPERATION_FAILED; */
707 free(scanbuf);
709 str9xpec_isc_disable(bank);
711 return ERROR_OK;
714 static int str9xpec_probe(struct flash_bank *bank)
716 return ERROR_OK;
719 COMMAND_HANDLER(str9xpec_handle_part_id_command)
721 struct scan_field field;
722 uint8_t *buffer = NULL;
723 struct jtag_tap *tap;
724 uint32_t idcode;
725 struct str9xpec_flash_controller *str9xpec_info = NULL;
727 if (CMD_ARGC < 1)
728 return ERROR_COMMAND_SYNTAX_ERROR;
730 struct flash_bank *bank;
731 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
732 if (ERROR_OK != retval)
733 return retval;
735 str9xpec_info = bank->driver_priv;
736 tap = str9xpec_info->tap;
738 buffer = calloc(DIV_ROUND_UP(32, 8), 1);
740 str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
742 field.num_bits = 32;
743 field.out_value = NULL;
744 field.in_value = buffer;
746 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
747 jtag_execute_queue();
749 idcode = buf_get_u32(buffer, 0, 32);
751 command_print(CMD_CTX, "str9xpec part id: 0x%8.8" PRIx32 "", idcode);
753 free(buffer);
755 return ERROR_OK;
758 static int str9xpec_erase_check(struct flash_bank *bank)
760 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
763 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
765 uint8_t status;
766 struct str9xpec_flash_controller *str9xpec_info = NULL;
768 if (CMD_ARGC < 1)
769 return ERROR_COMMAND_SYNTAX_ERROR;
771 struct flash_bank *bank;
772 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
773 if (ERROR_OK != retval)
774 return retval;
776 str9xpec_info = bank->driver_priv;
778 status = str9xpec_read_config(bank);
780 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
781 return ERROR_FLASH_OPERATION_FAILED;
783 /* boot bank */
784 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
785 command_print(CMD_CTX, "CS Map: bank1");
786 else
787 command_print(CMD_CTX, "CS Map: bank0");
789 /* OTP lock */
790 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
791 command_print(CMD_CTX, "OTP Lock: OTP Locked");
792 else
793 command_print(CMD_CTX, "OTP Lock: OTP Unlocked");
795 /* LVD Threshold */
796 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
797 command_print(CMD_CTX, "LVD Threshold: 2.7v");
798 else
799 command_print(CMD_CTX, "LVD Threshold: 2.4v");
801 /* LVD reset warning */
802 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
803 command_print(CMD_CTX, "LVD Reset Warning: VDD or VDDQ Inputs");
804 else
805 command_print(CMD_CTX, "LVD Reset Warning: VDD Input Only");
807 /* LVD reset select */
808 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
809 command_print(CMD_CTX, "LVD Reset Selection: VDD or VDDQ Inputs");
810 else
811 command_print(CMD_CTX, "LVD Reset Selection: VDD Input Only");
813 return ERROR_OK;
816 static int str9xpec_write_options(struct flash_bank *bank)
818 struct scan_field field;
819 uint8_t status;
820 struct jtag_tap *tap;
821 struct str9xpec_flash_controller *str9xpec_info = NULL;
823 str9xpec_info = bank->driver_priv;
824 tap = str9xpec_info->tap;
826 /* erase config options first */
827 status = str9xpec_erase_area(bank, 0xFE, 0xFE);
829 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
830 return status;
832 if (!str9xpec_info->isc_enable)
833 str9xpec_isc_enable(bank);
835 if (!str9xpec_info->isc_enable)
836 return ISC_STATUS_ERROR;
838 /* according to data 64th bit has to be set */
839 buf_set_u32(str9xpec_info->options, 63, 1, 1);
841 /* set option byte address */
842 str9xpec_set_address(bank, 0x50);
844 /* execute ISC_PROGRAM command */
845 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
847 field.num_bits = 64;
848 field.out_value = str9xpec_info->options;
849 field.in_value = NULL;
851 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
853 /* small delay before polling */
854 jtag_add_sleep(50);
856 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
858 do {
859 field.num_bits = 8;
860 field.out_value = NULL;
861 field.in_value = &status;
863 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
864 jtag_execute_queue();
866 } while (!(status & ISC_STATUS_BUSY));
868 str9xpec_isc_disable(bank);
870 return status;
873 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
875 uint8_t status;
877 if (CMD_ARGC < 1)
878 return ERROR_COMMAND_SYNTAX_ERROR;
880 struct flash_bank *bank;
881 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
882 if (ERROR_OK != retval)
883 return retval;
885 status = str9xpec_write_options(bank);
887 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
888 return ERROR_FLASH_OPERATION_FAILED;
890 command_print(CMD_CTX, "str9xpec write options complete.\n"
891 "INFO: a reset or power cycle is required "
892 "for the new settings to take effect.");
894 return ERROR_OK;
897 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
899 struct str9xpec_flash_controller *str9xpec_info = NULL;
901 if (CMD_ARGC < 2)
902 return ERROR_COMMAND_SYNTAX_ERROR;
904 struct flash_bank *bank;
905 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
906 if (ERROR_OK != retval)
907 return retval;
909 str9xpec_info = bank->driver_priv;
911 if (strcmp(CMD_ARGV[1], "bank1") == 0)
912 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
913 else
914 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
916 return ERROR_OK;
919 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
921 struct str9xpec_flash_controller *str9xpec_info = NULL;
923 if (CMD_ARGC < 2)
924 return ERROR_COMMAND_SYNTAX_ERROR;
926 struct flash_bank *bank;
927 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
928 if (ERROR_OK != retval)
929 return retval;
931 str9xpec_info = bank->driver_priv;
933 if (strcmp(CMD_ARGV[1], "2.7v") == 0)
934 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
935 else
936 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
938 return ERROR_OK;
941 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
943 struct str9xpec_flash_controller *str9xpec_info = NULL;
945 if (CMD_ARGC < 2)
946 return ERROR_COMMAND_SYNTAX_ERROR;
948 struct flash_bank *bank;
949 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
950 if (ERROR_OK != retval)
951 return retval;
953 str9xpec_info = bank->driver_priv;
955 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
956 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
957 else
958 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
960 return ERROR_OK;
963 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
965 struct str9xpec_flash_controller *str9xpec_info = NULL;
967 if (CMD_ARGC < 2)
968 return ERROR_COMMAND_SYNTAX_ERROR;
970 struct flash_bank *bank;
971 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
972 if (ERROR_OK != retval)
973 return retval;
975 str9xpec_info = bank->driver_priv;
977 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
978 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
979 else
980 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
982 return ERROR_OK;
985 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
987 uint8_t status;
989 if (CMD_ARGC < 1)
990 return ERROR_COMMAND_SYNTAX_ERROR;
992 struct flash_bank *bank;
993 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
994 if (ERROR_OK != retval)
995 return retval;
997 status = str9xpec_lock_device(bank);
999 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1000 return ERROR_FLASH_OPERATION_FAILED;
1002 return ERROR_OK;
1005 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
1007 uint8_t status;
1009 if (CMD_ARGC < 1)
1010 return ERROR_COMMAND_SYNTAX_ERROR;
1012 struct flash_bank *bank;
1013 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1014 if (ERROR_OK != retval)
1015 return retval;
1017 status = str9xpec_unlock_device(bank);
1019 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1020 return ERROR_FLASH_OPERATION_FAILED;
1022 command_print(CMD_CTX, "str9xpec unlocked.\n"
1023 "INFO: a reset or power cycle is required "
1024 "for the new settings to take effect.");
1026 return ERROR_OK;
1029 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
1031 struct jtag_tap *tap0;
1032 struct jtag_tap *tap1;
1033 struct jtag_tap *tap2;
1034 struct str9xpec_flash_controller *str9xpec_info = NULL;
1036 if (CMD_ARGC < 1)
1037 return ERROR_COMMAND_SYNTAX_ERROR;
1039 struct flash_bank *bank;
1040 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1041 if (ERROR_OK != retval)
1042 return retval;
1044 str9xpec_info = bank->driver_priv;
1046 /* remove arm core from chain - enter turbo mode */
1047 tap0 = str9xpec_info->tap;
1048 if (tap0 == NULL) {
1049 /* things are *WRONG* */
1050 command_print(CMD_CTX, "**STR9FLASH** (tap0) invalid chain?");
1051 return ERROR_FAIL;
1053 tap1 = tap0->next_tap;
1054 if (tap1 == NULL) {
1055 /* things are *WRONG* */
1056 command_print(CMD_CTX, "**STR9FLASH** (tap1) invalid chain?");
1057 return ERROR_FAIL;
1059 tap2 = tap1->next_tap;
1060 if (tap2 == NULL) {
1061 /* things are *WRONG* */
1062 command_print(CMD_CTX, "**STR9FLASH** (tap2) invalid chain?");
1063 return ERROR_FAIL;
1066 /* enable turbo mode - TURBO-PROG-ENABLE */
1067 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1068 retval = jtag_execute_queue();
1069 if (retval != ERROR_OK)
1070 return retval;
1072 /* modify scan chain - str9 core has been removed */
1073 tap1->enabled = 0;
1075 return ERROR_OK;
1078 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1080 struct jtag_tap *tap;
1081 struct str9xpec_flash_controller *str9xpec_info = NULL;
1083 if (CMD_ARGC < 1)
1084 return ERROR_COMMAND_SYNTAX_ERROR;
1086 struct flash_bank *bank;
1087 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1088 if (ERROR_OK != retval)
1089 return retval;
1091 str9xpec_info = bank->driver_priv;
1092 tap = str9xpec_info->tap;
1094 if (tap == NULL)
1095 return ERROR_FAIL;
1097 /* exit turbo mode via RESET */
1098 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1099 jtag_add_tlr();
1100 jtag_execute_queue();
1102 /* restore previous scan chain */
1103 if (tap->next_tap)
1104 tap->next_tap->enabled = 1;
1106 return ERROR_OK;
1109 static const struct command_registration str9xpec_config_command_handlers[] = {
1111 .name = "enable_turbo",
1112 .usage = "<bank>",
1113 .handler = str9xpec_handle_flash_enable_turbo_command,
1114 .mode = COMMAND_EXEC,
1115 .help = "enable str9xpec turbo mode",
1118 .name = "disable_turbo",
1119 .usage = "<bank>",
1120 .handler = str9xpec_handle_flash_disable_turbo_command,
1121 .mode = COMMAND_EXEC,
1122 .help = "disable str9xpec turbo mode",
1125 .name = "options_cmap",
1126 .usage = "<bank> <bank0 | bank1>",
1127 .handler = str9xpec_handle_flash_options_cmap_command,
1128 .mode = COMMAND_EXEC,
1129 .help = "configure str9xpec boot sector",
1132 .name = "options_lvdthd",
1133 .usage = "<bank> <2.4v | 2.7v>",
1134 .handler = str9xpec_handle_flash_options_lvdthd_command,
1135 .mode = COMMAND_EXEC,
1136 .help = "configure str9xpec lvd threshold",
1139 .name = "options_lvdsel",
1140 .usage = "<bank> <vdd | vdd_vddq>",
1141 .handler = str9xpec_handle_flash_options_lvdsel_command,
1142 .mode = COMMAND_EXEC,
1143 .help = "configure str9xpec lvd selection",
1146 .name = "options_lvdwarn",
1147 .usage = "<bank> <vdd | vdd_vddq>",
1148 .handler = str9xpec_handle_flash_options_lvdwarn_command,
1149 .mode = COMMAND_EXEC,
1150 .help = "configure str9xpec lvd warning",
1153 .name = "options_read",
1154 .usage = "<bank>",
1155 .handler = str9xpec_handle_flash_options_read_command,
1156 .mode = COMMAND_EXEC,
1157 .help = "read str9xpec options",
1160 .name = "options_write",
1161 .usage = "<bank>",
1162 .handler = str9xpec_handle_flash_options_write_command,
1163 .mode = COMMAND_EXEC,
1164 .help = "write str9xpec options",
1167 .name = "lock",
1168 .usage = "<bank>",
1169 .handler = str9xpec_handle_flash_lock_command,
1170 .mode = COMMAND_EXEC,
1171 .help = "lock str9xpec device",
1174 .name = "unlock",
1175 .usage = "<bank>",
1176 .handler = str9xpec_handle_flash_unlock_command,
1177 .mode = COMMAND_EXEC,
1178 .help = "unlock str9xpec device",
1181 .name = "part_id",
1182 .handler = str9xpec_handle_part_id_command,
1183 .mode = COMMAND_EXEC,
1184 .help = "print part id of str9xpec flash bank <num>",
1186 COMMAND_REGISTRATION_DONE
1189 static const struct command_registration str9xpec_command_handlers[] = {
1191 .name = "str9xpec",
1192 .mode = COMMAND_ANY,
1193 .help = "str9xpec flash command group",
1194 .usage = "",
1195 .chain = str9xpec_config_command_handlers,
1197 COMMAND_REGISTRATION_DONE
1200 struct flash_driver str9xpec_flash = {
1201 .name = "str9xpec",
1202 .commands = str9xpec_command_handlers,
1203 .flash_bank_command = str9xpec_flash_bank_command,
1204 .erase = str9xpec_erase,
1205 .protect = str9xpec_protect,
1206 .write = str9xpec_write,
1207 .read = default_flash_read,
1208 .probe = str9xpec_probe,
1209 .auto_probe = str9xpec_probe,
1210 .erase_check = str9xpec_erase_check,
1211 .protect_check = str9xpec_protect_check,