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/cortex_m.h>
33 #define DEVICEID0_DEVICEID0 (0x400490C0)
34 #define DEVICEID0_DEVICEID1 (0x400490D0)
35 #define DEVICEID0_DEVICEID2 (0x400490E0)
36 #define DEVICEID0_DEVICEID3 (0x400490F0)
39 #define CPUID_CHECK_VALUE (0x410FC230)
40 #define CPUID_CHECK_VALUE_MASK (0xFF0FFFF0)
43 #define FLASH_BASE_ADDRESS (0x00000000)
44 #define LOCK_WORD_ADDRESS (0x0003FFFC)
46 #define LOCK_WORD_MCU_UNLOCKED (0xFFFFFFFF)
47 /* Can't by locked again without erase, because LOCK_WORD is in FLASH */
48 #define LOCK_WORD_MCU_UNLOCKED_BY_FIRMWARE (0x00000000)
50 /* SI32_FLASHCTRL_0 */
51 #define FLASHCTRL0_CONFIG_ALL (0x4002E000)
52 #define FLASHCTRL0_CONFIG_SET (0x4002E004)
53 #define FLASHCTRL0_CONFIG_CLR (0x4002E008)
54 #define FLASHCTRL0_CONFIG_ERASEEN_MASK (0x00040000)
55 #define FLASHCTRL0_CONFIG_BUSYF_MASK (0x00100000)
57 #define FLASHCTRL0_WRADDR (0x4002E0A0)
58 #define FLASHCTRL0_WRDATA (0x4002E0B0)
60 #define FLASHCTRL0_KEY (0x4002E0C0)
61 #define FLASHCTRL0_KEY_INITIAL_UNLOCK (0x000000A5)
62 #define FLASHCTRL0_KEY_SINGLE_UNLOCK (0x000000F1)
63 #define FLASHCTRL0_KEY_MULTIPLE_UNLOCK (0x000000F2)
64 #define FLASHCTRL0_KEY_MULTIPLE_LOCK (0x0000005A)
66 #define FLASH_BUSY_TIMEOUT (100)
69 #define RSTSRC0_RESETEN_ALL (0x4002D060)
70 #define RSTSRC0_RESETEN_SET (0x4002D064)
71 #define RSTSRC0_RESETEN_CLR (0x4002D068)
72 #define RSTSRC0_RESETEN_VMONREN_MASK (0x00000004)
73 #define RSTSRC0_RESETEN_SWREN_MASK (0x00000040)
76 #define VMON0_CONTROL_ALL (0x4002F000)
77 #define VMON0_CONTROL_SET (0x4002F004)
78 #define VMON0_CONTROL_CLR (0x4002F008)
79 #define VMON0_CONTROL_VMONEN_MASK (0x80000000)
82 #define CLKCTRL0_APBCLKG0_ALL (0x4002D020)
83 #define CLKCTRL0_APBCLKG0_SET (0x4002D024)
84 #define CLKCTRL0_APBCLKG0_CLR (0x4002D028)
85 #define CLKCTRL0_APBCLKG0_FLCTRLCEN_MASK (0x40000000)
88 #define WDTIMER0_CONTROL_ALL (0x40030000)
89 #define WDTIMER0_CONTROL_SET (0x40030004)
90 #define WDTIMER0_CONTROL_CLR (0x40030008)
91 #define WDTIMER0_CONTROL_DBGMD_MASK (0x00000002)
93 #define WDTIMER0_STATUS_ALL (0x40030010)
94 #define WDTIMER0_STATUS_SET (0x40030014)
95 #define WDTIMER0_STATUS_CLR (0x40030018)
96 #define WDTIMER0_STATUS_KEYSTS_MASK (0x00000001)
97 #define WDTIMER0_STATUS_PRIVSTS_MASK (0x00000002)
99 #define WDTIMER0_THRESHOLD (0x40030020)
101 #define WDTIMER0_WDTKEY (0x40030030)
102 #define WDTIMER0_KEY_ATTN (0x000000A5)
103 #define WDTIMER0_KEY_WRITE (0x000000F1)
104 #define WDTIMER0_KEY_RESET (0x000000CC)
105 #define WDTIMER0_KEY_DISABLE (0x000000DD)
106 #define WDTIMER0_KEY_START (0x000000EE)
107 #define WDTIMER0_KEY_LOCK (0x000000FF)
110 #define SIM3X_AP (0x0A)
112 #define SIM3X_AP_CTRL1 (0x00)
113 #define SIM3X_AP_CTRL2 (0x04)
114 #define SIM3X_AP_LOCK (0x08)
115 #define SIM3X_AP_CRC (0x0C)
117 #define SIM3X_AP_INIT_STAT (0x10)
118 #define SIM3X_AP_DAP_IN (0x14)
119 #define SIM3X_AP_DAP_OUT (0x18)
121 #define SIM3X_AP_ID (0xFC)
123 /* DAP register values */
124 #define SIM3X_AP_CTRL1_MASS_ERASE_REQ (0x00000001)
125 #define SIM3X_AP_CTRL1_RESET_REQ (0x00000008)
126 /* this bit is set if MCU is locked */
127 #define SIM3X_AP_INIT_STAT_LOCK (0x00000004)
128 /* expected value inside SIM3X_AP_ID */
129 #define SIM3X_AP_ID_VALUE (0x2430002)
131 #define SIM3X_FLASH_PAGE_SIZE 1024
134 uint16_t flash_size_kb
;
135 uint16_t part_number
;
137 uint8_t device_revision
;
138 char device_package
[4];
144 /* flash bank sim3x 0 0 0 0 <target#> */
145 FLASH_BANK_COMMAND_HANDLER(sim3x_flash_bank_command
)
147 struct sim3x_info
*sim3x_info
;
150 return ERROR_COMMAND_SYNTAX_ERROR
;
152 /* Init sim3x_info struct */
153 sim3x_info
= malloc(sizeof(struct sim3x_info
));
154 sim3x_info
->probed
= false;
155 sim3x_info
->need_init
= true;
156 sim3x_info
->device_revision
= 0;
157 memset(sim3x_info
->device_package
, 0, 4);
158 bank
->driver_priv
= sim3x_info
;
163 static int sim3x_init(struct flash_bank
*bank
)
166 struct target
*target
;
167 struct sim3x_info
*sim3x_info
;
169 target
= bank
->target
;
171 /* Disable watchdog timer */
172 ret
= target_write_u32(target
, WDTIMER0_WDTKEY
, WDTIMER0_KEY_ATTN
);
176 ret
= target_write_u32(target
, WDTIMER0_WDTKEY
, WDTIMER0_KEY_DISABLE
);
180 /* Enable one write command */
181 ret
= target_write_u32(target
, WDTIMER0_WDTKEY
, WDTIMER0_KEY_ATTN
);
185 ret
= target_write_u32(target
, WDTIMER0_WDTKEY
, WDTIMER0_KEY_WRITE
);
189 /* Watchdog Timer Debug Mode */
190 ret
= target_write_u32(target
, WDTIMER0_CONTROL_SET
,
191 WDTIMER0_CONTROL_DBGMD_MASK
);
195 /* Enable VDD Supply Monitor */
196 ret
= target_write_u32(target
, VMON0_CONTROL_SET
,
197 VMON0_CONTROL_VMONEN_MASK
);
201 /* Set VDD Supply Monitor as a reset source */
202 ret
= target_write_u32(target
, RSTSRC0_RESETEN_SET
,
203 RSTSRC0_RESETEN_VMONREN_MASK
);
207 /* Flash Controller Clock Enable */
208 ret
= target_write_u32(target
, CLKCTRL0_APBCLKG0_SET
,
209 CLKCTRL0_APBCLKG0_FLCTRLCEN_MASK
);
213 /* Disable Flash Erase Mode */
214 ret
= target_write_u32(target
, FLASHCTRL0_CONFIG_CLR
,
215 FLASHCTRL0_CONFIG_ERASEEN_MASK
);
219 sim3x_info
= bank
->driver_priv
;
220 sim3x_info
->need_init
= 0;
224 static int sim3x_erase_page(struct flash_bank
*bank
, uint32_t addr
)
228 struct target
*target
;
230 target
= bank
->target
;
232 for (i
= 0; i
< FLASH_BUSY_TIMEOUT
; i
++) {
233 ret
= target_read_u32(target
, FLASHCTRL0_CONFIG_ALL
, &temp
);
238 if ((temp
& FLASHCTRL0_CONFIG_BUSYF_MASK
) == 0) {
239 /* If erase is not enabled */
240 if ((temp
& FLASHCTRL0_CONFIG_ERASEEN_MASK
) == 0) {
241 /* Enter Flash Erase Mode */
242 ret
= target_write_u32(target
, FLASHCTRL0_CONFIG_SET
,
243 FLASHCTRL0_CONFIG_ERASEEN_MASK
);
248 /* Write the address of the Flash page to WRADDR */
249 ret
= target_write_u32(target
, FLASHCTRL0_WRADDR
, addr
);
253 /* Write the inital unlock value to KEY */
254 ret
= target_write_u32(target
, FLASHCTRL0_KEY
,
255 FLASHCTRL0_KEY_INITIAL_UNLOCK
);
259 /* Write the single unlock value to KEY */
260 ret
= target_write_u32(target
, FLASHCTRL0_KEY
,
261 FLASHCTRL0_KEY_SINGLE_UNLOCK
);
265 /* Write any value to WRDATA to initiate the page erase */
266 ret
= target_write_u32(target
, FLASHCTRL0_WRDATA
, 0);
276 LOG_ERROR("timed out waiting for FLASHCTRL0_CONFIG_BUSYF");
280 static int sim3x_flash_erase(struct flash_bank
*bank
, unsigned int first
,
285 struct sim3x_info
*sim3x_info
;
286 struct target
*target
;
288 /* Check if target is halted */
289 if (bank
->target
->state
!= TARGET_HALTED
) {
290 LOG_ERROR("Target not halted");
291 return ERROR_TARGET_NOT_HALTED
;
294 sim3x_info
= bank
->driver_priv
;
296 /* Init MCU after reset */
297 if (sim3x_info
->need_init
) {
298 ret
= sim3x_init(bank
);
299 if (ret
!= ERROR_OK
) {
300 LOG_ERROR("Failed to init MCU");
306 for (unsigned int i
= first
; i
<= last
; i
++) {
307 ret
= sim3x_erase_page(bank
, bank
->sectors
[i
].offset
);
312 target
= bank
->target
;
314 /* Wait until busy */
315 for (unsigned int i
= 0; i
< FLASH_BUSY_TIMEOUT
; i
++) {
316 ret
= target_read_u32(target
, FLASHCTRL0_CONFIG_ALL
, &temp
);
320 if ((temp
& FLASHCTRL0_CONFIG_BUSYF_MASK
) == 0) { /* If is not busy */
321 if ((temp
& FLASHCTRL0_CONFIG_ERASEEN_MASK
) != 0) { /* If erase is enabled */
322 /* Disable Flash Erase Mode */
323 ret
= target_write_u32(target
, FLASHCTRL0_CONFIG_CLR
,
324 FLASHCTRL0_CONFIG_ERASEEN_MASK
);
335 LOG_ERROR("timed out waiting for FLASHCTRL0_CONFIG_BUSYF");
339 static int sim3x_write_block(struct flash_bank
*bank
, const uint8_t *buf
,
340 uint32_t offset
, uint32_t count
) /* count is count of half words (2 bytes)! */
342 struct target
*target
= bank
->target
;
343 uint32_t buffer_size
= 16384;
344 struct working_area
*write_algorithm
;
345 struct working_area
*source
;
346 uint32_t address
= bank
->base
+ offset
;
347 struct reg_param reg_params
[5];
348 struct armv7m_algorithm armv7m_info
;
351 /* see contrib/loaders/flash/sim3x.s for src */
353 static const uint8_t sim3x_flash_write_code
[] = {
354 /* Write the initial unlock value to KEY (0xA5) */
355 0xA5, 0x26, /* movs r6, #INITIAL_UNLOCK */
356 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */
358 /* Write the multiple unlock value to KEY (0xF2) */
359 0xF2, 0x26, /* movs r6, #MULTIPLE_UNLOCK */
360 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */
363 0x16, 0x68, /* ldr r6, [r2, #0] */
364 0x00, 0x2E, /* cmp r6, #0 */
365 0x16, 0xD0, /* beq exit */
366 0x55, 0x68, /* ldr r5, [r2, #4] */
367 0xB5, 0x42, /* cmp r5, r6 */
368 0xF9, 0xD0, /* beq wait_fifo */
370 /* wait for BUSYF flag */
372 0x06, 0x68, /* ldr r6, [r0, #FLASHCTRL_CONFIG] */
373 0x16, 0xF4, 0x80, 0x1F, /* tst r6, #BUSYF */
374 0xFB, 0xD1, /* bne wait_busy1 */
376 /* Write the destination address to WRADDR */
377 0xC0, 0xF8, 0xA0, 0x40, /* str r4, [r0, #FLASHCTRL_WRADDR] */
379 /* Write the data half-word to WRDATA in right-justified format */
380 0x2E, 0x88, /* ldrh r6, [r5] */
381 0xC0, 0xF8, 0xB0, 0x60, /* str r6, [r0, #FLASHCTRL_WRDATA] */
383 0x02, 0x35, /* adds r5, #2 */
384 0x02, 0x34, /* adds r4, #2 */
386 /* wrap rp at end of buffer */
387 0x9D, 0x42, /* cmp r5, r3 */
388 0x01, 0xD3, /* bcc no_wrap */
389 0x15, 0x46, /* mov r5, r2 */
390 0x08, 0x35, /* adds r5, #8 */
393 0x55, 0x60, /* str r5, [r2, #4] */
394 0x49, 0x1E, /* subs r1, r1, #1 */
395 0x00, 0x29, /* cmp r1, #0 */
396 0x00, 0xD0, /* beq exit */
397 0xE5, 0xE7, /* b wait_fifo */
400 0x5A, 0x26, /* movs r6, #MULTIPLE_LOCK */
401 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */
403 /* wait for BUSYF flag */
405 0x06, 0x68, /* ldr r6, [r0, #FLASHCTRL_CONFIG] */
406 0x16, 0xF4, 0x80, 0x1F, /* tst r6, #BUSYF */
407 0xFB, 0xD1, /* bne wait_busy2 */
409 0x00, 0xBE /* bkpt #0 */
412 /* flash write code */
413 if (target_alloc_working_area(target
, sizeof(sim3x_flash_write_code
),
414 &write_algorithm
) != ERROR_OK
) {
415 LOG_WARNING("no working area available, can't do block memory writes");
416 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
419 ret
= target_write_buffer(target
, write_algorithm
->address
,
420 sizeof(sim3x_flash_write_code
), sim3x_flash_write_code
);
425 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
427 buffer_size
&= ~1UL; /* Make sure it's 2 byte aligned */
428 if (buffer_size
<= 256) {
429 /* we already allocated the writing code, but failed to get a
430 * buffer, free the algorithm
432 target_free_working_area(target
, write_algorithm
);
434 LOG_WARNING("no large enough working area available, can't do block memory writes");
435 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
439 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* flash base */
440 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* count */
441 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* buffer start */
442 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* buffer end */
443 init_reg_param(®_params
[4], "r4", 32, PARAM_IN_OUT
); /* target address */
445 buf_set_u32(reg_params
[0].value
, 0, 32, FLASHCTRL0_CONFIG_ALL
);
446 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
447 buf_set_u32(reg_params
[2].value
, 0, 32, source
->address
);
448 buf_set_u32(reg_params
[3].value
, 0, 32, source
->address
+ source
->size
);
449 buf_set_u32(reg_params
[4].value
, 0, 32, address
);
451 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
452 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
454 ret
= target_run_flash_async_algorithm(target
, buf
, count
, 2, 0, NULL
, 5,
455 reg_params
, source
->address
, source
->size
, write_algorithm
->address
,
458 if (ret
== ERROR_FLASH_OPERATION_FAILED
) {
459 LOG_ERROR("flash write failed at address 0x%"PRIx32
,
460 buf_get_u32(reg_params
[4].value
, 0, 32));
463 target_free_working_area(target
, source
);
464 target_free_working_area(target
, write_algorithm
);
466 destroy_reg_param(®_params
[0]);
467 destroy_reg_param(®_params
[1]);
468 destroy_reg_param(®_params
[2]);
469 destroy_reg_param(®_params
[3]);
470 destroy_reg_param(®_params
[4]);
475 static int sim3x_flash_write(struct flash_bank
*bank
, const uint8_t *buffer
, uint32_t offset
, uint32_t count
)
478 struct target
*target
;
479 struct sim3x_info
*sim3x_info
;
480 uint8_t *new_buffer
= NULL
;
482 target
= bank
->target
;
484 /* Check if target is halted */
485 if (target
->state
!= TARGET_HALTED
) {
486 LOG_ERROR("Target not halted");
487 return ERROR_TARGET_NOT_HALTED
;
490 sim3x_info
= bank
->driver_priv
;
492 if (sim3x_info
->flash_locked
) {
493 LOG_ERROR("Falsh is locked");
497 /* Init MCU after reset */
498 if (sim3x_info
->need_init
) {
499 ret
= sim3x_init(bank
);
505 LOG_ERROR("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
506 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
510 uint32_t old_count
= count
;
512 new_buffer
= malloc(count
);
514 if (new_buffer
== NULL
) {
515 LOG_ERROR("odd number of bytes to write and no memory "
516 "for padding buffer");
519 LOG_INFO("odd number of bytes to write (%" PRIu32
"), extending to %" PRIu32
520 " and padding with 0xff", old_count
, count
);
522 new_buffer
[count
- 1] = 0xff;
523 buffer
= memcpy(new_buffer
, buffer
, old_count
);
526 ret
= sim3x_write_block(bank
, buffer
, offset
, count
/ 2);
531 static int sim3x_flash_lock_check(struct flash_bank
*bank
)
535 struct sim3x_info
*sim3x_info
;
537 ret
= target_read_u32(bank
->target
, LOCK_WORD_ADDRESS
, &lock_word
);
538 if (ret
!= ERROR_OK
) {
539 LOG_ERROR("Can not read Lock Word");
543 sim3x_info
= bank
->driver_priv
;
544 sim3x_info
->flash_locked
= (lock_word
!= 0xFFFFFFFF);
549 static int sim3x_flash_protect_check(struct flash_bank
*bank
)
552 struct sim3x_info
*sim3x_info
;
554 /* Check if target is halted */
555 if (bank
->target
->state
!= TARGET_HALTED
) {
556 LOG_ERROR("Target not halted");
557 return ERROR_TARGET_NOT_HALTED
;
560 ret
= sim3x_flash_lock_check(bank
);
564 sim3x_info
= bank
->driver_priv
;
566 for (unsigned int i
= 0; i
< bank
->num_sectors
; i
++)
567 bank
->sectors
[i
].is_protected
= sim3x_info
->flash_locked
;
572 static int sim3x_flash_protect(struct flash_bank
*bank
, int set
,
573 unsigned int first
, unsigned int last
)
576 uint8_t lock_word
[4];
577 struct sim3x_info
*sim3x_info
;
578 struct target
*target
;
580 target
= bank
->target
;
582 /* Check if target is halted */
583 if (target
->state
!= TARGET_HALTED
) {
584 LOG_ERROR("Target not halted");
585 return ERROR_TARGET_NOT_HALTED
;
588 if (first
!= 0 || last
!= bank
->num_sectors
- 1) {
589 LOG_ERROR("Flash does not support finer granularity");
593 sim3x_info
= bank
->driver_priv
;
596 if (sim3x_info
->flash_locked
) {
597 LOG_INFO("Flash is already locked");
602 target_buffer_set_u32(target
, lock_word
, 0xFFFFFFFE);
603 ret
= sim3x_flash_write(bank
, lock_word
, LOCK_WORD_ADDRESS
, 4);
608 /* Flash is unlocked by an erase operation */
609 ret
= sim3x_flash_erase(bank
, 0, 0);
614 ret
= sim3x_flash_protect_check(bank
);
619 if (sim3x_info
->flash_locked
) {
620 LOG_INFO("Flash locked");
623 LOG_ERROR("Flash lock error");
627 if (sim3x_info
->flash_locked
) {
628 LOG_ERROR("Flash unlock error");
631 LOG_INFO("Flash unlocked");
637 static int sim3x_read_deviceid(struct flash_bank
*bank
)
640 struct sim3x_info
*sim3x_info
;
644 char part_num_string
[4];
646 sim3x_info
= bank
->driver_priv
;
649 ret
= target_read_u32(bank
->target
, DEVICEID0_DEVICEID2
, &device_id
);
653 /* Device ID should be 'M3' */
654 if (device_id
!= 0x00004D33)
657 /* Family and Part number */
658 ret
= target_read_u32(bank
->target
, DEVICEID0_DEVICEID1
, &device_id
);
662 part_num_string
[0] = device_id
>> 16;
663 part_num_string
[1] = device_id
>> 8;
664 part_num_string
[2] = device_id
;
665 part_num_string
[3] = 0;
667 part_number
= atoi(part_num_string
);
669 /* Part Number should be between 100 and 999 */
670 if (!isalpha(device_id
>> 24) || part_number
< 100 || part_number
> 999)
673 sim3x_info
->part_family
= device_id
>> 24;
674 sim3x_info
->part_number
= part_number
;
676 /* Package and Revision */
677 ret
= target_read_u32(bank
->target
, DEVICEID0_DEVICEID0
, &device_id
);
681 sim3x_info
->device_package
[0] = device_id
>> 24;
682 sim3x_info
->device_package
[1] = device_id
>> 16;
683 sim3x_info
->device_package
[2] = device_id
>> 8;
684 sim3x_info
->device_package
[3] = 0;
686 sim3x_info
->device_revision
= device_id
;
691 static int sim3x_parse_part_info(struct sim3x_info
*sim3x_info
)
693 switch (sim3x_info
->part_number
) {
696 sim3x_info
->flash_size_kb
= 32;
700 sim3x_info
->flash_size_kb
= 64;
705 sim3x_info
->flash_size_kb
= 128;
710 sim3x_info
->flash_size_kb
= 256;
713 LOG_ERROR("Unknown Part number %d", sim3x_info
->part_number
);
714 sim3x_info
->part_number
= 0;
718 switch (sim3x_info
->part_family
) {
721 LOG_INFO("SiM3C%d detected", sim3x_info
->part_number
);
725 LOG_INFO("SiM3U%d detected", sim3x_info
->part_number
);
729 LOG_INFO("SiM3L%d detected", sim3x_info
->part_number
);
732 LOG_ERROR("Unsupported MCU family %c", sim3x_info
->part_family
);
733 sim3x_info
->part_family
= 0;
740 static int sim3x_read_info(struct flash_bank
*bank
)
743 struct sim3x_info
*sim3x_info
;
746 sim3x_info
= bank
->driver_priv
;
749 ret
= target_read_u32(bank
->target
, CPUID
, &cpuid
);
750 if (ret
!= ERROR_OK
) {
751 LOG_ERROR("Failed to read CPU ID");
755 if (((cpuid
>> 4) & 0xfff) != 0xc23) {
756 LOG_ERROR("Target is not Cortex-M3");
760 /* Read info from chip */
761 ret
= sim3x_read_deviceid(bank
);
762 if (ret
== ERROR_OK
) {
763 ret
= sim3x_parse_part_info(sim3x_info
);
764 if (ret
!= ERROR_OK
) {
765 LOG_ERROR("Failed to parse info from MCU");
769 LOG_WARNING("Failed to read info from MCU, using info from flash bank parameters");
771 /* Check if flash size is given in flash bank command */
773 LOG_ERROR("Flash size not set in the flash bank command");
777 /* Convert bank size to kb */
778 sim3x_info
->flash_size_kb
= bank
->size
/ 1024;
781 LOG_INFO("Flash size = %dKB", sim3x_info
->flash_size_kb
);
786 static int sim3x_probe(struct flash_bank
*bank
)
789 struct sim3x_info
*sim3x_info
;
791 sim3x_info
= bank
->driver_priv
;
792 sim3x_info
->probed
= false;
793 sim3x_info
->need_init
= true;
795 /* Read info from chip */
796 ret
= sim3x_read_info(bank
);
800 ret
= sim3x_flash_lock_check(bank
);
806 bank
->sectors
= NULL
;
809 bank
->base
= FLASH_BASE_ADDRESS
;
810 bank
->size
= sim3x_info
->flash_size_kb
* SIM3X_FLASH_PAGE_SIZE
;
811 bank
->num_sectors
= SIM3X_FLASH_PAGE_SIZE
;
812 bank
->sectors
= malloc(sizeof(struct flash_sector
) * sim3x_info
->flash_size_kb
);
814 for (i
= 0; i
< sim3x_info
->flash_size_kb
; i
++) {
815 bank
->sectors
[i
].offset
= i
* SIM3X_FLASH_PAGE_SIZE
;
816 bank
->sectors
[i
].size
= SIM3X_FLASH_PAGE_SIZE
;
817 bank
->sectors
[i
].is_erased
= -1;
818 bank
->sectors
[i
].is_protected
= sim3x_info
->flash_locked
;
821 sim3x_info
->probed
= true;
826 static int sim3x_auto_probe(struct flash_bank
*bank
)
828 struct sim3x_info
*sim3x_info
;
830 sim3x_info
= bank
->driver_priv
;
832 if (sim3x_info
->probed
) {
833 sim3x_info
->need_init
= true;
836 return sim3x_probe(bank
);
840 static int sim3x_flash_info(struct flash_bank
*bank
, char *buf
, int buf_size
)
844 struct sim3x_info
*sim3x_info
;
846 sim3x_info
= bank
->driver_priv
;
848 /* Read info about chip */
849 ret
= sim3x_read_info(bank
);
854 if (sim3x_info
->part_family
&& sim3x_info
->part_number
) {
855 printed
= snprintf(buf
, buf_size
, "SiM3%c%d", sim3x_info
->part_family
, sim3x_info
->part_number
);
860 return ERROR_BUF_TOO_SMALL
;
863 if (sim3x_info
->device_revision
&& sim3x_info
->device_revision
<= 'Z' - 'A') {
864 printed
= snprintf(buf
, buf_size
, "-%c", sim3x_info
->device_revision
+ 'A');
869 return ERROR_BUF_TOO_SMALL
;
872 printed
= snprintf(buf
, buf_size
, "-G%s", sim3x_info
->device_package
);
877 return ERROR_BUF_TOO_SMALL
;
881 /* Print flash size */
882 printed
= snprintf(buf
, buf_size
, " flash_size = %dKB", sim3x_info
->flash_size_kb
);
886 return ERROR_BUF_TOO_SMALL
;
891 * reg 31:8 - no effect
894 * reg 1:0 - no effect
896 static int ap_write_register(struct adiv5_dap
*dap
, unsigned reg
, uint32_t value
)
899 LOG_DEBUG("DAP_REG[0x%02x] <- %08" PRIX32
, reg
, value
);
901 retval
= dap_queue_ap_write(dap_ap(dap
, SIM3X_AP
), reg
, value
);
902 if (retval
!= ERROR_OK
) {
903 LOG_DEBUG("DAP: failed to queue a write request");
907 retval
= dap_run(dap
);
908 if (retval
!= ERROR_OK
) {
909 LOG_DEBUG("DAP: dap_run failed");
916 static int ap_read_register(struct adiv5_dap
*dap
, unsigned reg
, uint32_t *result
)
920 retval
= dap_queue_ap_read(dap_ap(dap
, SIM3X_AP
), reg
, result
);
921 if (retval
!= ERROR_OK
) {
922 LOG_DEBUG("DAP: failed to queue a read request");
926 retval
= dap_run(dap
);
927 if (retval
!= ERROR_OK
) {
928 LOG_DEBUG("DAP: dap_run failed");
932 LOG_DEBUG("DAP_REG[0x%02x]: %08" PRIX32
, reg
, *result
);
936 static int ap_poll_register(struct adiv5_dap
*dap
, unsigned reg
, uint32_t mask
, uint32_t value
, int timeout
)
942 retval
= ap_read_register(dap
, reg
, &val
);
943 if (retval
!= ERROR_OK
|| (val
& mask
) == value
)
949 LOG_DEBUG("DAP: polling timed out");
953 COMMAND_HANDLER(sim3x_mass_erase
)
958 struct target
*target
= get_current_target(CMD_CTX
);
959 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
960 struct adiv5_dap
*dap
= cortex_m
->armv7m
.arm
.dap
;
963 /* Used debug interface doesn't support direct DAP access */
964 LOG_ERROR("mass_erase can't be used by this debug interface");
968 ret
= ap_read_register(dap
, SIM3X_AP_ID
, &val
);
972 if (val
!= SIM3X_AP_ID_VALUE
) {
973 LOG_ERROR("Wrong SIM3X_AP_ID");
977 /* Mass erase sequence */
978 ret
= ap_write_register(dap
, SIM3X_AP_CTRL1
, SIM3X_AP_CTRL1_RESET_REQ
);
982 ret
= ap_write_register(dap
, SIM3X_AP_CTRL1
, SIM3X_AP_CTRL1_RESET_REQ
| SIM3X_AP_CTRL1_MASS_ERASE_REQ
);
986 ret
= ap_poll_register(dap
, SIM3X_AP_CTRL1
, SIM3X_AP_CTRL1_MASS_ERASE_REQ
, 0x00000000, FLASH_BUSY_TIMEOUT
);
990 ret
= ap_write_register(dap
, SIM3X_AP_CTRL1
, 0x00000000); /* clear SIM3X_AP_CTRL1_RESET_REQ */
994 LOG_INFO("Mass erase success");
998 COMMAND_HANDLER(sim3x_lock
)
1003 struct target
*target
= get_current_target(CMD_CTX
);
1004 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1005 struct adiv5_dap
*dap
= cortex_m
->armv7m
.arm
.dap
;
1008 /* Used debug interface doesn't support direct DAP access */
1009 LOG_INFO("Target can't by unlocked by this debug interface");
1012 ret
= target_read_u32(target
, CPUID
, &val
);
1013 if (ret
!= ERROR_OK
)
1016 if ((val
& CPUID_CHECK_VALUE_MASK
) != CPUID_CHECK_VALUE
) {
1017 LOG_ERROR("Target is not ARM Cortex-M3 or is already locked");
1021 /* check SIM3X_AP_ID */
1022 ret
= ap_read_register(dap
, SIM3X_AP_ID
, &val
);
1023 if (ret
!= ERROR_OK
)
1026 if (val
!= SIM3X_AP_ID_VALUE
) {
1027 LOG_ERROR("Wrong SIM3X_AP_ID");
1031 /* check if locked */
1032 ret
= target_read_u32(target
, CPUID
, &val
);
1033 /* if correct value is read, then it will continue */
1034 if (ret
!= ERROR_OK
|| (val
& CPUID_CHECK_VALUE_MASK
) != CPUID_CHECK_VALUE
) {
1035 /* if correct value is'n read, then it will check SIM3X_AP_INIT_STAT register */
1036 ret
= ap_read_register(dap
, SIM3X_AP_INIT_STAT
, &val
);
1037 if (ret
!= ERROR_OK
)
1040 if (val
& SIM3X_AP_INIT_STAT_LOCK
) {
1041 LOG_INFO("Target is already locked");
1044 LOG_ERROR("Target doesn't seem to be locked but memory was not read correct");
1050 ret
= target_read_u32(target
, LOCK_WORD_ADDRESS
, &val
);
1051 if (ret
!= ERROR_OK
)
1054 if (val
== LOCK_WORD_MCU_UNLOCKED
) {
1056 uint8_t lock_word
[4];
1057 target_buffer_set_u32(target
, lock_word
, 0xFFFFFFFE);
1059 /* Get Flash Bank */
1060 struct flash_bank
*bank
;
1061 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1062 if (retval
!= ERROR_OK
)
1065 ret
= sim3x_flash_write(bank
, lock_word
, LOCK_WORD_ADDRESS
, 4);
1066 if (ERROR_OK
!= ret
)
1069 LOG_INFO("Target is successfully locked");
1071 } else if (val
== LOCK_WORD_MCU_UNLOCKED_BY_FIRMWARE
) {
1072 /* Can't by locked again without erase, because LOCK_WORD is in FLASH */
1073 LOG_ERROR("Target is unlocked by firmware and can't by locked again without the lock page erase or mass erase");
1076 LOG_ERROR("Unexpected lock word value");
1078 /* SIM3X_AP_ID_VALUE is not checked */
1080 LOG_INFO("Maybe this isn't a SiM3x MCU");
1086 static const struct command_registration sim3x_exec_command_handlers
[] = {
1088 .name
= "mass_erase",
1089 .mode
= COMMAND_EXEC
,
1090 .help
= "Erase the complete flash",
1092 .handler
= sim3x_mass_erase
,
1096 .mode
= COMMAND_EXEC
,
1097 .help
= "Locks the flash. Unlock by mass erase",
1099 .handler
= sim3x_lock
,
1101 COMMAND_REGISTRATION_DONE
1104 static const struct command_registration sim3x_command_handlers
[] = {
1107 .mode
= COMMAND_ANY
,
1108 .help
= "sim3x flash command group",
1110 .chain
= sim3x_exec_command_handlers
,
1112 COMMAND_REGISTRATION_DONE
1115 const struct flash_driver sim3x_flash
= {
1117 .commands
= sim3x_command_handlers
,
1118 .flash_bank_command
= sim3x_flash_bank_command
,
1119 .erase
= sim3x_flash_erase
,
1120 .protect
= sim3x_flash_protect
,
1121 .write
= sim3x_flash_write
,
1122 .read
= default_flash_read
,
1123 .probe
= sim3x_probe
,
1124 .auto_probe
= sim3x_auto_probe
,
1125 .erase_check
= default_flash_blank_check
,
1126 .protect_check
= sim3x_flash_protect_check
,
1127 .info
= sim3x_flash_info
,
1128 .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)