str9xpec_flash_controller_t -> struct str9xpec_flash_controller
[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(struct jtag_tap *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 struct scan_field 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(struct jtag_tap *tap)
60 {
61 struct scan_field 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 struct jtag_tap *tap;
88 struct str9xpec_flash_controller *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 struct jtag_tap *tap;
115 struct str9xpec_flash_controller *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 struct scan_field field;
143 uint8_t status;
144 struct jtag_tap *tap;
145
146 struct str9xpec_flash_controller *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 struct str9xpec_flash_controller *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(struct flash_sector) * 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 struct str9xpec_flash_controller *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(struct str9xpec_flash_controller));
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 struct scan_field field;
275 uint8_t status;
276 struct jtag_tap *tap;
277 int i;
278 uint8_t *buffer = NULL;
279
280 struct str9xpec_flash_controller *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 struct str9xpec_flash_controller *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 struct scan_field field;
364 uint8_t status;
365 struct jtag_tap *tap;
366 int i;
367 uint8_t *buffer = NULL;
368
369 struct str9xpec_flash_controller *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 struct scan_field field;
446 uint8_t status;
447 struct jtag_tap *tap;
448 struct str9xpec_flash_controller *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 struct str9xpec_flash_controller *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 struct jtag_tap *tap;
543 struct scan_field field;
544 struct str9xpec_flash_controller *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 struct str9xpec_flash_controller *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 struct jtag_tap *tap;
570 struct scan_field 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 struct scan_field field;
732 uint8_t *buffer = NULL;
733 struct jtag_tap *tap;
734 uint32_t idcode;
735 struct str9xpec_flash_controller *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 struct str9xpec_flash_controller *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 struct scan_field field;
839 uint8_t status;
840 struct jtag_tap *tap;
841 struct str9xpec_flash_controller *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 struct str9xpec_flash_controller *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 struct str9xpec_flash_controller *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 struct str9xpec_flash_controller *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 struct str9xpec_flash_controller *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 struct jtag_tap *tap0;
1085 struct jtag_tap *tap1;
1086 struct jtag_tap *tap2;
1087 struct str9xpec_flash_controller *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 struct jtag_tap *tap;
1134 struct str9xpec_flash_controller *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 struct flash_driver 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 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)