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

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)