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