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

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)