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
, int first
, int last
)
284 struct sim3x_info
*sim3x_info
;
285 struct target
*target
;
287 /* Check if target is halted */
288 if (bank
->target
->state
!= TARGET_HALTED
) {
289 LOG_ERROR("Target not halted");
290 return ERROR_TARGET_NOT_HALTED
;
293 sim3x_info
= bank
->driver_priv
;
295 /* Init MCU after reset */
296 if (sim3x_info
->need_init
) {
297 ret
= sim3x_init(bank
);
298 if (ret
!= ERROR_OK
) {
299 LOG_ERROR("Failed to init MCU");
305 for (i
= first
; i
<= last
; i
++) {
306 ret
= sim3x_erase_page(bank
, bank
->sectors
[i
].offset
);
311 target
= bank
->target
;
313 /* Wait until busy */
314 for (i
= 0; i
< FLASH_BUSY_TIMEOUT
; i
++) {
315 ret
= target_read_u32(target
, FLASHCTRL0_CONFIG_ALL
, &temp
);
319 if ((temp
& FLASHCTRL0_CONFIG_BUSYF_MASK
) == 0) { /* If is not busy */
320 if ((temp
& FLASHCTRL0_CONFIG_ERASEEN_MASK
) != 0) { /* If erase is enabled */
321 /* Disable Flash Erase Mode */
322 ret
= target_write_u32(target
, FLASHCTRL0_CONFIG_CLR
,
323 FLASHCTRL0_CONFIG_ERASEEN_MASK
);
334 LOG_ERROR("timed out waiting for FLASHCTRL0_CONFIG_BUSYF");
338 static int sim3x_write_block(struct flash_bank
*bank
, const uint8_t *buf
,
339 uint32_t offset
, uint32_t count
) /* count is count of half words (2 bytes)! */
341 struct target
*target
= bank
->target
;
342 uint32_t buffer_size
= 16384;
343 struct working_area
*write_algorithm
;
344 struct working_area
*source
;
345 uint32_t address
= bank
->base
+ offset
;
346 struct reg_param reg_params
[5];
347 struct armv7m_algorithm armv7m_info
;
350 /* see contrib/loaders/flash/sim3x.s for src */
352 static const uint8_t sim3x_flash_write_code
[] = {
353 /* Write the initial unlock value to KEY (0xA5) */
354 0xA5, 0x26, /* movs r6, #INITIAL_UNLOCK */
355 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */
357 /* Write the multiple unlock value to KEY (0xF2) */
358 0xF2, 0x26, /* movs r6, #MULTIPLE_UNLOCK */
359 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */
362 0x16, 0x68, /* ldr r6, [r2, #0] */
363 0x00, 0x2E, /* cmp r6, #0 */
364 0x16, 0xD0, /* beq exit */
365 0x55, 0x68, /* ldr r5, [r2, #4] */
366 0xB5, 0x42, /* cmp r5, r6 */
367 0xF9, 0xD0, /* beq wait_fifo */
369 /* wait for BUSYF flag */
371 0x06, 0x68, /* ldr r6, [r0, #FLASHCTRL_CONFIG] */
372 0x16, 0xF4, 0x80, 0x1F, /* tst r6, #BUSYF */
373 0xFB, 0xD1, /* bne wait_busy1 */
375 /* Write the destination address to WRADDR */
376 0xC0, 0xF8, 0xA0, 0x40, /* str r4, [r0, #FLASHCTRL_WRADDR] */
378 /* Write the data half-word to WRDATA in right-justified format */
379 0x2E, 0x88, /* ldrh r6, [r5] */
380 0xC0, 0xF8, 0xB0, 0x60, /* str r6, [r0, #FLASHCTRL_WRDATA] */
382 0x02, 0x35, /* adds r5, #2 */
383 0x02, 0x34, /* adds r4, #2 */
385 /* wrap rp at end of buffer */
386 0x9D, 0x42, /* cmp r5, r3 */
387 0x01, 0xD3, /* bcc no_wrap */
388 0x15, 0x46, /* mov r5, r2 */
389 0x08, 0x35, /* adds r5, #8 */
392 0x55, 0x60, /* str r5, [r2, #4] */
393 0x49, 0x1E, /* subs r1, r1, #1 */
394 0x00, 0x29, /* cmp r1, #0 */
395 0x00, 0xD0, /* beq exit */
396 0xE5, 0xE7, /* b wait_fifo */
399 0x5A, 0x26, /* movs r6, #MULTIPLE_LOCK */
400 0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */
402 /* wait for BUSYF flag */
404 0x06, 0x68, /* ldr r6, [r0, #FLASHCTRL_CONFIG] */
405 0x16, 0xF4, 0x80, 0x1F, /* tst r6, #BUSYF */
406 0xFB, 0xD1, /* bne wait_busy2 */
408 0x00, 0xBE /* bkpt #0 */
411 /* flash write code */
412 if (target_alloc_working_area(target
, sizeof(sim3x_flash_write_code
),
413 &write_algorithm
) != ERROR_OK
) {
414 LOG_WARNING("no working area available, can't do block memory writes");
415 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
418 ret
= target_write_buffer(target
, write_algorithm
->address
,
419 sizeof(sim3x_flash_write_code
), sim3x_flash_write_code
);
424 while (target_alloc_working_area_try(target
, buffer_size
, &source
) != ERROR_OK
) {
426 buffer_size
&= ~1UL; /* Make sure it's 2 byte aligned */
427 if (buffer_size
<= 256) {
428 /* we already allocated the writing code, but failed to get a
429 * buffer, free the algorithm
431 target_free_working_area(target
, write_algorithm
);
433 LOG_WARNING("no large enough working area available, can't do block memory writes");
434 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE
;
438 init_reg_param(®_params
[0], "r0", 32, PARAM_OUT
); /* flash base */
439 init_reg_param(®_params
[1], "r1", 32, PARAM_OUT
); /* count */
440 init_reg_param(®_params
[2], "r2", 32, PARAM_OUT
); /* buffer start */
441 init_reg_param(®_params
[3], "r3", 32, PARAM_OUT
); /* buffer end */
442 init_reg_param(®_params
[4], "r4", 32, PARAM_IN_OUT
); /* target address */
444 buf_set_u32(reg_params
[0].value
, 0, 32, FLASHCTRL0_CONFIG_ALL
);
445 buf_set_u32(reg_params
[1].value
, 0, 32, count
);
446 buf_set_u32(reg_params
[2].value
, 0, 32, source
->address
);
447 buf_set_u32(reg_params
[3].value
, 0, 32, source
->address
+ source
->size
);
448 buf_set_u32(reg_params
[4].value
, 0, 32, address
);
450 armv7m_info
.common_magic
= ARMV7M_COMMON_MAGIC
;
451 armv7m_info
.core_mode
= ARM_MODE_THREAD
;
453 ret
= target_run_flash_async_algorithm(target
, buf
, count
, 2, 0, NULL
, 5,
454 reg_params
, source
->address
, source
->size
, write_algorithm
->address
,
457 if (ret
== ERROR_FLASH_OPERATION_FAILED
) {
458 LOG_ERROR("flash write failed at address 0x%"PRIx32
,
459 buf_get_u32(reg_params
[4].value
, 0, 32));
462 target_free_working_area(target
, source
);
463 target_free_working_area(target
, write_algorithm
);
465 destroy_reg_param(®_params
[0]);
466 destroy_reg_param(®_params
[1]);
467 destroy_reg_param(®_params
[2]);
468 destroy_reg_param(®_params
[3]);
469 destroy_reg_param(®_params
[4]);
474 static int sim3x_flash_write(struct flash_bank
*bank
, const uint8_t * buffer
, uint32_t offset
, uint32_t count
)
477 struct target
*target
;
478 struct sim3x_info
*sim3x_info
;
479 uint8_t *new_buffer
= NULL
;
481 target
= bank
->target
;
483 /* Check if target is halted */
484 if (target
->state
!= TARGET_HALTED
) {
485 LOG_ERROR("Target not halted");
486 return ERROR_TARGET_NOT_HALTED
;
489 sim3x_info
= bank
->driver_priv
;
491 if (sim3x_info
->flash_locked
) {
492 LOG_ERROR("Falsh is locked");
496 /* Init MCU after reset */
497 if (sim3x_info
->need_init
) {
498 ret
= sim3x_init(bank
);
504 LOG_ERROR("offset 0x%" PRIx32
" breaks required 2-byte alignment", offset
);
505 return ERROR_FLASH_DST_BREAKS_ALIGNMENT
;
509 uint32_t old_count
= count
;
511 new_buffer
= malloc(count
);
513 if (new_buffer
== NULL
) {
514 LOG_ERROR("odd number of bytes to write and no memory "
515 "for padding buffer");
518 LOG_INFO("odd number of bytes to write (%" PRIu32
"), extending to %" PRIu32
519 " and padding with 0xff", old_count
, count
);
521 new_buffer
[count
- 1] = 0xff;
522 buffer
= memcpy(new_buffer
, buffer
, old_count
);
525 ret
= sim3x_write_block(bank
, buffer
, offset
, count
/ 2);
530 static int sim3x_flash_lock_check(struct flash_bank
*bank
)
534 struct sim3x_info
*sim3x_info
;
536 ret
= target_read_u32(bank
->target
, LOCK_WORD_ADDRESS
, &lock_word
);
537 if (ret
!= ERROR_OK
) {
538 LOG_ERROR("Can not read Lock Word");
542 sim3x_info
= bank
->driver_priv
;
543 sim3x_info
->flash_locked
= (lock_word
!= 0xFFFFFFFF);
548 static int sim3x_flash_protect_check(struct flash_bank
*bank
)
551 struct sim3x_info
*sim3x_info
;
553 /* Check if target is halted */
554 if (bank
->target
->state
!= TARGET_HALTED
) {
555 LOG_ERROR("Target not halted");
556 return ERROR_TARGET_NOT_HALTED
;
559 ret
= sim3x_flash_lock_check(bank
);
563 sim3x_info
= bank
->driver_priv
;
565 for (i
= 0; i
< bank
->num_sectors
; i
++)
566 bank
->sectors
[i
].is_protected
= sim3x_info
->flash_locked
;
571 static int sim3x_flash_protect(struct flash_bank
*bank
, int set
, int first
, int last
)
574 uint8_t lock_word
[4];
575 struct sim3x_info
*sim3x_info
;
576 struct target
*target
;
578 target
= bank
->target
;
580 /* Check if target is halted */
581 if (target
->state
!= TARGET_HALTED
) {
582 LOG_ERROR("Target not halted");
583 return ERROR_TARGET_NOT_HALTED
;
586 if (first
!= 0 || last
!= bank
->num_sectors
- 1) {
587 LOG_ERROR("Flash does not support finer granularity");
591 sim3x_info
= bank
->driver_priv
;
594 if (sim3x_info
->flash_locked
) {
595 LOG_INFO("Flash is already locked");
600 target_buffer_set_u32(target
, lock_word
, 0xFFFFFFFE);
601 ret
= sim3x_flash_write(bank
, lock_word
, LOCK_WORD_ADDRESS
, 4);
606 /* Flash is unlocked by an erase operation */
607 ret
= sim3x_flash_erase(bank
, 0, 0);
612 ret
= sim3x_flash_protect_check(bank
);
617 if (sim3x_info
->flash_locked
) {
618 LOG_INFO("Flash locked");
621 LOG_ERROR("Flash lock error");
625 if (sim3x_info
->flash_locked
) {
626 LOG_ERROR("Flash unlock error");
629 LOG_INFO("Flash unlocked");
635 static int sim3x_read_deviceid(struct flash_bank
*bank
)
638 struct sim3x_info
*sim3x_info
;
642 char part_num_string
[4];
644 sim3x_info
= bank
->driver_priv
;
647 ret
= target_read_u32(bank
->target
, DEVICEID0_DEVICEID2
, &device_id
);
651 /* Device ID should be 'M3' */
652 if (device_id
!= 0x00004D33)
655 /* Family and Part number */
656 ret
= target_read_u32(bank
->target
, DEVICEID0_DEVICEID1
, &device_id
);
660 part_num_string
[0] = device_id
>> 16;
661 part_num_string
[1] = device_id
>> 8;
662 part_num_string
[2] = device_id
;
663 part_num_string
[3] = 0;
665 part_number
= atoi(part_num_string
);
667 /* Part Number should be between 100 and 999 */
668 if (!isalpha(device_id
>> 24) || part_number
< 100 || part_number
> 999)
671 sim3x_info
->part_family
= device_id
>> 24;
672 sim3x_info
->part_number
= part_number
;
674 /* Package and Revision */
675 ret
= target_read_u32(bank
->target
, DEVICEID0_DEVICEID0
, &device_id
);
679 sim3x_info
->device_package
[0] = device_id
>> 24;
680 sim3x_info
->device_package
[1] = device_id
>> 16;
681 sim3x_info
->device_package
[2] = device_id
>> 8;
682 sim3x_info
->device_package
[3] = 0;
684 sim3x_info
->device_revision
= device_id
;
689 static int sim3x_parse_part_info(struct sim3x_info
*sim3x_info
)
691 switch (sim3x_info
->part_number
) {
694 sim3x_info
->flash_size_kb
= 32;
698 sim3x_info
->flash_size_kb
= 64;
703 sim3x_info
->flash_size_kb
= 128;
708 sim3x_info
->flash_size_kb
= 256;
711 LOG_ERROR("Unknown Part number %d", sim3x_info
->part_number
);
712 sim3x_info
->part_number
= 0;
716 switch (sim3x_info
->part_family
) {
719 LOG_INFO("SiM3C%d detected", sim3x_info
->part_number
);
723 LOG_INFO("SiM3U%d detected", sim3x_info
->part_number
);
727 LOG_INFO("SiM3L%d detected", sim3x_info
->part_number
);
730 LOG_ERROR("Unsupported MCU family %c", sim3x_info
->part_family
);
731 sim3x_info
->part_family
= 0;
738 static int sim3x_read_info(struct flash_bank
*bank
)
741 struct sim3x_info
*sim3x_info
;
744 sim3x_info
= bank
->driver_priv
;
747 ret
= target_read_u32(bank
->target
, CPUID
, &cpuid
);
748 if (ret
!= ERROR_OK
) {
749 LOG_ERROR("Failed to read CPU ID");
753 if (((cpuid
>> 4) & 0xfff) != 0xc23) {
754 LOG_ERROR("Target is not Cortex-M3");
758 /* Read info from chip */
759 ret
= sim3x_read_deviceid(bank
);
760 if (ret
== ERROR_OK
) {
761 ret
= sim3x_parse_part_info(sim3x_info
);
762 if (ret
!= ERROR_OK
) {
763 LOG_ERROR("Failed to parse info from MCU");
767 LOG_WARNING("Failed to read info from MCU, using info from flash bank parameters");
769 /* Check if flash size is given in flash bank command */
771 LOG_ERROR("Flash size not set in the flash bank command");
775 /* Convert bank size to kb */
776 sim3x_info
->flash_size_kb
= bank
->size
/ 1024;
779 LOG_INFO("Flash size = %dKB", sim3x_info
->flash_size_kb
);
784 static int sim3x_probe(struct flash_bank
*bank
)
787 struct sim3x_info
*sim3x_info
;
789 sim3x_info
= bank
->driver_priv
;
790 sim3x_info
->probed
= false;
791 sim3x_info
->need_init
= true;
793 /* Read info from chip */
794 ret
= sim3x_read_info(bank
);
798 ret
= sim3x_flash_lock_check(bank
);
804 bank
->sectors
= NULL
;
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
, char *buf
, int buf_size
)
842 struct sim3x_info
*sim3x_info
;
844 sim3x_info
= bank
->driver_priv
;
846 /* Read info about chip */
847 ret
= sim3x_read_info(bank
);
852 if (sim3x_info
->part_family
&& sim3x_info
->part_number
) {
853 printed
= snprintf(buf
, buf_size
, "SiM3%c%d", sim3x_info
->part_family
, sim3x_info
->part_number
);
858 return ERROR_BUF_TOO_SMALL
;
861 if (sim3x_info
->device_revision
&& sim3x_info
->device_revision
<= 'Z' - 'A') {
862 printed
= snprintf(buf
, buf_size
, "-%c", sim3x_info
->device_revision
+ 'A');
867 return ERROR_BUF_TOO_SMALL
;
870 printed
= snprintf(buf
, buf_size
, "-G%s", sim3x_info
->device_package
);
875 return ERROR_BUF_TOO_SMALL
;
879 /* Print flash size */
880 printed
= snprintf(buf
, buf_size
, " flash_size = %dKB", sim3x_info
->flash_size_kb
);
884 return ERROR_BUF_TOO_SMALL
;
889 * reg 31:8 - no effect
892 * reg 1:0 - no effect
894 static int ap_write_register(struct adiv5_dap
*dap
, unsigned reg
, uint32_t value
)
897 LOG_DEBUG("DAP_REG[0x%02x] <- %08" PRIX32
, reg
, value
);
899 retval
= dap_queue_ap_write(dap_ap(dap
, SIM3X_AP
), reg
, value
);
900 if (retval
!= ERROR_OK
) {
901 LOG_DEBUG("DAP: failed to queue a write request");
905 retval
= dap_run(dap
);
906 if (retval
!= ERROR_OK
) {
907 LOG_DEBUG("DAP: dap_run failed");
914 static int ap_read_register(struct adiv5_dap
*dap
, unsigned reg
, uint32_t *result
)
918 retval
= dap_queue_ap_read(dap_ap(dap
, SIM3X_AP
), reg
, result
);
919 if (retval
!= ERROR_OK
) {
920 LOG_DEBUG("DAP: failed to queue a read request");
924 retval
= dap_run(dap
);
925 if (retval
!= ERROR_OK
) {
926 LOG_DEBUG("DAP: dap_run failed");
930 LOG_DEBUG("DAP_REG[0x%02x]: %08" PRIX32
, reg
, *result
);
934 static int ap_poll_register(struct adiv5_dap
*dap
, unsigned reg
, uint32_t mask
, uint32_t value
, int timeout
)
940 retval
= ap_read_register(dap
, reg
, &val
);
941 if (retval
!= ERROR_OK
|| (val
& mask
) == value
)
947 LOG_DEBUG("DAP: polling timed out");
951 COMMAND_HANDLER(sim3x_mass_erase
)
956 struct target
*target
= get_current_target(CMD_CTX
);
957 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
958 struct adiv5_dap
*dap
= cortex_m
->armv7m
.arm
.dap
;
961 /* Used debug interface doesn't support direct DAP access */
962 LOG_ERROR("mass_erase can't be used by this debug interface");
966 ret
= ap_read_register(dap
, SIM3X_AP_ID
, &val
);
970 if (val
!= SIM3X_AP_ID_VALUE
) {
971 LOG_ERROR("Wrong SIM3X_AP_ID");
975 /* Mass erase sequence */
976 ret
= ap_write_register(dap
, SIM3X_AP_CTRL1
, SIM3X_AP_CTRL1_RESET_REQ
);
980 ret
= ap_write_register(dap
, SIM3X_AP_CTRL1
, SIM3X_AP_CTRL1_RESET_REQ
| SIM3X_AP_CTRL1_MASS_ERASE_REQ
);
984 ret
= ap_poll_register(dap
, SIM3X_AP_CTRL1
, SIM3X_AP_CTRL1_MASS_ERASE_REQ
, 0x00000000, FLASH_BUSY_TIMEOUT
);
988 ret
= ap_write_register(dap
, SIM3X_AP_CTRL1
, 0x00000000); /* clear SIM3X_AP_CTRL1_RESET_REQ */
992 LOG_INFO("Mass erase success");
996 COMMAND_HANDLER(sim3x_lock
)
1001 struct target
*target
= get_current_target(CMD_CTX
);
1002 struct cortex_m_common
*cortex_m
= target_to_cm(target
);
1003 struct adiv5_dap
*dap
= cortex_m
->armv7m
.arm
.dap
;
1006 /* Used debug interface doesn't support direct DAP access */
1007 LOG_INFO("Target can't by unlocked by this debug interface");
1010 ret
= target_read_u32(target
, CPUID
, &val
);
1011 if (ret
!= ERROR_OK
)
1014 if ((val
& CPUID_CHECK_VALUE_MASK
) != CPUID_CHECK_VALUE
) {
1015 LOG_ERROR("Target is not ARM Cortex-M3 or is already locked");
1019 /* check SIM3X_AP_ID */
1020 ret
= ap_read_register(dap
, SIM3X_AP_ID
, &val
);
1021 if (ret
!= ERROR_OK
)
1024 if (val
!= SIM3X_AP_ID_VALUE
) {
1025 LOG_ERROR("Wrong SIM3X_AP_ID");
1029 /* check if locked */
1030 ret
= target_read_u32(target
, CPUID
, &val
);
1031 /* if correct value is read, then it will continue */
1032 if (ret
!= ERROR_OK
|| (val
& CPUID_CHECK_VALUE_MASK
) != CPUID_CHECK_VALUE
) {
1033 /* if correct value is'n read, then it will check SIM3X_AP_INIT_STAT register */
1034 ret
= ap_read_register(dap
, SIM3X_AP_INIT_STAT
, &val
);
1035 if (ret
!= ERROR_OK
)
1038 if (val
& SIM3X_AP_INIT_STAT_LOCK
) {
1039 LOG_INFO("Target is already locked");
1042 LOG_ERROR("Target doesn't seem to be locked but memory was not read correct");
1048 ret
= target_read_u32(target
, LOCK_WORD_ADDRESS
, &val
);
1049 if (ret
!= ERROR_OK
)
1052 if (val
== LOCK_WORD_MCU_UNLOCKED
) {
1054 uint8_t lock_word
[4];
1055 target_buffer_set_u32(target
, lock_word
, 0xFFFFFFFE);
1057 /* Get Flash Bank */
1058 struct flash_bank
*bank
;
1059 int retval
= CALL_COMMAND_HANDLER(flash_command_get_bank
, 0, &bank
);
1060 if (retval
!= ERROR_OK
)
1063 ret
= sim3x_flash_write(bank
, lock_word
, LOCK_WORD_ADDRESS
, 4);
1064 if (ERROR_OK
!= ret
)
1067 LOG_INFO("Target is successfully locked");
1069 } else if (val
== LOCK_WORD_MCU_UNLOCKED_BY_FIRMWARE
) {
1070 /* Can't by locked again without erase, because LOCK_WORD is in FLASH */
1071 LOG_ERROR("Target is unlocked by firmware and can't by locked again without the lock page erase or mass erase");
1074 LOG_ERROR("Unexpected lock word value");
1076 /* SIM3X_AP_ID_VALUE is not checked */
1078 LOG_INFO("Maybe this isn't a SiM3x MCU");
1084 static const struct command_registration sim3x_exec_command_handlers
[] = {
1086 .name
= "mass_erase",
1087 .mode
= COMMAND_EXEC
,
1088 .help
= "Erase the complete flash",
1090 .handler
= sim3x_mass_erase
,
1094 .mode
= COMMAND_EXEC
,
1095 .help
= "Locks the flash. Unlock by mass erase",
1097 .handler
= sim3x_lock
,
1099 COMMAND_REGISTRATION_DONE
1102 static const struct command_registration sim3x_command_handlers
[] = {
1105 .mode
= COMMAND_ANY
,
1106 .help
= "sim3x flash command group",
1108 .chain
= sim3x_exec_command_handlers
,
1110 COMMAND_REGISTRATION_DONE
1113 const struct flash_driver sim3x_flash
= {
1115 .commands
= sim3x_command_handlers
,
1116 .flash_bank_command
= sim3x_flash_bank_command
,
1117 .erase
= sim3x_flash_erase
,
1118 .protect
= sim3x_flash_protect
,
1119 .write
= sim3x_flash_write
,
1120 .read
= default_flash_read
,
1121 .probe
= sim3x_probe
,
1122 .auto_probe
= sim3x_auto_probe
,
1123 .erase_check
= default_flash_blank_check
,
1124 .protect_check
= sim3x_flash_protect_check
,
1125 .info
= sim3x_flash_info
,
1126 .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)