flash/nor: Make info function optional
[openocd.git] / src / flash / nor / str9xpec.c
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 ***************************************************************************/
23
24 #ifdef HAVE_CONFIG_H
25 #include "config.h"
26 #endif
27
28 #include "imp.h"
29 #include <target/arm7_9_common.h>
30
31 /* ISC commands */
32
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
47
48 /* ISC_DEFAULT bit definitions */
49
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
55
56 /* Option bytes definitions */
57
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
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,
69 };
70
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];
77 };
78
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);
82
83 static int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
84 {
85 if (tap == NULL)
86 return ERROR_TARGET_INVALID;
87
88 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {
89 struct scan_field field;
90
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;
96
97 jtag_add_ir_scan(tap, &field, end_state);
98
99 free(t);
100 }
101
102 return ERROR_OK;
103 }
104
105 static uint8_t str9xpec_isc_status(struct jtag_tap *tap)
106 {
107 struct scan_field field;
108 uint8_t status;
109
110 if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
111 return ISC_STATUS_ERROR;
112
113 field.num_bits = 8;
114 field.out_value = NULL;
115 field.in_value = &status;
116
117
118 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
119 jtag_execute_queue();
120
121 LOG_DEBUG("status: 0x%2.2x", status);
122
123 if (status & ISC_STATUS_SECURITY)
124 LOG_INFO("Device Security Bit Set");
125
126 return status;
127 }
128
129 static int str9xpec_isc_enable(struct flash_bank *bank)
130 {
131 uint8_t status;
132 struct jtag_tap *tap;
133 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
134
135 tap = str9xpec_info->tap;
136
137 if (str9xpec_info->isc_enable)
138 return ERROR_OK;
139
140 /* enter isc mode */
141 if (str9xpec_set_instr(tap, ISC_ENABLE, TAP_IDLE) != ERROR_OK)
142 return ERROR_TARGET_INVALID;
143
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");
150 }
151
152 return ERROR_OK;
153 }
154
155 static int str9xpec_isc_disable(struct flash_bank *bank)
156 {
157 uint8_t status;
158 struct jtag_tap *tap;
159 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
160
161 tap = str9xpec_info->tap;
162
163 if (!str9xpec_info->isc_enable)
164 return ERROR_OK;
165
166 if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)
167 return ERROR_TARGET_INVALID;
168
169 /* delay to handle aborts */
170 jtag_add_sleep(50);
171
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");
178 }
179
180 return ERROR_OK;
181 }
182
183 static int str9xpec_read_config(struct flash_bank *bank)
184 {
185 struct scan_field field;
186 uint8_t status;
187 struct jtag_tap *tap;
188
189 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
190
191 tap = str9xpec_info->tap;
192
193 LOG_DEBUG("ISC_CONFIGURATION");
194
195 /* execute ISC_CONFIGURATION command */
196 str9xpec_set_instr(tap, ISC_CONFIGURATION, TAP_IRPAUSE);
197
198 field.num_bits = 64;
199 field.out_value = NULL;
200 field.in_value = str9xpec_info->options;
201
202 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
203 jtag_execute_queue();
204
205 status = str9xpec_isc_status(tap);
206
207 return status;
208 }
209
210 static int str9xpec_build_block_list(struct flash_bank *bank)
211 {
212 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
213
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;
219
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);
243 }
244
245 num_sectors = b0_sectors + b1_sectors;
246
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);
250
251 num_sectors = 0;
252
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;
260 }
261
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;
269 }
270
271 return ERROR_OK;
272 }
273
274 /* flash bank str9x <base> <size> 0 0 <target#>
275 */
276 FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)
277 {
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;
282
283 if (CMD_ARGC < 6)
284 return ERROR_COMMAND_SYNTAX_ERROR;
285
286 str9xpec_info = malloc(sizeof(struct str9xpec_flash_controller));
287 bank->driver_priv = str9xpec_info;
288
289 /* REVISIT verify that the jtag position of flash controller is
290 * right after *THIS* core, which must be a STR9xx core ...
291 */
292 arm = bank->target->arch_info;
293 arm7_9 = arm->arch_info;
294 jtag_info = &arm7_9->jtag_info;
295
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;
299
300 str9xpec_build_block_list(bank);
301
302 /* clear option byte register */
303 buf_set_u32(str9xpec_info->options, 0, 64, 0);
304
305 return ERROR_OK;
306 }
307
308 static int str9xpec_blank_check(struct flash_bank *bank, int first, int last)
309 {
310 struct scan_field field;
311 uint8_t status;
312 struct jtag_tap *tap;
313 int i;
314 uint8_t *buffer = NULL;
315
316 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
317
318 tap = str9xpec_info->tap;
319
320 if (!str9xpec_info->isc_enable)
321 str9xpec_isc_enable(bank);
322
323 if (!str9xpec_info->isc_enable)
324 return ERROR_FLASH_OPERATION_FAILED;
325
326 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
327
328 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
329
330 for (i = first; i <= last; i++)
331 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
332
333 /* execute ISC_BLANK_CHECK command */
334 str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);
335
336 field.num_bits = 64;
337 field.out_value = buffer;
338 field.in_value = NULL;
339
340 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
341 jtag_add_sleep(40000);
342
343 /* read blank check result */
344 field.num_bits = 64;
345 field.out_value = NULL;
346 field.in_value = buffer;
347
348 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
349 jtag_execute_queue();
350
351 status = str9xpec_isc_status(tap);
352
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;
358 }
359
360 free(buffer);
361
362 str9xpec_isc_disable(bank);
363
364 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
365 return ERROR_FLASH_OPERATION_FAILED;
366 return ERROR_OK;
367 }
368
369 static int str9xpec_protect_check(struct flash_bank *bank)
370 {
371 uint8_t status;
372 int i;
373
374 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
375
376 status = str9xpec_read_config(bank);
377
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;
383 }
384
385 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
386 return ERROR_FLASH_OPERATION_FAILED;
387 return ERROR_OK;
388 }
389
390 static int str9xpec_erase_area(struct flash_bank *bank, int first, int last)
391 {
392 struct scan_field field;
393 uint8_t status;
394 struct jtag_tap *tap;
395 int i;
396 uint8_t *buffer = NULL;
397
398 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
399
400 tap = str9xpec_info->tap;
401
402 if (!str9xpec_info->isc_enable)
403 str9xpec_isc_enable(bank);
404
405 if (!str9xpec_info->isc_enable)
406 return ISC_STATUS_ERROR;
407
408 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
409
410 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
411
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);
422 }
423
424 LOG_DEBUG("ISC_ERASE");
425
426 /* execute ISC_ERASE command */
427 str9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);
428
429 field.num_bits = 64;
430 field.out_value = buffer;
431 field.in_value = NULL;
432
433 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
434 jtag_execute_queue();
435
436 jtag_add_sleep(10);
437
438 /* wait for erase completion */
439 while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY))
440 alive_sleep(1);
441
442 free(buffer);
443
444 str9xpec_isc_disable(bank);
445
446 return status;
447 }
448
449 static int str9xpec_erase(struct flash_bank *bank, int first, int last)
450 {
451 int status;
452
453 status = str9xpec_erase_area(bank, first, last);
454
455 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
456 return ERROR_FLASH_OPERATION_FAILED;
457
458 return ERROR_OK;
459 }
460
461 static int str9xpec_lock_device(struct flash_bank *bank)
462 {
463 struct scan_field field;
464 uint8_t status;
465 struct jtag_tap *tap;
466 struct str9xpec_flash_controller *str9xpec_info = NULL;
467
468 str9xpec_info = bank->driver_priv;
469 tap = str9xpec_info->tap;
470
471 if (!str9xpec_info->isc_enable)
472 str9xpec_isc_enable(bank);
473
474 if (!str9xpec_info->isc_enable)
475 return ISC_STATUS_ERROR;
476
477 /* set security address */
478 str9xpec_set_address(bank, 0x80);
479
480 /* execute ISC_PROGRAM command */
481 str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);
482
483 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
484
485 do {
486 field.num_bits = 8;
487 field.out_value = NULL;
488 field.in_value = &status;
489
490 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
491 jtag_execute_queue();
492
493 } while (!(status & ISC_STATUS_BUSY));
494
495 str9xpec_isc_disable(bank);
496
497 return status;
498 }
499
500 static int str9xpec_unlock_device(struct flash_bank *bank)
501 {
502 uint8_t status;
503
504 status = str9xpec_erase_area(bank, 0, 255);
505
506 return status;
507 }
508
509 static int str9xpec_protect(struct flash_bank *bank, int set, int first, int last)
510 {
511 uint8_t status;
512 int i;
513
514 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
515
516 status = str9xpec_read_config(bank);
517
518 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
519 return ERROR_FLASH_OPERATION_FAILED;
520
521 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
522
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);
530 }
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);
537 }
538
539 status = str9xpec_write_options(bank);
540 }
541
542 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
543 return ERROR_FLASH_OPERATION_FAILED;
544
545 return ERROR_OK;
546 }
547
548 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector)
549 {
550 struct jtag_tap *tap;
551 struct scan_field field;
552 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
553
554 tap = str9xpec_info->tap;
555
556 /* set flash controller address */
557 str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);
558
559 field.num_bits = 8;
560 field.out_value = &sector;
561 field.in_value = NULL;
562
563 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
564
565 return ERROR_OK;
566 }
567
568 static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer,
569 uint32_t offset, uint32_t count)
570 {
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;
583
584 tap = str9xpec_info->tap;
585
586 if (!str9xpec_info->isc_enable)
587 str9xpec_isc_enable(bank);
588
589 if (!str9xpec_info->isc_enable)
590 return ERROR_FLASH_OPERATION_FAILED;
591
592 if (offset & 0x7) {
593 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
594 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
595 }
596
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;
600
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;
608 }
609
610 if ((offset >= sec_start) && (offset < sec_end))
611 first_sector = i;
612
613 if ((offset + count >= sec_start) && (offset + count < sec_end))
614 last_sector = i;
615 }
616
617 if (check_address != offset + count)
618 return ERROR_FLASH_DST_OUT_OF_BANK;
619
620 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
621
622 scanbuf = calloc(DIV_ROUND_UP(64, 8), 1);
623
624 LOG_DEBUG("ISC_PROGRAM");
625
626 for (i = first_sector; i <= last_sector; i++) {
627 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
628
629 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8)
630 ? dwords_remaining : (bank->sectors[i].size/8);
631
632 while (dwords_remaining > 0) {
633 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
634
635 field.num_bits = 64;
636 field.out_value = (buffer + bytes_written);
637 field.in_value = NULL;
638
639 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
640
641 /* small delay before polling */
642 jtag_add_sleep(50);
643
644 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
645
646 do {
647 field.num_bits = 8;
648 field.out_value = NULL;
649 field.in_value = scanbuf;
650
651 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
652 jtag_execute_queue();
653
654 status = buf_get_u32(scanbuf, 0, 8);
655
656 } while (!(status & ISC_STATUS_BUSY));
657
658 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
659 return ERROR_FLASH_OPERATION_FAILED;
660
661 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
662 return ERROR_FLASH_OPERATION_FAILED; */
663
664 dwords_remaining--;
665 bytes_written += 8;
666 }
667 }
668
669 if (bytes_remaining) {
670 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
671
672 /* copy the last remaining bytes into the write buffer */
673 memcpy(last_dword, buffer+bytes_written, bytes_remaining);
674
675 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
676
677 field.num_bits = 64;
678 field.out_value = last_dword;
679 field.in_value = NULL;
680
681 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
682
683 /* small delay before polling */
684 jtag_add_sleep(50);
685
686 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
687
688 do {
689 field.num_bits = 8;
690 field.out_value = NULL;
691 field.in_value = scanbuf;
692
693 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
694 jtag_execute_queue();
695
696 status = buf_get_u32(scanbuf, 0, 8);
697
698 } while (!(status & ISC_STATUS_BUSY));
699
700 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
701 return ERROR_FLASH_OPERATION_FAILED;
702
703 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
704 return ERROR_FLASH_OPERATION_FAILED; */
705 }
706
707 free(scanbuf);
708
709 str9xpec_isc_disable(bank);
710
711 return ERROR_OK;
712 }
713
714 static int str9xpec_probe(struct flash_bank *bank)
715 {
716 return ERROR_OK;
717 }
718
719 COMMAND_HANDLER(str9xpec_handle_part_id_command)
720 {
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;
726
727 if (CMD_ARGC < 1)
728 return ERROR_COMMAND_SYNTAX_ERROR;
729
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;
734
735 str9xpec_info = bank->driver_priv;
736 tap = str9xpec_info->tap;
737
738 buffer = calloc(DIV_ROUND_UP(32, 8), 1);
739
740 str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
741
742 field.num_bits = 32;
743 field.out_value = NULL;
744 field.in_value = buffer;
745
746 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
747 jtag_execute_queue();
748
749 idcode = buf_get_u32(buffer, 0, 32);
750
751 command_print(CMD_CTX, "str9xpec part id: 0x%8.8" PRIx32 "", idcode);
752
753 free(buffer);
754
755 return ERROR_OK;
756 }
757
758 static int str9xpec_erase_check(struct flash_bank *bank)
759 {
760 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
761 }
762
763 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
764 {
765 uint8_t status;
766 struct str9xpec_flash_controller *str9xpec_info = NULL;
767
768 if (CMD_ARGC < 1)
769 return ERROR_COMMAND_SYNTAX_ERROR;
770
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;
775
776 str9xpec_info = bank->driver_priv;
777
778 status = str9xpec_read_config(bank);
779
780 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
781 return ERROR_FLASH_OPERATION_FAILED;
782
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");
788
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");
794
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");
800
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");
806
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");
812
813 return ERROR_OK;
814 }
815
816 static int str9xpec_write_options(struct flash_bank *bank)
817 {
818 struct scan_field field;
819 uint8_t status;
820 struct jtag_tap *tap;
821 struct str9xpec_flash_controller *str9xpec_info = NULL;
822
823 str9xpec_info = bank->driver_priv;
824 tap = str9xpec_info->tap;
825
826 /* erase config options first */
827 status = str9xpec_erase_area(bank, 0xFE, 0xFE);
828
829 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
830 return status;
831
832 if (!str9xpec_info->isc_enable)
833 str9xpec_isc_enable(bank);
834
835 if (!str9xpec_info->isc_enable)
836 return ISC_STATUS_ERROR;
837
838 /* according to data 64th bit has to be set */
839 buf_set_u32(str9xpec_info->options, 63, 1, 1);
840
841 /* set option byte address */
842 str9xpec_set_address(bank, 0x50);
843
844 /* execute ISC_PROGRAM command */
845 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
846
847 field.num_bits = 64;
848 field.out_value = str9xpec_info->options;
849 field.in_value = NULL;
850
851 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
852
853 /* small delay before polling */
854 jtag_add_sleep(50);
855
856 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
857
858 do {
859 field.num_bits = 8;
860 field.out_value = NULL;
861 field.in_value = &status;
862
863 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
864 jtag_execute_queue();
865
866 } while (!(status & ISC_STATUS_BUSY));
867
868 str9xpec_isc_disable(bank);
869
870 return status;
871 }
872
873 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
874 {
875 uint8_t status;
876
877 if (CMD_ARGC < 1)
878 return ERROR_COMMAND_SYNTAX_ERROR;
879
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;
884
885 status = str9xpec_write_options(bank);
886
887 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
888 return ERROR_FLASH_OPERATION_FAILED;
889
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.");
893
894 return ERROR_OK;
895 }
896
897 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
898 {
899 struct str9xpec_flash_controller *str9xpec_info = NULL;
900
901 if (CMD_ARGC < 2)
902 return ERROR_COMMAND_SYNTAX_ERROR;
903
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;
908
909 str9xpec_info = bank->driver_priv;
910
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);
915
916 return ERROR_OK;
917 }
918
919 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
920 {
921 struct str9xpec_flash_controller *str9xpec_info = NULL;
922
923 if (CMD_ARGC < 2)
924 return ERROR_COMMAND_SYNTAX_ERROR;
925
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;
930
931 str9xpec_info = bank->driver_priv;
932
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);
937
938 return ERROR_OK;
939 }
940
941 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
942 {
943 struct str9xpec_flash_controller *str9xpec_info = NULL;
944
945 if (CMD_ARGC < 2)
946 return ERROR_COMMAND_SYNTAX_ERROR;
947
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;
952
953 str9xpec_info = bank->driver_priv;
954
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);
959
960 return ERROR_OK;
961 }
962
963 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
964 {
965 struct str9xpec_flash_controller *str9xpec_info = NULL;
966
967 if (CMD_ARGC < 2)
968 return ERROR_COMMAND_SYNTAX_ERROR;
969
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;
974
975 str9xpec_info = bank->driver_priv;
976
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);
981
982 return ERROR_OK;
983 }
984
985 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
986 {
987 uint8_t status;
988
989 if (CMD_ARGC < 1)
990 return ERROR_COMMAND_SYNTAX_ERROR;
991
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;
996
997 status = str9xpec_lock_device(bank);
998
999 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1000 return ERROR_FLASH_OPERATION_FAILED;
1001
1002 return ERROR_OK;
1003 }
1004
1005 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
1006 {
1007 uint8_t status;
1008
1009 if (CMD_ARGC < 1)
1010 return ERROR_COMMAND_SYNTAX_ERROR;
1011
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;
1016
1017 status = str9xpec_unlock_device(bank);
1018
1019 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1020 return ERROR_FLASH_OPERATION_FAILED;
1021
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.");
1025
1026 return ERROR_OK;
1027 }
1028
1029 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
1030 {
1031 struct jtag_tap *tap0;
1032 struct jtag_tap *tap1;
1033 struct jtag_tap *tap2;
1034 struct str9xpec_flash_controller *str9xpec_info = NULL;
1035
1036 if (CMD_ARGC < 1)
1037 return ERROR_COMMAND_SYNTAX_ERROR;
1038
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;
1043
1044 str9xpec_info = bank->driver_priv;
1045
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;
1052 }
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;
1058 }
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;
1064 }
1065
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;
1071
1072 /* modify scan chain - str9 core has been removed */
1073 tap1->enabled = 0;
1074
1075 return ERROR_OK;
1076 }
1077
1078 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1079 {
1080 struct jtag_tap *tap;
1081 struct str9xpec_flash_controller *str9xpec_info = NULL;
1082
1083 if (CMD_ARGC < 1)
1084 return ERROR_COMMAND_SYNTAX_ERROR;
1085
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;
1090
1091 str9xpec_info = bank->driver_priv;
1092 tap = str9xpec_info->tap;
1093
1094 if (tap == NULL)
1095 return ERROR_FAIL;
1096
1097 /* exit turbo mode via RESET */
1098 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1099 jtag_add_tlr();
1100 jtag_execute_queue();
1101
1102 /* restore previous scan chain */
1103 if (tap->next_tap)
1104 tap->next_tap->enabled = 1;
1105
1106 return ERROR_OK;
1107 }
1108
1109 static const struct command_registration str9xpec_config_command_handlers[] = {
1110 {
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",
1116 },
1117 {
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",
1123 },
1124 {
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",
1130 },
1131 {
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",
1137 },
1138 {
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",
1144 },
1145 {
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",
1151 },
1152 {
1153 .name = "options_read",
1154 .usage = "<bank>",
1155 .handler = str9xpec_handle_flash_options_read_command,
1156 .mode = COMMAND_EXEC,
1157 .help = "read str9xpec options",
1158 },
1159 {
1160 .name = "options_write",
1161 .usage = "<bank>",
1162 .handler = str9xpec_handle_flash_options_write_command,
1163 .mode = COMMAND_EXEC,
1164 .help = "write str9xpec options",
1165 },
1166 {
1167 .name = "lock",
1168 .usage = "<bank>",
1169 .handler = str9xpec_handle_flash_lock_command,
1170 .mode = COMMAND_EXEC,
1171 .help = "lock str9xpec device",
1172 },
1173 {
1174 .name = "unlock",
1175 .usage = "<bank>",
1176 .handler = str9xpec_handle_flash_unlock_command,
1177 .mode = COMMAND_EXEC,
1178 .help = "unlock str9xpec device",
1179 },
1180 {
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>",
1185 },
1186 COMMAND_REGISTRATION_DONE
1187 };
1188
1189 static const struct command_registration str9xpec_command_handlers[] = {
1190 {
1191 .name = "str9xpec",
1192 .mode = COMMAND_ANY,
1193 .help = "str9xpec flash command group",
1194 .usage = "",
1195 .chain = str9xpec_config_command_handlers,
1196 },
1197 COMMAND_REGISTRATION_DONE
1198 };
1199
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,
1212 };