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

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)