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

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)