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