569ffc5f82ab9011db977f0745763e88f79ff0a4
[openocd.git] / src / flash / nor / 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 "imp.h"
27 #include "cfi.h"
28 #include "non_cfi.h"
29
30
31 #define KB 1024
32 #define MB (1024*1024)
33 #define ERASE_REGION(num, size) (((size/256) << 16) | (num-1))
34
35 /* non-CFI compatible flashes */
36 static struct non_cfi non_cfi_flashes[] = {
37 {
38 .mfr = CFI_MFR_SST,
39 .id = 0xd4,
40 .pri_id = 0x02,
41 .dev_size = 64*KB,
42 .interface_desc = 0x0, /* x8 only device */
43 .max_buf_write_size = 0x0,
44 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
45 .num_erase_regions = 1,
46 .erase_region_info =
47 {
48 ERASE_REGION(16, 4*KB)
49 }
50 },
51 {
52 .mfr = CFI_MFR_SST,
53 .id = 0xd5,
54 .pri_id = 0x02,
55 .dev_size = 128*KB,
56 .interface_desc = 0x0, /* x8 only device */
57 .max_buf_write_size = 0x0,
58 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
59 .num_erase_regions = 1,
60 .erase_region_info =
61 {
62 ERASE_REGION(32, 4*KB)
63 }
64 },
65 {
66 .mfr = CFI_MFR_SST,
67 .id = 0xd6,
68 .pri_id = 0x02,
69 .dev_size = 256*KB,
70 .interface_desc = 0x0, /* x8 only device */
71 .max_buf_write_size = 0x0,
72 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
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 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
87 .num_erase_regions = 1,
88 .erase_region_info =
89 {
90 ERASE_REGION(128, 4*KB)
91 }
92 },
93 {
94 .mfr = CFI_MFR_SST,
95 .id = 0x2780,
96 .pri_id = 0x02,
97 .dev_size = 512*KB,
98 .interface_desc = 0x2, /* x8 or x16 device */
99 .max_buf_write_size = 0x0,
100 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
101 .num_erase_regions = 1,
102 .erase_region_info =
103 {
104 ERASE_REGION(128, 4*KB)
105 }
106 },
107 {
108 .mfr = CFI_MFR_ST,
109 .id = 0xd6, /* ST29F400BB */
110 .pri_id = 0x02,
111 .dev_size = 512*KB,
112 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
113 .max_buf_write_size = 0x0,
114 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
115 .num_erase_regions = 4,
116 .erase_region_info =
117 {
118 ERASE_REGION(1, 16*KB),
119 ERASE_REGION(2, 8*KB),
120 ERASE_REGION(1, 32*KB),
121 ERASE_REGION(7, 64*KB)
122 }
123 },
124 {
125 .mfr = CFI_MFR_ST,
126 .id = 0xd5, /* ST29F400BT */
127 .pri_id = 0x02,
128 .dev_size = 512*KB,
129 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
130 .max_buf_write_size = 0x0,
131 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
132 .num_erase_regions = 4,
133 .erase_region_info =
134 {
135 ERASE_REGION(7, 64*KB),
136 ERASE_REGION(1, 32*KB),
137 ERASE_REGION(2, 8*KB),
138 ERASE_REGION(1, 16*KB)
139 }
140 },
141
142 /* SST 39VF* do not support DQ5 status polling - this currently is
143 only supported by the host algorithm, not by the target code using
144 the work area.
145 Only true for 8-bit and 32-bit wide memories. 16-bit wide memories
146 without DQ5 status polling are supported by the target code.
147 */
148 {
149 .mfr = CFI_MFR_SST,
150 .id = 0x2782, /* SST39xF160 */
151 .pri_id = 0x02,
152 .dev_size = 2*MB,
153 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
154 .max_buf_write_size = 0x0,
155 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
156 .num_erase_regions = 1,
157 .erase_region_info =
158 {
159 ERASE_REGION(512, 4*KB)
160 }
161 },
162 {
163 .mfr = CFI_MFR_SST,
164 .id = 0x2783, /* SST39VF320 */
165 .pri_id = 0x02,
166 .dev_size = 4*MB,
167 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
168 .max_buf_write_size = 0x0,
169 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
170 .num_erase_regions = 1,
171 .erase_region_info =
172 {
173 ERASE_REGION(1024, 4*KB)
174 }
175 },
176 {
177 .mfr = CFI_MFR_SST,
178 .id = 0x234b, /* SST39VF1601 */
179 .pri_id = 0x02,
180 .dev_size = 2*MB,
181 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
182 .max_buf_write_size = 0x0,
183 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
184 .num_erase_regions = 1,
185 .erase_region_info =
186 {
187 ERASE_REGION(512, 4*KB)
188 }
189 },
190 {
191 .mfr = CFI_MFR_SST,
192 .id = 0x234a, /* SST39VF1602 */
193 .pri_id = 0x02,
194 .dev_size = 2*MB,
195 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
196 .max_buf_write_size = 0x0,
197 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
198 .num_erase_regions = 1,
199 .erase_region_info =
200 {
201 ERASE_REGION(512, 4*KB)
202 }
203 },
204 {
205 .mfr = CFI_MFR_SST,
206 .id = 0x235b, /* SST39VF3201 */
207 .pri_id = 0x02,
208 .dev_size = 4*MB,
209 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
210 .max_buf_write_size = 0x0,
211 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
212 .num_erase_regions = 1,
213 .erase_region_info =
214 {
215 ERASE_REGION(1024, 4*KB)
216 }
217 },
218 {
219 .mfr = CFI_MFR_SST,
220 .id = 0x235a, /* SST39VF3202 */
221 .pri_id = 0x02,
222 .dev_size = 4*MB,
223 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
224 .max_buf_write_size = 0x0,
225 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ6_DQ7,
226 .num_erase_regions = 1,
227 .erase_region_info =
228 {
229 ERASE_REGION(1024, 4*KB)
230 }
231 },
232 {
233 .mfr = CFI_MFR_AMD,
234 .id = 0x22ab, /* AM29F400BB */
235 .pri_id = 0x02,
236 .dev_size = 512*KB,
237 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
238 .max_buf_write_size = 0x0,
239 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
240 .num_erase_regions = 4,
241 .erase_region_info =
242 {
243 ERASE_REGION(1, 16*KB),
244 ERASE_REGION(2, 8*KB),
245 ERASE_REGION(1, 32*KB),
246 ERASE_REGION(7, 64*KB)
247 }
248 },
249 {
250 .mfr = CFI_MFR_AMD,
251 .id = 0x2223, /* AM29F400BT */
252 .pri_id = 0x02,
253 .dev_size = 512*KB,
254 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
255 .max_buf_write_size = 0x0,
256 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
257 .num_erase_regions = 4,
258 .erase_region_info =
259 {
260 ERASE_REGION(7, 64*KB),
261 ERASE_REGION(1, 32*KB),
262 ERASE_REGION(2, 8*KB),
263 ERASE_REGION(1, 16*KB)
264 }
265 },
266 {
267 .mfr = CFI_MFR_FUJITSU,
268 .id = 0x226b, /* AM29SL800DB */
269 .pri_id = 0x02,
270 .dev_size = 1*MB,
271 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
272 .max_buf_write_size = 0x0,
273 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
274 .num_erase_regions = 4,
275 .erase_region_info =
276 {
277 ERASE_REGION(1, 16*KB),
278 ERASE_REGION(2, 8*KB),
279 ERASE_REGION(1, 32*KB),
280 ERASE_REGION(15, 64*KB)
281 }
282 },
283 {
284 .mfr = CFI_MFR_FUJITSU,
285 .id = 0x22ea, /* MBM29SL800TE */
286 .pri_id = 0x02,
287 .dev_size = 1*MB,
288 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
289 .max_buf_write_size = 0x0,
290 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
291 .num_erase_regions = 4,
292 .erase_region_info =
293 {
294 ERASE_REGION(15, 64*KB),
295 ERASE_REGION(1, 32*KB),
296 ERASE_REGION(2, 8*KB),
297 ERASE_REGION(1, 16*KB)
298 }
299 },
300 {
301 .mfr = CFI_MFR_FUJITSU,
302 .id = 0xba, /* 29LV400BC */
303 .pri_id = 0x02,
304 .dev_size = 512*KB,
305 .interface_desc = 0x1, /* x8 or x16 device w/ nBYTE */
306 .max_buf_write_size = 0x00,
307 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
308 .num_erase_regions = 4,
309 .erase_region_info =
310 {
311 ERASE_REGION(1, 16*KB),
312 ERASE_REGION(2, 8*KB),
313 ERASE_REGION(1, 32*KB),
314 ERASE_REGION(7, 64*KB)
315 }
316 },
317 {
318 .mfr = CFI_MFR_AMIC,
319 .id = 0xb31a, /* A29L800A */
320 .pri_id = 0x02,
321 .dev_size = 1*MB,
322 .interface_desc = 0x2,
323 .max_buf_write_size = 0x0,
324 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
325 .num_erase_regions = 4,
326 .erase_region_info =
327 {
328 ERASE_REGION(1, 16*KB),
329 ERASE_REGION(2, 8*KB),
330 ERASE_REGION(1, 32*KB),
331 ERASE_REGION(15, 64*KB)
332 }
333 },
334 {
335 .mfr = CFI_MFR_MX,
336 .id = 0x225b, /* MX29LV800B */
337 .pri_id = 0x02,
338 .dev_size = 1*MB,
339 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
340 .max_buf_write_size = 0x0,
341 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
342 .num_erase_regions = 4,
343 .erase_region_info =
344 {
345 ERASE_REGION(1, 16*KB),
346 ERASE_REGION(2, 8*KB),
347 ERASE_REGION(1, 32*KB),
348 ERASE_REGION(15, 64*KB)
349 }
350 },
351
352 {
353 .mfr = CFI_MFR_MX,
354 .id = 0x2249, /* MX29LV160AB: 2MB */
355 .pri_id = 0x02,
356 .dev_size = 2*MB,
357 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
358 .max_buf_write_size = 0x0,
359 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
360 .num_erase_regions = 4,
361 .erase_region_info =
362 {
363 ERASE_REGION(1, 16*KB),
364 ERASE_REGION(2, 8*KB),
365 ERASE_REGION(1, 32*KB),
366 ERASE_REGION(31, 64*KB)
367 }
368 },
369 {
370 .mfr = CFI_MFR_MX,
371 .id = 0x22C4, /* MX29LV160AT: 2MB */
372 .pri_id = 0x02,
373 .dev_size = 2*MB,
374 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
375 .max_buf_write_size = 0x0,
376 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
377 .num_erase_regions = 4,
378 .erase_region_info =
379 {
380 ERASE_REGION(31, 64*KB),
381 ERASE_REGION(1, 32*KB),
382 ERASE_REGION(2, 8*KB),
383 ERASE_REGION(1, 16*KB)
384 }
385 },
386 {
387 .mfr = CFI_MFR_ATMEL,
388 .id = 0x00c0, /* Atmel 49BV1614 */
389 .pri_id = 0x02,
390 .dev_size = 2*MB,
391 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
392 .max_buf_write_size = 0x0,
393 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
394 .num_erase_regions = 3,
395 .erase_region_info =
396 {
397 ERASE_REGION(8, 8*KB),
398 ERASE_REGION(2, 32*KB),
399 ERASE_REGION(30, 64*KB)
400 }
401 },
402 {
403 .mfr = CFI_MFR_ATMEL,
404 .id = 0xC2, /* Atmel 49BV1614T */
405 .pri_id = 0x02,
406 .dev_size = 2*MB,
407 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
408 .max_buf_write_size = 0x0,
409 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
410 .num_erase_regions = 3,
411 .erase_region_info =
412 {
413 ERASE_REGION(30, 64*KB),
414 ERASE_REGION(2, 32*KB),
415 ERASE_REGION(8, 8*KB)
416 }
417 },
418 {
419 .mfr = CFI_MFR_AMD,
420 .id = 0x225b, /* S29AL008D */
421 .pri_id = 0x02,
422 .dev_size = 1*MB,
423 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
424 .max_buf_write_size = 0x0,
425 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
426 .num_erase_regions = 4,
427 .erase_region_info =
428 {
429 ERASE_REGION(1, 16*KB),
430 ERASE_REGION(2, 8*KB),
431 ERASE_REGION(1, 32*KB),
432 ERASE_REGION(15, 64*KB)
433 }
434 },
435 {
436 .mfr = 0,
437 .id = 0,
438 }
439 };
440
441 void cfi_fixup_non_cfi(struct flash_bank *bank)
442 {
443 struct cfi_flash_bank *cfi_info = bank->driver_priv;
444 struct non_cfi *non_cfi = non_cfi_flashes;
445
446 for (non_cfi = non_cfi_flashes; non_cfi->mfr; non_cfi++)
447 {
448 if ((cfi_info->manufacturer == non_cfi->mfr)
449 && (cfi_info->device_id == non_cfi->id))
450 {
451 break;
452 }
453 }
454
455 /* only fixup jedec flashs found in table */
456 if (!non_cfi->mfr)
457 return;
458
459 cfi_info->not_cfi = 1;
460
461 /* fill in defaults for non-critical data */
462 cfi_info->vcc_min = 0x0;
463 cfi_info->vcc_max = 0x0;
464 cfi_info->vpp_min = 0x0;
465 cfi_info->vpp_max = 0x0;
466 cfi_info->word_write_timeout_typ = 0x0;
467 cfi_info->buf_write_timeout_typ = 0x0;
468 cfi_info->block_erase_timeout_typ = 0x0;
469 cfi_info->chip_erase_timeout_typ = 0x0;
470 cfi_info->word_write_timeout_max = 0x0;
471 cfi_info->buf_write_timeout_max = 0x0;
472 cfi_info->block_erase_timeout_max = 0x0;
473 cfi_info->chip_erase_timeout_max = 0x0;
474
475 cfi_info->qry[0] = 'Q';
476 cfi_info->qry[1] = 'R';
477 cfi_info->qry[2] = 'Y';
478
479 cfi_info->pri_id = non_cfi->pri_id;
480 cfi_info->pri_addr = 0x0;
481 cfi_info->alt_id = 0x0;
482 cfi_info->alt_addr = 0x0;
483 cfi_info->alt_ext = NULL;
484
485 cfi_info->interface_desc = non_cfi->interface_desc;
486 cfi_info->max_buf_write_size = non_cfi->max_buf_write_size;
487 cfi_info->status_poll_mask = non_cfi->status_poll_mask;
488 cfi_info->num_erase_regions = non_cfi->num_erase_regions;
489 size_t erase_region_info_size = sizeof(*cfi_info->erase_region_info) *
490 cfi_info->num_erase_regions;
491 cfi_info->erase_region_info = malloc(erase_region_info_size);
492 memcpy(cfi_info->erase_region_info,
493 non_cfi->erase_region_info, erase_region_info_size);
494 cfi_info->dev_size = non_cfi->dev_size;
495
496 if (cfi_info->pri_id == 0x2)
497 {
498 struct cfi_spansion_pri_ext *pri_ext = malloc(sizeof(struct cfi_spansion_pri_ext));
499
500 pri_ext->pri[0] = 'P';
501 pri_ext->pri[1] = 'R';
502 pri_ext->pri[2] = 'I';
503
504 pri_ext->major_version = '1';
505 pri_ext->minor_version = '0';
506
507 pri_ext->SiliconRevision = 0x0;
508 pri_ext->EraseSuspend = 0x0;
509 pri_ext->EraseSuspend = 0x0;
510 pri_ext->BlkProt = 0x0;
511 pri_ext->TmpBlkUnprotect = 0x0;
512 pri_ext->BlkProtUnprot = 0x0;
513 pri_ext->SimultaneousOps = 0x0;
514 pri_ext->BurstMode = 0x0;
515 pri_ext->PageMode = 0x0;
516 pri_ext->VppMin = 0x0;
517 pri_ext->VppMax = 0x0;
518 pri_ext->TopBottom = 0x0;
519
520 pri_ext->_unlock1 = 0x5555;
521 pri_ext->_unlock2 = 0x2AAA;
522 pri_ext->_reversed_geometry = 0;
523
524 cfi_info->pri_ext = pri_ext;
525 } else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3))
526 {
527 LOG_ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported");
528 exit(-1);
529 }
530 }

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)