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

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)