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