]> git.sur5r.net Git - openocd/blob - src/flash/non_cfi.c
- renamed M5960 USB JTAG to "flyswatter"
[openocd] / src / flash / non_cfi.c
1 /***************************************************************************
2  *   Copyright (C) 2007 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include <stdlib.h>
25
26 #include "log.h"
27
28 #include "flash.h"
29 #include "cfi.h"
30 #include "non_cfi.h"
31
32 /* non-CFI compatible flashes */
33 non_cfi_t non_cfi_flashes[] = {
34         {
35                 .mfr = CFI_MFR_SST,
36                 .id = 0xd4,
37                 .pri_id = 0x02,
38                 .dev_size = 0x10,                       /* 2^16 = 64KB */
39                 .interface_desc = 0x0,          /* x8 only device */
40                 .max_buf_write_size = 0x0,
41                 .num_erase_regions = 1,
42                 .erase_region_info =
43                 {
44                         0x0010000f,                             /* 16x  4KB */
45                         0x00000000
46                 }
47         },
48         {
49                 .mfr = CFI_MFR_SST,
50                 .id = 0xd5,
51                 .pri_id = 0x02,
52                 .dev_size = 0x11,                       /* 2^17 = 128KB */
53                 .interface_desc = 0x0,          /* x8 only device */
54                 .max_buf_write_size = 0x0,
55                 .num_erase_regions = 1,
56                 .erase_region_info =
57                 {
58                         0x0010001f,
59                         0x00000000
60                 }
61         },
62         {
63                 .mfr = CFI_MFR_SST,
64                 .id = 0xd6,
65                 .pri_id = 0x02,
66                 .dev_size = 0x12,                       /* 2^18 = 256KB */
67                 .interface_desc = 0x0,          /* x8 only device */
68                 .max_buf_write_size = 0x0,
69                 .num_erase_regions = 1,
70                 .erase_region_info =
71                 {
72                         0x0010003f,
73                         0x00000000
74                 }
75         },
76         {
77                 .mfr = CFI_MFR_SST,
78                 .id = 0xd7,
79                 .pri_id = 0x02,
80                 .dev_size = 0x13,                       /* 2^19 = 512KB */
81                 .interface_desc = 0x0,          /* x8 only device */
82                 .max_buf_write_size = 0x0,
83                 .num_erase_regions = 1,
84                 .erase_region_info =
85                 {
86                         0x0010007f,
87                         0x00000000
88                 }
89         },
90         {
91                 .mfr = CFI_MFR_ST,
92                 .id = 0xd6,                                     /* ST29F400BB */
93                 .pri_id = 0x02,
94                 .dev_size = 0x13,                       /* 2^19 = 512KB */
95                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
96                 .max_buf_write_size = 0x0,
97                 .num_erase_regions = 4,
98                 .erase_region_info =
99                 {
100                         0x00400000,             /* 1x 16KB */
101                         0x00200001,             /* 2x  8KB */
102                         0x00800000,             /* 1x 32KB */
103                         0x01000006,             /* 7x 64KB */
104                         0x00000000
105                 }
106         },
107         {
108                 .mfr = CFI_MFR_ST,
109                 .id = 0xd5,                                     /* ST29F400BT */
110                 .pri_id = 0x02,
111                 .dev_size = 0x13,                       /* 2^19 = 512KB */
112                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
113                 .max_buf_write_size = 0x0,
114                 .num_erase_regions = 4,
115                 .erase_region_info =
116                 {
117                         0x01000006,             /* 7x 64KB */
118                         0x00800000,             /* 1x 32KB */
119                         0x00200001,             /* 2x  8KB */
120                         0x00400000,             /* 1x 16KB */
121                         0x00000000
122                 }
123         },
124         {
125                 .mfr = CFI_MFR_AMD,
126                 .id = 0x22ab,                           /* AM29F400BB */
127                 .pri_id = 0x02,
128                 .dev_size = 0x13,                       /* 2^19 = 512KB */
129                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
130                 .max_buf_write_size = 0x0,
131                 .num_erase_regions = 4,
132                 .erase_region_info =
133                 {
134                         0x00400000,             /* 1x 16KB */
135                         0x00200001,             /* 2x  8KB */
136                         0x00800000,             /* 1x 32KB */
137                         0x01000006,             /* 7x 64KB */
138                         0x00000000
139                 }
140         },
141         {
142                 .mfr = CFI_MFR_AMD,
143                 .id = 0x2223,                           /* AM29F400BT */
144                 .pri_id = 0x02,
145                 .dev_size = 0x13,                       /* 2^19 = 512KB */
146                 .interface_desc = 0x2,          /* x8 or x16 device with nBYTE */
147                 .max_buf_write_size = 0x0,
148                 .num_erase_regions = 4,
149                 .erase_region_info =
150                 {
151                         0x01000006,             /* 7x 64KB */
152                         0x00800000,             /* 1x 32KB */
153                         0x00200001,             /* 2x  8KB */
154                         0x00400000,             /* 1x 16KB */
155                         0x00000000
156                 }
157         },
158         {
159                 .mfr = 0,
160                 .id = 0,
161         }
162 };
163
164 void cfi_fixup_non_cfi(flash_bank_t *bank, void *param)
165 {
166         cfi_flash_bank_t *cfi_info = bank->driver_priv;
167         non_cfi_t *non_cfi = non_cfi_flashes;
168         
169         while (non_cfi->mfr)
170         {
171                 if ((cfi_info->manufacturer == non_cfi->mfr)
172                         && (cfi_info->device_id == non_cfi->id))
173                 {
174                         break;
175                 }
176                 non_cfi++;
177         }
178         
179         cfi_info->not_cfi = 1;
180         
181         /* fill in defaults for non-critical data */
182         cfi_info->vcc_min = 0x0;
183         cfi_info->vcc_max = 0x0;
184         cfi_info->vpp_min = 0x0;
185         cfi_info->vpp_max = 0x0;
186         cfi_info->word_write_timeout_typ = 0x0;
187         cfi_info->buf_write_timeout_typ = 0x0;
188         cfi_info->block_erase_timeout_typ = 0x0;
189         cfi_info->chip_erase_timeout_typ = 0x0;
190         cfi_info->word_write_timeout_max = 0x0;
191         cfi_info->buf_write_timeout_max = 0x0;
192         cfi_info->block_erase_timeout_max = 0x0;
193         cfi_info->chip_erase_timeout_max = 0x0;
194         
195         cfi_info->qry[0] = 'Q';
196         cfi_info->qry[1] = 'R';
197         cfi_info->qry[2] = 'Y';
198         
199         cfi_info->pri_id = non_cfi->pri_id;
200         cfi_info->pri_addr = 0x0;
201         cfi_info->alt_id = 0x0;
202         cfi_info->alt_addr = 0x0;
203         cfi_info->alt_ext = NULL;
204         
205         cfi_info->interface_desc = non_cfi->interface_desc;
206         cfi_info->max_buf_write_size = non_cfi->max_buf_write_size;
207         cfi_info->num_erase_regions = non_cfi->num_erase_regions;
208         cfi_info->erase_region_info = non_cfi->erase_region_info;
209         
210         if (cfi_info->pri_id == 0x2)
211         {
212                 cfi_spansion_pri_ext_t *pri_ext = malloc(sizeof(cfi_spansion_pri_ext_t));
213
214                 pri_ext->pri[0] = 'P';
215                 pri_ext->pri[1] = 'R';
216                 pri_ext->pri[2] = 'I';
217                 
218                 pri_ext->major_version = '1';
219                 pri_ext->minor_version = '0';
220                 
221                 pri_ext->SiliconRevision = 0x0;
222                 pri_ext->EraseSuspend = 0x0;
223                 pri_ext->EraseSuspend = 0x0;
224                 pri_ext->BlkProt = 0x0;
225                 pri_ext->TmpBlkUnprotect = 0x0;
226                 pri_ext->BlkProtUnprot = 0x0;
227                 pri_ext->SimultaneousOps = 0x0;
228                 pri_ext->BurstMode = 0x0;
229                 pri_ext->PageMode = 0x0;
230                 pri_ext->VppMin = 0x0;
231                 pri_ext->VppMax = 0x0;
232                 pri_ext->TopBottom = 0x0;
233         
234                 pri_ext->_reversed_geometry = 0;
235                 
236                 cfi_info->pri_ext = pri_ext;
237         } else if ((cfi_info->pri_id == 0x1) || (cfi_info->pri_id == 0x3))
238         {
239                 ERROR("BUG: non-CFI flashes using the Intel commandset are not yet supported");
240                 exit(-1);
241         }
242 }
243