Zach Welch <zw@superlucidity.net> use static keyword in jtag layer and drivers
[openocd.git] / src / flash / non_cfi.c
1 /***************************************************************************
2 * Copyright (C) 2007 by Dominic Rath *
3 * Dominic.Rath@gmx.de *
4 * Copyright (C) 2009 Michael Schwingen *
5 * michael@schwingen.org *
6 * *
7 * This program is free software; you can redistribute it and/or modify *
8 * it under the terms of the GNU General Public License as published by *
9 * the Free Software Foundation; either version 2 of the License, or *
10 * (at your option) any later version. *
11 * *
12 * This program is distributed in the hope that it will be useful, *
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
15 * GNU General Public License for more details. *
16 * *
17 * You should have received a copy of the GNU General Public License *
18 * along with this program; if not, write to the *
19 * Free Software Foundation, Inc., *
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
21 ***************************************************************************/
22 #ifdef HAVE_CONFIG_H
23 #include "config.h"
24 #endif
25
26 #include <stdlib.h>
27
28 #include "log.h"
29
30 #include "flash.h"
31 #include "cfi.h"
32 #include "non_cfi.h"
33
34 #define KB 1024
35 #define MB (1024*1024)
36 #define ERASE_REGION(num, size) (((size/256)<<16)|(num-1))
37
38 /* non-CFI compatible flashes */
39 non_cfi_t non_cfi_flashes[] = {
40 {
41 .mfr = CFI_MFR_SST,
42 .id = 0xd4,
43 .pri_id = 0x02,
44 .dev_size = 64*KB,
45 .interface_desc = 0x0, /* x8 only device */
46 .max_buf_write_size = 0x0,
47 .num_erase_regions = 1,
48 .erase_region_info =
49 {
50 ERASE_REGION(16, 4*KB)
51 }
52 },
53 {
54 .mfr = CFI_MFR_SST,
55 .id = 0xd5,
56 .pri_id = 0x02,
57 .dev_size = 128*KB,
58 .interface_desc = 0x0, /* x8 only device */
59 .max_buf_write_size = 0x0,
60 .num_erase_regions = 1,
61 .erase_region_info =
62 {
63 ERASE_REGION(32, 4*KB)
64 }
65 },
66 {
67 .mfr = CFI_MFR_SST,
68 .id = 0xd6,
69 .pri_id = 0x02,
70 .dev_size = 256*KB,
71 .interface_desc = 0x0, /* x8 only device */
72 .max_buf_write_size = 0x0,
73 .num_erase_regions = 1,
74 .erase_region_info =
75 {
76 ERASE_REGION(64, 4*KB)
77 }
78 },
79 {
80 .mfr = CFI_MFR_SST,
81 .id = 0xd7,
82 .pri_id = 0x02,
83 .dev_size = 512*KB,
84 .interface_desc = 0x0, /* x8 only device */
85 .max_buf_write_size = 0x0,
86 .num_erase_regions = 1,
87 .erase_region_info =
88 {
89 ERASE_REGION(128, 4*KB)
90 }
91 },
92 {
93 .mfr = CFI_MFR_SST,
94 .id = 0x2780,
95 .pri_id = 0x02,
96 .dev_size = 512*KB,
97 .interface_desc = 0x2, /* x8 or x16 device */
98 .max_buf_write_size = 0x0,
99 .num_erase_regions = 1,
100 .erase_region_info =
101 {
102 ERASE_REGION(128, 4*KB)
103 }
104 },
105 {
106 .mfr = CFI_MFR_ST,
107 .id = 0xd6, /* ST29F400BB */
108 .pri_id = 0x02,
109 .dev_size = 512*KB,
110 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
111 .max_buf_write_size = 0x0,
112 .num_erase_regions = 4,
113 .erase_region_info =
114 {
115 ERASE_REGION( 1, 16*KB),
116 ERASE_REGION( 2, 8*KB),
117 ERASE_REGION( 1, 32*KB),
118 ERASE_REGION( 7, 64*KB)
119 }
120 },
121 {
122 .mfr = CFI_MFR_ST,
123 .id = 0xd5, /* ST29F400BT */
124 .pri_id = 0x02,
125 .dev_size = 512*KB,
126 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
127 .max_buf_write_size = 0x0,
128 .num_erase_regions = 4,
129 .erase_region_info =
130 {
131 ERASE_REGION( 7, 64*KB),
132 ERASE_REGION( 1, 32*KB),
133 ERASE_REGION( 2, 8*KB),
134 ERASE_REGION( 1, 16*KB)
135 }
136 },
137 {
138 .mfr = CFI_MFR_AMD,
139 .id = 0x22ab, /* AM29F400BB */
140 .pri_id = 0x02,
141 .dev_size = 512*KB,
142 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
143 .max_buf_write_size = 0x0,
144 .num_erase_regions = 4,
145 .erase_region_info =
146 {
147 ERASE_REGION( 1, 16*KB),
148 ERASE_REGION( 2, 8*KB),
149 ERASE_REGION( 1, 32*KB),
150 ERASE_REGION( 7, 64*KB)
151 }
152 },
153 {
154 .mfr = CFI_MFR_AMD,
155 .id = 0x2223, /* AM29F400BT */
156 .pri_id = 0x02,
157 .dev_size = 512*KB,
158 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
159 .max_buf_write_size = 0x0,
160 .num_erase_regions = 4,
161 .erase_region_info =
162 {
163 ERASE_REGION( 7, 64*KB),
164 ERASE_REGION( 1, 32*KB),
165 ERASE_REGION( 2, 8*KB),
166 ERASE_REGION( 1, 16*KB)
167 }
168 },
169 {
170 .mfr = CFI_MFR_FUJITSU,
171 .id = 0x226b, /* AM29SL800DB */
172 .pri_id = 0x02,
173 .dev_size = 1*MB,
174 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
175 .max_buf_write_size = 0x0,
176 .num_erase_regions = 4,
177 .erase_region_info =
178 {
179 ERASE_REGION( 1, 16*KB),
180 ERASE_REGION( 2, 8*KB),
181 ERASE_REGION( 1, 32*KB),
182 ERASE_REGION(15, 64*KB)
183 }
184 },
185 {
186 .mfr = CFI_MFR_AMIC,
187 .id = 0xb31a, /* A29L800A */
188 .pri_id = 0x02,
189 .dev_size = 1*MB,
190 .interface_desc = 0x2,
191 .max_buf_write_size = 0x0,
192 .num_erase_regions = 4,
193 .erase_region_info =
194 {
195 ERASE_REGION( 1, 16*KB),
196 ERASE_REGION( 2, 8*KB),
197 ERASE_REGION( 1, 32*KB),
198 ERASE_REGION(15, 64*KB)
199 }
200 },
201 {
202 .mfr = CFI_MFR_MX,
203 .id = 0x225b, /* MX29LV800B */
204 .pri_id = 0x02,
205 .dev_size = 1*MB,
206 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
207 .max_buf_write_size = 0x0,
208 .num_erase_regions = 4,
209 .erase_region_info =
210 {
211 ERASE_REGION( 1, 16*KB),
212 ERASE_REGION( 2, 8*KB),
213 ERASE_REGION( 1, 32*KB),
214 ERASE_REGION(15, 64*KB)
215 }
216 },
217
218 {
219 .mfr = CFI_MFR_MX,
220 .id = 0x2249, /* MX29LV160AB: 2MB */
221 .pri_id = 0x02,
222 .dev_size = 2*MB,
223 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
224 .max_buf_write_size = 0x0,
225 .num_erase_regions = 4,
226 .erase_region_info =
227 {
228 ERASE_REGION( 1, 16*KB),
229 ERASE_REGION( 2, 8*KB),
230 ERASE_REGION( 1, 32*KB),
231 ERASE_REGION(31, 64*KB)
232 }
233 },
234 {
235 .mfr = CFI_MFR_MX,
236 .id = 0x22C4, /* MX29LV160AT: 2MB */
237 .pri_id = 0x02,
238 .dev_size = 2*MB,
239 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
240 .max_buf_write_size = 0x0,
241 .num_erase_regions = 4,
242 .erase_region_info =
243 {
244 ERASE_REGION(31, 64*KB),
245 ERASE_REGION( 1, 32*KB),
246 ERASE_REGION( 2, 8*KB),
247 ERASE_REGION( 1, 16*KB)
248 }
249 },
250 {
251 .mfr = CFI_MFR_SST,
252 .id = 0x2782, /* SST39xF160 */
253 .pri_id = 0x02,
254 .dev_size = 2*MB,
255 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
256 .max_buf_write_size = 0x0,
257 .num_erase_regions = 1,
258 .erase_region_info =
259 {
260 ERASE_REGION(512, 4*KB)
261 }
262 },
263 {
264 .mfr = CFI_MFR_ATMEL,
265 .id = 0x00c0, /* Atmel 49BV1614 */
266 .pri_id = 0x02,
267 .dev_size = 2*MB,
268 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
269 .max_buf_write_size = 0x0,
270 .num_erase_regions = 3,
271 .erase_region_info =
272 {
273 ERASE_REGION( 8, 8*KB),
274 ERASE_REGION( 2, 32*KB),
275 ERASE_REGION(30, 64*KB)
276 }
277 },
278 {
279 .mfr = CFI_MFR_ATMEL,
280 .id = 0xC2, /* Atmel 49BV1614T */
281 .pri_id = 0x02,
282 .dev_size = 2*MB,
283 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
284 .max_buf_write_size = 0x0,
285 .num_erase_regions = 3,
286 .erase_region_info =
287 {
288 ERASE_REGION(30, 64*KB),
289 ERASE_REGION( 2, 32*KB),
290 ERASE_REGION( 8, 8*KB)
291 }
292 },
293 {
294 .mfr = CFI_MFR_AMD,
295 .id = 0x225b, /* S29AL008D */
296 .pri_id = 0x02,
297 .dev_size = 1*MB,
298 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
299 .max_buf_write_size = 0x0,
300 .num_erase_regions = 4,
301 .erase_region_info =
302 {
303 ERASE_REGION( 1, 16*KB),
304 ERASE_REGION( 2, 8*KB),
305 ERASE_REGION( 1, 32*KB),
306 ERASE_REGION(15, 64*KB)
307 }
308 },
309 {
310 .mfr = 0,
311 .id = 0,
312 }
313 };
314
315 void cfi_fixup_non_cfi(flash_bank_t *bank)
316 {
317 cfi_flash_bank_t *cfi_info = bank->driver_priv;
318 non_cfi_t *non_cfi = non_cfi_flashes;
319
320 for (non_cfi = non_cfi_flashes; non_cfi->mfr; non_cfi++)
321 {
322 if ((cfi_info->manufacturer == non_cfi->mfr)
323 && (cfi_info->device_id == non_cfi->id))
324 {
325 break;
326 }
327 }
328
329 /* only fixup jedec flashs found in table */
330 if (!non_cfi->mfr)
331 return;
332
333 cfi_info->not_cfi = 1;
334
335 /* fill in defaults for non-critical data */
336 cfi_info->vcc_min = 0x0;
337 cfi_info->vcc_max = 0x0;
338 cfi_info->vpp_min = 0x0;
339 cfi_info->vpp_max = 0x0;
340 cfi_info->word_write_timeout_typ = 0x0;
341 cfi_info->buf_write_timeout_typ = 0x0;
342 cfi_info->block_erase_timeout_typ = 0x0;
343 cfi_info->chip_erase_timeout_typ = 0x0;
344 cfi_info->word_write_timeout_max = 0x0;
345 cfi_info->buf_write_timeout_max = 0x0;
346 cfi_info->block_erase_timeout_max = 0x0;
347 cfi_info->chip_erase_timeout_max = 0x0;
348
349 cfi_info->qry[0] = 'Q';
350 cfi_info->qry[1] = 'R';
351 cfi_info->qry[2] = 'Y';
352
353 cfi_info->pri_id = non_cfi->pri_id;
354 cfi_info->pri_addr = 0x0;
355 cfi_info->alt_id = 0x0;
356 cfi_info->alt_addr = 0x0;
357 cfi_info->alt_ext = NULL;
358
359 cfi_info->interface_desc = non_cfi->interface_desc;
360 cfi_info->max_buf_write_size = non_cfi->max_buf_write_size;
361 cfi_info->num_erase_regions = non_cfi->num_erase_regions;
362 cfi_info->erase_region_info = non_cfi->erase_region_info;
363 cfi_info->dev_size = non_cfi->dev_size;
364
365 if (cfi_info->pri_id == 0x2)
366 {
367 cfi_spansion_pri_ext_t *pri_ext = malloc(sizeof(cfi_spansion_pri_ext_t));
368
369 pri_ext->pri[0] = 'P';
370 pri_ext->pri[1] = 'R';
371 pri_ext->pri[2] = 'I';
372
373 pri_ext->major_version = '1';
374 pri_ext->minor_version = '0';
375
376 pri_ext->SiliconRevision = 0x0;
377 pri_ext->EraseSuspend = 0x0;
378 pri_ext->EraseSuspend = 0x0;
379 pri_ext->BlkProt = 0x0;
380 pri_ext->TmpBlkUnprotect = 0x0;
381 pri_ext->BlkProtUnprot = 0x0;
382 pri_ext->SimultaneousOps = 0x0;
383 pri_ext->BurstMode = 0x0;
384 pri_ext->PageMode = 0x0;
385 pri_ext->VppMin = 0x0;
386 pri_ext->VppMax = 0x0;
387 pri_ext->TopBottom = 0x0;
388
389 pri_ext->_unlock1 = 0x5555;
390 pri_ext->_unlock2 = 0x2AAA;
391 pri_ext->_reversed_geometry = 0;
392
393 cfi_info->pri_ext = pri_ext;
394 } else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3))
395 {
396 LOG_ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported");
397 exit(-1);
398 }
399 }

Linking to existing account procedure

If you already have an account and want to add another login method you MUST first sign in with your existing account and then change URL to read https://review.openocd.org/login/?link to get to this page again but this time it'll work for linking. Thank you.

SSH host keys fingerprints

1024 SHA256:YKx8b7u5ZWdcbp7/4AeXNaqElP49m6QrwfXaqQGJAOk gerrit-code-review@openocd.zylin.com (DSA)
384 SHA256:jHIbSQa4REvwCFG4cq5LBlBLxmxSqelQPem/EXIrxjk gerrit-code-review@openocd.org (ECDSA)
521 SHA256:UAOPYkU9Fjtcao0Ul/Rrlnj/OsQvt+pgdYSZ4jOYdgs gerrit-code-review@openocd.org (ECDSA)
256 SHA256:A13M5QlnozFOvTllybRZH6vm7iSt0XLxbA48yfc2yfY gerrit-code-review@openocd.org (ECDSA)
256 SHA256:spYMBqEYoAOtK7yZBrcwE8ZpYt6b68Cfh9yEVetvbXg gerrit-code-review@openocd.org (ED25519)
+--[ED25519 256]--+
|=..              |
|+o..   .         |
|*.o   . .        |
|+B . . .         |
|Bo. = o S        |
|Oo.+ + =         |
|oB=.* = . o      |
| =+=.+   + E     |
|. .=o   . o      |
+----[SHA256]-----+
2048 SHA256:0Onrb7/PHjpo6iVZ7xQX2riKN83FJ3KGU0TvI0TaFG4 gerrit-code-review@openocd.zylin.com (RSA)