update files to correct FSF address
[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, 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 static int get_str9xpec_info(struct flash_bank *bank, char *buf, int buf_size)
764 {
765 snprintf(buf, buf_size, "str9xpec flash driver info");
766 return ERROR_OK;
767 }
768
769 COMMAND_HANDLER(str9xpec_handle_flash_options_read_command)
770 {
771 uint8_t status;
772 struct str9xpec_flash_controller *str9xpec_info = NULL;
773
774 if (CMD_ARGC < 1)
775 return ERROR_COMMAND_SYNTAX_ERROR;
776
777 struct flash_bank *bank;
778 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
779 if (ERROR_OK != retval)
780 return retval;
781
782 str9xpec_info = bank->driver_priv;
783
784 status = str9xpec_read_config(bank);
785
786 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
787 return ERROR_FLASH_OPERATION_FAILED;
788
789 /* boot bank */
790 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1))
791 command_print(CMD_CTX, "CS Map: bank1");
792 else
793 command_print(CMD_CTX, "CS Map: bank0");
794
795 /* OTP lock */
796 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_OTPBIT, 1))
797 command_print(CMD_CTX, "OTP Lock: OTP Locked");
798 else
799 command_print(CMD_CTX, "OTP Lock: OTP Unlocked");
800
801 /* LVD Threshold */
802 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1))
803 command_print(CMD_CTX, "LVD Threshold: 2.7v");
804 else
805 command_print(CMD_CTX, "LVD Threshold: 2.4v");
806
807 /* LVD reset warning */
808 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1))
809 command_print(CMD_CTX, "LVD Reset Warning: VDD or VDDQ Inputs");
810 else
811 command_print(CMD_CTX, "LVD Reset Warning: VDD Input Only");
812
813 /* LVD reset select */
814 if (buf_get_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1))
815 command_print(CMD_CTX, "LVD Reset Selection: VDD or VDDQ Inputs");
816 else
817 command_print(CMD_CTX, "LVD Reset Selection: VDD Input Only");
818
819 return ERROR_OK;
820 }
821
822 static int str9xpec_write_options(struct flash_bank *bank)
823 {
824 struct scan_field field;
825 uint8_t status;
826 struct jtag_tap *tap;
827 struct str9xpec_flash_controller *str9xpec_info = NULL;
828
829 str9xpec_info = bank->driver_priv;
830 tap = str9xpec_info->tap;
831
832 /* erase config options first */
833 status = str9xpec_erase_area(bank, 0xFE, 0xFE);
834
835 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
836 return status;
837
838 if (!str9xpec_info->isc_enable)
839 str9xpec_isc_enable(bank);
840
841 if (!str9xpec_info->isc_enable)
842 return ISC_STATUS_ERROR;
843
844 /* according to data 64th bit has to be set */
845 buf_set_u32(str9xpec_info->options, 63, 1, 1);
846
847 /* set option byte address */
848 str9xpec_set_address(bank, 0x50);
849
850 /* execute ISC_PROGRAM command */
851 str9xpec_set_instr(tap, ISC_PROGRAM, TAP_IRPAUSE);
852
853 field.num_bits = 64;
854 field.out_value = str9xpec_info->options;
855 field.in_value = NULL;
856
857 jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
858
859 /* small delay before polling */
860 jtag_add_sleep(50);
861
862 str9xpec_set_instr(tap, ISC_NOOP, TAP_IRPAUSE);
863
864 do {
865 field.num_bits = 8;
866 field.out_value = NULL;
867 field.in_value = &status;
868
869 jtag_add_dr_scan(tap, 1, &field, TAP_IRPAUSE);
870 jtag_execute_queue();
871
872 } while (!(status & ISC_STATUS_BUSY));
873
874 str9xpec_isc_disable(bank);
875
876 return status;
877 }
878
879 COMMAND_HANDLER(str9xpec_handle_flash_options_write_command)
880 {
881 uint8_t status;
882
883 if (CMD_ARGC < 1)
884 return ERROR_COMMAND_SYNTAX_ERROR;
885
886 struct flash_bank *bank;
887 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
888 if (ERROR_OK != retval)
889 return retval;
890
891 status = str9xpec_write_options(bank);
892
893 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
894 return ERROR_FLASH_OPERATION_FAILED;
895
896 command_print(CMD_CTX, "str9xpec write options complete.\n"
897 "INFO: a reset or power cycle is required "
898 "for the new settings to take effect.");
899
900 return ERROR_OK;
901 }
902
903 COMMAND_HANDLER(str9xpec_handle_flash_options_cmap_command)
904 {
905 struct str9xpec_flash_controller *str9xpec_info = NULL;
906
907 if (CMD_ARGC < 2)
908 return ERROR_COMMAND_SYNTAX_ERROR;
909
910 struct flash_bank *bank;
911 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
912 if (ERROR_OK != retval)
913 return retval;
914
915 str9xpec_info = bank->driver_priv;
916
917 if (strcmp(CMD_ARGV[1], "bank1") == 0)
918 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 1);
919 else
920 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_CSMAPBIT, 1, 0);
921
922 return ERROR_OK;
923 }
924
925 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdthd_command)
926 {
927 struct str9xpec_flash_controller *str9xpec_info = NULL;
928
929 if (CMD_ARGC < 2)
930 return ERROR_COMMAND_SYNTAX_ERROR;
931
932 struct flash_bank *bank;
933 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
934 if (ERROR_OK != retval)
935 return retval;
936
937 str9xpec_info = bank->driver_priv;
938
939 if (strcmp(CMD_ARGV[1], "2.7v") == 0)
940 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 1);
941 else
942 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDTHRESBIT, 1, 0);
943
944 return ERROR_OK;
945 }
946
947 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdsel_command)
948 {
949 struct str9xpec_flash_controller *str9xpec_info = NULL;
950
951 if (CMD_ARGC < 2)
952 return ERROR_COMMAND_SYNTAX_ERROR;
953
954 struct flash_bank *bank;
955 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
956 if (ERROR_OK != retval)
957 return retval;
958
959 str9xpec_info = bank->driver_priv;
960
961 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
962 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 1);
963 else
964 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDSELBIT, 1, 0);
965
966 return ERROR_OK;
967 }
968
969 COMMAND_HANDLER(str9xpec_handle_flash_options_lvdwarn_command)
970 {
971 struct str9xpec_flash_controller *str9xpec_info = NULL;
972
973 if (CMD_ARGC < 2)
974 return ERROR_COMMAND_SYNTAX_ERROR;
975
976 struct flash_bank *bank;
977 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
978 if (ERROR_OK != retval)
979 return retval;
980
981 str9xpec_info = bank->driver_priv;
982
983 if (strcmp(CMD_ARGV[1], "vdd_vddq") == 0)
984 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 1);
985 else
986 buf_set_u32(str9xpec_info->options, STR9XPEC_OPT_LVDWARNBIT, 1, 0);
987
988 return ERROR_OK;
989 }
990
991 COMMAND_HANDLER(str9xpec_handle_flash_lock_command)
992 {
993 uint8_t status;
994
995 if (CMD_ARGC < 1)
996 return ERROR_COMMAND_SYNTAX_ERROR;
997
998 struct flash_bank *bank;
999 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1000 if (ERROR_OK != retval)
1001 return retval;
1002
1003 status = str9xpec_lock_device(bank);
1004
1005 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1006 return ERROR_FLASH_OPERATION_FAILED;
1007
1008 return ERROR_OK;
1009 }
1010
1011 COMMAND_HANDLER(str9xpec_handle_flash_unlock_command)
1012 {
1013 uint8_t status;
1014
1015 if (CMD_ARGC < 1)
1016 return ERROR_COMMAND_SYNTAX_ERROR;
1017
1018 struct flash_bank *bank;
1019 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1020 if (ERROR_OK != retval)
1021 return retval;
1022
1023 status = str9xpec_unlock_device(bank);
1024
1025 if ((status & ISC_STATUS_ERROR) != STR9XPEC_ISC_SUCCESS)
1026 return ERROR_FLASH_OPERATION_FAILED;
1027
1028 command_print(CMD_CTX, "str9xpec unlocked.\n"
1029 "INFO: a reset or power cycle is required "
1030 "for the new settings to take effect.");
1031
1032 return ERROR_OK;
1033 }
1034
1035 COMMAND_HANDLER(str9xpec_handle_flash_enable_turbo_command)
1036 {
1037 struct jtag_tap *tap0;
1038 struct jtag_tap *tap1;
1039 struct jtag_tap *tap2;
1040 struct str9xpec_flash_controller *str9xpec_info = NULL;
1041
1042 if (CMD_ARGC < 1)
1043 return ERROR_COMMAND_SYNTAX_ERROR;
1044
1045 struct flash_bank *bank;
1046 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1047 if (ERROR_OK != retval)
1048 return retval;
1049
1050 str9xpec_info = bank->driver_priv;
1051
1052 /* remove arm core from chain - enter turbo mode */
1053 tap0 = str9xpec_info->tap;
1054 if (tap0 == NULL) {
1055 /* things are *WRONG* */
1056 command_print(CMD_CTX, "**STR9FLASH** (tap0) invalid chain?");
1057 return ERROR_FAIL;
1058 }
1059 tap1 = tap0->next_tap;
1060 if (tap1 == NULL) {
1061 /* things are *WRONG* */
1062 command_print(CMD_CTX, "**STR9FLASH** (tap1) invalid chain?");
1063 return ERROR_FAIL;
1064 }
1065 tap2 = tap1->next_tap;
1066 if (tap2 == NULL) {
1067 /* things are *WRONG* */
1068 command_print(CMD_CTX, "**STR9FLASH** (tap2) invalid chain?");
1069 return ERROR_FAIL;
1070 }
1071
1072 /* enable turbo mode - TURBO-PROG-ENABLE */
1073 str9xpec_set_instr(tap2, 0xD, TAP_IDLE);
1074 retval = jtag_execute_queue();
1075 if (retval != ERROR_OK)
1076 return retval;
1077
1078 /* modify scan chain - str9 core has been removed */
1079 tap1->enabled = 0;
1080
1081 return ERROR_OK;
1082 }
1083
1084 COMMAND_HANDLER(str9xpec_handle_flash_disable_turbo_command)
1085 {
1086 struct jtag_tap *tap;
1087 struct str9xpec_flash_controller *str9xpec_info = NULL;
1088
1089 if (CMD_ARGC < 1)
1090 return ERROR_COMMAND_SYNTAX_ERROR;
1091
1092 struct flash_bank *bank;
1093 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1094 if (ERROR_OK != retval)
1095 return retval;
1096
1097 str9xpec_info = bank->driver_priv;
1098 tap = str9xpec_info->tap;
1099
1100 if (tap == NULL)
1101 return ERROR_FAIL;
1102
1103 /* exit turbo mode via RESET */
1104 str9xpec_set_instr(tap, ISC_NOOP, TAP_IDLE);
1105 jtag_add_tlr();
1106 jtag_execute_queue();
1107
1108 /* restore previous scan chain */
1109 if (tap->next_tap)
1110 tap->next_tap->enabled = 1;
1111
1112 return ERROR_OK;
1113 }
1114
1115 static const struct command_registration str9xpec_config_command_handlers[] = {
1116 {
1117 .name = "enable_turbo",
1118 .usage = "<bank>",
1119 .handler = str9xpec_handle_flash_enable_turbo_command,
1120 .mode = COMMAND_EXEC,
1121 .help = "enable str9xpec turbo mode",
1122 },
1123 {
1124 .name = "disable_turbo",
1125 .usage = "<bank>",
1126 .handler = str9xpec_handle_flash_disable_turbo_command,
1127 .mode = COMMAND_EXEC,
1128 .help = "disable str9xpec turbo mode",
1129 },
1130 {
1131 .name = "options_cmap",
1132 .usage = "<bank> <bank0 | bank1>",
1133 .handler = str9xpec_handle_flash_options_cmap_command,
1134 .mode = COMMAND_EXEC,
1135 .help = "configure str9xpec boot sector",
1136 },
1137 {
1138 .name = "options_lvdthd",
1139 .usage = "<bank> <2.4v | 2.7v>",
1140 .handler = str9xpec_handle_flash_options_lvdthd_command,
1141 .mode = COMMAND_EXEC,
1142 .help = "configure str9xpec lvd threshold",
1143 },
1144 {
1145 .name = "options_lvdsel",
1146 .usage = "<bank> <vdd | vdd_vddq>",
1147 .handler = str9xpec_handle_flash_options_lvdsel_command,
1148 .mode = COMMAND_EXEC,
1149 .help = "configure str9xpec lvd selection",
1150 },
1151 {
1152 .name = "options_lvdwarn",
1153 .usage = "<bank> <vdd | vdd_vddq>",
1154 .handler = str9xpec_handle_flash_options_lvdwarn_command,
1155 .mode = COMMAND_EXEC,
1156 .help = "configure str9xpec lvd warning",
1157 },
1158 {
1159 .name = "options_read",
1160 .usage = "<bank>",
1161 .handler = str9xpec_handle_flash_options_read_command,
1162 .mode = COMMAND_EXEC,
1163 .help = "read str9xpec options",
1164 },
1165 {
1166 .name = "options_write",
1167 .usage = "<bank>",
1168 .handler = str9xpec_handle_flash_options_write_command,
1169 .mode = COMMAND_EXEC,
1170 .help = "write str9xpec options",
1171 },
1172 {
1173 .name = "lock",
1174 .usage = "<bank>",
1175 .handler = str9xpec_handle_flash_lock_command,
1176 .mode = COMMAND_EXEC,
1177 .help = "lock str9xpec device",
1178 },
1179 {
1180 .name = "unlock",
1181 .usage = "<bank>",
1182 .handler = str9xpec_handle_flash_unlock_command,
1183 .mode = COMMAND_EXEC,
1184 .help = "unlock str9xpec device",
1185 },
1186 {
1187 .name = "part_id",
1188 .handler = str9xpec_handle_part_id_command,
1189 .mode = COMMAND_EXEC,
1190 .help = "print part id of str9xpec flash bank <num>",
1191 },
1192 COMMAND_REGISTRATION_DONE
1193 };
1194
1195 static const struct command_registration str9xpec_command_handlers[] = {
1196 {
1197 .name = "str9xpec",
1198 .mode = COMMAND_ANY,
1199 .help = "str9xpec flash command group",
1200 .usage = "",
1201 .chain = str9xpec_config_command_handlers,
1202 },
1203 COMMAND_REGISTRATION_DONE
1204 };
1205
1206 struct flash_driver str9xpec_flash = {
1207 .name = "str9xpec",
1208 .commands = str9xpec_command_handlers,
1209 .flash_bank_command = str9xpec_flash_bank_command,
1210 .erase = str9xpec_erase,
1211 .protect = str9xpec_protect,
1212 .write = str9xpec_write,
1213 .read = default_flash_read,
1214 .probe = str9xpec_probe,
1215 .auto_probe = str9xpec_probe,
1216 .erase_check = str9xpec_erase_check,
1217 .protect_check = str9xpec_protect_check,
1218 .info = get_str9xpec_info,
1219 };

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)