8ca1a7cfa84bdf8ee92fe711c6181cd5258c8ffc
[fw/openocd] / src / flash / nor / psoc4.c
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
125 struct psoc4_chip_family {
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
146 struct psoc4_flash_bank {
147         uint32_t row_size;
148         uint32_t user_bank_size;
149         unsigned int num_macros;
150         bool probed;
151         uint8_t cmd_program_row;
152         uint16_t family_id;
153         bool legacy_family;
154         uint32_t cpuss_sysreq_addr;
155         uint32_t cpuss_sysarg_addr;
156         uint32_t spcif_geometry_addr;
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) {
172         case PSOC4_CHIP_PROT_VIRGIN:
173                 return "protection VIRGIN";
174         case PSOC4_CHIP_PROT_OPEN:
175                 return "protection open";
176         case PSOC4_CHIP_PROT_PROTECTED:
177                 return "PROTECTED";
178         case PSOC4_CHIP_PROT_KILL:
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)
194                 return ERROR_COMMAND_SYNTAX_ERROR;
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");
253                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
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 */
277                         retval = ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
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,
321                                   PSOC4_SROM_SYSREQ_BIT | PSOC4_SROM_HMASTER_BIT | cmd);
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
372         if ((part0 & PSOC4_SROM_STATUS_MASK) != PSOC4_SROM_STATUS_SUCCEEDED) {
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
433 static int psoc4_flash_prepare(struct flash_bank *bank)
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");
440                 return ERROR_TARGET_NOT_HALTED;
441         }
442
443         uint16_t family_id;
444         int retval;
445
446         /* get family ID from SROM call */
447         retval = psoc4_get_silicon_id(bank, NULL, &family_id, NULL);
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
481 static int psoc4_protect_check(struct flash_bank *bank)
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;
512         return psoc4_sysreq(bank, PSOC4_CMD_ERASE_ALL,
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);
580                 retval = psoc4_sysreq(bank, PSOC4_CMD_LOAD_LATCH,
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 */
589                 retval = psoc4_sysreq(bank, PSOC4_CMD_WRITE_PROTECTION,
590                         chip_prot | (m << 8), NULL, 0, NULL);
591                 if (retval != ERROR_OK)
592                         break;
593         }
594
595         free(sysrq_buffer);
596
597         psoc4_protect_check(bank);
598         return retval;
599 }
600
601
602 COMMAND_HANDLER(psoc4_handle_flash_autoerase_command)
603 {
604         if (CMD_ARGC < 1)
605                 return ERROR_COMMAND_SYNTAX_ERROR;
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 {
622                 psoc4_info->cmd_program_row = PSOC4_CMD_PROGRAM_ROW;
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);
672                 retval = psoc4_sysreq(bank, PSOC4_CMD_LOAD_LATCH,
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;
743                 psoc4_info->cpuss_sysreq_addr = PSOC4_CPUSS_SYSREQ_LEGACY;
744                 psoc4_info->cpuss_sysarg_addr = PSOC4_CPUSS_SYSARG_LEGACY;
745                 psoc4_info->spcif_geometry_addr = PSOC4_SPCIF_GEOMETRY_LEGACY;
746         } else {
747                 LOG_INFO("%s family detected.", family->name);
748                 psoc4_info->legacy_family = false;
749                 psoc4_info->cpuss_sysreq_addr = PSOC4_CPUSS_SYSREQ_NEW;
750                 psoc4_info->cpuss_sysarg_addr = PSOC4_CPUSS_SYSARG_NEW;
751                 psoc4_info->spcif_geometry_addr = PSOC4_SPCIF_GEOMETRY_NEW;
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
836 static int get_psoc4_info(struct flash_bank *bank, struct command_invocation *cmd)
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)
879                 return ERROR_COMMAND_SYNTAX_ERROR;
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         },
911         COMMAND_REGISTRATION_DONE
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 = "",
920                 .chain = psoc4_exec_command_handlers,
921         },
922         COMMAND_REGISTRATION_DONE
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 };