da6c83e28bef83b29e393071e1e9176f16101a85
[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 static int get_str9xpec_info(struct flash_bank *bank, char *buf, int buf_size)
764 {
765 snprintf(buf, buf_size, "str9xpec flash driver info");
766 return ERROR_OK;
767 }
768
769 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
770 {
771 uint8_t status;
772 struct str9xpec_flash_controller *str9xpec_info = NULL;
773
774 if (CMD_ARGC < 1)
775 return ERROR_COMMAND_SYNTAX_ERROR;
776
777 struct flash_bank *bank;
778 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
779 if (ERROR_OK != retval)
780 return retval;
781
782 str9xpec_info = bank->driver_priv;
783
784 status = str9xpec_read_config(bank);
785
786 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
787 return ERROR_FLASH_OPERATION_FAILED;
788
789 /* boot bank */
790 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
791 command_print(CMD_CTX, "CS Map: bank1");
792 else
793 command_print(CMD_CTX, "CS Map: bank0");
794
795 /* OTP lock */
796 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
797 command_print(CMD_CTX, "OTP Lock: OTP Locked");
798 else
799 command_print(CMD_CTX, "OTP Lock: OTP Unlocked");
800
801 /* LVD Threshold */
802 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
803 command_print(CMD_CTX, "LVD Threshold: 2.7v");
804 else
805 command_print(CMD_CTX, "LVD Threshold: 2.4v");
806
807 /* LVD reset warning */
808 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
809 command_print(CMD_CTX, "LVD Reset Warning: VDD or VDDQ Inputs");
810 else
811 command_print(CMD_CTX, "LVD Reset Warning: VDD Input Only");
812
813 /* LVD reset select */
814 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
815 command_print(CMD_CTX, "LVD Reset Selection: VDD or VDDQ Inputs");
816 else
817 command_print(CMD_CTX, "LVD Reset Selection: VDD Input Only");
818
819 return ERROR_OK;
820 }
821
822 static int str9xpec_write_options(struct flash_bank *bank)
823 {
824 struct scan_field field;
825 uint8_t status;
826 struct jtag_tap *tap;
827 struct str9xpec_flash_controller *str9xpec_info = NULL;
828
829 str9xpec_info = bank->driver_priv;
830 tap = str9xpec_info->tap;
831
832 /* erase config options first */
833 status = str9xpec_erase_area(bank, 0xFE, 0xFE);
834
835 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
836 return status;
837
838 if (!str9xpec_info->isc_enable)
839 str9xpec_isc_enable(bank);
840
841 if (!str9xpec_info->isc_enable)
842 return ISC_STATUS_ERROR;
843
844 /* according to data 64th bit has to be set */
845 buf_set_u32(str9xpec_info->options, 63, 1, 1);
846
847 /* set option byte address */
848 str9xpec_set_address(bank, 0x50);
849
850 /* execute ISC_PROGRAM command */
851 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
852
853 field.num_bits = 64;
854 field.out_value = str9xpec_info->options;
855 field.in_value = NULL;
856
857 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
858
859 /* small delay before polling */
860 jtag_add_sleep(50);
861
862 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
863
864 do {
865 field.num_bits = 8;
866 field.out_value = NULL;
867 field.in_value = &status;
868
869 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
870 jtag_execute_queue();
871
872 } while (!(status & ISC_STATUS_BUSY));
873
874 str9xpec_isc_disable(bank);
875
876 return status;
877 }
878
879 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
880 {
881 uint8_t status;
882
883 if (CMD_ARGC < 1)
884 return ERROR_COMMAND_SYNTAX_ERROR;
885
886 struct flash_bank *bank;
887 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
888 if (ERROR_OK != retval)
889 return retval;
890
891 status = str9xpec_write_options(bank);
892
893 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
894 return ERROR_FLASH_OPERATION_FAILED;
895
896 command_print(CMD_CTX, "str9xpec write options complete.\n"
897 "INFO: a reset or power cycle is required "
898 "for the new settings to take effect.");
899
900 return ERROR_OK;
901 }
902
903 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
904 {
905 struct str9xpec_flash_controller *str9xpec_info = NULL;
906
907 if (CMD_ARGC < 2)
908 return ERROR_COMMAND_SYNTAX_ERROR;
909
910 struct flash_bank *bank;
911 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
912 if (ERROR_OK != retval)
913 return retval;
914
915 str9xpec_info = bank->driver_priv;
916
917 if (strcmp(CMD_ARGV[1], "bank1") == 0)
918 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
919 else
920 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
921
922 return ERROR_OK;
923 }
924
925 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
926 {
927 struct str9xpec_flash_controller *str9xpec_info = NULL;
928
929 if (CMD_ARGC < 2)
930 return ERROR_COMMAND_SYNTAX_ERROR;
931
932 struct flash_bank *bank;
933 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
934 if (ERROR_OK != retval)
935 return retval;
936
937 str9xpec_info = bank->driver_priv;
938
939 if (strcmp(CMD_ARGV[1], "2.7v") == 0)
940 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
941 else
942 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
943
944 return ERROR_OK;
945 }
946
947 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
948 {
949 struct str9xpec_flash_controller *str9xpec_info = NULL;
950
951 if (CMD_ARGC < 2)
952 return ERROR_COMMAND_SYNTAX_ERROR;
953
954 struct flash_bank *bank;
955 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
956 if (ERROR_OK != retval)
957 return retval;
958
959 str9xpec_info = bank->driver_priv;
960
961 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
962 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
963 else
964 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
965
966 return ERROR_OK;
967 }
968
969 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
970 {
971 struct str9xpec_flash_controller *str9xpec_info = NULL;
972
973 if (CMD_ARGC < 2)
974 return ERROR_COMMAND_SYNTAX_ERROR;
975
976 struct flash_bank *bank;
977 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
978 if (ERROR_OK != retval)
979 return retval;
980
981 str9xpec_info = bank->driver_priv;
982
983 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
984 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
985 else
986 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
987
988 return ERROR_OK;
989 }
990
991 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
992 {
993 uint8_t status;
994
995 if (CMD_ARGC < 1)
996 return ERROR_COMMAND_SYNTAX_ERROR;
997
998 struct flash_bank *bank;
999 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1000 if (ERROR_OK != retval)
1001 return retval;
1002
1003 status = str9xpec_lock_device(bank);
1004
1005 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1006 return ERROR_FLASH_OPERATION_FAILED;
1007
1008 return ERROR_OK;
1009 }
1010
1011 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
1012 {
1013 uint8_t status;
1014
1015 if (CMD_ARGC < 1)
1016 return ERROR_COMMAND_SYNTAX_ERROR;
1017
1018 struct flash_bank *bank;
1019 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1020 if (ERROR_OK != retval)
1021 return retval;
1022
1023 status = str9xpec_unlock_device(bank);
1024
1025 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1026 return ERROR_FLASH_OPERATION_FAILED;
1027
1028 command_print(CMD_CTX, "str9xpec unlocked.\n"
1029 "INFO: a reset or power cycle is required "
1030 "for the new settings to take effect.");
1031
1032 return ERROR_OK;
1033 }
1034
1035 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
1036 {
1037 struct jtag_tap *tap0;
1038 struct jtag_tap *tap1;
1039 struct jtag_tap *tap2;
1040 struct str9xpec_flash_controller *str9xpec_info = NULL;
1041
1042 if (CMD_ARGC < 1)
1043 return ERROR_COMMAND_SYNTAX_ERROR;
1044
1045 struct flash_bank *bank;
1046 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1047 if (ERROR_OK != retval)
1048 return retval;
1049
1050 str9xpec_info = bank->driver_priv;
1051
1052 /* remove arm core from chain - enter turbo mode */
1053 tap0 = str9xpec_info->tap;
1054 if (tap0 == NULL) {
1055 /* things are *WRONG* */
1056 command_print(CMD_CTX, "**STR9FLASH** (tap0) invalid chain?");
1057 return ERROR_FAIL;
1058 }
1059 tap1 = tap0->next_tap;
1060 if (tap1 == NULL) {
1061 /* things are *WRONG* */
1062 command_print(CMD_CTX, "**STR9FLASH** (tap1) invalid chain?");
1063 return ERROR_FAIL;
1064 }
1065 tap2 = tap1->next_tap;
1066 if (tap2 == NULL) {
1067 /* things are *WRONG* */
1068 command_print(CMD_CTX, "**STR9FLASH** (tap2) invalid chain?");
1069 return ERROR_FAIL;
1070 }
1071
1072 /* enable turbo mode - TURBO-PROG-ENABLE */
1073 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1074 retval = jtag_execute_queue();
1075 if (retval != ERROR_OK)
1076 return retval;
1077
1078 /* modify scan chain - str9 core has been removed */
1079 tap1->enabled = 0;
1080
1081 return ERROR_OK;
1082 }
1083
1084 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1085 {
1086 struct jtag_tap *tap;
1087 struct str9xpec_flash_controller *str9xpec_info = NULL;
1088
1089 if (CMD_ARGC < 1)
1090 return ERROR_COMMAND_SYNTAX_ERROR;
1091
1092 struct flash_bank *bank;
1093 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1094 if (ERROR_OK != retval)
1095 return retval;
1096
1097 str9xpec_info = bank->driver_priv;
1098 tap = str9xpec_info->tap;
1099
1100 if (tap == NULL)
1101 return ERROR_FAIL;
1102
1103 /* exit turbo mode via RESET */
1104 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1105 jtag_add_tlr();
1106 jtag_execute_queue();
1107
1108 /* restore previous scan chain */
1109 if (tap->next_tap)
1110 tap->next_tap->enabled = 1;
1111
1112 return ERROR_OK;
1113 }
1114
1115 static const struct command_registration str9xpec_config_command_handlers[] = {
1116 {
1117 .name = "enable_turbo",
1118 .usage = "<bank>",
1119 .handler = str9xpec_handle_flash_enable_turbo_command,
1120 .mode = COMMAND_EXEC,
1121 .help = "enable str9xpec turbo mode",
1122 },
1123 {
1124 .name = "disable_turbo",
1125 .usage = "<bank>",
1126 .handler = str9xpec_handle_flash_disable_turbo_command,
1127 .mode = COMMAND_EXEC,
1128 .help = "disable str9xpec turbo mode",
1129 },
1130 {
1131 .name = "options_cmap",
1132 .usage = "<bank> <bank0 | bank1>",
1133 .handler = str9xpec_handle_flash_options_cmap_command,
1134 .mode = COMMAND_EXEC,
1135 .help = "configure str9xpec boot sector",
1136 },
1137 {
1138 .name = "options_lvdthd",
1139 .usage = "<bank> <2.4v | 2.7v>",
1140 .handler = str9xpec_handle_flash_options_lvdthd_command,
1141 .mode = COMMAND_EXEC,
1142 .help = "configure str9xpec lvd threshold",
1143 },
1144 {
1145 .name = "options_lvdsel",
1146 .usage = "<bank> <vdd | vdd_vddq>",
1147 .handler = str9xpec_handle_flash_options_lvdsel_command,
1148 .mode = COMMAND_EXEC,
1149 .help = "configure str9xpec lvd selection",
1150 },
1151 {
1152 .name = "options_lvdwarn",
1153 .usage = "<bank> <vdd | vdd_vddq>",
1154 .handler = str9xpec_handle_flash_options_lvdwarn_command,
1155 .mode = COMMAND_EXEC,
1156 .help = "configure str9xpec lvd warning",
1157 },
1158 {
1159 .name = "options_read",
1160 .usage = "<bank>",
1161 .handler = str9xpec_handle_flash_options_read_command,
1162 .mode = COMMAND_EXEC,
1163 .help = "read str9xpec options",
1164 },
1165 {
1166 .name = "options_write",
1167 .usage = "<bank>",
1168 .handler = str9xpec_handle_flash_options_write_command,
1169 .mode = COMMAND_EXEC,
1170 .help = "write str9xpec options",
1171 },
1172 {
1173 .name = "lock",
1174 .usage = "<bank>",
1175 .handler = str9xpec_handle_flash_lock_command,
1176 .mode = COMMAND_EXEC,
1177 .help = "lock str9xpec device",
1178 },
1179 {
1180 .name = "unlock",
1181 .usage = "<bank>",
1182 .handler = str9xpec_handle_flash_unlock_command,
1183 .mode = COMMAND_EXEC,
1184 .help = "unlock str9xpec device",
1185 },
1186 {
1187 .name = "part_id",
1188 .handler = str9xpec_handle_part_id_command,
1189 .mode = COMMAND_EXEC,
1190 .help = "print part id of str9xpec flash bank <num>",
1191 },
1192 COMMAND_REGISTRATION_DONE
1193 };
1194
1195 static const struct command_registration str9xpec_command_handlers[] = {
1196 {
1197 .name = "str9xpec",
1198 .mode = COMMAND_ANY,
1199 .help = "str9xpec flash command group",
1200 .usage = "",
1201 .chain = str9xpec_config_command_handlers,
1202 },
1203 COMMAND_REGISTRATION_DONE
1204 };
1205
1206 struct flash_driver str9xpec_flash = {
1207 .name = "str9xpec",
1208 .commands = str9xpec_command_handlers,
1209 .flash_bank_command = str9xpec_flash_bank_command,
1210 .erase = str9xpec_erase,
1211 .protect = str9xpec_protect,
1212 .write = str9xpec_write,
1213 .read = default_flash_read,
1214 .probe = str9xpec_probe,
1215 .auto_probe = str9xpec_probe,
1216 .erase_check = str9xpec_erase_check,
1217 .protect_check = str9xpec_protect_check,
1218 .info = get_str9xpec_info,
1219 };