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

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)