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

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)