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