target/xtensa: avoid IHI for writes to non-executable memory
[openocd.git] / src / flash / nor / niietcm4.c
blob0c36e2c96d2e46252cda46410fc5527f6373e6ad
1 // SPDX-License-Identifier: GPL-2.0-or-later
3 /***************************************************************************
4 * Copyright (C) 2015 by Bogdan Kolbov *
5 * kolbov@niiet.ru *
6 ***************************************************************************/
8 #ifdef HAVE_CONFIG_H
9 #include "config.h"
10 #endif
12 #include "imp.h"
13 #include <helper/binarybuffer.h>
14 #include <target/algorithm.h>
15 #include <target/armv7m.h>
17 #define FLASH_DRIVER_VER 0x00010000
18 #define CHIPID_ADDR 0xF0000000
19 #define K1921VK01T_ID 0x00000000
21 /*==============================================================================
22 * FLASH CONTROL REGS
23 *==============================================================================
26 #define MAIN_MEM_TYPE 0
27 #define INFO_MEM_TYPE 1
28 #define SERVICE_MODE_ERASE_ADDR 0x80030164
29 #define MAGIC_KEY 0xA442
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)
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 */
52 /*---- FCIS: Status register */
53 #define FCIS_OP_CMLT (1<<0) /* Completion flag operation */
54 #define FCIS_OP_ERROR (1<<1) /* Flag operation error */
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 */
60 /*-- USERFLASH ---------------------------------------------------------------*/
61 #define USERFLASH_PAGE_SIZE 256
62 #define USERFLASH_PAGE_TOTALNUM 256
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)
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 */
82 /*---- UFCIS: Status register */
83 #define UFCIS_OP_CMLT (1<<0) /* Completion flag operation */
84 #define UFCIS_OP_ERROR (1<<1) /* Flag operation error */
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 */
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 */
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 */
102 #define INFOWORD2_ADDR 0x02
103 #define INFOWORD2_LOCK_IFB_BF (1<<0) /* Protect info part of bootflash */
105 #define INFOWORD3_ADDR 0x03
106 #define INFOWORD3_LOCK_IFB_UF (1<<0) /* Protect info part of userflash */
108 #define BF_LOCK_ADDR 0x40
109 #define UF_LOCK_ADDR 0x80
112 * Private data for flash driver.
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;
134 /*==============================================================================
135 * HELPER FUNCTIONS
136 *==============================================================================
140 * Wait while operation with bootflash being performed and check result status
142 static int niietcm4_opstatus_check(struct flash_bank *bank)
144 struct target *target = bank->target;
145 int retval;
146 int timeout = 5000;
148 uint32_t flash_status;
149 retval = target_read_u32(target, FCIS, &flash_status);
150 if (retval != ERROR_OK)
151 return retval;
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;
161 busy_sleep(1); /* can use busy sleep for short times. */
163 if (flash_status == FCIS_OP_ERROR) {
164 LOG_ERROR("Bootflash operation error");
165 return ERROR_FLASH_OPERATION_FAILED;
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;
173 return retval;
177 * Wait while operation with userflash being performed and check result status
179 static int niietcm4_uopstatus_check(struct flash_bank *bank)
181 struct target *target = bank->target;
182 int retval;
183 int timeout = 5000;
185 uint32_t uflash_status;
186 retval = target_read_u32(target, UFCIS, &uflash_status);
187 if (retval != ERROR_OK)
188 return retval;
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;
198 busy_sleep(1); /* can use busy sleep for short times. */
200 if (uflash_status == UFCIS_OP_ERROR) {
201 LOG_ERROR("Userflash operation error");
202 return ERROR_FLASH_OPERATION_FAILED;
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;
210 return retval;
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.
219 static int niietcm4_dump_uflash_page(struct flash_bank *bank, uint32_t *dump, int page_num, int mem_type)
221 struct target *target = bank->target;
222 int i;
223 int retval = ERROR_OK;
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;
231 int first = page_num*USERFLASH_PAGE_SIZE;
232 int last = first + USERFLASH_PAGE_SIZE;
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;
249 return retval;
253 * Load modified page dump to userflash region page.
255 static int niietcm4_load_uflash_page(struct flash_bank *bank, uint32_t *dump, int page_num, int mem_type)
257 struct target *target = bank->target;
258 int i;
259 int retval = ERROR_OK;
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;
267 int first = page_num*USERFLASH_PAGE_SIZE;
268 int last = first + USERFLASH_PAGE_SIZE;
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;
285 return retval;
289 * Erase one page of userflash info or main region
291 static int niietcm4_uflash_page_erase(struct flash_bank *bank, int page_num, int mem_type)
293 struct target *target = bank->target;
294 int retval;
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;
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;
316 return retval;
320 * Enable or disable protection of userflash pages
322 static int niietcm4_uflash_protect(struct flash_bank *bank, int mem_type,
323 int set, unsigned int first, unsigned int last)
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);
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;
370 return retval;
373 /*==============================================================================
374 * FLASH COMMANDS
375 *==============================================================================
377 COMMAND_HANDLER(niietcm4_handle_uflash_read_byte_command)
379 if (CMD_ARGC < 3)
380 return ERROR_COMMAND_SYNTAX_ERROR;
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;
388 /* skip over flash bank */
389 CMD_ARGC--;
390 CMD_ARGV++;
392 uint32_t uflash_addr;
393 uint32_t uflash_cmd;
394 uint32_t uflash_data;
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;
403 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], uflash_addr);
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;
424 COMMAND_HANDLER(niietcm4_handle_uflash_write_byte_command)
426 if (CMD_ARGC < 4)
427 return ERROR_COMMAND_SYNTAX_ERROR;
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;
435 if (target->state != TARGET_HALTED) {
436 LOG_ERROR("Target not halted");
437 return ERROR_TARGET_NOT_HALTED;
440 /* skip over flash bank */
441 CMD_ARGC--;
442 CMD_ARGV++;
444 uint32_t uflash_addr;
445 uint32_t uflash_data;
446 int mem_type;
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;
455 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], uflash_addr);
456 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[2], uflash_data);
458 int page_num = uflash_addr/USERFLASH_PAGE_SIZE;
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);
468 /* modify dump */
469 uflash_dump[uflash_addr%USERFLASH_PAGE_SIZE] = uflash_data;
471 /* erase page userflash */
472 niietcm4_uflash_page_erase(bank, page_num, mem_type);
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;
480 COMMAND_HANDLER(niietcm4_handle_uflash_full_erase_command)
482 if (CMD_ARGC < 1)
483 return ERROR_COMMAND_SYNTAX_ERROR;
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;
491 if (target->state != TARGET_HALTED) {
492 LOG_ERROR("Target not halted");
493 return ERROR_TARGET_NOT_HALTED;
496 uint32_t uflash_addr = 0;
497 uint32_t uflash_data = 0xFF;
498 uint32_t uflash_cmd = UFMC_MAGIC_KEY | UFMC_FULL_ERASE;
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!");
515 return retval;
518 COMMAND_HANDLER(niietcm4_handle_uflash_erase_command)
520 if (CMD_ARGC < 4)
521 return ERROR_COMMAND_SYNTAX_ERROR;
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;
529 if (target->state != TARGET_HALTED) {
530 LOG_ERROR("Target not halted");
531 return ERROR_TARGET_NOT_HALTED;
534 /* skip over flash bank */
535 CMD_ARGC--;
536 CMD_ARGV++;
538 unsigned int first, last;
539 int mem_type;
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;
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;
556 command_print(CMD, "Erase %s userflash pages %u through %u done!", CMD_ARGV[0], first, last);
558 return retval;
561 COMMAND_HANDLER(niietcm4_handle_uflash_protect_check_command)
563 if (CMD_ARGC < 2)
564 return ERROR_COMMAND_SYNTAX_ERROR;
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;
571 struct target *target = bank->target;
572 if (target->state != TARGET_HALTED) {
573 LOG_ERROR("Target not halted");
574 return ERROR_TARGET_NOT_HALTED;
577 /* skip over flash bank */
578 CMD_ARGC--;
579 CMD_ARGV++;
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;
589 int i, j;
590 uint32_t uflash_addr;
591 uint32_t uflash_cmd;
592 uint32_t uflash_data;
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;
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;
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;
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;
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;
645 uflash_addr++;
649 return retval;
652 COMMAND_HANDLER(niietcm4_handle_uflash_protect_command)
654 if (CMD_ARGC < 5)
655 return ERROR_COMMAND_SYNTAX_ERROR;
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;
663 if (target->state != TARGET_HALTED) {
664 LOG_ERROR("Target not halted");
665 return ERROR_TARGET_NOT_HALTED;
668 /* skip over flash bank */
669 CMD_ARGC--;
670 CMD_ARGV++;
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;
680 unsigned int first, last;
681 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[1], first);
682 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[2], last);
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;
696 retval = niietcm4_uflash_protect(bank, mem_type, set, first, last);
697 if (retval != ERROR_OK)
698 return retval;
700 command_print(CMD, "done!");
701 return retval;
704 COMMAND_HANDLER(niietcm4_handle_bflash_info_remap_command)
706 if (CMD_ARGC < 2)
707 return ERROR_COMMAND_SYNTAX_ERROR;
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;
715 if (target->state != TARGET_HALTED) {
716 LOG_ERROR("Target not halted");
717 return ERROR_TARGET_NOT_HALTED;
720 /* skip over flash bank */
721 CMD_ARGC--;
722 CMD_ARGV++;
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;
734 /* dump */
735 uint32_t uflash_dump[USERFLASH_PAGE_SIZE];
736 niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1);
738 /* modify dump */
739 if (set)
740 uflash_dump[INFOWORD0_ADDR] &= ~INFOWORD0_BOOTFROM_IFB;
741 else
742 uflash_dump[INFOWORD0_ADDR] |= INFOWORD0_BOOTFROM_IFB;
744 /* erase page userflash */
745 niietcm4_uflash_page_erase(bank, 0, 1);
747 /* write dump to userflash */
748 niietcm4_load_uflash_page(bank, uflash_dump, 0, 1);
749 command_print(CMD, "done!");
751 return retval;
754 COMMAND_HANDLER(niietcm4_handle_extmem_cfg_command)
756 if (CMD_ARGC < 4)
757 return ERROR_COMMAND_SYNTAX_ERROR;
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;
765 if (target->state != TARGET_HALTED) {
766 LOG_ERROR("Target not halted");
767 return ERROR_TARGET_NOT_HALTED;
770 /* skip over flash bank */
771 CMD_ARGC--;
772 CMD_ARGV++;
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;
794 uint32_t pin;
795 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], pin);
796 if (pin > 15)
797 return ERROR_COMMAND_SYNTAX_ERROR;
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;
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);
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);
821 /* erase page userflash */
822 niietcm4_uflash_page_erase(bank, 0, 1);
824 /* write dump to userflash */
825 niietcm4_load_uflash_page(bank, uflash_dump, 0, 1);
826 command_print(CMD, "done!");
828 return retval;
831 COMMAND_HANDLER(niietcm4_handle_extmem_boot_command)
833 if (CMD_ARGC < 2)
834 return ERROR_COMMAND_SYNTAX_ERROR;
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;
842 if (target->state != TARGET_HALTED) {
843 LOG_ERROR("Target not halted");
844 return ERROR_TARGET_NOT_HALTED;
847 /* skip over flash bank */
848 CMD_ARGC--;
849 CMD_ARGV++;
851 int set;
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;
862 /* dump */
863 uint32_t uflash_dump[USERFLASH_PAGE_SIZE];
864 niietcm4_dump_uflash_page(bank, uflash_dump, 0, 1);
866 /* modify dump */
867 if (set)
868 uflash_dump[INFOWORD0_ADDR] &= ~INFOWORD0_EN_GPIO;
869 else
870 uflash_dump[INFOWORD0_ADDR] |= INFOWORD0_EN_GPIO;
872 /* erase page userflash */
873 niietcm4_uflash_page_erase(bank, 0, 1);
875 /* write dump to userflash */
876 niietcm4_load_uflash_page(bank, uflash_dump, 0, 1);
877 command_print(CMD, "done!");
879 return retval;
882 COMMAND_HANDLER(niietcm4_handle_service_mode_erase_command)
884 if (CMD_ARGC < 1)
885 return ERROR_COMMAND_SYNTAX_ERROR;
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;
893 command_print(CMD, "Try to perform service mode erase. Please wait ...");
895 retval = target_write_u32(target, SERVICE_MODE_ERASE_ADDR, 1);
896 if (retval != ERROR_OK)
897 return retval;
899 int timeout = 500;
900 uint32_t status;
902 retval = target_read_u32(target, SERVICE_MODE_ERASE_ADDR, &status);
903 if (retval != ERROR_OK)
904 return retval;
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;
914 busy_sleep(1); /* can use busy sleep for short times. */
916 command_print(CMD, "done! All data erased.");
918 return retval;
921 COMMAND_HANDLER(niietcm4_handle_driver_info_command)
923 if (CMD_ARGC < 1)
924 return ERROR_COMMAND_SYNTAX_ERROR;
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;
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);
938 return retval;
941 static const struct command_registration niietcm4_exec_command_handlers[] = {
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",
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",
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",
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.",
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.",
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.",
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).",
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.",
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.",
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).",
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.",
1019 COMMAND_REGISTRATION_DONE
1022 static const struct command_registration niietcm4_command_handlers[] = {
1024 .name = "niietcm4",
1025 .mode = COMMAND_ANY,
1026 .help = "niietcm4 flash command group",
1027 .usage = "",
1028 .chain = niietcm4_exec_command_handlers,
1030 COMMAND_REGISTRATION_DONE
1033 /*==============================================================================
1034 * FLASH INTERFACE
1035 *==============================================================================
1038 FLASH_BANK_COMMAND_HANDLER(niietcm4_flash_bank_command)
1040 struct niietcm4_flash_bank *niietcm4_info;
1042 if (CMD_ARGC < 6)
1043 return ERROR_COMMAND_SYNTAX_ERROR;
1045 niietcm4_info = malloc(sizeof(struct niietcm4_flash_bank));
1047 bank->driver_priv = niietcm4_info;
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;
1064 return ERROR_OK;
1067 static int niietcm4_protect_check(struct flash_bank *bank)
1069 struct target *target = bank->target;
1070 struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
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;
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;
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;
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;
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;
1128 uflash_addr++;
1132 return retval;
1135 static int niietcm4_mass_erase(struct flash_bank *bank)
1137 struct target *target = bank->target;
1139 int retval;
1140 uint32_t flash_cmd;
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;
1148 /* status check */
1149 retval = niietcm4_opstatus_check(bank);
1150 if (retval != ERROR_OK)
1151 return retval;
1153 return retval;
1156 static int niietcm4_erase(struct flash_bank *bank, unsigned int first,
1157 unsigned int last)
1159 struct target *target = bank->target;
1160 struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
1161 int retval = ERROR_FLASH_OPERATION_FAILED;
1163 if (bank->target->state != TARGET_HALTED) {
1164 LOG_ERROR("Target not halted");
1165 return ERROR_TARGET_NOT_HALTED;
1168 if ((first == 0) && (last == (bank->num_sectors - 1))) {
1169 retval = niietcm4_mass_erase(bank);
1170 return retval;
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;
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;
1189 /* start erase */
1190 retval = target_write_u32(target, FMC, flash_cmd);
1191 if (retval != ERROR_OK)
1192 return retval;
1194 /* status check */
1195 retval = niietcm4_opstatus_check(bank);
1196 if (retval != ERROR_OK)
1197 return retval;
1200 return retval;
1203 static int niietcm4_protect(struct flash_bank *bank, int set,
1204 unsigned int first, unsigned int last)
1206 struct target *target = bank->target;
1207 struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
1209 int retval;
1211 if (target->state != TARGET_HALTED) {
1212 LOG_ERROR("Target not halted");
1213 return ERROR_TARGET_NOT_HALTED;
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);
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;
1262 return retval;
1265 static int niietcm4_write_block(struct flash_bank *bank, const uint8_t *buffer,
1266 uint32_t offset, uint32_t count)
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;
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
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;
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;
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);
1310 LOG_WARNING("no large enough working area available, can't do block memory writes");
1311 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
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 */
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;
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);
1333 armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
1334 armv7m_info.core_mode = ARM_MODE_THREAD;
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);
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));
1347 target_free_working_area(target, source);
1348 target_free_working_area(target, write_algorithm);
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]);
1356 return retval;
1359 static int niietcm4_write(struct flash_bank *bank, const uint8_t *buffer,
1360 uint32_t offset, uint32_t count)
1362 struct target *target = bank->target;
1363 struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
1364 uint8_t *new_buffer = NULL;
1366 if (bank->target->state != TARGET_HALTED) {
1367 LOG_ERROR("Target not halted");
1368 return ERROR_TARGET_NOT_HALTED;
1371 if (offset & 0xF) {
1372 LOG_ERROR("offset 0x%" PRIx32 " breaks required 4-word alignment", offset);
1373 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
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. */
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;
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++;
1396 int retval;
1398 /* try using block write */
1399 retval = niietcm4_write_block(bank, buffer, offset, count/16);
1400 uint32_t flash_addr, flash_cmd, flash_data;
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 */
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;
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;
1423 /* Prepare data (4 words) */
1424 uint32_t value[4];
1425 memcpy(&value, buffer + i*16, 4*sizeof(uint32_t));
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;
1445 /* write start */
1446 retval = target_write_u32(target, FMC, flash_cmd);
1447 if (retval != ERROR_OK)
1448 goto free_buffer;
1450 /* status check */
1451 retval = niietcm4_opstatus_check(bank);
1452 if (retval != ERROR_OK)
1453 goto free_buffer;
1458 free_buffer:
1459 free(new_buffer);
1460 return retval;
1463 static int niietcm4_probe_k1921vk01t(struct flash_bank *bank)
1465 struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
1466 struct target *target = bank->target;
1467 int retval;
1469 niietcm4_info->chip_name = "K1921VK01T";
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;
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;
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;
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;
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;
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;
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;
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;
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");
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;
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"
1661 return retval;
1664 static int niietcm4_probe(struct flash_bank *bank)
1666 struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
1667 struct target *target = bank->target;
1669 free(bank->sectors);
1670 bank->sectors = NULL;
1672 uint32_t retval;
1673 uint32_t chipid;
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");
1681 if (chipid == K1921VK01T_ID)
1682 niietcm4_probe_k1921vk01t(bank);
1684 int page_total = bank->num_sectors;
1685 int page_size = bank->size / page_total;
1687 bank->sectors = malloc(sizeof(struct flash_sector) * page_total);
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;
1696 niietcm4_info->probed = true;
1698 return ERROR_OK;
1701 static int niietcm4_auto_probe(struct flash_bank *bank)
1703 struct niietcm4_flash_bank *niietcm4_info = bank->driver_priv;
1704 if (niietcm4_info->probed)
1705 return ERROR_OK;
1706 return niietcm4_probe(bank);
1709 static int get_niietcm4_info(struct flash_bank *bank, struct command_invocation *cmd)
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;
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,