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