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