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

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)