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

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)