1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2014 by Ladislav Bábel *
5 * ladababel@seznam.cz *
7 * Copyright (C) 2015 by Andreas Bomholtz *
8 * andreas@seluxit.com *
9 ***************************************************************************/
16 #include <helper/binarybuffer.h>
17 #include <helper/time_support.h>
18 #include <target/algorithm.h>
19 #include <target/arm_adi_v5.h>
20 #include <target/cortex_m.h>
23 #define DEVICEID0_DEVICEID0 (0x400490C0)
24 #define DEVICEID0_DEVICEID1 (0x400490D0)
25 #define DEVICEID0_DEVICEID2 (0x400490E0)
26 #define DEVICEID0_DEVICEID3 (0x400490F0)
29 #define CPUID_CHECK_VALUE (0x410FC230)
30 #define CPUID_CHECK_VALUE_MASK (0xFF0FFFF0)
33 #define FLASH_BASE_ADDRESS (0x00000000)
34 #define LOCK_WORD_ADDRESS (0x0003FFFC)
36 #define LOCK_WORD_MCU_UNLOCKED (0xFFFFFFFF)
37 /* Can't by locked again without erase, because LOCK_WORD is in FLASH */
38 #define LOCK_WORD_MCU_UNLOCKED_BY_FIRMWARE (0x00000000)
40 /* SI32_FLASHCTRL_0 */
41 #define FLASHCTRL0_CONFIG_ALL (0x4002E000)
42 #define FLASHCTRL0_CONFIG_SET (0x4002E004)
43 #define FLASHCTRL0_CONFIG_CLR (0x4002E008)
44 #define FLASHCTRL0_CONFIG_ERASEEN_MASK (0x00040000)
45 #define FLASHCTRL0_CONFIG_BUSYF_MASK (0x00100000)
47 #define FLASHCTRL0_WRADDR (0x4002E0A0)
48 #define FLASHCTRL0_WRDATA (0x4002E0B0)
50 #define FLASHCTRL0_KEY (0x4002E0C0)
51 #define FLASHCTRL0_KEY_INITIAL_UNLOCK (0x000000A5)
52 #define FLASHCTRL0_KEY_SINGLE_UNLOCK (0x000000F1)
53 #define FLASHCTRL0_KEY_MULTIPLE_UNLOCK (0x000000F2)
54 #define FLASHCTRL0_KEY_MULTIPLE_LOCK (0x0000005A)
56 #define FLASH_BUSY_TIMEOUT (100)
59 #define RSTSRC0_RESETEN_ALL (0x4002D060)
60 #define RSTSRC0_RESETEN_SET (0x4002D064)
61 #define RSTSRC0_RESETEN_CLR (0x4002D068)
62 #define RSTSRC0_RESETEN_VMONREN_MASK (0x00000004)
63 #define RSTSRC0_RESETEN_SWREN_MASK (0x00000040)
66 #define VMON0_CONTROL_ALL (0x4002F000)
67 #define VMON0_CONTROL_SET (0x4002F004)
68 #define VMON0_CONTROL_CLR (0x4002F008)
69 #define VMON0_CONTROL_VMONEN_MASK (0x80000000)
72 #define CLKCTRL0_APBCLKG0_ALL (0x4002D020)
73 #define CLKCTRL0_APBCLKG0_SET (0x4002D024)
74 #define CLKCTRL0_APBCLKG0_CLR (0x4002D028)
75 #define CLKCTRL0_APBCLKG0_FLCTRLCEN_MASK (0x40000000)
78 #define WDTIMER0_CONTROL_ALL (0x40030000)
79 #define WDTIMER0_CONTROL_SET (0x40030004)
80 #define WDTIMER0_CONTROL_CLR (0x40030008)
81 #define WDTIMER0_CONTROL_DBGMD_MASK (0x00000002)
83 #define WDTIMER0_STATUS_ALL (0x40030010)
84 #define WDTIMER0_STATUS_SET (0x40030014)
85 #define WDTIMER0_STATUS_CLR (0x40030018)
86 #define WDTIMER0_STATUS_KEYSTS_MASK (0x00000001)
87 #define WDTIMER0_STATUS_PRIVSTS_MASK (0x00000002)
89 #define WDTIMER0_THRESHOLD (0x40030020)
91 #define WDTIMER0_WDTKEY (0x40030030)
92 #define WDTIMER0_KEY_ATTN (0x000000A5)
93 #define WDTIMER0_KEY_WRITE (0x000000F1)
94 #define WDTIMER0_KEY_RESET (0x000000CC)
95 #define WDTIMER0_KEY_DISABLE (0x000000DD)
96 #define WDTIMER0_KEY_START (0x000000EE)
97 #define WDTIMER0_KEY_LOCK (0x000000FF)
100 #define SIM3X_AP (0x0A)
102 #define SIM3X_AP_CTRL1 (0x00)
103 #define SIM3X_AP_CTRL2 (0x04)
104 #define SIM3X_AP_LOCK (0x08)
105 #define SIM3X_AP_CRC (0x0C)
107 #define SIM3X_AP_INIT_STAT (0x10)
108 #define SIM3X_AP_DAP_IN (0x14)
109 #define SIM3X_AP_DAP_OUT (0x18)
111 #define SIM3X_AP_ID (0xFC)
113 /* DAP register values */
114 #define SIM3X_AP_CTRL1_MASS_ERASE_REQ (0x00000001)
115 #define SIM3X_AP_CTRL1_RESET_REQ (0x00000008)
116 /* this bit is set if MCU is locked */
117 #define SIM3X_AP_INIT_STAT_LOCK (0x00000004)
118 /* expected value inside SIM3X_AP_ID */
119 #define SIM3X_AP_ID_VALUE (0x2430002)
121 #define SIM3X_FLASH_PAGE_SIZE 1024
124 uint16_t flash_size_kb
;
125 uint16_t part_number
;
127 uint8_t device_revision
;
128 char device_package
[4];
134 /* flash bank sim3x 0 0 0 0 <target#> */
135 FLASH_BANK_COMMAND_HANDLER(sim3x_flash_bank_command
)
137 struct sim3x_info
*sim3x_info
;
140 return ERROR_COMMAND_SYNTAX_ERROR
;
142 /* Init sim3x_info struct */
143 sim3x_info
= malloc(sizeof(struct sim3x_info
));
144 sim3x_info
->probed
= false;
145 sim3x_info
->need_init
= true;
146 sim3x_info
->device_revision
= 0;
147 memset(sim3x_info
->device_package
, 0, 4);
148 bank
->driver_priv
= sim3x_info
;
153 static int sim3x_init(struct flash_bank
*bank
)
156 struct target
*target
;
157 struct sim3x_info
*sim3x_info
;
159 target
= bank
->target
;
161 /* Disable watchdog timer */
162 ret
= target_write_u32(target
, WDTIMER0_WDTKEY
, WDTIMER0_KEY_ATTN
);
166 ret
= target_write_u32(target
, WDTIMER0_WDTKEY
, WDTIMER0_KEY_DISABLE
);
170 /* Enable one write command */
171 ret
= target_write_u32(target
, WDTIMER0_WDTKEY
, WDTIMER0_KEY_ATTN
);
175 ret
= target_write_u32(target
, WDTIMER0_WDTKEY
, WDTIMER0_KEY_WRITE
);
179 /* Watchdog Timer Debug Mode */
180 ret
= target_write_u32(target
, WDTIMER0_CONTROL_SET
,
181 WDTIMER0_CONTROL_DBGMD_MASK
);
185 /* Enable VDD Supply Monitor */
186 ret
= target_write_u32(target
, VMON0_CONTROL_SET
,
187 VMON0_CONTROL_VMONEN_MASK
);
191 /* Set VDD Supply Monitor as a reset source */
192 ret
= target_write_u32(target
, RSTSRC0_RESETEN_SET
,
193 RSTSRC0_RESETEN_VMONREN_MASK
);
197 /* Flash Controller Clock Enable */
198 ret
= target_write_u32(target
, CLKCTRL0_APBCLKG0_SET
,
199 CLKCTRL0_APBCLKG0_FLCTRLCEN_MASK
);
203 /* Disable Flash Erase Mode */
204 ret
= target_write_u32(target
, FLASHCTRL0_CONFIG_CLR
,
205 FLASHCTRL0_CONFIG_ERASEEN_MASK
);
209 sim3x_info
= bank
->driver_priv
;
210 sim3x_info
->need_init
= 0;
214 static int sim3x_erase_page(struct flash_bank
*bank
, uint32_t addr
)
218 struct target
*target
;
220 target
= bank
->target
;
222 for (i
= 0; i
< FLASH_BUSY_TIMEOUT
; i
++) {
223 ret
= target_read_u32(target
, FLASHCTRL0_CONFIG_ALL
, &temp
);
228 if ((temp
& FLASHCTRL0_CONFIG_BUSYF_MASK
) == 0) {
229 /* If erase is not enabled */
230 if ((temp
& FLASHCTRL0_CONFIG_ERASEEN_MASK
) == 0) {
231 /* Enter Flash Erase Mode */
232 ret
= target_write_u32(target
, FLASHCTRL0_CONFIG_SET
,
233 FLASHCTRL0_CONFIG_ERASEEN_MASK
);
238 /* Write the address of the Flash page to WRADDR */
239 ret
= target_write_u32(target
, FLASHCTRL0_WRADDR
, addr
);
243 /* Write the initial unlock value to KEY */
244 ret
= target_write_u32(target
, FLASHCTRL0_KEY
,
245 FLASHCTRL0_KEY_INITIAL_UNLOCK
);
249 /* Write the single unlock value to KEY */
250 ret
= target_write_u32(target
, FLASHCTRL0_KEY
,
251 FLASHCTRL0_KEY_SINGLE_UNLOCK
);
255 /* Write any value to WRDATA to initiate the page erase */
256 ret
= target_write_u32(target
, FLASHCTRL0_WRDATA
, 0);
266 LOG_ERROR("timed out waiting for FLASHCTRL0_CONFIG_BUSYF");
270 static int sim3x_flash_erase(struct flash_bank
*bank
, unsigned int first
,
275 struct sim3x_info
*sim3x_info
;
276 struct target
*target
;
278 /* Check if target is halted */
279 if (bank
->target
->state
!= TARGET_HALTED
) {
280 LOG_ERROR("Target not halted");
281 return ERROR_TARGET_NOT_HALTED
;
284 sim3x_info
= bank
->driver_priv
;
286 /* Init MCU after reset */
287 if (sim3x_info
->need_init
) {
288 ret
= sim3x_init(bank
);
289 if (ret
!= ERROR_OK
) {
290 LOG_ERROR("Failed to init MCU");
296 for (unsigned int i
= first
; i
<= last
; i
++) {
297 ret
= sim3x_erase_page(bank
, bank
->sectors
[i
].offset
);
302 target
= bank
->target
;
304 /* Wait until busy */
305 for (unsigned int i
= 0; i
< FLASH_BUSY_TIMEOUT
; i
++) {
306 ret
= target_read_u32(target
, FLASHCTRL0_CONFIG_ALL
, &temp
);
310 if ((temp
& FLASHCTRL0_CONFIG_BUSYF_MASK
) == 0) { /* If is not busy */
311 if ((temp
& FLASHCTRL0_CONFIG_ERASEEN_MASK
) != 0) { /* If erase is enabled */
312 /* Disable Flash Erase Mode */
313 ret
= target_write_u32(target
, FLASHCTRL0_CONFIG_CLR
,
314 FLASHCTRL0_CONFIG_ERASEEN_MASK
);
325 LOG_ERROR("timed out waiting for FLASHCTRL0_CONFIG_BUSYF");
329 static int sim3x_write_block(struct flash_bank
*bank
, const uint8_t *buf
,
330 uint32_t offset
, uint32_t count
) /* count is count of half words (2 bytes)! */
332 struct target
*target
= bank
->target
;
333 uint32_t buffer_size
= 16384;
334 struct working_area
*write_algorithm
;
335 struct working_area
*source
;
336 uint32_t address
= bank
->base
+ offset
;
337 struct reg_param reg_params
[5];
338 struct armv7m_algorithm armv7m_info
;
341 /* see contrib/loaders/flash/sim3x.s for src */
343 static const uint8_t sim3x_flash_write_code
[] = {
344 /* Write the initial unlock value to KEY (0xA5) */
345 0xA5, 0x26, /* movs r6, #INITIAL_UNLOCK */
346 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */
348 /* Write the multiple unlock value to KEY (0xF2) */
349 0xF2, 0x26, /* movs r6, #MULTIPLE_UNLOCK */
350 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */
353 0x16, 0x68, /* ldr r6, [r2, #0] */
354 0x00, 0x2E, /* cmp r6, #0 */
355 0x16, 0xD0, /* beq exit */
356 0x55, 0x68, /* ldr r5, [r2, #4] */
357 0xB5, 0x42, /* cmp r5, r6 */
358 0xF9, 0xD0, /* beq wait_fifo */
360 /* wait for BUSYF flag */
362 0x06, 0x68, /* ldr r6, [r0, #FLASHCTRL_CONFIG] */
363 0x16, 0xF4, 0x80, 0x1F, /* tst r6, #BUSYF */
364 0xFB, 0xD1, /* bne wait_busy1 */
366 /* Write the destination address to WRADDR */
367 0xC0, 0xF8, 0xA0, 0x40, /* str r4, [r0, #FLASHCTRL_WRADDR] */
369 /* Write the data half-word to WRDATA in right-justified format */
370 0x2E, 0x88, /* ldrh r6, [r5] */
371 0xC0, 0xF8, 0xB0, 0x60, /* str r6, [r0, #FLASHCTRL_WRDATA] */
373 0x02, 0x35, /* adds r5, #2 */
374 0x02, 0x34, /* adds r4, #2 */
376 /* wrap rp at end of buffer */
377 0x9D, 0x42, /* cmp r5, r3 */
378 0x01, 0xD3, /* bcc no_wrap */
379 0x15, 0x46, /* mov r5, r2 */
380 0x08, 0x35, /* adds r5, #8 */
383 0x55, 0x60, /* str r5, [r2, #4] */
384 0x49, 0x1E, /* subs r1, r1, #1 */
385 0x00, 0x29, /* cmp r1, #0 */
386 0x00, 0xD0, /* beq exit */
387 0xE5, 0xE7, /* b wait_fifo */
390 0x5A, 0x26, /* movs r6, #MULTIPLE_LOCK */
391 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */
393 /* wait for BUSYF flag */
395 0x06, 0x68, /* ldr r6, [r0, #FLASHCTRL_CONFIG] */
396 0x16, 0xF4, 0x80, 0x1F, /* tst r6, #BUSYF */
397 0xFB, 0xD1, /* bne wait_busy2 */
399 0x00, 0xBE /* bkpt #0 */
402 /* flash write code */
403 if (target_alloc_working_area(target
, sizeof(sim3x_flash_write_code
),
404 &write_algorithm
) != ERROR_OK
) {
405 LOG_WARNING("no working area available, can't do block memory writes");
406 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
409 ret
= target_write_buffer(target
, write_algorithm
->address
,
410 sizeof(sim3x_flash_write_code
), sim3x_flash_write_code
);
415 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
417 buffer_size
&= ~1UL; /* Make sure it's 2 byte aligned */
418 if (buffer_size
<= 256) {
419 /* we already allocated the writing code, but failed to get a
420 * buffer, free the algorithm
422 target_free_working_area(target
, write_algorithm
);
424 LOG_WARNING("no large enough working area available, can't do block memory writes");
425 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
429 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* flash base */
430 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* count */
431 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* buffer start */
432 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* buffer end */
433 init_reg_param(®_params
[4], "r4", 32, PARAM_IN_OUT
); /* target address */
435 buf_set_u32(reg_params
[0].value
, 0, 32, FLASHCTRL0_CONFIG_ALL
);
436 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
437 buf_set_u32(reg_params
[2].value
, 0, 32, source
->address
);
438 buf_set_u32(reg_params
[3].value
, 0, 32, source
->address
+ source
->size
);
439 buf_set_u32(reg_params
[4].value
, 0, 32, address
);
441 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
442 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
444 ret
= target_run_flash_async_algorithm(target
, buf
, count
, 2, 0, NULL
, 5,
445 reg_params
, source
->address
, source
->size
, write_algorithm
->address
,
448 if (ret
== ERROR_FLASH_OPERATION_FAILED
) {
449 LOG_ERROR("flash write failed at address 0x%"PRIx32
,
450 buf_get_u32(reg_params
[4].value
, 0, 32));
453 target_free_working_area(target
, source
);
454 target_free_working_area(target
, write_algorithm
);
456 destroy_reg_param(®_params
[0]);
457 destroy_reg_param(®_params
[1]);
458 destroy_reg_param(®_params
[2]);
459 destroy_reg_param(®_params
[3]);
460 destroy_reg_param(®_params
[4]);
465 static int sim3x_flash_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
468 struct target
*target
;
469 struct sim3x_info
*sim3x_info
;
470 uint8_t *new_buffer
= NULL
;
472 target
= bank
->target
;
474 /* Check if target is halted */
475 if (target
->state
!= TARGET_HALTED
) {
476 LOG_ERROR("Target not halted");
477 return ERROR_TARGET_NOT_HALTED
;
480 sim3x_info
= bank
->driver_priv
;
482 if (sim3x_info
->flash_locked
) {
483 LOG_ERROR("Flash is locked");
487 /* Init MCU after reset */
488 if (sim3x_info
->need_init
) {
489 ret
= sim3x_init(bank
);
495 LOG_ERROR("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
496 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
500 uint32_t old_count
= count
;
502 new_buffer
= malloc(count
);
505 LOG_ERROR("odd number of bytes to write and no memory "
506 "for padding buffer");
509 LOG_INFO("odd number of bytes to write (%" PRIu32
"), extending to %" PRIu32
510 " and padding with 0xff", old_count
, count
);
512 new_buffer
[count
- 1] = 0xff;
513 buffer
= memcpy(new_buffer
, buffer
, old_count
);
516 ret
= sim3x_write_block(bank
, buffer
, offset
, count
/ 2);
521 static int sim3x_flash_lock_check(struct flash_bank
*bank
)
525 struct sim3x_info
*sim3x_info
;
527 ret
= target_read_u32(bank
->target
, LOCK_WORD_ADDRESS
, &lock_word
);
528 if (ret
!= ERROR_OK
) {
529 LOG_ERROR("Can not read Lock Word");
533 sim3x_info
= bank
->driver_priv
;
534 sim3x_info
->flash_locked
= (lock_word
!= 0xFFFFFFFF);
539 static int sim3x_flash_protect_check(struct flash_bank
*bank
)
542 struct sim3x_info
*sim3x_info
;
544 /* Check if target is halted */
545 if (bank
->target
->state
!= TARGET_HALTED
) {
546 LOG_ERROR("Target not halted");
547 return ERROR_TARGET_NOT_HALTED
;
550 ret
= sim3x_flash_lock_check(bank
);
554 sim3x_info
= bank
->driver_priv
;
556 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++)
557 bank
->sectors
[i
].is_protected
= sim3x_info
->flash_locked
;
562 static int sim3x_flash_protect(struct flash_bank
*bank
, int set
,
563 unsigned int first
, unsigned int last
)
566 uint8_t lock_word
[4];
567 struct sim3x_info
*sim3x_info
;
568 struct target
*target
;
570 target
= bank
->target
;
572 /* Check if target is halted */
573 if (target
->state
!= TARGET_HALTED
) {
574 LOG_ERROR("Target not halted");
575 return ERROR_TARGET_NOT_HALTED
;
578 if (first
!= 0 || last
!= bank
->num_sectors
- 1) {
579 LOG_ERROR("Flash does not support finer granularity");
583 sim3x_info
= bank
->driver_priv
;
586 if (sim3x_info
->flash_locked
) {
587 LOG_INFO("Flash is already locked");
592 target_buffer_set_u32(target
, lock_word
, 0xFFFFFFFE);
593 ret
= sim3x_flash_write(bank
, lock_word
, LOCK_WORD_ADDRESS
, 4);
598 /* Flash is unlocked by an erase operation */
599 ret
= sim3x_flash_erase(bank
, 0, 0);
604 ret
= sim3x_flash_protect_check(bank
);
609 if (sim3x_info
->flash_locked
) {
610 LOG_INFO("Flash locked");
613 LOG_ERROR("Flash lock error");
617 if (sim3x_info
->flash_locked
) {
618 LOG_ERROR("Flash unlock error");
621 LOG_INFO("Flash unlocked");
627 static int sim3x_read_deviceid(struct flash_bank
*bank
)
630 struct sim3x_info
*sim3x_info
;
634 char part_num_string
[4];
636 sim3x_info
= bank
->driver_priv
;
639 ret
= target_read_u32(bank
->target
, DEVICEID0_DEVICEID2
, &device_id
);
643 /* Device ID should be 'M3' */
644 if (device_id
!= 0x00004D33)
647 /* Family and Part number */
648 ret
= target_read_u32(bank
->target
, DEVICEID0_DEVICEID1
, &device_id
);
652 part_num_string
[0] = device_id
>> 16;
653 part_num_string
[1] = device_id
>> 8;
654 part_num_string
[2] = device_id
;
655 part_num_string
[3] = 0;
657 part_number
= atoi(part_num_string
);
659 /* Part Number should be between 100 and 999 */
660 if (!isalpha(device_id
>> 24) || part_number
< 100 || part_number
> 999)
663 sim3x_info
->part_family
= device_id
>> 24;
664 sim3x_info
->part_number
= part_number
;
666 /* Package and Revision */
667 ret
= target_read_u32(bank
->target
, DEVICEID0_DEVICEID0
, &device_id
);
671 sim3x_info
->device_package
[0] = device_id
>> 24;
672 sim3x_info
->device_package
[1] = device_id
>> 16;
673 sim3x_info
->device_package
[2] = device_id
>> 8;
674 sim3x_info
->device_package
[3] = 0;
676 sim3x_info
->device_revision
= device_id
;
681 static int sim3x_parse_part_info(struct sim3x_info
*sim3x_info
)
683 switch (sim3x_info
->part_number
) {
686 sim3x_info
->flash_size_kb
= 32;
690 sim3x_info
->flash_size_kb
= 64;
695 sim3x_info
->flash_size_kb
= 128;
700 sim3x_info
->flash_size_kb
= 256;
703 LOG_ERROR("Unknown Part number %d", sim3x_info
->part_number
);
704 sim3x_info
->part_number
= 0;
708 switch (sim3x_info
->part_family
) {
711 LOG_INFO("SiM3C%d detected", sim3x_info
->part_number
);
715 LOG_INFO("SiM3U%d detected", sim3x_info
->part_number
);
719 LOG_INFO("SiM3L%d detected", sim3x_info
->part_number
);
722 LOG_ERROR("Unsupported MCU family %c", sim3x_info
->part_family
);
723 sim3x_info
->part_family
= 0;
730 static int sim3x_read_info(struct flash_bank
*bank
)
733 struct sim3x_info
*sim3x_info
;
736 sim3x_info
= bank
->driver_priv
;
739 ret
= target_read_u32(bank
->target
, CPUID
, &cpuid
);
740 if (ret
!= ERROR_OK
) {
741 LOG_ERROR("Failed to read CPU ID");
745 if (((cpuid
>> 4) & 0xfff) != 0xc23) {
746 LOG_ERROR("Target is not Cortex-M3");
750 /* Read info from chip */
751 ret
= sim3x_read_deviceid(bank
);
752 if (ret
== ERROR_OK
) {
753 ret
= sim3x_parse_part_info(sim3x_info
);
754 if (ret
!= ERROR_OK
) {
755 LOG_ERROR("Failed to parse info from MCU");
759 LOG_WARNING("Failed to read info from MCU, using info from flash bank parameters");
761 /* Check if flash size is given in flash bank command */
763 LOG_ERROR("Flash size not set in the flash bank command");
767 /* Convert bank size to kb */
768 sim3x_info
->flash_size_kb
= bank
->size
/ 1024;
771 LOG_INFO("Flash size = %dKB", sim3x_info
->flash_size_kb
);
776 static int sim3x_probe(struct flash_bank
*bank
)
779 struct sim3x_info
*sim3x_info
;
781 sim3x_info
= bank
->driver_priv
;
782 sim3x_info
->probed
= false;
783 sim3x_info
->need_init
= true;
785 /* Read info from chip */
786 ret
= sim3x_read_info(bank
);
790 ret
= sim3x_flash_lock_check(bank
);
796 bank
->base
= FLASH_BASE_ADDRESS
;
797 bank
->size
= sim3x_info
->flash_size_kb
* SIM3X_FLASH_PAGE_SIZE
;
798 bank
->num_sectors
= SIM3X_FLASH_PAGE_SIZE
;
799 bank
->sectors
= malloc(sizeof(struct flash_sector
) * sim3x_info
->flash_size_kb
);
801 for (i
= 0; i
< sim3x_info
->flash_size_kb
; i
++) {
802 bank
->sectors
[i
].offset
= i
* SIM3X_FLASH_PAGE_SIZE
;
803 bank
->sectors
[i
].size
= SIM3X_FLASH_PAGE_SIZE
;
804 bank
->sectors
[i
].is_erased
= -1;
805 bank
->sectors
[i
].is_protected
= sim3x_info
->flash_locked
;
808 sim3x_info
->probed
= true;
813 static int sim3x_auto_probe(struct flash_bank
*bank
)
815 struct sim3x_info
*sim3x_info
;
817 sim3x_info
= bank
->driver_priv
;
819 if (sim3x_info
->probed
) {
820 sim3x_info
->need_init
= true;
823 return sim3x_probe(bank
);
827 static int sim3x_flash_info(struct flash_bank
*bank
, struct command_invocation
*cmd
)
829 struct sim3x_info
*sim3x_info
;
831 sim3x_info
= bank
->driver_priv
;
833 /* Read info about chip */
834 int ret
= sim3x_read_info(bank
);
839 if (sim3x_info
->part_family
&& sim3x_info
->part_number
) {
840 command_print_sameline(cmd
, "SiM3%c%d", sim3x_info
->part_family
, sim3x_info
->part_number
);
843 if (sim3x_info
->device_revision
&& sim3x_info
->device_revision
<= 'Z' - 'A') {
844 command_print_sameline(cmd
, "-%c", sim3x_info
->device_revision
+ 'A');
847 command_print_sameline(cmd
, "-G%s", sim3x_info
->device_package
);
851 /* Print flash size */
852 command_print_sameline(cmd
, " flash_size = %dKB", sim3x_info
->flash_size_kb
);
857 * reg 31:8 - no effect
860 * reg 1:0 - no effect
862 static int ap_write_register(struct adiv5_dap
*dap
, unsigned reg
, uint32_t value
)
864 LOG_DEBUG("DAP_REG[0x%02x] <- %08" PRIX32
, reg
, value
);
866 struct adiv5_ap
*ap
= dap_get_ap(dap
, SIM3X_AP
);
868 LOG_DEBUG("DAP: failed to get AP");
872 int retval
= dap_queue_ap_write(ap
, reg
, value
);
873 if (retval
!= ERROR_OK
) {
874 LOG_DEBUG("DAP: failed to queue a write request");
879 retval
= dap_run(dap
);
881 if (retval
!= ERROR_OK
) {
882 LOG_DEBUG("DAP: dap_run failed");
889 static int ap_read_register(struct adiv5_dap
*dap
, unsigned reg
, uint32_t *result
)
891 struct adiv5_ap
*ap
= dap_get_ap(dap
, SIM3X_AP
);
893 LOG_DEBUG("DAP: failed to get AP");
897 int retval
= dap_queue_ap_read(ap
, reg
, result
);
898 if (retval
!= ERROR_OK
) {
899 LOG_DEBUG("DAP: failed to queue a read request");
904 retval
= dap_run(dap
);
906 if (retval
!= ERROR_OK
) {
907 LOG_DEBUG("DAP: dap_run failed");
911 LOG_DEBUG("DAP_REG[0x%02x]: %08" PRIX32
, reg
, *result
);
915 static int ap_poll_register(struct adiv5_dap
*dap
, unsigned reg
, uint32_t mask
, uint32_t value
, int timeout
)
921 retval
= ap_read_register(dap
, reg
, &val
);
922 if (retval
!= ERROR_OK
|| (val
& mask
) == value
)
928 LOG_DEBUG("DAP: polling timed out");
932 COMMAND_HANDLER(sim3x_mass_erase
)
937 struct target
*target
= get_current_target(CMD_CTX
);
938 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
939 struct adiv5_dap
*dap
= cortex_m
->armv7m
.arm
.dap
;
942 /* Used debug interface doesn't support direct DAP access */
943 LOG_ERROR("mass_erase can't be used by this debug interface");
947 ret
= ap_read_register(dap
, SIM3X_AP_ID
, &val
);
951 if (val
!= SIM3X_AP_ID_VALUE
) {
952 LOG_ERROR("Wrong SIM3X_AP_ID");
956 /* Mass erase sequence */
957 ret
= ap_write_register(dap
, SIM3X_AP_CTRL1
, SIM3X_AP_CTRL1_RESET_REQ
);
961 ret
= ap_write_register(dap
, SIM3X_AP_CTRL1
, SIM3X_AP_CTRL1_RESET_REQ
| SIM3X_AP_CTRL1_MASS_ERASE_REQ
);
965 ret
= ap_poll_register(dap
, SIM3X_AP_CTRL1
, SIM3X_AP_CTRL1_MASS_ERASE_REQ
, 0x00000000, FLASH_BUSY_TIMEOUT
);
969 ret
= ap_write_register(dap
, SIM3X_AP_CTRL1
, 0x00000000); /* clear SIM3X_AP_CTRL1_RESET_REQ */
973 LOG_INFO("Mass erase success");
977 COMMAND_HANDLER(sim3x_lock
)
982 struct target
*target
= get_current_target(CMD_CTX
);
983 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
984 struct adiv5_dap
*dap
= cortex_m
->armv7m
.arm
.dap
;
987 /* Used debug interface doesn't support direct DAP access */
988 LOG_INFO("Target can't be unlocked by this debug interface");
991 ret
= target_read_u32(target
, CPUID
, &val
);
995 if ((val
& CPUID_CHECK_VALUE_MASK
) != CPUID_CHECK_VALUE
) {
996 LOG_ERROR("Target is not ARM Cortex-M3 or is already locked");
1000 /* check SIM3X_AP_ID */
1001 ret
= ap_read_register(dap
, SIM3X_AP_ID
, &val
);
1002 if (ret
!= ERROR_OK
)
1005 if (val
!= SIM3X_AP_ID_VALUE
) {
1006 LOG_ERROR("Wrong SIM3X_AP_ID");
1010 /* check if locked */
1011 ret
= target_read_u32(target
, CPUID
, &val
);
1012 /* if correct value is read, then it will continue */
1013 if (ret
!= ERROR_OK
|| (val
& CPUID_CHECK_VALUE_MASK
) != CPUID_CHECK_VALUE
) {
1014 /* if correct value isn't read, then it will check SIM3X_AP_INIT_STAT register */
1015 ret
= ap_read_register(dap
, SIM3X_AP_INIT_STAT
, &val
);
1016 if (ret
!= ERROR_OK
)
1019 if (val
& SIM3X_AP_INIT_STAT_LOCK
) {
1020 LOG_INFO("Target is already locked");
1023 LOG_ERROR("Target doesn't seem to be locked but memory was not read correct");
1029 ret
= target_read_u32(target
, LOCK_WORD_ADDRESS
, &val
);
1030 if (ret
!= ERROR_OK
)
1033 if (val
== LOCK_WORD_MCU_UNLOCKED
) {
1035 uint8_t lock_word
[4];
1036 target_buffer_set_u32(target
, lock_word
, 0xFFFFFFFE);
1038 /* Get Flash Bank */
1039 struct flash_bank
*bank
;
1040 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1041 if (retval
!= ERROR_OK
)
1044 ret
= sim3x_flash_write(bank
, lock_word
, LOCK_WORD_ADDRESS
, 4);
1045 if (ret
!= ERROR_OK
)
1048 LOG_INFO("Target is successfully locked");
1050 } else if (val
== LOCK_WORD_MCU_UNLOCKED_BY_FIRMWARE
) {
1051 /* Can't by locked again without erase, because LOCK_WORD is in FLASH */
1052 LOG_ERROR("Target is unlocked by firmware and can't by locked again without the lock page erase or mass erase");
1055 LOG_ERROR("Unexpected lock word value");
1057 /* SIM3X_AP_ID_VALUE is not checked */
1059 LOG_INFO("Maybe this isn't a SiM3x MCU");
1065 static const struct command_registration sim3x_exec_command_handlers
[] = {
1067 .name
= "mass_erase",
1068 .mode
= COMMAND_EXEC
,
1069 .help
= "Erase the complete flash",
1071 .handler
= sim3x_mass_erase
,
1075 .mode
= COMMAND_EXEC
,
1076 .help
= "Locks the flash. Unlock by mass erase",
1078 .handler
= sim3x_lock
,
1080 COMMAND_REGISTRATION_DONE
1083 static const struct command_registration sim3x_command_handlers
[] = {
1086 .mode
= COMMAND_ANY
,
1087 .help
= "sim3x flash command group",
1089 .chain
= sim3x_exec_command_handlers
,
1091 COMMAND_REGISTRATION_DONE
1094 const struct flash_driver sim3x_flash
= {
1096 .commands
= sim3x_command_handlers
,
1097 .flash_bank_command
= sim3x_flash_bank_command
,
1098 .erase
= sim3x_flash_erase
,
1099 .protect
= sim3x_flash_protect
,
1100 .write
= sim3x_flash_write
,
1101 .read
= default_flash_read
,
1102 .probe
= sim3x_probe
,
1103 .auto_probe
= sim3x_auto_probe
,
1104 .erase_check
= default_flash_blank_check
,
1105 .protect_check
= sim3x_flash_protect_check
,
1106 .info
= sim3x_flash_info
,
1107 .free_driver_priv
= default_flash_free_driver_priv
,
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)