]> git.sur5r.net Git - openocd/blob - src/flash/non_cfi.c
Michael Schwingen <rincewind@discworld.dascon.de> add non-CFI SST flashs
[openocd] / 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 }