OpenOCD
psoc4.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  * Copyright (C) 2011 by Andreas Fritiofson *
11  * andreas.fritiofson@gmail.com *
12  * *
13  * Copyright (C) 2014 by Tomas Vanek (PSoC 4 support derived from STM32) *
14  * vanekt@fbl.cz *
15  ***************************************************************************/
16 
17 #ifdef HAVE_CONFIG_H
18 #include "config.h"
19 #endif
20 
21 #include "imp.h"
22 #include <helper/binarybuffer.h>
23 #include <jtag/jtag.h>
24 #include <target/algorithm.h>
25 #include <target/armv7m.h>
26 
27 /* device documents:
28 
29  PSoC(R) 4: PSoC 4200 Family Datasheet
30  Document Number: 001-87197 Rev. *B Revised August 29, 2013
31 
32  PSoC 4100/4200 Family PSoC(R) 4 Architecture TRM
33  Document No. 001-85634 Rev. *E June 28, 2016
34 
35  PSoC(R) 4 Registers TRM Spec.
36  Document No. 001-85847 Rev. *A June 25, 2013
37 
38  PSoC 4000 Family PSoC(R) 4 Technical Reference Manual
39  Document No. 001-89309 Rev. *B May 9, 2016
40 
41  PSoC 41XX_BLE/42XX_BLE Family PSoC 4 BLE Architecture TRM
42  Document No. 001-92738 Rev. *C February 12, 2016
43 
44  PSoC 4200L Family PSoC 4 Architecture TRM
45  Document No. 001-97952 Rev. *A December 15, 2015
46 
47  PSoC 4200L Family PSoC 4 Registers TRM
48  Document No. 001-98126 Rev. *A December 16, 2015
49 
50  PSoC 4100M/4200M Family PSoC 4 Architecture TRM
51  Document No. 001-95223 Rev. *B July 29, 2015
52 
53  PSoC 4100S Family PSoC 4 Architecture TRM
54  Document No. 002-10621 Rev. *A July 29, 2016
55 
56  PSoC 4100S Family PSoC 4 Registers TRM
57  Document No. 002-10523 Rev. *A July 20, 2016
58 
59  PSoC Analog Coprocessor Architecture TRM
60  Document No. 002-10404 Rev. ** December 18, 2015
61 
62  CY8C4Axx PSoC Analog Coprocessor Registers TRM
63  Document No. 002-10405 Rev. ** December 18, 2015
64 
65  CY8C41xx, CY8C42xx Programming Specifications
66  Document No. 001-81799 Rev. *C March 4, 2014
67 
68  CYBL10x6x, CY8C4127_BL, CY8C4247_BL Programming Specifications
69  Document No. 001-91508 Rev. *B September 22, 2014
70 
71  http://dmitry.gr/index.php?r=05.Projects&proj=24.%20PSoC4%20confidential
72 */
73 
74 /* register locations */
75 #define PSOC4_SFLASH_MACRO0 0x0FFFF000
76 
77 #define PSOC4_CPUSS_SYSREQ_LEGACY 0x40000004
78 #define PSOC4_CPUSS_SYSARG_LEGACY 0x40000008
79 #define PSOC4_SPCIF_GEOMETRY_LEGACY 0x400E0000
80 
81 #define PSOC4_CPUSS_SYSREQ_NEW 0x40100004
82 #define PSOC4_CPUSS_SYSARG_NEW 0x40100008
83 #define PSOC4_SPCIF_GEOMETRY_NEW 0x40110000
84 
85 #define PSOC4_TEST_MODE 0x40030014
86 
87 #define PSOC4_ROMTABLE_PID0 0xF0000FE0
88 
89 
90 /* constants */
91 #define PSOC4_SFLASH_MACRO_SIZE 0x800
92 #define PSOC4_ROWS_PER_MACRO 512
93 
94 #define PSOC4_SROM_KEY1 0xb6
95 #define PSOC4_SROM_KEY2 0xd3
96 #define PSOC4_SROM_SYSREQ_BIT (1<<31)
97 #define PSOC4_SROM_HMASTER_BIT (1<<30)
98 #define PSOC4_SROM_PRIVILEGED_BIT (1<<28)
99 #define PSOC4_SROM_STATUS_SUCCEEDED 0xa0000000
100 #define PSOC4_SROM_STATUS_FAILED 0xf0000000
101 #define PSOC4_SROM_STATUS_MASK 0xf0000000
102 
103 /* not documented in any TRM */
104 #define PSOC4_SROM_ERR_IMO_NOT_IMPLEM 0xf0000013
105 
106 #define PSOC4_CMD_GET_SILICON_ID 0
107 #define PSOC4_CMD_LOAD_LATCH 4
108 #define PSOC4_CMD_WRITE_ROW 5
109 #define PSOC4_CMD_PROGRAM_ROW 6
110 #define PSOC4_CMD_ERASE_ALL 0xa
111 #define PSOC4_CMD_CHECKSUM 0xb
112 #define PSOC4_CMD_WRITE_PROTECTION 0xd
113 #define PSOC4_CMD_SET_IMO48 0x15
114 #define PSOC4_CMD_WRITE_SFLASH_ROW 0x18
115 
116 #define PSOC4_CHIP_PROT_VIRGIN 0x0
117 #define PSOC4_CHIP_PROT_OPEN 0x1
118 #define PSOC4_CHIP_PROT_PROTECTED 0x2
119 #define PSOC4_CHIP_PROT_KILL 0x4
120 
121 #define PSOC4_ROMTABLE_DESIGNER_CHECK 0xb4
122 
123 #define PSOC4_FAMILY_FLAG_LEGACY 1
124 
126  uint16_t id;
127  const char *name;
128  uint32_t flags;
129 };
130 
131 static const struct psoc4_chip_family psoc4_families[] = {
132  { 0x93, "PSoC4100/4200", .flags = PSOC4_FAMILY_FLAG_LEGACY },
133  { 0x9A, "PSoC4000", .flags = 0 },
134  { 0x9E, "PSoC/PRoC BLE (119E)", .flags = 0 },
135  { 0xA0, "PSoC4200L", .flags = 0 },
136  { 0xA1, "PSoC4100M/4200M", .flags = 0 },
137  { 0xA3, "PSoC/PRoC BLE (11A3)", .flags = 0 },
138  { 0xA9, "PSoC4000S", .flags = 0 },
139  { 0xAA, "PSoC/PRoC BLE (11AA)", .flags = 0 },
140  { 0xAB, "PSoC4100S", .flags = 0 },
141  { 0xAC, "PSoC Analog Coprocessor", .flags = 0 },
142  { 0, "Unknown", .flags = 0 }
143 };
144 
145 
147  uint32_t row_size;
148  uint32_t user_bank_size;
149  unsigned int num_macros;
150  bool probed;
152  uint16_t family_id;
157 };
158 
159 
160 static const struct psoc4_chip_family *psoc4_family_by_id(uint16_t family_id)
161 {
162  const struct psoc4_chip_family *p = psoc4_families;
163  while (p->id && p->id != family_id)
164  p++;
165 
166  return p;
167 }
168 
169 static const char *psoc4_decode_chip_protection(uint8_t protection)
170 {
171  switch (protection) {
173  return "protection VIRGIN";
175  return "protection open";
177  return "PROTECTED";
179  return "protection KILL";
180  default:
181  LOG_WARNING("Unknown protection state 0x%02" PRIx8 "", protection);
182  return "";
183  }
184 }
185 
186 
187 /* flash bank <name> psoc <base> <size> 0 0 <target#>
188  */
189 FLASH_BANK_COMMAND_HANDLER(psoc4_flash_bank_command)
190 {
191  struct psoc4_flash_bank *psoc4_info;
192 
193  if (CMD_ARGC < 6)
195 
196  psoc4_info = calloc(1, sizeof(struct psoc4_flash_bank));
197 
198  bank->driver_priv = psoc4_info;
199  bank->default_padded_value = bank->erased_value = 0x00;
200  psoc4_info->user_bank_size = bank->size;
201  psoc4_info->cmd_program_row = PSOC4_CMD_WRITE_ROW;
202 
203  return ERROR_OK;
204 }
205 
206 
207 /* PSoC 4 system ROM request
208  * Setting SROM_SYSREQ_BIT in CPUSS_SYSREQ register runs NMI service
209  * in sysrem ROM. Algorithm just waits for NMI to finish.
210  * When sysreq_params_size == 0 only one parameter is passed in CPUSS_SYSARG register.
211  * Otherwise address of memory parameter block is set in CPUSS_SYSARG
212  * and the first parameter is written to the first word of parameter block
213  */
214 static int psoc4_sysreq(struct flash_bank *bank, uint8_t cmd,
215  uint16_t cmd_param,
216  uint32_t *sysreq_params, uint32_t sysreq_params_size,
217  uint32_t *sysarg_out)
218 {
219  struct target *target = bank->target;
220  struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
221 
222  struct working_area *sysreq_wait_algorithm;
223  struct working_area *sysreq_mem;
224 
225  struct reg_param reg_params[1];
226  struct armv7m_algorithm armv7m_info;
227 
228  int retval = ERROR_OK;
229 
230  uint32_t param1 = PSOC4_SROM_KEY1
231  | ((PSOC4_SROM_KEY2 + cmd) << 8)
232  | (cmd_param << 16);
233 
234  static uint8_t psoc4_sysreq_wait_code[] = {
235  /* system request NMI is served immediately after algo run
236  now we are done: break */
237  0x00, 0xbe, /* bkpt 0 */
238  };
239 
240  const int code_words = (sizeof(psoc4_sysreq_wait_code) + 3) / 4;
241  /* stack must be aligned */
242  const int stack_size = 256;
243  /* tested stack sizes on PSoC4200:
244  ERASE_ALL 144
245  PROGRAM_ROW 112
246  other sysreq 68
247  */
248 
249  /* allocate area for sysreq wait code and stack */
250  if (target_alloc_working_area(target, code_words * 4 + stack_size,
251  &sysreq_wait_algorithm) != ERROR_OK) {
252  LOG_DEBUG("no working area for sysreq code");
254  }
255 
256  /* Write the code */
257  retval = target_write_buffer(target,
258  sysreq_wait_algorithm->address,
259  sizeof(psoc4_sysreq_wait_code),
260  psoc4_sysreq_wait_code);
261  if (retval != ERROR_OK) {
262  /* we already allocated the writing code, but failed to get a
263  * buffer, free the algorithm */
264  goto cleanup_algo;
265  }
266 
267  if (sysreq_params_size) {
268  LOG_DEBUG("SYSREQ %02" PRIx8 " %04" PRIx16 " %08" PRIx32 " size %" PRIu32,
269  cmd, cmd_param, param1, sysreq_params_size);
270  /* Allocate memory for sysreq_params */
271  retval = target_alloc_working_area(target, sysreq_params_size, &sysreq_mem);
272  if (retval != ERROR_OK) {
273  LOG_WARNING("no working area for sysreq parameters");
274 
275  /* we already allocated the writing code, but failed to get a
276  * buffer, free the algorithm */
278  goto cleanup_algo;
279  }
280 
281  /* Write sysreq_params */
282  target_buffer_set_u32(target, (uint8_t *)sysreq_params, param1);
283  retval = target_write_buffer(target, sysreq_mem->address,
284  sysreq_params_size, (uint8_t *)sysreq_params);
285  if (retval != ERROR_OK)
286  goto cleanup_mem;
287 
288  /* Set address of sysreq parameters block */
289  retval = target_write_u32(target, psoc4_info->cpuss_sysarg_addr, sysreq_mem->address);
290  if (retval != ERROR_OK)
291  goto cleanup_mem;
292 
293  } else {
294  /* Sysreq without memory block of parameters */
295  LOG_DEBUG("SYSREQ %02" PRIx8 " %04" PRIx16 " %08" PRIx32,
296  cmd, cmd_param, param1);
297  /* Set register parameter */
298  retval = target_write_u32(target, psoc4_info->cpuss_sysarg_addr, param1);
299  if (retval != ERROR_OK)
300  goto cleanup_mem;
301  }
302 
303  armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
304  armv7m_info.core_mode = ARM_MODE_THREAD;
305 
306  /* sysreq stack */
307  init_reg_param(&reg_params[0], "sp", 32, PARAM_OUT);
308  buf_set_u32(reg_params[0].value, 0, 32,
309  sysreq_wait_algorithm->address + sysreq_wait_algorithm->size);
310 
311  struct armv7m_common *armv7m = target_to_armv7m(target);
312  if (!armv7m) {
313  /* something is very wrong if armv7m is NULL */
314  LOG_ERROR("unable to get armv7m target");
315  retval = ERROR_FAIL;
316  goto cleanup;
317  }
318 
319  /* Set SROM request */
320  retval = target_write_u32(target, psoc4_info->cpuss_sysreq_addr,
322  if (retval != ERROR_OK)
323  goto cleanup;
324 
325  /* Execute wait code */
326  retval = target_run_algorithm(target, 0, NULL,
327  ARRAY_SIZE(reg_params), reg_params,
328  sysreq_wait_algorithm->address, 0, 1000, &armv7m_info);
329  if (retval != ERROR_OK) {
330  LOG_ERROR("sysreq wait code execution failed");
331  goto cleanup;
332  }
333 
334  uint32_t sysarg_out_tmp;
335  retval = target_read_u32(target, psoc4_info->cpuss_sysarg_addr, &sysarg_out_tmp);
336  if (retval != ERROR_OK)
337  goto cleanup;
338 
339  if (sysarg_out) {
340  *sysarg_out = sysarg_out_tmp;
341  /* If result is an error, do not show now, let caller to decide */
342  } else if ((sysarg_out_tmp & PSOC4_SROM_STATUS_MASK) != PSOC4_SROM_STATUS_SUCCEEDED) {
343  LOG_ERROR("sysreq error 0x%" PRIx32, sysarg_out_tmp);
344  retval = ERROR_FAIL;
345  }
346 cleanup:
347  destroy_reg_param(&reg_params[0]);
348 
349 cleanup_mem:
350  if (sysreq_params_size)
351  target_free_working_area(target, sysreq_mem);
352 
353 cleanup_algo:
354  target_free_working_area(target, sysreq_wait_algorithm);
355 
356  return retval;
357 }
358 
359 
360 /* helper routine to get silicon ID from a PSoC 4 chip */
361 static int psoc4_get_silicon_id(struct flash_bank *bank, uint32_t *silicon_id, uint16_t *family_id, uint8_t *protection)
362 {
363  struct target *target = bank->target;
364  struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
365 
366  uint32_t part0, part1;
367 
368  int retval = psoc4_sysreq(bank, PSOC4_CMD_GET_SILICON_ID, 0, NULL, 0, &part0);
369  if (retval != ERROR_OK)
370  return retval;
371 
373  LOG_ERROR("sysreq error 0x%" PRIx32, part0);
374  return ERROR_FAIL;
375  }
376 
377  retval = target_read_u32(target, psoc4_info->cpuss_sysreq_addr, &part1);
378  if (retval != ERROR_OK)
379  return retval;
380 
381  /* build ID as Cypress sw does:
382  * bit 31..16 silicon ID
383  * bit 15..8 revision ID (so far 0x11 for all devices)
384  * bit 7..0 family ID (lowest 8 bits)
385  */
386  if (silicon_id)
387  *silicon_id = ((part0 & 0x0000ffff) << 16)
388  | ((part0 & 0x00ff0000) >> 8)
389  | (part1 & 0x000000ff);
390 
391  if (family_id)
392  *family_id = part1 & 0x0fff;
393 
394  if (protection)
395  *protection = (part1 >> 12) & 0x0f;
396 
397  return ERROR_OK;
398 }
399 
400 
401 static int psoc4_get_family(struct target *target, uint16_t *family_id)
402 {
403  int retval, i;
404  uint32_t pidbf[3];
405  uint8_t pid[3];
406 
407  retval = target_read_memory(target, PSOC4_ROMTABLE_PID0, 4, 3, (uint8_t *)pidbf);
408  if (retval != ERROR_OK)
409  return retval;
410 
411  for (i = 0; i < 3; i++) {
412  uint32_t tmp = target_buffer_get_u32(target, (uint8_t *)(pidbf + i));
413  if (tmp & 0xffffff00) {
414  LOG_ERROR("Unexpected data in ROMTABLE");
415  return ERROR_FAIL;
416  }
417  pid[i] = tmp & 0xff;
418  }
419 
420  uint16_t family = pid[0] | ((pid[1] & 0xf) << 8);
421  uint32_t designer = ((pid[1] & 0xf0) >> 4) | ((pid[2] & 0xf) << 4);
422 
423  if (designer != PSOC4_ROMTABLE_DESIGNER_CHECK) {
424  LOG_ERROR("ROMTABLE designer is not Cypress");
425  return ERROR_FAIL;
426  }
427 
428  *family_id = family;
429  return ERROR_OK;
430 }
431 
432 
434 {
435  struct target *target = bank->target;
436  struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
437 
438  if (target->state != TARGET_HALTED) {
439  LOG_ERROR("Target not halted");
441  }
442 
443  uint16_t family_id;
444  int retval;
445 
446  /* get family ID from SROM call */
448  if (retval != ERROR_OK)
449  return retval;
450 
451  /* and check with family ID from ROMTABLE */
452  if (family_id != psoc4_info->family_id) {
453  LOG_ERROR("Family mismatch");
454  return ERROR_FAIL;
455  }
456 
457  if (!psoc4_info->legacy_family) {
458  uint32_t sysreq_status;
459  retval = psoc4_sysreq(bank, PSOC4_CMD_SET_IMO48, 0, NULL, 0, &sysreq_status);
460  if (retval != ERROR_OK)
461  return retval;
462 
463  if ((sysreq_status & PSOC4_SROM_STATUS_MASK) != PSOC4_SROM_STATUS_SUCCEEDED) {
464  /* This undocumented error code is returned probably when
465  * PSOC4_CMD_SET_IMO48 command is not implemented.
466  * Can be safely ignored, programming works.
467  */
468  if (sysreq_status == PSOC4_SROM_ERR_IMO_NOT_IMPLEM)
469  LOG_INFO("PSOC4_CMD_SET_IMO48 is not implemented on this device.");
470  else {
471  LOG_ERROR("sysreq error 0x%" PRIx32, sysreq_status);
472  return ERROR_FAIL;
473  }
474  }
475  }
476 
477  return ERROR_OK;
478 }
479 
480 
482 {
483  struct target *target = bank->target;
484  struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
485 
486  uint32_t prot_addr = PSOC4_SFLASH_MACRO0;
487  int retval;
488  uint8_t bf[PSOC4_ROWS_PER_MACRO/8];
489  unsigned int s = 0;
490 
491  for (unsigned int m = 0; m < psoc4_info->num_macros; m++, prot_addr += PSOC4_SFLASH_MACRO_SIZE) {
492  retval = target_read_memory(target, prot_addr, 4, PSOC4_ROWS_PER_MACRO/32, bf);
493  if (retval != ERROR_OK)
494  return retval;
495 
496  for (unsigned int i = 0; i < PSOC4_ROWS_PER_MACRO && s < bank->num_sectors; i++, s++)
497  bank->sectors[s].is_protected = bf[i/8] & (1 << (i%8)) ? 1 : 0;
498  }
499 
500  return ERROR_OK;
501 }
502 
503 
504 static int psoc4_mass_erase(struct flash_bank *bank)
505 {
506  int retval = psoc4_flash_prepare(bank);
507  if (retval != ERROR_OK)
508  return retval;
509 
510  /* Call "Erase All" system ROM API */
511  uint32_t param = 0;
513  0,
514  &param, sizeof(param), NULL);
515 }
516 
517 
518 static int psoc4_erase(struct flash_bank *bank, unsigned int first,
519  unsigned int last)
520 {
521  struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
522  if (psoc4_info->cmd_program_row == PSOC4_CMD_WRITE_ROW) {
523  LOG_INFO("Autoerase enabled, erase command ignored");
524  return ERROR_OK;
525  }
526 
527  if ((first == 0) && (last == (bank->num_sectors - 1)))
528  return psoc4_mass_erase(bank);
529 
530  LOG_ERROR("Only mass erase available! Consider using 'psoc4 flash_autoerase 0 on'");
531 
532  return ERROR_FAIL;
533 }
534 
535 
536 static int psoc4_protect(struct flash_bank *bank, int set, unsigned int first,
537  unsigned int last)
538 {
539  struct target *target = bank->target;
540  struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
541 
542  if (!psoc4_info->probed)
543  return ERROR_FAIL;
544 
545  int retval = psoc4_flash_prepare(bank);
546  if (retval != ERROR_OK)
547  return retval;
548 
549  uint32_t *sysrq_buffer = NULL;
550  const int param_sz = 8;
551  int chip_prot = PSOC4_CHIP_PROT_OPEN;
552  unsigned int i;
553  unsigned int num_bits = bank->num_sectors;
554 
555  if (num_bits > PSOC4_ROWS_PER_MACRO)
556  num_bits = PSOC4_ROWS_PER_MACRO;
557 
558  int prot_sz = num_bits / 8;
559 
560  sysrq_buffer = malloc(param_sz + prot_sz);
561  if (!sysrq_buffer) {
562  LOG_ERROR("no memory for row buffer");
563  return ERROR_FAIL;
564  }
565 
566  for (i = first; i <= last && i < bank->num_sectors; i++)
567  bank->sectors[i].is_protected = set;
568 
569  for (unsigned int m = 0, sect = 0; m < psoc4_info->num_macros; m++) {
570  uint8_t *p = (uint8_t *)(sysrq_buffer + 2);
571  memset(p, 0, prot_sz);
572  for (i = 0; i < num_bits && sect < bank->num_sectors; i++, sect++) {
573  if (bank->sectors[sect].is_protected)
574  p[i/8] |= 1 << (i%8);
575  }
576 
577  /* Call "Load Latch" system ROM API */
578  target_buffer_set_u32(target, (uint8_t *)(sysrq_buffer + 1),
579  prot_sz - 1);
581  0 /* Byte number in latch from what to write */
582  | (m << 8), /* flash macro index */
583  sysrq_buffer, param_sz + prot_sz,
584  NULL);
585  if (retval != ERROR_OK)
586  break;
587 
588  /* Call "Write Protection" system ROM API */
590  chip_prot | (m << 8), NULL, 0, NULL);
591  if (retval != ERROR_OK)
592  break;
593  }
594 
595  free(sysrq_buffer);
596 
598  return retval;
599 }
600 
601 
602 COMMAND_HANDLER(psoc4_handle_flash_autoerase_command)
603 {
604  if (CMD_ARGC < 1)
606 
607  struct flash_bank *bank;
608  int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
609  if (retval != ERROR_OK)
610  return retval;
611 
612  struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
613  bool enable = psoc4_info->cmd_program_row == PSOC4_CMD_WRITE_ROW;
614 
615  if (CMD_ARGC >= 2)
616  COMMAND_PARSE_ON_OFF(CMD_ARGV[1], enable);
617 
618  if (enable) {
619  psoc4_info->cmd_program_row = PSOC4_CMD_WRITE_ROW;
620  LOG_INFO("Flash auto-erase enabled, non mass erase commands will be ignored.");
621  } else {
623  LOG_INFO("Flash auto-erase disabled. Use psoc mass_erase before flash programming.");
624  }
625 
626  return retval;
627 }
628 
629 
630 static int psoc4_write(struct flash_bank *bank, const uint8_t *buffer,
631  uint32_t offset, uint32_t count)
632 {
633  struct target *target = bank->target;
634  struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
635  uint32_t *sysrq_buffer = NULL;
636  const int param_sz = 8;
637 
638  int retval = psoc4_flash_prepare(bank);
639  if (retval != ERROR_OK)
640  return retval;
641 
642  sysrq_buffer = malloc(param_sz + psoc4_info->row_size);
643  if (!sysrq_buffer) {
644  LOG_ERROR("no memory for row buffer");
645  return ERROR_FAIL;
646  }
647 
648  uint8_t *row_buffer = (uint8_t *)sysrq_buffer + param_sz;
649  uint32_t row_num = offset / psoc4_info->row_size;
650  uint32_t row_offset = offset - row_num * psoc4_info->row_size;
651  if (row_offset)
652  memset(row_buffer, bank->default_padded_value, row_offset);
653 
654  /* Mask automatic polling triggered by execution of halted events */
655  bool save_poll_mask = jtag_poll_mask();
656 
657  while (count) {
658  uint32_t chunk_size = psoc4_info->row_size - row_offset;
659  if (chunk_size > count) {
660  chunk_size = count;
661  memset(row_buffer + chunk_size, bank->default_padded_value, psoc4_info->row_size - chunk_size);
662  }
663  memcpy(row_buffer + row_offset, buffer, chunk_size);
664  LOG_DEBUG("offset / row: 0x%08" PRIx32 " / %" PRIu32 ", size %" PRIu32 "",
665  offset, row_offset, chunk_size);
666 
667  uint32_t macro_idx = row_num / PSOC4_ROWS_PER_MACRO;
668 
669  /* Call "Load Latch" system ROM API */
670  target_buffer_set_u32(target, (uint8_t *)(sysrq_buffer + 1),
671  psoc4_info->row_size - 1);
673  0 /* Byte number in latch from what to write */
674  | (macro_idx << 8),
675  sysrq_buffer, param_sz + psoc4_info->row_size,
676  NULL);
677  if (retval != ERROR_OK)
678  goto cleanup;
679 
680  /* Call "Program Row" or "Write Row" system ROM API */
681  uint32_t sysrq_param;
682  retval = psoc4_sysreq(bank, psoc4_info->cmd_program_row,
683  row_num & 0xffff,
684  &sysrq_param, sizeof(sysrq_param),
685  NULL);
686  if (retval != ERROR_OK)
687  goto cleanup;
688 
689  buffer += chunk_size;
690  row_num++;
691  row_offset = 0;
692  count -= chunk_size;
693  }
694 
695 cleanup:
696  jtag_poll_unmask(save_poll_mask);
697 
698  free(sysrq_buffer);
699  return retval;
700 }
701 
702 
703 /* Due to Cypress's method of market segmentation some devices
704  * have accessible only 1/2, 1/4 or 1/8 of SPCIF described flash */
705 static int psoc4_test_flash_wounding(struct target *target, uint32_t flash_size)
706 {
707  int retval, i;
708  for (i = 3; i >= 1; i--) {
709  uint32_t addr = flash_size >> i;
710  uint32_t dummy;
711  retval = target_read_u32(target, addr, &dummy);
712  if (retval != ERROR_OK)
713  return i;
714  }
715  return 0;
716 }
717 
718 
719 static int psoc4_probe(struct flash_bank *bank)
720 {
721  struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
722  struct target *target = bank->target;
723 
724  int retval;
725  uint16_t family_id;
726 
727  psoc4_info->probed = false;
728 
729  retval = psoc4_get_family(target, &family_id);
730  if (retval != ERROR_OK)
731  return retval;
732 
733  const struct psoc4_chip_family *family = psoc4_family_by_id(family_id);
734 
735  if (family->id == 0) {
736  LOG_ERROR("Cannot identify PSoC 4 family.");
737  return ERROR_FAIL;
738  }
739 
740  if (family->flags & PSOC4_FAMILY_FLAG_LEGACY) {
741  LOG_INFO("%s legacy family detected.", family->name);
742  psoc4_info->legacy_family = true;
746  } else {
747  LOG_INFO("%s family detected.", family->name);
748  psoc4_info->legacy_family = false;
752  }
753 
754  uint32_t spcif_geometry;
755  retval = target_read_u32(target, psoc4_info->spcif_geometry_addr, &spcif_geometry);
756  if (retval != ERROR_OK)
757  return retval;
758 
759  uint32_t flash_size_in_kb = spcif_geometry & 0x3fff;
760  /* TRM of legacy, M and L version describes FLASH field as 16-bit.
761  * S-series and PSoC Analog Coprocessor changes spec to 14-bit only.
762  * Impose PSoC Analog Coprocessor limit to all devices as it
763  * does not make any harm: flash size is safely below 4 MByte limit
764  */
765  uint32_t row_size = (spcif_geometry >> 22) & 3;
766  uint32_t num_macros = (spcif_geometry >> 20) & 3;
767 
768  if (psoc4_info->legacy_family) {
769  flash_size_in_kb = flash_size_in_kb * 256 / 1024;
770  row_size *= 128;
771  } else {
772  flash_size_in_kb = (flash_size_in_kb + 1) * 256 / 1024;
773  row_size = 64 * (row_size + 1);
774  num_macros++;
775  }
776 
777  LOG_DEBUG("SPCIF geometry: %" PRIu32 " KiB flash, row %" PRIu32 " bytes.",
778  flash_size_in_kb, row_size);
779 
780  /* if the user sets the size manually then ignore the probed value
781  * this allows us to work around devices that have a invalid flash size register value */
782  if (psoc4_info->user_bank_size) {
783  LOG_INFO("ignoring flash probed value, using configured bank size");
784  flash_size_in_kb = psoc4_info->user_bank_size / 1024;
785  }
786 
787  char macros_txt[20] = "";
788  if (num_macros > 1)
789  snprintf(macros_txt, sizeof(macros_txt), " in %" PRIu32 " macros", num_macros);
790 
791  LOG_INFO("flash size = %" PRIu32 " KiB%s", flash_size_in_kb, macros_txt);
792 
793  /* calculate number of pages */
794  uint32_t num_rows = flash_size_in_kb * 1024 / row_size;
795 
796  /* check number of flash macros */
797  if (num_macros != (num_rows + PSOC4_ROWS_PER_MACRO - 1) / PSOC4_ROWS_PER_MACRO)
798  LOG_WARNING("Number of macros does not correspond with flash size!");
799 
800  if (!psoc4_info->legacy_family) {
801  int wounding = psoc4_test_flash_wounding(target, num_rows * row_size);
802  if (wounding > 0) {
803  flash_size_in_kb = flash_size_in_kb >> wounding;
804  num_rows = num_rows >> wounding;
805  LOG_INFO("WOUNDING detected: accessible flash size %" PRIu32 " kbytes", flash_size_in_kb);
806  }
807  }
808 
809  free(bank->sectors);
810 
811  psoc4_info->family_id = family_id;
812  psoc4_info->num_macros = num_macros;
813  psoc4_info->row_size = row_size;
814  bank->base = 0x00000000;
815  bank->size = num_rows * row_size;
816  bank->num_sectors = num_rows;
817  bank->sectors = alloc_block_array(0, row_size, num_rows);
818  if (!bank->sectors)
819  return ERROR_FAIL;
820 
821  LOG_DEBUG("flash bank set %" PRIu32 " rows", num_rows);
822  psoc4_info->probed = true;
823 
824  return ERROR_OK;
825 }
826 
827 static int psoc4_auto_probe(struct flash_bank *bank)
828 {
829  struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
830  if (psoc4_info->probed)
831  return ERROR_OK;
832  return psoc4_probe(bank);
833 }
834 
835 
837 {
838  struct target *target = bank->target;
839  struct psoc4_flash_bank *psoc4_info = bank->driver_priv;
840 
841  if (!psoc4_info->probed)
842  return ERROR_FAIL;
843 
844  const struct psoc4_chip_family *family = psoc4_family_by_id(psoc4_info->family_id);
845  uint32_t size_in_kb = bank->size / 1024;
846 
847  if (target->state != TARGET_HALTED) {
848  command_print_sameline(cmd, "%s, flash %" PRIu32 " kb"
849  " (halt target to see details)", family->name, size_in_kb);
850  return ERROR_OK;
851  }
852 
853  uint32_t silicon_id;
854  uint16_t family_id;
855  uint8_t protection;
856 
857  int retval = psoc4_get_silicon_id(bank, &silicon_id, &family_id, &protection);
858  if (retval != ERROR_OK)
859  return retval;
860 
861  if (family_id != psoc4_info->family_id)
862  command_print_sameline(cmd, "Family id mismatch 0x%02" PRIx16
863  "/0x%02" PRIx16 ", silicon id 0x%08" PRIx32,
864  psoc4_info->family_id, family_id, silicon_id);
865  else {
866  command_print_sameline(cmd, "%s silicon id 0x%08" PRIx32 "",
867  family->name, silicon_id);
868  }
869 
870  const char *prot_txt = psoc4_decode_chip_protection(protection);
871  command_print_sameline(cmd, ", flash %" PRIu32 " kb %s", size_in_kb, prot_txt);
872  return ERROR_OK;
873 }
874 
875 
876 COMMAND_HANDLER(psoc4_handle_mass_erase_command)
877 {
878  if (CMD_ARGC < 1)
880 
881  struct flash_bank *bank;
882  int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
883  if (retval != ERROR_OK)
884  return retval;
885 
886  retval = psoc4_mass_erase(bank);
887  if (retval == ERROR_OK)
888  command_print(CMD, "psoc mass erase complete");
889  else
890  command_print(CMD, "psoc mass erase failed");
891 
892  return retval;
893 }
894 
895 
896 static const struct command_registration psoc4_exec_command_handlers[] = {
897  {
898  .name = "mass_erase",
899  .handler = psoc4_handle_mass_erase_command,
900  .mode = COMMAND_EXEC,
901  .usage = "bank_id",
902  .help = "Erase entire flash device.",
903  },
904  {
905  .name = "flash_autoerase",
906  .handler = psoc4_handle_flash_autoerase_command,
907  .mode = COMMAND_EXEC,
908  .usage = "bank_id on|off",
909  .help = "Set autoerase mode for flash bank.",
910  },
912 };
913 
914 static const struct command_registration psoc4_command_handlers[] = {
915  {
916  .name = "psoc4",
917  .mode = COMMAND_ANY,
918  .help = "PSoC 4 flash command group",
919  .usage = "",
921  },
923 };
924 
925 const struct flash_driver psoc4_flash = {
926  .name = "psoc4",
927  .commands = psoc4_command_handlers,
928  .flash_bank_command = psoc4_flash_bank_command,
929  .erase = psoc4_erase,
930  .protect = psoc4_protect,
931  .write = psoc4_write,
932  .read = default_flash_read,
933  .probe = psoc4_probe,
934  .auto_probe = psoc4_auto_probe,
935  .erase_check = default_flash_blank_check,
936  .protect_check = psoc4_protect_check,
937  .info = get_psoc4_info,
938  .free_driver_priv = default_flash_free_driver_priv,
939 };
static struct aice_port_param_s param
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
Definition: algorithm.c:29
void destroy_reg_param(struct reg_param *param)
Definition: algorithm.c:37
@ PARAM_OUT
Definition: algorithm.h:16
@ ARM_MODE_THREAD
Definition: arm.h:86
static struct armv7m_common * target_to_armv7m(struct target *target)
Definition: armv7m.h:260
#define ARMV7M_COMMON_MAGIC
Definition: armv7m.h:218
Support functions to access arbitrary bits in a byte array.
static void buf_set_u32(uint8_t *_buffer, unsigned first, unsigned num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:30
void command_print_sameline(struct command_invocation *cmd, const char *format,...)
Definition: command.c:450
void command_print(struct command_invocation *cmd, const char *format,...)
Definition: command.c:473
#define CMD
Use this macro to access the command being handled, rather than accessing the variable directly.
Definition: command.h:140
#define CALL_COMMAND_HANDLER(name, extra ...)
Use this to macro to call a command helper (or a nested handler).
Definition: command.h:117
#define CMD_ARGV
Use this macro to access the arguments for the command being handled, rather than accessing the varia...
Definition: command.h:155
#define COMMAND_PARSE_ON_OFF(in, out)
parses an on/off command argument
Definition: command.h:504
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:385
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:150
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:247
@ COMMAND_ANY
Definition: command.h:42
@ COMMAND_EXEC
Definition: command.h:40
uint8_t bank
Definition: esirisc.c:135
struct flash_sector * alloc_block_array(uint32_t offset, uint32_t size, unsigned int num_blocks)
Allocate and fill an array of sectors or protection blocks.
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
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.
void jtag_poll_unmask(bool saved)
Restore saved mask for polling.
Definition: jtag/core.c:177
bool jtag_poll_mask(void)
Mask (disable) polling and return the current mask status that should be feed to jtag_poll_unmask() t...
Definition: jtag/core.c:170
The JTAG interface can be implemented with a software or hardware fifo.
#define LOG_WARNING(expr ...)
Definition: log.h:120
#define ERROR_FAIL
Definition: log.h:161
#define LOG_ERROR(expr ...)
Definition: log.h:123
#define LOG_INFO(expr ...)
Definition: log.h:117
#define LOG_DEBUG(expr ...)
Definition: log.h:109
#define ERROR_OK
Definition: log.h:155
uint32_t addr
Definition: nuttx.c:65
#define PSOC4_SROM_KEY1
Definition: psoc4.c:94
static const struct psoc4_chip_family psoc4_families[]
Definition: psoc4.c:131
#define PSOC4_SPCIF_GEOMETRY_LEGACY
Definition: psoc4.c:79
#define PSOC4_CMD_WRITE_ROW
Definition: psoc4.c:108
#define PSOC4_ROWS_PER_MACRO
Definition: psoc4.c:92
#define PSOC4_SROM_ERR_IMO_NOT_IMPLEM
Definition: psoc4.c:104
static const struct psoc4_chip_family * psoc4_family_by_id(uint16_t family_id)
Definition: psoc4.c:160
#define PSOC4_CMD_SET_IMO48
Definition: psoc4.c:113
static int psoc4_probe(struct flash_bank *bank)
Definition: psoc4.c:719
static int psoc4_erase(struct flash_bank *bank, unsigned int first, unsigned int last)
Definition: psoc4.c:518
static int psoc4_sysreq(struct flash_bank *bank, uint8_t cmd, uint16_t cmd_param, uint32_t *sysreq_params, uint32_t sysreq_params_size, uint32_t *sysarg_out)
Definition: psoc4.c:214
#define PSOC4_CHIP_PROT_PROTECTED
Definition: psoc4.c:118
static int get_psoc4_info(struct flash_bank *bank, struct command_invocation *cmd)
Definition: psoc4.c:836
#define PSOC4_CMD_WRITE_PROTECTION
Definition: psoc4.c:112
static int psoc4_get_silicon_id(struct flash_bank *bank, uint32_t *silicon_id, uint16_t *family_id, uint8_t *protection)
Definition: psoc4.c:361
#define PSOC4_SPCIF_GEOMETRY_NEW
Definition: psoc4.c:83
#define PSOC4_SROM_HMASTER_BIT
Definition: psoc4.c:97
static int psoc4_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: psoc4.c:630
static int psoc4_mass_erase(struct flash_bank *bank)
Definition: psoc4.c:504
#define PSOC4_SROM_KEY2
Definition: psoc4.c:95
static int psoc4_test_flash_wounding(struct target *target, uint32_t flash_size)
Definition: psoc4.c:705
static int psoc4_get_family(struct target *target, uint16_t *family_id)
Definition: psoc4.c:401
#define PSOC4_CPUSS_SYSREQ_NEW
Definition: psoc4.c:81
#define PSOC4_SFLASH_MACRO0
Definition: psoc4.c:75
#define PSOC4_CHIP_PROT_OPEN
Definition: psoc4.c:117
#define PSOC4_CPUSS_SYSREQ_LEGACY
Definition: psoc4.c:77
#define PSOC4_CMD_ERASE_ALL
Definition: psoc4.c:110
#define PSOC4_ROMTABLE_PID0
Definition: psoc4.c:87
static const struct command_registration psoc4_exec_command_handlers[]
Definition: psoc4.c:896
#define PSOC4_FAMILY_FLAG_LEGACY
Definition: psoc4.c:123
#define PSOC4_CPUSS_SYSARG_LEGACY
Definition: psoc4.c:78
#define PSOC4_CMD_LOAD_LATCH
Definition: psoc4.c:107
static int psoc4_protect_check(struct flash_bank *bank)
Definition: psoc4.c:481
static const struct command_registration psoc4_command_handlers[]
Definition: psoc4.c:914
static int psoc4_flash_prepare(struct flash_bank *bank)
Definition: psoc4.c:433
#define PSOC4_SROM_STATUS_SUCCEEDED
Definition: psoc4.c:99
FLASH_BANK_COMMAND_HANDLER(psoc4_flash_bank_command)
Definition: psoc4.c:189
COMMAND_HANDLER(psoc4_handle_flash_autoerase_command)
Definition: psoc4.c:602
#define PSOC4_CPUSS_SYSARG_NEW
Definition: psoc4.c:82
#define PSOC4_SFLASH_MACRO_SIZE
Definition: psoc4.c:91
#define PSOC4_CHIP_PROT_VIRGIN
Definition: psoc4.c:116
static const char * psoc4_decode_chip_protection(uint8_t protection)
Definition: psoc4.c:169
const struct flash_driver psoc4_flash
Definition: psoc4.c:925
#define PSOC4_ROMTABLE_DESIGNER_CHECK
Definition: psoc4.c:121
#define PSOC4_CMD_PROGRAM_ROW
Definition: psoc4.c:109
#define PSOC4_CMD_GET_SILICON_ID
Definition: psoc4.c:106
#define PSOC4_SROM_SYSREQ_BIT
Definition: psoc4.c:96
#define PSOC4_SROM_STATUS_MASK
Definition: psoc4.c:101
static int psoc4_protect(struct flash_bank *bank, int set, unsigned int first, unsigned int last)
Definition: psoc4.c:536
static int psoc4_auto_probe(struct flash_bank *bank)
Definition: psoc4.c:827
#define PSOC4_CHIP_PROT_KILL
Definition: psoc4.c:119
unsigned int common_magic
Definition: armv7m.h:293
enum arm_mode core_mode
Definition: armv7m.h:295
When run_command is called, a new instance will be created on the stack, filled with the proper value...
Definition: command.h:76
const char * name
Definition: command.h:229
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
uint16_t id
Definition: psoc4.c:126
uint32_t flags
Definition: psoc4.c:128
const char * name
Definition: psoc4.c:127
uint16_t family_id
Definition: psoc4.c:152
uint32_t cpuss_sysarg_addr
Definition: psoc4.c:155
unsigned int num_macros
Definition: psoc4.c:149
uint32_t row_size
Definition: psoc4.c:147
uint32_t user_bank_size
Definition: psoc4.c:148
bool legacy_family
Definition: psoc4.c:153
uint32_t cpuss_sysreq_addr
Definition: psoc4.c:154
uint32_t spcif_geometry_addr
Definition: psoc4.c:156
uint8_t cmd_program_row
Definition: psoc4.c:151
Definition: target.h:120
enum target_state state
Definition: target.h:162
uint32_t size
Definition: target.h:91
target_addr_t address
Definition: target.h:90
void target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t value)
Definition: target.c:411
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
Definition: target.c:2408
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
Definition: target.c:2129
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
Definition: target.c:2707
int target_free_working_area(struct target *target, struct working_area *area)
Free a working area.
Definition: target.c:2187
int target_run_algorithm(struct target *target, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_param, target_addr_t entry_point, target_addr_t exit_point, int timeout_ms, void *arch_info)
Downloads a target-specific native code algorithm to the target, and executes it.
Definition: target.c:846
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
Definition: target.c:2616
int target_read_memory(struct target *target, target_addr_t address, uint32_t size, uint32_t count, uint8_t *buffer)
Read count items of size bytes from the memory of target at the address given.
Definition: target.c:1306
uint32_t target_buffer_get_u32(struct target *target, const uint8_t *buffer)
Definition: target.c:375
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:792
@ TARGET_HALTED
Definition: target.h:55
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
Definition: target.h:796
#define ARRAY_SIZE(x)
Compute the number of elements of a variable length array.
Definition: types.h:57
#define NULL
Definition: usb.h:16
uint8_t cmd
Definition: vdebug.c:1
uint8_t offset[4]
Definition: vdebug.c:9
uint8_t dummy[96]
Definition: vdebug.c:23
uint8_t count[4]
Definition: vdebug.c:22