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. *
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 ***************************************************************************/
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>
34 #define DEVICEID0_DEVICEID0 (0x400490C0)
35 #define DEVICEID0_DEVICEID1 (0x400490D0)
36 #define DEVICEID0_DEVICEID2 (0x400490E0)
37 #define DEVICEID0_DEVICEID3 (0x400490F0)
40 #define CPUID_CHECK_VALUE (0x410FC230)
41 #define CPUID_CHECK_VALUE_MASK (0xFF0FFFF0)
44 #define FLASH_BASE_ADDRESS (0x00000000)
45 #define LOCK_WORD_ADDRESS (0x0003FFFC)
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)
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)
58 #define FLASHCTRL0_WRADDR (0x4002E0A0)
59 #define FLASHCTRL0_WRDATA (0x4002E0B0)
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)
67 #define FLASH_BUSY_TIMEOUT (100)
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)
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)
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)
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)
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)
100 #define WDTIMER0_THRESHOLD (0x40030020)
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)
111 #define SIM3X_AP (0x0A)
113 #define SIM3X_AP_CTRL1 (0x00)
114 #define SIM3X_AP_CTRL2 (0x04)
115 #define SIM3X_AP_LOCK (0x08)
116 #define SIM3X_AP_CRC (0x0C)
118 #define SIM3X_AP_INIT_STAT (0x10)
119 #define SIM3X_AP_DAP_IN (0x14)
120 #define SIM3X_AP_DAP_OUT (0x18)
122 #define SIM3X_AP_ID (0xFC)
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)
132 #define SIM3X_FLASH_PAGE_SIZE 1024
135 uint16_t flash_size_kb
;
136 uint16_t part_number
;
138 uint8_t device_revision
;
139 char device_package
[4];
145 /* flash bank sim3x 0 0 0 0 <target#> */
146 FLASH_BANK_COMMAND_HANDLER(sim3x_flash_bank_command
)
148 struct sim3x_info
*sim3x_info
;
151 return ERROR_COMMAND_SYNTAX_ERROR
;
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
;
164 static int sim3x_init(struct flash_bank
*bank
)
167 struct target
*target
;
168 struct sim3x_info
*sim3x_info
;
170 target
= bank
->target
;
172 /* Disable watchdog timer */
173 ret
= target_write_u32(target
, WDTIMER0_WDTKEY
, WDTIMER0_KEY_ATTN
);
177 ret
= target_write_u32(target
, WDTIMER0_WDTKEY
, WDTIMER0_KEY_DISABLE
);
181 /* Enable one write command */
182 ret
= target_write_u32(target
, WDTIMER0_WDTKEY
, WDTIMER0_KEY_ATTN
);
186 ret
= target_write_u32(target
, WDTIMER0_WDTKEY
, WDTIMER0_KEY_WRITE
);
190 /* Watchdog Timer Debug Mode */
191 ret
= target_write_u32(target
, WDTIMER0_CONTROL_SET
,
192 WDTIMER0_CONTROL_DBGMD_MASK
);
196 /* Enable VDD Supply Monitor */
197 ret
= target_write_u32(target
, VMON0_CONTROL_SET
,
198 VMON0_CONTROL_VMONEN_MASK
);
202 /* Set VDD Supply Monitor as a reset source */
203 ret
= target_write_u32(target
, RSTSRC0_RESETEN_SET
,
204 RSTSRC0_RESETEN_VMONREN_MASK
);
208 /* Flash Controller Clock Enable */
209 ret
= target_write_u32(target
, CLKCTRL0_APBCLKG0_SET
,
210 CLKCTRL0_APBCLKG0_FLCTRLCEN_MASK
);
214 /* Disable Flash Erase Mode */
215 ret
= target_write_u32(target
, FLASHCTRL0_CONFIG_CLR
,
216 FLASHCTRL0_CONFIG_ERASEEN_MASK
);
220 sim3x_info
= bank
->driver_priv
;
221 sim3x_info
->need_init
= 0;
225 static int sim3x_erase_page(struct flash_bank
*bank
, uint32_t addr
)
229 struct target
*target
;
231 target
= bank
->target
;
233 for (i
= 0; i
< FLASH_BUSY_TIMEOUT
; i
++) {
234 ret
= target_read_u32(target
, FLASHCTRL0_CONFIG_ALL
, &temp
);
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
);
249 /* Write the address of the Flash page to WRADDR */
250 ret
= target_write_u32(target
, FLASHCTRL0_WRADDR
, addr
);
254 /* Write the initial unlock value to KEY */
255 ret
= target_write_u32(target
, FLASHCTRL0_KEY
,
256 FLASHCTRL0_KEY_INITIAL_UNLOCK
);
260 /* Write the single unlock value to KEY */
261 ret
= target_write_u32(target
, FLASHCTRL0_KEY
,
262 FLASHCTRL0_KEY_SINGLE_UNLOCK
);
266 /* Write any value to WRDATA to initiate the page erase */
267 ret
= target_write_u32(target
, FLASHCTRL0_WRDATA
, 0);
277 LOG_ERROR("timed out waiting for FLASHCTRL0_CONFIG_BUSYF");
281 static int sim3x_flash_erase(struct flash_bank
*bank
, unsigned int first
,
286 struct sim3x_info
*sim3x_info
;
287 struct target
*target
;
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
;
295 sim3x_info
= bank
->driver_priv
;
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");
307 for (unsigned int i
= first
; i
<= last
; i
++) {
308 ret
= sim3x_erase_page(bank
, bank
->sectors
[i
].offset
);
313 target
= bank
->target
;
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
);
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
);
336 LOG_ERROR("timed out waiting for FLASHCTRL0_CONFIG_BUSYF");
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)! */
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
;
352 /* see contrib/loaders/flash/sim3x.s for src */
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] */
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] */
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 */
371 /* wait for BUSYF flag */
373 0x06, 0x68, /* ldr r6, [r0, #FLASHCTRL_CONFIG] */
374 0x16, 0xF4, 0x80, 0x1F, /* tst r6, #BUSYF */
375 0xFB, 0xD1, /* bne wait_busy1 */
377 /* Write the destination address to WRADDR */
378 0xC0, 0xF8, 0xA0, 0x40, /* str r4, [r0, #FLASHCTRL_WRADDR] */
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] */
384 0x02, 0x35, /* adds r5, #2 */
385 0x02, 0x34, /* adds r4, #2 */
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 */
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 */
401 0x5A, 0x26, /* movs r6, #MULTIPLE_LOCK */
402 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */
404 /* wait for BUSYF flag */
406 0x06, 0x68, /* ldr r6, [r0, #FLASHCTRL_CONFIG] */
407 0x16, 0xF4, 0x80, 0x1F, /* tst r6, #BUSYF */
408 0xFB, 0xD1, /* bne wait_busy2 */
410 0x00, 0xBE /* bkpt #0 */
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
;
420 ret
= target_write_buffer(target
, write_algorithm
->address
,
421 sizeof(sim3x_flash_write_code
), sim3x_flash_write_code
);
426 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
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
433 target_free_working_area(target
, write_algorithm
);
435 LOG_WARNING("no large enough working area available, can't do block memory writes");
436 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
440 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* flash base */
441 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* count */
442 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* buffer start */
443 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* buffer end */
444 init_reg_param(®_params
[4], "r4", 32, PARAM_IN_OUT
); /* target address */
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
);
452 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
453 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
455 ret
= target_run_flash_async_algorithm(target
, buf
, count
, 2, 0, NULL
, 5,
456 reg_params
, source
->address
, source
->size
, write_algorithm
->address
,
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));
464 target_free_working_area(target
, source
);
465 target_free_working_area(target
, write_algorithm
);
467 destroy_reg_param(®_params
[0]);
468 destroy_reg_param(®_params
[1]);
469 destroy_reg_param(®_params
[2]);
470 destroy_reg_param(®_params
[3]);
471 destroy_reg_param(®_params
[4]);
476 static int sim3x_flash_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
479 struct target
*target
;
480 struct sim3x_info
*sim3x_info
;
481 uint8_t *new_buffer
= NULL
;
483 target
= bank
->target
;
485 /* Check if target is halted */
486 if (target
->state
!= TARGET_HALTED
) {
487 LOG_ERROR("Target not halted");
488 return ERROR_TARGET_NOT_HALTED
;
491 sim3x_info
= bank
->driver_priv
;
493 if (sim3x_info
->flash_locked
) {
494 LOG_ERROR("Flash is locked");
498 /* Init MCU after reset */
499 if (sim3x_info
->need_init
) {
500 ret
= sim3x_init(bank
);
506 LOG_ERROR("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
507 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
511 uint32_t old_count
= count
;
513 new_buffer
= malloc(count
);
516 LOG_ERROR("odd number of bytes to write and no memory "
517 "for padding buffer");
520 LOG_INFO("odd number of bytes to write (%" PRIu32
"), extending to %" PRIu32
521 " and padding with 0xff", old_count
, count
);
523 new_buffer
[count
- 1] = 0xff;
524 buffer
= memcpy(new_buffer
, buffer
, old_count
);
527 ret
= sim3x_write_block(bank
, buffer
, offset
, count
/ 2);
532 static int sim3x_flash_lock_check(struct flash_bank
*bank
)
536 struct sim3x_info
*sim3x_info
;
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");
544 sim3x_info
= bank
->driver_priv
;
545 sim3x_info
->flash_locked
= (lock_word
!= 0xFFFFFFFF);
550 static int sim3x_flash_protect_check(struct flash_bank
*bank
)
553 struct sim3x_info
*sim3x_info
;
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
;
561 ret
= sim3x_flash_lock_check(bank
);
565 sim3x_info
= bank
->driver_priv
;
567 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++)
568 bank
->sectors
[i
].is_protected
= sim3x_info
->flash_locked
;
573 static int sim3x_flash_protect(struct flash_bank
*bank
, int set
,
574 unsigned int first
, unsigned int last
)
577 uint8_t lock_word
[4];
578 struct sim3x_info
*sim3x_info
;
579 struct target
*target
;
581 target
= bank
->target
;
583 /* Check if target is halted */
584 if (target
->state
!= TARGET_HALTED
) {
585 LOG_ERROR("Target not halted");
586 return ERROR_TARGET_NOT_HALTED
;
589 if (first
!= 0 || last
!= bank
->num_sectors
- 1) {
590 LOG_ERROR("Flash does not support finer granularity");
594 sim3x_info
= bank
->driver_priv
;
597 if (sim3x_info
->flash_locked
) {
598 LOG_INFO("Flash is already locked");
603 target_buffer_set_u32(target
, lock_word
, 0xFFFFFFFE);
604 ret
= sim3x_flash_write(bank
, lock_word
, LOCK_WORD_ADDRESS
, 4);
609 /* Flash is unlocked by an erase operation */
610 ret
= sim3x_flash_erase(bank
, 0, 0);
615 ret
= sim3x_flash_protect_check(bank
);
620 if (sim3x_info
->flash_locked
) {
621 LOG_INFO("Flash locked");
624 LOG_ERROR("Flash lock error");
628 if (sim3x_info
->flash_locked
) {
629 LOG_ERROR("Flash unlock error");
632 LOG_INFO("Flash unlocked");
638 static int sim3x_read_deviceid(struct flash_bank
*bank
)
641 struct sim3x_info
*sim3x_info
;
645 char part_num_string
[4];
647 sim3x_info
= bank
->driver_priv
;
650 ret
= target_read_u32(bank
->target
, DEVICEID0_DEVICEID2
, &device_id
);
654 /* Device ID should be 'M3' */
655 if (device_id
!= 0x00004D33)
658 /* Family and Part number */
659 ret
= target_read_u32(bank
->target
, DEVICEID0_DEVICEID1
, &device_id
);
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;
668 part_number
= atoi(part_num_string
);
670 /* Part Number should be between 100 and 999 */
671 if (!isalpha(device_id
>> 24) || part_number
< 100 || part_number
> 999)
674 sim3x_info
->part_family
= device_id
>> 24;
675 sim3x_info
->part_number
= part_number
;
677 /* Package and Revision */
678 ret
= target_read_u32(bank
->target
, DEVICEID0_DEVICEID0
, &device_id
);
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;
687 sim3x_info
->device_revision
= device_id
;
692 static int sim3x_parse_part_info(struct sim3x_info
*sim3x_info
)
694 switch (sim3x_info
->part_number
) {
697 sim3x_info
->flash_size_kb
= 32;
701 sim3x_info
->flash_size_kb
= 64;
706 sim3x_info
->flash_size_kb
= 128;
711 sim3x_info
->flash_size_kb
= 256;
714 LOG_ERROR("Unknown Part number %d", sim3x_info
->part_number
);
715 sim3x_info
->part_number
= 0;
719 switch (sim3x_info
->part_family
) {
722 LOG_INFO("SiM3C%d detected", sim3x_info
->part_number
);
726 LOG_INFO("SiM3U%d detected", sim3x_info
->part_number
);
730 LOG_INFO("SiM3L%d detected", sim3x_info
->part_number
);
733 LOG_ERROR("Unsupported MCU family %c", sim3x_info
->part_family
);
734 sim3x_info
->part_family
= 0;
741 static int sim3x_read_info(struct flash_bank
*bank
)
744 struct sim3x_info
*sim3x_info
;
747 sim3x_info
= bank
->driver_priv
;
750 ret
= target_read_u32(bank
->target
, CPUID
, &cpuid
);
751 if (ret
!= ERROR_OK
) {
752 LOG_ERROR("Failed to read CPU ID");
756 if (((cpuid
>> 4) & 0xfff) != 0xc23) {
757 LOG_ERROR("Target is not Cortex-M3");
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");
770 LOG_WARNING("Failed to read info from MCU, using info from flash bank parameters");
772 /* Check if flash size is given in flash bank command */
774 LOG_ERROR("Flash size not set in the flash bank command");
778 /* Convert bank size to kb */
779 sim3x_info
->flash_size_kb
= bank
->size
/ 1024;
782 LOG_INFO("Flash size = %dKB", sim3x_info
->flash_size_kb
);
787 static int sim3x_probe(struct flash_bank
*bank
)
790 struct sim3x_info
*sim3x_info
;
792 sim3x_info
= bank
->driver_priv
;
793 sim3x_info
->probed
= false;
794 sim3x_info
->need_init
= true;
796 /* Read info from chip */
797 ret
= sim3x_read_info(bank
);
801 ret
= sim3x_flash_lock_check(bank
);
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
);
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
;
819 sim3x_info
->probed
= true;
824 static int sim3x_auto_probe(struct flash_bank
*bank
)
826 struct sim3x_info
*sim3x_info
;
828 sim3x_info
= bank
->driver_priv
;
830 if (sim3x_info
->probed
) {
831 sim3x_info
->need_init
= true;
834 return sim3x_probe(bank
);
838 static int sim3x_flash_info(struct flash_bank
*bank
, struct command_invocation
*cmd
)
840 struct sim3x_info
*sim3x_info
;
842 sim3x_info
= bank
->driver_priv
;
844 /* Read info about chip */
845 int ret
= sim3x_read_info(bank
);
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
);
854 if (sim3x_info
->device_revision
&& sim3x_info
->device_revision
<= 'Z' - 'A') {
855 command_print_sameline(cmd
, "-%c", sim3x_info
->device_revision
+ 'A');
858 command_print_sameline(cmd
, "-G%s", sim3x_info
->device_package
);
862 /* Print flash size */
863 command_print_sameline(cmd
, " flash_size = %dKB", sim3x_info
->flash_size_kb
);
868 * reg 31:8 - no effect
871 * reg 1:0 - no effect
873 static int ap_write_register(struct adiv5_dap
*dap
, unsigned reg
, uint32_t value
)
876 LOG_DEBUG("DAP_REG[0x%02x] <- %08" PRIX32
, reg
, value
);
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");
884 retval
= dap_run(dap
);
885 if (retval
!= ERROR_OK
) {
886 LOG_DEBUG("DAP: dap_run failed");
893 static int ap_read_register(struct adiv5_dap
*dap
, unsigned reg
, uint32_t *result
)
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");
903 retval
= dap_run(dap
);
904 if (retval
!= ERROR_OK
) {
905 LOG_DEBUG("DAP: dap_run failed");
909 LOG_DEBUG("DAP_REG[0x%02x]: %08" PRIX32
, reg
, *result
);
913 static int ap_poll_register(struct adiv5_dap
*dap
, unsigned reg
, uint32_t mask
, uint32_t value
, int timeout
)
919 retval
= ap_read_register(dap
, reg
, &val
);
920 if (retval
!= ERROR_OK
|| (val
& mask
) == value
)
926 LOG_DEBUG("DAP: polling timed out");
930 COMMAND_HANDLER(sim3x_mass_erase
)
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
;
940 /* Used debug interface doesn't support direct DAP access */
941 LOG_ERROR("mass_erase can't be used by this debug interface");
945 ret
= ap_read_register(dap
, SIM3X_AP_ID
, &val
);
949 if (val
!= SIM3X_AP_ID_VALUE
) {
950 LOG_ERROR("Wrong SIM3X_AP_ID");
954 /* Mass erase sequence */
955 ret
= ap_write_register(dap
, SIM3X_AP_CTRL1
, SIM3X_AP_CTRL1_RESET_REQ
);
959 ret
= ap_write_register(dap
, SIM3X_AP_CTRL1
, SIM3X_AP_CTRL1_RESET_REQ
| SIM3X_AP_CTRL1_MASS_ERASE_REQ
);
963 ret
= ap_poll_register(dap
, SIM3X_AP_CTRL1
, SIM3X_AP_CTRL1_MASS_ERASE_REQ
, 0x00000000, FLASH_BUSY_TIMEOUT
);
967 ret
= ap_write_register(dap
, SIM3X_AP_CTRL1
, 0x00000000); /* clear SIM3X_AP_CTRL1_RESET_REQ */
971 LOG_INFO("Mass erase success");
975 COMMAND_HANDLER(sim3x_lock
)
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
;
985 /* Used debug interface doesn't support direct DAP access */
986 LOG_INFO("Target can't by unlocked by this debug interface");
989 ret
= target_read_u32(target
, CPUID
, &val
);
993 if ((val
& CPUID_CHECK_VALUE_MASK
) != CPUID_CHECK_VALUE
) {
994 LOG_ERROR("Target is not ARM Cortex-M3 or is already locked");
998 /* check SIM3X_AP_ID */
999 ret
= ap_read_register(dap
, SIM3X_AP_ID
, &val
);
1000 if (ret
!= ERROR_OK
)
1003 if (val
!= SIM3X_AP_ID_VALUE
) {
1004 LOG_ERROR("Wrong SIM3X_AP_ID");
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
)
1017 if (val
& SIM3X_AP_INIT_STAT_LOCK
) {
1018 LOG_INFO("Target is already locked");
1021 LOG_ERROR("Target doesn't seem to be locked but memory was not read correct");
1027 ret
= target_read_u32(target
, LOCK_WORD_ADDRESS
, &val
);
1028 if (ret
!= ERROR_OK
)
1031 if (val
== LOCK_WORD_MCU_UNLOCKED
) {
1033 uint8_t lock_word
[4];
1034 target_buffer_set_u32(target
, lock_word
, 0xFFFFFFFE);
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
)
1042 ret
= sim3x_flash_write(bank
, lock_word
, LOCK_WORD_ADDRESS
, 4);
1043 if (ret
!= ERROR_OK
)
1046 LOG_INFO("Target is successfully locked");
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");
1053 LOG_ERROR("Unexpected lock word value");
1055 /* SIM3X_AP_ID_VALUE is not checked */
1057 LOG_INFO("Maybe this isn't a SiM3x MCU");
1063 static const struct command_registration sim3x_exec_command_handlers
[] = {
1065 .name
= "mass_erase",
1066 .mode
= COMMAND_EXEC
,
1067 .help
= "Erase the complete flash",
1069 .handler
= sim3x_mass_erase
,
1073 .mode
= COMMAND_EXEC
,
1074 .help
= "Locks the flash. Unlock by mass erase",
1076 .handler
= sim3x_lock
,
1078 COMMAND_REGISTRATION_DONE
1081 static const struct command_registration sim3x_command_handlers
[] = {
1084 .mode
= COMMAND_ANY
,
1085 .help
= "sim3x flash command group",
1087 .chain
= sim3x_exec_command_handlers
,
1089 COMMAND_REGISTRATION_DONE
1092 const struct flash_driver sim3x_flash
= {
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
,
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)