4056ba7e5c392e1128226c100877262ccf3a4827
[openocd.git] / src / flash / 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 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
22 ***************************************************************************/
23 #ifdef HAVE_CONFIG_H
24 #include "config.h"
25 #endif
26
27 #include "str9xpec.h"
28 #include "arm7_9_common.h"
29
30
31 static int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last);
32 static int str9xpec_set_address(struct flash_bank_s *bank, uint8_t sector);
33 static int str9xpec_write_options(struct flash_bank_s *bank);
34
35 int str9xpec_set_instr(jtag_tap_t *tap, uint32_t new_instr, tap_state_t end_state)
36 {
37 if (tap == NULL) {
38 return ERROR_TARGET_INVALID;
39 }
40
41 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr)
42 {
43 scan_field_t field;
44
45 field.tap = tap;
46 field.num_bits = tap->ir_length;
47 field.out_value = calloc(CEIL(field.num_bits, 8), 1);
48 buf_set_u32(field.out_value, 0, field.num_bits, new_instr);
49 field.in_value = NULL;
50
51 jtag_add_ir_scan(1, &field, end_state);
52
53 free(field.out_value);
54 }
55
56 return ERROR_OK;
57 }
58
59 static uint8_t str9xpec_isc_status(jtag_tap_t *tap)
60 {
61 scan_field_t field;
62 uint8_t status;
63
64 if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
65 return ISC_STATUS_ERROR;
66
67 field.tap = tap;
68 field.num_bits = 8;
69 field.out_value = NULL;
70 field.in_value = &status;
71
72
73 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
74 jtag_execute_queue();
75
76 LOG_DEBUG("status: 0x%2.2x", status);
77
78 if (status & ISC_STATUS_SECURITY)
79 LOG_INFO("Device Security Bit Set");
80
81 return status;
82 }
83
84 static int str9xpec_isc_enable(struct flash_bank_s *bank)
85 {
86 uint8_t status;
87 jtag_tap_t *tap;
88 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
89
90 tap = str9xpec_info->tap;
91
92 if (str9xpec_info->isc_enable)
93 return ERROR_OK;
94
95 /* enter isc mode */
96 if (str9xpec_set_instr(tap, ISC_ENABLE, TAP_IDLE) != ERROR_OK)
97 return ERROR_TARGET_INVALID;
98
99 /* check ISC status */
100 status = str9xpec_isc_status(tap);
101 if (status & ISC_STATUS_MODE)
102 {
103 /* we have entered isc mode */
104 str9xpec_info->isc_enable = 1;
105 LOG_DEBUG("ISC_MODE Enabled");
106 }
107
108 return ERROR_OK;
109 }
110
111 static int str9xpec_isc_disable(struct flash_bank_s *bank)
112 {
113 uint8_t status;
114 jtag_tap_t *tap;
115 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
116
117 tap = str9xpec_info->tap;
118
119 if (!str9xpec_info->isc_enable)
120 return ERROR_OK;
121
122 if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)
123 return ERROR_TARGET_INVALID;
124
125 /* delay to handle aborts */
126 jtag_add_sleep(50);
127
128 /* check ISC status */
129 status = str9xpec_isc_status(tap);
130 if (!(status & ISC_STATUS_MODE))
131 {
132 /* we have left isc mode */
133 str9xpec_info->isc_enable = 0;
134 LOG_DEBUG("ISC_MODE Disabled");
135 }
136
137 return ERROR_OK;
138 }
139
140 static int str9xpec_read_config(struct flash_bank_s *bank)
141 {
142 scan_field_t field;
143 uint8_t status;
144 jtag_tap_t *tap;
145
146 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
147
148 tap = str9xpec_info->tap;
149
150 LOG_DEBUG("ISC_CONFIGURATION");
151
152 /* execute ISC_CONFIGURATION command */
153 str9xpec_set_instr(tap, ISC_CONFIGURATION, TAP_IRPAUSE);
154
155 field.tap = tap;
156 field.num_bits = 64;
157 field.out_value = NULL;
158 field.in_value = str9xpec_info->options;
159
160
161 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
162 jtag_execute_queue();
163
164 status = str9xpec_isc_status(tap);
165
166 return status;
167 }
168
169 static int str9xpec_build_block_list(struct flash_bank_s *bank)
170 {
171 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
172
173 int i;
174 int num_sectors;
175 int b0_sectors = 0, b1_sectors = 0;
176 uint32_t offset = 0;
177 int b1_size = 0x2000;
178
179 switch (bank->size)
180 {
181 case (256 * 1024):
182 b0_sectors = 4;
183 break;
184 case (512 * 1024):
185 b0_sectors = 8;
186 break;
187 case (1024 * 1024):
188 b0_sectors = 16;
189 break;
190 case (2048 * 1024):
191 b0_sectors = 32;
192 break;
193 case (128 * 1024):
194 b1_size = 0x4000;
195 b1_sectors = 8;
196 break;
197 case (32 * 1024):
198 b1_sectors = 4;
199 break;
200 default:
201 LOG_ERROR("BUG: unknown bank->size encountered");
202 exit(-1);
203 }
204
205 num_sectors = b0_sectors + b1_sectors;
206
207 bank->num_sectors = num_sectors;
208 bank->sectors = malloc(sizeof(flash_sector_t) * num_sectors);
209 str9xpec_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
210
211 num_sectors = 0;
212
213 for (i = 0; i < b0_sectors; i++)
214 {
215 bank->sectors[num_sectors].offset = offset;
216 bank->sectors[num_sectors].size = 0x10000;
217 offset += bank->sectors[i].size;
218 bank->sectors[num_sectors].is_erased = -1;
219 bank->sectors[num_sectors].is_protected = 1;
220 str9xpec_info->sector_bits[num_sectors++] = i;
221 }
222
223 for (i = 0; i < b1_sectors; i++)
224 {
225 bank->sectors[num_sectors].offset = offset;
226 bank->sectors[num_sectors].size = b1_size;
227 offset += bank->sectors[i].size;
228 bank->sectors[num_sectors].is_erased = -1;
229 bank->sectors[num_sectors].is_protected = 1;
230 str9xpec_info->sector_bits[num_sectors++] = i + 32;
231 }
232
233 return ERROR_OK;
234 }
235
236 /* flash bank str9x <base> <size> 0 0 <target#>
237 */
238 FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)
239 {
240 str9xpec_flash_controller_t *str9xpec_info;
241 armv4_5_common_t *armv4_5 = NULL;
242 arm7_9_common_t *arm7_9 = NULL;
243 arm_jtag_t *jtag_info = NULL;
244
245 if (argc < 6)
246 {
247 LOG_WARNING("incomplete flash_bank str9x configuration");
248 return ERROR_FLASH_BANK_INVALID;
249 }
250
251 str9xpec_info = malloc(sizeof(str9xpec_flash_controller_t));
252 bank->driver_priv = str9xpec_info;
253
254 /* REVISIT verify that the jtag position of flash controller is
255 * right after *THIS* core, which must be a STR9xx core ...
256 */
257 armv4_5 = bank->target->arch_info;
258 arm7_9 = armv4_5->arch_info;
259 jtag_info = &arm7_9->jtag_info;
260
261 str9xpec_info->tap = bank->target->tap;
262 str9xpec_info->isc_enable = 0;
263
264 str9xpec_build_block_list(bank);
265
266 /* clear option byte register */
267 buf_set_u32(str9xpec_info->options, 0, 64, 0);
268
269 return ERROR_OK;
270 }
271
272 static int str9xpec_blank_check(struct flash_bank_s *bank, int first, int last)
273 {
274 scan_field_t field;
275 uint8_t status;
276 jtag_tap_t *tap;
277 int i;
278 uint8_t *buffer = NULL;
279
280 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
281
282 tap = str9xpec_info->tap;
283
284 if (!str9xpec_info->isc_enable) {
285 str9xpec_isc_enable(bank);
286 }
287
288 if (!str9xpec_info->isc_enable) {
289 return ERROR_FLASH_OPERATION_FAILED;
290 }
291
292 buffer = calloc(CEIL(64, 8), 1);
293
294 LOG_DEBUG("blank check: first_bank: %i, last_bank: %i", first, last);
295
296 for (i = first; i <= last; i++) {
297 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
298 }
299
300 /* execute ISC_BLANK_CHECK command */
301 str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);
302
303 field.tap = tap;
304 field.num_bits = 64;
305 field.out_value = buffer;
306 field.in_value = NULL;
307
308 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
309 jtag_add_sleep(40000);
310
311 /* read blank check result */
312 field.tap = tap;
313 field.num_bits = 64;
314 field.out_value = NULL;
315 field.in_value = buffer;
316
317 jtag_add_dr_scan(1, &field, TAP_IRPAUSE);
318 jtag_execute_queue();
319
320 status = str9xpec_isc_status(tap);
321
322 for (i = first; i <= last; i++)
323 {
324 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
325 bank->sectors[i].is_erased = 0;
326 else
327 bank->sectors[i].is_erased = 1;
328 }
329
330 free(buffer);
331
332 str9xpec_isc_disable(bank);
333
334 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
335 return ERROR_FLASH_OPERATION_FAILED;
336 return ERROR_OK;
337 }
338
339 static int str9xpec_protect_check(struct flash_bank_s *bank)
340 {
341 uint8_t status;
342 int i;
343
344 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
345
346 status = str9xpec_read_config(bank);
347
348 for (i = 0; i < bank->num_sectors; i++)
349 {
350 if (buf_get_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1))
351 bank->sectors[i].is_protected = 1;
352 else
353 bank->sectors[i].is_protected = 0;
354 }
355
356 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
357 return ERROR_FLASH_OPERATION_FAILED;
358 return ERROR_OK;
359 }
360
361 static int str9xpec_erase_area(struct flash_bank_s *bank, int first, int last)
362 {
363 scan_field_t field;
364 uint8_t status;
365 jtag_tap_t *tap;
366 int i;
367 uint8_t *buffer = NULL;
368
369 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
370
371 tap = str9xpec_info->tap;
372
373 if (!str9xpec_info->isc_enable) {
374 str9xpec_isc_enable(bank);
375 }
376
377 if (!str9xpec_info->isc_enable) {
378 return ISC_STATUS_ERROR;
379 }
380
381 buffer = calloc(CEIL(64, 8), 1);
382
383 LOG_DEBUG("erase: first_bank: %i, last_bank: %i", first, last);
384
385 /* last bank: 0xFF signals a full erase (unlock complete device) */
386 /* last bank: 0xFE signals a option byte erase */
387 if (last == 0xFF)
388 {
389 for (i = 0; i < 64; i++) {
390 buf_set_u32(buffer, i, 1, 1);
391 }
392 }
393 else if (last == 0xFE)
394 {
395 buf_set_u32(buffer, 49, 1, 1);
396 }
397 else
398 {
399 for (i = first; i <= last; i++) {
400 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
401 }
402 }
403
404 LOG_DEBUG("ISC_ERASE");
405
406 /* execute ISC_ERASE command */
407 str9xpec_set_instr(tap, ISC_ERASE, TAP_IRPAUSE);
408
409 field.tap = tap;
410 field.num_bits = 64;
411 field.out_value = buffer;
412 field.in_value = NULL;
413
414 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
415 jtag_execute_queue();
416
417 jtag_add_sleep(10);
418
419 /* wait for erase completion */
420 while (!((status = str9xpec_isc_status(tap)) & ISC_STATUS_BUSY)) {
421 alive_sleep(1);
422 }
423
424 free(buffer);
425
426 str9xpec_isc_disable(bank);
427
428 return status;
429 }
430
431 static int str9xpec_erase(struct flash_bank_s *bank, int first, int last)
432 {
433 int status;
434
435 status = str9xpec_erase_area(bank, first, last);
436
437 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
438 return ERROR_FLASH_OPERATION_FAILED;
439
440 return ERROR_OK;
441 }
442
443 static int str9xpec_lock_device(struct flash_bank_s *bank)
444 {
445 scan_field_t field;
446 uint8_t status;
447 jtag_tap_t *tap;
448 str9xpec_flash_controller_t *str9xpec_info = NULL;
449
450 str9xpec_info = bank->driver_priv;
451 tap = str9xpec_info->tap;
452
453 if (!str9xpec_info->isc_enable) {
454 str9xpec_isc_enable(bank);
455 }
456
457 if (!str9xpec_info->isc_enable) {
458 return ISC_STATUS_ERROR;
459 }
460
461 /* set security address */
462 str9xpec_set_address(bank, 0x80);
463
464 /* execute ISC_PROGRAM command */
465 str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);
466
467 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
468
469 do {
470 field.tap = tap;
471 field.num_bits = 8;
472 field.out_value = NULL;
473 field.in_value = &status;
474
475 jtag_add_dr_scan(1, &field, jtag_get_end_state());
476 jtag_execute_queue();
477
478 } while (!(status & ISC_STATUS_BUSY));
479
480 str9xpec_isc_disable(bank);
481
482 return status;
483 }
484
485 static int str9xpec_unlock_device(struct flash_bank_s *bank)
486 {
487 uint8_t status;
488
489 status = str9xpec_erase_area(bank, 0, 255);
490
491 return status;
492 }
493
494 static int str9xpec_protect(struct flash_bank_s *bank, int set, int first, int last)
495 {
496 uint8_t status;
497 int i;
498
499 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
500
501 status = str9xpec_read_config(bank);
502
503 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
504 return ERROR_FLASH_OPERATION_FAILED;
505
506 LOG_DEBUG("protect: first_bank: %i, last_bank: %i", first, last);
507
508 /* last bank: 0xFF signals a full device protect */
509 if (last == 0xFF)
510 {
511 if (set)
512 {
513 status = str9xpec_lock_device(bank);
514 }
515 else
516 {
517 /* perform full erase to unlock device */
518 status = str9xpec_unlock_device(bank);
519 }
520 }
521 else
522 {
523 for (i = first; i <= last; i++)
524 {
525 if (set)
526 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
527 else
528 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
529 }
530
531 status = str9xpec_write_options(bank);
532 }
533
534 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
535 return ERROR_FLASH_OPERATION_FAILED;
536
537 return ERROR_OK;
538 }
539
540 static int str9xpec_set_address(struct flash_bank_s *bank, uint8_t sector)
541 {
542 jtag_tap_t *tap;
543 scan_field_t field;
544 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
545
546 tap = str9xpec_info->tap;
547
548 /* set flash controller address */
549 str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);
550
551 field.tap = tap;
552 field.num_bits = 8;
553 field.out_value = &sector;
554 field.in_value = NULL;
555
556 jtag_add_dr_scan(1, &field, jtag_get_end_state());
557
558 return ERROR_OK;
559 }
560
561 static int str9xpec_write(struct flash_bank_s *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
562 {
563 str9xpec_flash_controller_t *str9xpec_info = bank->driver_priv;
564 uint32_t dwords_remaining = (count / 8);
565 uint32_t bytes_remaining = (count & 0x00000007);
566 uint32_t bytes_written = 0;
567 uint8_t status;
568 uint32_t check_address = offset;
569 jtag_tap_t *tap;
570 scan_field_t field;
571 uint8_t *scanbuf;
572 int i;
573 int first_sector = 0;
574 int last_sector = 0;
575
576 tap = str9xpec_info->tap;
577
578 if (!str9xpec_info->isc_enable) {
579 str9xpec_isc_enable(bank);
580 }
581
582 if (!str9xpec_info->isc_enable) {
583 return ERROR_FLASH_OPERATION_FAILED;
584 }
585
586 if (offset & 0x7)
587 {
588 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
589 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
590 }
591
592 for (i = 0; i < bank->num_sectors; i++)
593 {
594 uint32_t sec_start = bank->sectors[i].offset;
595 uint32_t sec_end = sec_start + bank->sectors[i].size;
596
597 /* check if destination falls within the current sector */
598 if ((check_address >= sec_start) && (check_address < sec_end))
599 {
600 /* check if destination ends in the current sector */
601 if (offset + count < sec_end)
602 check_address = offset + count;
603 else
604 check_address = sec_end;
605 }
606
607 if ((offset >= sec_start) && (offset < sec_end)) {
608 first_sector = i;
609 }
610
611 if ((offset + count >= sec_start) && (offset + count < sec_end)) {
612 last_sector = i;
613 }
614 }
615
616 if (check_address != offset + count)
617 return ERROR_FLASH_DST_OUT_OF_BANK;
618
619 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
620
621 scanbuf = calloc(CEIL(64, 8), 1);
622
623 LOG_DEBUG("ISC_PROGRAM");
624
625 for (i = first_sector; i <= last_sector; i++)
626 {
627 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
628
629 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8) ? dwords_remaining : (bank->sectors[i].size/8);
630
631 while (dwords_remaining > 0)
632 {
633 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
634
635 field.tap = tap;
636 field.num_bits = 64;
637 field.out_value = (buffer + bytes_written);
638 field.in_value = NULL;
639
640 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
641
642 /* small delay before polling */
643 jtag_add_sleep(50);
644
645 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
646
647 do {
648 field.tap = tap;
649 field.num_bits = 8;
650 field.out_value = NULL;
651 field.in_value = scanbuf;
652
653 jtag_add_dr_scan(1, &field, jtag_get_end_state());
654 jtag_execute_queue();
655
656 status = buf_get_u32(scanbuf, 0, 8);
657
658 } while (!(status & ISC_STATUS_BUSY));
659
660 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
661 return ERROR_FLASH_OPERATION_FAILED;
662
663 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
664 return ERROR_FLASH_OPERATION_FAILED; */
665
666 dwords_remaining--;
667 bytes_written += 8;
668 }
669 }
670
671 if (bytes_remaining)
672 {
673 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
674 int i = 0;
675
676 while (bytes_remaining > 0)
677 {
678 last_dword[i++] = *(buffer + bytes_written);
679 bytes_remaining--;
680 bytes_written++;
681 }
682
683 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
684
685 field.tap = tap;
686 field.num_bits = 64;
687 field.out_value = last_dword;
688 field.in_value = NULL;
689
690 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
691
692 /* small delay before polling */
693 jtag_add_sleep(50);
694
695 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
696
697 do {
698 field.tap = tap;
699 field.num_bits = 8;
700 field.out_value = NULL;
701 field.in_value = scanbuf;
702
703 jtag_add_dr_scan(1, &field, jtag_get_end_state());
704 jtag_execute_queue();
705
706 status = buf_get_u32(scanbuf, 0, 8);
707
708 } while (!(status & ISC_STATUS_BUSY));
709
710 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
711 return ERROR_FLASH_OPERATION_FAILED;
712
713 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
714 return ERROR_FLASH_OPERATION_FAILED; */
715 }
716
717 free(scanbuf);
718
719 str9xpec_isc_disable(bank);
720
721 return ERROR_OK;
722 }
723
724 static int str9xpec_probe(struct flash_bank_s *bank)
725 {
726 return ERROR_OK;
727 }
728
729 COMMAND_HANDLER(str9xpec_handle_part_id_command)
730 {
731 scan_field_t field;
732 uint8_t *buffer = NULL;
733 jtag_tap_t *tap;
734 uint32_t idcode;
735 str9xpec_flash_controller_t *str9xpec_info = NULL;
736
737 if (argc < 1)
738 return ERROR_COMMAND_SYNTAX_ERROR;
739
740 flash_bank_t *bank;
741 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
742 if (ERROR_OK != retval)
743 return retval;
744
745 str9xpec_info = bank->driver_priv;
746 tap = str9xpec_info->tap;
747
748 buffer = calloc(CEIL(32, 8), 1);
749
750 str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
751
752 field.tap = tap;
753 field.num_bits = 32;
754 field.out_value = NULL;
755 field.in_value = buffer;
756
757 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
758 jtag_execute_queue();
759
760 idcode = buf_get_u32(buffer, 0, 32);
761
762 command_print(cmd_ctx, "str9xpec part id: 0x%8.8" PRIx32 "", idcode);
763
764 free(buffer);
765
766 return ERROR_OK;
767 }
768
769 static int str9xpec_erase_check(struct flash_bank_s *bank)
770 {
771 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
772 }
773
774 static int str9xpec_info(struct flash_bank_s *bank, char *buf, int buf_size)
775 {
776 snprintf(buf, buf_size, "str9xpec flash driver info");
777 return ERROR_OK;
778 }
779
780 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
781 {
782 uint8_t status;
783 str9xpec_flash_controller_t *str9xpec_info = NULL;
784
785 if (argc < 1)
786 {
787 command_print(cmd_ctx, "str9xpec options_read <bank>");
788 return ERROR_OK;
789 }
790
791 flash_bank_t *bank;
792 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
793 if (ERROR_OK != retval)
794 return retval;
795
796 str9xpec_info = bank->driver_priv;
797
798 status = str9xpec_read_config(bank);
799
800 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
801 return ERROR_FLASH_OPERATION_FAILED;
802
803 /* boot bank */
804 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
805 command_print(cmd_ctx, "CS Map: bank1");
806 else
807 command_print(cmd_ctx, "CS Map: bank0");
808
809 /* OTP lock */
810 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
811 command_print(cmd_ctx, "OTP Lock: OTP Locked");
812 else
813 command_print(cmd_ctx, "OTP Lock: OTP Unlocked");
814
815 /* LVD Threshold */
816 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
817 command_print(cmd_ctx, "LVD Threshold: 2.7v");
818 else
819 command_print(cmd_ctx, "LVD Threshold: 2.4v");
820
821 /* LVD reset warning */
822 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
823 command_print(cmd_ctx, "LVD Reset Warning: VDD or VDDQ Inputs");
824 else
825 command_print(cmd_ctx, "LVD Reset Warning: VDD Input Only");
826
827 /* LVD reset select */
828 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
829 command_print(cmd_ctx, "LVD Reset Selection: VDD or VDDQ Inputs");
830 else
831 command_print(cmd_ctx, "LVD Reset Selection: VDD Input Only");
832
833 return ERROR_OK;
834 }
835
836 static int str9xpec_write_options(struct flash_bank_s *bank)
837 {
838 scan_field_t field;
839 uint8_t status;
840 jtag_tap_t *tap;
841 str9xpec_flash_controller_t *str9xpec_info = NULL;
842
843 str9xpec_info = bank->driver_priv;
844 tap = str9xpec_info->tap;
845
846 /* erase config options first */
847 status = str9xpec_erase_area(bank, 0xFE, 0xFE);
848
849 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
850 return status;
851
852 if (!str9xpec_info->isc_enable) {
853 str9xpec_isc_enable(bank);
854 }
855
856 if (!str9xpec_info->isc_enable) {
857 return ISC_STATUS_ERROR;
858 }
859
860 /* according to data 64th bit has to be set */
861 buf_set_u32(str9xpec_info->options, 63, 1, 1);
862
863 /* set option byte address */
864 str9xpec_set_address(bank, 0x50);
865
866 /* execute ISC_PROGRAM command */
867 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
868
869 field.tap = tap;
870 field.num_bits = 64;
871 field.out_value = str9xpec_info->options;
872 field.in_value = NULL;
873
874 jtag_add_dr_scan(1, &field, jtag_set_end_state(TAP_IDLE));
875
876 /* small delay before polling */
877 jtag_add_sleep(50);
878
879 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
880
881 do {
882 field.tap = tap;
883 field.num_bits = 8;
884 field.out_value = NULL;
885 field.in_value = &status;
886
887 jtag_add_dr_scan(1, &field, jtag_get_end_state());
888 jtag_execute_queue();
889
890 } while (!(status & ISC_STATUS_BUSY));
891
892 str9xpec_isc_disable(bank);
893
894 return status;
895 }
896
897 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
898 {
899 uint8_t status;
900
901 if (argc < 1)
902 {
903 command_print(cmd_ctx, "str9xpec options_write <bank>");
904 return ERROR_OK;
905 }
906
907 flash_bank_t *bank;
908 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
909 if (ERROR_OK != retval)
910 return retval;
911
912 status = str9xpec_write_options(bank);
913
914 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
915 return ERROR_FLASH_OPERATION_FAILED;
916
917 return ERROR_OK;
918 }
919
920 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
921 {
922 str9xpec_flash_controller_t *str9xpec_info = NULL;
923
924 if (argc < 2)
925 {
926 command_print(cmd_ctx, "str9xpec options_cmap <bank> <bank0 | bank1>");
927 return ERROR_OK;
928 }
929
930 flash_bank_t *bank;
931 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
932 if (ERROR_OK != retval)
933 return retval;
934
935 str9xpec_info = bank->driver_priv;
936
937 if (strcmp(args[1], "bank1") == 0)
938 {
939 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
940 }
941 else
942 {
943 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
944 }
945
946 return ERROR_OK;
947 }
948
949 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
950 {
951 str9xpec_flash_controller_t *str9xpec_info = NULL;
952
953 if (argc < 2)
954 {
955 command_print(cmd_ctx, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
956 return ERROR_OK;
957 }
958
959 flash_bank_t *bank;
960 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
961 if (ERROR_OK != retval)
962 return retval;
963
964 str9xpec_info = bank->driver_priv;
965
966 if (strcmp(args[1], "2.7v") == 0)
967 {
968 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
969 }
970 else
971 {
972 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
973 }
974
975 return ERROR_OK;
976 }
977
978 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
979 {
980 str9xpec_flash_controller_t *str9xpec_info = NULL;
981
982 if (argc < 2)
983 {
984 command_print(cmd_ctx, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
985 return ERROR_OK;
986 }
987
988 flash_bank_t *bank;
989 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
990 if (ERROR_OK != retval)
991 return retval;
992
993 str9xpec_info = bank->driver_priv;
994
995 if (strcmp(args[1], "vdd_vddq") == 0)
996 {
997 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
998 }
999 else
1000 {
1001 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
1002 }
1003
1004 return ERROR_OK;
1005 }
1006
1007 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
1008 {
1009 str9xpec_flash_controller_t *str9xpec_info = NULL;
1010
1011 if (argc < 2)
1012 {
1013 command_print(cmd_ctx, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
1014 return ERROR_OK;
1015 }
1016
1017 flash_bank_t *bank;
1018 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
1019 if (ERROR_OK != retval)
1020 return retval;
1021
1022 str9xpec_info = bank->driver_priv;
1023
1024 if (strcmp(args[1], "vdd_vddq") == 0)
1025 {
1026 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
1027 }
1028 else
1029 {
1030 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1031 }
1032
1033 return ERROR_OK;
1034 }
1035
1036 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
1037 {
1038 uint8_t status;
1039
1040 if (argc < 1)
1041 {
1042 command_print(cmd_ctx, "str9xpec lock <bank>");
1043 return ERROR_OK;
1044 }
1045
1046 flash_bank_t *bank;
1047 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
1048 if (ERROR_OK != retval)
1049 return retval;
1050
1051 status = str9xpec_lock_device(bank);
1052
1053 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1054 return ERROR_FLASH_OPERATION_FAILED;
1055
1056 return ERROR_OK;
1057 }
1058
1059 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
1060 {
1061 uint8_t status;
1062
1063 if (argc < 1)
1064 {
1065 command_print(cmd_ctx, "str9xpec unlock <bank>");
1066 return ERROR_OK;
1067 }
1068
1069 flash_bank_t *bank;
1070 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
1071 if (ERROR_OK != retval)
1072 return retval;
1073
1074 status = str9xpec_unlock_device(bank);
1075
1076 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1077 return ERROR_FLASH_OPERATION_FAILED;
1078
1079 return ERROR_OK;
1080 }
1081
1082 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
1083 {
1084 jtag_tap_t *tap0;
1085 jtag_tap_t *tap1;
1086 jtag_tap_t *tap2;
1087 str9xpec_flash_controller_t *str9xpec_info = NULL;
1088
1089 if (argc < 1)
1090 {
1091 command_print(cmd_ctx, "str9xpec enable_turbo <bank>");
1092 return ERROR_OK;
1093 }
1094
1095 flash_bank_t *bank;
1096 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
1097 if (ERROR_OK != retval)
1098 return retval;
1099
1100 str9xpec_info = bank->driver_priv;
1101
1102 tap0 = str9xpec_info->tap;
1103
1104 /* remove arm core from chain - enter turbo mode */
1105 tap1 = tap0->next_tap;
1106 if (tap1 == NULL)
1107 {
1108 /* things are *WRONG* */
1109 command_print(cmd_ctx,"**STR9FLASH** (tap1) invalid chain?");
1110 return ERROR_OK;
1111 }
1112 tap2 = tap1->next_tap;
1113 if (tap2 == NULL)
1114 {
1115 /* things are *WRONG* */
1116 command_print(cmd_ctx,"**STR9FLASH** (tap2) invalid chain?");
1117 return ERROR_OK;
1118 }
1119
1120 /* enable turbo mode - TURBO-PROG-ENABLE */
1121 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1122 if ((retval = jtag_execute_queue()) != ERROR_OK)
1123 return retval;
1124
1125 /* modify scan chain - str9 core has been removed */
1126 tap1->enabled = 0;
1127
1128 return ERROR_OK;
1129 }
1130
1131 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1132 {
1133 jtag_tap_t *tap;
1134 str9xpec_flash_controller_t *str9xpec_info = NULL;
1135
1136 if (argc < 1)
1137 {
1138 command_print(cmd_ctx, "str9xpec disable_turbo <bank>");
1139 return ERROR_OK;
1140 }
1141
1142 flash_bank_t *bank;
1143 int retval = flash_command_get_bank_by_num(cmd_ctx, args[0], &bank);
1144 if (ERROR_OK != retval)
1145 return retval;
1146
1147 str9xpec_info = bank->driver_priv;
1148 tap = str9xpec_info->tap;
1149
1150 if (tap == NULL)
1151 return ERROR_FAIL;
1152
1153 /* exit turbo mode via RESET */
1154 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1155 jtag_add_tlr();
1156 jtag_execute_queue();
1157
1158 /* restore previous scan chain */
1159 if (tap->next_tap) {
1160 tap->next_tap->enabled = 1;
1161 }
1162
1163 return ERROR_OK;
1164 }
1165
1166 static int str9xpec_register_commands(struct command_context_s *cmd_ctx)
1167 {
1168 command_t *str9xpec_cmd = register_command(cmd_ctx, NULL, "str9xpec",
1169 NULL, COMMAND_ANY, "str9xpec flash specific commands");
1170
1171 register_command(cmd_ctx, str9xpec_cmd, "enable_turbo",
1172 str9xpec_handle_flash_enable_turbo_command,
1173 COMMAND_EXEC, "enable str9xpec turbo mode");
1174 register_command(cmd_ctx, str9xpec_cmd, "disable_turbo",
1175 str9xpec_handle_flash_disable_turbo_command,
1176 COMMAND_EXEC, "disable str9xpec turbo mode");
1177 register_command(cmd_ctx, str9xpec_cmd, "options_cmap",
1178 str9xpec_handle_flash_options_cmap_command,
1179 COMMAND_EXEC, "configure str9xpec boot sector");
1180 register_command(cmd_ctx, str9xpec_cmd, "options_lvdthd",
1181 str9xpec_handle_flash_options_lvdthd_command,
1182 COMMAND_EXEC, "configure str9xpec lvd threshold");
1183 register_command(cmd_ctx, str9xpec_cmd, "options_lvdsel",
1184 str9xpec_handle_flash_options_lvdsel_command,
1185 COMMAND_EXEC, "configure str9xpec lvd selection");
1186 register_command(cmd_ctx, str9xpec_cmd, "options_lvdwarn",
1187 str9xpec_handle_flash_options_lvdwarn_command,
1188 COMMAND_EXEC, "configure str9xpec lvd warning");
1189 register_command(cmd_ctx, str9xpec_cmd, "options_read",
1190 str9xpec_handle_flash_options_read_command,
1191 COMMAND_EXEC, "read str9xpec options");
1192 register_command(cmd_ctx, str9xpec_cmd, "options_write",
1193 str9xpec_handle_flash_options_write_command,
1194 COMMAND_EXEC, "write str9xpec options");
1195 register_command(cmd_ctx, str9xpec_cmd, "lock",
1196 str9xpec_handle_flash_lock_command,
1197 COMMAND_EXEC, "lock str9xpec device");
1198 register_command(cmd_ctx, str9xpec_cmd, "unlock",
1199 str9xpec_handle_flash_unlock_command,
1200 COMMAND_EXEC, "unlock str9xpec device");
1201 register_command(cmd_ctx, str9xpec_cmd, "part_id",
1202 str9xpec_handle_part_id_command,
1203 COMMAND_EXEC, "print part id of str9xpec flash bank <num>");
1204
1205 return ERROR_OK;
1206 }
1207
1208 flash_driver_t str9xpec_flash = {
1209 .name = "str9xpec",
1210 .register_commands = &str9xpec_register_commands,
1211 .flash_bank_command = &str9xpec_flash_bank_command,
1212 .erase = &str9xpec_erase,
1213 .protect = &str9xpec_protect,
1214 .write = &str9xpec_write,
1215 .probe = &str9xpec_probe,
1216 .auto_probe = &str9xpec_probe,
1217 .erase_check = &str9xpec_erase_check,
1218 .protect_check = &str9xpec_protect_check,
1219 .info = &str9xpec_info,
1220 };