OpenOCD
sim3x.c
Go to the documentation of this file.
1 /***************************************************************************
2  * Copyright (C) 2014 by Ladislav Bábel *
3  * ladababel@seznam.cz *
4  * *
5  * Copyright (C) 2015 by Andreas Bomholtz *
6  * andreas@seluxit.com *
7  * *
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. *
12  * *
13  * This program is distributed in the hope that it will be useful, *
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of *
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
16  * GNU General Public License for more details. *
17  * *
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  ***************************************************************************/
21 
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25 
26 #include "imp.h"
27 #include <helper/binarybuffer.h>
28 #include <helper/time_support.h>
29 #include <target/algorithm.h>
30 #include <target/cortex_m.h>
31 
32 /* SI32_DEVICEID0 */
33 #define DEVICEID0_DEVICEID0 (0x400490C0)
34 #define DEVICEID0_DEVICEID1 (0x400490D0)
35 #define DEVICEID0_DEVICEID2 (0x400490E0)
36 #define DEVICEID0_DEVICEID3 (0x400490F0)
37 
38 /* cortex_m CPUID */
39 #define CPUID_CHECK_VALUE (0x410FC230)
40 #define CPUID_CHECK_VALUE_MASK (0xFF0FFFF0)
41 
42 /* Flash */
43 #define FLASH_BASE_ADDRESS (0x00000000)
44 #define LOCK_WORD_ADDRESS (0x0003FFFC)
45 
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)
49 
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)
56 
57 #define FLASHCTRL0_WRADDR (0x4002E0A0)
58 #define FLASHCTRL0_WRDATA (0x4002E0B0)
59 
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)
65 
66 #define FLASH_BUSY_TIMEOUT (100)
67 
68 /* SI32_RSTSRC_0 */
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)
74 
75 /* SI32_VMON_0 */
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)
80 
81 /* SI32_CLKCTRL_0 */
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)
86 
87 /* SI32_WDTIMER_0 */
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)
92 
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)
98 
99 #define WDTIMER0_THRESHOLD (0x40030020)
100 
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)
108 
109 /* DAP */
110 #define SIM3X_AP (0x0A)
111 
112 #define SIM3X_AP_CTRL1 (0x00)
113 #define SIM3X_AP_CTRL2 (0x04)
114 #define SIM3X_AP_LOCK (0x08)
115 #define SIM3X_AP_CRC (0x0C)
116 
117 #define SIM3X_AP_INIT_STAT (0x10)
118 #define SIM3X_AP_DAP_IN (0x14)
119 #define SIM3X_AP_DAP_OUT (0x18)
120 
121 #define SIM3X_AP_ID (0xFC)
122 
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)
130 
131 #define SIM3X_FLASH_PAGE_SIZE 1024
132 
133 struct sim3x_info {
134  uint16_t flash_size_kb;
135  uint16_t part_number;
138  char device_package[4];
139  bool probed;
140  bool need_init;
142 };
143 
144 /* flash bank sim3x 0 0 0 0 <target#> */
145 FLASH_BANK_COMMAND_HANDLER(sim3x_flash_bank_command)
146 {
147  struct sim3x_info *sim3x_info;
148 
149  if (CMD_ARGC < 6)
151 
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;
159 
160  return ERROR_OK;
161 }
162 
163 static int sim3x_init(struct flash_bank *bank)
164 {
165  int ret;
166  struct target *target;
167  struct sim3x_info *sim3x_info;
168 
169  target = bank->target;
170 
171  /* Disable watchdog timer */
173  if (ret != ERROR_OK)
174  return ret;
175 
177  if (ret != ERROR_OK)
178  return ret;
179 
180  /* Enable one write command */
182  if (ret != ERROR_OK)
183  return ret;
184 
186  if (ret != ERROR_OK)
187  return ret;
188 
189  /* Watchdog Timer Debug Mode */
192  if (ret != ERROR_OK)
193  return ret;
194 
195  /* Enable VDD Supply Monitor */
196  ret = target_write_u32(target, VMON0_CONTROL_SET,
198  if (ret != ERROR_OK)
199  return ret;
200 
201  /* Set VDD Supply Monitor as a reset source */
204  if (ret != ERROR_OK)
205  return ret;
206 
207  /* Flash Controller Clock Enable */
210  if (ret != ERROR_OK)
211  return ret;
212 
213  /* Disable Flash Erase Mode */
216  if (ret != ERROR_OK)
217  return ret;
218 
219  sim3x_info = bank->driver_priv;
220  sim3x_info->need_init = 0;
221  return ERROR_OK;
222 }
223 
224 static int sim3x_erase_page(struct flash_bank *bank, uint32_t addr)
225 {
226  int ret, i;
227  uint32_t temp;
228  struct target *target;
229 
230  target = bank->target;
231 
232  for (i = 0; i < FLASH_BUSY_TIMEOUT; i++) {
233  ret = target_read_u32(target, FLASHCTRL0_CONFIG_ALL, &temp);
234  if (ret != ERROR_OK)
235  return ret;
236 
237  /* If is not busy */
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 */
243  FLASHCTRL0_CONFIG_ERASEEN_MASK);
244  if (ret != ERROR_OK)
245  return ret;
246  }
247 
248  /* Write the address of the Flash page to WRADDR */
249  ret = target_write_u32(target, FLASHCTRL0_WRADDR, addr);
250  if (ret != ERROR_OK)
251  return ret;
252 
253  /* Write the inital unlock value to KEY */
254  ret = target_write_u32(target, FLASHCTRL0_KEY,
256  if (ret != ERROR_OK)
257  return ret;
258 
259  /* Write the single unlock value to KEY */
260  ret = target_write_u32(target, FLASHCTRL0_KEY,
262  if (ret != ERROR_OK)
263  return ret;
264 
265  /* Write any value to WRDATA to initiate the page erase */
266  ret = target_write_u32(target, FLASHCTRL0_WRDATA, 0);
267  if (ret != ERROR_OK)
268  return ret;
269 
270  return ERROR_OK;
271  }
272 
273  alive_sleep(1);
274  }
275 
276  LOG_ERROR("timed out waiting for FLASHCTRL0_CONFIG_BUSYF");
277  return ERROR_FAIL;
278 }
279 
280 static int sim3x_flash_erase(struct flash_bank *bank, int first, int last)
281 {
282  int ret, i;
283  uint32_t temp;
284  struct sim3x_info *sim3x_info;
285  struct target *target;
286 
287  /* Check if target is halted */
288  if (bank->target->state != TARGET_HALTED) {
289  LOG_ERROR("Target not halted");
291  }
292 
293  sim3x_info = bank->driver_priv;
294 
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");
300  return ret;
301  }
302  }
303 
304  /* erase pages */
305  for (i = first; i <= last; i++) {
306  ret = sim3x_erase_page(bank, bank->sectors[i].offset);
307  if (ret != ERROR_OK)
308  return ret;
309  }
310 
311  target = bank->target;
312 
313  /* Wait until busy */
314  for (i = 0; i < FLASH_BUSY_TIMEOUT; i++) {
315  ret = target_read_u32(target, FLASHCTRL0_CONFIG_ALL, &temp);
316  if (ret != ERROR_OK)
317  return ret;
318 
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 */
323  FLASHCTRL0_CONFIG_ERASEEN_MASK);
324  if (ret != ERROR_OK)
325  return ret;
326  }
327 
328  return ERROR_OK;
329  }
330 
331  alive_sleep(1);
332  }
333 
334  LOG_ERROR("timed out waiting for FLASHCTRL0_CONFIG_BUSYF");
335  return ERROR_FAIL;
336 }
337 
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)! */
340 {
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;
348  int ret = ERROR_OK;
349 
350  /* see contrib/loaders/flash/sim3x.s for src */
351 
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] */
356 
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] */
360 
361  /* wait_fifo: */
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 */
368 
369  /* wait for BUSYF flag */
370  /* wait_busy1: */
371  0x06, 0x68, /* ldr r6, [r0, #FLASHCTRL_CONFIG] */
372  0x16, 0xF4, 0x80, 0x1F, /* tst r6, #BUSYF */
373  0xFB, 0xD1, /* bne wait_busy1 */
374 
375  /* Write the destination address to WRADDR */
376  0xC0, 0xF8, 0xA0, 0x40, /* str r4, [r0, #FLASHCTRL_WRADDR] */
377 
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] */
381 
382  0x02, 0x35, /* adds r5, #2 */
383  0x02, 0x34, /* adds r4, #2 */
384 
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 */
390 
391  /* no_wrap: */
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 */
397 
398  /* exit: */
399  0x5A, 0x26, /* movs r6, #MULTIPLE_LOCK */
400  0xC0, 0xF8, 0xC0, 0x60, /* str r6, [r0, #FLASHCTRL_KEY] */
401 
402  /* wait for BUSYF flag */
403  /* wait_busy2: */
404  0x06, 0x68, /* ldr r6, [r0, #FLASHCTRL_CONFIG] */
405  0x16, 0xF4, 0x80, 0x1F, /* tst r6, #BUSYF */
406  0xFB, 0xD1, /* bne wait_busy2 */
407 
408  0x00, 0xBE /* bkpt #0 */
409  };
410 
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");
416  }
417 
418  ret = target_write_buffer(target, write_algorithm->address,
419  sizeof(sim3x_flash_write_code), sim3x_flash_write_code);
420  if (ret != ERROR_OK)
421  return ret;
422 
423  /* memory buffer */
424  while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
425  buffer_size /= 2;
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
430  */
431  target_free_working_area(target, write_algorithm);
432 
433  LOG_WARNING("no large enough working area available, can't do block memory writes");
435  }
436  }
437 
438  init_reg_param(&reg_params[0], "r0", 32, PARAM_OUT); /* flash base */
439  init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* count */
440  init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* buffer start */
441  init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* buffer end */
442  init_reg_param(&reg_params[4], "r4", 32, PARAM_IN_OUT); /* target address */
443 
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);
449 
450  armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
451  armv7m_info.core_mode = ARM_MODE_THREAD;
452 
453  ret = target_run_flash_async_algorithm(target, buf, count, 2, 0, NULL, 5,
454  reg_params, source->address, source->size, write_algorithm->address,
455  0, &armv7m_info);
456 
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));
460  }
461 
462  target_free_working_area(target, source);
463  target_free_working_area(target, write_algorithm);
464 
465  destroy_reg_param(&reg_params[0]);
466  destroy_reg_param(&reg_params[1]);
467  destroy_reg_param(&reg_params[2]);
468  destroy_reg_param(&reg_params[3]);
469  destroy_reg_param(&reg_params[4]);
470 
471  return ret;
472 }
473 
474 static int sim3x_flash_write(struct flash_bank *bank, const uint8_t * buffer, uint32_t offset, uint32_t count)
475 {
476  int ret;
477  struct target *target;
478  struct sim3x_info *sim3x_info;
479  uint8_t *new_buffer = NULL;
480 
481  target = bank->target;
482 
483  /* Check if target is halted */
484  if (target->state != TARGET_HALTED) {
485  LOG_ERROR("Target not halted");
487  }
488 
489  sim3x_info = bank->driver_priv;
490 
491  if (sim3x_info->flash_locked) {
492  LOG_ERROR("Falsh is locked");
493  return ERROR_FAIL;
494  }
495 
496  /* Init MCU after reset */
497  if (sim3x_info->need_init) {
498  ret = sim3x_init(bank);
499  if (ret != ERROR_OK)
500  return ret;
501  }
502 
503  if (offset & 0x1) {
504  LOG_ERROR("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
506  }
507 
508  if (count & 0x1) {
509  uint32_t old_count = count;
510  count++;
511  new_buffer = malloc(count);
512 
513  if (new_buffer == NULL) {
514  LOG_ERROR("odd number of bytes to write and no memory "
515  "for padding buffer");
516  return ERROR_FAIL;
517  }
518  LOG_INFO("odd number of bytes to write (%" PRIu32 "), extending to %" PRIu32
519  " and padding with 0xff", old_count, count);
520 
521  new_buffer[count - 1] = 0xff;
522  buffer = memcpy(new_buffer, buffer, old_count);
523  }
524 
525  ret = sim3x_write_block(bank, buffer, offset, count / 2);
526  free(new_buffer);
527  return ret;
528 }
529 
530 static int sim3x_flash_lock_check(struct flash_bank *bank)
531 {
532  int ret;
533  uint32_t lock_word;
534  struct sim3x_info *sim3x_info;
535 
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");
539  return ret;
540  }
541 
542  sim3x_info = bank->driver_priv;
543  sim3x_info->flash_locked = (lock_word != 0xFFFFFFFF);
544 
545  return ERROR_OK;
546 }
547 
548 static int sim3x_flash_protect_check(struct flash_bank *bank)
549 {
550  int ret, i;
551  struct sim3x_info *sim3x_info;
552 
553  /* Check if target is halted */
554  if (bank->target->state != TARGET_HALTED) {
555  LOG_ERROR("Target not halted");
557  }
558 
559  ret = sim3x_flash_lock_check(bank);
560  if (ret != ERROR_OK)
561  return ret;
562 
563  sim3x_info = bank->driver_priv;
564 
565  for (i = 0; i < bank->num_sectors; i++)
566  bank->sectors[i].is_protected = sim3x_info->flash_locked;
567 
568  return ERROR_OK;
569 }
570 
571 static int sim3x_flash_protect(struct flash_bank *bank, int set, int first, int last)
572 {
573  int ret;
574  uint8_t lock_word[4];
575  struct sim3x_info *sim3x_info;
576  struct target *target;
577 
578  target = bank->target;
579 
580  /* Check if target is halted */
581  if (target->state != TARGET_HALTED) {
582  LOG_ERROR("Target not halted");
584  }
585 
586  if (first != 0 || last != bank->num_sectors - 1) {
587  LOG_ERROR("Flash does not support finer granularity");
588  return ERROR_FAIL;
589  }
590 
591  sim3x_info = bank->driver_priv;
592 
593  if (set) {
594  if (sim3x_info->flash_locked) {
595  LOG_INFO("Flash is already locked");
596  return ERROR_OK;
597  }
598 
599  /* Lock Flash */
600  target_buffer_set_u32(target, lock_word, 0xFFFFFFFE);
601  ret = sim3x_flash_write(bank, lock_word, LOCK_WORD_ADDRESS, 4);
602  if (ret != ERROR_OK)
603  return ret;
604 
605  } else {
606  /* Flash is unlocked by an erase operation */
607  ret = sim3x_flash_erase(bank, 0, 0);
608  if (ret != ERROR_OK)
609  return ret;
610  }
611 
612  ret = sim3x_flash_protect_check(bank);
613  if (ret != ERROR_OK)
614  return ret;
615 
616  if (set) {
617  if (sim3x_info->flash_locked) {
618  LOG_INFO("Flash locked");
619  return ERROR_OK;
620  } else {
621  LOG_ERROR("Flash lock error");
622  return ERROR_FAIL;
623  }
624  } else {
625  if (sim3x_info->flash_locked) {
626  LOG_ERROR("Flash unlock error");
627  return ERROR_FAIL;
628  } else {
629  LOG_INFO("Flash unlocked");
630  return ERROR_OK;
631  }
632  }
633 }
634 
635 static int sim3x_read_deviceid(struct flash_bank *bank)
636 {
637  int ret;
638  struct sim3x_info *sim3x_info;
639 
640  uint32_t device_id;
641  int part_number;
642  char part_num_string[4];
643 
644  sim3x_info = bank->driver_priv;
645 
646  /* MCU check */
647  ret = target_read_u32(bank->target, DEVICEID0_DEVICEID2, &device_id);
648  if (ret != ERROR_OK)
649  return ret;
650 
651  /* Device ID should be 'M3' */
652  if (device_id != 0x00004D33)
653  return ERROR_FAIL;
654 
655  /* Family and Part number */
656  ret = target_read_u32(bank->target, DEVICEID0_DEVICEID1, &device_id);
657  if (ret != ERROR_OK)
658  return ret;
659 
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;
664 
665  part_number = atoi(part_num_string);
666 
667  /* Part Number should be between 100 and 999 */
668  if (!isalpha(device_id >> 24) || part_number < 100 || part_number > 999)
669  return ERROR_FAIL;
670 
671  sim3x_info->part_family = device_id >> 24;
672  sim3x_info->part_number = part_number;
673 
674  /* Package and Revision */
675  ret = target_read_u32(bank->target, DEVICEID0_DEVICEID0, &device_id);
676  if (ret != ERROR_OK)
677  return ret;
678 
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;
683 
684  sim3x_info->device_revision = device_id;
685 
686  return ERROR_OK;
687 }
688 
690 {
691  switch (sim3x_info->part_number) {
692  case 134:
693  case 136:
694  sim3x_info->flash_size_kb = 32;
695  break;
696  case 144:
697  case 146:
698  sim3x_info->flash_size_kb = 64;
699  break;
700  case 154:
701  case 156:
702  case 157:
703  sim3x_info->flash_size_kb = 128;
704  break;
705  case 164:
706  case 166:
707  case 167:
708  sim3x_info->flash_size_kb = 256;
709  break;
710  default:
711  LOG_ERROR("Unknown Part number %d", sim3x_info->part_number);
712  sim3x_info->part_number = 0;
713  return ERROR_FAIL;
714  }
715 
716  switch (sim3x_info->part_family) {
717  case 'c':
718  case 'C':
719  LOG_INFO("SiM3C%d detected", sim3x_info->part_number);
720  break;
721  case 'u':
722  case 'U':
723  LOG_INFO("SiM3U%d detected", sim3x_info->part_number);
724  break;
725  case 'l':
726  case 'L':
727  LOG_INFO("SiM3L%d detected", sim3x_info->part_number);
728  break;
729  default:
730  LOG_ERROR("Unsupported MCU family %c", sim3x_info->part_family);
731  sim3x_info->part_family = 0;
732  return ERROR_FAIL;
733  }
734 
735  return ERROR_OK;
736 }
737 
738 static int sim3x_read_info(struct flash_bank *bank)
739 {
740  int ret;
741  struct sim3x_info *sim3x_info;
742  uint32_t cpuid;
743 
744  sim3x_info = bank->driver_priv;
745 
746  /* Core check */
747  ret = target_read_u32(bank->target, CPUID, &cpuid);
748  if (ret != ERROR_OK) {
749  LOG_ERROR("Failed to read CPU ID");
750  return ret;
751  }
752 
753  if (((cpuid >> 4) & 0xfff) != 0xc23) {
754  LOG_ERROR("Target is not Cortex-M3");
755  return ERROR_FAIL;
756  }
757 
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");
764  return ERROR_FAIL;
765  }
766  } else {
767  LOG_WARNING("Failed to read info from MCU, using info from flash bank parameters");
768 
769  /* Check if flash size is given in flash bank command */
770  if (!bank->size) {
771  LOG_ERROR("Flash size not set in the flash bank command");
772  return ERROR_FAIL;
773  }
774 
775  /* Convert bank size to kb */
776  sim3x_info->flash_size_kb = bank->size / 1024;
777  }
778 
779  LOG_INFO("Flash size = %dKB", sim3x_info->flash_size_kb);
780 
781  return ERROR_OK;
782 }
783 
784 static int sim3x_probe(struct flash_bank *bank)
785 {
786  int ret, i;
787  struct sim3x_info *sim3x_info;
788 
789  sim3x_info = bank->driver_priv;
790  sim3x_info->probed = false;
791  sim3x_info->need_init = true;
792 
793  /* Read info from chip */
794  ret = sim3x_read_info(bank);
795  if (ret != ERROR_OK)
796  return ret;
797 
798  ret = sim3x_flash_lock_check(bank);
799  if (ret != ERROR_OK)
800  return ret;
801 
802  if (bank->sectors) {
803  free(bank->sectors);
804  bank->sectors = NULL;
805  }
806 
807  bank->base = FLASH_BASE_ADDRESS;
808  bank->size = sim3x_info->flash_size_kb * SIM3X_FLASH_PAGE_SIZE;
810  bank->sectors = malloc(sizeof(struct flash_sector) * sim3x_info->flash_size_kb);
811 
812  for (i = 0; i < sim3x_info->flash_size_kb; i++) {
813  bank->sectors[i].offset = i * SIM3X_FLASH_PAGE_SIZE;
815  bank->sectors[i].is_erased = -1;
816  bank->sectors[i].is_protected = sim3x_info->flash_locked;
817  }
818 
819  sim3x_info->probed = true;
820 
821  return ERROR_OK;
822 }
823 
824 static int sim3x_auto_probe(struct flash_bank *bank)
825 {
826  struct sim3x_info *sim3x_info;
827 
828  sim3x_info = bank->driver_priv;
829 
830  if (sim3x_info->probed) {
831  sim3x_info->need_init = true;
832  return ERROR_OK;
833  } else {
834  return sim3x_probe(bank);
835  }
836 }
837 
838 static int sim3x_flash_info(struct flash_bank *bank, char *buf, int buf_size)
839 {
840  int ret;
841  int printed = 0;
842  struct sim3x_info *sim3x_info;
843 
844  sim3x_info = bank->driver_priv;
845 
846  /* Read info about chip */
847  ret = sim3x_read_info(bank);
848  if (ret != ERROR_OK)
849  return ret;
850 
851  /* Part */
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);
854  buf += printed;
855  buf_size -= printed;
856 
857  if (buf_size <= 0)
858  return ERROR_BUF_TOO_SMALL;
859 
860  /* Revision */
861  if (sim3x_info->device_revision && sim3x_info->device_revision <= 'Z' - 'A') {
862  printed = snprintf(buf, buf_size, "-%c", sim3x_info->device_revision + 'A');
863  buf += printed;
864  buf_size -= printed;
865 
866  if (buf_size <= 0)
867  return ERROR_BUF_TOO_SMALL;
868 
869  /* Package */
870  printed = snprintf(buf, buf_size, "-G%s", sim3x_info->device_package);
871  buf += printed;
872  buf_size -= printed;
873 
874  if (buf_size <= 0)
875  return ERROR_BUF_TOO_SMALL;
876  }
877  }
878 
879  /* Print flash size */
880  printed = snprintf(buf, buf_size, " flash_size = %dKB", sim3x_info->flash_size_kb);
881  buf_size -= printed;
882 
883  if (buf_size <= 0)
884  return ERROR_BUF_TOO_SMALL;
885 
886  return ERROR_OK;
887 }
894 static int ap_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)
895 {
896  int retval;
897  LOG_DEBUG("DAP_REG[0x%02x] <- %08" PRIX32, reg, value);
898 
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");
902  return retval;
903  }
904 
905  retval = dap_run(dap);
906  if (retval != ERROR_OK) {
907  LOG_DEBUG("DAP: dap_run failed");
908  return retval;
909  }
910 
911  return ERROR_OK;
912 }
913 
914 static int ap_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)
915 {
916  int retval;
917 
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");
921  return retval;
922  }
923 
924  retval = dap_run(dap);
925  if (retval != ERROR_OK) {
926  LOG_DEBUG("DAP: dap_run failed");
927  return retval;
928  }
929 
930  LOG_DEBUG("DAP_REG[0x%02x]: %08" PRIX32, reg, *result);
931  return ERROR_OK;
932 }
933 
934 static int ap_poll_register(struct adiv5_dap *dap, unsigned reg, uint32_t mask, uint32_t value, int timeout)
935 {
936  uint32_t val;
937  int retval;
938 
939  do {
940  retval = ap_read_register(dap, reg, &val);
941  if (retval != ERROR_OK || (val & mask) == value)
942  return retval;
943 
944  alive_sleep(1);
945  } while (timeout--);
946 
947  LOG_DEBUG("DAP: polling timed out");
948  return ERROR_FAIL;
949 }
950 
951 COMMAND_HANDLER(sim3x_mass_erase)
952 {
953  uint32_t val;
954  int ret;
955 
957  struct cortex_m_common *cortex_m = target_to_cm(target);
958  struct adiv5_dap *dap = cortex_m->armv7m.arm.dap;
959 
960  if (dap == NULL) {
961  /* Used debug interface doesn't support direct DAP access */
962  LOG_ERROR("mass_erase can't be used by this debug interface");
963  return ERROR_FAIL;
964  }
965 
966  ret = ap_read_register(dap, SIM3X_AP_ID, &val);
967  if (ret != ERROR_OK)
968  return ret;
969 
970  if (val != SIM3X_AP_ID_VALUE) {
971  LOG_ERROR("Wrong SIM3X_AP_ID");
972  return ERROR_FAIL;
973  }
974 
975  /* Mass erase sequence */
977  if (ret != ERROR_OK)
978  return ret;
979 
981  if (ret != ERROR_OK)
982  return ret;
983 
985  if (ret != ERROR_OK)
986  return ret;
987 
988  ret = ap_write_register(dap, SIM3X_AP_CTRL1, 0x00000000); /* clear SIM3X_AP_CTRL1_RESET_REQ */
989  if (ret != ERROR_OK)
990  return ret;
991 
992  LOG_INFO("Mass erase success");
993  return ERROR_OK;
994 }
995 
996 COMMAND_HANDLER(sim3x_lock)
997 {
998  uint32_t val;
999  int ret;
1000 
1002  struct cortex_m_common *cortex_m = target_to_cm(target);
1003  struct adiv5_dap *dap = cortex_m->armv7m.arm.dap;
1004 
1005  if (dap == NULL) {
1006  /* Used debug interface doesn't support direct DAP access */
1007  LOG_INFO("Target can't by unlocked by this debug interface");
1008 
1009  /* Core check */
1010  ret = target_read_u32(target, CPUID, &val);
1011  if (ret != ERROR_OK)
1012  return ret;
1013 
1014  if ((val & CPUID_CHECK_VALUE_MASK) != CPUID_CHECK_VALUE) {
1015  LOG_ERROR("Target is not ARM Cortex-M3 or is already locked");
1016  return ERROR_FAIL;
1017  }
1018  } else {
1019  /* check SIM3X_AP_ID */
1020  ret = ap_read_register(dap, SIM3X_AP_ID, &val);
1021  if (ret != ERROR_OK)
1022  return ret;
1023 
1024  if (val != SIM3X_AP_ID_VALUE) {
1025  LOG_ERROR("Wrong SIM3X_AP_ID");
1026  return ERROR_FAIL;
1027  }
1028 
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)
1036  return ret;
1037 
1038  if (val & SIM3X_AP_INIT_STAT_LOCK) {
1039  LOG_INFO("Target is already locked");
1040  return ERROR_OK;
1041  } else {
1042  LOG_ERROR("Target doesn't seem to be locked but memory was not read correct");
1043  return ERROR_FAIL;
1044  }
1045  }
1046  }
1047 
1048  ret = target_read_u32(target, LOCK_WORD_ADDRESS, &val);
1049  if (ret != ERROR_OK)
1050  return ret;
1051 
1052  if (val == LOCK_WORD_MCU_UNLOCKED) {
1053  /* Lock Flash */
1054  uint8_t lock_word[4];
1055  target_buffer_set_u32(target, lock_word, 0xFFFFFFFE);
1056 
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)
1061  return retval;
1062 
1063  ret = sim3x_flash_write(bank, lock_word, LOCK_WORD_ADDRESS, 4);
1064  if (ERROR_OK != ret)
1065  return ret;
1066 
1067  LOG_INFO("Target is successfully locked");
1068  return ERROR_OK;
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");
1072  return ERROR_FAIL;
1073  } else {
1074  LOG_ERROR("Unexpected lock word value");
1075 
1076  /* SIM3X_AP_ID_VALUE is not checked */
1077  if (dap == NULL)
1078  LOG_INFO("Maybe this isn't a SiM3x MCU");
1079 
1080  return ERROR_FAIL;
1081  }
1082 }
1083 
1085  {
1086  .name = "mass_erase",
1087  .mode = COMMAND_EXEC,
1088  .help = "Erase the complete flash",
1089  .usage = "",
1090  .handler = sim3x_mass_erase,
1091  },
1092  {
1093  .name = "lock",
1094  .mode = COMMAND_EXEC,
1095  .help = "Locks the flash. Unlock by mass erase",
1096  .usage = "",
1097  .handler = sim3x_lock,
1098  },
1100 };
1101 
1103  {
1104  .name = "sim3x",
1105  .mode = COMMAND_ANY,
1106  .help = "sim3x flash command group",
1107  .usage = "",
1108  .chain = sim3x_exec_command_handlers,
1109  },
1111 };
1112 
1114  .name = "sim3x",
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 };
#define RSTSRC0_RESETEN_VMONREN_MASK
Definition: sim3x.c:72
#define FLASHCTRL0_CONFIG_CLR
Definition: sim3x.c:53
#define ERROR_FLASH_OPERATION_FAILED
Definition: flash/common.h:40
#define DEVICEID0_DEVICEID1
Definition: sim3x.c:34
static int sim3x_flash_erase(struct flash_bank *bank, int first, int last)
Definition: sim3x.c:280
#define LOG_DEBUG(expr...)
Definition: log.h:115
#define FLASH_BUSY_TIMEOUT
Definition: sim3x.c:66
#define WDTIMER0_CONTROL_DBGMD_MASK
Definition: sim3x.c:91
int target_write_u32(struct target *target, target_addr_t address, uint32_t value)
#define FLASHCTRL0_KEY
Definition: sim3x.c:60
#define FLASHCTRL0_CONFIG_SET
Definition: sim3x.c:52
unsigned short addr
Definition: embeddedice.c:56
unsigned mask
Definition: cortex_m.c:2212
Provides the implementation-independent structure that defines all of the callbacks required by OpenO...
uint32_t offset
Bus offset from start of the flash chip (in bytes).
Definition: nor/core.h:43
#define ERROR_BUF_TOO_SMALL
Definition: log.h:146
#define ERROR_FLASH_DST_BREAKS_ALIGNMENT
Definition: flash/common.h:42
#define SIM3X_AP_ID_VALUE
Definition: sim3x.c:129
static int dap_run(struct adiv5_dap *dap)
Perform all queued DAP operations, and clear any errors posted in the CTRL_STAT register when they ar...
Definition: arm_adi_v5.h:393
uint32_t size
The size of this chip bank, in bytes.
Definition: nor/core.h:88
This represents an ARM Debug Interface (v5) Debug Access Port (DAP).
Definition: arm_adi_v5.h:202
static int sim3x_probe(struct flash_bank *bank)
Definition: sim3x.c:784
uint16_t part_number
Definition: sim3x.c:135
#define SIM3X_AP_CTRL1_RESET_REQ
Definition: sim3x.c:125
static int sim3x_write_block(struct flash_bank *bank, const uint8_t *buf, uint32_t offset, uint32_t count)
Definition: sim3x.c:338
static int sim3x_flash_write(struct flash_bank *bank, const uint8_t *buffer, uint32_t offset, uint32_t count)
Definition: sim3x.c:474
#define SIM3X_AP_ID
Definition: sim3x.c:121
static int sim3x_parse_part_info(struct sim3x_info *sim3x_info)
Definition: sim3x.c:689
struct armv7m_common armv7m
Definition: cortex_m.h:190
#define LOG_INFO(expr...)
Definition: log.h:123
#define DEVICEID0_DEVICEID0
Definition: sim3x.c:33
#define ERROR_TARGET_NOT_HALTED
Definition: target.h:689
uint32_t size
Number of bytes in this flash sector.
Definition: nor/core.h:45
#define CALL_COMMAND_HANDLER(name, extra...)
Use this to macro to call a command helper (or a nested handler).
Definition: command.h:93
#define CLKCTRL0_APBCLKG0_SET
Definition: sim3x.c:83
void * driver_priv
Private driver storage pointer.
Definition: nor/core.h:84
struct flash_driver sim3x_flash
Definition: sim3x.c:1113
static int sim3x_init(struct flash_bank *bank)
Definition: sim3x.c:163
#define DEVICEID0_DEVICEID2
Definition: sim3x.c:35
struct flash_sector * sectors
Array of sectors, allocated and initialized by the flash driver.
Definition: nor/core.h:107
#define ERROR_FAIL
Definition: log.h:150
COMMAND_HANDLER(sim3x_mass_erase)
Definition: sim3x.c:951
Support functions to access arbitrary bits in a byte array.
static int dap_queue_ap_read(struct adiv5_ap *ap, unsigned reg, uint32_t *data)
Queue an AP register read.
Definition: arm_adi_v5.h:343
#define CPUID_CHECK_VALUE
Definition: sim3x.c:39
int default_flash_read(struct flash_bank *bank, uint8_t *buffer, uint32_t offset, uint32_t count)
Provides default read implementation for flash memory.
#define CMD_ARGC
Use this macro to access the number of arguments for the command being handled, rather than accessing...
Definition: command.h:121
#define WDTIMER0_KEY_DISABLE
Definition: sim3x.c:105
static const struct command_registration sim3x_command_handlers[]
Definition: sim3x.c:1102
#define FLASHCTRL0_WRADDR
Definition: sim3x.c:57
void init_reg_param(struct reg_param *param, char *reg_name, uint32_t size, enum param_direction direction)
Definition: algorithm.c:40
#define FLASHCTRL0_KEY_INITIAL_UNLOCK
Definition: sim3x.c:61
#define CLKCTRL0_APBCLKG0_FLCTRLCEN_MASK
Definition: sim3x.c:85
static const struct command_registration sim3x_exec_command_handlers[]
Definition: sim3x.c:1084
int default_flash_blank_check(struct flash_bank *bank)
Provides default erased-bank check handling.
#define WDTIMER0_CONTROL_SET
Definition: sim3x.c:89
int target_free_working_area(struct target *target, struct working_area *area)
static void buf_set_u32(uint8_t *_buffer, unsigned first, unsigned num, uint32_t value)
Sets num bits in _buffer, starting at the first bit, using the bits in value.
Definition: binarybuffer.h:40
#define WDTIMER0_KEY_WRITE
Definition: sim3x.c:103
const char * name
Gives a human-readable name of this flash driver, This field is used to select and initialize the dri...
#define FLASH_BASE_ADDRESS
Definition: sim3x.c:43
static int ap_poll_register(struct adiv5_dap *dap, unsigned reg, uint32_t mask, uint32_t value, int timeout)
Definition: sim3x.c:934
enum arm_mode core_mode
Definition: armv7m.h:185
int target_read_u32(struct target *target, target_addr_t address, uint32_t *value)
bool need_init
Definition: sim3x.c:140
#define WDTIMER0_WDTKEY
Definition: sim3x.c:101
int is_erased
Indication of erasure status: 0 = not erased, 1 = erased, other = unknown.
Definition: nor/core.h:52
static int sim3x_read_deviceid(struct flash_bank *bank)
Definition: sim3x.c:635
#define ARMV7M_COMMON_MAGIC
Definition: armv7m.h:142
#define FLASHCTRL0_CONFIG_ERASEEN_MASK
Definition: sim3x.c:54
#define COMMAND_REGISTRATION_DONE
Use this as the last entry in an array of command_registration records.
Definition: command.h:222
void target_buffer_set_u32(struct target *target, uint8_t *buffer, uint32_t value)
#define RSTSRC0_RESETEN_SET
Definition: sim3x.c:70
#define LOG_ERROR(expr...)
Definition: log.h:129
#define ERROR_COMMAND_SYNTAX_ERROR
Definition: command.h:338
bool flash_locked
Definition: sim3x.c:141
#define FLASHCTRL0_CONFIG_ALL
Definition: sim3x.c:51
#define SIM3X_AP
Definition: sim3x.c:110
enum target_state state
Definition: target.h:168
static int sim3x_flash_protect(struct flash_bank *bank, int set, int first, int last)
Definition: sim3x.c:571
static struct adiv5_ap * dap_ap(struct adiv5_dap *dap, uint8_t ap_num)
Definition: arm_adi_v5.h:488
bool probed
Definition: sim3x.c:139
const char * name
Definition: command.h:203
#define CMD_CTX
Use this macro to access the context of the command being handled, rather than accessing the variable...
Definition: command.h:116
struct target * get_current_target(struct command_context *cmd_ctx)
Definition: register.h:116
#define SIM3X_AP_INIT_STAT_LOCK
Definition: sim3x.c:127
struct target * target
Target to which this bank belongs.
Definition: nor/core.h:81
#define SIM3X_AP_INIT_STAT
Definition: sim3x.c:117
static int dap_queue_ap_write(struct adiv5_ap *ap, unsigned reg, uint32_t data)
Queue an AP register write.
Definition: arm_adi_v5.h:359
#define CPUID
Definition: cortex_m.h:40
int target_write_buffer(struct target *target, target_addr_t address, uint32_t size, const uint8_t *buffer)
static int sim3x_flash_protect_check(struct flash_bank *bank)
Definition: sim3x.c:548
static int sim3x_read_info(struct flash_bank *bank)
Definition: sim3x.c:738
char device_package[4]
Definition: sim3x.c:138
struct adiv5_dap * dap
For targets conforming to ARM Debug Interface v5, this handle references the Debug Access Port (DAP) ...
Definition: arm.h:201
#define ERROR_TARGET_RESOURCE_NOT_AVAILABLE
Definition: target.h:693
#define VMON0_CONTROL_SET
Definition: sim3x.c:77
int target_alloc_working_area(struct target *target, uint32_t size, struct working_area **area)
static uint32_t buf_get_u32(const uint8_t *_buffer, unsigned first, unsigned num)
Retrieves num bits from _buffer, starting at the first bit, returning the bits in a 32-bit word...
Definition: binarybuffer.h:107
int target_run_flash_async_algorithm(struct target *target, const uint8_t *buffer, uint32_t count, int block_size, int num_mem_params, struct mem_param *mem_params, int num_reg_params, struct reg_param *reg_params, uint32_t buffer_start, uint32_t buffer_size, uint32_t entry_point, uint32_t exit_point, void *arch_info)
Executes a target-specific native code algorithm in the target.
static struct cortex_m_common * target_to_cm(struct target *target)
Definition: cortex_m.h:196
static int ap_read_register(struct adiv5_dap *dap, unsigned reg, uint32_t *result)
Definition: sim3x.c:914
uint16_t flash_size_kb
Definition: sim3x.c:134
struct arm arm
Definition: armv7m.h:145
int num_sectors
The number of sectors on this chip.
Definition: nor/core.h:105
Provides details of a flash bank, available either on-chip or through a major interface.
Definition: nor/core.h:78
#define SIM3X_AP_CTRL1_MASS_ERASE_REQ
Definition: sim3x.c:124
#define LOCK_WORD_ADDRESS
Definition: sim3x.c:44
void destroy_reg_param(struct reg_param *param)
Definition: algorithm.c:48
#define ERROR_OK
Definition: log.h:144
void alive_sleep(uint64_t ms)
Definition: helper/log.c:465
#define WDTIMER0_KEY_ATTN
Definition: sim3x.c:102
static int sim3x_flash_info(struct flash_bank *bank, char *buf, int buf_size)
Definition: sim3x.c:838
static int count
Definition: helper/log.c:62
int target_alloc_working_area_try(struct target *target, uint32_t size, struct working_area **area)
static int sim3x_flash_lock_check(struct flash_bank *bank)
Definition: sim3x.c:530
FLASH_BANK_COMMAND_HANDLER(sim3x_flash_bank_command)
Definition: sim3x.c:145
uint32_t size
Definition: target.h:97
#define VMON0_CONTROL_VMONEN_MASK
Definition: sim3x.c:79
#define LOCK_WORD_MCU_UNLOCKED_BY_FIRMWARE
Definition: sim3x.c:48
static int sim3x_erase_page(struct flash_bank *bank, uint32_t addr)
Definition: sim3x.c:224
char part_family
Definition: sim3x.c:136
int common_magic
Definition: armv7m.h:183
#define NULL
Definition: usb.h:27
#define FLASHCTRL0_KEY_SINGLE_UNLOCK
Definition: sim3x.c:62
int is_protected
Indication of protection status: 0 = unprotected/unlocked, 1 = protected/locked, other = unknown...
Definition: nor/core.h:65
#define LOCK_WORD_MCU_UNLOCKED
Definition: sim3x.c:46
#define FLASHCTRL0_CONFIG_BUSYF_MASK
Definition: sim3x.c:55
static int ap_write_register(struct adiv5_dap *dap, unsigned reg, uint32_t value)
reg 31:8 - no effect reg 7:4 - bank reg 3:2 - register reg 1:0 - no effect
Definition: sim3x.c:894
Describes the geometry and status of a single flash sector within a flash bank.
Definition: nor/core.h:41
#define FLASHCTRL0_WRDATA
Definition: sim3x.c:58
#define LOG_WARNING(expr...)
Definition: log.h:126
#define SIM3X_FLASH_PAGE_SIZE
Definition: sim3x.c:131
Definition: target.h:126
uint32_t base
The base address of this bank.
Definition: nor/core.h:87
#define CPUID_CHECK_VALUE_MASK
Definition: sim3x.c:40
target_addr_t address
Definition: target.h:96
#define SIM3X_AP_CTRL1
Definition: sim3x.c:112
uint8_t device_revision
Definition: sim3x.c:137
static int sim3x_auto_probe(struct flash_bank *bank)
Definition: sim3x.c:824