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

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)