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