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

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)