flash/nor/numicro: remove useless architecture check
[fw/openocd] / src / flash / nor / numicro.c
1 /***************************************************************************
2  *   Copyright (C) 2011 by James K. Larson                                 *
3  *   jlarson@pacifier.com                                                  *
4  *                                                                         *
5  *   Copyright (C) 2013 Cosmin Gorgovan                                    *
6  *   cosmin [at] linux-geek [dot] org                                      *
7  *                                                                         *
8  *   Copyright (C) 2014 Pawel Si                                           *
9  *   stawel+openocd@gmail.com                                              *
10  *                                                                         *
11  *   Copyright (C) 2015 Nemui Trinomius                                    *
12  *   nemuisan_kawausogasuki@live.jp                                        *
13  *                                                                         *
14  *   This program is free software; you can redistribute it and/or modify  *
15  *   it under the terms of the GNU General Public License as published by  *
16  *   the Free Software Foundation; either version 2 of the License, or     *
17  *   (at your option) any later version.                                   *
18  *                                                                         *
19  *   This program is distributed in the hope that it will be useful,       *
20  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
21  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
22  *   GNU General Public License for more details.                          *
23  *                                                                         *
24  *   You should have received a copy of the GNU General Public License     *
25  *   along with this program.  If not, see <http://www.gnu.org/licenses/>. *
26  ***************************************************************************/
27
28 #ifdef HAVE_CONFIG_H
29 #include <config.h>
30 #endif
31
32 #include "imp.h"
33 #include <helper/binarybuffer.h>
34 #include <target/algorithm.h>
35 #include <target/armv7m.h>
36 #include <target/cortex_m.h>
37
38 /* Nuvoton NuMicro register locations */
39 #define NUMICRO_SYS_BASE        0x50000000
40 #define NUMICRO_SYS_WRPROT      0x50000100
41 #define NUMICRO_SYS_IPRSTC1     0x50000008
42
43 #define NUMICRO_SYSCLK_BASE     0x50000200
44 #define NUMICRO_SYSCLK_PWRCON   0x50000200
45 #define NUMICRO_SYSCLK_CLKSEL0  0x50000210
46 #define NUMICRO_SYSCLK_CLKDIV   0x50000218
47 #define NUMICRO_SYSCLK_AHBCLK   0x50000204
48
49 #define NUMICRO_FLASH_BASE      0x5000C000
50 #define NUMICRO_FLASH_ISPCON    0x5000C000
51 #define NUMICRO_FLASH_ISPADR    0x5000C004
52 #define NUMICRO_FLASH_ISPDAT    0x5000C008
53 #define NUMICRO_FLASH_ISPCMD    0x5000C00C
54 #define NUMICRO_FLASH_ISPTRG    0x5000C010
55 #define NUMICRO_FLASH_CHEAT       0x5000C01C    /* Undocumented isp register(may be cheat register) */
56
57 #define NUMICRO_SCS_BASE        0xE000E000
58 #define NUMICRO_SCS_AIRCR       0xE000ED0C
59 #define NUMICRO_SCS_DHCSR       0xE000EDF0
60 #define NUMICRO_SCS_DEMCR       0xE000EDFC
61
62 #define NUMICRO_APROM_BASE      0x00000000
63 #define NUMICRO_DATA_BASE       0x0001F000
64 #define NUMICRO_LDROM_BASE      0x00100000
65 #define NUMICRO_CONFIG_BASE     0x00300000
66
67 #define NUMICRO_CONFIG0         0x5000C000
68 #define NUMICRO_CONFIG1         0x5000C004
69
70 /* Command register bits */
71 #define PWRCON_OSC22M         (1 << 2)
72 #define PWRCON_XTL12M         (1 << 0)
73
74 #define IPRSTC1_CPU_RST       (1 << 1)
75 #define IPRSTC1_CHIP_RST      (1 << 0)
76
77 #define AHBCLK_ISP_EN         (1 << 2)
78 #define AHBCLK_SRAM_EN        (1 << 4)
79 #define AHBCLK_TICK_EN        (1 << 5)
80
81 #define ISPCON_ISPEN          (1 << 0)
82 #define ISPCON_BS_AP          (0 << 1)
83 #define ISPCON_BS_LP          (1 << 1)
84 #define ISPCON_BS_MASK        (1 << 1)
85 #define ISPCON_APUEN          (1 << 3)
86 #define ISPCON_CFGUEN         (1 << 4)
87 #define ISPCON_LDUEN          (1 << 5)
88 #define ISPCON_ISPFF          (1 << 6)
89
90 #define CONFIG0_LOCK_MASK         (1 << 1)
91
92 /* isp commands */
93 #define ISPCMD_READ           0x00
94 #define ISPCMD_WRITE          0x21
95 #define ISPCMD_ERASE          0x22
96 #define ISPCMD_CHIPERASE      0x26   /* Undocumented isp "Chip-Erase" command */
97 #define ISPCMD_READ_CID       0x0B
98 #define ISPCMD_READ_DID       0x0C
99 #define ISPCMD_READ_UID       0x04
100 #define ISPCMD_VECMAP         0x2E
101 #define ISPTRG_ISPGO          (1 << 0)
102
103 /* access unlock keys */
104 #define REG_KEY1              0x59
105 #define REG_KEY2              0x16
106 #define REG_KEY3              0x88
107 #define REG_LOCK              0x00
108
109 /* flash pagesizes */
110 #define NUMICRO_PAGESIZE        512
111 /* flash MAX banks */
112 #define NUMICRO_MAX_FLASH_BANKS 4
113
114 /* flash bank structs */
115 struct numicro_flash_bank_type {
116         uint32_t base;
117         uint32_t size;
118 };
119
120 /* part structs */
121 struct numicro_cpu_type {
122         char *partname;
123         uint32_t partid;
124         unsigned int n_banks;
125         struct numicro_flash_bank_type bank[NUMICRO_MAX_FLASH_BANKS];
126 };
127
128 /* TODO : Support variable DataFlash region for 128kB Flash model */
129 #define NUMICRO_BANKS_NUC100(aprom_size) \
130         .n_banks = 4, \
131         { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_DATA_BASE, 4*1024}, {NUMICRO_LDROM_BASE, 4*1024}, \
132         {NUMICRO_CONFIG_BASE, 1024} }
133
134 #define NUMICRO_BANKS_M051(aprom_size) \
135         .n_banks = 4, \
136         { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_DATA_BASE, 4*1024}, {NUMICRO_LDROM_BASE, 4*1024}, \
137         {NUMICRO_CONFIG_BASE, 1024} }
138
139 #define NUMICRO_BANKS_MINI51(aprom_size) \
140         .n_banks = 3, \
141         { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_LDROM_BASE, 2*1024}, {NUMICRO_CONFIG_BASE, 512} }
142
143 #define NUMICRO_BANKS_NANO(aprom_size) \
144         .n_banks = 4, \
145         { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_DATA_BASE, 4*1024}, {NUMICRO_LDROM_BASE, 4*1024}, \
146         {NUMICRO_CONFIG_BASE, 1024} }
147
148 #define NUMICRO_BANKS_NUC400(aprom_size) \
149         .n_banks = 4, \
150         { {NUMICRO_APROM_BASE, (aprom_size)}, {NUMICRO_DATA_BASE, 4*1024}, {NUMICRO_LDROM_BASE, 16*1024}, \
151         {NUMICRO_CONFIG_BASE, 1024} }
152
153
154 static const struct numicro_cpu_type numicro_parts[] = {
155         /*PART NO*/     /*PART ID*/ /*Banks*/
156         /* NUC100 Version B */
157         {"NUC100LD2BN", 0x10010004, NUMICRO_BANKS_NUC100(64*1024)},
158         {"NUC100LD1BN", 0x10010005, NUMICRO_BANKS_NUC100(64*1024)},
159         {"NUC100LD0BN", 0x10010027, NUMICRO_BANKS_NUC100(64*1024)},
160         {"NUC100LC2BN", 0x10010007, NUMICRO_BANKS_NUC100(32*1024)},
161         {"NUC100LC1BN", 0x10010008, NUMICRO_BANKS_NUC100(32*1024)},
162         {"NUC100LC0BN", 0x10010028, NUMICRO_BANKS_NUC100(32*1024)},
163         {"NUC100LB2BN", 0x10010029, NUMICRO_BANKS_NUC100(16*1024)},
164         {"NUC100LB1BN", 0x10010030, NUMICRO_BANKS_NUC100(16*1024)},
165         {"NUC100LB0BN", 0x10010031, NUMICRO_BANKS_NUC100(16*1024)},
166         {"NUC100LA2BN", 0x10010032, NUMICRO_BANKS_NUC100(8*1024)},
167         {"NUC100LA1BN", 0x10010033, NUMICRO_BANKS_NUC100(8*1024)},
168         {"NUC100LA0BN", 0x10010034, NUMICRO_BANKS_NUC100(8*1024)},
169
170         {"NUC100RD2BN", 0x10010013, NUMICRO_BANKS_NUC100(64*1024)},
171         {"NUC100RD1BN", 0x10010014, NUMICRO_BANKS_NUC100(64*1024)},
172         {"NUC100RD0BN", 0x10010035, NUMICRO_BANKS_NUC100(64*1024)},
173         {"NUC100RC2BN", 0x10010016, NUMICRO_BANKS_NUC100(32*1024)},
174         {"NUC100RC1BN", 0x10010017, NUMICRO_BANKS_NUC100(32*1024)},
175         {"NUC100RC0BN", 0x10010036, NUMICRO_BANKS_NUC100(32*1024)},
176         {"NUC100RB2BN", 0x10010037, NUMICRO_BANKS_NUC100(16*1024)},
177         {"NUC100RB1BN", 0x10010038, NUMICRO_BANKS_NUC100(16*1024)},
178         {"NUC100RB0BN", 0x10010039, NUMICRO_BANKS_NUC100(16*1024)},
179         {"NUC100RA2BN", 0x10010040, NUMICRO_BANKS_NUC100(8*1024)},
180         {"NUC100RA1BN", 0x10010041, NUMICRO_BANKS_NUC100(8*1024)},
181         {"NUC100RA0BN", 0x10010042, NUMICRO_BANKS_NUC100(8*1024)},
182
183     /* NUC100 Version C */
184         {"NUC100LE3CN", 0x20010000, NUMICRO_BANKS_NUC100(128*1024)},
185         {"NUC100LE2CN", 0x20010001, NUMICRO_BANKS_NUC100(128*1024)},
186         {"NUC100LE1CN", 0x20010002, NUMICRO_BANKS_NUC100(128*1024)},
187         {"NUC100LD3CN", 0x20010003, NUMICRO_BANKS_NUC100(64*1024)},
188         {"NUC100LD2CN", 0x20010004, NUMICRO_BANKS_NUC100(64*1024)},
189         {"NUC100LD1CN", 0x20010005, NUMICRO_BANKS_NUC100(64*1024)},
190         {"NUC100LC3CN", 0x20010006, NUMICRO_BANKS_NUC100(32*1024)},
191         {"NUC100LC2CN", 0x20010007, NUMICRO_BANKS_NUC100(32*1024)},
192         {"NUC100LC1CN", 0x20010008, NUMICRO_BANKS_NUC100(32*1024)},
193         {"NUC100RE3CN", 0x20010009, NUMICRO_BANKS_NUC100(128*1024)},
194         {"NUC100RE2CN", 0x20010010, NUMICRO_BANKS_NUC100(128*1024)},
195         {"NUC100RE1CN", 0x20010011, NUMICRO_BANKS_NUC100(128*1024)},
196         {"NUC100RD3CN", 0x20010012, NUMICRO_BANKS_NUC100(64*1024)},
197         {"NUC100RD2CN", 0x20010013, NUMICRO_BANKS_NUC100(64*1024)},
198         {"NUC100RD1CN", 0x20010014, NUMICRO_BANKS_NUC100(64*1024)},
199         {"NUC100RC3CN", 0x20010015, NUMICRO_BANKS_NUC100(32*1024)},
200         {"NUC100RC2CN", 0x20010016, NUMICRO_BANKS_NUC100(32*1024)},
201         {"NUC100RC1CN", 0x20010017, NUMICRO_BANKS_NUC100(32*1024)},
202         {"NUC100VE3CN", 0x20010018, NUMICRO_BANKS_NUC100(128*1024)},
203         {"NUC100VE2CN", 0x20010019, NUMICRO_BANKS_NUC100(128*1024)},
204         {"NUC100VE1CN", 0x20010020, NUMICRO_BANKS_NUC100(128*1024)},
205         {"NUC100VD3CN", 0x20010021, NUMICRO_BANKS_NUC100(64*1024)},
206         {"NUC100VD2CN", 0x20010022, NUMICRO_BANKS_NUC100(64*1024)},
207         {"NUC100VD1CN", 0x20010023, NUMICRO_BANKS_NUC100(64*1024)},
208         {"NUC100VC3CN", 0x20010024, NUMICRO_BANKS_NUC100(32*1024)},
209         {"NUC100VC2CN", 0x20010025, NUMICRO_BANKS_NUC100(32*1024)},
210         {"NUC100VC1CN", 0x20010026, NUMICRO_BANKS_NUC100(32*1024)},
211
212     /* NUC100 Version B */
213         {"NUC101YD2BN", 0x10010143, NUMICRO_BANKS_NUC100(64*1024)},
214         {"NUC101YD1BN", 0x10010144, NUMICRO_BANKS_NUC100(64*1024)},
215         {"NUC101YD0BN", 0x10010145, NUMICRO_BANKS_NUC100(64*1024)},
216         {"NUC101YC2BN", 0x10010146, NUMICRO_BANKS_NUC100(32*1024)},
217         {"NUC101YC1BN", 0x10010147, NUMICRO_BANKS_NUC100(32*1024)},
218         {"NUC101YC0BN", 0x10010148, NUMICRO_BANKS_NUC100(32*1024)},
219         {"NUC101YB2BN", 0x10010149, NUMICRO_BANKS_NUC100(16*1024)},
220         {"NUC101YB1BN", 0x10010150, NUMICRO_BANKS_NUC100(16*1024)},
221         {"NUC101YB0BN", 0x10010151, NUMICRO_BANKS_NUC100(16*1024)},
222         {"NUC101YA2BN", 0x10010152, NUMICRO_BANKS_NUC100(8*1024)},
223         {"NUC101YA1BN", 0x10010153, NUMICRO_BANKS_NUC100(8*1024)},
224         {"NUC101YA0BN", 0x10010154, NUMICRO_BANKS_NUC100(8*1024)},
225
226         {"NUC101LD2BN", 0x10010104, NUMICRO_BANKS_NUC100(64*1024)},
227         {"NUC101LD1BN", 0x10010105, NUMICRO_BANKS_NUC100(64*1024)},
228         {"NUC101LD0BN", 0x10010127, NUMICRO_BANKS_NUC100(64*1024)},
229         {"NUC101LC2BN", 0x10010107, NUMICRO_BANKS_NUC100(32*1024)},
230         {"NUC101LC1BN", 0x10010108, NUMICRO_BANKS_NUC100(32*1024)},
231         {"NUC101LC0BN", 0x10010128, NUMICRO_BANKS_NUC100(32*1024)},
232         {"NUC101LB2BN", 0x10010129, NUMICRO_BANKS_NUC100(16*1024)},
233         {"NUC101LB1BN", 0x10010130, NUMICRO_BANKS_NUC100(16*1024)},
234         {"NUC101LB0BN", 0x10010131, NUMICRO_BANKS_NUC100(16*1024)},
235         {"NUC101LA2BN", 0x10010132, NUMICRO_BANKS_NUC100(8*1024)},
236         {"NUC101LA1BN", 0x10010133, NUMICRO_BANKS_NUC100(8*1024)},
237         {"NUC101LA0BN", 0x10010134, NUMICRO_BANKS_NUC100(8*1024)},
238
239         {"NUC101RD2BN", 0x10010113, NUMICRO_BANKS_NUC100(64*1024)},
240         {"NUC101RD1BN", 0x10010114, NUMICRO_BANKS_NUC100(64*1024)},
241         {"NUC101RD0BN", 0x10010135, NUMICRO_BANKS_NUC100(64*1024)},
242         {"NUC101RC2BN", 0x10010116, NUMICRO_BANKS_NUC100(32*1024)},
243         {"NUC101RC1BN", 0x10010117, NUMICRO_BANKS_NUC100(32*1024)},
244         {"NUC101RC0BN", 0x10010136, NUMICRO_BANKS_NUC100(32*1024)},
245         {"NUC101RB2BN", 0x10010137, NUMICRO_BANKS_NUC100(16*1024)},
246         {"NUC101RB1BN", 0x10010138, NUMICRO_BANKS_NUC100(16*1024)},
247         {"NUC101RB0BN", 0x10010139, NUMICRO_BANKS_NUC100(16*1024)},
248         {"NUC101RA2BN", 0x10010140, NUMICRO_BANKS_NUC100(8*1024)},
249         {"NUC101RA1BN", 0x10010141, NUMICRO_BANKS_NUC100(8*1024)},
250         {"NUC101RA0BN", 0x10010142, NUMICRO_BANKS_NUC100(8*1024)},
251
252     /* NUC101 Version C */
253         {"NUC101LE3CN", 0x20010100, NUMICRO_BANKS_NUC100(128*1024)},
254         {"NUC101LE2CN", 0x20010101, NUMICRO_BANKS_NUC100(128*1024)},
255         {"NUC101LE1CN", 0x20010102, NUMICRO_BANKS_NUC100(128*1024)},
256         {"NUC101LD3CN", 0x20010103, NUMICRO_BANKS_NUC100(64*1024)},
257         {"NUC101LD2CN", 0x20010104, NUMICRO_BANKS_NUC100(64*1024)},
258         {"NUC101LD1CN", 0x20010105, NUMICRO_BANKS_NUC100(64*1024)},
259         {"NUC101LC3CN", 0x20010106, NUMICRO_BANKS_NUC100(32*1024)},
260         {"NUC101LC2CN", 0x20010107, NUMICRO_BANKS_NUC100(32*1024)},
261         {"NUC101LC1CN", 0x20010108, NUMICRO_BANKS_NUC100(32*1024)},
262         {"NUC101RE3CN", 0x20010109, NUMICRO_BANKS_NUC100(128*1024)},
263         {"NUC101RE2CN", 0x20010110, NUMICRO_BANKS_NUC100(128*1024)},
264         {"NUC101RE1CN", 0x20010111, NUMICRO_BANKS_NUC100(128*1024)},
265
266         {"NUC101RD3CN", 0x20010112, NUMICRO_BANKS_NUC100(64*1024)},
267         {"NUC101RD2CN", 0x20010113, NUMICRO_BANKS_NUC100(64*1024)},
268         {"NUC101RD1CN", 0x20010114, NUMICRO_BANKS_NUC100(64*1024)},
269         {"NUC101RC3CN", 0x20010115, NUMICRO_BANKS_NUC100(32*1024)},
270         {"NUC101RC2CN", 0x20010116, NUMICRO_BANKS_NUC100(32*1024)},
271         {"NUC101RC1CN", 0x20010117, NUMICRO_BANKS_NUC100(32*1024)},
272         {"NUC101VE3CN", 0x20010118, NUMICRO_BANKS_NUC100(128*1024)},
273         {"NUC101VE2CN", 0x20010119, NUMICRO_BANKS_NUC100(128*1024)},
274         {"NUC101VE1CN", 0x20010120, NUMICRO_BANKS_NUC100(128*1024)},
275         {"NUC101VD3CN", 0x20010121, NUMICRO_BANKS_NUC100(64*1024)},
276         {"NUC101VD2CN", 0x20010122, NUMICRO_BANKS_NUC100(64*1024)},
277         {"NUC101VD1CN", 0x20010123, NUMICRO_BANKS_NUC100(64*1024)},
278         {"NUC101VC3CN", 0x20010124, NUMICRO_BANKS_NUC100(32*1024)},
279         {"NUC101VC2CN", 0x20010125, NUMICRO_BANKS_NUC100(32*1024)},
280         {"NUC101VC1CN", 0x20010126, NUMICRO_BANKS_NUC100(32*1024)},
281
282     /* NUC102 Version A */
283         {"NUC102ZD2AN", 0x00010231, NUMICRO_BANKS_NUC100(64*1024)},
284         {"NUC102ZC1AN", 0x00010235, NUMICRO_BANKS_NUC100(32*1024)},
285         {"NUC102LD2AN", 0x00010204, NUMICRO_BANKS_NUC100(64*1024)},
286         {"NUC102LC1AN", 0x00010208, NUMICRO_BANKS_NUC100(32*1024)},
287
288         {"NUC102RB3AN", 0x00010248, NUMICRO_BANKS_NUC100(16*1024)},
289         {"NUC102RB2AN", 0x00010249, NUMICRO_BANKS_NUC100(16*1024)},
290         {"NUC102RB1AN", 0x00010250, NUMICRO_BANKS_NUC100(16*1024)},
291         {"NUC102RA3AN", 0x00010251, NUMICRO_BANKS_NUC100(8*1024)},
292         {"NUC102RA2AN", 0x00010252, NUMICRO_BANKS_NUC100(8*1024)},
293         {"NUC102RA1AN", 0x00010253, NUMICRO_BANKS_NUC100(8*1024)},
294         {"NUC102VB3AN", 0x00010254, NUMICRO_BANKS_NUC100(16*1024)},
295         {"NUC102VB2AN", 0x00010255, NUMICRO_BANKS_NUC100(16*1024)},
296         {"NUC102VB1AN", 0x00010256, NUMICRO_BANKS_NUC100(16*1024)},
297         {"NUC102VA3AN", 0x00010257, NUMICRO_BANKS_NUC100(8*1024)},
298         {"NUC102VA2AN", 0x00010258, NUMICRO_BANKS_NUC100(8*1024)},
299         {"NUC102VA1AN", 0x00010259, NUMICRO_BANKS_NUC100(8*1024)},
300         {"NUC102LA0AN", 0x00010260, NUMICRO_BANKS_NUC100(8*1024)},
301         {"NUC102LB0AN", 0x00010261, NUMICRO_BANKS_NUC100(16*1024)},
302         {"NUC102LC0AN", 0x00010262, NUMICRO_BANKS_NUC100(32*1024)},
303         {"NUC102LD0AN", 0x00010263, NUMICRO_BANKS_NUC100(64*1024)},
304         {"NUC102RA0AN", 0x00010264, NUMICRO_BANKS_NUC100(8*1024)},
305         {"NUC102RB0AN", 0x00010265, NUMICRO_BANKS_NUC100(16*1024)},
306         {"NUC102RC0AN", 0x00010266, NUMICRO_BANKS_NUC100(32*1024)},
307         {"NUC102RD0AN", 0x00010267, NUMICRO_BANKS_NUC100(64*1024)},
308         {"NUC102VA0AN", 0x00010268, NUMICRO_BANKS_NUC100(8*1024)},
309         {"NUC102VB0AN", 0x00010269, NUMICRO_BANKS_NUC100(16*1024)},
310         {"NUC102VC0AN", 0x00010270, NUMICRO_BANKS_NUC100(32*1024)},
311         {"NUC102VD0AN", 0x00010271, NUMICRO_BANKS_NUC100(64*1024)},
312         {"NUC102ZA0AN", 0x00010272, NUMICRO_BANKS_NUC100(8*1024)},
313         {"NUC102ZB0AN", 0x00010273, NUMICRO_BANKS_NUC100(16*1024)},
314         {"NUC102ZC0AN", 0x00010274, NUMICRO_BANKS_NUC100(32*1024)},
315         {"NUC102ZD0AN", 0x00010275, NUMICRO_BANKS_NUC100(64*1024)},
316
317     /* NUC102 Version A */
318         {"NUC122LD2AN", 0x00012204, NUMICRO_BANKS_NUC100(64*1024)},
319         {"NUC122LD1AN", 0x00012205, NUMICRO_BANKS_NUC100(64*1024)},
320         {"NUC122LC2AN", 0x00012207, NUMICRO_BANKS_NUC100(32*1024)},
321         {"NUC122LC1AN", 0x00012208, NUMICRO_BANKS_NUC100(32*1024)},
322         {"NUC122RD2AN", 0x00012213, NUMICRO_BANKS_NUC100(64*1024)},
323         {"NUC122RD1AN", 0x00012214, NUMICRO_BANKS_NUC100(64*1024)},
324         {"NUC122RC2AN", 0x00012216, NUMICRO_BANKS_NUC100(32*1024)},
325         {"NUC122RC1AN", 0x00012217, NUMICRO_BANKS_NUC100(32*1024)},
326         {"NUC122SD2AN", 0x00012222, NUMICRO_BANKS_NUC100(64*1024)},
327         {"NUC122SD1AN", 0x00012223, NUMICRO_BANKS_NUC100(64*1024)},
328         {"NUC122SC2AN", 0x00012225, NUMICRO_BANKS_NUC100(32*1024)},
329         {"NUC122SC1AN", 0x00012226, NUMICRO_BANKS_NUC100(32*1024)},
330         {"NUC122ZD2AN", 0x00012231, NUMICRO_BANKS_NUC100(64*1024)},
331         {"NUC122ZD1AN", 0x00012232, NUMICRO_BANKS_NUC100(64*1024)},
332         {"NUC122ZC2AN", 0x00012234, NUMICRO_BANKS_NUC100(32*1024)},
333         {"NUC122ZC1AN", 0x00012235, NUMICRO_BANKS_NUC100(32*1024)},
334         {"NUC122ZB2AN", 0x00012237, NUMICRO_BANKS_NUC100(16*1024)},
335         {"NUC122ZB1AN", 0x00012238, NUMICRO_BANKS_NUC100(16*1024)},
336         {"NUC122ZA2AN", 0x00012240, NUMICRO_BANKS_NUC100(8*1024)},
337         {"NUC122ZA1AN", 0x00012241, NUMICRO_BANKS_NUC100(8*1024)},
338         {"NUC122LB2AN", 0x00012243, NUMICRO_BANKS_NUC100(16*1024)},
339         {"NUC122LB1AN", 0x00012244, NUMICRO_BANKS_NUC100(16*1024)},
340         {"NUC122LA2AN", 0x00012246, NUMICRO_BANKS_NUC100(8*1024)},
341         {"NUC122LA1AN", 0x00012247, NUMICRO_BANKS_NUC100(8*1024)},
342         {"NUC122RB2AN", 0x00012249, NUMICRO_BANKS_NUC100(16*1024)},
343         {"NUC122RB1AN", 0x00012250, NUMICRO_BANKS_NUC100(16*1024)},
344         {"NUC122RA2AN", 0x00012252, NUMICRO_BANKS_NUC100(8*1024)},
345         {"NUC122RA1AN", 0x00012253, NUMICRO_BANKS_NUC100(8*1024)},
346         {"NUC122SB2AN", 0x00012255, NUMICRO_BANKS_NUC100(16*1024)},
347         {"NUC122SB1AN", 0x00012256, NUMICRO_BANKS_NUC100(16*1024)},
348         {"NUC122SA2AN", 0x00012258, NUMICRO_BANKS_NUC100(8*1024)},
349         {"NUC122SA1AN", 0x00012259, NUMICRO_BANKS_NUC100(8*1024)},
350         {"NUC122LA0AN", 0x00012260, NUMICRO_BANKS_NUC100(8*1024)},
351         {"NUC122LB0AN", 0x00012261, NUMICRO_BANKS_NUC100(16*1024)},
352         {"NUC122LC0AN", 0x00012262, NUMICRO_BANKS_NUC100(32*1024)},
353         {"NUC122LD0AN", 0x00012263, NUMICRO_BANKS_NUC100(64*1024)},
354         {"NUC122RA0AN", 0x00012264, NUMICRO_BANKS_NUC100(8*1024)},
355         {"NUC122RB0AN", 0x00012265, NUMICRO_BANKS_NUC100(16*1024)},
356         {"NUC122RC0AN", 0x00012266, NUMICRO_BANKS_NUC100(32*1024)},
357         {"NUC122RD0AN", 0x00012267, NUMICRO_BANKS_NUC100(64*1024)},
358         {"NUC122SA0AN", 0x00012268, NUMICRO_BANKS_NUC100(8*1024)},
359         {"NUC122SB0AN", 0x00012269, NUMICRO_BANKS_NUC100(16*1024)},
360         {"NUC122SC0AN", 0x00012270, NUMICRO_BANKS_NUC100(32*1024)},
361         {"NUC122SD0AN", 0x00012271, NUMICRO_BANKS_NUC100(64*1024)},
362         {"NUC122ZA0AN", 0x00012272, NUMICRO_BANKS_NUC100(8*1024)},
363         {"NUC122ZB0AN", 0x00012273, NUMICRO_BANKS_NUC100(16*1024)},
364         {"NUC122ZC0AN", 0x00012274, NUMICRO_BANKS_NUC100(32*1024)},
365         {"NUC122ZD0AN", 0x00012275, NUMICRO_BANKS_NUC100(64*1024)},
366         {"NUC122YD2AN", 0x00012277, NUMICRO_BANKS_NUC100(64*1024)},
367         {"NUC122YD1AN", 0x00012278, NUMICRO_BANKS_NUC100(64*1024)},
368         {"NUC122YD0AN", 0x00012279, NUMICRO_BANKS_NUC100(64*1024)},
369         {"NUC122YC2AN", 0x00012281, NUMICRO_BANKS_NUC100(32*1024)},
370         {"NUC122YC1AN", 0x00012282, NUMICRO_BANKS_NUC100(32*1024)},
371         {"NUC122YC0AN", 0x00012283, NUMICRO_BANKS_NUC100(32*1024)},
372         {"NUC122YB2AN", 0x00012285, NUMICRO_BANKS_NUC100(16*1024)},
373         {"NUC122YB1AN", 0x00012286, NUMICRO_BANKS_NUC100(16*1024)},
374         {"NUC122YB0AN", 0x00012287, NUMICRO_BANKS_NUC100(16*1024)},
375         {"NUC122YA2AN", 0x00012289, NUMICRO_BANKS_NUC100(8*1024)},
376         {"NUC122YA1AN", 0x00012290, NUMICRO_BANKS_NUC100(8*1024)},
377         {"NUC122YA0AN", 0x00012291, NUMICRO_BANKS_NUC100(8*1024)},
378
379     /* NUC120 Version C */
380         {"NUC120LD2BN", 0x10012004, NUMICRO_BANKS_NUC100(64*1024)},
381         {"NUC120LD1BN", 0x10012005, NUMICRO_BANKS_NUC100(64*1024)},
382         {"NUC120LD0BN", 0x10012027, NUMICRO_BANKS_NUC100(64*1024)},
383         {"NUC120LC2BN", 0x10012007, NUMICRO_BANKS_NUC100(32*1024)},
384         {"NUC120LC1BN", 0x10012008, NUMICRO_BANKS_NUC100(32*1024)},
385         {"NUC120LC0BN", 0x10012028, NUMICRO_BANKS_NUC100(32*1024)},
386         {"NUC120LB2BN", 0x10012029, NUMICRO_BANKS_NUC100(16*1024)},
387         {"NUC120LB1BN", 0x10012030, NUMICRO_BANKS_NUC100(16*1024)},
388         {"NUC120LB0BN", 0x10012031, NUMICRO_BANKS_NUC100(16*1024)},
389         {"NUC120LA2BN", 0x10012032, NUMICRO_BANKS_NUC100(8*1024)},
390         {"NUC120LA1BN", 0x10012033, NUMICRO_BANKS_NUC100(8*1024)},
391         {"NUC120LA0BN", 0x10012034, NUMICRO_BANKS_NUC100(8*1024)},
392
393         {"NUC120RD2BN", 0x10012013, NUMICRO_BANKS_NUC100(64*1024)},
394         {"NUC120RD1BN", 0x10012014, NUMICRO_BANKS_NUC100(64*1024)},
395         {"NUC120RD0BN", 0x10012035, NUMICRO_BANKS_NUC100(64*1024)},
396         {"NUC120RC2BN", 0x10012016, NUMICRO_BANKS_NUC100(32*1024)},
397         {"NUC120RC1BN", 0x10012017, NUMICRO_BANKS_NUC100(32*1024)},
398         {"NUC120RC0BN", 0x10012036, NUMICRO_BANKS_NUC100(32*1024)},
399         {"NUC120RB2BN", 0x10012037, NUMICRO_BANKS_NUC100(16*1024)},
400         {"NUC120RB1BN", 0x10012038, NUMICRO_BANKS_NUC100(16*1024)},
401         {"NUC120RB0BN", 0x10012039, NUMICRO_BANKS_NUC100(16*1024)},
402         {"NUC120RA2BN", 0x10012040, NUMICRO_BANKS_NUC100(8*1024)},
403         {"NUC120RA1BN", 0x10012041, NUMICRO_BANKS_NUC100(8*1024)},
404         {"NUC120RA0BN", 0x10012042, NUMICRO_BANKS_NUC100(8*1024)},
405
406     /* NUC120 Version C */
407         {"NUC120LE3CN", 0x20012000, NUMICRO_BANKS_NUC100(128*1024)},
408         {"NUC120LE2CN", 0x20012001, NUMICRO_BANKS_NUC100(128*1024)},
409         {"NUC120LE1CN", 0x20012002, NUMICRO_BANKS_NUC100(128*1024)},
410         {"NUC120LD3CN", 0x20012003, NUMICRO_BANKS_NUC100(64*1024)},
411         {"NUC120LD2CN", 0x20012004, NUMICRO_BANKS_NUC100(64*1024)},
412         {"NUC120LD1CN", 0x20012005, NUMICRO_BANKS_NUC100(64*1024)},
413         {"NUC120LC3CN", 0x20012006, NUMICRO_BANKS_NUC100(32*1024)},
414         {"NUC120LC2CN", 0x20012007, NUMICRO_BANKS_NUC100(32*1024)},
415         {"NUC120LC1CN", 0x20012008, NUMICRO_BANKS_NUC100(32*1024)},
416         {"NUC120RE3CN", 0x20012009, NUMICRO_BANKS_NUC100(128*1024)},
417         {"NUC120RE2CN", 0x20012010, NUMICRO_BANKS_NUC100(128*1024)},
418         {"NUC120RE1CN", 0x20012011, NUMICRO_BANKS_NUC100(128*1024)},
419
420         {"NUC120RD3CN", 0x20012012, NUMICRO_BANKS_NUC100(64*1024)},
421         {"NUC120RD2CN", 0x20012013, NUMICRO_BANKS_NUC100(64*1024)},
422         {"NUC120RD1CN", 0x20012014, NUMICRO_BANKS_NUC100(64*1024)},
423         {"NUC120RC3CN", 0x20012015, NUMICRO_BANKS_NUC100(32*1024)},
424         {"NUC120RC2CN", 0x20012016, NUMICRO_BANKS_NUC100(32*1024)},
425         {"NUC120RC1CN", 0x20012017, NUMICRO_BANKS_NUC100(32*1024)},
426         {"NUC120VE3CN", 0x20012018, NUMICRO_BANKS_NUC100(128*1024)},
427         {"NUC120VE2CN", 0x20012019, NUMICRO_BANKS_NUC100(128*1024)},
428         {"NUC120VE1CN", 0x20012020, NUMICRO_BANKS_NUC100(128*1024)},
429         {"NUC120VD3CN", 0x20012021, NUMICRO_BANKS_NUC100(64*1024)},
430         {"NUC120VD2CN", 0x20012022, NUMICRO_BANKS_NUC100(64*1024)},
431         {"NUC120VD1CN", 0x20012023, NUMICRO_BANKS_NUC100(64*1024)},
432         {"NUC120VC3CN", 0x20012024, NUMICRO_BANKS_NUC100(32*1024)},
433         {"NUC120VC2CN", 0x20012025, NUMICRO_BANKS_NUC100(32*1024)},
434         {"NUC120VC1CN", 0x20012026, NUMICRO_BANKS_NUC100(32*1024)},
435
436     /* NUC120 Version B */
437         {"NUC130LD2BN", 0x10013004, NUMICRO_BANKS_NUC100(64*1024)},
438         {"NUC130LD1BN", 0x10013005, NUMICRO_BANKS_NUC100(64*1024)},
439         {"NUC130LD0BN", 0x10013027, NUMICRO_BANKS_NUC100(64*1024)},
440         {"NUC130LC2BN", 0x10013007, NUMICRO_BANKS_NUC100(32*1024)},
441         {"NUC130LC1BN", 0x10013008, NUMICRO_BANKS_NUC100(32*1024)},
442         {"NUC130LC0BN", 0x10013028, NUMICRO_BANKS_NUC100(32*1024)},
443         {"NUC130LB2BN", 0x10013029, NUMICRO_BANKS_NUC100(16*1024)},
444         {"NUC130LB1BN", 0x10013030, NUMICRO_BANKS_NUC100(16*1024)},
445         {"NUC130LB0BN", 0x10013031, NUMICRO_BANKS_NUC100(16*1024)},
446         {"NUC130LA2BN", 0x10013032, NUMICRO_BANKS_NUC100(8*1024)},
447         {"NUC130LA1BN", 0x10013033, NUMICRO_BANKS_NUC100(8*1024)},
448         {"NUC130LA0BN", 0x10013034, NUMICRO_BANKS_NUC100(8*1024)},
449
450         {"NUC130RD2BN", 0x10013013, NUMICRO_BANKS_NUC100(64*1024)},
451         {"NUC130RD1BN", 0x10013014, NUMICRO_BANKS_NUC100(64*1024)},
452         {"NUC130RD0BN", 0x10013035, NUMICRO_BANKS_NUC100(64*1024)},
453         {"NUC130RC2BN", 0x10013016, NUMICRO_BANKS_NUC100(32*1024)},
454         {"NUC130RC1BN", 0x10013017, NUMICRO_BANKS_NUC100(32*1024)},
455         {"NUC130RC0BN", 0x10013036, NUMICRO_BANKS_NUC100(32*1024)},
456         {"NUC130RB2BN", 0x10013037, NUMICRO_BANKS_NUC100(16*1024)},
457         {"NUC130RB1BN", 0x10013038, NUMICRO_BANKS_NUC100(16*1024)},
458         {"NUC130RB0BN", 0x10013039, NUMICRO_BANKS_NUC100(16*1024)},
459         {"NUC130RA2BN", 0x10013040, NUMICRO_BANKS_NUC100(8*1024)},
460         {"NUC130RA1BN", 0x10013041, NUMICRO_BANKS_NUC100(8*1024)},
461         {"NUC130RA0BN", 0x10013042, NUMICRO_BANKS_NUC100(8*1024)},
462
463     /* NUC130 Version C */
464         {"NUC130LE3CN", 0x20013000, NUMICRO_BANKS_NUC100(128*1024)},
465         {"NUC130LE2CN", 0x20013001, NUMICRO_BANKS_NUC100(128*1024)},
466         {"NUC130LE1CN", 0x20013002, NUMICRO_BANKS_NUC100(128*1024)},
467         {"NUC130LD3CN", 0x20013003, NUMICRO_BANKS_NUC100(64*1024)},
468         {"NUC130LD2CN", 0x20013004, NUMICRO_BANKS_NUC100(64*1024)},
469         {"NUC130LD1CN", 0x20013005, NUMICRO_BANKS_NUC100(64*1024)},
470         {"NUC130LC3CN", 0x20013006, NUMICRO_BANKS_NUC100(32*1024)},
471         {"NUC130LC2CN", 0x20013007, NUMICRO_BANKS_NUC100(32*1024)},
472         {"NUC130LC1CN", 0x20013008, NUMICRO_BANKS_NUC100(32*1024)},
473         {"NUC130RE3CN", 0x20013009, NUMICRO_BANKS_NUC100(128*1024)},
474         {"NUC130RE2CN", 0x20013010, NUMICRO_BANKS_NUC100(128*1024)},
475         {"NUC130RE1CN", 0x20013011, NUMICRO_BANKS_NUC100(128*1024)},
476
477         {"NUC130RD3CN", 0x20013012, NUMICRO_BANKS_NUC100(64*1024)},
478         {"NUC130RD2CN", 0x20013013, NUMICRO_BANKS_NUC100(64*1024)},
479         {"NUC130RD1CN", 0x20013014, NUMICRO_BANKS_NUC100(64*1024)},
480         {"NUC130RC3CN", 0x20013015, NUMICRO_BANKS_NUC100(32*1024)},
481         {"NUC130RC2CN", 0x20013016, NUMICRO_BANKS_NUC100(32*1024)},
482         {"NUC130RC1CN", 0x20013017, NUMICRO_BANKS_NUC100(32*1024)},
483         {"NUC130VE3CN", 0x20013018, NUMICRO_BANKS_NUC100(128*1024)},
484         {"NUC130VE2CN", 0x20013019, NUMICRO_BANKS_NUC100(128*1024)},
485         {"NUC130VE1CN", 0x20013020, NUMICRO_BANKS_NUC100(128*1024)},
486         {"NUC130VD3CN", 0x20013021, NUMICRO_BANKS_NUC100(64*1024)},
487         {"NUC130VD2CN", 0x20013022, NUMICRO_BANKS_NUC100(64*1024)},
488         {"NUC130VD1CN", 0x20013023, NUMICRO_BANKS_NUC100(64*1024)},
489         {"NUC130VC3CN", 0x20013024, NUMICRO_BANKS_NUC100(32*1024)},
490         {"NUC130VC2CN", 0x20013025, NUMICRO_BANKS_NUC100(32*1024)},
491         {"NUC130VC1CN", 0x20013026, NUMICRO_BANKS_NUC100(32*1024)},
492
493     /* NUC140 Version B */
494         {"NUC140LD2BN", 0x10014004, NUMICRO_BANKS_NUC100(64*1024)},
495         {"NUC140LD1BN", 0x10014005, NUMICRO_BANKS_NUC100(64*1024)},
496         {"NUC140LD0BN", 0x10014027, NUMICRO_BANKS_NUC100(64*1024)},
497         {"NUC140LC2BN", 0x10014007, NUMICRO_BANKS_NUC100(32*1024)},
498         {"NUC140LC1BN", 0x10014008, NUMICRO_BANKS_NUC100(32*1024)},
499         {"NUC140LC0BN", 0x10014028, NUMICRO_BANKS_NUC100(32*1024)},
500         {"NUC140LB2BN", 0x10014029, NUMICRO_BANKS_NUC100(16*1024)},
501         {"NUC140LB1BN", 0x10014030, NUMICRO_BANKS_NUC100(16*1024)},
502         {"NUC140LB0BN", 0x10014031, NUMICRO_BANKS_NUC100(16*1024)},
503         {"NUC140LA2BN", 0x10014032, NUMICRO_BANKS_NUC100(8*1024)},
504         {"NUC140LA1BN", 0x10014033, NUMICRO_BANKS_NUC100(8*1024)},
505         {"NUC140LA0BN", 0x10014034, NUMICRO_BANKS_NUC100(8*1024)},
506
507         {"NUC140RD2BN", 0x10014013, NUMICRO_BANKS_NUC100(64*1024)},
508         {"NUC140RD1BN", 0x10014014, NUMICRO_BANKS_NUC100(64*1024)},
509         {"NUC140RD0BN", 0x10014035, NUMICRO_BANKS_NUC100(64*1024)},
510         {"NUC140RC2BN", 0x10014016, NUMICRO_BANKS_NUC100(32*1024)},
511         {"NUC140RC1BN", 0x10014017, NUMICRO_BANKS_NUC100(32*1024)},
512         {"NUC140RC0BN", 0x10014036, NUMICRO_BANKS_NUC100(32*1024)},
513         {"NUC140RB2BN", 0x10014037, NUMICRO_BANKS_NUC100(16*1024)},
514         {"NUC140RB1BN", 0x10014038, NUMICRO_BANKS_NUC100(16*1024)},
515         {"NUC140RB0BN", 0x10014039, NUMICRO_BANKS_NUC100(16*1024)},
516         {"NUC140RA2BN", 0x10014040, NUMICRO_BANKS_NUC100(8*1024)},
517         {"NUC140RA1BN", 0x10014041, NUMICRO_BANKS_NUC100(8*1024)},
518         {"NUC140RA0BN", 0x10014042, NUMICRO_BANKS_NUC100(8*1024)},
519
520     /* NUC140 Version C */
521         {"NUC140LE3CN", 0x20014000, NUMICRO_BANKS_NUC100(128*1024)},
522         {"NUC140LE2CN", 0x20014001, NUMICRO_BANKS_NUC100(128*1024)},
523         {"NUC140LE1CN", 0x20014002, NUMICRO_BANKS_NUC100(128*1024)},
524         {"NUC140LD3CN", 0x20014003, NUMICRO_BANKS_NUC100(64*1024)},
525         {"NUC140LD2CN", 0x20014004, NUMICRO_BANKS_NUC100(64*1024)},
526         {"NUC140LD1CN", 0x20014005, NUMICRO_BANKS_NUC100(64*1024)},
527         {"NUC140LC3CN", 0x20014006, NUMICRO_BANKS_NUC100(32*1024)},
528         {"NUC140LC2CN", 0x20014007, NUMICRO_BANKS_NUC100(32*1024)},
529         {"NUC140LC1CN", 0x20014008, NUMICRO_BANKS_NUC100(32*1024)},
530         {"NUC140RE3CN", 0x20014009, NUMICRO_BANKS_NUC100(128*1024)},
531         {"NUC140RE2CN", 0x20014010, NUMICRO_BANKS_NUC100(128*1024)},
532         {"NUC140RE1CN", 0x20014011, NUMICRO_BANKS_NUC100(128*1024)},
533
534         {"NUC140RD3CN", 0x20014012, NUMICRO_BANKS_NUC100(64*1024)},
535         {"NUC140RD2CN", 0x20014013, NUMICRO_BANKS_NUC100(64*1024)},
536         {"NUC140RD1CN", 0x20014014, NUMICRO_BANKS_NUC100(64*1024)},
537         {"NUC140RC3CN", 0x20014015, NUMICRO_BANKS_NUC100(32*1024)},
538         {"NUC140RC2CN", 0x20014016, NUMICRO_BANKS_NUC100(32*1024)},
539         {"NUC140RC1CN", 0x20014017, NUMICRO_BANKS_NUC100(32*1024)},
540         {"NUC140VE3CN", 0x20014018, NUMICRO_BANKS_NUC100(128*1024)},
541         {"NUC140VE2CN", 0x20014019, NUMICRO_BANKS_NUC100(128*1024)},
542         {"NUC140VE1CN", 0x20014020, NUMICRO_BANKS_NUC100(128*1024)},
543         {"NUC140VD3CN", 0x20014021, NUMICRO_BANKS_NUC100(64*1024)},
544         {"NUC140VD2CN", 0x20014022, NUMICRO_BANKS_NUC100(64*1024)},
545         {"NUC140VD1CN", 0x20014023, NUMICRO_BANKS_NUC100(64*1024)},
546         {"NUC140VC3CN", 0x20014024, NUMICRO_BANKS_NUC100(32*1024)},
547         {"NUC140VC2CN", 0x20014025, NUMICRO_BANKS_NUC100(32*1024)},
548         {"NUC140VC1CN", 0x20014026, NUMICRO_BANKS_NUC100(32*1024)},
549
550     /* NUC100 Version A */
551         {"NUC100LE3AN", 0x00010000, NUMICRO_BANKS_NUC100(128*1024)},
552         {"NUC100LE2AN", 0x00010001, NUMICRO_BANKS_NUC100(128*1024)},
553         {"NUC100LE1AN", 0x00010002, NUMICRO_BANKS_NUC100(128*1024)},
554         {"NUC100LD3AN", 0x00010003, NUMICRO_BANKS_NUC100(64*1024)},
555         {"NUC100LD2AN", 0x00010004, NUMICRO_BANKS_NUC100(64*1024)},
556         {"NUC100LD1AN", 0x00010005, NUMICRO_BANKS_NUC100(64*1024)},
557         {"NUC100LC3AN", 0x00010006, NUMICRO_BANKS_NUC100(32*1024)},
558         {"NUC100LC2AN", 0x00010007, NUMICRO_BANKS_NUC100(32*1024)},
559         {"NUC100LC1AN", 0x00010008, NUMICRO_BANKS_NUC100(32*1024)},
560         {"NUC100RE3AN", 0x00010009, NUMICRO_BANKS_NUC100(128*1024)},
561         {"NUC100RE2AN", 0x00010010, NUMICRO_BANKS_NUC100(128*1024)},
562         {"NUC100RE1AN", 0x00010011, NUMICRO_BANKS_NUC100(128*1024)},
563         {"NUC100RD3AN", 0x00010012, NUMICRO_BANKS_NUC100(64*1024)},
564         {"NUC100RD2AN", 0x00010013, NUMICRO_BANKS_NUC100(64*1024)},
565         {"NUC100RD1AN", 0x00010014, NUMICRO_BANKS_NUC100(64*1024)},
566         {"NUC100RC3AN", 0x00010015, NUMICRO_BANKS_NUC100(32*1024)},
567         {"NUC100RC2AN", 0x00010016, NUMICRO_BANKS_NUC100(32*1024)},
568         {"NUC100RC1AN", 0x00010017, NUMICRO_BANKS_NUC100(32*1024)},
569         {"NUC100VE3AN", 0x00010018, NUMICRO_BANKS_NUC100(128*1024)},
570         {"NUC100VE2AN", 0x00010019, NUMICRO_BANKS_NUC100(128*1024)},
571         {"NUC100VE1AN", 0x00010020, NUMICRO_BANKS_NUC100(128*1024)},
572         {"NUC100VD3AN", 0x00010021, NUMICRO_BANKS_NUC100(64*1024)},
573         {"NUC100VD2AN", 0x00010022, NUMICRO_BANKS_NUC100(64*1024)},
574         {"NUC100VD1AN", 0x00010023, NUMICRO_BANKS_NUC100(64*1024)},
575         {"NUC100VC3AN", 0x00010024, NUMICRO_BANKS_NUC100(32*1024)},
576         {"NUC100VC2AN", 0x00010025, NUMICRO_BANKS_NUC100(32*1024)},
577         {"NUC100VC1AN", 0x00010026, NUMICRO_BANKS_NUC100(32*1024)},
578
579     /* NUC100 Version A */
580         {"NUC101LE3AN", 0x00010100, NUMICRO_BANKS_NUC100(128*1024)},
581         {"NUC101LE2AN", 0x00010101, NUMICRO_BANKS_NUC100(128*1024)},
582         {"NUC101LE1AN", 0x00010102, NUMICRO_BANKS_NUC100(128*1024)},
583         {"NUC101LD3AN", 0x00010103, NUMICRO_BANKS_NUC100(64*1024)},
584         {"NUC101LD2AN", 0x00010104, NUMICRO_BANKS_NUC100(64*1024)},
585         {"NUC101LD1AN", 0x00010105, NUMICRO_BANKS_NUC100(64*1024)},
586         {"NUC101LC3AN", 0x00010106, NUMICRO_BANKS_NUC100(32*1024)},
587         {"NUC101LC2AN", 0x00010107, NUMICRO_BANKS_NUC100(32*1024)},
588         {"NUC101LC1AN", 0x00010108, NUMICRO_BANKS_NUC100(32*1024)},
589         {"NUC101RE3AN", 0x00010109, NUMICRO_BANKS_NUC100(128*1024)},
590         {"NUC101RE2AN", 0x00010110, NUMICRO_BANKS_NUC100(128*1024)},
591         {"NUC101RE1AN", 0x00010111, NUMICRO_BANKS_NUC100(128*1024)},
592         {"NUC101RD3AN", 0x00010112, NUMICRO_BANKS_NUC100(64*1024)},
593         {"NUC101RD2AN", 0x00010113, NUMICRO_BANKS_NUC100(64*1024)},
594         {"NUC101RD1AN", 0x00010114, NUMICRO_BANKS_NUC100(64*1024)},
595         {"NUC101RC3AN", 0x00010115, NUMICRO_BANKS_NUC100(32*1024)},
596         {"NUC101RC2AN", 0x00010116, NUMICRO_BANKS_NUC100(32*1024)},
597         {"NUC101RC1AN", 0x00010117, NUMICRO_BANKS_NUC100(32*1024)},
598         {"NUC101VE3AN", 0x00010118, NUMICRO_BANKS_NUC100(128*1024)},
599         {"NUC101VE2AN", 0x00010119, NUMICRO_BANKS_NUC100(128*1024)},
600         {"NUC101VE1AN", 0x00010120, NUMICRO_BANKS_NUC100(128*1024)},
601         {"NUC101VD3AN", 0x00010121, NUMICRO_BANKS_NUC100(64*1024)},
602         {"NUC101VD2AN", 0x00010122, NUMICRO_BANKS_NUC100(64*1024)},
603         {"NUC101VD1AN", 0x00010123, NUMICRO_BANKS_NUC100(64*1024)},
604         {"NUC101VC3AN", 0x00010124, NUMICRO_BANKS_NUC100(32*1024)},
605         {"NUC101VC2AN", 0x00010125, NUMICRO_BANKS_NUC100(32*1024)},
606         {"NUC101VC1AN", 0x00010126, NUMICRO_BANKS_NUC100(32*1024)},
607
608     /* NUC120 Version A */
609         {"NUC120LE3AN", 0x00012000, NUMICRO_BANKS_NUC100(128*1024)},
610         {"NUC120LE2AN", 0x00012001, NUMICRO_BANKS_NUC100(128*1024)},
611         {"NUC120LE1AN", 0x00012002, NUMICRO_BANKS_NUC100(128*1024)},
612         {"NUC120LD3AN", 0x00012003, NUMICRO_BANKS_NUC100(64*1024)},
613         {"NUC120LD2AN", 0x00012004, NUMICRO_BANKS_NUC100(64*1024)},
614         {"NUC120LD1AN", 0x00012005, NUMICRO_BANKS_NUC100(64*1024)},
615         {"NUC120LC3AN", 0x00012006, NUMICRO_BANKS_NUC100(32*1024)},
616         {"NUC120LC2AN", 0x00012007, NUMICRO_BANKS_NUC100(32*1024)},
617         {"NUC120LC1AN", 0x00012008, NUMICRO_BANKS_NUC100(32*1024)},
618         {"NUC120RE3AN", 0x00012009, NUMICRO_BANKS_NUC100(128*1024)},
619         {"NUC120RE2AN", 0x00012010, NUMICRO_BANKS_NUC100(128*1024)},
620         {"NUC120RE1AN", 0x00012011, NUMICRO_BANKS_NUC100(128*1024)},
621         {"NUC120RD3AN", 0x00012012, NUMICRO_BANKS_NUC100(64*1024)},
622         {"NUC120RD2AN", 0x00012013, NUMICRO_BANKS_NUC100(64*1024)},
623         {"NUC120RD1AN", 0x00012014, NUMICRO_BANKS_NUC100(64*1024)},
624         {"NUC120RC3AN", 0x00012015, NUMICRO_BANKS_NUC100(32*1024)},
625         {"NUC120RC2AN", 0x00012016, NUMICRO_BANKS_NUC100(32*1024)},
626         {"NUC120RC1AN", 0x00012017, NUMICRO_BANKS_NUC100(32*1024)},
627         {"NUC120VE3AN", 0x00012018, NUMICRO_BANKS_NUC100(128*1024)},
628         {"NUC120VE2AN", 0x00012019, NUMICRO_BANKS_NUC100(128*1024)},
629         {"NUC120VE1AN", 0x00012020, NUMICRO_BANKS_NUC100(128*1024)},
630         {"NUC120VD3AN", 0x00012021, NUMICRO_BANKS_NUC100(64*1024)},
631         {"NUC120VD2AN", 0x00012022, NUMICRO_BANKS_NUC100(64*1024)},
632         {"NUC120VD1AN", 0x00012023, NUMICRO_BANKS_NUC100(64*1024)},
633         {"NUC120VC3AN", 0x00012024, NUMICRO_BANKS_NUC100(32*1024)},
634         {"NUC120VC2AN", 0x00012025, NUMICRO_BANKS_NUC100(32*1024)},
635         {"NUC120VC1AN", 0x00012026, NUMICRO_BANKS_NUC100(32*1024)},
636
637     /* NUC120 Version A */
638         {"NUC130LE3AN", 0x00013000, NUMICRO_BANKS_NUC100(128*1024)},
639         {"NUC130LE2AN", 0x00013001, NUMICRO_BANKS_NUC100(128*1024)},
640         {"NUC130LE1AN", 0x00013002, NUMICRO_BANKS_NUC100(128*1024)},
641         {"NUC130LD3AN", 0x00013003, NUMICRO_BANKS_NUC100(64*1024)},
642         {"NUC130LD2AN", 0x00013004, NUMICRO_BANKS_NUC100(64*1024)},
643         {"NUC130LD1AN", 0x00013005, NUMICRO_BANKS_NUC100(64*1024)},
644         {"NUC130LC3AN", 0x00013006, NUMICRO_BANKS_NUC100(32*1024)},
645         {"NUC130LC2AN", 0x00013007, NUMICRO_BANKS_NUC100(32*1024)},
646         {"NUC130LC1AN", 0x00013008, NUMICRO_BANKS_NUC100(32*1024)},
647         {"NUC130RE3AN", 0x00013009, NUMICRO_BANKS_NUC100(128*1024)},
648         {"NUC130RE2AN", 0x00013010, NUMICRO_BANKS_NUC100(128*1024)},
649         {"NUC130RE1AN", 0x00013011, NUMICRO_BANKS_NUC100(128*1024)},
650         {"NUC130RD3AN", 0x00013012, NUMICRO_BANKS_NUC100(64*1024)},
651         {"NUC130RD2AN", 0x00013013, NUMICRO_BANKS_NUC100(64*1024)},
652         {"NUC130RD1AN", 0x00013014, NUMICRO_BANKS_NUC100(64*1024)},
653         {"NUC130RC3AN", 0x00013015, NUMICRO_BANKS_NUC100(32*1024)},
654         {"NUC130RC2AN", 0x00013016, NUMICRO_BANKS_NUC100(32*1024)},
655         {"NUC130RC1AN", 0x00013017, NUMICRO_BANKS_NUC100(32*1024)},
656         {"NUC130VE3AN", 0x00013018, NUMICRO_BANKS_NUC100(128*1024)},
657         {"NUC130VE2AN", 0x00013019, NUMICRO_BANKS_NUC100(128*1024)},
658         {"NUC130VE1AN", 0x00013020, NUMICRO_BANKS_NUC100(128*1024)},
659         {"NUC130VD3AN", 0x00013021, NUMICRO_BANKS_NUC100(64*1024)},
660         {"NUC130VD2AN", 0x00013022, NUMICRO_BANKS_NUC100(64*1024)},
661         {"NUC130VD1AN", 0x00013023, NUMICRO_BANKS_NUC100(64*1024)},
662         {"NUC130VC3AN", 0x00013024, NUMICRO_BANKS_NUC100(32*1024)},
663         {"NUC130VC2AN", 0x00013025, NUMICRO_BANKS_NUC100(32*1024)},
664         {"NUC130VC1AN", 0x00013026, NUMICRO_BANKS_NUC100(32*1024)},
665
666     /* NUC140 Version A */
667         {"NUC140LE3AN", 0x00014000, NUMICRO_BANKS_NUC100(128*1024)},
668         {"NUC140LE2AN", 0x00014001, NUMICRO_BANKS_NUC100(128*1024)},
669         {"NUC140LE1AN", 0x00014002, NUMICRO_BANKS_NUC100(128*1024)},
670         {"NUC140LD3AN", 0x00014003, NUMICRO_BANKS_NUC100(64*1024)},
671         {"NUC140LD2AN", 0x00014004, NUMICRO_BANKS_NUC100(64*1024)},
672         {"NUC140LD1AN", 0x00014005, NUMICRO_BANKS_NUC100(64*1024)},
673         {"NUC140LC3AN", 0x00014006, NUMICRO_BANKS_NUC100(32*1024)},
674         {"NUC140LC2AN", 0x00014007, NUMICRO_BANKS_NUC100(32*1024)},
675         {"NUC140LC1AN", 0x00014008, NUMICRO_BANKS_NUC100(32*1024)},
676         {"NUC140RE3AN", 0x00014009, NUMICRO_BANKS_NUC100(128*1024)},
677         {"NUC140RE2AN", 0x00014010, NUMICRO_BANKS_NUC100(128*1024)},
678         {"NUC140RE1AN", 0x00014011, NUMICRO_BANKS_NUC100(128*1024)},
679         {"NUC140RD3AN", 0x00014012, NUMICRO_BANKS_NUC100(64*1024)},
680         {"NUC140RD2AN", 0x00014013, NUMICRO_BANKS_NUC100(64*1024)},
681         {"NUC140RD1AN", 0x00014014, NUMICRO_BANKS_NUC100(64*1024)},
682         {"NUC140RC3AN", 0x00014015, NUMICRO_BANKS_NUC100(32*1024)},
683         {"NUC140RC2AN", 0x00014016, NUMICRO_BANKS_NUC100(32*1024)},
684         {"NUC140RC1AN", 0x00014017, NUMICRO_BANKS_NUC100(32*1024)},
685         {"NUC140VE3AN", 0x00014018, NUMICRO_BANKS_NUC100(128*1024)},
686         {"NUC140VE2AN", 0x00014019, NUMICRO_BANKS_NUC100(128*1024)},
687         {"NUC140VE1AN", 0x00014020, NUMICRO_BANKS_NUC100(128*1024)},
688         {"NUC140VD3AN", 0x00014021, NUMICRO_BANKS_NUC100(64*1024)},
689         {"NUC140VD2AN", 0x00014022, NUMICRO_BANKS_NUC100(64*1024)},
690         {"NUC140VD1AN", 0x00014023, NUMICRO_BANKS_NUC100(64*1024)},
691         {"NUC140VC3AN", 0x00014024, NUMICRO_BANKS_NUC100(32*1024)},
692         {"NUC140VC2AN", 0x00014025, NUMICRO_BANKS_NUC100(32*1024)},
693         {"NUC140VC1AN", 0x00014026, NUMICRO_BANKS_NUC100(32*1024)},
694
695
696         /* M052 */
697         {"M052LAN"  , 0x00005200, NUMICRO_BANKS_M051(8*1024)},
698         {"M052PAN"  , 0x00005201, NUMICRO_BANKS_M051(8*1024)},
699         {"M052YAN"  , 0x00005202, NUMICRO_BANKS_M051(8*1024)},
700         {"M052ZAN"  , 0x00005203, NUMICRO_BANKS_M051(8*1024)},
701
702     /* M054 */
703         {"M054LAN"  , 0x00005400, NUMICRO_BANKS_M051(16*1024)},
704         {"M054PAN"  , 0x00005401, NUMICRO_BANKS_M051(16*1024)},
705         {"M054YAN"  , 0x00005402, NUMICRO_BANKS_M051(16*1024)},
706         {"M054ZAN"  , 0x00005403, NUMICRO_BANKS_M051(16*1024)},
707
708     /* M058 */
709         {"M058LAN"  , 0x00005800, NUMICRO_BANKS_M051(32*1024)},
710         {"M058PAN"  , 0x00005801, NUMICRO_BANKS_M051(32*1024)},
711         {"M058YAN"  , 0x00005802, NUMICRO_BANKS_M051(32*1024)},
712         {"M058ZAN"  , 0x00005803, NUMICRO_BANKS_M051(32*1024)},
713
714     /* M0516 */
715         {"M0516LAN" , 0x00005A00, NUMICRO_BANKS_M051(64*1024)},
716         {"M0516PAN" , 0x00005A01, NUMICRO_BANKS_M051(64*1024)},
717         {"M0516YAN" , 0x00005A02, NUMICRO_BANKS_M051(64*1024)},
718         {"M0516ZAN" , 0x00005A03, NUMICRO_BANKS_M051(64*1024)},
719         {"M051LBN"  , 0x10005100, NUMICRO_BANKS_M051(4*1024)},
720         {"M051PBN"  , 0x10005101, NUMICRO_BANKS_M051(4*1024)},
721         {"M051YBN"  , 0x10005102, NUMICRO_BANKS_M051(4*1024)},
722         {"M051ZBN"  , 0x10005103, NUMICRO_BANKS_M051(4*1024)},
723         {"M052LBN"  , 0x10005200, NUMICRO_BANKS_M051(8*1024)},
724         {"M052PBN"  , 0x10005201, NUMICRO_BANKS_M051(8*1024)},
725         {"M052YBN"  , 0x10005202, NUMICRO_BANKS_M051(8*1024)},
726         {"M052ZBN"  , 0x10005203, NUMICRO_BANKS_M051(8*1024)},
727         {"M054LBN"  , 0x10005400, NUMICRO_BANKS_M051(16*1024)},
728         {"M054PBN"  , 0x10005401, NUMICRO_BANKS_M051(16*1024)},
729         {"M054YBN"  , 0x10005402, NUMICRO_BANKS_M051(16*1024)},
730         {"M054ZBN"  , 0x10005403, NUMICRO_BANKS_M051(16*1024)},
731         {"M058LBN"  , 0x10005800, NUMICRO_BANKS_M051(32*1024)},
732         {"M058PBN"  , 0x10005801, NUMICRO_BANKS_M051(32*1024)},
733         {"M058YBN"  , 0x10005802, NUMICRO_BANKS_M051(32*1024)},
734         {"M058ZBN"  , 0x10005803, NUMICRO_BANKS_M051(32*1024)},
735         {"M0516LBN" , 0x10005A00, NUMICRO_BANKS_M051(64*1024)},
736         {"M0516PBN" , 0x10005A01, NUMICRO_BANKS_M051(64*1024)},
737         {"M0516YBN" , 0x10005A02, NUMICRO_BANKS_M051(64*1024)},
738         {"M0516ZBN" , 0x10005A03, NUMICRO_BANKS_M051(64*1024)},
739         {"M052LDN"  , 0x20005200, NUMICRO_BANKS_M051(8*1024)},
740         {"M054LDN"  , 0x20005400, NUMICRO_BANKS_M051(16*1024)},
741         {"M058LDN"  , 0x20005800, NUMICRO_BANKS_M051(32*1024)},
742         {"M0516LDN" , 0x20005A00, NUMICRO_BANKS_M051(64*1024)},
743         {"M052ZDN"  , 0x20005203, NUMICRO_BANKS_M051(8*1024)},
744         {"M054ZDN"  , 0x20005403, NUMICRO_BANKS_M051(16*1024)},
745         {"M058ZDN"  , 0x20005803, NUMICRO_BANKS_M051(32*1024)},
746         {"M0516ZDN" , 0x20005A03, NUMICRO_BANKS_M051(64*1024)},
747         {"M052TDN"  , 0x20005204, NUMICRO_BANKS_M051(8*1024)},
748         {"M054TDN"  , 0x20005404, NUMICRO_BANKS_M051(16*1024)},
749         {"M058TDN"  , 0x20005804, NUMICRO_BANKS_M051(32*1024)},
750         {"M0516TDN" , 0x20005A04, NUMICRO_BANKS_M051(64*1024)},
751         {"M052XDN"  , 0x20005205, NUMICRO_BANKS_M051(8*1024)},
752         {"M054XDN"  , 0x20005405, NUMICRO_BANKS_M051(16*1024)},
753         {"M058XDN"  , 0x20005805, NUMICRO_BANKS_M051(32*1024)},
754         {"M0516XDN" , 0x20005A05, NUMICRO_BANKS_M051(64*1024)},
755         {"M052LDE"  , 0x30005200, NUMICRO_BANKS_M051(8*1024)},
756         {"M054LDE"  , 0x30005400, NUMICRO_BANKS_M051(16*1024)},
757         {"M058LDE"  , 0x30005800, NUMICRO_BANKS_M051(32*1024)},
758         {"M0516LDE" , 0x30005A00, NUMICRO_BANKS_M051(64*1024)},
759         {"M052ZDE"  , 0x30005203, NUMICRO_BANKS_M051(8*1024)},
760         {"M054ZDE"  , 0x30005403, NUMICRO_BANKS_M051(16*1024)},
761         {"M058ZDE"  , 0x30005803, NUMICRO_BANKS_M051(32*1024)},
762         {"M0516ZDE" , 0x30005A03, NUMICRO_BANKS_M051(64*1024)},
763         {"M052TDE"  , 0x30005204, NUMICRO_BANKS_M051(8*1024)},
764         {"M054TDE"  , 0x30005404, NUMICRO_BANKS_M051(16*1024)},
765         {"M058TDE"  , 0x30005804, NUMICRO_BANKS_M051(32*1024)},
766         {"M0516TDE" , 0x30005A04, NUMICRO_BANKS_M051(64*1024)},
767         {"M052XDE"  , 0x30005205, NUMICRO_BANKS_M051(8*1024)},
768         {"M054XDE"  , 0x30005405, NUMICRO_BANKS_M051(16*1024)},
769         {"M058XDE"  , 0x30005805, NUMICRO_BANKS_M051(32*1024)},
770         {"M0516XDE" , 0x30005A05, NUMICRO_BANKS_M051(64*1024)},
771
772         /* Mini51 */
773         {"MINI51LAN",  0x00205100, NUMICRO_BANKS_MINI51(4*1024)},
774         {"MINI51QAN",  0x00205101, NUMICRO_BANKS_MINI51(4*1024)},
775         {"MINI51   ",  0x00205102, NUMICRO_BANKS_MINI51(4*1024)},
776         {"MINI51ZAN",  0x00205103, NUMICRO_BANKS_MINI51(4*1024)},
777         {"MINI51TAN",  0x00205104, NUMICRO_BANKS_MINI51(4*1024)},
778         {"MINI52LAN",  0x00205200, NUMICRO_BANKS_MINI51(8*1024)},
779         {"MINI52QAN",  0x00205201, NUMICRO_BANKS_MINI51(8*1024)},
780         {"MINI52   ",  0x00205202, NUMICRO_BANKS_MINI51(8*1024)},
781         {"MINI52ZAN",  0x00205203, NUMICRO_BANKS_MINI51(8*1024)},
782         {"MINI52TAN",  0x00205204, NUMICRO_BANKS_MINI51(8*1024)},
783         {"MINI54LAN",  0x00205400, NUMICRO_BANKS_MINI51(16*1024)},
784         {"MINI54QAN",  0x00205401, NUMICRO_BANKS_MINI51(16*1024)},
785         {"MINI54   ",  0x00205402, NUMICRO_BANKS_MINI51(16*1024)},
786         {"MINI54ZAN",  0x00205403, NUMICRO_BANKS_MINI51(16*1024)},
787         {"MINI54TAN",  0x00205404, NUMICRO_BANKS_MINI51(16*1024)},
788         {"MINI51LBN",  0x10205100, NUMICRO_BANKS_MINI51(4*1024)},
789         {"MINI51QBN",  0x10205101, NUMICRO_BANKS_MINI51(4*1024)},
790         {"MINI51   ",  0x10205102, NUMICRO_BANKS_MINI51(4*1024)},
791         {"MINI51ZBN",  0x10205103, NUMICRO_BANKS_MINI51(4*1024)},
792         {"MINI51TBN",  0x10205104, NUMICRO_BANKS_MINI51(4*1024)},
793         {"MINI52LBN",  0x10205200, NUMICRO_BANKS_MINI51(8*1024)},
794         {"MINI52QBN",  0x10205201, NUMICRO_BANKS_MINI51(8*1024)},
795         {"MINI52   ",  0x10205202, NUMICRO_BANKS_MINI51(8*1024)},
796         {"MINI52ZBN",  0x10205203, NUMICRO_BANKS_MINI51(8*1024)},
797         {"MINI52TBN",  0x10205204, NUMICRO_BANKS_MINI51(8*1024)},
798         {"MINI54LBN",  0x10205400, NUMICRO_BANKS_MINI51(16*1024)},
799         {"MINI54QBN",  0x10205401, NUMICRO_BANKS_MINI51(16*1024)},
800         {"MINI54   ",  0x10205402, NUMICRO_BANKS_MINI51(16*1024)},
801         {"MINI54ZBN" , 0x10205403, NUMICRO_BANKS_MINI51(16*1024)},
802         {"MINI54TBN" , 0x10205404, NUMICRO_BANKS_MINI51(16*1024)},
803         {"MINI51LDE" , 0x20205100, NUMICRO_BANKS_MINI51(4*1024)},
804         {"MINI51QDE" , 0x20205101, NUMICRO_BANKS_MINI51(4*1024)},
805         {"MINI51   " , 0x20205102, NUMICRO_BANKS_MINI51(4*1024)},
806         {"MINI51ZDE" , 0x20205103, NUMICRO_BANKS_MINI51(4*1024)},
807         {"MINI51TDE" , 0x20205104, NUMICRO_BANKS_MINI51(4*1024)},
808         {"MINI51FDE" , 0x20205105, NUMICRO_BANKS_MINI51(4*1024)},
809         {"MINI52LDE" , 0x20205200, NUMICRO_BANKS_MINI51(8*1024)},
810         {"MINI52QDE" , 0x20205201, NUMICRO_BANKS_MINI51(8*1024)},
811         {"MINI52   " , 0x20205202, NUMICRO_BANKS_MINI51(8*1024)},
812         {"MINI52ZDE" , 0x20205203, NUMICRO_BANKS_MINI51(8*1024)},
813         {"MINI52TDE" , 0x20205204, NUMICRO_BANKS_MINI51(8*1024)},
814         {"MINI52FDE" , 0x20205205, NUMICRO_BANKS_MINI51(8*1024)},
815         {"MINI54LDE" , 0x20205400, NUMICRO_BANKS_MINI51(16*1024)},
816         {"MINI54QDE" , 0x20205401, NUMICRO_BANKS_MINI51(16*1024)},
817         {"MINI54   " , 0x20205402, NUMICRO_BANKS_MINI51(16*1024)},
818         {"MINI54ZDE" , 0x20205403, NUMICRO_BANKS_MINI51(16*1024)},
819         {"MINI54TDE" , 0x20205404, NUMICRO_BANKS_MINI51(16*1024)},
820         {"MINI54FDE" , 0x20205405, NUMICRO_BANKS_MINI51(16*1024)},
821         {"MINI55LDE" , 0x20205500, NUMICRO_BANKS_MINI51(16*1024)},
822
823         /* NANO100 */
824         {"NANO100VF3AN" , 0x00110000, NUMICRO_BANKS_NANO(256*1024)},
825         {"NANO100VF2AN" , 0x00110001, NUMICRO_BANKS_NANO(256*1024)},
826         {"NANO100RF3AN" , 0x00110002, NUMICRO_BANKS_NANO(256*1024)},
827         {"NANO100RF2AN" , 0x00110003, NUMICRO_BANKS_NANO(256*1024)},
828         {"NANO100LF3AN" , 0x00110004, NUMICRO_BANKS_NANO(256*1024)},
829         {"NANO100LF2AN" , 0x00110005, NUMICRO_BANKS_NANO(256*1024)},
830         {"NANO100VE3AN" , 0x00110006, NUMICRO_BANKS_NANO(128*1024)},
831         {"NANO100VE2AN" , 0x00110007, NUMICRO_BANKS_NANO(128*1024)},
832         {"NANO100RE3AN" , 0x00110008, NUMICRO_BANKS_NANO(128*1024)},
833         {"NANO100RE2AN" , 0x00110009, NUMICRO_BANKS_NANO(128*1024)},
834         {"NANO100LE3AN" , 0x00110010, NUMICRO_BANKS_NANO(128*1024)},
835         {"NANO100LE2AN" , 0x00110011, NUMICRO_BANKS_NANO(128*1024)},
836         {"NANO100VD3AN" , 0x00110012, NUMICRO_BANKS_NANO(64*1024)},
837         {"NANO100VD2AN" , 0x00110013, NUMICRO_BANKS_NANO(64*1024)},
838         {"NANO100VD1AN" , 0x00110014, NUMICRO_BANKS_NANO(64*1024)},
839         {"NANO100RD3AN" , 0x00110015, NUMICRO_BANKS_NANO(64*1024)},
840         {"NANO100RD2AN" , 0x00110016, NUMICRO_BANKS_NANO(64*1024)},
841         {"NANO100RD1AN" , 0x00110017, NUMICRO_BANKS_NANO(64*1024)},
842         {"NANO100LD3AN" , 0x00110018, NUMICRO_BANKS_NANO(64*1024)},
843         {"NANO100LD2AN" , 0x00110019, NUMICRO_BANKS_NANO(64*1024)},
844         {"NANO100LD1AN" , 0x00110020, NUMICRO_BANKS_NANO(64*1024)},
845         {"NANO100VC2AN" , 0x00110021, NUMICRO_BANKS_NANO(32*1024)},
846         {"NANO100VC1AN" , 0x00110022, NUMICRO_BANKS_NANO(32*1024)},
847         {"NANO100RC2AN" , 0x00110023, NUMICRO_BANKS_NANO(32*1024)},
848         {"NANO100RC1AN" , 0x00110024, NUMICRO_BANKS_NANO(32*1024)},
849         {"NANO100LC2AN" , 0x00110025, NUMICRO_BANKS_NANO(32*1024)},
850         {"NANO100LC1AN" , 0x00110026, NUMICRO_BANKS_NANO(32*1024)},
851         {"NANO100VB1AN" , 0x00110027, NUMICRO_BANKS_NANO(16*1024)},
852         {"NANO100VB0AN" , 0x00110028, NUMICRO_BANKS_NANO(16*1024)},
853         {"NANO100RB1AN" , 0x00110029, NUMICRO_BANKS_NANO(16*1024)},
854
855         {"NANO110VF3AN" , 0x00111000, NUMICRO_BANKS_NANO(256*1024)},
856         {"NANO110VF2AN" , 0x00111001, NUMICRO_BANKS_NANO(256*1024)},
857         {"NANO110RF3AN" , 0x00111002, NUMICRO_BANKS_NANO(256*1024)},
858         {"NANO110RF2AN" , 0x00111003, NUMICRO_BANKS_NANO(256*1024)},
859         {"NANO110VE3AN" , 0x00111006, NUMICRO_BANKS_NANO(128*1024)},
860         {"NANO110VE2AN" , 0x00111007, NUMICRO_BANKS_NANO(128*1024)},
861         {"NANO110RE3AN" , 0x00111008, NUMICRO_BANKS_NANO(128*1024)},
862         {"NANO110RE2AN" , 0x00111009, NUMICRO_BANKS_NANO(128*1024)},
863         {"NANO110VD3AN" , 0x00111012, NUMICRO_BANKS_NANO(64*1024)},
864         {"NANO110VD2AN" , 0x00111013, NUMICRO_BANKS_NANO(64*1024)},
865         {"NANO110VD1AN" , 0x00111014, NUMICRO_BANKS_NANO(64*1024)},
866         {"NANO110RD3AN" , 0x00111015, NUMICRO_BANKS_NANO(64*1024)},
867         {"NANO110RD2AN" , 0x00111016, NUMICRO_BANKS_NANO(64*1024)},
868         {"NANO110RD1AN" , 0x00111017, NUMICRO_BANKS_NANO(64*1024)},
869         {"NANO110VC2AN" , 0x00111021, NUMICRO_BANKS_NANO(32*1024)},
870         {"NANO110VC1AN" , 0x00111022, NUMICRO_BANKS_NANO(32*1024)},
871         {"NANO110SC2AN" , 0x00111023, NUMICRO_BANKS_NANO(32*1024)},
872         {"NANO110SC1AN" , 0x00111024, NUMICRO_BANKS_NANO(32*1024)},
873         {"NANO120VF3AN" , 0x00112000, NUMICRO_BANKS_NANO(256*1024)},
874         {"NANO120VF2AN" , 0x00112001, NUMICRO_BANKS_NANO(256*1024)},
875         {"NANO120RF3AN" , 0x00112002, NUMICRO_BANKS_NANO(256*1024)},
876         {"NANO120RF2AN" , 0x00112003, NUMICRO_BANKS_NANO(256*1024)},
877         {"NANO120LF3AN" , 0x00112004, NUMICRO_BANKS_NANO(256*1024)},
878         {"NANO120LF2AN" , 0x00112005, NUMICRO_BANKS_NANO(256*1024)},
879         {"NANO120VE3AN" , 0x00112006, NUMICRO_BANKS_NANO(128*1024)},
880         {"NANO120VE2AN" , 0x00112007, NUMICRO_BANKS_NANO(128*1024)},
881         {"NANO120RE3AN" , 0x00112008, NUMICRO_BANKS_NANO(128*1024)},
882         {"NANO120RE2AN" , 0x00112009, NUMICRO_BANKS_NANO(128*1024)},
883         {"NANO120LE3AN" , 0x00112010, NUMICRO_BANKS_NANO(128*1024)},
884         {"NANO120LE2AN" , 0x00112011, NUMICRO_BANKS_NANO(128*1024)},
885         {"NANO120VD3AN" , 0x00112012, NUMICRO_BANKS_NANO(64*1024)},
886         {"NANO120VD2AN" , 0x00112013, NUMICRO_BANKS_NANO(64*1024)},
887         {"NANO120VD1AN" , 0x00112014, NUMICRO_BANKS_NANO(64*1024)},
888         {"NANO120SD3AN" , 0x00112015, NUMICRO_BANKS_NANO(64*1024)},
889         {"NANO120SD2AN" , 0x00112016, NUMICRO_BANKS_NANO(64*1024)},
890         {"NANO120SD1AN" , 0x00112017, NUMICRO_BANKS_NANO(64*1024)},
891         {"NANO120LD3AN" , 0x00112018, NUMICRO_BANKS_NANO(64*1024)},
892         {"NANO120LD2AN" , 0x00112019, NUMICRO_BANKS_NANO(64*1024)},
893         {"NANO120LD1AN" , 0x00112020, NUMICRO_BANKS_NANO(64*1024)},
894         {"NANO120VC2AN" , 0x00112021, NUMICRO_BANKS_NANO(32*1024)},
895         {"NANO120VC1AN" , 0x00112022, NUMICRO_BANKS_NANO(32*1024)},
896         {"NANO120SC2AN" , 0x00112023, NUMICRO_BANKS_NANO(32*1024)},
897         {"NANO120SC1AN" , 0x00112024, NUMICRO_BANKS_NANO(32*1024)},
898         {"NANO120LC2AN" , 0x00112025, NUMICRO_BANKS_NANO(32*1024)},
899         {"NANO120LC1AN" , 0x00112026, NUMICRO_BANKS_NANO(32*1024)},
900         {"NANO130VF3AN" , 0x00113000, NUMICRO_BANKS_NANO(256*1024)},
901         {"NANO130VF2AN" , 0x00113001, NUMICRO_BANKS_NANO(256*1024)},
902         {"NANO130SF3AN" , 0x00113002, NUMICRO_BANKS_NANO(256*1024)},
903         {"NANO130SF2AN" , 0x00113003, NUMICRO_BANKS_NANO(256*1024)},
904         {"NANO130VE3AN" , 0x00113006, NUMICRO_BANKS_NANO(128*1024)},
905         {"NANO130VE2AN" , 0x00113007, NUMICRO_BANKS_NANO(128*1024)},
906         {"NANO130SE3AN" , 0x00113008, NUMICRO_BANKS_NANO(128*1024)},
907         {"NANO130SE2AN" , 0x00113009, NUMICRO_BANKS_NANO(128*1024)},
908         {"NANO130VD3AN" , 0x00113012, NUMICRO_BANKS_NANO(64*1024)},
909         {"NANO130VD2AN" , 0x00113013, NUMICRO_BANKS_NANO(64*1024)},
910         {"NANO130VD1AN" , 0x00113014, NUMICRO_BANKS_NANO(64*1024)},
911         {"NANO130SD3AN" , 0x00113015, NUMICRO_BANKS_NANO(64*1024)},
912         {"NANO130SD2AN" , 0x00113016, NUMICRO_BANKS_NANO(64*1024)},
913         {"NANO130SD1AN" , 0x00113017, NUMICRO_BANKS_NANO(64*1024)},
914         {"NANO130VC2AN" , 0x00113021, NUMICRO_BANKS_NANO(32*1024)},
915         {"NANO130VC1AN" , 0x00113022, NUMICRO_BANKS_NANO(32*1024)},
916         {"NANO130SC2AN" , 0x00113023, NUMICRO_BANKS_NANO(32*1024)},
917         {"NANO130SC1AN" , 0x00113024, NUMICRO_BANKS_NANO(32*1024)},
918         {"NANO100KE3BN" , 0x00110030, NUMICRO_BANKS_NANO(128*1024)},
919         {"NANO100KE2BN" , 0x00110031, NUMICRO_BANKS_NANO(128*1024)},
920         {"NANO100VE3BN" , 0x00110032, NUMICRO_BANKS_NANO(128*1024)},
921         {"NANO100VE2BN" , 0x00110033, NUMICRO_BANKS_NANO(128*1024)},
922         {"NANO100SE3BN" , 0x00110034, NUMICRO_BANKS_NANO(128*1024)},
923         {"NANO100SE2BN" , 0x00110035, NUMICRO_BANKS_NANO(128*1024)},
924         {"NANO100LE3BN" , 0x00110036, NUMICRO_BANKS_NANO(128*1024)},
925         {"NANO100LE2BN" , 0x00110037, NUMICRO_BANKS_NANO(128*1024)},
926         {"NANO100KD3BN" , 0x00110038, NUMICRO_BANKS_NANO(64*1024)},
927         {"NANO100KD2BN" , 0x00110039, NUMICRO_BANKS_NANO(64*1024)},
928         {"NANO100VD3BN" , 0x0011003A, NUMICRO_BANKS_NANO(64*1024)},
929         {"NANO100VD2BN" , 0x0011003B, NUMICRO_BANKS_NANO(64*1024)},
930         {"NANO100SD3BN" , 0x0011003C, NUMICRO_BANKS_NANO(64*1024)},
931         {"NANO100SD2BN" , 0x0011003D, NUMICRO_BANKS_NANO(64*1024)},
932         {"NANO100LD3BN" , 0x0011003E, NUMICRO_BANKS_NANO(64*1024)},
933         {"NANO100LD2BN" , 0x0011003F, NUMICRO_BANKS_NANO(64*1024)},
934         {"NANO100KC2BN" , 0x00110040, NUMICRO_BANKS_NANO(32*1024)},
935         {"NANO100VC2BN" , 0x00110041, NUMICRO_BANKS_NANO(32*1024)},
936         {"NANO100SC2BN" , 0x00110042, NUMICRO_BANKS_NANO(32*1024)},
937         {"NANO100LC2BN" , 0x00110043, NUMICRO_BANKS_NANO(32*1024)},
938         {"NANO110KE3BN" , 0x00111030, NUMICRO_BANKS_NANO(128*1024)},
939         {"NANO110KE2BN" , 0x00111031, NUMICRO_BANKS_NANO(128*1024)},
940         {"NANO110VE3BN" , 0x00111032, NUMICRO_BANKS_NANO(128*1024)},
941         {"NANO110VE2BN" , 0x00111033, NUMICRO_BANKS_NANO(128*1024)},
942         {"NANO110SE3BN" , 0x00111034, NUMICRO_BANKS_NANO(128*1024)},
943         {"NANO110SE2BN" , 0x00111035, NUMICRO_BANKS_NANO(128*1024)},
944         {"NANO110KD3BN" , 0x00111038, NUMICRO_BANKS_NANO(64*1024)},
945         {"NANO110KD2BN" , 0x00111039, NUMICRO_BANKS_NANO(64*1024)},
946         {"NANO110VD3BN" , 0x0011103A, NUMICRO_BANKS_NANO(64*1024)},
947         {"NANO110VD2BN" , 0x0011103B, NUMICRO_BANKS_NANO(64*1024)},
948         {"NANO110SD3BN" , 0x0011103C, NUMICRO_BANKS_NANO(64*1024)},
949         {"NANO110SD2BN" , 0x0011103D, NUMICRO_BANKS_NANO(64*1024)},
950         {"NANO110KC2BN" , 0x00111040, NUMICRO_BANKS_NANO(32*1024)},
951         {"NANO110VC2BN" , 0x00111041, NUMICRO_BANKS_NANO(32*1024)},
952         {"NANO110SC2BN" , 0x00111042, NUMICRO_BANKS_NANO(32*1024)},
953         {"NANO120KE3BN" , 0x00112030, NUMICRO_BANKS_NANO(128*1024)},
954         {"NANO120KE2BN" , 0x00112031, NUMICRO_BANKS_NANO(128*1024)},
955         {"NANO120VE3BN" , 0x00112032, NUMICRO_BANKS_NANO(128*1024)},
956         {"NANO120VE2BN" , 0x00112033, NUMICRO_BANKS_NANO(128*1024)},
957         {"NANO120SE3BN" , 0x00112034, NUMICRO_BANKS_NANO(128*1024)},
958         {"NANO120SE2BN" , 0x00112035, NUMICRO_BANKS_NANO(128*1024)},
959         {"NANO120LE3BN" , 0x00112036, NUMICRO_BANKS_NANO(128*1024)},
960         {"NANO120LE2BN" , 0x00112037, NUMICRO_BANKS_NANO(128*1024)},
961         {"NANO120KD3BN" , 0x00112038, NUMICRO_BANKS_NANO(64*1024)},
962         {"NANO120KD2BN" , 0x00112039, NUMICRO_BANKS_NANO(64*1024)},
963         {"NANO120VD3BN" , 0x0011203A, NUMICRO_BANKS_NANO(64*1024)},
964         {"NANO120VD2BN" , 0x0011203B, NUMICRO_BANKS_NANO(64*1024)},
965         {"NANO120SD3BN" , 0x0011203C, NUMICRO_BANKS_NANO(64*1024)},
966         {"NANO120SD2BN" , 0x0011203D, NUMICRO_BANKS_NANO(64*1024)},
967         {"NANO120LD3BN" , 0x0011203E, NUMICRO_BANKS_NANO(64*1024)},
968         {"NANO120LD2BN" , 0x0011203F, NUMICRO_BANKS_NANO(64*1024)},
969         {"NANO120KC2BN" , 0x00112040, NUMICRO_BANKS_NANO(32*1024)},
970         {"NANO120VC2BN" , 0x00112041, NUMICRO_BANKS_NANO(32*1024)},
971         {"NANO120SC2BN" , 0x00112042, NUMICRO_BANKS_NANO(32*1024)},
972         {"NANO120LC2BN" , 0x00112043, NUMICRO_BANKS_NANO(32*1024)},
973         {"NANO130KE3BN" , 0x00113030, NUMICRO_BANKS_NANO(123*1024)},
974         {"NANO130KE2BN" , 0x00113031, NUMICRO_BANKS_NANO(123*1024)},
975         {"NANO130VE3BN" , 0x00113032, NUMICRO_BANKS_NANO(123*1024)},
976         {"NANO130VE2BN" , 0x00113033, NUMICRO_BANKS_NANO(123*1024)},
977         {"NANO130SE3BN" , 0x00113034, NUMICRO_BANKS_NANO(123*1024)},
978         {"NANO130SE2BN" , 0x00113035, NUMICRO_BANKS_NANO(123*1024)},
979         {"NANO130KD3BN" , 0x00113038, NUMICRO_BANKS_NANO(64*1024)},
980         {"NANO130KD2BN" , 0x00113039, NUMICRO_BANKS_NANO(64*1024)},
981         {"NANO130VD3BN" , 0x0011303A, NUMICRO_BANKS_NANO(64*1024)},
982         {"NANO130VD2BN" , 0x0011303B, NUMICRO_BANKS_NANO(64*1024)},
983         {"NANO130SD3BN" , 0x0011303C, NUMICRO_BANKS_NANO(64*1024)},
984         {"NANO130SD2BN" , 0x0011303D, NUMICRO_BANKS_NANO(64*1024)},
985         {"NANO130KC2BN" , 0x00113040, NUMICRO_BANKS_NANO(32*1024)},
986         {"NANO130VC2BN" , 0x00113041, NUMICRO_BANKS_NANO(32*1024)},
987         {"NANO130SC2BN" , 0x00113042, NUMICRO_BANKS_NANO(32*1024)},
988         {"N512DC4"      , 0x00100000, NUMICRO_BANKS_NANO(64*1024)},
989         {"N512LC4"      , 0x00100001, NUMICRO_BANKS_NANO(64*1024)},
990         {"N512MC4"      , 0x00100003, NUMICRO_BANKS_NANO(64*1024)},
991
992         {"N512SC4"      , 0x00100005, NUMICRO_BANKS_NANO(64*1024)},
993         {"N512VD4"      , 0x00100008, NUMICRO_BANKS_NANO(128*1024)},
994         {"N512MD4"      , 0x00100009, NUMICRO_BANKS_NANO(128*1024)},
995         {"N512SD4"      , 0x00100010, NUMICRO_BANKS_NANO(128*1024)},
996         {"NANO110RC2BN" , 0x00111043, NUMICRO_BANKS_NANO(32*1024)},
997         {"NANO110RD3BN" , 0x00111045, NUMICRO_BANKS_NANO(64*1024)},
998         {"TX110VE3BN"   , 0x00111036, NUMICRO_BANKS_NANO(128*1024)},
999
1000         /* NANO102/NANO112 */
1001         {"NANO112LB0AN" , 0x00111201, NUMICRO_BANKS_NANO(16*1024)},
1002         {"NANO112LB1AN" , 0x00111202, NUMICRO_BANKS_NANO(16*1024)},
1003         {"NANO112LC1AN" , 0x00111203, NUMICRO_BANKS_NANO(32*1024)},
1004         {"NANO112LC2AN" , 0x00111204, NUMICRO_BANKS_NANO(32*1024)},
1005         {"NANO112SB0AN" , 0x00111205, NUMICRO_BANKS_NANO(16*1024)},
1006         {"NANO112SB1AN" , 0x00111206, NUMICRO_BANKS_NANO(16*1024)},
1007         {"NANO112SC1AN" , 0x00111207, NUMICRO_BANKS_NANO(32*1024)},
1008         {"NANO112SC2AN" , 0x00111208, NUMICRO_BANKS_NANO(32*1024)},
1009         {"NANO112RB0AN" , 0x00111209, NUMICRO_BANKS_NANO(16*1024)},
1010         {"NANO112RB1AN" , 0x00111210, NUMICRO_BANKS_NANO(16*1024)},
1011         {"NANO112RC1AN" , 0x00111211, NUMICRO_BANKS_NANO(32*1024)},
1012         {"NANO112RC2AN" , 0x00111212, NUMICRO_BANKS_NANO(32*1024)},
1013         {"NANO112VB0AN" , 0x00111213, NUMICRO_BANKS_NANO(16*1024)},
1014         {"NANO112VB1AN" , 0x00111214, NUMICRO_BANKS_NANO(16*1024)},
1015         {"NANO112VC1AN" , 0x00111215, NUMICRO_BANKS_NANO(32*1024)},
1016         {"NANO112VC2AN" , 0x00111216, NUMICRO_BANKS_NANO(32*1024)},
1017         {"NANO102ZB0AN" , 0x00110201, NUMICRO_BANKS_NANO(16*1024)},
1018         {"NANO102ZB1AN" , 0x00110202, NUMICRO_BANKS_NANO(16*1024)},
1019         {"NANO102ZC1AN" , 0x00110203, NUMICRO_BANKS_NANO(32*1024)},
1020         {"NANO102ZC2AN" , 0x00110204, NUMICRO_BANKS_NANO(32*1024)},
1021         {"NANO102LB0AN" , 0x00110205, NUMICRO_BANKS_NANO(16*1024)},
1022         {"NANO102LB1AN" , 0x00110206, NUMICRO_BANKS_NANO(16*1024)},
1023         {"NANO102LC1AN" , 0x00110207, NUMICRO_BANKS_NANO(32*1024)},
1024         {"NANO102LC2AN" , 0x00110208, NUMICRO_BANKS_NANO(32*1024)},
1025         {"NANO102SB0AN" , 0x00110209, NUMICRO_BANKS_NANO(16*1024)},
1026         {"NANO102SB1AN" , 0x00110210, NUMICRO_BANKS_NANO(16*1024)},
1027         {"NANO102SC1AN" , 0x00110211, NUMICRO_BANKS_NANO(32*1024)},
1028         {"NANO102SC2AN" , 0x00110212, NUMICRO_BANKS_NANO(32*1024)},
1029
1030         /* NUC103/NUC105/NUC123 */
1031         {"NUC123SC2AN" , 0x00012305, NUMICRO_BANKS_NUC100(36*1024)},
1032         {"NUC123SD4AN" , 0x00012315, NUMICRO_BANKS_NUC100(68*1024)},
1033         {"NUC123LC2AN" , 0x00012325, NUMICRO_BANKS_NUC100(36*1024)},
1034         {"NUC103LC2AN" , 0x00010325, NUMICRO_BANKS_NUC100(36*1024)},
1035         {"NUC105LC2AN" , 0x00010525, NUMICRO_BANKS_NUC100(36*1024)},
1036         {"NUC123LD4AN" , 0x00012335, NUMICRO_BANKS_NUC100(68*1024)},
1037         {"NUC103LD4AN" , 0x00010335, NUMICRO_BANKS_NUC100(68*1024)},
1038         {"NUC105LD4AN" , 0x00010535, NUMICRO_BANKS_NUC100(68*1024)},
1039         {"NUC123ZC2AN" , 0x00012345, NUMICRO_BANKS_NUC100(36*1024)},
1040         {"NUC103ZC2AN" , 0x00010345, NUMICRO_BANKS_NUC100(36*1024)},
1041         {"NUC105ZC2AN" , 0x00010545, NUMICRO_BANKS_NUC100(36*1024)},
1042         {"NUC123ZD4AN" , 0x00012355, NUMICRO_BANKS_NUC100(68*1024)},
1043         {"NUC103ZD4AN" , 0x00010355, NUMICRO_BANKS_NUC100(68*1024)},
1044         {"NUC105ZD4AN" , 0x00010555, NUMICRO_BANKS_NUC100(68*1024)},
1045
1046         /* NUC200 */
1047         {"NUC200LC2AN" , 0x00020007, NUMICRO_BANKS_NUC100(32*1024)},
1048         {"NUC200LD2AN" , 0x00020004, NUMICRO_BANKS_NUC100(64*1024)},
1049         {"NUC200LE3AN" , 0x00020000, NUMICRO_BANKS_NUC100(128*1024)},
1050         {"NUC200SC1AN" , 0x00020035, NUMICRO_BANKS_NUC100(32*1024)},
1051         {"NUC200SD2AN" , 0x00020031, NUMICRO_BANKS_NUC100(64*1024)},
1052         {"NUC200SE3AN" , 0x00020027, NUMICRO_BANKS_NUC100(128*1024)},
1053         {"NUC200VE3AN" , 0x00020018, NUMICRO_BANKS_NUC100(128*1024)},
1054         {"NUC220LC2AN" , 0x00022007, NUMICRO_BANKS_NUC100(32*1024)},
1055         {"NUC220LD2AN" , 0x00022004, NUMICRO_BANKS_NUC100(64*1024)},
1056         {"NUC220LE3AN" , 0x00022000, NUMICRO_BANKS_NUC100(128*1024)},
1057         {"NUC220SC1AN" , 0x00022035, NUMICRO_BANKS_NUC100(32*1024)},
1058         {"NUC220SD2AN" , 0x00022031, NUMICRO_BANKS_NUC100(64*1024)},
1059         {"NUC220SE3AN" , 0x00022027, NUMICRO_BANKS_NUC100(128*1024)},
1060         {"NUC220VE3AN" , 0x00022018, NUMICRO_BANKS_NUC100(128*1024)},
1061         {"NUC230LC2AN" , 0x00023007, NUMICRO_BANKS_NUC100(32*1024)},
1062         {"NUC230LD2AN" , 0x00023004, NUMICRO_BANKS_NUC100(64*1024)},
1063         {"NUC230LE3AN" , 0x00023000, NUMICRO_BANKS_NUC100(128*1024)},
1064         {"NUC230SC1AN" , 0x00023035, NUMICRO_BANKS_NUC100(32*1024)},
1065         {"NUC230SD2AN" , 0x00023031, NUMICRO_BANKS_NUC100(64*1024)},
1066         {"NUC230SE3AN" , 0x00023027, NUMICRO_BANKS_NUC100(128*1024)},
1067         {"NUC230VE3AN" , 0x00023018, NUMICRO_BANKS_NUC100(128*1024)},
1068         {"NUC240LC2AN" , 0x00024007, NUMICRO_BANKS_NUC100(32*1024)},
1069         {"NUC240LD2AN" , 0x00024004, NUMICRO_BANKS_NUC100(64*1024)},
1070         {"NUC240LE3AN" , 0x00024000, NUMICRO_BANKS_NUC100(128*1024)},
1071         {"NUC240SC1AN" , 0x00024035, NUMICRO_BANKS_NUC100(32*1024)},
1072         {"NUC240SD2AN" , 0x00024031, NUMICRO_BANKS_NUC100(64*1024)},
1073         {"NUC240SE3AN" , 0x00024027, NUMICRO_BANKS_NUC100(128*1024)},
1074         {"NUC240VE3AN" , 0x00024018, NUMICRO_BANKS_NUC100(128*1024)},
1075
1076         /* NUC200 NUC2XXAE */
1077         {"NUC230RC1AE" , 0x40013017, NUMICRO_BANKS_NUC100(32*1024)},
1078         {"NUC200LC2AE" , 0x10020007, NUMICRO_BANKS_NUC100(32*1024)},
1079         {"NUC200LD2AE" , 0x10020004, NUMICRO_BANKS_NUC100(64*1024)},
1080         {"NUC200LE3AE" , 0x10020000, NUMICRO_BANKS_NUC100(128*1024)},
1081         {"NUC200SC2AE" , 0x10020034, NUMICRO_BANKS_NUC100(32*1024)},
1082         {"NUC200SD2AE" , 0x10020031, NUMICRO_BANKS_NUC100(64*1024)},
1083         {"NUC200SE3AE" , 0x10020027, NUMICRO_BANKS_NUC100(128*1024)},
1084         {"NUC200VE3AE" , 0x10020018, NUMICRO_BANKS_NUC100(128*1024)},
1085         {"NUC230LC2AE" , 0x10023007, NUMICRO_BANKS_NUC100(32*1024)},
1086         {"NUC230LD2AE" , 0x10023004, NUMICRO_BANKS_NUC100(64*1024)},
1087         {"NUC230LE3AE" , 0x10023000, NUMICRO_BANKS_NUC100(128*1024)},
1088         {"NUC230SC2AE" , 0x10023034, NUMICRO_BANKS_NUC100(32*1024)},
1089         {"NUC230SD2AE" , 0x10023031, NUMICRO_BANKS_NUC100(64*1024)},
1090         {"NUC230SE3AE" , 0x10023027, NUMICRO_BANKS_NUC100(128*1024)},
1091         {"NUC230VE3AE" , 0x10023018, NUMICRO_BANKS_NUC100(128*1024)},
1092         {"NUC240LC2AE" , 0x10024007, NUMICRO_BANKS_NUC100(32*1024)},
1093         {"NUC240LD2AE" , 0x10024004, NUMICRO_BANKS_NUC100(64*1024)},
1094         {"NUC240LE3AE" , 0x10024000, NUMICRO_BANKS_NUC100(128*1024)},
1095         {"NUC240SC2AE" , 0x10024034, NUMICRO_BANKS_NUC100(32*1024)},
1096         {"NUC240SD2AE" , 0x10024031, NUMICRO_BANKS_NUC100(64*1024)},
1097         {"NUC240SE3AE" , 0x10024027, NUMICRO_BANKS_NUC100(128*1024)},
1098         {"NUC240VE3AE" , 0x10024018, NUMICRO_BANKS_NUC100(128*1024)},
1099
1100         /* NUC100 Version D */
1101         {"NUC100LC1DN" , 0x30010008, NUMICRO_BANKS_NUC100(32*1024)},
1102         {"NUC100LD1DN" , 0x30010005, NUMICRO_BANKS_NUC100(64*1024)},
1103         {"NUC100LD2DN" , 0x30010004, NUMICRO_BANKS_NUC100(64*1024)},
1104         {"NUC100RC1DN" , 0x30010017, NUMICRO_BANKS_NUC100(32*1024)},
1105         {"NUC100RD1DN" , 0x30010014, NUMICRO_BANKS_NUC100(64*1024)},
1106         {"NUC100RD2DN" , 0x30010013, NUMICRO_BANKS_NUC100(64*1024)},
1107         {"NUC100LD3DN" , 0x30010003, NUMICRO_BANKS_NUC100(64*1024)},
1108         {"NUC100LE3DN" , 0x30010000, NUMICRO_BANKS_NUC100(128*1024)},
1109         {"NUC100RD3DN" , 0x30010012, NUMICRO_BANKS_NUC100(64*1024)},
1110         {"NUC100RE3DN" , 0x30010009, NUMICRO_BANKS_NUC100(128*1024)},
1111         {"NUC100VD2DN" , 0x30010022, NUMICRO_BANKS_NUC100(64*1024)},
1112         {"NUC100VD3DN" , 0x30010021, NUMICRO_BANKS_NUC100(64*1024)},
1113         {"NUC100VE3DN" , 0x30010018, NUMICRO_BANKS_NUC100(128*1024)},
1114         {"NUC120LC1DN" , 0x30012008, NUMICRO_BANKS_NUC100(32*1024)},
1115         {"NUC120LD1DN" , 0x30012005, NUMICRO_BANKS_NUC100(64*1024)},
1116         {"NUC120LD2DN" , 0x30012004, NUMICRO_BANKS_NUC100(64*1024)},
1117         {"NUC120RC1DN" , 0x30012017, NUMICRO_BANKS_NUC100(32*1024)},
1118         {"NUC120RD1DN" , 0x30012014, NUMICRO_BANKS_NUC100(64*1024)},
1119         {"NUC120RD2DN" , 0x30012013, NUMICRO_BANKS_NUC100(64*1024)},
1120         {"NUC120LD3DN" , 0x30012003, NUMICRO_BANKS_NUC100(64*1024)},
1121         {"NUC120LE3DN" , 0x30012000, NUMICRO_BANKS_NUC100(128*1024)},
1122         {"NUC120RD3DN" , 0x30012012, NUMICRO_BANKS_NUC100(64*1024)},
1123         {"NUC120RE3DN" , 0x30012009, NUMICRO_BANKS_NUC100(128*1024)},
1124         {"NUC120VD2DN" , 0x30012022, NUMICRO_BANKS_NUC100(64*1024)},
1125         {"NUC120VD3DN" , 0x30012021, NUMICRO_BANKS_NUC100(64*1024)},
1126         {"NUC120VE3DN" , 0x30012018, NUMICRO_BANKS_NUC100(128*1024)},
1127         {"NUC130RC1DN" , 0x30013017, NUMICRO_BANKS_NUC100(32*1024)},
1128
1129         {"UNKNOWN"     , 0x00000000, NUMICRO_BANKS_NUC100(128*1024)},
1130 };
1131
1132 /* Private bank information for NuMicro. */
1133 struct  numicro_flash_bank {
1134         struct working_area *write_algorithm;
1135         bool probed;
1136         const struct numicro_cpu_type *cpu;
1137 };
1138
1139 /* Private methods */
1140 static int numicro_reg_unlock(struct target *target)
1141 {
1142         uint32_t is_protected;
1143         int retval = ERROR_OK;
1144
1145         /* Check to see if NUC is register unlocked or not */
1146         retval = target_read_u32(target, NUMICRO_SYS_WRPROT, &is_protected);
1147         if (retval != ERROR_OK)
1148                 return retval;
1149
1150         LOG_DEBUG("protected = 0x%08" PRIx32 "", is_protected);
1151         if (is_protected == 0) {        /* means protected - so unlock it */
1152                 /* unlock flash registers */
1153                 retval = target_write_u32(target, NUMICRO_SYS_WRPROT, REG_KEY1);
1154                 if (retval != ERROR_OK)
1155                         return retval;
1156                 retval = target_write_u32(target, NUMICRO_SYS_WRPROT, REG_KEY2);
1157                 if (retval != ERROR_OK)
1158                         return retval;
1159                 retval = target_write_u32(target, NUMICRO_SYS_WRPROT, REG_KEY3);
1160                 if (retval != ERROR_OK)
1161                         return retval;
1162         }
1163         /* Check that unlock worked */
1164         retval = target_read_u32(target, NUMICRO_SYS_WRPROT, &is_protected);
1165         if (retval != ERROR_OK)
1166                 return retval;
1167
1168         if (is_protected == 1) {        /* means unprotected */
1169                 LOG_DEBUG("protection removed");
1170         } else {
1171                 LOG_DEBUG("still protected!!");
1172         }
1173
1174         return ERROR_OK;
1175 }
1176
1177 static int numicro_init_isp(struct target *target)
1178 {
1179         uint32_t reg_stat;
1180         int retval = ERROR_OK;
1181
1182         if (target->state != TARGET_HALTED) {
1183                 LOG_ERROR("Target not halted");
1184                 return ERROR_TARGET_NOT_HALTED;
1185         }
1186
1187         retval = numicro_reg_unlock(target);
1188         if (retval != ERROR_OK)
1189                 return retval;
1190
1191         /* Enable ISP/SRAM/TICK Clock */
1192         retval = target_read_u32(target, NUMICRO_SYSCLK_AHBCLK, &reg_stat);
1193         if (retval != ERROR_OK)
1194                 return retval;
1195
1196         reg_stat |= AHBCLK_ISP_EN | AHBCLK_SRAM_EN | AHBCLK_TICK_EN;
1197         retval = target_write_u32(target, NUMICRO_SYSCLK_AHBCLK, reg_stat);
1198         if (retval != ERROR_OK)
1199                 return retval;
1200
1201         /* Enable ISP */
1202         retval = target_read_u32(target, NUMICRO_FLASH_ISPCON, &reg_stat);
1203         if (retval != ERROR_OK)
1204                 return retval;
1205
1206         reg_stat |= ISPCON_ISPFF | ISPCON_LDUEN | ISPCON_APUEN | ISPCON_CFGUEN | ISPCON_ISPEN;
1207         retval = target_write_u32(target, NUMICRO_FLASH_ISPCON, reg_stat);
1208         if (retval != ERROR_OK)
1209                 return retval;
1210
1211         /* Write one to undocumented flash control register */
1212         retval = target_write_u32(target, NUMICRO_FLASH_CHEAT, 1);
1213         if (retval != ERROR_OK)
1214                 return retval;
1215
1216         return ERROR_OK;
1217 }
1218
1219 static uint32_t numicro_fmc_cmd(struct target *target, uint32_t cmd, uint32_t addr, uint32_t wdata, uint32_t *rdata)
1220 {
1221         uint32_t timeout, status;
1222         int retval = ERROR_OK;
1223
1224         retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD, cmd);
1225         if (retval != ERROR_OK)
1226                 return retval;
1227
1228         retval = target_write_u32(target, NUMICRO_FLASH_ISPDAT, wdata);
1229         if (retval != ERROR_OK)
1230                 return retval;
1231
1232         retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, addr);
1233         if (retval != ERROR_OK)
1234                 return retval;
1235
1236         retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO);
1237         if (retval != ERROR_OK)
1238                 return retval;
1239
1240         /* Wait for busy to clear - check the GO flag */
1241         timeout = 100;
1242         for (;;) {
1243                 retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status);
1244                 if (retval != ERROR_OK)
1245                         return retval;
1246                 LOG_DEBUG("status: 0x%" PRIx32 "", status);
1247                 if ((status & (ISPTRG_ISPGO)) == 0)
1248                         break;
1249                 if (timeout-- <= 0) {
1250                         LOG_DEBUG("timed out waiting for flash");
1251                         return ERROR_FAIL;
1252                 }
1253                 busy_sleep(1);  /* can use busy sleep for short times. */
1254         }
1255
1256         retval = target_read_u32(target, NUMICRO_FLASH_ISPDAT, rdata);
1257         if (retval != ERROR_OK)
1258                 return retval;
1259
1260         return ERROR_OK;
1261 }
1262
1263
1264 /* NuMicro Program-LongWord Microcodes */
1265 static const uint8_t numicro_flash_write_code[] = {
1266                                 /* Params:
1267                                  * r0 - workarea buffer / result
1268                                  * r1 - target address
1269                                  * r2 - wordcount
1270                                  * Clobbered:
1271                                  * r4 - tmp
1272                                  * r5 - tmp
1273                                  * r6 - tmp
1274                                  * r7 - tmp
1275                                  */
1276
1277                                 /* .L1: */
1278                                                 /* for(register uint32_t i=0;i<wcount;i++){ */
1279         0x04, 0x1C,                             /* mov    r4, r0          */
1280         0x00, 0x23,                             /* mov    r3, #0          */
1281                                 /* .L2: */
1282         0x0D, 0x1A,                             /* sub    r5, r1, r0      */
1283         0x67, 0x19,                             /* add    r7, r4, r7      */
1284         0x93, 0x42,                             /* cmp    r3, r2                  */
1285         0x0C, 0xD0,                             /* beq    .L7             */
1286                                 /* .L4: */
1287                                                 /* NUMICRO_FLASH_ISPADR = faddr; */
1288         0x08, 0x4E,                             /* ldr  r6, .L8           */
1289         0x37, 0x60,                             /* str  r7, [r6]          */
1290                                                 /* NUMICRO_FLASH_ISPDAT = *pLW; */
1291         0x80, 0xCC,                             /* ldmia        r4!, {r7}     */
1292         0x08, 0x4D,                             /* ldr  r5, .L8+4         */
1293         0x2F, 0x60,                             /* str  r7, [r5]                  */
1294                                                         /* faddr += 4; */
1295                                                         /* pLW++; */
1296                                                         /*  Trigger write action  */
1297                                                 /* NUMICRO_FLASH_ISPTRG = ISPTRG_ISPGO; */
1298         0x08, 0x4D,                             /* ldr  r5, .L8+8         */
1299         0x01, 0x26,                             /* mov  r6, #1            */
1300         0x2E, 0x60,                             /* str  r6, [r5]          */
1301                                 /* .L3: */
1302                                                 /* while((NUMICRO_FLASH_ISPTRG & ISPTRG_ISPGO) == ISPTRG_ISPGO){}; */
1303         0x2F, 0x68,                             /* ldr  r7, [r5]          */
1304         0xFF, 0x07,                             /* lsl  r7, r7, #31       */
1305         0xFC, 0xD4,                             /* bmi  .L3               */
1306
1307         0x01, 0x33,                             /* add  r3, r3, #1        */
1308         0xEE, 0xE7,                             /* b    .L2               */
1309                                 /* .L7: */
1310                                                 /* return (NUMICRO_FLASH_ISPCON & ISPCON_ISPFF); */
1311         0x05, 0x4B,                             /* ldr  r3, .L8+12        */
1312         0x18, 0x68,                             /* ldr  r0, [r3]          */
1313         0x40, 0x21,                             /* mov  r1, #64           */
1314         0x08, 0x40,                             /* and  r0, r1            */
1315                                 /* .L9: */
1316         0x00, 0xBE,                             /* bkpt    #0             */
1317                                 /* .L8: */
1318         0x04, 0xC0, 0x00, 0x50,/* .word 1342226436    */
1319         0x08, 0xC0, 0x00, 0x50,/* .word 1342226440    */
1320         0x10, 0xC0, 0x00, 0x50,/* .word 1342226448    */
1321         0x00, 0xC0, 0x00, 0x50 /* .word 1342226432    */
1322 };
1323 /* Program LongWord Block Write */
1324 static int numicro_writeblock(struct flash_bank *bank, const uint8_t *buffer,
1325                 uint32_t offset, uint32_t count)
1326 {
1327         struct target *target = bank->target;
1328         uint32_t buffer_size = 1024;            /* Default minimum value */
1329         struct working_area *write_algorithm;
1330         struct working_area *source;
1331         uint32_t address = bank->base + offset;
1332         struct reg_param reg_params[3];
1333         struct armv7m_algorithm armv7m_info;
1334         int retval = ERROR_OK;
1335
1336         /* Params:
1337          * r0 - workarea buffer / result
1338          * r1 - target address
1339          * r2 - wordcount
1340          * Clobbered:
1341          * r4 - tmp
1342          * r5 - tmp
1343          * r6 - tmp
1344          * r7 - tmp
1345          */
1346
1347         /* Increase buffer_size if needed */
1348         if (buffer_size < (target->working_area_size/2))
1349                 buffer_size = (target->working_area_size/2);
1350
1351         /* check code alignment */
1352         if (offset & 0x1) {
1353                 LOG_WARNING("offset 0x%" PRIx32 " breaks required 2-byte alignment", offset);
1354                 return ERROR_FLASH_DST_BREAKS_ALIGNMENT;
1355         }
1356
1357         /* allocate working area with flash programming code */
1358         if (target_alloc_working_area(target, sizeof(numicro_flash_write_code),
1359                         &write_algorithm) != ERROR_OK) {
1360                 LOG_WARNING("no working area available, can't do block memory writes");
1361                 return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1362         }
1363
1364         retval = target_write_buffer(target, write_algorithm->address,
1365                 sizeof(numicro_flash_write_code), numicro_flash_write_code);
1366         if (retval != ERROR_OK)
1367                 return retval;
1368
1369         /* memory buffer */
1370         while (target_alloc_working_area(target, buffer_size, &source) != ERROR_OK) {
1371                 buffer_size /= 4;
1372                 if (buffer_size <= 256) {
1373                         /* free working area, write algorithm already allocated */
1374                         target_free_working_area(target, write_algorithm);
1375
1376                         LOG_WARNING("No large enough working area available, can't do block memory writes");
1377                         return ERROR_TARGET_RESOURCE_NOT_AVAILABLE;
1378                 }
1379         }
1380
1381         armv7m_info.common_magic = ARMV7M_COMMON_MAGIC;
1382         armv7m_info.core_mode = ARM_MODE_THREAD;
1383
1384         init_reg_param(&reg_params[0], "r0", 32, PARAM_IN_OUT); /* *pLW (*buffer) */
1385         init_reg_param(&reg_params[1], "r1", 32, PARAM_OUT);    /* faddr */
1386         init_reg_param(&reg_params[2], "r2", 32, PARAM_OUT);    /* number of words to program */
1387
1388         /* write code buffer and use Flash programming code within NuMicro     */
1389         /* Set breakpoint to 0 with time-out of 1000 ms                        */
1390         while (count > 0) {
1391                 uint32_t thisrun_count = (count > (buffer_size / 4)) ? (buffer_size / 4) : count;
1392
1393                 retval = target_write_buffer(target, source->address, thisrun_count * 4, buffer);
1394                 if (retval != ERROR_OK)
1395                         break;
1396
1397                 buf_set_u32(reg_params[0].value, 0, 32, source->address);
1398                 buf_set_u32(reg_params[1].value, 0, 32, address);
1399                 buf_set_u32(reg_params[2].value, 0, 32, thisrun_count);
1400
1401                 retval = target_run_algorithm(target, 0, NULL, 3, reg_params,
1402                                 write_algorithm->address, 0, 100000, &armv7m_info);
1403                 if (retval != ERROR_OK) {
1404                         LOG_ERROR("Error executing NuMicro Flash programming algorithm");
1405                         retval = ERROR_FLASH_OPERATION_FAILED;
1406                         break;
1407                 }
1408
1409                 buffer  += thisrun_count * 4;
1410                 address += thisrun_count * 4;
1411                 count   -= thisrun_count;
1412         }
1413
1414         target_free_working_area(target, source);
1415         target_free_working_area(target, write_algorithm);
1416
1417         destroy_reg_param(&reg_params[0]);
1418         destroy_reg_param(&reg_params[1]);
1419         destroy_reg_param(&reg_params[2]);
1420
1421         return retval;
1422 }
1423
1424 /* Flash Lock checking - examines the lock bit. */
1425 static int numicro_protect_check(struct flash_bank *bank)
1426 {
1427         struct target *target = bank->target;
1428         uint32_t set, config[2];
1429         int retval = ERROR_OK;
1430
1431         if (target->state != TARGET_HALTED) {
1432                 LOG_ERROR("Target not halted");
1433                 return ERROR_TARGET_NOT_HALTED;
1434         }
1435
1436         LOG_INFO("Nuvoton NuMicro: Flash Lock Check...");
1437
1438         retval = numicro_init_isp(target);
1439         if (retval != ERROR_OK)
1440                 return retval;
1441
1442         /* Read CONFIG0,CONFIG1 */
1443         numicro_fmc_cmd(target, ISPCMD_READ, NUMICRO_CONFIG0, 0 , &config[0]);
1444         numicro_fmc_cmd(target, ISPCMD_READ, NUMICRO_CONFIG1, 0 , &config[1]);
1445
1446         LOG_DEBUG("CONFIG0: 0x%" PRIx32 ",CONFIG1: 0x%" PRIx32 "", config[0], config[1]);
1447
1448         if ((config[0] & (1<<7)) == 0)
1449                 LOG_INFO("CBS=0: Boot From LPROM");
1450         else
1451                 LOG_INFO("CBS=1: Boot From APROM");
1452
1453         if ((config[0] & CONFIG0_LOCK_MASK) == 0) {
1454
1455                 LOG_INFO("Flash is secure locked!");
1456                 LOG_INFO("TO UNLOCK FLASH,EXECUTE chip_erase COMMAND!!");
1457                 set = 1;
1458         } else {
1459                 LOG_INFO("Flash is not locked!");
1460             set = 0;
1461         }
1462
1463         for (unsigned int i = 0; i < bank->num_sectors; i++)
1464                 bank->sectors[i].is_protected = set;
1465
1466         return ERROR_OK;
1467 }
1468
1469
1470 static int numicro_erase(struct flash_bank *bank, unsigned int first,
1471                 unsigned int last)
1472 {
1473         struct target *target = bank->target;
1474         uint32_t timeout, status;
1475         int retval = ERROR_OK;
1476
1477         if (target->state != TARGET_HALTED) {
1478                 LOG_ERROR("Target not halted");
1479                 return ERROR_TARGET_NOT_HALTED;
1480         }
1481
1482         LOG_INFO("Nuvoton NuMicro: Sector Erase ... (%u to %u)", first, last);
1483
1484         retval = numicro_init_isp(target);
1485         if (retval != ERROR_OK)
1486                 return retval;
1487
1488         retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD, ISPCMD_ERASE);
1489         if (retval != ERROR_OK)
1490                 return retval;
1491
1492         for (unsigned int i = first; i <= last; i++) {
1493                 LOG_DEBUG("erasing sector %u at address " TARGET_ADDR_FMT, i,
1494                                 bank->base + bank->sectors[i].offset);
1495                 retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, bank->base + bank->sectors[i].offset);
1496                 if (retval != ERROR_OK)
1497                         return retval;
1498                 retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO); /* This is the only bit available */
1499                 if (retval != ERROR_OK)
1500                         return retval;
1501
1502                 /* wait for busy to clear - check the GO flag */
1503                 timeout = 100;
1504                 for (;;) {
1505                         retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status);
1506                         if (retval != ERROR_OK)
1507                                 return retval;
1508                         LOG_DEBUG("status: 0x%" PRIx32 "", status);
1509                         if (status == 0)
1510                                 break;
1511                         if (timeout-- <= 0) {
1512                                 LOG_DEBUG("timed out waiting for flash");
1513                                 return ERROR_FAIL;
1514                         }
1515                         busy_sleep(1);  /* can use busy sleep for short times. */
1516                 }
1517
1518                 /* check for failure */
1519                 retval = target_read_u32(target, NUMICRO_FLASH_ISPCON, &status);
1520                 if (retval != ERROR_OK)
1521                         return retval;
1522                 if ((status & ISPCON_ISPFF) != 0) {
1523                         LOG_DEBUG("failure: 0x%" PRIx32 "", status);
1524                         /* if bit is set, then must write to it to clear it. */
1525                         retval = target_write_u32(target, NUMICRO_FLASH_ISPCON, (status | ISPCON_ISPFF));
1526                         if (retval != ERROR_OK)
1527                                 return retval;
1528                 }
1529         }
1530
1531         /* done, */
1532         LOG_DEBUG("Erase done.");
1533
1534         return ERROR_OK;
1535 }
1536
1537 /* The write routine stub. */
1538 static int numicro_write(struct flash_bank *bank, const uint8_t *buffer,
1539                 uint32_t offset, uint32_t count)
1540 {
1541         struct target *target = bank->target;
1542         uint32_t timeout, status;
1543         int retval = ERROR_OK;
1544
1545         if (target->state != TARGET_HALTED) {
1546                 LOG_ERROR("Target not halted");
1547                 return ERROR_TARGET_NOT_HALTED;
1548         }
1549
1550         LOG_INFO("Nuvoton NuMicro: Flash Write ...");
1551
1552         retval = numicro_init_isp(target);
1553         if (retval != ERROR_OK)
1554                 return retval;
1555
1556         retval = target_write_u32(target, NUMICRO_FLASH_ISPCMD, ISPCMD_WRITE);
1557         if (retval != ERROR_OK)
1558                 return retval;
1559
1560         assert(offset % 4 == 0);
1561         assert(count % 4 == 0);
1562
1563         uint32_t words_remaining = count / 4;
1564
1565         /* try using a block write */
1566         retval = numicro_writeblock(bank, buffer, offset, words_remaining);
1567
1568         if (retval == ERROR_TARGET_RESOURCE_NOT_AVAILABLE) {
1569                 /* if block write failed (no sufficient working area),
1570                  * we use normal (slow) single word accesses */
1571                 LOG_WARNING("couldn't use block writes, falling back to single "
1572                         "memory accesses");
1573
1574                 /* program command */
1575                 for (uint32_t i = 0; i < count; i += 4) {
1576
1577                         LOG_DEBUG("write longword @ %08" PRIX32, offset + i);
1578
1579                         retval = target_write_u32(target, NUMICRO_FLASH_ISPADR, bank->base + offset + i);
1580                         if (retval != ERROR_OK)
1581                                 return retval;
1582                         retval = target_write_memory(target, NUMICRO_FLASH_ISPDAT, 4, 1, buffer + i);
1583                         if (retval != ERROR_OK)
1584                                 return retval;
1585                         retval = target_write_u32(target, NUMICRO_FLASH_ISPTRG, ISPTRG_ISPGO);
1586                         if (retval != ERROR_OK)
1587                                 return retval;
1588
1589                         /* wait for busy to clear - check the GO flag */
1590                         timeout = 100;
1591                         for (;;) {
1592                                 retval = target_read_u32(target, NUMICRO_FLASH_ISPTRG, &status);
1593                                 if (retval != ERROR_OK)
1594                                         return retval;
1595                                 LOG_DEBUG("status: 0x%" PRIx32 "", status);
1596                                 if (status == 0)
1597                                         break;
1598                                 if (timeout-- <= 0) {
1599                                         LOG_DEBUG("timed out waiting for flash");
1600                                         return ERROR_FAIL;
1601                                 }
1602                                 busy_sleep(1);  /* can use busy sleep for short times. */
1603                         }
1604
1605                 }
1606         }
1607
1608         /* check for failure */
1609         retval = target_read_u32(target, NUMICRO_FLASH_ISPCON, &status);
1610         if (retval != ERROR_OK)
1611                 return retval;
1612         if ((status & ISPCON_ISPFF) != 0) {
1613                 LOG_DEBUG("failure: 0x%" PRIx32 "", status);
1614                 /* if bit is set, then must write to it to clear it. */
1615                 retval = target_write_u32(target, NUMICRO_FLASH_ISPCON, (status | ISPCON_ISPFF));
1616                 if (retval != ERROR_OK)
1617                         return retval;
1618         } else {
1619                 LOG_DEBUG("Write OK");
1620         }
1621
1622         /* done. */
1623         LOG_DEBUG("Write done.");
1624
1625         return ERROR_OK;
1626 }
1627
1628 static int numicro_get_cpu_type(struct target *target, const struct numicro_cpu_type **cpu)
1629 {
1630         uint32_t part_id;
1631         int retval = ERROR_OK;
1632
1633         /* Read NuMicro PartID */
1634         retval = target_read_u32(target, NUMICRO_SYS_BASE, &part_id);
1635         if (retval != ERROR_OK) {
1636                 LOG_WARNING("NuMicro flash driver: Failed to Get PartID\n");
1637                 return ERROR_FLASH_OPERATION_FAILED;
1638         }
1639
1640         LOG_INFO("Device ID: 0x%08" PRIx32 "", part_id);
1641         /* search part numbers */
1642         for (size_t i = 0; i < ARRAY_SIZE(numicro_parts); i++) {
1643                 if (part_id == numicro_parts[i].partid) {
1644                         *cpu = &numicro_parts[i];
1645                         LOG_INFO("Device Name: %s", (*cpu)->partname);
1646                         return ERROR_OK;
1647                 }
1648         }
1649
1650         return ERROR_FAIL;
1651 }
1652
1653 static int numicro_get_flash_size(struct flash_bank *bank, const struct numicro_cpu_type *cpu, uint32_t *flash_size)
1654 {
1655         for (size_t i = 0; i < cpu->n_banks; i++) {
1656                 if (bank->base == cpu->bank[i].base) {
1657                         *flash_size = cpu->bank[i].size;
1658                         LOG_INFO("bank base = " TARGET_ADDR_FMT ", size = 0x%08"
1659                                         PRIx32, bank->base, *flash_size);
1660                         return ERROR_OK;
1661                 }
1662         }
1663         return ERROR_FLASH_OPERATION_FAILED;
1664 }
1665
1666 static int numicro_probe(struct flash_bank *bank)
1667 {
1668         uint32_t flash_size, offset = 0;
1669         int num_pages;
1670         const struct numicro_cpu_type *cpu;
1671         struct target *target = bank->target;
1672         int retval = ERROR_OK;
1673
1674         retval = numicro_get_cpu_type(target, &cpu);
1675         if (retval != ERROR_OK) {
1676                 LOG_WARNING("NuMicro flash driver: Failed to detect a known part\n");
1677                 return ERROR_FLASH_OPERATION_FAILED;
1678         }
1679
1680         retval = numicro_get_flash_size(bank, cpu, &flash_size);
1681         if (retval != ERROR_OK) {
1682                 LOG_WARNING("NuMicro flash driver: Failed to detect flash size\n");
1683                 return ERROR_FLASH_OPERATION_FAILED;
1684         }
1685
1686         num_pages = flash_size / NUMICRO_PAGESIZE;
1687
1688         bank->num_sectors = num_pages;
1689         bank->sectors = malloc(sizeof(struct flash_sector) * num_pages);
1690         bank->size = flash_size;
1691
1692         for (int i = 0; i < num_pages; i++) {
1693                 bank->sectors[i].offset = offset;
1694                 bank->sectors[i].size = NUMICRO_PAGESIZE;
1695                 bank->sectors[i].is_erased = -1;
1696                 bank->sectors[i].is_protected = 0;
1697                 offset += NUMICRO_PAGESIZE;
1698         }
1699
1700         struct numicro_flash_bank *numicro_info = bank->driver_priv;
1701         numicro_info->probed = true;
1702         numicro_info->cpu = cpu;
1703         LOG_DEBUG("Nuvoton NuMicro: Probed ...");
1704
1705         return ERROR_OK;
1706 }
1707
1708 /* Standard approach to autoprobing. */
1709 static int numicro_auto_probe(struct flash_bank *bank)
1710 {
1711         struct numicro_flash_bank *numicro_info = bank->driver_priv;
1712         if (numicro_info->probed)
1713                 return ERROR_OK;
1714         return numicro_probe(bank);
1715 }
1716
1717
1718 /* This is the function called in the config file. */
1719 FLASH_BANK_COMMAND_HANDLER(numicro_flash_bank_command)
1720 {
1721         struct numicro_flash_bank *bank_info;
1722
1723         if (CMD_ARGC < 6)
1724                 return ERROR_COMMAND_SYNTAX_ERROR;
1725
1726         LOG_DEBUG("add flash_bank numicro %s", bank->name);
1727
1728         bank_info = malloc(sizeof(struct numicro_flash_bank));
1729
1730         memset(bank_info, 0, sizeof(struct numicro_flash_bank));
1731
1732         bank->driver_priv = bank_info;
1733         bank->write_start_alignment = bank->write_end_alignment = 4;
1734
1735         return ERROR_OK;
1736
1737 }
1738
1739 COMMAND_HANDLER(numicro_handle_read_isp_command)
1740 {
1741         uint32_t address;
1742         uint32_t ispdat;
1743         int retval = ERROR_OK;
1744
1745         if (CMD_ARGC != 1)
1746                 return ERROR_COMMAND_SYNTAX_ERROR;
1747
1748         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
1749
1750         struct target *target = get_current_target(CMD_CTX);
1751
1752         retval = numicro_init_isp(target);
1753         if (retval != ERROR_OK)
1754                 return retval;
1755
1756         retval = numicro_fmc_cmd(target, ISPCMD_READ, address, 0, &ispdat);
1757         if (retval != ERROR_OK)
1758                 return retval;
1759
1760         LOG_INFO("0x%08" PRIx32 ": 0x%08" PRIx32, address, ispdat);
1761
1762         return ERROR_OK;
1763 }
1764
1765 COMMAND_HANDLER(numicro_handle_write_isp_command)
1766 {
1767         uint32_t address;
1768         uint32_t ispdat, rdat;
1769         int retval = ERROR_OK;
1770
1771         if (CMD_ARGC != 2)
1772                 return ERROR_COMMAND_SYNTAX_ERROR;
1773
1774         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[0], address);
1775         COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], ispdat);
1776
1777         struct target *target = get_current_target(CMD_CTX);
1778
1779         retval = numicro_init_isp(target);
1780         if (retval != ERROR_OK)
1781                 return retval;
1782
1783         retval = numicro_fmc_cmd(target, ISPCMD_WRITE, address, ispdat, &rdat);
1784         if (retval != ERROR_OK)
1785                 return retval;
1786
1787         LOG_INFO("0x%08" PRIx32 ": 0x%08" PRIx32, address, ispdat);
1788         return ERROR_OK;
1789 }
1790
1791 COMMAND_HANDLER(numicro_handle_chip_erase_command)
1792 {
1793         int retval = ERROR_OK;
1794         uint32_t rdat;
1795
1796         if (CMD_ARGC != 0)
1797                 return ERROR_COMMAND_SYNTAX_ERROR;
1798
1799         struct target *target = get_current_target(CMD_CTX);
1800
1801         retval = numicro_init_isp(target);
1802         if (retval != ERROR_OK)
1803                 return retval;
1804
1805         retval = numicro_fmc_cmd(target, ISPCMD_CHIPERASE, 0, 0, &rdat);
1806         if (retval != ERROR_OK) {
1807                 command_print(CMD, "numicro chip_erase failed");
1808                 return retval;
1809         }
1810
1811         command_print(CMD, "numicro chip_erase complete");
1812
1813         return ERROR_OK;
1814 }
1815
1816 static const struct command_registration numicro_exec_command_handlers[] = {
1817         {
1818                 .name = "read_isp",
1819                 .handler = numicro_handle_read_isp_command,
1820                 .usage = "address",
1821                 .mode = COMMAND_EXEC,
1822                 .help = "read flash through ISP.",
1823         },
1824         {
1825                 .name = "write_isp",
1826                 .handler = numicro_handle_write_isp_command,
1827                 .usage = "address value",
1828                 .mode = COMMAND_EXEC,
1829                 .help = "write flash through ISP.",
1830         },
1831         {
1832                 .name = "chip_erase",
1833                 .handler = numicro_handle_chip_erase_command,
1834                 .mode = COMMAND_EXEC,
1835                 .help = "chip erase through ISP.",
1836                 .usage = "",
1837         },
1838         COMMAND_REGISTRATION_DONE
1839 };
1840
1841 static const struct command_registration numicro_command_handlers[] = {
1842         {
1843                 .name = "numicro",
1844                 .mode = COMMAND_ANY,
1845                 .help = "numicro flash command group",
1846                 .usage = "",
1847                 .chain = numicro_exec_command_handlers,
1848         },
1849         COMMAND_REGISTRATION_DONE
1850 };
1851
1852 const struct flash_driver numicro_flash = {
1853         .name = "numicro",
1854         .commands = numicro_command_handlers,
1855         .flash_bank_command = numicro_flash_bank_command,
1856         .erase = numicro_erase,
1857         .write = numicro_write,
1858         .read = default_flash_read,
1859         .probe = numicro_probe,
1860         .auto_probe = numicro_auto_probe,
1861         .erase_check = default_flash_blank_check,
1862         .protect_check = numicro_protect_check,
1863         .free_driver_priv = default_flash_free_driver_priv,
1864 };