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

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)