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