jtag: linuxgpiod: drop extra parenthesis
[openocd.git] / src / flash / nor / niietcm4.c
1 /***************************************************************************
2 * Copyright (C) 2015 by Bogdan Kolbov *
3 * kolbov@niiet.ru *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 2 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program. If not, see <http://www.gnu.org/licenses/>. *
17 ***************************************************************************/
18
19 #ifdef HAVE_CONFIG_H
20 #include "config.h"
21 #endif
22
23 #include "imp.h"
24 #include <helper/binarybuffer.h>
25 #include <target/algorithm.h>
26 #include <target/armv7m.h>
27
28 #define FLASH_DRIVER_VER 0x00010000
29 #define CHIPID_ADDR 0xF0000000
30 #define K1921VK01T_ID 0x00000000
31
32 /*==============================================================================
33 * FLASH CONTROL REGS
34 *==============================================================================
35 */
36
37 #define MAIN_MEM_TYPE 0
38 #define INFO_MEM_TYPE 1
39 #define SERVICE_MODE_ERASE_ADDR 0x80030164
40 #define MAGIC_KEY 0xA442
41
42 /*-- BOOTFLASH ---------------------------------------------------------------*/
43 #define BOOTFLASH_BASE 0xA001C000
44 #define FMA (BOOTFLASH_BASE + 0x00)
45 #define FMD1 (BOOTFLASH_BASE + 0x04)
46 #define FMC (BOOTFLASH_BASE + 0x08)
47 #define FCIS (BOOTFLASH_BASE + 0x0C)
48 #define FCIM (BOOTFLASH_BASE + 0x10)
49 #define FCIC (BOOTFLASH_BASE + 0x14)
50 #define FMD2 (BOOTFLASH_BASE + 0x50)
51 #define FMD3 (BOOTFLASH_BASE + 0x54)
52 #define FMD4 (BOOTFLASH_BASE + 0x58)
53
54
55 /*---- FMC: Command register */
56 #define FMC_WRITE (1<<0) /* Writing in main region */
57 #define FMC_PAGE_ERASE (1<<1) /* Page erase the main region */
58 #define FMC_FULL_ERASE (1<<2) /* Erase full flash */
59 #define FMC_WRITE_IFB (1<<4) /* Writing in info region */
60 #define FMC_PAGEERASE_IFB (1<<5) /* Erase page of info region */
61 #define FMC_MAGIC_KEY (MAGIC_KEY<<16) /* Operation run command */
62
63 /*---- FCIS: Status register */
64 #define FCIS_OP_CMLT (1<<0) /* Completion flag operation */
65 #define FCIS_OP_ERROR (1<<1) /* Flag operation error */
66
67 /*---- FCIC: CLear status register */
68 #define FCIC_CLR_OPCMLT (1<<0) /* Clear completion flag in register FCIS */
69 #define FCIC_CLR_OPERROR (1<<1) /* Clear error flag in register FCIS */
70
71 /*-- USERFLASH ---------------------------------------------------------------*/
72 #define USERFLASH_PAGE_SIZE 256
73 #define USERFLASH_PAGE_TOTALNUM 256
74
75 #define USERFLASH_BASE 0xA0022000
76 #define UFMA (USERFLASH_BASE + 0x00)
77 #define UFMD (USERFLASH_BASE + 0x04)
78 #define UFMC (USERFLASH_BASE + 0x08)
79 #define UFCIS (USERFLASH_BASE + 0x0C)
80 #define UFCIM (USERFLASH_BASE + 0x10)
81 #define UFCIC (USERFLASH_BASE + 0x14)
82
83 /*---- UFMC: Command register */
84 #define UFMC_WRITE (1<<0) /* Writing in main region */
85 #define UFMC_PAGE_ERASE (1<<1) /* Paged erase the main region */
86 #define UFMC_FULL_ERASE (1<<2) /* Erase full flash */
87 #define UFMC_READ (1<<3) /* Reading from main region */
88 #define UFMC_WRITE_IFB (1<<4) /* Writing in info region */
89 #define UFMC_PAGEERASE_IFB (1<<5) /* Erase page of info region */
90 #define UFMC_READ_IFB (1<<6) /* Reading from info region */
91 #define UFMC_MAGIC_KEY (MAGIC_KEY<<16) /* Operation run command */
92
93 /*---- UFCIS: Status register */
94 #define UFCIS_OP_CMLT (1<<0) /* Completion flag operation */
95 #define UFCIS_OP_ERROR (1<<1) /* Flag operation error */
96
97 /*---- UFCIC: CLear status register */
98 #define UFCIC_CLR_OPCMLT (1<<0) /* Clear completion flag in register FCIS */
99 #define UFCIC_CLR_OPERROR (1<<1) /* Clear error flag in register FCIS */
100
101 /*---- In info userflash address space */
102 #define INFOWORD0_ADDR 0x00
103 #define INFOWORD0_BOOTFROM_IFB (1<<0) /* Boot from bootflash or bootflash_ifb */
104 #define INFOWORD0_EN_GPIO (1<<1) /* Remap to 0x00000000 extmem or bootflash */
105 #define INFOWORD0_BOOTFROM_IFB_POS 0
106 #define INFOWORD0_EN_GPIO_POS 1
107 #define INFOWORD0_EXTMEM_SEL_POS 3 /* Choose altfunc of gpio to work with extmem */
108
109 #define INFOWORD1_ADDR 0x01
110 #define INFOWORD1_PINNUM_POS 0 /* Choose gpio pin number to control extmem boot */
111 #define INFOWORD1_PORTNUM_POS 4 /* Choose gpio port to control extmem boot */
112
113 #define INFOWORD2_ADDR 0x02
114 #define INFOWORD2_LOCK_IFB_BF (1<<0) /* Protect info part of bootflash */
115
116 #define INFOWORD3_ADDR 0x03
117 #define INFOWORD3_LOCK_IFB_UF (1<<0) /* Protect info part of userflash */
118
119 #define BF_LOCK_ADDR 0x40
120 #define UF_LOCK_ADDR 0x80
121
122 /**
123 * Private data for flash driver.
124 */
125 struct niietcm4_flash_bank {
126 /* target params */
127 bool probed;
128 uint32_t chipid;
129 char *chip_name;
130 char chip_brief[4096];
131 /* not mapped userflash params */
132 uint32_t uflash_width;
133 uint32_t uflash_size;
134 uint32_t uflash_pagetotal;
135 uint32_t uflash_info_size;
136 uint32_t uflash_info_pagetotal;
137 /* boot params */
138 bool bflash_info_remap;
139 char *extmem_boot_port;
140 uint32_t extmem_boot_pin;
141 uint32_t extmem_boot_altfunc;
142 bool extmem_boot;
143 };
144
145 /*==============================================================================
146 * HELPER FUNCTIONS
147 *==============================================================================
148 */
149
150 /**
151 * Wait while operation with bootflash being performed and check result status
152 */
153 static int niietcm4_opstatus_check(struct flash_bank *bank)
154 {
155 struct target *target = bank->target;
156 int retval;
157 int timeout = 5000;
158
159 uint32_t flash_status;
160 retval = target_read_u32(target, FCIS, &flash_status);
161 if (retval != ERROR_OK)
162 return retval;
163
164 while (flash_status == 0x00) {
165 retval = target_read_u32(target, FCIS, &flash_status);
166 if (retval != ERROR_OK)
167 return retval;
168 if (timeout-- <= 0) {
169 LOG_ERROR("Bootflash operation timeout");
170 return ERROR_FLASH_OPERATION_FAILED;
171 }
172 busy_sleep(1); /* can use busy sleep for short times. */
173 }
174 if (flash_status == FCIS_OP_ERROR) {
175 LOG_ERROR("Bootflash operation error");
176 return ERROR_FLASH_OPERATION_FAILED;
177 }
178 /* clear status */
179 uint32_t flash_cmd = FCIC_CLR_OPCMLT | FCIC_CLR_OPERROR;
180 retval = target_write_u32(target, FCIC, flash_cmd);
181 if (retval != ERROR_OK)
182 return retval;
183
184 return retval;
185 }
186
187 /**
188 * Wait while operation with userflash being performed and check result status
189 */
190 static int niietcm4_uopstatus_check(struct flash_bank *bank)
191 {
192 struct target *target = bank->target;
193 int retval;
194 int timeout = 5000;
195
196 uint32_t uflash_status;
197 retval = target_read_u32(target, UFCIS, &uflash_status);
198 if (retval != ERROR_OK)
199 return retval;
200
201 while (uflash_status == 0x00) {
202 retval = target_read_u32(target, UFCIS, &uflash_status);
203 if (retval != ERROR_OK)
204 return retval;
205 if (timeout-- <= 0) {
206 LOG_ERROR("Userflash operation timeout");
207 return ERROR_FLASH_OPERATION_FAILED;
208 }
209 busy_sleep(1); /* can use busy sleep for short times. */
210 }
211 if (uflash_status == UFCIS_OP_ERROR) {
212 LOG_ERROR("Userflash operation error");
213 return ERROR_FLASH_OPERATION_FAILED;
214 }
215 /* clear status */
216 uint32_t uflash_cmd = UFCIC_CLR_OPCMLT | UFCIC_CLR_OPERROR;
217 retval = target_write_u32(target, UFCIC, uflash_cmd);
218 if (retval != ERROR_OK)
219 return retval;
220
221 return retval;
222 }
223
224 /**
225 * Dump page of userflash region.
226 * If we want to change some settings, we have to dump it full, because userflash is flash(not EEPROM).
227 * And correct write to flash can be performed only after erase.
228 * So without dump, changing one registers will clear others.
229 */
230 static int niietcm4_dump_uflash_page(struct flash_bank *bank, uint32_t *dump, int page_num, int mem_type)
231 {
232 struct target *target = bank->target;
233 int i;
234 int retval = ERROR_OK;
235
236 uint32_t uflash_cmd;
237 if (mem_type == INFO_MEM_TYPE)
238 uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB;
239 else
240 uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ;
241
242 int first = page_num*USERFLASH_PAGE_SIZE;
243 int last = first + USERFLASH_PAGE_SIZE;
244
245 for (i = first; i < last; i++) {
246 retval = target_write_u32(target, UFMA, i);
247 if (retval != ERROR_OK)
248 return retval;
249 retval = target_write_u32(target, UFMC, uflash_cmd);
250 if (retval != ERROR_OK)
251 return retval;
252 retval = niietcm4_uopstatus_check(bank);
253 if (retval != ERROR_OK)
254 return retval;
255 retval = target_read_u32(target, UFMD, &dump[i]);
256 if (retval != ERROR_OK)
257 return retval;
258 }
259
260 return retval;
261 }
262
263 /**
264 * Load modified page dump to userflash region page.
265 */
266 static int niietcm4_load_uflash_page(struct flash_bank *bank, uint32_t *dump, int page_num, int mem_type)
267 {
268 struct target *target = bank->target;
269 int i;
270 int retval = ERROR_OK;
271
272 uint32_t uflash_cmd;
273 if (mem_type == INFO_MEM_TYPE)
274 uflash_cmd = UFMC_MAGIC_KEY | UFMC_WRITE_IFB;
275 else
276 uflash_cmd = UFMC_MAGIC_KEY | UFMC_WRITE;
277
278 int first = page_num*USERFLASH_PAGE_SIZE;
279 int last = first + USERFLASH_PAGE_SIZE;
280
281 for (i = first; i < last; i++) {
282 retval = target_write_u32(target, UFMA, i);
283 if (retval != ERROR_OK)
284 return retval;
285 retval = target_write_u32(target, UFMD, dump[i]);
286 if (retval != ERROR_OK)
287 return retval;
288 retval = target_write_u32(target, UFMC, uflash_cmd);
289 if (retval != ERROR_OK)
290 return retval;
291 retval = niietcm4_uopstatus_check(bank);
292 if (retval != ERROR_OK)
293 return retval;
294 }
295
296 return retval;
297 }
298
299 /**
300 * Erase one page of userflash info or main region
301 */
302 static int niietcm4_uflash_page_erase(struct flash_bank *bank, int page_num, int mem_type)
303 {
304 struct target *target = bank->target;
305 int retval;
306
307 uint32_t uflash_cmd;
308 if (mem_type == INFO_MEM_TYPE)
309 uflash_cmd = UFMC_MAGIC_KEY | UFMC_PAGEERASE_IFB;
310 else
311 uflash_cmd = UFMC_MAGIC_KEY | UFMC_PAGE_ERASE;
312
313 retval = target_write_u32(target, UFMA, page_num*USERFLASH_PAGE_SIZE);
314 if (retval != ERROR_OK)
315 return retval;
316 retval = target_write_u32(target, UFMD, 0xFF);
317 if (retval != ERROR_OK)
318 return retval;
319 retval = target_write_u32(target, UFMC, uflash_cmd);
320 if (retval != ERROR_OK)
321 return retval;
322 /* status check */
323 retval = niietcm4_uopstatus_check(bank);
324 if (retval != ERROR_OK)
325 return retval;
326
327 return retval;
328 }
329
330 /**
331 * Enable or disable protection of userflash pages
332 */
333 static int niietcm4_uflash_protect(struct flash_bank *bank, int mem_type,
334 int set, unsigned int first, unsigned int last)
335 {
336 int retval;
337 if (mem_type == INFO_MEM_TYPE) {
338 /* read dump */
339 uint32_t uflash_dump[USERFLASH_PAGE_SIZE];
340 retval = niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1);
341 if (retval != ERROR_OK)
342 return retval;
343 /* modify dump */
344 if (set)
345 uflash_dump[INFOWORD2_ADDR] &= ~INFOWORD3_LOCK_IFB_UF;
346 else
347 uflash_dump[INFOWORD2_ADDR] |= INFOWORD3_LOCK_IFB_UF;
348 /* erase page 0 userflash */
349 retval = niietcm4_uflash_page_erase(bank, 0, 1);
350 if (retval != ERROR_OK)
351 return retval;
352 /* write dump to userflash */
353 retval = niietcm4_load_uflash_page(bank, uflash_dump, 0, 1);
354 if (retval != ERROR_OK)
355 return retval;
356 } else {
357 /* read dump */
358 uint32_t uflash_dump[USERFLASH_PAGE_SIZE];
359 retval = niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1);
360 if (retval != ERROR_OK)
361 return retval;
362 /* modify dump */
363 for (unsigned int i = first; i <= last; i++) {
364 uint32_t reg_num = i/8;
365 uint32_t bit_num = i%8;
366 if (set)
367 uflash_dump[UF_LOCK_ADDR+reg_num] &= ~(1<<bit_num);
368 else
369 uflash_dump[UF_LOCK_ADDR+reg_num] |= (1<<bit_num);
370 }
371 /* erase page 0 info userflash */
372 retval = niietcm4_uflash_page_erase(bank, 0, 1);
373 if (retval != ERROR_OK)
374 return retval;
375 /* write dump to userflash */
376 retval = niietcm4_load_uflash_page(bank, uflash_dump, 0, 1);
377 if (retval != ERROR_OK)
378 return retval;
379 }
380
381 return retval;
382 }
383
384 /*==============================================================================
385 * FLASH COMMANDS
386 *==============================================================================
387 */
388 COMMAND_HANDLER(niietcm4_handle_uflash_read_byte_command)
389 {
390 if (CMD_ARGC < 3)
391 return ERROR_COMMAND_SYNTAX_ERROR;
392
393 struct flash_bank *bank;
394 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
395 if (retval != ERROR_OK)
396 return retval;
397 struct target *target = bank->target;
398
399 /* skip over flash bank */
400 CMD_ARGC--;
401 CMD_ARGV++;
402
403 uint32_t uflash_addr;
404 uint32_t uflash_cmd;
405 uint32_t uflash_data;
406
407 if (strcmp("info", CMD_ARGV[0]) == 0)
408 uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB;
409 else if (strcmp("main", CMD_ARGV[0]) == 0)
410 uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ;
411 else
412 return ERROR_COMMAND_SYNTAX_ERROR;
413
414 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], uflash_addr);
415
416 retval = target_write_u32(target, UFMA, uflash_addr);
417 if (retval != ERROR_OK)
418 return retval;
419 retval = target_write_u32(target, UFMC, uflash_cmd);
420 if (retval != ERROR_OK)
421 return retval;
422 /* status check */
423 retval = niietcm4_uopstatus_check(bank);
424 if (retval != ERROR_OK)
425 return retval;
426 retval = target_read_u32(target, UFMD, &uflash_data);
427 if (retval != ERROR_OK)
428 return retval;
429 command_print(CMD, "Read userflash %s region:\n"
430 "address = 0x%04" PRIx32 ",\n"
431 "value = 0x%02" PRIx32 ".", CMD_ARGV[0], uflash_addr, uflash_data);
432 return retval;
433 }
434
435 COMMAND_HANDLER(niietcm4_handle_uflash_write_byte_command)
436 {
437 if (CMD_ARGC < 4)
438 return ERROR_COMMAND_SYNTAX_ERROR;
439
440 struct flash_bank *bank;
441 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
442 if (retval != ERROR_OK)
443 return retval;
444 struct target *target = bank->target;
445
446 if (target->state != TARGET_HALTED) {
447 LOG_ERROR("Target not halted");
448 return ERROR_TARGET_NOT_HALTED;
449 }
450
451 /* skip over flash bank */
452 CMD_ARGC--;
453 CMD_ARGV++;
454
455 uint32_t uflash_addr;
456 uint32_t uflash_data;
457 int mem_type;
458
459 if (strcmp("info", CMD_ARGV[0]) == 0)
460 mem_type = 1;
461 else if (strcmp("main", CMD_ARGV[0]) == 0)
462 mem_type = 0;
463 else
464 return ERROR_COMMAND_SYNTAX_ERROR;
465
466 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], uflash_addr);
467 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], uflash_data);
468
469 int page_num = uflash_addr/USERFLASH_PAGE_SIZE;
470
471 command_print(CMD, "Write userflash %s region:\n"
472 "address = 0x%04" PRIx32 ",\n"
473 "value = 0x%02" PRIx32 ".\n"
474 "Please wait ... ", CMD_ARGV[0], uflash_addr, uflash_data);
475 /* dump */
476 uint32_t uflash_dump[USERFLASH_PAGE_SIZE];
477 niietcm4_dump_uflash_page(bank, uflash_dump, page_num, mem_type);
478
479 /* modify dump */
480 uflash_dump[uflash_addr%USERFLASH_PAGE_SIZE] = uflash_data;
481
482 /* erase page userflash */
483 niietcm4_uflash_page_erase(bank, page_num, mem_type);
484
485 /* write dump to userflash */
486 niietcm4_load_uflash_page(bank, uflash_dump, page_num, mem_type);
487 command_print(CMD, "done!");
488 return retval;
489 }
490
491 COMMAND_HANDLER(niietcm4_handle_uflash_full_erase_command)
492 {
493 if (CMD_ARGC < 1)
494 return ERROR_COMMAND_SYNTAX_ERROR;
495
496 struct flash_bank *bank;
497 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
498 if (retval != ERROR_OK)
499 return retval;
500 struct target *target = bank->target;
501
502 if (target->state != TARGET_HALTED) {
503 LOG_ERROR("Target not halted");
504 return ERROR_TARGET_NOT_HALTED;
505 }
506
507 uint32_t uflash_addr = 0;
508 uint32_t uflash_data = 0xFF;
509 uint32_t uflash_cmd = UFMC_MAGIC_KEY | UFMC_FULL_ERASE;
510
511 retval = target_write_u32(target, UFMA, uflash_addr);
512 if (retval != ERROR_OK)
513 return retval;
514 retval = target_write_u32(target, UFMD, uflash_data);
515 if (retval != ERROR_OK)
516 return retval;
517 retval = target_write_u32(target, UFMC, uflash_cmd);
518 if (retval != ERROR_OK)
519 return retval;
520 /* status check */
521 retval = niietcm4_uopstatus_check(bank);
522 if (retval != ERROR_OK)
523 return retval;
524 command_print(CMD, "Userflash full erase done!");
525
526 return retval;
527 }
528
529 COMMAND_HANDLER(niietcm4_handle_uflash_erase_command)
530 {
531 if (CMD_ARGC < 4)
532 return ERROR_COMMAND_SYNTAX_ERROR;
533
534 struct flash_bank *bank;
535 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
536 if (retval != ERROR_OK)
537 return retval;
538 struct target *target = bank->target;
539
540 if (target->state != TARGET_HALTED) {
541 LOG_ERROR("Target not halted");
542 return ERROR_TARGET_NOT_HALTED;
543 }
544
545 /* skip over flash bank */
546 CMD_ARGC--;
547 CMD_ARGV++;
548
549 unsigned int first, last;
550 int mem_type;
551
552 if (strcmp("info", CMD_ARGV[0]) == 0)
553 mem_type = 1;
554 else if (strcmp("main", CMD_ARGV[0]) == 0)
555 mem_type = 0;
556 else
557 return ERROR_COMMAND_SYNTAX_ERROR;
558
559 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], first);
560 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], last);
561 for (unsigned int i = first; i <= last; i++) {
562 retval = niietcm4_uflash_page_erase(bank, i, mem_type);
563 if (retval != ERROR_OK)
564 return retval;
565 }
566
567 command_print(CMD, "Erase %s userflash pages %u through %u done!", CMD_ARGV[0], first, last);
568
569 return retval;
570 }
571
572 COMMAND_HANDLER(niietcm4_handle_uflash_protect_check_command)
573 {
574 if (CMD_ARGC < 2)
575 return ERROR_COMMAND_SYNTAX_ERROR;
576
577 struct flash_bank *bank;
578 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
579 if (retval != ERROR_OK)
580 return retval;
581
582 struct target *target = bank->target;
583 if (target->state != TARGET_HALTED) {
584 LOG_ERROR("Target not halted");
585 return ERROR_TARGET_NOT_HALTED;
586 }
587
588 /* skip over flash bank */
589 CMD_ARGC--;
590 CMD_ARGV++;
591
592 int mem_type;
593 if (strcmp("info", CMD_ARGV[0]) == 0)
594 mem_type = 1;
595 else if (strcmp("main", CMD_ARGV[0]) == 0)
596 mem_type = 0;
597 else
598 return ERROR_COMMAND_SYNTAX_ERROR;
599
600 int i, j;
601 uint32_t uflash_addr;
602 uint32_t uflash_cmd;
603 uint32_t uflash_data;
604
605 /* chose between main userflash and info userflash */
606 if (mem_type == INFO_MEM_TYPE) {
607 uflash_addr = INFOWORD3_ADDR;
608 uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB;
609 retval = target_write_u32(target, UFMA, uflash_addr);
610 if (retval != ERROR_OK)
611 return retval;
612 retval = target_write_u32(target, UFMC, uflash_cmd);
613 if (retval != ERROR_OK)
614 return retval;
615
616 /* status check */
617 retval = niietcm4_uopstatus_check(bank);
618 if (retval != ERROR_OK)
619 return retval;
620 retval = target_read_u32(target, UFMD, &uflash_data);
621 if (retval != ERROR_OK)
622 return retval;
623
624 if (uflash_data & INFOWORD3_LOCK_IFB_UF)
625 command_print(CMD, "All sectors of info userflash are not protected!");
626 else
627 command_print(CMD, "All sectors of info userflash are protected!");
628 } else {
629 uflash_addr = UF_LOCK_ADDR;
630 uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB;
631 for (i = 0; i < USERFLASH_PAGE_TOTALNUM/8; i++) {
632 retval = target_write_u32(target, UFMA, uflash_addr);
633 if (retval != ERROR_OK)
634 return retval;
635 retval = target_write_u32(target, UFMC, uflash_cmd);
636 if (retval != ERROR_OK)
637 return retval;
638
639 /* status check */
640 retval = niietcm4_uopstatus_check(bank);
641 if (retval != ERROR_OK)
642 return retval;
643 retval = target_read_u32(target, UFMD, &uflash_data);
644 if (retval != ERROR_OK)
645 return retval;
646
647 for (j = 0; j < 8; j++) {
648 if (uflash_data & 0x1)
649 command_print(CMD, "Userflash sector #%03d: 0x%04x (0x100) is not protected!",
650 i*8+j, (i*8+j)*USERFLASH_PAGE_SIZE);
651 else
652 command_print(CMD, "Userflash sector #%03d: 0x%04x (0x100) is protected!",
653 i*8+j, (i*8+j)*USERFLASH_PAGE_SIZE);
654 uflash_data = uflash_data >> 1;
655 }
656 uflash_addr++;
657 }
658 }
659
660 return retval;
661 }
662
663 COMMAND_HANDLER(niietcm4_handle_uflash_protect_command)
664 {
665 if (CMD_ARGC < 5)
666 return ERROR_COMMAND_SYNTAX_ERROR;
667
668 struct flash_bank *bank;
669 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
670 if (retval != ERROR_OK)
671 return retval;
672 struct target *target = bank->target;
673
674 if (target->state != TARGET_HALTED) {
675 LOG_ERROR("Target not halted");
676 return ERROR_TARGET_NOT_HALTED;
677 }
678
679 /* skip over flash bank */
680 CMD_ARGC--;
681 CMD_ARGV++;
682
683 int mem_type;
684 if (strcmp("info", CMD_ARGV[0]) == 0)
685 mem_type = 1;
686 else if (strcmp("main", CMD_ARGV[0]) == 0)
687 mem_type = 0;
688 else
689 return ERROR_COMMAND_SYNTAX_ERROR;
690
691 unsigned int first, last;
692 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], first);
693 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], last);
694
695 int set;
696 if (strcmp("on", CMD_ARGV[3]) == 0) {
697 command_print(CMD, "Try to enable %s userflash sectors %u through %u protection. Please wait ... ",
698 CMD_ARGV[0], first, last);
699 set = 1;
700 } else if (strcmp("off", CMD_ARGV[3]) == 0) {
701 command_print(CMD, "Try to disable %s userflash sectors %u through %u protection. Please wait ... ",
702 CMD_ARGV[0], first, last);
703 set = 0;
704 } else
705 return ERROR_COMMAND_SYNTAX_ERROR;
706
707 retval = niietcm4_uflash_protect(bank, mem_type, set, first, last);
708 if (retval != ERROR_OK)
709 return retval;
710
711 command_print(CMD, "done!");
712 return retval;
713 }
714
715 COMMAND_HANDLER(niietcm4_handle_bflash_info_remap_command)
716 {
717 if (CMD_ARGC < 2)
718 return ERROR_COMMAND_SYNTAX_ERROR;
719
720 struct flash_bank *bank;
721 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
722 if (retval != ERROR_OK)
723 return retval;
724 struct target *target = bank->target;
725
726 if (target->state != TARGET_HALTED) {
727 LOG_ERROR("Target not halted");
728 return ERROR_TARGET_NOT_HALTED;
729 }
730
731 /* skip over flash bank */
732 CMD_ARGC--;
733 CMD_ARGV++;
734
735 int set;
736 if (strcmp("on", CMD_ARGV[0]) == 0) {
737 command_print(CMD, "Try to enable bootflash info region remap. Please wait ...");
738 set = 1;
739 } else if (strcmp("off", CMD_ARGV[0]) == 0) {
740 command_print(CMD, "Try to disable bootflash info region remap. Please wait ...");
741 set = 0;
742 } else
743 return ERROR_COMMAND_SYNTAX_ERROR;
744
745 /* dump */
746 uint32_t uflash_dump[USERFLASH_PAGE_SIZE];
747 niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1);
748
749 /* modify dump */
750 if (set)
751 uflash_dump[INFOWORD0_ADDR] &= ~INFOWORD0_BOOTFROM_IFB;
752 else
753 uflash_dump[INFOWORD0_ADDR] |= INFOWORD0_BOOTFROM_IFB;
754
755 /* erase page userflash */
756 niietcm4_uflash_page_erase(bank, 0, 1);
757
758 /* write dump to userflash */
759 niietcm4_load_uflash_page(bank, uflash_dump, 0, 1);
760 command_print(CMD, "done!");
761
762 return retval;
763 }
764
765 COMMAND_HANDLER(niietcm4_handle_extmem_cfg_command)
766 {
767 if (CMD_ARGC < 4)
768 return ERROR_COMMAND_SYNTAX_ERROR;
769
770 struct flash_bank *bank;
771 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
772 if (retval != ERROR_OK)
773 return retval;
774 struct target *target = bank->target;
775
776 if (target->state != TARGET_HALTED) {
777 LOG_ERROR("Target not halted");
778 return ERROR_TARGET_NOT_HALTED;
779 }
780
781 /* skip over flash bank */
782 CMD_ARGC--;
783 CMD_ARGV++;
784
785 uint32_t port;
786 if (strcmp("gpioa", CMD_ARGV[0]) == 0)
787 port = 8;
788 else if (strcmp("gpiob", CMD_ARGV[0]) == 0)
789 port = 9;
790 else if (strcmp("gpioc", CMD_ARGV[0]) == 0)
791 port = 10;
792 else if (strcmp("gpiod", CMD_ARGV[0]) == 0)
793 port = 11;
794 else if (strcmp("gpioe", CMD_ARGV[0]) == 0)
795 port = 12;
796 else if (strcmp("gpiof", CMD_ARGV[0]) == 0)
797 port = 13;
798 else if (strcmp("gpiog", CMD_ARGV[0]) == 0)
799 port = 14;
800 else if (strcmp("gpioh", CMD_ARGV[0]) == 0)
801 port = 15;
802 else
803 return ERROR_COMMAND_SYNTAX_ERROR;
804
805 uint32_t pin;
806 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], pin);
807 if (pin > 15)
808 return ERROR_COMMAND_SYNTAX_ERROR;
809
810 uint32_t func;
811 if (strcmp("func1", CMD_ARGV[2]) == 0)
812 func = 0;
813 else if (strcmp("func3", CMD_ARGV[2]) == 0)
814 func = 3;
815 else
816 return ERROR_COMMAND_SYNTAX_ERROR;
817
818 command_print(CMD, "Try to configure external memory boot interface:\n"
819 "port = %s\n"
820 "pin = %s\n"
821 "func = %s\n"
822 "Please wait ...", CMD_ARGV[0], CMD_ARGV[1], CMD_ARGV[2]);
823 /* dump */
824 uint32_t uflash_dump[USERFLASH_PAGE_SIZE];
825 niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1);
826
827 /* modify dump */
828 uflash_dump[INFOWORD0_ADDR] &= ~(3<<INFOWORD0_EXTMEM_SEL_POS);
829 uflash_dump[INFOWORD0_ADDR] |= func<<INFOWORD0_EXTMEM_SEL_POS;
830 uflash_dump[INFOWORD1_ADDR] = (port<<INFOWORD1_PORTNUM_POS) | (pin<<INFOWORD1_PINNUM_POS);
831
832 /* erase page userflash */
833 niietcm4_uflash_page_erase(bank, 0, 1);
834
835 /* write dump to userflash */
836 niietcm4_load_uflash_page(bank, uflash_dump, 0, 1);
837 command_print(CMD, "done!");
838
839 return retval;
840 }
841
842 COMMAND_HANDLER(niietcm4_handle_extmem_boot_command)
843 {
844 if (CMD_ARGC < 2)
845 return ERROR_COMMAND_SYNTAX_ERROR;
846
847 struct flash_bank *bank;
848 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
849 if (retval != ERROR_OK)
850 return retval;
851 struct target *target = bank->target;
852
853 if (target->state != TARGET_HALTED) {
854 LOG_ERROR("Target not halted");
855 return ERROR_TARGET_NOT_HALTED;
856 }
857
858 /* skip over flash bank */
859 CMD_ARGC--;
860 CMD_ARGV++;
861
862 int set;
863
864 if (strcmp("on", CMD_ARGV[0]) == 0) {
865 command_print(CMD, "Try to enable boot from external memory. Please wait ...");
866 set = 1;
867 } else if (strcmp("off", CMD_ARGV[0]) == 0) {
868 command_print(CMD, "Try to disable boot from external memory. Please wait ...");
869 set = 0;
870 } else
871 return ERROR_COMMAND_SYNTAX_ERROR;
872
873 /* dump */
874 uint32_t uflash_dump[USERFLASH_PAGE_SIZE];
875 niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1);
876
877 /* modify dump */
878 if (set)
879 uflash_dump[INFOWORD0_ADDR] &= ~INFOWORD0_EN_GPIO;
880 else
881 uflash_dump[INFOWORD0_ADDR] |= INFOWORD0_EN_GPIO;
882
883 /* erase page userflash */
884 niietcm4_uflash_page_erase(bank, 0, 1);
885
886 /* write dump to userflash */
887 niietcm4_load_uflash_page(bank, uflash_dump, 0, 1);
888 command_print(CMD, "done!");
889
890 return retval;
891 }
892
893 COMMAND_HANDLER(niietcm4_handle_service_mode_erase_command)
894 {
895 if (CMD_ARGC < 1)
896 return ERROR_COMMAND_SYNTAX_ERROR;
897
898 struct flash_bank *bank;
899 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
900 if (retval != ERROR_OK)
901 return retval;
902 struct target *target = bank->target;
903
904 command_print(CMD, "Try to perform service mode erase. Please wait ...");
905
906 retval = target_write_u32(target, SERVICE_MODE_ERASE_ADDR, 1);
907 if (retval != ERROR_OK)
908 return retval;
909
910 int timeout = 500;
911 uint32_t status;
912
913 retval = target_read_u32(target, SERVICE_MODE_ERASE_ADDR, &status);
914 if (retval != ERROR_OK)
915 return retval;
916
917 while (status != 0x03) {
918 retval = target_read_u32(target, SERVICE_MODE_ERASE_ADDR, &status);
919 if (retval != ERROR_OK)
920 return retval;
921 if (timeout-- <= 0) {
922 LOG_ERROR("Service mode erase timeout");
923 return ERROR_FLASH_OPERATION_FAILED;
924 }
925 busy_sleep(1); /* can use busy sleep for short times. */
926 }
927 command_print(CMD, "done! All data erased.");
928
929 return retval;
930 }
931
932 COMMAND_HANDLER(niietcm4_handle_driver_info_command)
933 {
934 if (CMD_ARGC < 1)
935 return ERROR_COMMAND_SYNTAX_ERROR;
936
937 struct flash_bank *bank;
938 int retval = CALL_COMMAND_HANDLER(flash_command_get_bank, 0, &bank);
939 if (retval != ERROR_OK)
940 return retval;
941
942 command_print(CMD, "niietcm4 flash driver\n"
943 "version: %d.%d\n"
944 "author: Bogdan Kolbov\n"
945 "mail: kolbov@niiet.ru",
946 FLASH_DRIVER_VER>>16,
947 FLASH_DRIVER_VER&0xFFFF);
948
949 return retval;
950 }
951
952 static const struct command_registration niietcm4_exec_command_handlers[] = {
953 {
954 .name = "uflash_read_byte",
955 .handler = niietcm4_handle_uflash_read_byte_command,
956 .mode = COMMAND_EXEC,
957 .usage = "bank_id ('main'|'info') address",
958 .help = "Read byte from main or info userflash region",
959 },
960 {
961 .name = "uflash_write_byte",
962 .handler = niietcm4_handle_uflash_write_byte_command,
963 .mode = COMMAND_EXEC,
964 .usage = "bank_id ('main'|'info') address value",
965 .help = "Write byte to main or info userflash region",
966 },
967 {
968 .name = "uflash_full_erase",
969 .handler = niietcm4_handle_uflash_full_erase_command,
970 .mode = COMMAND_EXEC,
971 .usage = "bank_id",
972 .help = "Erase all userflash including info region",
973 },
974 {
975 .name = "uflash_erase",
976 .handler = niietcm4_handle_uflash_erase_command,
977 .mode = COMMAND_EXEC,
978 .usage = "bank_id ('main'|'info') first_sector_num last_sector_num",
979 .help = "Erase sectors of main or info userflash region, starting at sector first up to and including last.",
980 },
981 {
982 .name = "uflash_protect_check",
983 .handler = niietcm4_handle_uflash_protect_check_command,
984 .mode = COMMAND_EXEC,
985 .usage = "bank_id ('main'|'info')",
986 .help = "Check sectors protect.",
987 },
988 {
989 .name = "uflash_protect",
990 .handler = niietcm4_handle_uflash_protect_command,
991 .mode = COMMAND_EXEC,
992 .usage = "bank_id ('main'|'info') first_sector_num last_sector_num ('on'|'off')",
993 .help = "Protect sectors of main or info userflash region, starting at sector first up to and including last.",
994 },
995 {
996 .name = "bflash_info_remap",
997 .handler = niietcm4_handle_bflash_info_remap_command,
998 .mode = COMMAND_EXEC,
999 .usage = "bank_id ('on'|'off')",
1000 .help = "Enable remapping bootflash info region to 0x00000000 (or 0x40000000 if external memory boot used).",
1001 },
1002 {
1003 .name = "extmem_cfg",
1004 .handler = niietcm4_handle_extmem_cfg_command,
1005 .mode = COMMAND_EXEC,
1006 .usage = "bank_id ('gpioa'|'gpiob'|'gpioc'|'gpiod'|'gpioe'|'gpiof'|'gpiog'|'gpioh') pin_num ('func1'|'func3')",
1007 .help = "Configure external memory interface for boot.",
1008 },
1009 {
1010 .name = "extmem_boot",
1011 .handler = niietcm4_handle_extmem_boot_command,
1012 .mode = COMMAND_EXEC,
1013 .usage = "bank_id ('on'|'off')",
1014 .help = "Enable boot from external memory.",
1015 },
1016 {
1017 .name = "service_mode_erase",
1018 .handler = niietcm4_handle_service_mode_erase_command,
1019 .mode = COMMAND_EXEC,
1020 .usage = "bank_id",
1021 .help = "Perform emergency erase of all flash (bootflash and userflash).",
1022 },
1023 {
1024 .name = "driver_info",
1025 .handler = niietcm4_handle_driver_info_command,
1026 .mode = COMMAND_EXEC,
1027 .usage = "bank_id",
1028 .help = "Show information about flash driver.",
1029 },
1030 COMMAND_REGISTRATION_DONE
1031 };
1032
1033 static const struct command_registration niietcm4_command_handlers[] = {
1034 {
1035 .name = "niietcm4",
1036 .mode = COMMAND_ANY,
1037 .help = "niietcm4 flash command group",
1038 .usage = "",
1039 .chain = niietcm4_exec_command_handlers,
1040 },
1041 COMMAND_REGISTRATION_DONE
1042 };
1043
1044 /*==============================================================================
1045 * FLASH INTERFACE
1046 *==============================================================================
1047 */
1048
1049 FLASH_BANK_COMMAND_HANDLER(niietcm4_flash_bank_command)
1050 {
1051 struct niietcm4_flash_bank *niietcm4_info;
1052
1053 if (CMD_ARGC < 6)
1054 return ERROR_COMMAND_SYNTAX_ERROR;
1055
1056 niietcm4_info = malloc(sizeof(struct niietcm4_flash_bank));
1057
1058 bank->driver_priv = niietcm4_info;
1059
1060 /* information will be updated by probing */
1061 niietcm4_info->probed = false;
1062 niietcm4_info->chipid = 0;
1063 niietcm4_info->chip_name = NULL;
1064 niietcm4_info->uflash_width = 0;
1065 niietcm4_info->uflash_size = 0;
1066 niietcm4_info->uflash_pagetotal = 0;
1067 niietcm4_info->uflash_info_size = 0;
1068 niietcm4_info->uflash_info_pagetotal = 0;
1069 niietcm4_info->bflash_info_remap = false;
1070 niietcm4_info->extmem_boot_port = NULL;
1071 niietcm4_info->extmem_boot_pin = 0;
1072 niietcm4_info->extmem_boot_altfunc = 0;
1073 niietcm4_info->extmem_boot = false;
1074
1075 return ERROR_OK;
1076 }
1077
1078 static int niietcm4_protect_check(struct flash_bank *bank)
1079 {
1080 struct target *target = bank->target;
1081 struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
1082
1083 int retval = ERROR_FLASH_OPERATION_FAILED;
1084 int set;
1085 uint32_t uflash_addr;
1086 uint32_t uflash_cmd;
1087 uint32_t uflash_data;
1088 /* chose between main bootflash and info bootflash */
1089 if (niietcm4_info->bflash_info_remap) {
1090 uflash_addr = INFOWORD2_ADDR;
1091 uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB;
1092 retval = target_write_u32(target, UFMA, uflash_addr);
1093 if (retval != ERROR_OK)
1094 return retval;
1095 retval = target_write_u32(target, UFMC, uflash_cmd);
1096 if (retval != ERROR_OK)
1097 return retval;
1098
1099 /* status check */
1100 retval = niietcm4_uopstatus_check(bank);
1101 if (retval != ERROR_OK)
1102 return retval;
1103 retval = target_read_u32(target, UFMD, &uflash_data);
1104 if (retval != ERROR_OK)
1105 return retval;
1106
1107 if (uflash_data & INFOWORD2_LOCK_IFB_BF)
1108 set = 0;
1109 else
1110 set = 1;
1111 bank->sectors[0].is_protected = set;
1112 } else {
1113 uflash_addr = BF_LOCK_ADDR;
1114 uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB;
1115 for (unsigned int i = 0; i < bank->num_sectors/8; i++) {
1116 retval = target_write_u32(target, UFMA, uflash_addr);
1117 if (retval != ERROR_OK)
1118 return retval;
1119 retval = target_write_u32(target, UFMC, uflash_cmd);
1120 if (retval != ERROR_OK)
1121 return retval;
1122
1123 /* status check */
1124 retval = niietcm4_uopstatus_check(bank);
1125 if (retval != ERROR_OK)
1126 return retval;
1127 retval = target_read_u32(target, UFMD, &uflash_data);
1128 if (retval != ERROR_OK)
1129 return retval;
1130
1131 for (int j = 0; j < 8; j++) {
1132 if (uflash_data & 0x1)
1133 set = 0;
1134 else
1135 set = 1;
1136 bank->sectors[i*8+j].is_protected = set;
1137 uflash_data = uflash_data >> 1;
1138 }
1139 uflash_addr++;
1140 }
1141 }
1142
1143 return retval;
1144 }
1145
1146 static int niietcm4_mass_erase(struct flash_bank *bank)
1147 {
1148 struct target *target = bank->target;
1149
1150 int retval;
1151 uint32_t flash_cmd;
1152
1153 /* start mass erase */
1154 flash_cmd = FMC_MAGIC_KEY | FMC_FULL_ERASE;
1155 retval = target_write_u32(target, FMC, flash_cmd);
1156 if (retval != ERROR_OK)
1157 return retval;
1158
1159 /* status check */
1160 retval = niietcm4_opstatus_check(bank);
1161 if (retval != ERROR_OK)
1162 return retval;
1163
1164 return retval;
1165 }
1166
1167 static int niietcm4_erase(struct flash_bank *bank, unsigned int first,
1168 unsigned int last)
1169 {
1170 struct target *target = bank->target;
1171 struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
1172 int retval = ERROR_FLASH_OPERATION_FAILED;
1173
1174 if (bank->target->state != TARGET_HALTED) {
1175 LOG_ERROR("Target not halted");
1176 return ERROR_TARGET_NOT_HALTED;
1177 }
1178
1179 if ((first == 0) && (last == (bank->num_sectors - 1))) {
1180 retval = niietcm4_mass_erase(bank);
1181 return retval;
1182 }
1183
1184 /* chose between main bootflash and info bootflash */
1185 uint32_t flash_cmd, flash_addr;
1186 if (niietcm4_info->bflash_info_remap)
1187 flash_cmd = FMC_MAGIC_KEY | FMC_PAGEERASE_IFB;
1188 else
1189 flash_cmd = FMC_MAGIC_KEY | FMC_PAGE_ERASE;
1190
1191 /* erasing pages */
1192 unsigned int page_size = bank->size / bank->num_sectors;
1193 for (unsigned int i = first; i <= last; i++) {
1194 /* current page addr */
1195 flash_addr = i*page_size;
1196 retval = target_write_u32(target, FMA, flash_addr);
1197 if (retval != ERROR_OK)
1198 return retval;
1199
1200 /* start erase */
1201 retval = target_write_u32(target, FMC, flash_cmd);
1202 if (retval != ERROR_OK)
1203 return retval;
1204
1205 /* status check */
1206 retval = niietcm4_opstatus_check(bank);
1207 if (retval != ERROR_OK)
1208 return retval;
1209 }
1210
1211 return retval;
1212 }
1213
1214 static int niietcm4_protect(struct flash_bank *bank, int set,
1215 unsigned int first, unsigned int last)
1216 {
1217 struct target *target = bank->target;
1218 struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
1219
1220 int retval;
1221
1222 if (target->state != TARGET_HALTED) {
1223 LOG_ERROR("Target not halted");
1224 return ERROR_TARGET_NOT_HALTED;
1225 }
1226
1227 LOG_INFO("Please wait ..."); /* it`s quite a long process */
1228 /* chose between main bootflash and info bootflash */
1229 if (niietcm4_info->bflash_info_remap) {
1230 /* dump */
1231 uint32_t uflash_dump[USERFLASH_PAGE_SIZE];
1232 retval = niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1);
1233 if (retval != ERROR_OK)
1234 return retval;
1235 /* modify dump */
1236 if (set)
1237 uflash_dump[INFOWORD2_ADDR] &= ~INFOWORD2_LOCK_IFB_BF;
1238 else
1239 uflash_dump[INFOWORD2_ADDR] |= INFOWORD2_LOCK_IFB_BF;
1240 /* erase page 0 userflash */
1241 retval = niietcm4_uflash_page_erase(bank, 0, 1);
1242 if (retval != ERROR_OK)
1243 return retval;
1244 /* write dump to userflash */
1245 retval = niietcm4_load_uflash_page(bank, uflash_dump, 0, 1);
1246 if (retval != ERROR_OK)
1247 return retval;
1248 } else {
1249 /* read dump*/
1250 uint32_t uflash_dump[USERFLASH_PAGE_SIZE];
1251 retval = niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1);
1252 if (retval != ERROR_OK)
1253 return retval;
1254 /* modify dump */
1255 for (unsigned int i = first; i <= last; i++) {
1256 uint32_t reg_num = i/8;
1257 uint32_t bit_num = i%8;
1258 if (set)
1259 uflash_dump[BF_LOCK_ADDR+reg_num] &= ~(1<<bit_num);
1260 else
1261 uflash_dump[BF_LOCK_ADDR+reg_num] |= (1<<bit_num);
1262 }
1263 /* erase page 0 info userflash */
1264 retval = niietcm4_uflash_page_erase(bank, 0, 1);
1265 if (retval != ERROR_OK)
1266 return retval;
1267 /* write dump to userflash */
1268 retval = niietcm4_load_uflash_page(bank, uflash_dump, 0, 1);
1269 if (retval != ERROR_OK)
1270 return retval;
1271 }
1272
1273 return retval;
1274 }
1275
1276 static int niietcm4_write_block(struct flash_bank *bank, const uint8_t *buffer,
1277 uint32_t offset, uint32_t count)
1278 {
1279 struct target *target = bank->target;
1280 struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
1281 uint32_t buffer_size = 32768 + 8; /* 8 bytes for rp and wp */
1282 struct working_area *write_algorithm;
1283 struct working_area *source;
1284 uint32_t address = bank->base + offset;
1285 struct reg_param reg_params[5];
1286 struct armv7m_algorithm armv7m_info;
1287 int retval = ERROR_OK;
1288
1289 /* see contrib/loaders/flash/k1921vk01t.S for src */
1290 static const uint8_t niietcm4_flash_write_code[] = {
1291 0x14, 0x4f, 0x16, 0x68, 0x00, 0x2e, 0x23, 0xd0, 0x55, 0x68, 0xb5, 0x42, 0xf9, 0xd0, 0x2e, 0x68,
1292 0x7e, 0x60, 0x04, 0x35, 0x2e, 0x68, 0x3e, 0x65, 0x04, 0x35, 0x2e, 0x68, 0x7e, 0x65, 0x04, 0x35,
1293 0x2e, 0x68, 0xbe, 0x65, 0x04, 0x35, 0x3c, 0x60, 0x10, 0x34, 0xb8, 0x60, 0xfe, 0x68, 0x00, 0x2e,
1294 0xfc, 0xd0, 0x02, 0x2e, 0x0a, 0xd0, 0x01, 0x26, 0x7e, 0x61, 0x9d, 0x42, 0x01, 0xd3, 0x15, 0x46,
1295 0x08, 0x35, 0x55, 0x60, 0x01, 0x39, 0x00, 0x29, 0x02, 0xd0, 0xda, 0xe7, 0x00, 0x20, 0x50, 0x60,
1296 0x30, 0x46, 0x00, 0xbe, 0x00, 0xc0, 0x01, 0xa0
1297 };
1298
1299 /* flash write code */
1300 if (target_alloc_working_area(target, sizeof(niietcm4_flash_write_code),
1301 &write_algorithm) != ERROR_OK) {
1302 LOG_WARNING("no working area available, can't do block memory writes");
1303 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1304 }
1305
1306 retval = target_write_buffer(target, write_algorithm->address,
1307 sizeof(niietcm4_flash_write_code), niietcm4_flash_write_code);
1308 if (retval != ERROR_OK)
1309 return retval;
1310
1311 /* memory buffer */
1312 while (target_alloc_working_area_try(target, buffer_size, &source) != ERROR_OK) {
1313 buffer_size /= 2;
1314 buffer_size &= ~15UL; /* Make sure it's 16 byte aligned */
1315 buffer_size += 8; /* And 8 bytes for WP and RP */
1316 if (buffer_size <= 256) {
1317 /* we already allocated the writing code, but failed to get a
1318 * buffer, free the algorithm */
1319 target_free_working_area(target, write_algorithm);
1320
1321 LOG_WARNING("no large enough working area available, can't do block memory writes");
1322 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1323 }
1324 }
1325
1326 init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* write_cmd base (in), status (out) */
1327 init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT); /* count (128bit) */
1328 init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT); /* buffer start */
1329 init_reg_param(&reg_params[3], "r3", 32, PARAM_OUT); /* buffer end */
1330 init_reg_param(&reg_params[4], "r4", 32, PARAM_IN_OUT); /* target address */
1331
1332 uint32_t flash_cmd;
1333 if (niietcm4_info->bflash_info_remap)
1334 flash_cmd = FMC_MAGIC_KEY | FMC_WRITE_IFB;
1335 else
1336 flash_cmd = FMC_MAGIC_KEY | FMC_WRITE;
1337
1338 buf_set_u32(reg_params[0].value, 0, 32, flash_cmd);
1339 buf_set_u32(reg_params[1].value, 0, 32, count);
1340 buf_set_u32(reg_params[2].value, 0, 32, source->address);
1341 buf_set_u32(reg_params[3].value, 0, 32, source->address + source->size);
1342 buf_set_u32(reg_params[4].value, 0, 32, address);
1343
1344 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
1345 armv7m_info.core_mode = ARM_MODE_THREAD;
1346
1347 retval = target_run_flash_async_algorithm(target, buffer, count, 16,
1348 0, NULL,
1349 5, reg_params,
1350 source->address, source->size,
1351 write_algorithm->address, 0,
1352 &armv7m_info);
1353
1354 if (retval == ERROR_FLASH_OPERATION_FAILED)
1355 LOG_ERROR("flash write failed at address 0x%"PRIx32,
1356 buf_get_u32(reg_params[4].value, 0, 32));
1357
1358 target_free_working_area(target, source);
1359 target_free_working_area(target, write_algorithm);
1360
1361 destroy_reg_param(&reg_params[0]);
1362 destroy_reg_param(&reg_params[1]);
1363 destroy_reg_param(&reg_params[2]);
1364 destroy_reg_param(&reg_params[3]);
1365 destroy_reg_param(&reg_params[4]);
1366
1367 return retval;
1368 }
1369
1370 static int niietcm4_write(struct flash_bank *bank, const uint8_t *buffer,
1371 uint32_t offset, uint32_t count)
1372 {
1373 struct target *target = bank->target;
1374 struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
1375 uint8_t *new_buffer = NULL;
1376
1377 if (bank->target->state != TARGET_HALTED) {
1378 LOG_ERROR("Target not halted");
1379 return ERROR_TARGET_NOT_HALTED;
1380 }
1381
1382 if (offset & 0xF) {
1383 LOG_ERROR("offset 0x%" PRIx32 " breaks required 4-word alignment", offset);
1384 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
1385 }
1386
1387 /* If there's an odd number of words, the data has to be padded. Duplicate
1388 * the buffer and use the normal code path with a single block write since
1389 * it's probably cheaper than to special case the last odd write using
1390 * discrete accesses. */
1391
1392 int rem = count % 16;
1393 if (rem) {
1394 new_buffer = malloc(count + 16 - rem);
1395 if (!new_buffer) {
1396 LOG_ERROR("Odd number of words to write and no memory for padding buffer");
1397 return ERROR_FAIL;
1398 }
1399 LOG_INFO("Odd number of words to write, padding with 0xFFFFFFFF");
1400 buffer = memcpy(new_buffer, buffer, count);
1401 while (rem < 16) {
1402 new_buffer[count++] = 0xff;
1403 rem++;
1404 }
1405 }
1406
1407 int retval;
1408
1409 /* try using block write */
1410 retval = niietcm4_write_block(bank, buffer, offset, count/16);
1411 uint32_t flash_addr, flash_cmd, flash_data;
1412
1413 if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
1414 /* if block write failed (no sufficient working area),
1415 * we use normal (slow) single halfword accesses */
1416 LOG_WARNING("Can't use block writes, falling back to single memory accesses");
1417 LOG_INFO("Please wait ..."); /* it`s quite a long process */
1418
1419 /* chose between main bootflash and info bootflash */
1420 if (niietcm4_info->bflash_info_remap)
1421 flash_cmd = FMC_MAGIC_KEY | FMC_WRITE_IFB;
1422 else
1423 flash_cmd = FMC_MAGIC_KEY | FMC_WRITE;
1424
1425 /* write 16 bytes per try */
1426 for (unsigned int i = 0; i < count; i += 16) {
1427 /* current addr */
1428 LOG_INFO("%u byte of %" PRIu32, i, count);
1429 flash_addr = offset + i;
1430 retval = target_write_u32(target, FMA, flash_addr);
1431 if (retval != ERROR_OK)
1432 goto free_buffer;
1433
1434 /* Prepare data (4 words) */
1435 uint32_t value[4];
1436 memcpy(&value, buffer + i*16, 4*sizeof(uint32_t));
1437
1438 /* place in reg 16 bytes of data */
1439 flash_data = value[0];
1440 retval = target_write_u32(target, FMD1, flash_data);
1441 if (retval != ERROR_OK)
1442 goto free_buffer;
1443 flash_data = value[1];
1444 retval = target_write_u32(target, FMD2, flash_data);
1445 if (retval != ERROR_OK)
1446 goto free_buffer;
1447 flash_data = value[2];
1448 retval = target_write_u32(target, FMD3, flash_data);
1449 if (retval != ERROR_OK)
1450 goto free_buffer;
1451 flash_data = value[3];
1452 retval = target_write_u32(target, FMD4, flash_data);
1453 if (retval != ERROR_OK)
1454 goto free_buffer;
1455
1456 /* write start */
1457 retval = target_write_u32(target, FMC, flash_cmd);
1458 if (retval != ERROR_OK)
1459 goto free_buffer;
1460
1461 /* status check */
1462 retval = niietcm4_opstatus_check(bank);
1463 if (retval != ERROR_OK)
1464 goto free_buffer;
1465 }
1466
1467 }
1468
1469 free_buffer:
1470 free(new_buffer);
1471 return retval;
1472 }
1473
1474 static int niietcm4_probe_k1921vk01t(struct flash_bank *bank)
1475 {
1476 struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
1477 struct target *target = bank->target;
1478 int retval;
1479
1480 niietcm4_info->chip_name = "K1921VK01T";
1481
1482 /* check if we in service mode */
1483 uint32_t service_mode;
1484 retval = target_read_u32(target, 0x80017000, &service_mode);
1485 if (retval != ERROR_OK)
1486 return retval;
1487 service_mode = (service_mode>>2) & 0x1;
1488
1489 if (!service_mode) {
1490 niietcm4_info->uflash_width = 8;
1491 niietcm4_info->uflash_size = 0x10000;
1492 niietcm4_info->uflash_pagetotal = 256;
1493 niietcm4_info->uflash_info_size = 0x200;
1494 niietcm4_info->uflash_info_pagetotal = 2;
1495
1496 uint32_t uflash_data[2];
1497 uint32_t uflash_cmd = UFMC_MAGIC_KEY | UFMC_READ_IFB;
1498 for (int i = 0; i < 2; i++) {
1499 retval = target_write_u32(target, UFMA, i);
1500 if (retval != ERROR_OK)
1501 return retval;
1502 retval = target_write_u32(target, UFMC, uflash_cmd);
1503 if (retval != ERROR_OK)
1504 return retval;
1505 /* status check */
1506 retval = niietcm4_uopstatus_check(bank);
1507 if (retval != ERROR_OK)
1508 return retval;
1509 retval = target_read_u32(target, UFMD, &uflash_data[i]);
1510 if (retval != ERROR_OK)
1511 return retval;
1512 }
1513
1514 int boot_from_ifb = (uflash_data[0]>>INFOWORD0_BOOTFROM_IFB_POS) & 0x1;
1515 int en_gpio = (uflash_data[0]>>INFOWORD0_EN_GPIO_POS) & 0x1;
1516 int extmem_sel = (uflash_data[0]>>INFOWORD0_EXTMEM_SEL_POS) & 0x3;
1517 int pinnum = (uflash_data[1]>>INFOWORD1_PINNUM_POS) & 0xF;
1518 int portnum = (uflash_data[1]>>INFOWORD1_PORTNUM_POS) & 0x7;
1519
1520 if (boot_from_ifb)
1521 niietcm4_info->bflash_info_remap = false;
1522 else
1523 niietcm4_info->bflash_info_remap = true;
1524 if (extmem_sel == 0x2)
1525 niietcm4_info->extmem_boot_altfunc = 3;
1526 else
1527 niietcm4_info->extmem_boot_altfunc = 1;
1528 if (portnum == 0x0)
1529 niietcm4_info->extmem_boot_port = "GPIOA";
1530 else if (portnum == 0x1)
1531 niietcm4_info->extmem_boot_port = "GPIOB";
1532 else if (portnum == 0x2)
1533 niietcm4_info->extmem_boot_port = "GPIOC";
1534 else if (portnum == 0x3)
1535 niietcm4_info->extmem_boot_port = "GPIOD";
1536 else if (portnum == 0x4)
1537 niietcm4_info->extmem_boot_port = "GPIOE";
1538 else if (portnum == 0x5)
1539 niietcm4_info->extmem_boot_port = "GPIOF";
1540 else if (portnum == 0x6)
1541 niietcm4_info->extmem_boot_port = "GPIOG";
1542 else if (portnum == 0x7)
1543 niietcm4_info->extmem_boot_port = "GPIOH";
1544 else
1545 niietcm4_info->extmem_boot_port = "not defined";
1546 if (en_gpio)
1547 niietcm4_info->extmem_boot = false;
1548 else
1549 niietcm4_info->extmem_boot = true;
1550 niietcm4_info->extmem_boot_pin = pinnum;
1551
1552 /* check state of extmem boot en pin, if "high", extmem remapped to 0x00000000 */
1553 uint32_t extmem_boot_port_data;
1554 retval = target_read_u32(target, 0x80010000 + 0x1000*portnum, &extmem_boot_port_data);
1555 if (retval != ERROR_OK)
1556 return retval;
1557 int extmem_boot_pin_data = (extmem_boot_port_data>>pinnum) & 0x1;
1558
1559 uint32_t extmem_base;
1560 uint32_t bflash_base;
1561 if (extmem_boot_pin_data && niietcm4_info->extmem_boot) {
1562 extmem_base = 0x00000000;
1563 bflash_base = 0x40000000;
1564 } else {
1565 extmem_base = 0x40000000;
1566 bflash_base = 0x00000000;
1567 }
1568
1569 uint32_t bflash_size = 0x100000;
1570 uint32_t bflash_pages = 128;
1571 uint32_t bflash_info_size = 0x2000;
1572 uint32_t bflash_info_pages = 1;
1573 if (niietcm4_info->bflash_info_remap) {
1574 bflash_base += 0x2000;
1575 bflash_size -= 0x2000;
1576 bflash_pages--;
1577 bank->size = bflash_info_size;
1578 bank->num_sectors = bflash_info_pages;
1579 } else {
1580 bank->size = bflash_size;
1581 bank->num_sectors = bflash_pages;
1582 }
1583
1584 char info_bootflash_addr_str[64];
1585 if (niietcm4_info->bflash_info_remap)
1586 snprintf(info_bootflash_addr_str, sizeof(info_bootflash_addr_str),
1587 TARGET_ADDR_FMT " base address", bank->base);
1588 else
1589 snprintf(info_bootflash_addr_str, sizeof(info_bootflash_addr_str),
1590 "not mapped to global address space");
1591
1592 snprintf(niietcm4_info->chip_brief,
1593 sizeof(niietcm4_info->chip_brief),
1594 "\n"
1595 "MEMORY CONFIGURATION\n"
1596 "Bootflash :\n"
1597 " %" PRIu32 " kB total\n"
1598 " %" PRIu32 " pages %" PRIu32 " kB each\n"
1599 " 0x%08" PRIx32 " base address\n"
1600 "%s"
1601 "Info bootflash :\n"
1602 " %" PRIu32 " kB total\n"
1603 " %" PRIu32 " pages %" PRIu32 " kB each\n"
1604 " %s\n"
1605 "%s"
1606 "Userflash :\n"
1607 " %" PRIu32 " kB total\n"
1608 " %" PRIu32 " pages %" PRIu32 " B each\n"
1609 " %" PRIu32 " bit cells\n"
1610 " not mapped to global address space\n"
1611 "Info userflash :\n"
1612 " %" PRIu32 " B total\n"
1613 " %" PRIu32 " pages of %" PRIu32 " B each\n"
1614 " %" PRIu32 " bit cells\n"
1615 " not mapped to global address space\n"
1616 "RAM :\n"
1617 " 192 kB total\n"
1618 " 0x20000000 base address\n"
1619 "External memory :\n"
1620 " 8/16 bit address space\n"
1621 " 0x%08" PRIx32 " base address\n"
1622 "\n"
1623 "INFOWORD STATUS\n"
1624 "Bootflash info region remap :\n"
1625 " %s\n"
1626 "External memory boot port :\n"
1627 " %s\n"
1628 "External memory boot pin :\n"
1629 " %" PRIu32 "\n"
1630 "External memory interface alternative function :\n"
1631 " %" PRIu32 "\n"
1632 "Option boot from external memory :\n"
1633 " %s\n",
1634 bflash_size/1024,
1635 bflash_pages,
1636 (bflash_size/bflash_pages)/1024,
1637 bflash_base,
1638 niietcm4_info->bflash_info_remap ? "" : " this flash will be used for debugging, writing and etc\n",
1639 bflash_info_size/1024,
1640 bflash_info_pages,
1641 (bflash_info_size/bflash_info_pages)/1024,
1642 info_bootflash_addr_str,
1643 niietcm4_info->bflash_info_remap ? " this flash will be used for debugging, writing and etc\n" : "",
1644 niietcm4_info->uflash_size/1024,
1645 niietcm4_info->uflash_pagetotal,
1646 niietcm4_info->uflash_size/niietcm4_info->uflash_pagetotal,
1647 niietcm4_info->uflash_width,
1648 niietcm4_info->uflash_info_size,
1649 niietcm4_info->uflash_info_pagetotal,
1650 niietcm4_info->uflash_info_size/niietcm4_info->uflash_info_pagetotal,
1651 niietcm4_info->uflash_width,
1652 extmem_base,
1653 niietcm4_info->bflash_info_remap ? "enable" : "disable",
1654 niietcm4_info->extmem_boot_port,
1655 niietcm4_info->extmem_boot_pin,
1656 niietcm4_info->extmem_boot_altfunc,
1657 niietcm4_info->extmem_boot ? "enable" : "disable");
1658 } else {
1659 bank->size = 0x100000;
1660 bank->num_sectors = 128;
1661
1662 sprintf(niietcm4_info->chip_brief,
1663 "\n"
1664 "H[2] was HIGH while startup. Device entered service mode.\n"
1665 "All flashes were locked.\n"
1666 "If you want to perform emergency erase (erase all flashes),\n"
1667 "please use \"service_mode_erase\" command and reset device.\n"
1668 "Do not forget to pull H[2] down while reset for returning to normal operation mode.\n"
1669 );
1670 }
1671
1672 return retval;
1673 }
1674
1675 static int niietcm4_probe(struct flash_bank *bank)
1676 {
1677 struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
1678 struct target *target = bank->target;
1679
1680 free(bank->sectors);
1681 bank->sectors = NULL;
1682
1683 uint32_t retval;
1684 uint32_t chipid;
1685
1686 retval = target_read_u32(target, CHIPID_ADDR, &chipid);
1687 if (retval != ERROR_OK) {
1688 chipid = K1921VK01T_ID;
1689 LOG_INFO("unknown chipid, assuming K1921VK01T");
1690 }
1691
1692 if (chipid == K1921VK01T_ID)
1693 niietcm4_probe_k1921vk01t(bank);
1694
1695 int page_total = bank->num_sectors;
1696 int page_size = bank->size / page_total;
1697
1698 bank->sectors = malloc(sizeof(struct flash_sector) * page_total);
1699
1700 for (int i = 0; i < page_total; i++) {
1701 bank->sectors[i].offset = i * page_size;
1702 bank->sectors[i].size = page_size;
1703 bank->sectors[i].is_erased = -1;
1704 bank->sectors[i].is_protected = -1;
1705 }
1706
1707 niietcm4_info->probed = true;
1708
1709 return ERROR_OK;
1710 }
1711
1712 static int niietcm4_auto_probe(struct flash_bank *bank)
1713 {
1714 struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
1715 if (niietcm4_info->probed)
1716 return ERROR_OK;
1717 return niietcm4_probe(bank);
1718 }
1719
1720 static int get_niietcm4_info(struct flash_bank *bank, struct command_invocation *cmd)
1721 {
1722 struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
1723 command_print_sameline(cmd, "\nNIIET Cortex-M4F %s\n%s",
1724 niietcm4_info->chip_name, niietcm4_info->chip_brief);
1725 return ERROR_OK;
1726 }
1727
1728
1729 const struct flash_driver niietcm4_flash = {
1730 .name = "niietcm4",
1731 .usage = "flash bank <name> niietcm4 <base> <size> 0 0 <target#>",
1732 .commands = niietcm4_command_handlers,
1733 .flash_bank_command = niietcm4_flash_bank_command,
1734 .erase = niietcm4_erase,
1735 .protect = niietcm4_protect,
1736 .write = niietcm4_write,
1737 .read = default_flash_read,
1738 .probe = niietcm4_probe,
1739 .auto_probe = niietcm4_auto_probe,
1740 .erase_check = default_flash_blank_check,
1741 .protect_check = niietcm4_protect_check,
1742 .info = get_niietcm4_info,
1743 .free_driver_priv = default_flash_free_driver_priv,
1744 };

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)