Michael Schwingen <rincewind@discworld.dascon.de> add non-CFI SST flashs
[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 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
48 .num_erase_regions = 1,
49 .erase_region_info =
50 {
51 ERASE_REGION(16, 4*KB)
52 }
53 },
54 {
55 .mfr = CFI_MFR_SST,
56 .id = 0xd5,
57 .pri_id = 0x02,
58 .dev_size = 128*KB,
59 .interface_desc = 0x0, /* x8 only device */
60 .max_buf_write_size = 0x0,
61 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
62 .num_erase_regions = 1,
63 .erase_region_info =
64 {
65 ERASE_REGION(32, 4*KB)
66 }
67 },
68 {
69 .mfr = CFI_MFR_SST,
70 .id = 0xd6,
71 .pri_id = 0x02,
72 .dev_size = 256*KB,
73 .interface_desc = 0x0, /* x8 only device */
74 .max_buf_write_size = 0x0,
75 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
76 .num_erase_regions = 1,
77 .erase_region_info =
78 {
79 ERASE_REGION(64, 4*KB)
80 }
81 },
82 {
83 .mfr = CFI_MFR_SST,
84 .id = 0xd7,
85 .pri_id = 0x02,
86 .dev_size = 512*KB,
87 .interface_desc = 0x0, /* x8 only device */
88 .max_buf_write_size = 0x0,
89 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
90 .num_erase_regions = 1,
91 .erase_region_info =
92 {
93 ERASE_REGION(128, 4*KB)
94 }
95 },
96 {
97 .mfr = CFI_MFR_SST,
98 .id = 0x2780,
99 .pri_id = 0x02,
100 .dev_size = 512*KB,
101 .interface_desc = 0x2, /* x8 or x16 device */
102 .max_buf_write_size = 0x0,
103 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
104 .num_erase_regions = 1,
105 .erase_region_info =
106 {
107 ERASE_REGION(128, 4*KB)
108 }
109 },
110 {
111 .mfr = CFI_MFR_ST,
112 .id = 0xd6, /* ST29F400BB */
113 .pri_id = 0x02,
114 .dev_size = 512*KB,
115 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
116 .max_buf_write_size = 0x0,
117 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
118 .num_erase_regions = 4,
119 .erase_region_info =
120 {
121 ERASE_REGION( 1, 16*KB),
122 ERASE_REGION( 2, 8*KB),
123 ERASE_REGION( 1, 32*KB),
124 ERASE_REGION( 7, 64*KB)
125 }
126 },
127 {
128 .mfr = CFI_MFR_ST,
129 .id = 0xd5, /* ST29F400BT */
130 .pri_id = 0x02,
131 .dev_size = 512*KB,
132 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
133 .max_buf_write_size = 0x0,
134 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
135 .num_erase_regions = 4,
136 .erase_region_info =
137 {
138 ERASE_REGION( 7, 64*KB),
139 ERASE_REGION( 1, 32*KB),
140 ERASE_REGION( 2, 8*KB),
141 ERASE_REGION( 1, 16*KB)
142 }
143 },
144
145 /* SST 39VF* do not support DQ5 status polling - this currently is
146 only supported by the host algorithm, not by the target code using
147 the work area. */
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_AMIC,
285 .id = 0xb31a, /* A29L800A */
286 .pri_id = 0x02,
287 .dev_size = 1*MB,
288 .interface_desc = 0x2,
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( 1, 16*KB),
295 ERASE_REGION( 2, 8*KB),
296 ERASE_REGION( 1, 32*KB),
297 ERASE_REGION(15, 64*KB)
298 }
299 },
300 {
301 .mfr = CFI_MFR_MX,
302 .id = 0x225b, /* MX29LV800B */
303 .pri_id = 0x02,
304 .dev_size = 1*MB,
305 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
306 .max_buf_write_size = 0x0,
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(15, 64*KB)
315 }
316 },
317
318 {
319 .mfr = CFI_MFR_MX,
320 .id = 0x2249, /* MX29LV160AB: 2MB */
321 .pri_id = 0x02,
322 .dev_size = 2*MB,
323 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
324 .max_buf_write_size = 0x0,
325 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
326 .num_erase_regions = 4,
327 .erase_region_info =
328 {
329 ERASE_REGION( 1, 16*KB),
330 ERASE_REGION( 2, 8*KB),
331 ERASE_REGION( 1, 32*KB),
332 ERASE_REGION(31, 64*KB)
333 }
334 },
335 {
336 .mfr = CFI_MFR_MX,
337 .id = 0x22C4, /* MX29LV160AT: 2MB */
338 .pri_id = 0x02,
339 .dev_size = 2*MB,
340 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
341 .max_buf_write_size = 0x0,
342 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
343 .num_erase_regions = 4,
344 .erase_region_info =
345 {
346 ERASE_REGION(31, 64*KB),
347 ERASE_REGION( 1, 32*KB),
348 ERASE_REGION( 2, 8*KB),
349 ERASE_REGION( 1, 16*KB)
350 }
351 },
352 {
353 .mfr = CFI_MFR_ATMEL,
354 .id = 0x00c0, /* Atmel 49BV1614 */
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 = 3,
361 .erase_region_info =
362 {
363 ERASE_REGION( 8, 8*KB),
364 ERASE_REGION( 2, 32*KB),
365 ERASE_REGION(30, 64*KB)
366 }
367 },
368 {
369 .mfr = CFI_MFR_ATMEL,
370 .id = 0xC2, /* Atmel 49BV1614T */
371 .pri_id = 0x02,
372 .dev_size = 2*MB,
373 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
374 .max_buf_write_size = 0x0,
375 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
376 .num_erase_regions = 3,
377 .erase_region_info =
378 {
379 ERASE_REGION(30, 64*KB),
380 ERASE_REGION( 2, 32*KB),
381 ERASE_REGION( 8, 8*KB)
382 }
383 },
384 {
385 .mfr = CFI_MFR_AMD,
386 .id = 0x225b, /* S29AL008D */
387 .pri_id = 0x02,
388 .dev_size = 1*MB,
389 .interface_desc = 0x2, /* x8 or x16 device with nBYTE */
390 .max_buf_write_size = 0x0,
391 .status_poll_mask = CFI_STATUS_POLL_MASK_DQ5_DQ6_DQ7,
392 .num_erase_regions = 4,
393 .erase_region_info =
394 {
395 ERASE_REGION( 1, 16*KB),
396 ERASE_REGION( 2, 8*KB),
397 ERASE_REGION( 1, 32*KB),
398 ERASE_REGION(15, 64*KB)
399 }
400 },
401 {
402 .mfr = 0,
403 .id = 0,
404 }
405 };
406
407 void cfi_fixup_non_cfi(flash_bank_t *bank)
408 {
409 cfi_flash_bank_t *cfi_info = bank->driver_priv;
410 non_cfi_t *non_cfi = non_cfi_flashes;
411
412 for (non_cfi = non_cfi_flashes; non_cfi->mfr; non_cfi++)
413 {
414 if ((cfi_info->manufacturer == non_cfi->mfr)
415 && (cfi_info->device_id == non_cfi->id))
416 {
417 break;
418 }
419 }
420
421 /* only fixup jedec flashs found in table */
422 if (!non_cfi->mfr)
423 return;
424
425 cfi_info->not_cfi = 1;
426
427 /* fill in defaults for non-critical data */
428 cfi_info->vcc_min = 0x0;
429 cfi_info->vcc_max = 0x0;
430 cfi_info->vpp_min = 0x0;
431 cfi_info->vpp_max = 0x0;
432 cfi_info->word_write_timeout_typ = 0x0;
433 cfi_info->buf_write_timeout_typ = 0x0;
434 cfi_info->block_erase_timeout_typ = 0x0;
435 cfi_info->chip_erase_timeout_typ = 0x0;
436 cfi_info->word_write_timeout_max = 0x0;
437 cfi_info->buf_write_timeout_max = 0x0;
438 cfi_info->block_erase_timeout_max = 0x0;
439 cfi_info->chip_erase_timeout_max = 0x0;
440
441 cfi_info->qry[0] = 'Q';
442 cfi_info->qry[1] = 'R';
443 cfi_info->qry[2] = 'Y';
444
445 cfi_info->pri_id = non_cfi->pri_id;
446 cfi_info->pri_addr = 0x0;
447 cfi_info->alt_id = 0x0;
448 cfi_info->alt_addr = 0x0;
449 cfi_info->alt_ext = NULL;
450
451 cfi_info->interface_desc = non_cfi->interface_desc;
452 cfi_info->max_buf_write_size = non_cfi->max_buf_write_size;
453 cfi_info->status_poll_mask = non_cfi->status_poll_mask;
454 cfi_info->num_erase_regions = non_cfi->num_erase_regions;
455 cfi_info->erase_region_info = non_cfi->erase_region_info;
456 cfi_info->dev_size = non_cfi->dev_size;
457
458 if (cfi_info->pri_id == 0x2)
459 {
460 cfi_spansion_pri_ext_t *pri_ext = malloc(sizeof(cfi_spansion_pri_ext_t));
461
462 pri_ext->pri[0] = 'P';
463 pri_ext->pri[1] = 'R';
464 pri_ext->pri[2] = 'I';
465
466 pri_ext->major_version = '1';
467 pri_ext->minor_version = '0';
468
469 pri_ext->SiliconRevision = 0x0;
470 pri_ext->EraseSuspend = 0x0;
471 pri_ext->EraseSuspend = 0x0;
472 pri_ext->BlkProt = 0x0;
473 pri_ext->TmpBlkUnprotect = 0x0;
474 pri_ext->BlkProtUnprot = 0x0;
475 pri_ext->SimultaneousOps = 0x0;
476 pri_ext->BurstMode = 0x0;
477 pri_ext->PageMode = 0x0;
478 pri_ext->VppMin = 0x0;
479 pri_ext->VppMax = 0x0;
480 pri_ext->TopBottom = 0x0;
481
482 pri_ext->_unlock1 = 0x5555;
483 pri_ext->_unlock2 = 0x2AAA;
484 pri_ext->_reversed_geometry = 0;
485
486 cfi_info->pri_ext = pri_ext;
487 } else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3))
488 {
489 LOG_ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported");
490 exit(-1);
491 }
492 }

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)