jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / flash / nor / sim3x.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2
3 /***************************************************************************
4 * Copyright (C) 2014 by Ladislav Bábel *
5 * ladababel@seznam.cz *
6 * *
7 * Copyright (C) 2015 by Andreas Bomholtz *
8 * andreas@seluxit.com *
9 ***************************************************************************/
10
11 #ifdef HAVE_CONFIG_H
12 #include "config.h"
13 #endif
14
15 #include "imp.h"
16 #include <helper/binarybuffer.h>
17 #include <helper/time_support.h>
18 #include <target/algorithm.h>
19 #include <target/arm_adi_v5.h>
20 #include <target/cortex_m.h>
21
22 /* SI32_DEVICEID0 */
23 #define DEVICEID0_DEVICEID0 (0x400490C0)
24 #define DEVICEID0_DEVICEID1 (0x400490D0)
25 #define DEVICEID0_DEVICEID2 (0x400490E0)
26 #define DEVICEID0_DEVICEID3 (0x400490F0)
27
28 /* cortex_m CPUID */
29 #define CPUID_CHECK_VALUE (0x410FC230)
30 #define CPUID_CHECK_VALUE_MASK (0xFF0FFFF0)
31
32 /* Flash */
33 #define FLASH_BASE_ADDRESS (0x00000000)
34 #define LOCK_WORD_ADDRESS (0x0003FFFC)
35
36 #define LOCK_WORD_MCU_UNLOCKED (0xFFFFFFFF)
37 /* Can't by locked again without erase, because LOCK_WORD is in FLASH */
38 #define LOCK_WORD_MCU_UNLOCKED_BY_FIRMWARE (0x00000000)
39
40 /* SI32_FLASHCTRL_0 */
41 #define FLASHCTRL0_CONFIG_ALL (0x4002E000)
42 #define FLASHCTRL0_CONFIG_SET (0x4002E004)
43 #define FLASHCTRL0_CONFIG_CLR (0x4002E008)
44 #define FLASHCTRL0_CONFIG_ERASEEN_MASK (0x00040000)
45 #define FLASHCTRL0_CONFIG_BUSYF_MASK (0x00100000)
46
47 #define FLASHCTRL0_WRADDR (0x4002E0A0)
48 #define FLASHCTRL0_WRDATA (0x4002E0B0)
49
50 #define FLASHCTRL0_KEY (0x4002E0C0)
51 #define FLASHCTRL0_KEY_INITIAL_UNLOCK (0x000000A5)
52 #define FLASHCTRL0_KEY_SINGLE_UNLOCK (0x000000F1)
53 #define FLASHCTRL0_KEY_MULTIPLE_UNLOCK (0x000000F2)
54 #define FLASHCTRL0_KEY_MULTIPLE_LOCK (0x0000005A)
55
56 #define FLASH_BUSY_TIMEOUT (100)
57
58 /* SI32_RSTSRC_0 */
59 #define RSTSRC0_RESETEN_ALL (0x4002D060)
60 #define RSTSRC0_RESETEN_SET (0x4002D064)
61 #define RSTSRC0_RESETEN_CLR (0x4002D068)
62 #define RSTSRC0_RESETEN_VMONREN_MASK (0x00000004)
63 #define RSTSRC0_RESETEN_SWREN_MASK (0x00000040)
64
65 /* SI32_VMON_0 */
66 #define VMON0_CONTROL_ALL (0x4002F000)
67 #define VMON0_CONTROL_SET (0x4002F004)
68 #define VMON0_CONTROL_CLR (0x4002F008)
69 #define VMON0_CONTROL_VMONEN_MASK (0x80000000)
70
71 /* SI32_CLKCTRL_0 */
72 #define CLKCTRL0_APBCLKG0_ALL (0x4002D020)
73 #define CLKCTRL0_APBCLKG0_SET (0x4002D024)
74 #define CLKCTRL0_APBCLKG0_CLR (0x4002D028)
75 #define CLKCTRL0_APBCLKG0_FLCTRLCEN_MASK (0x40000000)
76
77 /* SI32_WDTIMER_0 */
78 #define WDTIMER0_CONTROL_ALL (0x40030000)
79 #define WDTIMER0_CONTROL_SET (0x40030004)
80 #define WDTIMER0_CONTROL_CLR (0x40030008)
81 #define WDTIMER0_CONTROL_DBGMD_MASK (0x00000002)
82
83 #define WDTIMER0_STATUS_ALL (0x40030010)
84 #define WDTIMER0_STATUS_SET (0x40030014)
85 #define WDTIMER0_STATUS_CLR (0x40030018)
86 #define WDTIMER0_STATUS_KEYSTS_MASK (0x00000001)
87 #define WDTIMER0_STATUS_PRIVSTS_MASK (0x00000002)
88
89 #define WDTIMER0_THRESHOLD (0x40030020)
90
91 #define WDTIMER0_WDTKEY (0x40030030)
92 #define WDTIMER0_KEY_ATTN (0x000000A5)
93 #define WDTIMER0_KEY_WRITE (0x000000F1)
94 #define WDTIMER0_KEY_RESET (0x000000CC)
95 #define WDTIMER0_KEY_DISABLE (0x000000DD)
96 #define WDTIMER0_KEY_START (0x000000EE)
97 #define WDTIMER0_KEY_LOCK (0x000000FF)
98
99 /* DAP */
100 #define SIM3X_AP (0x0A)
101
102 #define SIM3X_AP_CTRL1 (0x00)
103 #define SIM3X_AP_CTRL2 (0x04)
104 #define SIM3X_AP_LOCK (0x08)
105 #define SIM3X_AP_CRC (0x0C)
106
107 #define SIM3X_AP_INIT_STAT (0x10)
108 #define SIM3X_AP_DAP_IN (0x14)
109 #define SIM3X_AP_DAP_OUT (0x18)
110
111 #define SIM3X_AP_ID (0xFC)
112
113 /* DAP register values */
114 #define SIM3X_AP_CTRL1_MASS_ERASE_REQ (0x00000001)
115 #define SIM3X_AP_CTRL1_RESET_REQ (0x00000008)
116 /* this bit is set if MCU is locked */
117 #define SIM3X_AP_INIT_STAT_LOCK (0x00000004)
118 /* expected value inside SIM3X_AP_ID */
119 #define SIM3X_AP_ID_VALUE (0x2430002)
120
121 #define SIM3X_FLASH_PAGE_SIZE 1024
122
123 struct sim3x_info {
124 uint16_t flash_size_kb;
125 uint16_t part_number;
126 char part_family;
127 uint8_t device_revision;
128 char device_package[4];
129 bool probed;
130 bool need_init;
131 bool flash_locked;
132 };
133
134 /* flash bank sim3x 0 0 0 0 <target#> */
135 FLASH_BANK_COMMAND_HANDLER(sim3x_flash_bank_command)
136 {
137 struct sim3x_info *sim3x_info;
138
139 if (CMD_ARGC < 6)
140 return ERROR_COMMAND_SYNTAX_ERROR;
141
142 /* Init sim3x_info struct */
143 sim3x_info = malloc(sizeof(struct sim3x_info));
144 sim3x_info->probed = false;
145 sim3x_info->need_init = true;
146 sim3x_info->device_revision = 0;
147 memset(sim3x_info->device_package, 0, 4);
148 bank->driver_priv = sim3x_info;
149
150 return ERROR_OK;
151 }
152
153 static int sim3x_init(struct flash_bank *bank)
154 {
155 int ret;
156 struct target *target;
157 struct sim3x_info *sim3x_info;
158
159 target = bank->target;
160
161 /* Disable watchdog timer */
162 ret = target_write_u32(target, WDTIMER0_WDTKEY, WDTIMER0_KEY_ATTN);
163 if (ret != ERROR_OK)
164 return ret;
165
166 ret = target_write_u32(target, WDTIMER0_WDTKEY, WDTIMER0_KEY_DISABLE);
167 if (ret != ERROR_OK)
168 return ret;
169
170 /* Enable one write command */
171 ret = target_write_u32(target, WDTIMER0_WDTKEY, WDTIMER0_KEY_ATTN);
172 if (ret != ERROR_OK)
173 return ret;
174
175 ret = target_write_u32(target, WDTIMER0_WDTKEY, WDTIMER0_KEY_WRITE);
176 if (ret != ERROR_OK)
177 return ret;
178
179 /* Watchdog Timer Debug Mode */
180 ret = target_write_u32(target, WDTIMER0_CONTROL_SET,
181 WDTIMER0_CONTROL_DBGMD_MASK);
182 if (ret != ERROR_OK)
183 return ret;
184
185 /* Enable VDD Supply Monitor */
186 ret = target_write_u32(target, VMON0_CONTROL_SET,
187 VMON0_CONTROL_VMONEN_MASK);
188 if (ret != ERROR_OK)
189 return ret;
190
191 /* Set VDD Supply Monitor as a reset source */
192 ret = target_write_u32(target, RSTSRC0_RESETEN_SET,
193 RSTSRC0_RESETEN_VMONREN_MASK);
194 if (ret != ERROR_OK)
195 return ret;
196
197 /* Flash Controller Clock Enable */
198 ret = target_write_u32(target, CLKCTRL0_APBCLKG0_SET,
199 CLKCTRL0_APBCLKG0_FLCTRLCEN_MASK);
200 if (ret != ERROR_OK)
201 return ret;
202
203 /* Disable Flash Erase Mode */
204 ret = target_write_u32(target, FLASHCTRL0_CONFIG_CLR,
205 FLASHCTRL0_CONFIG_ERASEEN_MASK);
206 if (ret != ERROR_OK)
207 return ret;
208
209 sim3x_info = bank->driver_priv;
210 sim3x_info->need_init = 0;
211 return ERROR_OK;
212 }
213
214 static int sim3x_erase_page(struct flash_bank *bank, uint32_t addr)
215 {
216 int ret, i;
217 uint32_t temp;
218 struct target *target;
219
220 target = bank->target;
221
222 for (i = 0; i < FLASH_BUSY_TIMEOUT; i++) {
223 ret = target_read_u32(target, FLASHCTRL0_CONFIG_ALL, &temp);
224 if (ret != ERROR_OK)
225 return ret;
226
227 /* If is not busy */
228 if ((temp & FLASHCTRL0_CONFIG_BUSYF_MASK) == 0) {
229 /* If erase is not enabled */
230 if ((temp & FLASHCTRL0_CONFIG_ERASEEN_MASK) == 0) {
231 /* Enter Flash Erase Mode */
232 ret = target_write_u32(target, FLASHCTRL0_CONFIG_SET,
233 FLASHCTRL0_CONFIG_ERASEEN_MASK);
234 if (ret != ERROR_OK)
235 return ret;
236 }
237
238 /* Write the address of the Flash page to WRADDR */
239 ret = target_write_u32(target, FLASHCTRL0_WRADDR, addr);
240 if (ret != ERROR_OK)
241 return ret;
242
243 /* Write the initial unlock value to KEY */
244 ret = target_write_u32(target, FLASHCTRL0_KEY,
245 FLASHCTRL0_KEY_INITIAL_UNLOCK);
246 if (ret != ERROR_OK)
247 return ret;
248
249 /* Write the single unlock value to KEY */
250 ret = target_write_u32(target, FLASHCTRL0_KEY,
251 FLASHCTRL0_KEY_SINGLE_UNLOCK);
252 if (ret != ERROR_OK)
253 return ret;
254
255 /* Write any value to WRDATA to initiate the page erase */
256 ret = target_write_u32(target, FLASHCTRL0_WRDATA, 0);
257 if (ret != ERROR_OK)
258 return ret;
259
260 return ERROR_OK;
261 }
262
263 alive_sleep(1);
264 }
265
266 LOG_ERROR("timed out waiting for FLASHCTRL0_CONFIG_BUSYF");
267 return ERROR_FAIL;
268 }
269
270 static int sim3x_flash_erase(struct flash_bank *bank, unsigned int first,
271 unsigned int last)
272 {
273 int ret;
274 uint32_t temp;
275 struct sim3x_info *sim3x_info;
276 struct target *target;
277
278 /* Check if target is halted */
279 if (bank->target->state != TARGET_HALTED) {
280 LOG_ERROR("Target not halted");
281 return ERROR_TARGET_NOT_HALTED;
282 }
283
284 sim3x_info = bank->driver_priv;
285
286 /* Init MCU after reset */
287 if (sim3x_info->need_init) {
288 ret = sim3x_init(bank);
289 if (ret != ERROR_OK) {
290 LOG_ERROR("Failed to init MCU");
291 return ret;
292 }
293 }
294
295 /* erase pages */
296 for (unsigned int i = first; i <= last; i++) {
297 ret = sim3x_erase_page(bank, bank->sectors[i].offset);
298 if (ret != ERROR_OK)
299 return ret;
300 }
301
302 target = bank->target;
303
304 /* Wait until busy */
305 for (unsigned int i = 0; i < FLASH_BUSY_TIMEOUT; i++) {
306 ret = target_read_u32(target, FLASHCTRL0_CONFIG_ALL, &temp);
307 if (ret != ERROR_OK)
308 return ret;
309
310 if ((temp & FLASHCTRL0_CONFIG_BUSYF_MASK) == 0) { /* If is not busy */
311 if ((temp & FLASHCTRL0_CONFIG_ERASEEN_MASK) != 0) { /* If erase is enabled */
312 /* Disable Flash Erase Mode */
313 ret = target_write_u32(target, FLASHCTRL0_CONFIG_CLR,
314 FLASHCTRL0_CONFIG_ERASEEN_MASK);
315 if (ret != ERROR_OK)
316 return ret;
317 }
318
319 return ERROR_OK;
320 }
321
322 alive_sleep(1);
323 }
324
325 LOG_ERROR("timed out waiting for FLASHCTRL0_CONFIG_BUSYF");
326 return ERROR_FAIL;
327 }
328
329 static int sim3x_write_block(struct flash_bank *bank, const uint8_t *buf,
330 uint32_t offset, uint32_t count) /* count is count of half words (2 bytes)! */
331 {
332 struct target *target = bank->target;
333 uint32_t buffer_size = 16384;
334 struct working_area *write_algorithm;
335 struct working_area *source;
336 uint32_t address = bank->base + offset;
337 struct reg_param reg_params[5];
338 struct armv7m_algorithm armv7m_info;
339 int ret = ERROR_OK;
340
341 /* see contrib/loaders/flash/sim3x.s for src */
342
343 static const uint8_t sim3x_flash_write_code[] = {
344 /* Write the initial unlock value to KEY (0xA5) */
345 0xA5, 0x26, /* movs r6, #INITIAL_UNLOCK */
346 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */
347
348 /* Write the multiple unlock value to KEY (0xF2) */
349 0xF2, 0x26, /* movs r6, #MULTIPLE_UNLOCK */
350 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */
351
352 /* wait_fifo: */
353 0x16, 0x68, /* ldr r6, [r2, #0] */
354 0x00, 0x2E, /* cmp r6, #0 */
355 0x16, 0xD0, /* beq exit */
356 0x55, 0x68, /* ldr r5, [r2, #4] */
357 0xB5, 0x42, /* cmp r5, r6 */
358 0xF9, 0xD0, /* beq wait_fifo */
359
360 /* wait for BUSYF flag */
361 /* wait_busy1: */
362 0x06, 0x68, /* ldr r6, [r0, #FLASHCTRL_CONFIG] */
363 0x16, 0xF4, 0x80, 0x1F, /* tst r6, #BUSYF */
364 0xFB, 0xD1, /* bne wait_busy1 */
365
366 /* Write the destination address to WRADDR */
367 0xC0, 0xF8, 0xA0, 0x40, /* str r4, [r0, #FLASHCTRL_WRADDR] */
368
369 /* Write the data half-word to WRDATA in right-justified format */
370 0x2E, 0x88, /* ldrh r6, [r5] */
371 0xC0, 0xF8, 0xB0, 0x60, /* str r6, [r0, #FLASHCTRL_WRDATA] */
372
373 0x02, 0x35, /* adds r5, #2 */
374 0x02, 0x34, /* adds r4, #2 */
375
376 /* wrap rp at end of buffer */
377 0x9D, 0x42, /* cmp r5, r3 */
378 0x01, 0xD3, /* bcc no_wrap */
379 0x15, 0x46, /* mov r5, r2 */
380 0x08, 0x35, /* adds r5, #8 */
381
382 /* no_wrap: */
383 0x55, 0x60, /* str r5, [r2, #4] */
384 0x49, 0x1E, /* subs r1, r1, #1 */
385 0x00, 0x29, /* cmp r1, #0 */
386 0x00, 0xD0, /* beq exit */
387 0xE5, 0xE7, /* b wait_fifo */
388
389 /* exit: */
390 0x5A, 0x26, /* movs r6, #MULTIPLE_LOCK */
391 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */
392
393 /* wait for BUSYF flag */
394 /* wait_busy2: */
395 0x06, 0x68, /* ldr r6, [r0, #FLASHCTRL_CONFIG] */
396 0x16, 0xF4, 0x80, 0x1F, /* tst r6, #BUSYF */
397 0xFB, 0xD1, /* bne wait_busy2 */
398
399 0x00, 0xBE /* bkpt #0 */
400 };
401
402 /* flash write code */
403 if (target_alloc_working_area(target, sizeof(sim3x_flash_write_code),
404 &write_algorithm) != ERROR_OK) {
405 LOG_WARNING("no working area available, can't do block memory writes");
406 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
407 }
408
409 ret = target_write_buffer(target, write_algorithm->address,
410 sizeof(sim3x_flash_write_code), sim3x_flash_write_code);
411 if (ret != ERROR_OK)
412 return ret;
413
414 /* memory buffer */
415 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
416 buffer_size /= 2;
417 buffer_size &= ~1UL; /* Make sure it's 2 byte aligned */
418 if (buffer_size <= 256) {
419 /* we already allocated the writing code, but failed to get a
420 * buffer, free the algorithm
421 */
422 target_free_working_area(target, write_algorithm);
423
424 LOG_WARNING("no large enough working area available, can't do block memory writes");
425 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
426 }
427 }
428
429 init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT); /* flash base */
430 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* count */
431 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* buffer start */
432 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* buffer end */
433 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN_OUT); /* target address */
434
435 buf_set_u32(reg_params[0].value, 0, 32, FLASHCTRL0_CONFIG_ALL);
436 buf_set_u32(reg_params[1].value, 0, 32, count);
437 buf_set_u32(reg_params[2].value, 0, 32, source->address);
438 buf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);
439 buf_set_u32(reg_params[4].value, 0, 32, address);
440
441 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
442 armv7m_info.core_mode = ARM_MODE_THREAD;
443
444 ret = target_run_flash_async_algorithm(target, buf, count, 2, 0, NULL, 5,
445 reg_params, source->address, source->size, write_algorithm->address,
446 0, &armv7m_info);
447
448 if (ret == ERROR_FLASH_OPERATION_FAILED) {
449 LOG_ERROR("flash write failed at address 0x%"PRIx32,
450 buf_get_u32(reg_params[4].value, 0, 32));
451 }
452
453 target_free_working_area(target, source);
454 target_free_working_area(target, write_algorithm);
455
456 destroy_reg_param(&reg_params[0]);
457 destroy_reg_param(&reg_params[1]);
458 destroy_reg_param(&reg_params[2]);
459 destroy_reg_param(&reg_params[3]);
460 destroy_reg_param(&reg_params[4]);
461
462 return ret;
463 }
464
465 static int sim3x_flash_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
466 {
467 int ret;
468 struct target *target;
469 struct sim3x_info *sim3x_info;
470 uint8_t *new_buffer = NULL;
471
472 target = bank->target;
473
474 /* Check if target is halted */
475 if (target->state != TARGET_HALTED) {
476 LOG_ERROR("Target not halted");
477 return ERROR_TARGET_NOT_HALTED;
478 }
479
480 sim3x_info = bank->driver_priv;
481
482 if (sim3x_info->flash_locked) {
483 LOG_ERROR("Flash is locked");
484 return ERROR_FAIL;
485 }
486
487 /* Init MCU after reset */
488 if (sim3x_info->need_init) {
489 ret = sim3x_init(bank);
490 if (ret != ERROR_OK)
491 return ret;
492 }
493
494 if (offset & 0x1) {
495 LOG_ERROR("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
496 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
497 }
498
499 if (count & 0x1) {
500 uint32_t old_count = count;
501 count++;
502 new_buffer = malloc(count);
503
504 if (!new_buffer) {
505 LOG_ERROR("odd number of bytes to write and no memory "
506 "for padding buffer");
507 return ERROR_FAIL;
508 }
509 LOG_INFO("odd number of bytes to write (%" PRIu32 "), extending to %" PRIu32
510 " and padding with 0xff", old_count, count);
511
512 new_buffer[count - 1] = 0xff;
513 buffer = memcpy(new_buffer, buffer, old_count);
514 }
515
516 ret = sim3x_write_block(bank, buffer, offset, count / 2);
517 free(new_buffer);
518 return ret;
519 }
520
521 static int sim3x_flash_lock_check(struct flash_bank *bank)
522 {
523 int ret;
524 uint32_t lock_word;
525 struct sim3x_info *sim3x_info;
526
527 ret = target_read_u32(bank->target, LOCK_WORD_ADDRESS, &lock_word);
528 if (ret != ERROR_OK) {
529 LOG_ERROR("Can not read Lock Word");
530 return ret;
531 }
532
533 sim3x_info = bank->driver_priv;
534 sim3x_info->flash_locked = (lock_word != 0xFFFFFFFF);
535
536 return ERROR_OK;
537 }
538
539 static int sim3x_flash_protect_check(struct flash_bank *bank)
540 {
541 int ret;
542 struct sim3x_info *sim3x_info;
543
544 /* Check if target is halted */
545 if (bank->target->state != TARGET_HALTED) {
546 LOG_ERROR("Target not halted");
547 return ERROR_TARGET_NOT_HALTED;
548 }
549
550 ret = sim3x_flash_lock_check(bank);
551 if (ret != ERROR_OK)
552 return ret;
553
554 sim3x_info = bank->driver_priv;
555
556 for (unsigned int i = 0; i < bank->num_sectors; i++)
557 bank->sectors[i].is_protected = sim3x_info->flash_locked;
558
559 return ERROR_OK;
560 }
561
562 static int sim3x_flash_protect(struct flash_bank *bank, int set,
563 unsigned int first, unsigned int last)
564 {
565 int ret;
566 uint8_t lock_word[4];
567 struct sim3x_info *sim3x_info;
568 struct target *target;
569
570 target = bank->target;
571
572 /* Check if target is halted */
573 if (target->state != TARGET_HALTED) {
574 LOG_ERROR("Target not halted");
575 return ERROR_TARGET_NOT_HALTED;
576 }
577
578 if (first != 0 || last != bank->num_sectors - 1) {
579 LOG_ERROR("Flash does not support finer granularity");
580 return ERROR_FAIL;
581 }
582
583 sim3x_info = bank->driver_priv;
584
585 if (set) {
586 if (sim3x_info->flash_locked) {
587 LOG_INFO("Flash is already locked");
588 return ERROR_OK;
589 }
590
591 /* Lock Flash */
592 target_buffer_set_u32(target, lock_word, 0xFFFFFFFE);
593 ret = sim3x_flash_write(bank, lock_word, LOCK_WORD_ADDRESS, 4);
594 if (ret != ERROR_OK)
595 return ret;
596
597 } else {
598 /* Flash is unlocked by an erase operation */
599 ret = sim3x_flash_erase(bank, 0, 0);
600 if (ret != ERROR_OK)
601 return ret;
602 }
603
604 ret = sim3x_flash_protect_check(bank);
605 if (ret != ERROR_OK)
606 return ret;
607
608 if (set) {
609 if (sim3x_info->flash_locked) {
610 LOG_INFO("Flash locked");
611 return ERROR_OK;
612 } else {
613 LOG_ERROR("Flash lock error");
614 return ERROR_FAIL;
615 }
616 } else {
617 if (sim3x_info->flash_locked) {
618 LOG_ERROR("Flash unlock error");
619 return ERROR_FAIL;
620 } else {
621 LOG_INFO("Flash unlocked");
622 return ERROR_OK;
623 }
624 }
625 }
626
627 static int sim3x_read_deviceid(struct flash_bank *bank)
628 {
629 int ret;
630 struct sim3x_info *sim3x_info;
631
632 uint32_t device_id;
633 int part_number;
634 char part_num_string[4];
635
636 sim3x_info = bank->driver_priv;
637
638 /* MCU check */
639 ret = target_read_u32(bank->target, DEVICEID0_DEVICEID2, &device_id);
640 if (ret != ERROR_OK)
641 return ret;
642
643 /* Device ID should be 'M3' */
644 if (device_id != 0x00004D33)
645 return ERROR_FAIL;
646
647 /* Family and Part number */
648 ret = target_read_u32(bank->target, DEVICEID0_DEVICEID1, &device_id);
649 if (ret != ERROR_OK)
650 return ret;
651
652 part_num_string[0] = device_id >> 16;
653 part_num_string[1] = device_id >> 8;
654 part_num_string[2] = device_id;
655 part_num_string[3] = 0;
656
657 part_number = atoi(part_num_string);
658
659 /* Part Number should be between 100 and 999 */
660 if (!isalpha(device_id >> 24) || part_number < 100 || part_number > 999)
661 return ERROR_FAIL;
662
663 sim3x_info->part_family = device_id >> 24;
664 sim3x_info->part_number = part_number;
665
666 /* Package and Revision */
667 ret = target_read_u32(bank->target, DEVICEID0_DEVICEID0, &device_id);
668 if (ret != ERROR_OK)
669 return ret;
670
671 sim3x_info->device_package[0] = device_id >> 24;
672 sim3x_info->device_package[1] = device_id >> 16;
673 sim3x_info->device_package[2] = device_id >> 8;
674 sim3x_info->device_package[3] = 0;
675
676 sim3x_info->device_revision = device_id;
677
678 return ERROR_OK;
679 }
680
681 static int sim3x_parse_part_info(struct sim3x_info *sim3x_info)
682 {
683 switch (sim3x_info->part_number) {
684 case 134:
685 case 136:
686 sim3x_info->flash_size_kb = 32;
687 break;
688 case 144:
689 case 146:
690 sim3x_info->flash_size_kb = 64;
691 break;
692 case 154:
693 case 156:
694 case 157:
695 sim3x_info->flash_size_kb = 128;
696 break;
697 case 164:
698 case 166:
699 case 167:
700 sim3x_info->flash_size_kb = 256;
701 break;
702 default:
703 LOG_ERROR("Unknown Part number %d", sim3x_info->part_number);
704 sim3x_info->part_number = 0;
705 return ERROR_FAIL;
706 }
707
708 switch (sim3x_info->part_family) {
709 case 'c':
710 case 'C':
711 LOG_INFO("SiM3C%d detected", sim3x_info->part_number);
712 break;
713 case 'u':
714 case 'U':
715 LOG_INFO("SiM3U%d detected", sim3x_info->part_number);
716 break;
717 case 'l':
718 case 'L':
719 LOG_INFO("SiM3L%d detected", sim3x_info->part_number);
720 break;
721 default:
722 LOG_ERROR("Unsupported MCU family %c", sim3x_info->part_family);
723 sim3x_info->part_family = 0;
724 return ERROR_FAIL;
725 }
726
727 return ERROR_OK;
728 }
729
730 static int sim3x_read_info(struct flash_bank *bank)
731 {
732 int ret;
733 struct sim3x_info *sim3x_info;
734 uint32_t cpuid;
735
736 sim3x_info = bank->driver_priv;
737
738 /* Core check */
739 ret = target_read_u32(bank->target, CPUID, &cpuid);
740 if (ret != ERROR_OK) {
741 LOG_ERROR("Failed to read CPU ID");
742 return ret;
743 }
744
745 if (((cpuid >> 4) & 0xfff) != 0xc23) {
746 LOG_ERROR("Target is not Cortex-M3");
747 return ERROR_FAIL;
748 }
749
750 /* Read info from chip */
751 ret = sim3x_read_deviceid(bank);
752 if (ret == ERROR_OK) {
753 ret = sim3x_parse_part_info(sim3x_info);
754 if (ret != ERROR_OK) {
755 LOG_ERROR("Failed to parse info from MCU");
756 return ERROR_FAIL;
757 }
758 } else {
759 LOG_WARNING("Failed to read info from MCU, using info from flash bank parameters");
760
761 /* Check if flash size is given in flash bank command */
762 if (!bank->size) {
763 LOG_ERROR("Flash size not set in the flash bank command");
764 return ERROR_FAIL;
765 }
766
767 /* Convert bank size to kb */
768 sim3x_info->flash_size_kb = bank->size / 1024;
769 }
770
771 LOG_INFO("Flash size = %dKB", sim3x_info->flash_size_kb);
772
773 return ERROR_OK;
774 }
775
776 static int sim3x_probe(struct flash_bank *bank)
777 {
778 int ret, i;
779 struct sim3x_info *sim3x_info;
780
781 sim3x_info = bank->driver_priv;
782 sim3x_info->probed = false;
783 sim3x_info->need_init = true;
784
785 /* Read info from chip */
786 ret = sim3x_read_info(bank);
787 if (ret != ERROR_OK)
788 return ret;
789
790 ret = sim3x_flash_lock_check(bank);
791 if (ret != ERROR_OK)
792 return ret;
793
794 free(bank->sectors);
795
796 bank->base = FLASH_BASE_ADDRESS;
797 bank->size = sim3x_info->flash_size_kb * SIM3X_FLASH_PAGE_SIZE;
798 bank->num_sectors = SIM3X_FLASH_PAGE_SIZE;
799 bank->sectors = malloc(sizeof(struct flash_sector) * sim3x_info->flash_size_kb);
800
801 for (i = 0; i < sim3x_info->flash_size_kb; i++) {
802 bank->sectors[i].offset = i * SIM3X_FLASH_PAGE_SIZE;
803 bank->sectors[i].size = SIM3X_FLASH_PAGE_SIZE;
804 bank->sectors[i].is_erased = -1;
805 bank->sectors[i].is_protected = sim3x_info->flash_locked;
806 }
807
808 sim3x_info->probed = true;
809
810 return ERROR_OK;
811 }
812
813 static int sim3x_auto_probe(struct flash_bank *bank)
814 {
815 struct sim3x_info *sim3x_info;
816
817 sim3x_info = bank->driver_priv;
818
819 if (sim3x_info->probed) {
820 sim3x_info->need_init = true;
821 return ERROR_OK;
822 } else {
823 return sim3x_probe(bank);
824 }
825 }
826
827 static int sim3x_flash_info(struct flash_bank *bank, struct command_invocation *cmd)
828 {
829 struct sim3x_info *sim3x_info;
830
831 sim3x_info = bank->driver_priv;
832
833 /* Read info about chip */
834 int ret = sim3x_read_info(bank);
835 if (ret != ERROR_OK)
836 return ret;
837
838 /* Part */
839 if (sim3x_info->part_family && sim3x_info->part_number) {
840 command_print_sameline(cmd, "SiM3%c%d", sim3x_info->part_family, sim3x_info->part_number);
841
842 /* Revision */
843 if (sim3x_info->device_revision && sim3x_info->device_revision <= 'Z' - 'A') {
844 command_print_sameline(cmd, "-%c", sim3x_info->device_revision + 'A');
845
846 /* Package */
847 command_print_sameline(cmd, "-G%s", sim3x_info->device_package);
848 }
849 }
850
851 /* Print flash size */
852 command_print_sameline(cmd, " flash_size = %dKB", sim3x_info->flash_size_kb);
853
854 return ERROR_OK;
855 }
856 /**
857 * reg 31:8 - no effect
858 * reg 7:4 - bank
859 * reg 3:2 - register
860 * reg 1:0 - no effect
861 */
862 static int ap_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)
863 {
864 LOG_DEBUG("DAP_REG[0x%02x] <- %08" PRIX32, reg, value);
865
866 struct adiv5_ap *ap = dap_get_ap(dap, SIM3X_AP);
867 if (!ap) {
868 LOG_DEBUG("DAP: failed to get AP");
869 return ERROR_FAIL;
870 }
871
872 int retval = dap_queue_ap_write(ap, reg, value);
873 if (retval != ERROR_OK) {
874 LOG_DEBUG("DAP: failed to queue a write request");
875 dap_put_ap(ap);
876 return retval;
877 }
878
879 retval = dap_run(dap);
880 dap_put_ap(ap);
881 if (retval != ERROR_OK) {
882 LOG_DEBUG("DAP: dap_run failed");
883 return retval;
884 }
885
886 return ERROR_OK;
887 }
888
889 static int ap_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)
890 {
891 struct adiv5_ap *ap = dap_get_ap(dap, SIM3X_AP);
892 if (!ap) {
893 LOG_DEBUG("DAP: failed to get AP");
894 return ERROR_FAIL;
895 }
896
897 int retval = dap_queue_ap_read(ap, reg, result);
898 if (retval != ERROR_OK) {
899 LOG_DEBUG("DAP: failed to queue a read request");
900 dap_put_ap(ap);
901 return retval;
902 }
903
904 retval = dap_run(dap);
905 dap_put_ap(ap);
906 if (retval != ERROR_OK) {
907 LOG_DEBUG("DAP: dap_run failed");
908 return retval;
909 }
910
911 LOG_DEBUG("DAP_REG[0x%02x]: %08" PRIX32, reg, *result);
912 return ERROR_OK;
913 }
914
915 static int ap_poll_register(struct adiv5_dap *dap, unsigned reg, uint32_t mask, uint32_t value, int timeout)
916 {
917 uint32_t val;
918 int retval;
919
920 do {
921 retval = ap_read_register(dap, reg, &val);
922 if (retval != ERROR_OK || (val & mask) == value)
923 return retval;
924
925 alive_sleep(1);
926 } while (timeout--);
927
928 LOG_DEBUG("DAP: polling timed out");
929 return ERROR_FAIL;
930 }
931
932 COMMAND_HANDLER(sim3x_mass_erase)
933 {
934 uint32_t val;
935 int ret;
936
937 struct target *target = get_current_target(CMD_CTX);
938 struct cortex_m_common *cortex_m = target_to_cm(target);
939 struct adiv5_dap *dap = cortex_m->armv7m.arm.dap;
940
941 if (!dap) {
942 /* Used debug interface doesn't support direct DAP access */
943 LOG_ERROR("mass_erase can't be used by this debug interface");
944 return ERROR_FAIL;
945 }
946
947 ret = ap_read_register(dap, SIM3X_AP_ID, &val);
948 if (ret != ERROR_OK)
949 return ret;
950
951 if (val != SIM3X_AP_ID_VALUE) {
952 LOG_ERROR("Wrong SIM3X_AP_ID");
953 return ERROR_FAIL;
954 }
955
956 /* Mass erase sequence */
957 ret = ap_write_register(dap, SIM3X_AP_CTRL1, SIM3X_AP_CTRL1_RESET_REQ);
958 if (ret != ERROR_OK)
959 return ret;
960
961 ret = ap_write_register(dap, SIM3X_AP_CTRL1, SIM3X_AP_CTRL1_RESET_REQ | SIM3X_AP_CTRL1_MASS_ERASE_REQ);
962 if (ret != ERROR_OK)
963 return ret;
964
965 ret = ap_poll_register(dap, SIM3X_AP_CTRL1, SIM3X_AP_CTRL1_MASS_ERASE_REQ, 0x00000000, FLASH_BUSY_TIMEOUT);
966 if (ret != ERROR_OK)
967 return ret;
968
969 ret = ap_write_register(dap, SIM3X_AP_CTRL1, 0x00000000); /* clear SIM3X_AP_CTRL1_RESET_REQ */
970 if (ret != ERROR_OK)
971 return ret;
972
973 LOG_INFO("Mass erase success");
974 return ERROR_OK;
975 }
976
977 COMMAND_HANDLER(sim3x_lock)
978 {
979 uint32_t val;
980 int ret;
981
982 struct target *target = get_current_target(CMD_CTX);
983 struct cortex_m_common *cortex_m = target_to_cm(target);
984 struct adiv5_dap *dap = cortex_m->armv7m.arm.dap;
985
986 if (!dap) {
987 /* Used debug interface doesn't support direct DAP access */
988 LOG_INFO("Target can't be unlocked by this debug interface");
989
990 /* Core check */
991 ret = target_read_u32(target, CPUID, &val);
992 if (ret != ERROR_OK)
993 return ret;
994
995 if ((val & CPUID_CHECK_VALUE_MASK) != CPUID_CHECK_VALUE) {
996 LOG_ERROR("Target is not ARM Cortex-M3 or is already locked");
997 return ERROR_FAIL;
998 }
999 } else {
1000 /* check SIM3X_AP_ID */
1001 ret = ap_read_register(dap, SIM3X_AP_ID, &val);
1002 if (ret != ERROR_OK)
1003 return ret;
1004
1005 if (val != SIM3X_AP_ID_VALUE) {
1006 LOG_ERROR("Wrong SIM3X_AP_ID");
1007 return ERROR_FAIL;
1008 }
1009
1010 /* check if locked */
1011 ret = target_read_u32(target, CPUID, &val);
1012 /* if correct value is read, then it will continue */
1013 if (ret != ERROR_OK || (val & CPUID_CHECK_VALUE_MASK) != CPUID_CHECK_VALUE) {
1014 /* if correct value isn't read, then it will check SIM3X_AP_INIT_STAT register */
1015 ret = ap_read_register(dap, SIM3X_AP_INIT_STAT, &val);
1016 if (ret != ERROR_OK)
1017 return ret;
1018
1019 if (val & SIM3X_AP_INIT_STAT_LOCK) {
1020 LOG_INFO("Target is already locked");
1021 return ERROR_OK;
1022 } else {
1023 LOG_ERROR("Target doesn't seem to be locked but memory was not read correct");
1024 return ERROR_FAIL;
1025 }
1026 }
1027 }
1028
1029 ret = target_read_u32(target, LOCK_WORD_ADDRESS, &val);
1030 if (ret != ERROR_OK)
1031 return ret;
1032
1033 if (val == LOCK_WORD_MCU_UNLOCKED) {
1034 /* Lock Flash */
1035 uint8_t lock_word[4];
1036 target_buffer_set_u32(target, lock_word, 0xFFFFFFFE);
1037
1038 /* Get Flash Bank */
1039 struct flash_bank *bank;
1040 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
1041 if (retval != ERROR_OK)
1042 return retval;
1043
1044 ret = sim3x_flash_write(bank, lock_word, LOCK_WORD_ADDRESS, 4);
1045 if (ret != ERROR_OK)
1046 return ret;
1047
1048 LOG_INFO("Target is successfully locked");
1049 return ERROR_OK;
1050 } else if (val == LOCK_WORD_MCU_UNLOCKED_BY_FIRMWARE) {
1051 /* Can't by locked again without erase, because LOCK_WORD is in FLASH */
1052 LOG_ERROR("Target is unlocked by firmware and can't by locked again without the lock page erase or mass erase");
1053 return ERROR_FAIL;
1054 } else {
1055 LOG_ERROR("Unexpected lock word value");
1056
1057 /* SIM3X_AP_ID_VALUE is not checked */
1058 if (!dap)
1059 LOG_INFO("Maybe this isn't a SiM3x MCU");
1060
1061 return ERROR_FAIL;
1062 }
1063 }
1064
1065 static const struct command_registration sim3x_exec_command_handlers[] = {
1066 {
1067 .name = "mass_erase",
1068 .mode = COMMAND_EXEC,
1069 .help = "Erase the complete flash",
1070 .usage = "",
1071 .handler = sim3x_mass_erase,
1072 },
1073 {
1074 .name = "lock",
1075 .mode = COMMAND_EXEC,
1076 .help = "Locks the flash. Unlock by mass erase",
1077 .usage = "",
1078 .handler = sim3x_lock,
1079 },
1080 COMMAND_REGISTRATION_DONE
1081 };
1082
1083 static const struct command_registration sim3x_command_handlers[] = {
1084 {
1085 .name = "sim3x",
1086 .mode = COMMAND_ANY,
1087 .help = "sim3x flash command group",
1088 .usage = "",
1089 .chain = sim3x_exec_command_handlers,
1090 },
1091 COMMAND_REGISTRATION_DONE
1092 };
1093
1094 const struct flash_driver sim3x_flash = {
1095 .name = "sim3x",
1096 .commands = sim3x_command_handlers,
1097 .flash_bank_command = sim3x_flash_bank_command,
1098 .erase = sim3x_flash_erase,
1099 .protect = sim3x_flash_protect,
1100 .write = sim3x_flash_write,
1101 .read = default_flash_read,
1102 .probe = sim3x_probe,
1103 .auto_probe = sim3x_auto_probe,
1104 .erase_check = default_flash_blank_check,
1105 .protect_check = sim3x_flash_protect_check,
1106 .info = sim3x_flash_info,
1107 .free_driver_priv = default_flash_free_driver_priv,
1108 };

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)