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