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