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