jtag: linuxgpiod: drop extra parenthesis
[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, unsigned int first,
78 unsigned int last);
79 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector);
80 static int str9xpec_write_options(struct flash_bank *bank);
81
82 static int str9xpec_set_instr(struct jtag_tap *tap, uint32_t new_instr, tap_state_t end_state)
83 {
84 if (!tap)
85 return ERROR_TARGET_INVALID;
86
87 if (buf_get_u32(tap->cur_instr, 0, tap->ir_length) != new_instr) {
88 struct scan_field field;
89
90 field.num_bits = tap->ir_length;
91 void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
92 field.out_value = t;
93 buf_set_u32(t, 0, field.num_bits, new_instr);
94 field.in_value = NULL;
95
96 jtag_add_ir_scan(tap, &field, end_state);
97
98 free(t);
99 }
100
101 return ERROR_OK;
102 }
103
104 static uint8_t str9xpec_isc_status(struct jtag_tap *tap)
105 {
106 struct scan_field field;
107 uint8_t status;
108
109 if (str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE) != ERROR_OK)
110 return ISC_STATUS_ERROR;
111
112 field.num_bits = 8;
113 field.out_value = NULL;
114 field.in_value = &status;
115
116
117 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
118 jtag_execute_queue();
119
120 LOG_DEBUG("status: 0x%2.2x", status);
121
122 if (status & ISC_STATUS_SECURITY)
123 LOG_INFO("Device Security Bit Set");
124
125 return status;
126 }
127
128 static int str9xpec_isc_enable(struct flash_bank *bank)
129 {
130 uint8_t status;
131 struct jtag_tap *tap;
132 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
133
134 tap = str9xpec_info->tap;
135
136 if (str9xpec_info->isc_enable)
137 return ERROR_OK;
138
139 /* enter isc mode */
140 if (str9xpec_set_instr(tap, ISC_ENABLE, TAP_IDLE) != ERROR_OK)
141 return ERROR_TARGET_INVALID;
142
143 /* check ISC status */
144 status = str9xpec_isc_status(tap);
145 if (status & ISC_STATUS_MODE) {
146 /* we have entered isc mode */
147 str9xpec_info->isc_enable = 1;
148 LOG_DEBUG("ISC_MODE Enabled");
149 }
150
151 return ERROR_OK;
152 }
153
154 static int str9xpec_isc_disable(struct flash_bank *bank)
155 {
156 uint8_t status;
157 struct jtag_tap *tap;
158 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
159
160 tap = str9xpec_info->tap;
161
162 if (!str9xpec_info->isc_enable)
163 return ERROR_OK;
164
165 if (str9xpec_set_instr(tap, ISC_DISABLE, TAP_IDLE) != ERROR_OK)
166 return ERROR_TARGET_INVALID;
167
168 /* delay to handle aborts */
169 jtag_add_sleep(50);
170
171 /* check ISC status */
172 status = str9xpec_isc_status(tap);
173 if (!(status & ISC_STATUS_MODE)) {
174 /* we have left isc mode */
175 str9xpec_info->isc_enable = 0;
176 LOG_DEBUG("ISC_MODE Disabled");
177 }
178
179 return ERROR_OK;
180 }
181
182 static int str9xpec_read_config(struct flash_bank *bank)
183 {
184 struct scan_field field;
185 uint8_t status;
186 struct jtag_tap *tap;
187
188 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
189
190 tap = str9xpec_info->tap;
191
192 LOG_DEBUG("ISC_CONFIGURATION");
193
194 /* execute ISC_CONFIGURATION command */
195 str9xpec_set_instr(tap, ISC_CONFIGURATION, TAP_IRPAUSE);
196
197 field.num_bits = 64;
198 field.out_value = NULL;
199 field.in_value = str9xpec_info->options;
200
201 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
202 jtag_execute_queue();
203
204 status = str9xpec_isc_status(tap);
205
206 return status;
207 }
208
209 static int str9xpec_build_block_list(struct flash_bank *bank)
210 {
211 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
212
213 int i;
214 unsigned int num_sectors;
215 int b0_sectors = 0, b1_sectors = 0;
216 uint32_t offset = 0;
217 int b1_size = 0x2000;
218
219 switch (bank->size) {
220 case (256 * 1024):
221 b0_sectors = 4;
222 break;
223 case (512 * 1024):
224 b0_sectors = 8;
225 break;
226 case (1024 * 1024):
227 b0_sectors = 16;
228 break;
229 case (2048 * 1024):
230 b0_sectors = 32;
231 break;
232 case (128 * 1024):
233 b1_size = 0x4000;
234 b1_sectors = 8;
235 break;
236 case (32 * 1024):
237 b1_sectors = 4;
238 break;
239 default:
240 LOG_ERROR("BUG: unknown bank->size encountered");
241 exit(-1);
242 }
243
244 num_sectors = b0_sectors + b1_sectors;
245
246 bank->num_sectors = num_sectors;
247 bank->sectors = malloc(sizeof(struct flash_sector) * num_sectors);
248 str9xpec_info->sector_bits = malloc(sizeof(uint32_t) * num_sectors);
249
250 num_sectors = 0;
251
252 for (i = 0; i < b0_sectors; i++) {
253 bank->sectors[num_sectors].offset = offset;
254 bank->sectors[num_sectors].size = 0x10000;
255 offset += bank->sectors[i].size;
256 bank->sectors[num_sectors].is_erased = -1;
257 bank->sectors[num_sectors].is_protected = 1;
258 str9xpec_info->sector_bits[num_sectors++] = i;
259 }
260
261 for (i = 0; i < b1_sectors; i++) {
262 bank->sectors[num_sectors].offset = offset;
263 bank->sectors[num_sectors].size = b1_size;
264 offset += bank->sectors[i].size;
265 bank->sectors[num_sectors].is_erased = -1;
266 bank->sectors[num_sectors].is_protected = 1;
267 str9xpec_info->sector_bits[num_sectors++] = i + 32;
268 }
269
270 return ERROR_OK;
271 }
272
273 /* flash bank str9x <base> <size> 0 0 <target#>
274 */
275 FLASH_BANK_COMMAND_HANDLER(str9xpec_flash_bank_command)
276 {
277 struct str9xpec_flash_controller *str9xpec_info;
278 struct arm *arm = NULL;
279 struct arm7_9_common *arm7_9 = NULL;
280 struct arm_jtag *jtag_info = NULL;
281
282 if (CMD_ARGC < 6)
283 return ERROR_COMMAND_SYNTAX_ERROR;
284
285 str9xpec_info = malloc(sizeof(struct str9xpec_flash_controller));
286 bank->driver_priv = str9xpec_info;
287
288 /* REVISIT verify that the jtag position of flash controller is
289 * right after *THIS* core, which must be a STR9xx core ...
290 */
291 arm = bank->target->arch_info;
292 arm7_9 = arm->arch_info;
293 jtag_info = &arm7_9->jtag_info;
294
295 /* The core is the next tap after the flash controller in the chain */
296 str9xpec_info->tap = jtag_tap_by_position(jtag_info->tap->abs_chain_position - 1);
297 str9xpec_info->isc_enable = 0;
298
299 str9xpec_build_block_list(bank);
300
301 /* clear option byte register */
302 buf_set_u32(str9xpec_info->options, 0, 64, 0);
303
304 return ERROR_OK;
305 }
306
307 static int str9xpec_blank_check(struct flash_bank *bank, unsigned int first,
308 unsigned int last)
309 {
310 struct scan_field field;
311 uint8_t status;
312 struct jtag_tap *tap;
313 uint8_t *buffer = NULL;
314
315 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
316
317 tap = str9xpec_info->tap;
318
319 if (!str9xpec_info->isc_enable)
320 str9xpec_isc_enable(bank);
321
322 if (!str9xpec_info->isc_enable)
323 return ERROR_FLASH_OPERATION_FAILED;
324
325 buffer = calloc(DIV_ROUND_UP(64, 8), 1);
326
327 LOG_DEBUG("blank check: first_bank: %u, last_bank: %u", first, last);
328
329 for (unsigned int i = first; i <= last; i++)
330 buf_set_u32(buffer, str9xpec_info->sector_bits[i], 1, 1);
331
332 /* execute ISC_BLANK_CHECK command */
333 str9xpec_set_instr(tap, ISC_BLANK_CHECK, TAP_IRPAUSE);
334
335 field.num_bits = 64;
336 field.out_value = buffer;
337 field.in_value = NULL;
338
339 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
340 jtag_add_sleep(40000);
341
342 /* read blank check result */
343 field.num_bits = 64;
344 field.out_value = NULL;
345 field.in_value = buffer;
346
347 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
348 jtag_execute_queue();
349
350 status = str9xpec_isc_status(tap);
351
352 for (unsigned int i = first; i <= last; i++) {
353 if (buf_get_u32(buffer, str9xpec_info->sector_bits[i], 1))
354 bank->sectors[i].is_erased = 0;
355 else
356 bank->sectors[i].is_erased = 1;
357 }
358
359 free(buffer);
360
361 str9xpec_isc_disable(bank);
362
363 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
364 return ERROR_FLASH_OPERATION_FAILED;
365 return ERROR_OK;
366 }
367
368 static int str9xpec_protect_check(struct flash_bank *bank)
369 {
370 uint8_t status;
371
372 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
373
374 status = str9xpec_read_config(bank);
375
376 for (unsigned int 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, unsigned int first,
389 unsigned int last)
390 {
391 struct scan_field field;
392 uint8_t status;
393 struct jtag_tap *tap;
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: %u, last_bank: %u", 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 (unsigned int 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 (unsigned int 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, unsigned int first,
448 unsigned int last)
449 {
450 int status;
451
452 status = str9xpec_erase_area(bank, first, last);
453
454 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
455 return ERROR_FLASH_OPERATION_FAILED;
456
457 return ERROR_OK;
458 }
459
460 static int str9xpec_lock_device(struct flash_bank *bank)
461 {
462 struct scan_field field;
463 uint8_t status;
464 struct jtag_tap *tap;
465 struct str9xpec_flash_controller *str9xpec_info = NULL;
466
467 str9xpec_info = bank->driver_priv;
468 tap = str9xpec_info->tap;
469
470 if (!str9xpec_info->isc_enable)
471 str9xpec_isc_enable(bank);
472
473 if (!str9xpec_info->isc_enable)
474 return ISC_STATUS_ERROR;
475
476 /* set security address */
477 str9xpec_set_address(bank, 0x80);
478
479 /* execute ISC_PROGRAM command */
480 str9xpec_set_instr(tap, ISC_PROGRAM_SECURITY, TAP_IDLE);
481
482 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
483
484 do {
485 field.num_bits = 8;
486 field.out_value = NULL;
487 field.in_value = &status;
488
489 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
490 jtag_execute_queue();
491
492 } while (!(status & ISC_STATUS_BUSY));
493
494 str9xpec_isc_disable(bank);
495
496 return status;
497 }
498
499 static int str9xpec_unlock_device(struct flash_bank *bank)
500 {
501 uint8_t status;
502
503 status = str9xpec_erase_area(bank, 0, 255);
504
505 return status;
506 }
507
508 static int str9xpec_protect(struct flash_bank *bank, int set,
509 unsigned int first, unsigned int last)
510 {
511 uint8_t status;
512
513 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
514
515 status = str9xpec_read_config(bank);
516
517 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
518 return ERROR_FLASH_OPERATION_FAILED;
519
520 LOG_DEBUG("protect: first_bank: %u, last_bank: %u", first, last);
521
522 /* last bank: 0xFF signals a full device protect */
523 if (last == 0xFF) {
524 if (set)
525 status = str9xpec_lock_device(bank);
526 else {
527 /* perform full erase to unlock device */
528 status = str9xpec_unlock_device(bank);
529 }
530 } else {
531 for (unsigned int i = first; i <= last; i++) {
532 if (set)
533 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 1);
534 else
535 buf_set_u32(str9xpec_info->options, str9xpec_info->sector_bits[i], 1, 0);
536 }
537
538 status = str9xpec_write_options(bank);
539 }
540
541 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
542 return ERROR_FLASH_OPERATION_FAILED;
543
544 return ERROR_OK;
545 }
546
547 static int str9xpec_set_address(struct flash_bank *bank, uint8_t sector)
548 {
549 struct jtag_tap *tap;
550 struct scan_field field;
551 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
552
553 tap = str9xpec_info->tap;
554
555 /* set flash controller address */
556 str9xpec_set_instr(tap, ISC_ADDRESS_SHIFT, TAP_IRPAUSE);
557
558 field.num_bits = 8;
559 field.out_value = &sector;
560 field.in_value = NULL;
561
562 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
563
564 return ERROR_OK;
565 }
566
567 static int str9xpec_write(struct flash_bank *bank, const uint8_t *buffer,
568 uint32_t offset, uint32_t count)
569 {
570 struct str9xpec_flash_controller *str9xpec_info = bank->driver_priv;
571 uint32_t dwords_remaining = (count / 8);
572 uint32_t bytes_remaining = (count & 0x00000007);
573 uint32_t bytes_written = 0;
574 uint8_t status;
575 uint32_t check_address = offset;
576 struct jtag_tap *tap;
577 struct scan_field field;
578 uint8_t *scanbuf;
579 unsigned int first_sector = 0;
580 unsigned 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 (unsigned int 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 (unsigned int 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 (retval != ERROR_OK)
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, "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 (retval != ERROR_OK)
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, "CS Map: bank1");
784 else
785 command_print(CMD, "CS Map: bank0");
786
787 /* OTP lock */
788 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
789 command_print(CMD, "OTP Lock: OTP Locked");
790 else
791 command_print(CMD, "OTP Lock: OTP Unlocked");
792
793 /* LVD Threshold */
794 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
795 command_print(CMD, "LVD Threshold: 2.7v");
796 else
797 command_print(CMD, "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, "LVD Reset Warning: VDD or VDDQ Inputs");
802 else
803 command_print(CMD, "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, "LVD Reset Selection: VDD or VDDQ Inputs");
808 else
809 command_print(CMD, "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 (retval != ERROR_OK)
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, "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 (retval != ERROR_OK)
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 (retval != ERROR_OK)
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 (retval != ERROR_OK)
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 (retval != ERROR_OK)
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 (retval != ERROR_OK)
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 (retval != ERROR_OK)
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, "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 (retval != ERROR_OK)
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) {
1047 /* things are *WRONG* */
1048 command_print(CMD, "**STR9FLASH** (tap0) invalid chain?");
1049 return ERROR_FAIL;
1050 }
1051 tap1 = tap0->next_tap;
1052 if (!tap1) {
1053 /* things are *WRONG* */
1054 command_print(CMD, "**STR9FLASH** (tap1) invalid chain?");
1055 return ERROR_FAIL;
1056 }
1057 tap2 = tap1->next_tap;
1058 if (!tap2) {
1059 /* things are *WRONG* */
1060 command_print(CMD, "**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 (retval != ERROR_OK)
1087 return retval;
1088
1089 str9xpec_info = bank->driver_priv;
1090 tap = str9xpec_info->tap;
1091
1092 if (!tap)
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 .usage = "<bank>",
1181 .handler = str9xpec_handle_part_id_command,
1182 .mode = COMMAND_EXEC,
1183 .help = "print part id of str9xpec flash bank",
1184 },
1185 COMMAND_REGISTRATION_DONE
1186 };
1187
1188 static const struct command_registration str9xpec_command_handlers[] = {
1189 {
1190 .name = "str9xpec",
1191 .mode = COMMAND_ANY,
1192 .help = "str9xpec flash command group",
1193 .usage = "",
1194 .chain = str9xpec_config_command_handlers,
1195 },
1196 COMMAND_REGISTRATION_DONE
1197 };
1198
1199 const struct flash_driver str9xpec_flash = {
1200 .name = "str9xpec",
1201 .commands = str9xpec_command_handlers,
1202 .flash_bank_command = str9xpec_flash_bank_command,
1203 .erase = str9xpec_erase,
1204 .protect = str9xpec_protect,
1205 .write = str9xpec_write,
1206 .read = default_flash_read,
1207 .probe = str9xpec_probe,
1208 .auto_probe = str9xpec_probe,
1209 .erase_check = str9xpec_erase_check,
1210 .protect_check = str9xpec_protect_check,
1211 .free_driver_priv = default_flash_free_driver_priv,
1212 };

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)