NOR: cleanup driver decls
[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 return ERROR_OK;
919 }
920
921 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
922 {
923 struct str9xpec_flash_controller *str9xpec_info = NULL;
924
925 if (CMD_ARGC < 2)
926 {
927 command_print(CMD_CTX, "str9xpec options_cmap <bank> <bank0 | bank1>");
928 return ERROR_OK;
929 }
930
931 struct flash_bank *bank;
932 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
933 if (ERROR_OK != retval)
934 return retval;
935
936 str9xpec_info = bank->driver_priv;
937
938 if (strcmp(CMD_ARGV[1], "bank1") == 0)
939 {
940 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
941 }
942 else
943 {
944 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
945 }
946
947 return ERROR_OK;
948 }
949
950 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
951 {
952 struct str9xpec_flash_controller *str9xpec_info = NULL;
953
954 if (CMD_ARGC < 2)
955 {
956 command_print(CMD_CTX, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
957 return ERROR_OK;
958 }
959
960 struct flash_bank *bank;
961 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
962 if (ERROR_OK != retval)
963 return retval;
964
965 str9xpec_info = bank->driver_priv;
966
967 if (strcmp(CMD_ARGV[1], "2.7v") == 0)
968 {
969 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
970 }
971 else
972 {
973 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
974 }
975
976 return ERROR_OK;
977 }
978
979 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
980 {
981 struct str9xpec_flash_controller *str9xpec_info = NULL;
982
983 if (CMD_ARGC < 2)
984 {
985 command_print(CMD_CTX, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
986 return ERROR_OK;
987 }
988
989 struct flash_bank *bank;
990 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
991 if (ERROR_OK != retval)
992 return retval;
993
994 str9xpec_info = bank->driver_priv;
995
996 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
997 {
998 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
999 }
1000 else
1001 {
1002 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
1003 }
1004
1005 return ERROR_OK;
1006 }
1007
1008 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
1009 {
1010 struct str9xpec_flash_controller *str9xpec_info = NULL;
1011
1012 if (CMD_ARGC < 2)
1013 {
1014 command_print(CMD_CTX, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
1015 return ERROR_OK;
1016 }
1017
1018 struct flash_bank *bank;
1019 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1020 if (ERROR_OK != retval)
1021 return retval;
1022
1023 str9xpec_info = bank->driver_priv;
1024
1025 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
1026 {
1027 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
1028 }
1029 else
1030 {
1031 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1032 }
1033
1034 return ERROR_OK;
1035 }
1036
1037 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
1038 {
1039 uint8_t status;
1040
1041 if (CMD_ARGC < 1)
1042 {
1043 command_print(CMD_CTX, "str9xpec lock <bank>");
1044 return ERROR_OK;
1045 }
1046
1047 struct flash_bank *bank;
1048 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1049 if (ERROR_OK != retval)
1050 return retval;
1051
1052 status = str9xpec_lock_device(bank);
1053
1054 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1055 return ERROR_FLASH_OPERATION_FAILED;
1056
1057 return ERROR_OK;
1058 }
1059
1060 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
1061 {
1062 uint8_t status;
1063
1064 if (CMD_ARGC < 1)
1065 {
1066 command_print(CMD_CTX, "str9xpec unlock <bank>");
1067 return ERROR_OK;
1068 }
1069
1070 struct flash_bank *bank;
1071 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1072 if (ERROR_OK != retval)
1073 return retval;
1074
1075 status = str9xpec_unlock_device(bank);
1076
1077 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1078 return ERROR_FLASH_OPERATION_FAILED;
1079
1080 return ERROR_OK;
1081 }
1082
1083 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
1084 {
1085 struct jtag_tap *tap0;
1086 struct jtag_tap *tap1;
1087 struct jtag_tap *tap2;
1088 struct str9xpec_flash_controller *str9xpec_info = NULL;
1089
1090 if (CMD_ARGC < 1)
1091 {
1092 command_print(CMD_CTX, "str9xpec enable_turbo <bank>");
1093 return ERROR_OK;
1094 }
1095
1096 struct flash_bank *bank;
1097 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1098 if (ERROR_OK != retval)
1099 return retval;
1100
1101 str9xpec_info = bank->driver_priv;
1102
1103 tap0 = str9xpec_info->tap;
1104
1105 /* remove arm core from chain - enter turbo mode */
1106 tap1 = tap0->next_tap;
1107 if (tap1 == NULL)
1108 {
1109 /* things are *WRONG* */
1110 command_print(CMD_CTX,"**STR9FLASH** (tap1) invalid chain?");
1111 return ERROR_OK;
1112 }
1113 tap2 = tap1->next_tap;
1114 if (tap2 == NULL)
1115 {
1116 /* things are *WRONG* */
1117 command_print(CMD_CTX,"**STR9FLASH** (tap2) invalid chain?");
1118 return ERROR_OK;
1119 }
1120
1121 /* enable turbo mode - TURBO-PROG-ENABLE */
1122 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1123 if ((retval = jtag_execute_queue()) != ERROR_OK)
1124 return retval;
1125
1126 /* modify scan chain - str9 core has been removed */
1127 tap1->enabled = 0;
1128
1129 return ERROR_OK;
1130 }
1131
1132 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1133 {
1134 struct jtag_tap *tap;
1135 struct str9xpec_flash_controller *str9xpec_info = NULL;
1136
1137 if (CMD_ARGC < 1)
1138 {
1139 command_print(CMD_CTX, "str9xpec disable_turbo <bank>");
1140 return ERROR_OK;
1141 }
1142
1143 struct flash_bank *bank;
1144 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1145 if (ERROR_OK != retval)
1146 return retval;
1147
1148 str9xpec_info = bank->driver_priv;
1149 tap = str9xpec_info->tap;
1150
1151 if (tap == NULL)
1152 return ERROR_FAIL;
1153
1154 /* exit turbo mode via RESET */
1155 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1156 jtag_add_tlr();
1157 jtag_execute_queue();
1158
1159 /* restore previous scan chain */
1160 if (tap->next_tap) {
1161 tap->next_tap->enabled = 1;
1162 }
1163
1164 return ERROR_OK;
1165 }
1166
1167 static const struct command_registration str9xpec_config_command_handlers[] = {
1168 {
1169 .name = "enable_turbo",
1170 .handler = str9xpec_handle_flash_enable_turbo_command,
1171 .mode = COMMAND_EXEC,
1172 .help = "enable str9xpec turbo mode",
1173 },
1174 {
1175 .name = "disable_turbo",
1176 .handler = str9xpec_handle_flash_disable_turbo_command,
1177 .mode = COMMAND_EXEC,
1178 .help = "disable str9xpec turbo mode",
1179 },
1180 {
1181 .name = "options_cmap",
1182 .handler = str9xpec_handle_flash_options_cmap_command,
1183 .mode = COMMAND_EXEC,
1184 .help = "configure str9xpec boot sector",
1185 },
1186 {
1187 .name = "options_lvdthd",
1188 .handler = str9xpec_handle_flash_options_lvdthd_command,
1189 .mode = COMMAND_EXEC,
1190 .help = "configure str9xpec lvd threshold",
1191 },
1192 {
1193 .name = "options_lvdsel",
1194 .handler = str9xpec_handle_flash_options_lvdsel_command,
1195 .mode = COMMAND_EXEC,
1196 .help = "configure str9xpec lvd selection",
1197 },
1198 {
1199 .name = "options_lvdwarn",
1200 .handler = str9xpec_handle_flash_options_lvdwarn_command,
1201 .mode = COMMAND_EXEC,
1202 .help = "configure str9xpec lvd warning",
1203 },
1204 {
1205 .name = "options_read",
1206 .handler = str9xpec_handle_flash_options_read_command,
1207 .mode = COMMAND_EXEC,
1208 .help = "read str9xpec options",
1209 },
1210 {
1211 .name = "options_write",
1212 .handler = str9xpec_handle_flash_options_write_command,
1213 .mode = COMMAND_EXEC,
1214 .help = "write str9xpec options",
1215 },
1216 {
1217 .name = "lock",
1218 .handler = str9xpec_handle_flash_lock_command,
1219 .mode = COMMAND_EXEC,
1220 .help = "lock str9xpec device",
1221 },
1222 {
1223 .name = "unlock",
1224 .handler = str9xpec_handle_flash_unlock_command,
1225 .mode = COMMAND_EXEC,
1226 .help = "unlock str9xpec device",
1227 },
1228 {
1229 .name = "part_id",
1230 .handler = str9xpec_handle_part_id_command,
1231 .mode = COMMAND_EXEC,
1232 .help = "print part id of str9xpec flash bank <num>",
1233 },
1234 COMMAND_REGISTRATION_DONE
1235 };
1236 static const struct command_registration str9xpec_command_handlers[] = {
1237 {
1238 .name = "str9xpec",
1239 .mode = COMMAND_ANY,
1240 .help = "str9xpec flash command group",
1241 .chain = str9xpec_config_command_handlers,
1242 },
1243 COMMAND_REGISTRATION_DONE
1244 };
1245
1246 struct flash_driver str9xpec_flash = {
1247 .name = "str9xpec",
1248 .commands = str9xpec_command_handlers,
1249 .flash_bank_command = str9xpec_flash_bank_command,
1250 .erase = str9xpec_erase,
1251 .protect = str9xpec_protect,
1252 .write = str9xpec_write,
1253 .probe = str9xpec_probe,
1254 .auto_probe = str9xpec_probe,
1255 .erase_check = str9xpec_erase_check,
1256 .protect_check = str9xpec_protect_check,
1257 .info = str9xpec_info,
1258 };

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)