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

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)