target/xtensa: avoid IHI for writes to non-executable memory
[openocd.git] / src / flash / nor / str9xpec.c
blobc39eb3aa84da81ab8964bb01d31c4138a4722592
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2005 by Dominic Rath *
5 * Dominic.Rath@gmx.de *
6 * *
7 * Copyright (C) 2008 by Spencer Oliver *
8 * spen@spen-soft.co.uk *
9 ***************************************************************************/
11 #ifdef HAVE_CONFIG_H
12 #include "config.h"
13 #endif
15 #include "imp.h"
16 #include <target/arm7_9_common.h>
18 /* ISC commands */
20 #define ISC_IDCODE 0xFE
21 #define ISC_MFG_READ 0x4C
22 #define ISC_CONFIGURATION 0x07
23 #define ISC_ENABLE 0x0C
24 #define ISC_DISABLE 0x0F
25 #define ISC_NOOP 0x10
26 #define ISC_ADDRESS_SHIFT 0x11
27 #define ISC_CLR_STATUS 0x13
28 #define ISC_PROGRAM 0x20
29 #define ISC_PROGRAM_SECURITY 0x22
30 #define ISC_PROGRAM_UC 0x23
31 #define ISC_ERASE 0x30
32 #define ISC_READ 0x50
33 #define ISC_BLANK_CHECK 0x60
35 /* ISC_DEFAULT bit definitions */
37 #define ISC_STATUS_SECURITY 0x40
38 #define ISC_STATUS_INT_ERROR 0x30
39 #define ISC_STATUS_MODE 0x08
40 #define ISC_STATUS_BUSY 0x04
41 #define ISC_STATUS_ERROR 0x03
43 /* Option bytes definitions */
45 #define STR9XPEC_OPT_CSMAPBIT 48
46 #define STR9XPEC_OPT_LVDTHRESBIT 49
47 #define STR9XPEC_OPT_LVDSELBIT 50
48 #define STR9XPEC_OPT_LVDWARNBIT 51
49 #define STR9XPEC_OPT_OTPBIT 63
51 enum str9xpec_status_codes {
52 STR9XPEC_INVALID_COMMAND = 1,
53 STR9XPEC_ISC_SUCCESS = 2,
54 STR9XPEC_ISC_DISABLED = 3,
55 STR9XPEC_ISC_INTFAIL = 32,
58 struct str9xpec_flash_controller {
59 struct jtag_tap *tap;
60 uint32_t *sector_bits;
61 int chain_pos;
62 int isc_enable;
63 uint8_t options[8];
66 static int str9xpec_erase_area(struct flash_bank *bank, unsigned int first,
67 unsigned int last);
68 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector);
69 static int str9xpec_write_options(struct flash_bank *bank);
71 static int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
73 if (!tap)
74 return ERROR_TARGET_INVALID;
76 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {
77 struct scan_field field;
79 field.num_bits = tap->ir_length;
80 void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
81 field.out_value = t;
82 buf_set_u32(t, 0, field.num_bits, new_instr);
83 field.in_value = NULL;
85 jtag_add_ir_scan(tap, &field, end_state);
87 free(t);
90 return ERROR_OK;
93 static uint8_t str9xpec_isc_status(struct jtag_tap *tap)
95 struct scan_field field;
96 uint8_t status;
98 if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
99 return ISC_STATUS_ERROR;
101 field.num_bits = 8;
102 field.out_value = NULL;
103 field.in_value = &status;
106 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
107 jtag_execute_queue();
109 LOG_DEBUG("status: 0x%2.2x", status);
111 if (status & ISC_STATUS_SECURITY)
112 LOG_INFO("Device Security Bit Set");
114 return status;
117 static int str9xpec_isc_enable(struct flash_bank *bank)
119 uint8_t status;
120 struct jtag_tap *tap;
121 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
123 tap = str9xpec_info->tap;
125 if (str9xpec_info->isc_enable)
126 return ERROR_OK;
128 /* enter isc mode */
129 if (str9xpec_set_instr(tap, ISC_ENABLE, TAP_IDLE) != ERROR_OK)
130 return ERROR_TARGET_INVALID;
132 /* check ISC status */
133 status = str9xpec_isc_status(tap);
134 if (status & ISC_STATUS_MODE) {
135 /* we have entered isc mode */
136 str9xpec_info->isc_enable = 1;
137 LOG_DEBUG("ISC_MODE Enabled");
140 return ERROR_OK;
143 static int str9xpec_isc_disable(struct flash_bank *bank)
145 uint8_t status;
146 struct jtag_tap *tap;
147 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
149 tap = str9xpec_info->tap;
151 if (!str9xpec_info->isc_enable)
152 return ERROR_OK;
154 if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)
155 return ERROR_TARGET_INVALID;
157 /* delay to handle aborts */
158 jtag_add_sleep(50);
160 /* check ISC status */
161 status = str9xpec_isc_status(tap);
162 if (!(status & ISC_STATUS_MODE)) {
163 /* we have left isc mode */
164 str9xpec_info->isc_enable = 0;
165 LOG_DEBUG("ISC_MODE Disabled");
168 return ERROR_OK;
171 static int str9xpec_read_config(struct flash_bank *bank)
173 struct scan_field field;
174 uint8_t status;
175 struct jtag_tap *tap;
177 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
179 tap = str9xpec_info->tap;
181 LOG_DEBUG("ISC_CONFIGURATION");
183 /* execute ISC_CONFIGURATION command */
184 str9xpec_set_instr(tap, ISC_CONFIGURATION, TAP_IRPAUSE);
186 field.num_bits = 64;
187 field.out_value = NULL;
188 field.in_value = str9xpec_info->options;
190 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
191 jtag_execute_queue();
193 status = str9xpec_isc_status(tap);
195 return status;
198 static int str9xpec_build_block_list(struct flash_bank *bank)
200 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
202 int i;
203 unsigned int num_sectors;
204 int b0_sectors = 0, b1_sectors = 0;
205 uint32_t offset = 0;
206 int b1_size = 0x2000;
208 switch (bank->size) {
209 case (256 * 1024):
210 b0_sectors = 4;
211 break;
212 case (512 * 1024):
213 b0_sectors = 8;
214 break;
215 case (1024 * 1024):
216 b0_sectors = 16;
217 break;
218 case (2048 * 1024):
219 b0_sectors = 32;
220 break;
221 case (128 * 1024):
222 b1_size = 0x4000;
223 b1_sectors = 8;
224 break;
225 case (32 * 1024):
226 b1_sectors = 4;
227 break;
228 default:
229 LOG_ERROR("BUG: unknown bank->size encountered");
230 exit(-1);
233 num_sectors = b0_sectors + b1_sectors;
235 bank->num_sectors = num_sectors;
236 bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
237 str9xpec_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
239 num_sectors = 0;
241 for (i = 0; i < b0_sectors; i++) {
242 bank->sectors[num_sectors].offset = offset;
243 bank->sectors[num_sectors].size = 0x10000;
244 offset += bank->sectors[i].size;
245 bank->sectors[num_sectors].is_erased = -1;
246 bank->sectors[num_sectors].is_protected = 1;
247 str9xpec_info->sector_bits[num_sectors++] = i;
250 for (i = 0; i < b1_sectors; i++) {
251 bank->sectors[num_sectors].offset = offset;
252 bank->sectors[num_sectors].size = b1_size;
253 offset += bank->sectors[i].size;
254 bank->sectors[num_sectors].is_erased = -1;
255 bank->sectors[num_sectors].is_protected = 1;
256 str9xpec_info->sector_bits[num_sectors++] = i + 32;
259 return ERROR_OK;
262 /* flash bank str9x <base> <size> 0 0 <target#>
264 FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)
266 struct str9xpec_flash_controller *str9xpec_info;
267 struct arm *arm = NULL;
268 struct arm7_9_common *arm7_9 = NULL;
269 struct arm_jtag *jtag_info = NULL;
271 if (CMD_ARGC < 6)
272 return ERROR_COMMAND_SYNTAX_ERROR;
274 str9xpec_info = malloc(sizeof(struct str9xpec_flash_controller));
275 bank->driver_priv = str9xpec_info;
277 /* REVISIT verify that the jtag position of flash controller is
278 * right after *THIS* core, which must be a STR9xx core ...
280 arm = bank->target->arch_info;
281 arm7_9 = arm->arch_info;
282 jtag_info = &arm7_9->jtag_info;
284 /* The core is the next tap after the flash controller in the chain */
285 str9xpec_info->tap = jtag_tap_by_position(jtag_info->tap->abs_chain_position - 1);
286 str9xpec_info->isc_enable = 0;
288 str9xpec_build_block_list(bank);
290 /* clear option byte register */
291 buf_set_u32(str9xpec_info->options, 0, 64, 0);
293 return ERROR_OK;
296 static int str9xpec_blank_check(struct flash_bank *bank, unsigned int first,
297 unsigned int last)
299 struct scan_field field;
300 uint8_t status;
301 struct jtag_tap *tap;
302 uint8_t *buffer = NULL;
304 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
306 tap = str9xpec_info->tap;
308 if (!str9xpec_info->isc_enable)
309 str9xpec_isc_enable(bank);
311 if (!str9xpec_info->isc_enable)
312 return ERROR_FLASH_OPERATION_FAILED;
314 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
316 LOG_DEBUG("blank check: first_bank: %u, last_bank: %u", first, last);
318 for (unsigned int i = first; i <= last; i++)
319 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
321 /* execute ISC_BLANK_CHECK command */
322 str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);
324 field.num_bits = 64;
325 field.out_value = buffer;
326 field.in_value = NULL;
328 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
329 jtag_add_sleep(40000);
331 /* read blank check result */
332 field.num_bits = 64;
333 field.out_value = NULL;
334 field.in_value = buffer;
336 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
337 jtag_execute_queue();
339 status = str9xpec_isc_status(tap);
341 for (unsigned int i = first; i <= last; i++) {
342 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
343 bank->sectors[i].is_erased = 0;
344 else
345 bank->sectors[i].is_erased = 1;
348 free(buffer);
350 str9xpec_isc_disable(bank);
352 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
353 return ERROR_FLASH_OPERATION_FAILED;
354 return ERROR_OK;
357 static int str9xpec_protect_check(struct flash_bank *bank)
359 uint8_t status;
361 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
363 status = str9xpec_read_config(bank);
365 for (unsigned int i = 0; i < bank->num_sectors; i++) {
366 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
367 bank->sectors[i].is_protected = 1;
368 else
369 bank->sectors[i].is_protected = 0;
372 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
373 return ERROR_FLASH_OPERATION_FAILED;
374 return ERROR_OK;
377 static int str9xpec_erase_area(struct flash_bank *bank, unsigned int first,
378 unsigned int last)
380 struct scan_field field;
381 uint8_t status;
382 struct jtag_tap *tap;
383 uint8_t *buffer = NULL;
385 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
387 tap = str9xpec_info->tap;
389 if (!str9xpec_info->isc_enable)
390 str9xpec_isc_enable(bank);
392 if (!str9xpec_info->isc_enable)
393 return ISC_STATUS_ERROR;
395 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
397 LOG_DEBUG("erase: first_bank: %u, last_bank: %u", first, last);
399 /* last bank: 0xFF signals a full erase (unlock complete device) */
400 /* last bank: 0xFE signals a option byte erase */
401 if (last == 0xFF) {
402 for (unsigned int i = 0; i < 64; i++)
403 buf_set_u32(buffer, i, 1, 1);
404 } else if (last == 0xFE)
405 buf_set_u32(buffer, 49, 1, 1);
406 else {
407 for (unsigned int i = first; i <= last; i++)
408 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
411 LOG_DEBUG("ISC_ERASE");
413 /* execute ISC_ERASE command */
414 str9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);
416 field.num_bits = 64;
417 field.out_value = buffer;
418 field.in_value = NULL;
420 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
421 jtag_execute_queue();
423 jtag_add_sleep(10);
425 /* wait for erase completion */
426 while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY))
427 alive_sleep(1);
429 free(buffer);
431 str9xpec_isc_disable(bank);
433 return status;
436 static int str9xpec_erase(struct flash_bank *bank, unsigned int first,
437 unsigned int last)
439 int status;
441 status = str9xpec_erase_area(bank, first, last);
443 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
444 return ERROR_FLASH_OPERATION_FAILED;
446 return ERROR_OK;
449 static int str9xpec_lock_device(struct flash_bank *bank)
451 struct scan_field field;
452 uint8_t status;
453 struct jtag_tap *tap;
454 struct str9xpec_flash_controller *str9xpec_info = NULL;
456 str9xpec_info = bank->driver_priv;
457 tap = str9xpec_info->tap;
459 if (!str9xpec_info->isc_enable)
460 str9xpec_isc_enable(bank);
462 if (!str9xpec_info->isc_enable)
463 return ISC_STATUS_ERROR;
465 /* set security address */
466 str9xpec_set_address(bank, 0x80);
468 /* execute ISC_PROGRAM command */
469 str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);
471 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
473 do {
474 field.num_bits = 8;
475 field.out_value = NULL;
476 field.in_value = &status;
478 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
479 jtag_execute_queue();
481 } while (!(status & ISC_STATUS_BUSY));
483 str9xpec_isc_disable(bank);
485 return status;
488 static int str9xpec_unlock_device(struct flash_bank *bank)
490 uint8_t status;
492 status = str9xpec_erase_area(bank, 0, 255);
494 return status;
497 static int str9xpec_protect(struct flash_bank *bank, int set,
498 unsigned int first, unsigned int last)
500 uint8_t status;
502 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
504 status = str9xpec_read_config(bank);
506 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
507 return ERROR_FLASH_OPERATION_FAILED;
509 LOG_DEBUG("protect: first_bank: %u, last_bank: %u", first, last);
511 /* last bank: 0xFF signals a full device protect */
512 if (last == 0xFF) {
513 if (set)
514 status = str9xpec_lock_device(bank);
515 else {
516 /* perform full erase to unlock device */
517 status = str9xpec_unlock_device(bank);
519 } else {
520 for (unsigned int i = first; i <= last; i++) {
521 if (set)
522 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
523 else
524 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
527 status = str9xpec_write_options(bank);
530 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
531 return ERROR_FLASH_OPERATION_FAILED;
533 return ERROR_OK;
536 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector)
538 struct jtag_tap *tap;
539 struct scan_field field;
540 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
542 tap = str9xpec_info->tap;
544 /* set flash controller address */
545 str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);
547 field.num_bits = 8;
548 field.out_value = &sector;
549 field.in_value = NULL;
551 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
553 return ERROR_OK;
556 static int str9xpec_write(struct flash_bank *bank, const uint8_t *buffer,
557 uint32_t offset, uint32_t count)
559 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
560 uint32_t dwords_remaining = (count / 8);
561 uint32_t bytes_remaining = (count & 0x00000007);
562 uint32_t bytes_written = 0;
563 uint8_t status;
564 uint32_t check_address = offset;
565 struct jtag_tap *tap;
566 struct scan_field field;
567 uint8_t *scanbuf;
568 unsigned int first_sector = 0;
569 unsigned int last_sector = 0;
571 tap = str9xpec_info->tap;
573 if (!str9xpec_info->isc_enable)
574 str9xpec_isc_enable(bank);
576 if (!str9xpec_info->isc_enable)
577 return ERROR_FLASH_OPERATION_FAILED;
579 if (offset & 0x7) {
580 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
581 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
584 for (unsigned int i = 0; i < bank->num_sectors; i++) {
585 uint32_t sec_start = bank->sectors[i].offset;
586 uint32_t sec_end = sec_start + bank->sectors[i].size;
588 /* check if destination falls within the current sector */
589 if ((check_address >= sec_start) && (check_address < sec_end)) {
590 /* check if destination ends in the current sector */
591 if (offset + count < sec_end)
592 check_address = offset + count;
593 else
594 check_address = sec_end;
597 if ((offset >= sec_start) && (offset < sec_end))
598 first_sector = i;
600 if ((offset + count >= sec_start) && (offset + count < sec_end))
601 last_sector = i;
604 if (check_address != offset + count)
605 return ERROR_FLASH_DST_OUT_OF_BANK;
607 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
609 scanbuf = calloc(DIV_ROUND_UP(64, 8), 1);
611 LOG_DEBUG("ISC_PROGRAM");
613 for (unsigned int i = first_sector; i <= last_sector; i++) {
614 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
616 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8)
617 ? dwords_remaining : (bank->sectors[i].size/8);
619 while (dwords_remaining > 0) {
620 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
622 field.num_bits = 64;
623 field.out_value = (buffer + bytes_written);
624 field.in_value = NULL;
626 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
628 /* small delay before polling */
629 jtag_add_sleep(50);
631 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
633 do {
634 field.num_bits = 8;
635 field.out_value = NULL;
636 field.in_value = scanbuf;
638 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
639 jtag_execute_queue();
641 status = buf_get_u32(scanbuf, 0, 8);
643 } while (!(status & ISC_STATUS_BUSY));
645 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
646 return ERROR_FLASH_OPERATION_FAILED;
648 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
649 return ERROR_FLASH_OPERATION_FAILED; */
651 dwords_remaining--;
652 bytes_written += 8;
656 if (bytes_remaining) {
657 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
659 /* copy the last remaining bytes into the write buffer */
660 memcpy(last_dword, buffer+bytes_written, bytes_remaining);
662 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
664 field.num_bits = 64;
665 field.out_value = last_dword;
666 field.in_value = NULL;
668 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
670 /* small delay before polling */
671 jtag_add_sleep(50);
673 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
675 do {
676 field.num_bits = 8;
677 field.out_value = NULL;
678 field.in_value = scanbuf;
680 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
681 jtag_execute_queue();
683 status = buf_get_u32(scanbuf, 0, 8);
685 } while (!(status & ISC_STATUS_BUSY));
687 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
688 return ERROR_FLASH_OPERATION_FAILED;
690 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
691 return ERROR_FLASH_OPERATION_FAILED; */
694 free(scanbuf);
696 str9xpec_isc_disable(bank);
698 return ERROR_OK;
701 static int str9xpec_probe(struct flash_bank *bank)
703 return ERROR_OK;
706 COMMAND_HANDLER(str9xpec_handle_part_id_command)
708 struct scan_field field;
709 uint8_t *buffer = NULL;
710 struct jtag_tap *tap;
711 uint32_t idcode;
712 struct str9xpec_flash_controller *str9xpec_info = NULL;
714 if (CMD_ARGC < 1)
715 return ERROR_COMMAND_SYNTAX_ERROR;
717 struct flash_bank *bank;
718 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
719 if (retval != ERROR_OK)
720 return retval;
722 str9xpec_info = bank->driver_priv;
723 tap = str9xpec_info->tap;
725 buffer = calloc(DIV_ROUND_UP(32, 8), 1);
727 str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
729 field.num_bits = 32;
730 field.out_value = NULL;
731 field.in_value = buffer;
733 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
734 jtag_execute_queue();
736 idcode = buf_get_u32(buffer, 0, 32);
738 command_print(CMD, "str9xpec part id: 0x%8.8" PRIx32 "", idcode);
740 free(buffer);
742 return ERROR_OK;
745 static int str9xpec_erase_check(struct flash_bank *bank)
747 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
750 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
752 uint8_t status;
753 struct str9xpec_flash_controller *str9xpec_info = NULL;
755 if (CMD_ARGC < 1)
756 return ERROR_COMMAND_SYNTAX_ERROR;
758 struct flash_bank *bank;
759 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
760 if (retval != ERROR_OK)
761 return retval;
763 str9xpec_info = bank->driver_priv;
765 status = str9xpec_read_config(bank);
767 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
768 return ERROR_FLASH_OPERATION_FAILED;
770 /* boot bank */
771 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
772 command_print(CMD, "CS Map: bank1");
773 else
774 command_print(CMD, "CS Map: bank0");
776 /* OTP lock */
777 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
778 command_print(CMD, "OTP Lock: OTP Locked");
779 else
780 command_print(CMD, "OTP Lock: OTP Unlocked");
782 /* LVD Threshold */
783 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
784 command_print(CMD, "LVD Threshold: 2.7v");
785 else
786 command_print(CMD, "LVD Threshold: 2.4v");
788 /* LVD reset warning */
789 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
790 command_print(CMD, "LVD Reset Warning: VDD or VDDQ Inputs");
791 else
792 command_print(CMD, "LVD Reset Warning: VDD Input Only");
794 /* LVD reset select */
795 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
796 command_print(CMD, "LVD Reset Selection: VDD or VDDQ Inputs");
797 else
798 command_print(CMD, "LVD Reset Selection: VDD Input Only");
800 return ERROR_OK;
803 static int str9xpec_write_options(struct flash_bank *bank)
805 struct scan_field field;
806 uint8_t status;
807 struct jtag_tap *tap;
808 struct str9xpec_flash_controller *str9xpec_info = NULL;
810 str9xpec_info = bank->driver_priv;
811 tap = str9xpec_info->tap;
813 /* erase config options first */
814 status = str9xpec_erase_area(bank, 0xFE, 0xFE);
816 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
817 return status;
819 if (!str9xpec_info->isc_enable)
820 str9xpec_isc_enable(bank);
822 if (!str9xpec_info->isc_enable)
823 return ISC_STATUS_ERROR;
825 /* according to data 64th bit has to be set */
826 buf_set_u32(str9xpec_info->options, 63, 1, 1);
828 /* set option byte address */
829 str9xpec_set_address(bank, 0x50);
831 /* execute ISC_PROGRAM command */
832 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
834 field.num_bits = 64;
835 field.out_value = str9xpec_info->options;
836 field.in_value = NULL;
838 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
840 /* small delay before polling */
841 jtag_add_sleep(50);
843 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
845 do {
846 field.num_bits = 8;
847 field.out_value = NULL;
848 field.in_value = &status;
850 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
851 jtag_execute_queue();
853 } while (!(status & ISC_STATUS_BUSY));
855 str9xpec_isc_disable(bank);
857 return status;
860 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
862 uint8_t status;
864 if (CMD_ARGC < 1)
865 return ERROR_COMMAND_SYNTAX_ERROR;
867 struct flash_bank *bank;
868 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
869 if (retval != ERROR_OK)
870 return retval;
872 status = str9xpec_write_options(bank);
874 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
875 return ERROR_FLASH_OPERATION_FAILED;
877 command_print(CMD, "str9xpec write options complete.\n"
878 "INFO: a reset or power cycle is required "
879 "for the new settings to take effect.");
881 return ERROR_OK;
884 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
886 struct str9xpec_flash_controller *str9xpec_info = NULL;
888 if (CMD_ARGC < 2)
889 return ERROR_COMMAND_SYNTAX_ERROR;
891 struct flash_bank *bank;
892 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
893 if (retval != ERROR_OK)
894 return retval;
896 str9xpec_info = bank->driver_priv;
898 if (strcmp(CMD_ARGV[1], "bank1") == 0)
899 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
900 else
901 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
903 return ERROR_OK;
906 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
908 struct str9xpec_flash_controller *str9xpec_info = NULL;
910 if (CMD_ARGC < 2)
911 return ERROR_COMMAND_SYNTAX_ERROR;
913 struct flash_bank *bank;
914 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
915 if (retval != ERROR_OK)
916 return retval;
918 str9xpec_info = bank->driver_priv;
920 if (strcmp(CMD_ARGV[1], "2.7v") == 0)
921 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
922 else
923 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
925 return ERROR_OK;
928 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
930 struct str9xpec_flash_controller *str9xpec_info = NULL;
932 if (CMD_ARGC < 2)
933 return ERROR_COMMAND_SYNTAX_ERROR;
935 struct flash_bank *bank;
936 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
937 if (retval != ERROR_OK)
938 return retval;
940 str9xpec_info = bank->driver_priv;
942 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
943 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
944 else
945 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
947 return ERROR_OK;
950 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
952 struct str9xpec_flash_controller *str9xpec_info = NULL;
954 if (CMD_ARGC < 2)
955 return ERROR_COMMAND_SYNTAX_ERROR;
957 struct flash_bank *bank;
958 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
959 if (retval != ERROR_OK)
960 return retval;
962 str9xpec_info = bank->driver_priv;
964 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
965 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
966 else
967 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
969 return ERROR_OK;
972 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
974 uint8_t status;
976 if (CMD_ARGC < 1)
977 return ERROR_COMMAND_SYNTAX_ERROR;
979 struct flash_bank *bank;
980 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
981 if (retval != ERROR_OK)
982 return retval;
984 status = str9xpec_lock_device(bank);
986 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
987 return ERROR_FLASH_OPERATION_FAILED;
989 return ERROR_OK;
992 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
994 uint8_t status;
996 if (CMD_ARGC < 1)
997 return ERROR_COMMAND_SYNTAX_ERROR;
999 struct flash_bank *bank;
1000 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1001 if (retval != ERROR_OK)
1002 return retval;
1004 status = str9xpec_unlock_device(bank);
1006 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1007 return ERROR_FLASH_OPERATION_FAILED;
1009 command_print(CMD, "str9xpec unlocked.\n"
1010 "INFO: a reset or power cycle is required "
1011 "for the new settings to take effect.");
1013 return ERROR_OK;
1016 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
1018 struct jtag_tap *tap0;
1019 struct jtag_tap *tap1;
1020 struct jtag_tap *tap2;
1021 struct str9xpec_flash_controller *str9xpec_info = NULL;
1023 if (CMD_ARGC < 1)
1024 return ERROR_COMMAND_SYNTAX_ERROR;
1026 struct flash_bank *bank;
1027 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1028 if (retval != ERROR_OK)
1029 return retval;
1031 str9xpec_info = bank->driver_priv;
1033 /* remove arm core from chain - enter turbo mode */
1034 tap0 = str9xpec_info->tap;
1035 if (!tap0) {
1036 /* things are *WRONG* */
1037 command_print(CMD, "**STR9FLASH** (tap0) invalid chain?");
1038 return ERROR_FAIL;
1040 tap1 = tap0->next_tap;
1041 if (!tap1) {
1042 /* things are *WRONG* */
1043 command_print(CMD, "**STR9FLASH** (tap1) invalid chain?");
1044 return ERROR_FAIL;
1046 tap2 = tap1->next_tap;
1047 if (!tap2) {
1048 /* things are *WRONG* */
1049 command_print(CMD, "**STR9FLASH** (tap2) invalid chain?");
1050 return ERROR_FAIL;
1053 /* enable turbo mode - TURBO-PROG-ENABLE */
1054 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1055 retval = jtag_execute_queue();
1056 if (retval != ERROR_OK)
1057 return retval;
1059 /* modify scan chain - str9 core has been removed */
1060 tap1->enabled = 0;
1062 return ERROR_OK;
1065 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1067 struct jtag_tap *tap;
1068 struct str9xpec_flash_controller *str9xpec_info = NULL;
1070 if (CMD_ARGC < 1)
1071 return ERROR_COMMAND_SYNTAX_ERROR;
1073 struct flash_bank *bank;
1074 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1075 if (retval != ERROR_OK)
1076 return retval;
1078 str9xpec_info = bank->driver_priv;
1079 tap = str9xpec_info->tap;
1081 if (!tap)
1082 return ERROR_FAIL;
1084 /* exit turbo mode via RESET */
1085 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1086 jtag_add_tlr();
1087 jtag_execute_queue();
1089 /* restore previous scan chain */
1090 if (tap->next_tap)
1091 tap->next_tap->enabled = 1;
1093 return ERROR_OK;
1096 static const struct command_registration str9xpec_config_command_handlers[] = {
1098 .name = "enable_turbo",
1099 .usage = "<bank>",
1100 .handler = str9xpec_handle_flash_enable_turbo_command,
1101 .mode = COMMAND_EXEC,
1102 .help = "enable str9xpec turbo mode",
1105 .name = "disable_turbo",
1106 .usage = "<bank>",
1107 .handler = str9xpec_handle_flash_disable_turbo_command,
1108 .mode = COMMAND_EXEC,
1109 .help = "disable str9xpec turbo mode",
1112 .name = "options_cmap",
1113 .usage = "<bank> <bank0 | bank1>",
1114 .handler = str9xpec_handle_flash_options_cmap_command,
1115 .mode = COMMAND_EXEC,
1116 .help = "configure str9xpec boot sector",
1119 .name = "options_lvdthd",
1120 .usage = "<bank> <2.4v | 2.7v>",
1121 .handler = str9xpec_handle_flash_options_lvdthd_command,
1122 .mode = COMMAND_EXEC,
1123 .help = "configure str9xpec lvd threshold",
1126 .name = "options_lvdsel",
1127 .usage = "<bank> <vdd | vdd_vddq>",
1128 .handler = str9xpec_handle_flash_options_lvdsel_command,
1129 .mode = COMMAND_EXEC,
1130 .help = "configure str9xpec lvd selection",
1133 .name = "options_lvdwarn",
1134 .usage = "<bank> <vdd | vdd_vddq>",
1135 .handler = str9xpec_handle_flash_options_lvdwarn_command,
1136 .mode = COMMAND_EXEC,
1137 .help = "configure str9xpec lvd warning",
1140 .name = "options_read",
1141 .usage = "<bank>",
1142 .handler = str9xpec_handle_flash_options_read_command,
1143 .mode = COMMAND_EXEC,
1144 .help = "read str9xpec options",
1147 .name = "options_write",
1148 .usage = "<bank>",
1149 .handler = str9xpec_handle_flash_options_write_command,
1150 .mode = COMMAND_EXEC,
1151 .help = "write str9xpec options",
1154 .name = "lock",
1155 .usage = "<bank>",
1156 .handler = str9xpec_handle_flash_lock_command,
1157 .mode = COMMAND_EXEC,
1158 .help = "lock str9xpec device",
1161 .name = "unlock",
1162 .usage = "<bank>",
1163 .handler = str9xpec_handle_flash_unlock_command,
1164 .mode = COMMAND_EXEC,
1165 .help = "unlock str9xpec device",
1168 .name = "part_id",
1169 .usage = "<bank>",
1170 .handler = str9xpec_handle_part_id_command,
1171 .mode = COMMAND_EXEC,
1172 .help = "print part id of str9xpec flash bank",
1174 COMMAND_REGISTRATION_DONE
1177 static const struct command_registration str9xpec_command_handlers[] = {
1179 .name = "str9xpec",
1180 .mode = COMMAND_ANY,
1181 .help = "str9xpec flash command group",
1182 .usage = "",
1183 .chain = str9xpec_config_command_handlers,
1185 COMMAND_REGISTRATION_DONE
1188 const struct flash_driver str9xpec_flash = {
1189 .name = "str9xpec",
1190 .commands = str9xpec_command_handlers,
1191 .flash_bank_command = str9xpec_flash_bank_command,
1192 .erase = str9xpec_erase,
1193 .protect = str9xpec_protect,
1194 .write = str9xpec_write,
1195 .read = default_flash_read,
1196 .probe = str9xpec_probe,
1197 .auto_probe = str9xpec_probe,
1198 .erase_check = str9xpec_erase_check,
1199 .protect_check = str9xpec_protect_check,
1200 .free_driver_priv = default_flash_free_driver_priv,