1 /***************************************************************************
2 * Copyright (C) 2014 by Ladislav Bábel *
3 * ladababel@seznam.cz *
5 * Copyright (C) 2015 by Andreas Bomholtz *
6 * andreas@seluxit.com *
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. *
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 ***************************************************************************/
24 #include <helper/binarybuffer.h>
25 #include <helper/time_support.h>
26 #include <target/algorithm.h>
27 #include <target/cortex_m.h>
30 #define DEVICEID0_DEVICEID0 (0x400490C0)
31 #define DEVICEID0_DEVICEID1 (0x400490D0)
32 #define DEVICEID0_DEVICEID2 (0x400490E0)
33 #define DEVICEID0_DEVICEID3 (0x400490F0)
36 #define CPUID_CHECK_VALUE (0x410FC230)
37 #define CPUID_CHECK_VALUE_MASK (0xFF0FFFF0)
40 #define FLASH_BASE_ADDRESS (0x00000000)
41 #define LOCK_WORD_ADDRESS (0x0003FFFC)
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)
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)
54 #define FLASHCTRL0_WRADDR (0x4002E0A0)
55 #define FLASHCTRL0_WRDATA (0x4002E0B0)
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)
63 #define FLASH_BUSY_TIMEOUT (100)
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)
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)
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)
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)
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)
96 #define WDTIMER0_THRESHOLD (0x40030020)
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)
107 #define SIM3X_AP (0x0A)
109 #define SIM3X_AP_CTRL1 (0x00)
110 #define SIM3X_AP_CTRL2 (0x04)
111 #define SIM3X_AP_LOCK (0x08)
112 #define SIM3X_AP_CRC (0x0C)
114 #define SIM3X_AP_INIT_STAT (0x10)
115 #define SIM3X_AP_DAP_IN (0x14)
116 #define SIM3X_AP_DAP_OUT (0x18)
118 #define SIM3X_AP_ID (0xFC)
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)
128 #define SIM3X_FLASH_PAGE_SIZE 1024
131 uint16_t flash_size_kb
;
132 uint16_t part_number
;
134 uint8_t device_revision
;
135 char device_package
[4];
141 /* flash bank sim3x 0 0 0 0 <target#> */
142 FLASH_BANK_COMMAND_HANDLER(sim3x_flash_bank_command
)
144 struct sim3x_info
*sim3x_info
;
147 return ERROR_COMMAND_SYNTAX_ERROR
;
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
;
160 static int sim3x_init(struct flash_bank
*bank
)
163 struct target
*target
;
164 struct sim3x_info
*sim3x_info
;
166 target
= bank
->target
;
168 /* Disable watchdog timer */
169 ret
= target_write_u32(target
, WDTIMER0_WDTKEY
, WDTIMER0_KEY_ATTN
);
173 ret
= target_write_u32(target
, WDTIMER0_WDTKEY
, WDTIMER0_KEY_DISABLE
);
177 /* Enable one write command */
178 ret
= target_write_u32(target
, WDTIMER0_WDTKEY
, WDTIMER0_KEY_ATTN
);
182 ret
= target_write_u32(target
, WDTIMER0_WDTKEY
, WDTIMER0_KEY_WRITE
);
186 /* Watchdog Timer Debug Mode */
187 ret
= target_write_u32(target
, WDTIMER0_CONTROL_SET
,
188 WDTIMER0_CONTROL_DBGMD_MASK
);
192 /* Enable VDD Supply Monitor */
193 ret
= target_write_u32(target
, VMON0_CONTROL_SET
,
194 VMON0_CONTROL_VMONEN_MASK
);
198 /* Set VDD Supply Monitor as a reset source */
199 ret
= target_write_u32(target
, RSTSRC0_RESETEN_SET
,
200 RSTSRC0_RESETEN_VMONREN_MASK
);
204 /* Flash Controller Clock Enable */
205 ret
= target_write_u32(target
, CLKCTRL0_APBCLKG0_SET
,
206 CLKCTRL0_APBCLKG0_FLCTRLCEN_MASK
);
210 /* Disable Flash Erase Mode */
211 ret
= target_write_u32(target
, FLASHCTRL0_CONFIG_CLR
,
212 FLASHCTRL0_CONFIG_ERASEEN_MASK
);
216 sim3x_info
= bank
->driver_priv
;
217 sim3x_info
->need_init
= 0;
221 static int sim3x_erase_page(struct flash_bank
*bank
, uint32_t addr
)
225 struct target
*target
;
227 target
= bank
->target
;
229 for (i
= 0; i
< FLASH_BUSY_TIMEOUT
; i
++) {
230 ret
= target_read_u32(target
, FLASHCTRL0_CONFIG_ALL
, &temp
);
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
);
245 /* Write the address of the Flash page to WRADDR */
246 ret
= target_write_u32(target
, FLASHCTRL0_WRADDR
, addr
);
250 /* Write the inital unlock value to KEY */
251 ret
= target_write_u32(target
, FLASHCTRL0_KEY
,
252 FLASHCTRL0_KEY_INITIAL_UNLOCK
);
256 /* Write the single unlock value to KEY */
257 ret
= target_write_u32(target
, FLASHCTRL0_KEY
,
258 FLASHCTRL0_KEY_SINGLE_UNLOCK
);
262 /* Write any value to WRDATA to initiate the page erase */
263 ret
= target_write_u32(target
, FLASHCTRL0_WRDATA
, 0);
273 LOG_ERROR("timed out waiting for FLASHCTRL0_CONFIG_BUSYF");
277 static int sim3x_flash_erase(struct flash_bank
*bank
, int first
, int last
)
281 struct sim3x_info
*sim3x_info
;
282 struct target
*target
;
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
;
290 sim3x_info
= bank
->driver_priv
;
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");
302 for (i
= first
; i
<= last
; i
++) {
303 ret
= sim3x_erase_page(bank
, bank
->sectors
[i
].offset
);
308 target
= bank
->target
;
310 /* Wait until busy */
311 for (i
= 0; i
< FLASH_BUSY_TIMEOUT
; i
++) {
312 ret
= target_read_u32(target
, FLASHCTRL0_CONFIG_ALL
, &temp
);
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
);
331 LOG_ERROR("timed out waiting for FLASHCTRL0_CONFIG_BUSYF");
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)! */
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
;
347 /* see contrib/loaders/flash/sim3x.s for src */
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] */
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] */
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 */
366 /* wait for BUSYF flag */
368 0x06, 0x68, /* ldr r6, [r0, #FLASHCTRL_CONFIG] */
369 0x16, 0xF4, 0x80, 0x1F, /* tst r6, #BUSYF */
370 0xFB, 0xD1, /* bne wait_busy1 */
372 /* Write the destination address to WRADDR */
373 0xC0, 0xF8, 0xA0, 0x40, /* str r4, [r0, #FLASHCTRL_WRADDR] */
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] */
379 0x02, 0x35, /* adds r5, #2 */
380 0x02, 0x34, /* adds r4, #2 */
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 */
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 */
396 0x5A, 0x26, /* movs r6, #MULTIPLE_LOCK */
397 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */
399 /* wait for BUSYF flag */
401 0x06, 0x68, /* ldr r6, [r0, #FLASHCTRL_CONFIG] */
402 0x16, 0xF4, 0x80, 0x1F, /* tst r6, #BUSYF */
403 0xFB, 0xD1, /* bne wait_busy2 */
405 0x00, 0xBE /* bkpt #0 */
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
;
415 ret
= target_write_buffer(target
, write_algorithm
->address
,
416 sizeof(sim3x_flash_write_code
), sim3x_flash_write_code
);
421 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
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
428 target_free_working_area(target
, write_algorithm
);
430 LOG_WARNING("no large enough working area available, can't do block memory writes");
431 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
435 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* flash base */
436 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* count */
437 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* buffer start */
438 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* buffer end */
439 init_reg_param(®_params
[4], "r4", 32, PARAM_IN_OUT
); /* target address */
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
);
447 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
448 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
450 ret
= target_run_flash_async_algorithm(target
, buf
, count
, 2, 0, NULL
, 5,
451 reg_params
, source
->address
, source
->size
, write_algorithm
->address
,
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));
459 target_free_working_area(target
, source
);
460 target_free_working_area(target
, write_algorithm
);
462 destroy_reg_param(®_params
[0]);
463 destroy_reg_param(®_params
[1]);
464 destroy_reg_param(®_params
[2]);
465 destroy_reg_param(®_params
[3]);
466 destroy_reg_param(®_params
[4]);
471 static int sim3x_flash_write(struct flash_bank
*bank
, const uint8_t * buffer
, uint32_t offset
, uint32_t count
)
474 struct target
*target
;
475 struct sim3x_info
*sim3x_info
;
476 uint8_t *new_buffer
= NULL
;
478 target
= bank
->target
;
480 /* Check if target is halted */
481 if (target
->state
!= TARGET_HALTED
) {
482 LOG_ERROR("Target not halted");
483 return ERROR_TARGET_NOT_HALTED
;
486 sim3x_info
= bank
->driver_priv
;
488 if (sim3x_info
->flash_locked
) {
489 LOG_ERROR("Falsh is locked");
493 /* Init MCU after reset */
494 if (sim3x_info
->need_init
) {
495 ret
= sim3x_init(bank
);
501 LOG_ERROR("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
502 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
506 uint32_t old_count
= count
;
508 new_buffer
= malloc(count
);
510 if (new_buffer
== NULL
) {
511 LOG_ERROR("odd number of bytes to write and no memory "
512 "for padding buffer");
515 LOG_INFO("odd number of bytes to write (%d), extending to %d "
516 "and padding with 0xff", old_count
, count
);
518 new_buffer
[count
- 1] = 0xff;
519 buffer
= memcpy(new_buffer
, buffer
, old_count
);
522 ret
= sim3x_write_block(bank
, buffer
, offset
, count
/ 2);
527 static int sim3x_flash_lock_check(struct flash_bank
*bank
)
531 struct sim3x_info
*sim3x_info
;
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");
539 sim3x_info
= bank
->driver_priv
;
540 sim3x_info
->flash_locked
= (lock_word
!= 0xFFFFFFFF);
545 static int sim3x_flash_protect_check(struct flash_bank
*bank
)
548 struct sim3x_info
*sim3x_info
;
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
;
556 ret
= sim3x_flash_lock_check(bank
);
560 sim3x_info
= bank
->driver_priv
;
562 for (i
= 0; i
< bank
->num_sectors
; i
++)
563 bank
->sectors
[i
].is_protected
= sim3x_info
->flash_locked
;
568 static int sim3x_flash_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
571 uint8_t lock_word
[4];
572 struct sim3x_info
*sim3x_info
;
573 struct target
*target
;
575 target
= bank
->target
;
577 /* Check if target is halted */
578 if (target
->state
!= TARGET_HALTED
) {
579 LOG_ERROR("Target not halted");
580 return ERROR_TARGET_NOT_HALTED
;
583 if (first
!= 0 || last
!= bank
->num_sectors
- 1) {
584 LOG_ERROR("Flash does not support finer granularity");
588 sim3x_info
= bank
->driver_priv
;
591 if (sim3x_info
->flash_locked
) {
592 LOG_INFO("Flash is already locked");
597 target_buffer_set_u32(target
, lock_word
, 0xFFFFFFFE);
598 ret
= sim3x_flash_write(bank
, lock_word
, LOCK_WORD_ADDRESS
, 4);
603 /* Flash is unlocked by an erase operation */
604 ret
= sim3x_flash_erase(bank
, 0, 0);
609 ret
= sim3x_flash_protect_check(bank
);
614 if (sim3x_info
->flash_locked
) {
615 LOG_INFO("Flash locked");
618 LOG_ERROR("Flash lock error");
622 if (sim3x_info
->flash_locked
) {
623 LOG_ERROR("Flash unlock error");
626 LOG_INFO("Flash unlocked");
632 static int sim3x_read_deviceid(struct flash_bank
*bank
)
635 struct sim3x_info
*sim3x_info
;
639 char part_num_string
[4];
641 sim3x_info
= bank
->driver_priv
;
644 ret
= target_read_u32(bank
->target
, DEVICEID0_DEVICEID2
, &device_id
);
648 /* Device ID should be 'M3' */
649 if (device_id
!= 0x00004D33)
652 /* Family and Part number */
653 ret
= target_read_u32(bank
->target
, DEVICEID0_DEVICEID1
, &device_id
);
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;
662 part_number
= atoi(part_num_string
);
664 /* Part Number should be between 100 and 999 */
665 if (!isalpha(device_id
>> 24) || part_number
< 100 || part_number
> 999)
668 sim3x_info
->part_family
= device_id
>> 24;
669 sim3x_info
->part_number
= part_number
;
671 /* Package and Revision */
672 ret
= target_read_u32(bank
->target
, DEVICEID0_DEVICEID0
, &device_id
);
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;
681 sim3x_info
->device_revision
= device_id
;
686 static int sim3x_parse_part_info(struct sim3x_info
*sim3x_info
)
688 switch (sim3x_info
->part_number
) {
691 sim3x_info
->flash_size_kb
= 32;
695 sim3x_info
->flash_size_kb
= 64;
700 sim3x_info
->flash_size_kb
= 128;
705 sim3x_info
->flash_size_kb
= 256;
708 LOG_ERROR("Unknown Part number %d", sim3x_info
->part_number
);
709 sim3x_info
->part_number
= 0;
713 switch (sim3x_info
->part_family
) {
716 LOG_INFO("SiM3C%d detected", sim3x_info
->part_number
);
720 LOG_INFO("SiM3U%d detected", sim3x_info
->part_number
);
724 LOG_INFO("SiM3L%d detected", sim3x_info
->part_number
);
727 LOG_ERROR("Unsupported MCU family %c", sim3x_info
->part_family
);
728 sim3x_info
->part_family
= 0;
735 static int sim3x_read_info(struct flash_bank
*bank
)
738 struct sim3x_info
*sim3x_info
;
741 sim3x_info
= bank
->driver_priv
;
744 ret
= target_read_u32(bank
->target
, CPUID
, &cpuid
);
745 if (ret
!= ERROR_OK
) {
746 LOG_ERROR("Failed to read CPU ID");
750 if (((cpuid
>> 4) & 0xfff) != 0xc23) {
751 LOG_ERROR("Target is not CortexM3");
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");
764 LOG_WARNING("Failed to read info from MCU, using info from flash bank parameters");
766 /* Check if flash size is given in flash bank command */
768 LOG_ERROR("Flash size not set in the flash bank command");
772 /* Convert bank size to kb */
773 sim3x_info
->flash_size_kb
= bank
->size
/ 1024;
776 LOG_INFO("Flash size = %dKB", sim3x_info
->flash_size_kb
);
781 static int sim3x_probe(struct flash_bank
*bank
)
784 struct sim3x_info
*sim3x_info
;
786 sim3x_info
= bank
->driver_priv
;
787 sim3x_info
->probed
= false;
788 sim3x_info
->need_init
= true;
790 /* Read info from chip */
791 ret
= sim3x_read_info(bank
);
795 ret
= sim3x_flash_lock_check(bank
);
801 bank
->sectors
= NULL
;
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
);
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
;
816 sim3x_info
->probed
= true;
821 static int sim3x_auto_probe(struct flash_bank
*bank
)
823 struct sim3x_info
*sim3x_info
;
825 sim3x_info
= bank
->driver_priv
;
827 if (sim3x_info
->probed
) {
828 sim3x_info
->need_init
= true;
831 return sim3x_probe(bank
);
835 static int sim3x_flash_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
839 struct sim3x_info
*sim3x_info
;
841 sim3x_info
= bank
->driver_priv
;
843 /* Read info about chip */
844 ret
= sim3x_read_info(bank
);
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
);
855 return ERROR_BUF_TOO_SMALL
;
858 if (sim3x_info
->device_revision
&& sim3x_info
->device_revision
<= 'Z' - 'A') {
859 printed
= snprintf(buf
, buf_size
, "-%c", sim3x_info
->device_revision
+ 'A');
864 return ERROR_BUF_TOO_SMALL
;
867 if (sim3x_info
->device_package
) {
868 printed
= snprintf(buf
, buf_size
, "-G%s", sim3x_info
->device_package
);
873 return ERROR_BUF_TOO_SMALL
;
878 /* Print flash size */
879 printed
= snprintf(buf
, buf_size
, " flash_size = %dKB", sim3x_info
->flash_size_kb
);
883 return ERROR_BUF_TOO_SMALL
;
888 * reg 31:8 - no effect
891 * reg 1:0 - no effect
893 static int ap_write_register(struct adiv5_dap
*dap
, unsigned reg
, uint32_t value
)
896 LOG_DEBUG("DAP_REG[0x%02x] <- %08" PRIX32
, reg
, value
);
898 retval
= dap_queue_ap_write(dap
, reg
, value
);
899 if (retval
!= ERROR_OK
) {
900 LOG_DEBUG("DAP: failed to queue a write request");
904 retval
= dap_run(dap
);
905 if (retval
!= ERROR_OK
) {
906 LOG_DEBUG("DAP: dap_run failed");
913 static int ap_read_register(struct adiv5_dap
*dap
, unsigned reg
, uint32_t *result
)
916 retval
= dap_queue_ap_read(dap
, reg
, result
);
917 if (retval
!= ERROR_OK
) {
918 LOG_DEBUG("DAP: failed to queue a read request");
922 retval
= dap_run(dap
);
923 if (retval
!= ERROR_OK
) {
924 LOG_DEBUG("DAP: dap_run failed");
928 LOG_DEBUG("DAP_REG[0x%02x]: %08" PRIX32
, reg
, *result
);
932 static int ap_poll_register(struct adiv5_dap
*dap
, unsigned reg
, uint32_t mask
, uint32_t value
, int timeout
)
938 retval
= ap_read_register(dap
, reg
, &val
);
939 if (retval
!= ERROR_OK
|| (val
& mask
) == value
)
945 LOG_DEBUG("DAP: polling timed out");
949 COMMAND_HANDLER(sim3x_mass_erase
)
954 struct target
*target
= get_current_target(CMD_CTX
);
955 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
956 struct adiv5_dap
*dap
= cortex_m
->armv7m
.arm
.dap
;
959 /* Used debug interface doesn't support direct DAP access */
960 LOG_ERROR("mass_erase can't be used by this debug interface");
964 const uint8_t origninal_ap
= dap
->ap_current
>> 24;
965 dap_ap_select(dap
, SIM3X_AP
);
967 ret
= ap_read_register(dap
, SIM3X_AP_ID
, &val
);
971 if (val
!= SIM3X_AP_ID_VALUE
) {
972 LOG_ERROR("Wrong SIM3X_AP_ID");
976 /* Mass erase sequence */
977 ret
= ap_write_register(dap
, SIM3X_AP_CTRL1
, SIM3X_AP_CTRL1_RESET_REQ
);
981 ret
= ap_write_register(dap
, SIM3X_AP_CTRL1
, SIM3X_AP_CTRL1_RESET_REQ
| SIM3X_AP_CTRL1_MASS_ERASE_REQ
);
985 ret
= ap_poll_register(dap
, SIM3X_AP_CTRL1
, SIM3X_AP_CTRL1_MASS_ERASE_REQ
, 0x00000000, FLASH_BUSY_TIMEOUT
);
989 ret
= ap_write_register(dap
, SIM3X_AP_CTRL1
, 0x00000000); /* clear SIM3X_AP_CTRL1_RESET_REQ */
993 dap_ap_select(dap
, origninal_ap
);
995 LOG_INFO("Mass erase success");
999 COMMAND_HANDLER(sim3x_lock
)
1004 struct target
*target
= get_current_target(CMD_CTX
);
1005 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1006 struct adiv5_dap
*dap
= cortex_m
->armv7m
.arm
.dap
;
1009 /* Used debug interface doesn't support direct DAP access */
1010 LOG_INFO("Target can't by unlocked by this debug interface");
1013 ret
= target_read_u32(target
, CPUID
, &val
);
1014 if (ret
!= ERROR_OK
)
1017 if ((val
& CPUID_CHECK_VALUE_MASK
) != CPUID_CHECK_VALUE
) {
1018 LOG_ERROR("Target is not ARM CortexM3 or is already locked");
1022 const uint8_t origninal_ap
= dap
->ap_current
>> 24;
1023 dap_ap_select(dap
, SIM3X_AP
);
1025 /* check SIM3X_AP_ID */
1026 ret
= ap_read_register(dap
, SIM3X_AP_ID
, &val
);
1027 if (ret
!= ERROR_OK
)
1030 if (val
!= SIM3X_AP_ID_VALUE
) {
1031 LOG_ERROR("Wrong SIM3X_AP_ID");
1035 /* check if locked */
1036 ret
= target_read_u32(target
, CPUID
, &val
);
1037 /* if correct value is read, then it will continue */
1038 if (ret
!= ERROR_OK
|| (val
& CPUID_CHECK_VALUE_MASK
) != CPUID_CHECK_VALUE
) {
1039 /* if correct value is'n read, then it will check SIM3X_AP_INIT_STAT register */
1040 ret
= ap_read_register(dap
, SIM3X_AP_INIT_STAT
, &val
);
1041 if (ret
!= ERROR_OK
)
1044 dap_ap_select(dap
, origninal_ap
);
1046 if (val
& SIM3X_AP_INIT_STAT_LOCK
) {
1047 LOG_INFO("Target is already locked");
1050 LOG_ERROR("Target doesn't seem to be locked but memory was not read correct");
1055 dap_ap_select(dap
, origninal_ap
);
1058 ret
= target_read_u32(target
, LOCK_WORD_ADDRESS
, &val
);
1059 if (ret
!= ERROR_OK
)
1062 if (val
== LOCK_WORD_MCU_UNLOCKED
) {
1064 uint8_t lock_word
[4];
1065 target_buffer_set_u32(target
, lock_word
, 0xFFFFFFFE);
1067 /* Get Flash Bank */
1068 struct flash_bank
*bank
;
1069 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1070 if (retval
!= ERROR_OK
)
1073 ret
= sim3x_flash_write(bank
, lock_word
, LOCK_WORD_ADDRESS
, 4);
1074 if (ERROR_OK
!= ret
)
1077 LOG_INFO("Target is successfully locked");
1079 } else if (val
== LOCK_WORD_MCU_UNLOCKED_BY_FIRMWARE
) {
1080 /* Can't by locked again without erase, because LOCK_WORD is in FLASH */
1081 LOG_ERROR("Target is unlocked by firmware and can't by locked again without the lock page erase or mass erase");
1084 LOG_ERROR("Unexpected lock word value");
1086 /* SIM3X_AP_ID_VALUE is not checked */
1088 LOG_INFO("Maybe this isn't a SiM3x MCU");
1094 static const struct command_registration sim3x_exec_command_handlers
[] = {
1096 .name
= "mass_erase",
1097 .mode
= COMMAND_EXEC
,
1098 .help
= "Erase the complete flash",
1100 .handler
= sim3x_mass_erase
,
1104 .mode
= COMMAND_EXEC
,
1105 .help
= "Locks the flash. Unlock by mass erase",
1107 .handler
= sim3x_lock
,
1109 COMMAND_REGISTRATION_DONE
1112 static const struct command_registration sim3x_command_handlers
[] = {
1115 .mode
= COMMAND_ANY
,
1116 .help
= "sim3x flash command group",
1118 .chain
= sim3x_exec_command_handlers
,
1120 COMMAND_REGISTRATION_DONE
1123 struct flash_driver sim3x_flash
= {
1125 .commands
= sim3x_command_handlers
,
1126 .flash_bank_command
= sim3x_flash_bank_command
,
1127 .erase
= sim3x_flash_erase
,
1128 .protect
= sim3x_flash_protect
,
1129 .write
= sim3x_flash_write
,
1130 .read
= default_flash_read
,
1131 .probe
= sim3x_probe
,
1132 .auto_probe
= sim3x_auto_probe
,
1133 .erase_check
= default_flash_blank_check
,
1134 .protect_check
= sim3x_flash_protect_check
,
1135 .info
= sim3x_flash_info
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)