jtag: cut down on usage of unintended modification of global end state
[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, &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, 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, 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, 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, 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, TAP_IDLE);
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, TAP_IRPAUSE);
550
551 return ERROR_OK;
552 }
553
554 static int str9xpec_write(struct flash_bank *bank, uint8_t *buffer,
555 uint32_t offset, uint32_t count)
556 {
557 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
558 uint32_t dwords_remaining = (count / 8);
559 uint32_t bytes_remaining = (count & 0x00000007);
560 uint32_t bytes_written = 0;
561 uint8_t status;
562 uint32_t check_address = offset;
563 struct jtag_tap *tap;
564 struct scan_field field;
565 uint8_t *scanbuf;
566 int i;
567 int first_sector = 0;
568 int last_sector = 0;
569
570 tap = str9xpec_info->tap;
571
572 if (!str9xpec_info->isc_enable) {
573 str9xpec_isc_enable(bank);
574 }
575
576 if (!str9xpec_info->isc_enable) {
577 return ERROR_FLASH_OPERATION_FAILED;
578 }
579
580 if (offset & 0x7)
581 {
582 LOG_WARNING("offset 0x%" PRIx32 " breaks required 8-byte alignment", offset);
583 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
584 }
585
586 for (i = 0; i < bank->num_sectors; i++)
587 {
588 uint32_t sec_start = bank->sectors[i].offset;
589 uint32_t sec_end = sec_start + bank->sectors[i].size;
590
591 /* check if destination falls within the current sector */
592 if ((check_address >= sec_start) && (check_address < sec_end))
593 {
594 /* check if destination ends in the current sector */
595 if (offset + count < sec_end)
596 check_address = offset + count;
597 else
598 check_address = sec_end;
599 }
600
601 if ((offset >= sec_start) && (offset < sec_end)) {
602 first_sector = i;
603 }
604
605 if ((offset + count >= sec_start) && (offset + count < sec_end)) {
606 last_sector = i;
607 }
608 }
609
610 if (check_address != offset + count)
611 return ERROR_FLASH_DST_OUT_OF_BANK;
612
613 LOG_DEBUG("first_sector: %i, last_sector: %i", first_sector, last_sector);
614
615 scanbuf = calloc(DIV_ROUND_UP(64, 8), 1);
616
617 LOG_DEBUG("ISC_PROGRAM");
618
619 for (i = first_sector; i <= last_sector; i++)
620 {
621 str9xpec_set_address(bank, str9xpec_info->sector_bits[i]);
622
623 dwords_remaining = dwords_remaining < (bank->sectors[i].size/8)
624 ? dwords_remaining : (bank->sectors[i].size/8);
625
626 while (dwords_remaining > 0)
627 {
628 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
629
630 field.num_bits = 64;
631 field.out_value = (buffer + bytes_written);
632 field.in_value = NULL;
633
634 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
635
636 /* small delay before polling */
637 jtag_add_sleep(50);
638
639 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
640
641 do {
642 field.num_bits = 8;
643 field.out_value = NULL;
644 field.in_value = scanbuf;
645
646 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
647 jtag_execute_queue();
648
649 status = buf_get_u32(scanbuf, 0, 8);
650
651 } while (!(status & ISC_STATUS_BUSY));
652
653 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
654 return ERROR_FLASH_OPERATION_FAILED;
655
656 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
657 return ERROR_FLASH_OPERATION_FAILED; */
658
659 dwords_remaining--;
660 bytes_written += 8;
661 }
662 }
663
664 if (bytes_remaining)
665 {
666 uint8_t last_dword[8] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
667 int i = 0;
668
669 while (bytes_remaining > 0)
670 {
671 last_dword[i++] = *(buffer + bytes_written);
672 bytes_remaining--;
673 bytes_written++;
674 }
675
676 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
677
678 field.num_bits = 64;
679 field.out_value = last_dword;
680 field.in_value = NULL;
681
682 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
683
684 /* small delay before polling */
685 jtag_add_sleep(50);
686
687 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
688
689 do {
690 field.num_bits = 8;
691 field.out_value = NULL;
692 field.in_value = scanbuf;
693
694 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
695 jtag_execute_queue();
696
697 status = buf_get_u32(scanbuf, 0, 8);
698
699 } while (!(status & ISC_STATUS_BUSY));
700
701 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
702 return ERROR_FLASH_OPERATION_FAILED;
703
704 /* if ((status & ISC_STATUS_INT_ERROR) != STR9XPEC_ISC_INTFAIL)
705 return ERROR_FLASH_OPERATION_FAILED; */
706 }
707
708 free(scanbuf);
709
710 str9xpec_isc_disable(bank);
711
712 return ERROR_OK;
713 }
714
715 static int str9xpec_probe(struct flash_bank *bank)
716 {
717 return ERROR_OK;
718 }
719
720 COMMAND_HANDLER(str9xpec_handle_part_id_command)
721 {
722 struct scan_field field;
723 uint8_t *buffer = NULL;
724 struct jtag_tap *tap;
725 uint32_t idcode;
726 struct str9xpec_flash_controller *str9xpec_info = NULL;
727
728 if (CMD_ARGC < 1)
729 return ERROR_COMMAND_SYNTAX_ERROR;
730
731 struct flash_bank *bank;
732 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
733 if (ERROR_OK != retval)
734 return retval;
735
736 str9xpec_info = bank->driver_priv;
737 tap = str9xpec_info->tap;
738
739 buffer = calloc(DIV_ROUND_UP(32, 8), 1);
740
741 str9xpec_set_instr(tap, ISC_IDCODE, TAP_IRPAUSE);
742
743 field.num_bits = 32;
744 field.out_value = NULL;
745 field.in_value = buffer;
746
747 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
748 jtag_execute_queue();
749
750 idcode = buf_get_u32(buffer, 0, 32);
751
752 command_print(CMD_CTX, "str9xpec part id: 0x%8.8" PRIx32 "", idcode);
753
754 free(buffer);
755
756 return ERROR_OK;
757 }
758
759 static int str9xpec_erase_check(struct flash_bank *bank)
760 {
761 return str9xpec_blank_check(bank, 0, bank->num_sectors - 1);
762 }
763
764 static int str9xpec_info(struct flash_bank *bank, char *buf, int buf_size)
765 {
766 snprintf(buf, buf_size, "str9xpec flash driver info");
767 return ERROR_OK;
768 }
769
770 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
771 {
772 uint8_t status;
773 struct str9xpec_flash_controller *str9xpec_info = NULL;
774
775 if (CMD_ARGC < 1)
776 {
777 command_print(CMD_CTX, "str9xpec options_read <bank>");
778 return ERROR_OK;
779 }
780
781 struct flash_bank *bank;
782 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
783 if (ERROR_OK != retval)
784 return retval;
785
786 str9xpec_info = bank->driver_priv;
787
788 status = str9xpec_read_config(bank);
789
790 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
791 return ERROR_FLASH_OPERATION_FAILED;
792
793 /* boot bank */
794 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
795 command_print(CMD_CTX, "CS Map: bank1");
796 else
797 command_print(CMD_CTX, "CS Map: bank0");
798
799 /* OTP lock */
800 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
801 command_print(CMD_CTX, "OTP Lock: OTP Locked");
802 else
803 command_print(CMD_CTX, "OTP Lock: OTP Unlocked");
804
805 /* LVD Threshold */
806 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
807 command_print(CMD_CTX, "LVD Threshold: 2.7v");
808 else
809 command_print(CMD_CTX, "LVD Threshold: 2.4v");
810
811 /* LVD reset warning */
812 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
813 command_print(CMD_CTX, "LVD Reset Warning: VDD or VDDQ Inputs");
814 else
815 command_print(CMD_CTX, "LVD Reset Warning: VDD Input Only");
816
817 /* LVD reset select */
818 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
819 command_print(CMD_CTX, "LVD Reset Selection: VDD or VDDQ Inputs");
820 else
821 command_print(CMD_CTX, "LVD Reset Selection: VDD Input Only");
822
823 return ERROR_OK;
824 }
825
826 static int str9xpec_write_options(struct flash_bank *bank)
827 {
828 struct scan_field field;
829 uint8_t status;
830 struct jtag_tap *tap;
831 struct str9xpec_flash_controller *str9xpec_info = NULL;
832
833 str9xpec_info = bank->driver_priv;
834 tap = str9xpec_info->tap;
835
836 /* erase config options first */
837 status = str9xpec_erase_area(bank, 0xFE, 0xFE);
838
839 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
840 return status;
841
842 if (!str9xpec_info->isc_enable) {
843 str9xpec_isc_enable(bank);
844 }
845
846 if (!str9xpec_info->isc_enable) {
847 return ISC_STATUS_ERROR;
848 }
849
850 /* according to data 64th bit has to be set */
851 buf_set_u32(str9xpec_info->options, 63, 1, 1);
852
853 /* set option byte address */
854 str9xpec_set_address(bank, 0x50);
855
856 /* execute ISC_PROGRAM command */
857 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
858
859 field.num_bits = 64;
860 field.out_value = str9xpec_info->options;
861 field.in_value = NULL;
862
863 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
864
865 /* small delay before polling */
866 jtag_add_sleep(50);
867
868 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
869
870 do {
871 field.num_bits = 8;
872 field.out_value = NULL;
873 field.in_value = &status;
874
875 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
876 jtag_execute_queue();
877
878 } while (!(status & ISC_STATUS_BUSY));
879
880 str9xpec_isc_disable(bank);
881
882 return status;
883 }
884
885 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
886 {
887 uint8_t status;
888
889 if (CMD_ARGC < 1)
890 {
891 command_print(CMD_CTX, "str9xpec options_write <bank>");
892 return ERROR_OK;
893 }
894
895 struct flash_bank *bank;
896 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
897 if (ERROR_OK != retval)
898 return retval;
899
900 status = str9xpec_write_options(bank);
901
902 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
903 return ERROR_FLASH_OPERATION_FAILED;
904
905 command_print(CMD_CTX, "str9xpec write options complete.\n"
906 "INFO: a reset or power cycle is required "
907 "for the new settings to take effect.");
908
909 return ERROR_OK;
910 }
911
912 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
913 {
914 struct str9xpec_flash_controller *str9xpec_info = NULL;
915
916 if (CMD_ARGC < 2)
917 {
918 command_print(CMD_CTX, "str9xpec options_cmap <bank> <bank0 | bank1>");
919 return ERROR_OK;
920 }
921
922 struct flash_bank *bank;
923 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
924 if (ERROR_OK != retval)
925 return retval;
926
927 str9xpec_info = bank->driver_priv;
928
929 if (strcmp(CMD_ARGV[1], "bank1") == 0)
930 {
931 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
932 }
933 else
934 {
935 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
936 }
937
938 return ERROR_OK;
939 }
940
941 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
942 {
943 struct str9xpec_flash_controller *str9xpec_info = NULL;
944
945 if (CMD_ARGC < 2)
946 {
947 command_print(CMD_CTX, "str9xpec options_lvdthd <bank> <2.4v | 2.7v>");
948 return ERROR_OK;
949 }
950
951 struct flash_bank *bank;
952 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
953 if (ERROR_OK != retval)
954 return retval;
955
956 str9xpec_info = bank->driver_priv;
957
958 if (strcmp(CMD_ARGV[1], "2.7v") == 0)
959 {
960 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
961 }
962 else
963 {
964 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
965 }
966
967 return ERROR_OK;
968 }
969
970 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
971 {
972 struct str9xpec_flash_controller *str9xpec_info = NULL;
973
974 if (CMD_ARGC < 2)
975 {
976 command_print(CMD_CTX, "str9xpec options_lvdsel <bank> <vdd | vdd_vddq>");
977 return ERROR_OK;
978 }
979
980 struct flash_bank *bank;
981 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
982 if (ERROR_OK != retval)
983 return retval;
984
985 str9xpec_info = bank->driver_priv;
986
987 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
988 {
989 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
990 }
991 else
992 {
993 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
994 }
995
996 return ERROR_OK;
997 }
998
999 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
1000 {
1001 struct str9xpec_flash_controller *str9xpec_info = NULL;
1002
1003 if (CMD_ARGC < 2)
1004 {
1005 command_print(CMD_CTX, "str9xpec options_lvdwarn <bank> <vdd | vdd_vddq>");
1006 return ERROR_OK;
1007 }
1008
1009 struct flash_bank *bank;
1010 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1011 if (ERROR_OK != retval)
1012 return retval;
1013
1014 str9xpec_info = bank->driver_priv;
1015
1016 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
1017 {
1018 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
1019 }
1020 else
1021 {
1022 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
1023 }
1024
1025 return ERROR_OK;
1026 }
1027
1028 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
1029 {
1030 uint8_t status;
1031
1032 if (CMD_ARGC < 1)
1033 {
1034 command_print(CMD_CTX, "str9xpec lock <bank>");
1035 return ERROR_OK;
1036 }
1037
1038 struct flash_bank *bank;
1039 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1040 if (ERROR_OK != retval)
1041 return retval;
1042
1043 status = str9xpec_lock_device(bank);
1044
1045 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1046 return ERROR_FLASH_OPERATION_FAILED;
1047
1048 return ERROR_OK;
1049 }
1050
1051 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
1052 {
1053 uint8_t status;
1054
1055 if (CMD_ARGC < 1)
1056 {
1057 command_print(CMD_CTX, "str9xpec unlock <bank>");
1058 return ERROR_OK;
1059 }
1060
1061 struct flash_bank *bank;
1062 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1063 if (ERROR_OK != retval)
1064 return retval;
1065
1066 status = str9xpec_unlock_device(bank);
1067
1068 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1069 return ERROR_FLASH_OPERATION_FAILED;
1070
1071 command_print(CMD_CTX, "str9xpec unlocked.\n"
1072 "INFO: a reset or power cycle is required "
1073 "for the new settings to take effect.");
1074
1075 return ERROR_OK;
1076 }
1077
1078 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
1079 {
1080 struct jtag_tap *tap0;
1081 struct jtag_tap *tap1;
1082 struct jtag_tap *tap2;
1083 struct str9xpec_flash_controller *str9xpec_info = NULL;
1084
1085 if (CMD_ARGC < 1)
1086 {
1087 command_print(CMD_CTX, "str9xpec enable_turbo <bank>");
1088 return ERROR_OK;
1089 }
1090
1091 struct flash_bank *bank;
1092 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1093 if (ERROR_OK != retval)
1094 return retval;
1095
1096 str9xpec_info = bank->driver_priv;
1097
1098 tap0 = str9xpec_info->tap;
1099
1100 /* remove arm core from chain - enter turbo mode */
1101 tap1 = tap0->next_tap;
1102 if (tap1 == NULL)
1103 {
1104 /* things are *WRONG* */
1105 command_print(CMD_CTX,"**STR9FLASH** (tap1) invalid chain?");
1106 return ERROR_OK;
1107 }
1108 tap2 = tap1->next_tap;
1109 if (tap2 == NULL)
1110 {
1111 /* things are *WRONG* */
1112 command_print(CMD_CTX,"**STR9FLASH** (tap2) invalid chain?");
1113 return ERROR_OK;
1114 }
1115
1116 /* enable turbo mode - TURBO-PROG-ENABLE */
1117 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1118 if ((retval = jtag_execute_queue()) != ERROR_OK)
1119 return retval;
1120
1121 /* modify scan chain - str9 core has been removed */
1122 tap1->enabled = 0;
1123
1124 return ERROR_OK;
1125 }
1126
1127 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1128 {
1129 struct jtag_tap *tap;
1130 struct str9xpec_flash_controller *str9xpec_info = NULL;
1131
1132 if (CMD_ARGC < 1)
1133 {
1134 command_print(CMD_CTX, "str9xpec disable_turbo <bank>");
1135 return ERROR_OK;
1136 }
1137
1138 struct flash_bank *bank;
1139 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1140 if (ERROR_OK != retval)
1141 return retval;
1142
1143 str9xpec_info = bank->driver_priv;
1144 tap = str9xpec_info->tap;
1145
1146 if (tap == NULL)
1147 return ERROR_FAIL;
1148
1149 /* exit turbo mode via RESET */
1150 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1151 jtag_add_tlr();
1152 jtag_execute_queue();
1153
1154 /* restore previous scan chain */
1155 if (tap->next_tap) {
1156 tap->next_tap->enabled = 1;
1157 }
1158
1159 return ERROR_OK;
1160 }
1161
1162 static const struct command_registration str9xpec_config_command_handlers[] = {
1163 {
1164 .name = "enable_turbo",
1165 .handler = str9xpec_handle_flash_enable_turbo_command,
1166 .mode = COMMAND_EXEC,
1167 .help = "enable str9xpec turbo mode",
1168 },
1169 {
1170 .name = "disable_turbo",
1171 .handler = str9xpec_handle_flash_disable_turbo_command,
1172 .mode = COMMAND_EXEC,
1173 .help = "disable str9xpec turbo mode",
1174 },
1175 {
1176 .name = "options_cmap",
1177 .handler = str9xpec_handle_flash_options_cmap_command,
1178 .mode = COMMAND_EXEC,
1179 .help = "configure str9xpec boot sector",
1180 },
1181 {
1182 .name = "options_lvdthd",
1183 .handler = str9xpec_handle_flash_options_lvdthd_command,
1184 .mode = COMMAND_EXEC,
1185 .help = "configure str9xpec lvd threshold",
1186 },
1187 {
1188 .name = "options_lvdsel",
1189 .handler = str9xpec_handle_flash_options_lvdsel_command,
1190 .mode = COMMAND_EXEC,
1191 .help = "configure str9xpec lvd selection",
1192 },
1193 {
1194 .name = "options_lvdwarn",
1195 .handler = str9xpec_handle_flash_options_lvdwarn_command,
1196 .mode = COMMAND_EXEC,
1197 .help = "configure str9xpec lvd warning",
1198 },
1199 {
1200 .name = "options_read",
1201 .handler = str9xpec_handle_flash_options_read_command,
1202 .mode = COMMAND_EXEC,
1203 .help = "read str9xpec options",
1204 },
1205 {
1206 .name = "options_write",
1207 .handler = str9xpec_handle_flash_options_write_command,
1208 .mode = COMMAND_EXEC,
1209 .help = "write str9xpec options",
1210 },
1211 {
1212 .name = "lock",
1213 .handler = str9xpec_handle_flash_lock_command,
1214 .mode = COMMAND_EXEC,
1215 .help = "lock str9xpec device",
1216 },
1217 {
1218 .name = "unlock",
1219 .handler = str9xpec_handle_flash_unlock_command,
1220 .mode = COMMAND_EXEC,
1221 .help = "unlock str9xpec device",
1222 },
1223 {
1224 .name = "part_id",
1225 .handler = str9xpec_handle_part_id_command,
1226 .mode = COMMAND_EXEC,
1227 .help = "print part id of str9xpec flash bank <num>",
1228 },
1229 COMMAND_REGISTRATION_DONE
1230 };
1231
1232 static const struct command_registration str9xpec_command_handlers[] = {
1233 {
1234 .name = "str9xpec",
1235 .mode = COMMAND_ANY,
1236 .help = "str9xpec flash command group",
1237 .chain = str9xpec_config_command_handlers,
1238 },
1239 COMMAND_REGISTRATION_DONE
1240 };
1241
1242 struct flash_driver str9xpec_flash = {
1243 .name = "str9xpec",
1244 .commands = str9xpec_command_handlers,
1245 .flash_bank_command = str9xpec_flash_bank_command,
1246 .erase = str9xpec_erase,
1247 .protect = str9xpec_protect,
1248 .write = str9xpec_write,
1249 .probe = str9xpec_probe,
1250 .auto_probe = str9xpec_probe,
1251 .erase_check = str9xpec_erase_check,
1252 .protect_check = str9xpec_protect_check,
1253 .info = str9xpec_info,
1254 };

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)