1d861edc9d538cb41cab754b3b646bbb31678fbf
[openocd.git] / 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 };

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)