1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24#include "qemu/osdep.h"
25#include "qemu/units.h"
26#include "sysemu/block-backend.h"
27#include "hw/qdev-properties.h"
28#include "hw/qdev-properties-system.h"
29#include "hw/ssi/ssi.h"
30#include "migration/vmstate.h"
31#include "qemu/bitops.h"
32#include "qemu/log.h"
33#include "qemu/module.h"
34#include "qemu/error-report.h"
35#include "qapi/error.h"
36#include "trace.h"
37#include "qom/object.h"
38#include "m25p80_sfdp.h"
39
40
41#define MAX_3BYTES_SIZE 0x1000000
42#define SPI_NOR_MAX_ID_LEN 6
43
44
45enum spi_flash_option_flags {
46 ER_4K = BIT(0),
47 ER_32K = BIT(1),
48 EEPROM = BIT(2),
49 HAS_SR_TB = BIT(3),
50 HAS_SR_BP3_BIT6 = BIT(4),
51};
52
53typedef struct FlashPartInfo {
54 const char *part_name;
55
56
57
58
59
60 uint8_t id[SPI_NOR_MAX_ID_LEN];
61 uint8_t id_len;
62
63
64
65
66 uint32_t sector_size;
67 uint32_t n_sectors;
68 uint32_t page_size;
69 uint16_t flags;
70
71
72
73
74
75 uint8_t die_cnt;
76 uint8_t (*sfdp_read)(uint32_t sfdp_addr);
77} FlashPartInfo;
78
79
80
81#define INFO(_part_name, _jedec_id, _ext_id, _sector_size, _n_sectors, _flags)\
82 .part_name = _part_name,\
83 .id = {\
84 ((_jedec_id) >> 16) & 0xff,\
85 ((_jedec_id) >> 8) & 0xff,\
86 (_jedec_id) & 0xff,\
87 ((_ext_id) >> 8) & 0xff,\
88 (_ext_id) & 0xff,\
89 },\
90 .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))),\
91 .sector_size = (_sector_size),\
92 .n_sectors = (_n_sectors),\
93 .page_size = 256,\
94 .flags = (_flags),\
95 .die_cnt = 0
96
97#define INFO6(_part_name, _jedec_id, _ext_id, _sector_size, _n_sectors, _flags)\
98 .part_name = _part_name,\
99 .id = {\
100 ((_jedec_id) >> 16) & 0xff,\
101 ((_jedec_id) >> 8) & 0xff,\
102 (_jedec_id) & 0xff,\
103 ((_ext_id) >> 16) & 0xff,\
104 ((_ext_id) >> 8) & 0xff,\
105 (_ext_id) & 0xff,\
106 },\
107 .id_len = 6,\
108 .sector_size = (_sector_size),\
109 .n_sectors = (_n_sectors),\
110 .page_size = 256,\
111 .flags = (_flags),\
112 .die_cnt = 0
113
114#define INFO_STACKED(_part_name, _jedec_id, _ext_id, _sector_size, _n_sectors,\
115 _flags, _die_cnt)\
116 .part_name = _part_name,\
117 .id = {\
118 ((_jedec_id) >> 16) & 0xff,\
119 ((_jedec_id) >> 8) & 0xff,\
120 (_jedec_id) & 0xff,\
121 ((_ext_id) >> 8) & 0xff,\
122 (_ext_id) & 0xff,\
123 },\
124 .id_len = (!(_jedec_id) ? 0 : (3 + ((_ext_id) ? 2 : 0))),\
125 .sector_size = (_sector_size),\
126 .n_sectors = (_n_sectors),\
127 .page_size = 256,\
128 .flags = (_flags),\
129 .die_cnt = _die_cnt
130
131#define JEDEC_NUMONYX 0x20
132#define JEDEC_WINBOND 0xEF
133#define JEDEC_SPANSION 0x01
134
135
136#define VCFG_DUMMY 0x1
137#define VCFG_WRAP_SEQUENTIAL 0x2
138#define NVCFG_XIP_MODE_DISABLED (7 << 9)
139#define NVCFG_XIP_MODE_MASK (7 << 9)
140#define VCFG_XIP_MODE_DISABLED (1 << 3)
141#define CFG_DUMMY_CLK_LEN 4
142#define NVCFG_DUMMY_CLK_POS 12
143#define VCFG_DUMMY_CLK_POS 4
144#define EVCFG_OUT_DRIVER_STRENGTH_DEF 7
145#define EVCFG_VPP_ACCELERATOR (1 << 3)
146#define EVCFG_RESET_HOLD_ENABLED (1 << 4)
147#define NVCFG_DUAL_IO_MASK (1 << 2)
148#define EVCFG_DUAL_IO_DISABLED (1 << 6)
149#define NVCFG_QUAD_IO_MASK (1 << 3)
150#define EVCFG_QUAD_IO_DISABLED (1 << 7)
151#define NVCFG_4BYTE_ADDR_MASK (1 << 0)
152#define NVCFG_LOWER_SEGMENT_MASK (1 << 1)
153
154
155#define FSR_4BYTE_ADDR_MODE_ENABLED 0x1
156#define FSR_FLASH_READY (1 << 7)
157
158
159#define SPANSION_QUAD_CFG_POS 0
160#define SPANSION_QUAD_CFG_LEN 1
161#define SPANSION_DUMMY_CLK_POS 0
162#define SPANSION_DUMMY_CLK_LEN 4
163#define SPANSION_ADDR_LEN_POS 7
164#define SPANSION_ADDR_LEN_LEN 1
165
166
167
168
169
170
171#define SPANSION_CONTINUOUS_READ_MODE_CMD_LEN 1
172#define WINBOND_CONTINUOUS_READ_MODE_CMD_LEN 1
173
174static const FlashPartInfo known_devices[] = {
175
176 { INFO("at25fs010", 0x1f6601, 0, 32 << 10, 4, ER_4K) },
177 { INFO("at25fs040", 0x1f6604, 0, 64 << 10, 8, ER_4K) },
178
179 { INFO("at25df041a", 0x1f4401, 0, 64 << 10, 8, ER_4K) },
180 { INFO("at25df321a", 0x1f4701, 0, 64 << 10, 64, ER_4K) },
181 { INFO("at25df641", 0x1f4800, 0, 64 << 10, 128, ER_4K) },
182
183 { INFO("at26f004", 0x1f0400, 0, 64 << 10, 8, ER_4K) },
184 { INFO("at26df081a", 0x1f4501, 0, 64 << 10, 16, ER_4K) },
185 { INFO("at26df161a", 0x1f4601, 0, 64 << 10, 32, ER_4K) },
186 { INFO("at26df321", 0x1f4700, 0, 64 << 10, 64, ER_4K) },
187
188 { INFO("at45db081d", 0x1f2500, 0, 64 << 10, 16, ER_4K) },
189
190
191
192
193 { INFO("at25128a-nonjedec", 0x0, 0, 1, 131072, EEPROM) },
194 { INFO("at25256a-nonjedec", 0x0, 0, 1, 262144, EEPROM) },
195
196
197 { INFO("en25f32", 0x1c3116, 0, 64 << 10, 64, ER_4K) },
198 { INFO("en25p32", 0x1c2016, 0, 64 << 10, 64, 0) },
199 { INFO("en25q32b", 0x1c3016, 0, 64 << 10, 64, 0) },
200 { INFO("en25p64", 0x1c2017, 0, 64 << 10, 128, 0) },
201 { INFO("en25q64", 0x1c3017, 0, 64 << 10, 128, ER_4K) },
202
203
204 { INFO("gd25q32", 0xc84016, 0, 64 << 10, 64, ER_4K) },
205 { INFO("gd25q64", 0xc84017, 0, 64 << 10, 128, ER_4K) },
206
207
208 { INFO("160s33b", 0x898911, 0, 64 << 10, 32, 0) },
209 { INFO("320s33b", 0x898912, 0, 64 << 10, 64, 0) },
210 { INFO("640s33b", 0x898913, 0, 64 << 10, 128, 0) },
211 { INFO("n25q064", 0x20ba17, 0, 64 << 10, 128, 0) },
212
213
214 { INFO("is25lq040b", 0x9d4013, 0, 64 << 10, 8, ER_4K) },
215 { INFO("is25lp080d", 0x9d6014, 0, 64 << 10, 16, ER_4K) },
216 { INFO("is25lp016d", 0x9d6015, 0, 64 << 10, 32, ER_4K) },
217 { INFO("is25lp032", 0x9d6016, 0, 64 << 10, 64, ER_4K) },
218 { INFO("is25lp064", 0x9d6017, 0, 64 << 10, 128, ER_4K) },
219 { INFO("is25lp128", 0x9d6018, 0, 64 << 10, 256, ER_4K) },
220 { INFO("is25lp256", 0x9d6019, 0, 64 << 10, 512, ER_4K) },
221 { INFO("is25wp032", 0x9d7016, 0, 64 << 10, 64, ER_4K) },
222 { INFO("is25wp064", 0x9d7017, 0, 64 << 10, 128, ER_4K) },
223 { INFO("is25wp128", 0x9d7018, 0, 64 << 10, 256, ER_4K) },
224 { INFO("is25wp256", 0x9d7019, 0, 64 << 10, 512, ER_4K) },
225
226
227 { INFO("mx25l2005a", 0xc22012, 0, 64 << 10, 4, ER_4K) },
228 { INFO("mx25l4005a", 0xc22013, 0, 64 << 10, 8, ER_4K) },
229 { INFO("mx25l8005", 0xc22014, 0, 64 << 10, 16, 0) },
230 { INFO("mx25l1606e", 0xc22015, 0, 64 << 10, 32, ER_4K) },
231 { INFO("mx25l3205d", 0xc22016, 0, 64 << 10, 64, 0) },
232 { INFO("mx25l6405d", 0xc22017, 0, 64 << 10, 128, 0) },
233 { INFO("mx25l12805d", 0xc22018, 0, 64 << 10, 256, 0) },
234 { INFO("mx25l12855e", 0xc22618, 0, 64 << 10, 256, 0) },
235 { INFO6("mx25l25635e", 0xc22019, 0xc22019, 64 << 10, 512,
236 ER_4K | ER_32K), .sfdp_read = m25p80_sfdp_mx25l25635e },
237 { INFO6("mx25l25635f", 0xc22019, 0xc22019, 64 << 10, 512,
238 ER_4K | ER_32K), .sfdp_read = m25p80_sfdp_mx25l25635f },
239 { INFO("mx25l25655e", 0xc22619, 0, 64 << 10, 512, 0) },
240 { INFO("mx66l51235f", 0xc2201a, 0, 64 << 10, 1024, ER_4K | ER_32K) },
241 { INFO("mx66u51235f", 0xc2253a, 0, 64 << 10, 1024, ER_4K | ER_32K) },
242 { INFO("mx66u1g45g", 0xc2253b, 0, 64 << 10, 2048, ER_4K | ER_32K) },
243 { INFO("mx66l1g45g", 0xc2201b, 0, 64 << 10, 2048, ER_4K | ER_32K),
244 .sfdp_read = m25p80_sfdp_mx66l1g45g },
245
246
247 { INFO("n25q032a11", 0x20bb16, 0, 64 << 10, 64, ER_4K) },
248 { INFO("n25q032a13", 0x20ba16, 0, 64 << 10, 64, ER_4K) },
249 { INFO("n25q064a11", 0x20bb17, 0, 64 << 10, 128, ER_4K) },
250 { INFO("n25q064a13", 0x20ba17, 0, 64 << 10, 128, ER_4K) },
251 { INFO("n25q128a11", 0x20bb18, 0, 64 << 10, 256, ER_4K) },
252 { INFO("n25q128a13", 0x20ba18, 0, 64 << 10, 256, ER_4K) },
253 { INFO("n25q256a11", 0x20bb19, 0, 64 << 10, 512, ER_4K) },
254 { INFO("n25q256a13", 0x20ba19, 0, 64 << 10, 512, ER_4K),
255 .sfdp_read = m25p80_sfdp_n25q256a },
256 { INFO("n25q512a11", 0x20bb20, 0, 64 << 10, 1024, ER_4K) },
257 { INFO("n25q512a13", 0x20ba20, 0, 64 << 10, 1024, ER_4K) },
258 { INFO("n25q128", 0x20ba18, 0, 64 << 10, 256, 0) },
259 { INFO("n25q256a", 0x20ba19, 0, 64 << 10, 512,
260 ER_4K | HAS_SR_BP3_BIT6 | HAS_SR_TB),
261 .sfdp_read = m25p80_sfdp_n25q256a },
262 { INFO("n25q512a", 0x20ba20, 0, 64 << 10, 1024, ER_4K) },
263 { INFO("n25q512ax3", 0x20ba20, 0x1000, 64 << 10, 1024, ER_4K) },
264 { INFO("mt25ql512ab", 0x20ba20, 0x1044, 64 << 10, 1024, ER_4K | ER_32K) },
265 { INFO_STACKED("mt35xu01g", 0x2c5b1b, 0x104100, 128 << 10, 1024,
266 ER_4K | ER_32K, 2) },
267 { INFO_STACKED("n25q00", 0x20ba21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
268 { INFO_STACKED("n25q00a", 0x20bb21, 0x1000, 64 << 10, 2048, ER_4K, 4) },
269 { INFO_STACKED("mt25ql01g", 0x20ba21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
270 { INFO_STACKED("mt25qu01g", 0x20bb21, 0x1040, 64 << 10, 2048, ER_4K, 2) },
271 { INFO_STACKED("mt25ql02g", 0x20ba22, 0x1040, 64 << 10, 4096, ER_4K | ER_32K, 2) },
272 { INFO_STACKED("mt25qu02g", 0x20bb22, 0x1040, 64 << 10, 4096, ER_4K | ER_32K, 2) },
273
274
275
276
277 { INFO("s25sl032p", 0x010215, 0x4d00, 64 << 10, 64, ER_4K) },
278 { INFO("s25sl064p", 0x010216, 0x4d00, 64 << 10, 128, ER_4K) },
279 { INFO("s25fl256s0", 0x010219, 0x4d00, 256 << 10, 128, 0) },
280 { INFO("s25fl256s1", 0x010219, 0x4d01, 64 << 10, 512, 0) },
281 { INFO6("s25fl512s", 0x010220, 0x4d0080, 256 << 10, 256, 0) },
282 { INFO6("s70fl01gs", 0x010221, 0x4d0080, 256 << 10, 512, 0) },
283 { INFO("s25sl12800", 0x012018, 0x0300, 256 << 10, 64, 0) },
284 { INFO("s25sl12801", 0x012018, 0x0301, 64 << 10, 256, 0) },
285 { INFO("s25fl129p0", 0x012018, 0x4d00, 256 << 10, 64, 0) },
286 { INFO("s25fl129p1", 0x012018, 0x4d01, 64 << 10, 256, 0) },
287 { INFO("s25sl004a", 0x010212, 0, 64 << 10, 8, 0) },
288 { INFO("s25sl008a", 0x010213, 0, 64 << 10, 16, 0) },
289 { INFO("s25sl016a", 0x010214, 0, 64 << 10, 32, 0) },
290 { INFO("s25sl032a", 0x010215, 0, 64 << 10, 64, 0) },
291 { INFO("s25sl064a", 0x010216, 0, 64 << 10, 128, 0) },
292 { INFO("s25fl016k", 0xef4015, 0, 64 << 10, 32, ER_4K | ER_32K) },
293 { INFO("s25fl064k", 0xef4017, 0, 64 << 10, 128, ER_4K | ER_32K) },
294
295
296 { INFO6("s25fs512s", 0x010220, 0x4d0081, 256 << 10, 256, 0) },
297 { INFO6("s70fs01gs", 0x010221, 0x4d0081, 256 << 10, 512, 0) },
298
299
300 { INFO("sst25vf040b", 0xbf258d, 0, 64 << 10, 8, ER_4K) },
301 { INFO("sst25vf080b", 0xbf258e, 0, 64 << 10, 16, ER_4K) },
302 { INFO("sst25vf016b", 0xbf2541, 0, 64 << 10, 32, ER_4K) },
303 { INFO("sst25vf032b", 0xbf254a, 0, 64 << 10, 64, ER_4K) },
304 { INFO("sst25wf512", 0xbf2501, 0, 64 << 10, 1, ER_4K) },
305 { INFO("sst25wf010", 0xbf2502, 0, 64 << 10, 2, ER_4K) },
306 { INFO("sst25wf020", 0xbf2503, 0, 64 << 10, 4, ER_4K) },
307 { INFO("sst25wf040", 0xbf2504, 0, 64 << 10, 8, ER_4K) },
308 { INFO("sst25wf080", 0xbf2505, 0, 64 << 10, 16, ER_4K) },
309
310
311 { INFO("m25p05", 0x202010, 0, 32 << 10, 2, 0) },
312 { INFO("m25p10", 0x202011, 0, 32 << 10, 4, 0) },
313 { INFO("m25p20", 0x202012, 0, 64 << 10, 4, 0) },
314 { INFO("m25p40", 0x202013, 0, 64 << 10, 8, 0) },
315 { INFO("m25p80", 0x202014, 0, 64 << 10, 16, 0) },
316 { INFO("m25p16", 0x202015, 0, 64 << 10, 32, 0) },
317 { INFO("m25p32", 0x202016, 0, 64 << 10, 64, 0) },
318 { INFO("m25p64", 0x202017, 0, 64 << 10, 128, 0) },
319 { INFO("m25p128", 0x202018, 0, 256 << 10, 64, 0) },
320 { INFO("n25q032", 0x20ba16, 0, 64 << 10, 64, 0) },
321
322 { INFO("m45pe10", 0x204011, 0, 64 << 10, 2, 0) },
323 { INFO("m45pe80", 0x204014, 0, 64 << 10, 16, 0) },
324 { INFO("m45pe16", 0x204015, 0, 64 << 10, 32, 0) },
325
326 { INFO("m25pe20", 0x208012, 0, 64 << 10, 4, 0) },
327 { INFO("m25pe80", 0x208014, 0, 64 << 10, 16, 0) },
328 { INFO("m25pe16", 0x208015, 0, 64 << 10, 32, ER_4K) },
329
330 { INFO("m25px32", 0x207116, 0, 64 << 10, 64, ER_4K) },
331 { INFO("m25px32-s0", 0x207316, 0, 64 << 10, 64, ER_4K) },
332 { INFO("m25px32-s1", 0x206316, 0, 64 << 10, 64, ER_4K) },
333 { INFO("m25px64", 0x207117, 0, 64 << 10, 128, 0) },
334
335
336 { INFO("w25x10", 0xef3011, 0, 64 << 10, 2, ER_4K) },
337 { INFO("w25x20", 0xef3012, 0, 64 << 10, 4, ER_4K) },
338 { INFO("w25x40", 0xef3013, 0, 64 << 10, 8, ER_4K) },
339 { INFO("w25x80", 0xef3014, 0, 64 << 10, 16, ER_4K) },
340 { INFO("w25x16", 0xef3015, 0, 64 << 10, 32, ER_4K) },
341 { INFO("w25x32", 0xef3016, 0, 64 << 10, 64, ER_4K) },
342 { INFO("w25q32", 0xef4016, 0, 64 << 10, 64, ER_4K) },
343 { INFO("w25q32dw", 0xef6016, 0, 64 << 10, 64, ER_4K) },
344 { INFO("w25x64", 0xef3017, 0, 64 << 10, 128, ER_4K) },
345 { INFO("w25q64", 0xef4017, 0, 64 << 10, 128, ER_4K) },
346 { INFO("w25q80", 0xef5014, 0, 64 << 10, 16, ER_4K) },
347 { INFO("w25q80bl", 0xef4014, 0, 64 << 10, 16, ER_4K) },
348 { INFO("w25q256", 0xef4019, 0, 64 << 10, 512, ER_4K),
349 .sfdp_read = m25p80_sfdp_w25q256 },
350 { INFO("w25q512jv", 0xef4020, 0, 64 << 10, 1024, ER_4K),
351 .sfdp_read = m25p80_sfdp_w25q512jv },
352 { INFO("w25q01jvq", 0xef4021, 0, 64 << 10, 2048, ER_4K),
353 .sfdp_read = m25p80_sfdp_w25q01jvq },
354};
355
356typedef enum {
357 NOP = 0,
358 WRSR = 0x1,
359 WRDI = 0x4,
360 RDSR = 0x5,
361 WREN = 0x6,
362 BRRD = 0x16,
363 BRWR = 0x17,
364 JEDEC_READ = 0x9f,
365 BULK_ERASE_60 = 0x60,
366 BULK_ERASE = 0xc7,
367 READ_FSR = 0x70,
368 RDCR = 0x15,
369 RDSFDP = 0x5a,
370
371 READ = 0x03,
372 READ4 = 0x13,
373 FAST_READ = 0x0b,
374 FAST_READ4 = 0x0c,
375 DOR = 0x3b,
376 DOR4 = 0x3c,
377 QOR = 0x6b,
378 QOR4 = 0x6c,
379 DIOR = 0xbb,
380 DIOR4 = 0xbc,
381 QIOR = 0xeb,
382 QIOR4 = 0xec,
383
384 PP = 0x02,
385 PP4 = 0x12,
386 PP4_4 = 0x3e,
387 DPP = 0xa2,
388 QPP = 0x32,
389 QPP_4 = 0x34,
390 RDID_90 = 0x90,
391 RDID_AB = 0xab,
392 AAI_WP = 0xad,
393
394 ERASE_4K = 0x20,
395 ERASE4_4K = 0x21,
396 ERASE_32K = 0x52,
397 ERASE4_32K = 0x5c,
398 ERASE_SECTOR = 0xd8,
399 ERASE4_SECTOR = 0xdc,
400
401 EN_4BYTE_ADDR = 0xB7,
402 EX_4BYTE_ADDR = 0xE9,
403
404 EXTEND_ADDR_READ = 0xC8,
405 EXTEND_ADDR_WRITE = 0xC5,
406
407 RESET_ENABLE = 0x66,
408 RESET_MEMORY = 0x99,
409
410
411
412
413
414 RDCR_EQIO = 0x35,
415 RSTQIO = 0xf5,
416
417 RNVCR = 0xB5,
418 WNVCR = 0xB1,
419
420 RVCR = 0x85,
421 WVCR = 0x81,
422
423 REVCR = 0x65,
424 WEVCR = 0x61,
425
426 DIE_ERASE = 0xC4,
427} FlashCMD;
428
429typedef enum {
430 STATE_IDLE,
431 STATE_PAGE_PROGRAM,
432 STATE_READ,
433 STATE_COLLECTING_DATA,
434 STATE_COLLECTING_VAR_LEN_DATA,
435 STATE_READING_DATA,
436 STATE_READING_SFDP,
437} CMDState;
438
439typedef enum {
440 MAN_SPANSION,
441 MAN_MACRONIX,
442 MAN_NUMONYX,
443 MAN_WINBOND,
444 MAN_SST,
445 MAN_ISSI,
446 MAN_GENERIC,
447} Manufacturer;
448
449typedef enum {
450 MODE_STD = 0,
451 MODE_DIO = 1,
452 MODE_QIO = 2
453} SPIMode;
454
455#define M25P80_INTERNAL_DATA_BUFFER_SZ 16
456
457struct Flash {
458 SSIPeripheral parent_obj;
459
460 BlockBackend *blk;
461
462 uint8_t *storage;
463 uint32_t size;
464 int page_size;
465
466 uint8_t state;
467 uint8_t data[M25P80_INTERNAL_DATA_BUFFER_SZ];
468 uint32_t len;
469 uint32_t pos;
470 bool data_read_loop;
471 uint8_t needed_bytes;
472 uint8_t cmd_in_progress;
473 uint32_t cur_addr;
474 uint32_t nonvolatile_cfg;
475
476 uint32_t volatile_cfg;
477 uint32_t enh_volatile_cfg;
478
479 uint8_t spansion_cr1nv;
480 uint8_t spansion_cr2nv;
481 uint8_t spansion_cr3nv;
482 uint8_t spansion_cr4nv;
483 uint8_t spansion_cr1v;
484 uint8_t spansion_cr2v;
485 uint8_t spansion_cr3v;
486 uint8_t spansion_cr4v;
487 bool wp_level;
488 bool write_enable;
489 bool four_bytes_address_mode;
490 bool reset_enable;
491 bool quad_enable;
492 bool aai_enable;
493 bool block_protect0;
494 bool block_protect1;
495 bool block_protect2;
496 bool block_protect3;
497 bool top_bottom_bit;
498 bool status_register_write_disabled;
499 uint8_t ear;
500
501 int64_t dirty_page;
502
503 const FlashPartInfo *pi;
504
505};
506
507struct M25P80Class {
508 SSIPeripheralClass parent_class;
509 FlashPartInfo *pi;
510};
511
512#define TYPE_M25P80 "m25p80-generic"
513OBJECT_DECLARE_TYPE(Flash, M25P80Class, M25P80)
514
515static inline Manufacturer get_man(Flash *s)
516{
517 switch (s->pi->id[0]) {
518 case 0x20:
519 return MAN_NUMONYX;
520 case 0xEF:
521 return MAN_WINBOND;
522 case 0x01:
523 return MAN_SPANSION;
524 case 0xC2:
525 return MAN_MACRONIX;
526 case 0xBF:
527 return MAN_SST;
528 case 0x9D:
529 return MAN_ISSI;
530 default:
531 return MAN_GENERIC;
532 }
533}
534
535static void blk_sync_complete(void *opaque, int ret)
536{
537 QEMUIOVector *iov = opaque;
538
539 qemu_iovec_destroy(iov);
540 g_free(iov);
541
542
543
544
545}
546
547static void flash_sync_page(Flash *s, int page)
548{
549 QEMUIOVector *iov;
550
551 if (!s->blk || !blk_is_writable(s->blk)) {
552 return;
553 }
554
555 iov = g_new(QEMUIOVector, 1);
556 qemu_iovec_init(iov, 1);
557 qemu_iovec_add(iov, s->storage + page * s->pi->page_size,
558 s->pi->page_size);
559 blk_aio_pwritev(s->blk, page * s->pi->page_size, iov, 0,
560 blk_sync_complete, iov);
561}
562
563static inline void flash_sync_area(Flash *s, int64_t off, int64_t len)
564{
565 QEMUIOVector *iov;
566
567 if (!s->blk || !blk_is_writable(s->blk)) {
568 return;
569 }
570
571 assert(!(len % BDRV_SECTOR_SIZE));
572 iov = g_new(QEMUIOVector, 1);
573 qemu_iovec_init(iov, 1);
574 qemu_iovec_add(iov, s->storage + off, len);
575 blk_aio_pwritev(s->blk, off, iov, 0, blk_sync_complete, iov);
576}
577
578static void flash_erase(Flash *s, int offset, FlashCMD cmd)
579{
580 uint32_t len;
581 uint8_t capa_to_assert = 0;
582
583 switch (cmd) {
584 case ERASE_4K:
585 case ERASE4_4K:
586 len = 4 * KiB;
587 capa_to_assert = ER_4K;
588 break;
589 case ERASE_32K:
590 case ERASE4_32K:
591 len = 32 * KiB;
592 capa_to_assert = ER_32K;
593 break;
594 case ERASE_SECTOR:
595 case ERASE4_SECTOR:
596 len = s->pi->sector_size;
597 break;
598 case BULK_ERASE:
599 len = s->size;
600 break;
601 case DIE_ERASE:
602 if (s->pi->die_cnt) {
603 len = s->size / s->pi->die_cnt;
604 offset = offset & (~(len - 1));
605 } else {
606 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: die erase is not supported"
607 " by device\n");
608 return;
609 }
610 break;
611 default:
612 abort();
613 }
614
615 trace_m25p80_flash_erase(s, offset, len);
616
617 if ((s->pi->flags & capa_to_assert) != capa_to_assert) {
618 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: %d erase size not supported by"
619 " device\n", len);
620 }
621
622 if (!s->write_enable) {
623 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: erase with write protect!\n");
624 return;
625 }
626 memset(s->storage + offset, 0xff, len);
627 flash_sync_area(s, offset, len);
628}
629
630static inline void flash_sync_dirty(Flash *s, int64_t newpage)
631{
632 if (s->dirty_page >= 0 && s->dirty_page != newpage) {
633 flash_sync_page(s, s->dirty_page);
634 s->dirty_page = newpage;
635 }
636}
637
638static inline
639void flash_write8(Flash *s, uint32_t addr, uint8_t data)
640{
641 uint32_t page = addr / s->pi->page_size;
642 uint8_t prev = s->storage[s->cur_addr];
643 uint32_t block_protect_value = (s->block_protect3 << 3) |
644 (s->block_protect2 << 2) |
645 (s->block_protect1 << 1) |
646 (s->block_protect0 << 0);
647
648 if (!s->write_enable) {
649 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: write with write protect!\n");
650 return;
651 }
652
653 if (block_protect_value > 0) {
654 uint32_t num_protected_sectors = 1 << (block_protect_value - 1);
655 uint32_t sector = addr / s->pi->sector_size;
656
657
658 if (!s->top_bottom_bit) {
659 if (s->pi->n_sectors <= sector + num_protected_sectors) {
660 qemu_log_mask(LOG_GUEST_ERROR,
661 "M25P80: write with write protect!\n");
662 return;
663 }
664 } else {
665 if (sector < num_protected_sectors) {
666 qemu_log_mask(LOG_GUEST_ERROR,
667 "M25P80: write with write protect!\n");
668 return;
669 }
670 }
671 }
672
673 if ((prev ^ data) & data) {
674 trace_m25p80_programming_zero_to_one(s, addr, prev, data);
675 }
676
677 if (s->pi->flags & EEPROM) {
678 s->storage[s->cur_addr] = data;
679 } else {
680 s->storage[s->cur_addr] &= data;
681 }
682
683 flash_sync_dirty(s, page);
684 s->dirty_page = page;
685}
686
687static inline int get_addr_length(Flash *s)
688{
689
690 if (s->pi->flags == EEPROM) {
691 return 2;
692 }
693
694 switch (s->cmd_in_progress) {
695 case RDSFDP:
696 return 3;
697 case PP4:
698 case PP4_4:
699 case QPP_4:
700 case READ4:
701 case QIOR4:
702 case ERASE4_4K:
703 case ERASE4_32K:
704 case ERASE4_SECTOR:
705 case FAST_READ4:
706 case DOR4:
707 case QOR4:
708 case DIOR4:
709 return 4;
710 default:
711 return s->four_bytes_address_mode ? 4 : 3;
712 }
713}
714
715static void complete_collecting_data(Flash *s)
716{
717 int i, n;
718
719 n = get_addr_length(s);
720 s->cur_addr = (n == 3 ? s->ear : 0);
721 for (i = 0; i < n; ++i) {
722 s->cur_addr <<= 8;
723 s->cur_addr |= s->data[i];
724 }
725
726 s->cur_addr &= s->size - 1;
727
728 s->state = STATE_IDLE;
729
730 trace_m25p80_complete_collecting(s, s->cmd_in_progress, n, s->ear,
731 s->cur_addr);
732
733 switch (s->cmd_in_progress) {
734 case DPP:
735 case QPP:
736 case QPP_4:
737 case PP:
738 case PP4:
739 case PP4_4:
740 s->state = STATE_PAGE_PROGRAM;
741 break;
742 case AAI_WP:
743
744 s->cur_addr &= ~BIT(0);
745 s->state = STATE_PAGE_PROGRAM;
746 break;
747 case READ:
748 case READ4:
749 case FAST_READ:
750 case FAST_READ4:
751 case DOR:
752 case DOR4:
753 case QOR:
754 case QOR4:
755 case DIOR:
756 case DIOR4:
757 case QIOR:
758 case QIOR4:
759 s->state = STATE_READ;
760 break;
761 case ERASE_4K:
762 case ERASE4_4K:
763 case ERASE_32K:
764 case ERASE4_32K:
765 case ERASE_SECTOR:
766 case ERASE4_SECTOR:
767 case DIE_ERASE:
768 flash_erase(s, s->cur_addr, s->cmd_in_progress);
769 break;
770 case WRSR:
771 s->status_register_write_disabled = extract32(s->data[0], 7, 1);
772 s->block_protect0 = extract32(s->data[0], 2, 1);
773 s->block_protect1 = extract32(s->data[0], 3, 1);
774 s->block_protect2 = extract32(s->data[0], 4, 1);
775 if (s->pi->flags & HAS_SR_TB) {
776 s->top_bottom_bit = extract32(s->data[0], 5, 1);
777 }
778 if (s->pi->flags & HAS_SR_BP3_BIT6) {
779 s->block_protect3 = extract32(s->data[0], 6, 1);
780 }
781
782 switch (get_man(s)) {
783 case MAN_SPANSION:
784 s->quad_enable = !!(s->data[1] & 0x02);
785 break;
786 case MAN_ISSI:
787 s->quad_enable = extract32(s->data[0], 6, 1);
788 break;
789 case MAN_MACRONIX:
790 s->quad_enable = extract32(s->data[0], 6, 1);
791 if (s->len > 1) {
792 s->volatile_cfg = s->data[1];
793 s->four_bytes_address_mode = extract32(s->data[1], 5, 1);
794 }
795 break;
796 default:
797 break;
798 }
799 if (s->write_enable) {
800 s->write_enable = false;
801 }
802 break;
803 case BRWR:
804 case EXTEND_ADDR_WRITE:
805 s->ear = s->data[0];
806 break;
807 case WNVCR:
808 s->nonvolatile_cfg = s->data[0] | (s->data[1] << 8);
809 break;
810 case WVCR:
811 s->volatile_cfg = s->data[0];
812 break;
813 case WEVCR:
814 s->enh_volatile_cfg = s->data[0];
815 break;
816 case RDID_90:
817 case RDID_AB:
818 if (get_man(s) == MAN_SST) {
819 if (s->cur_addr <= 1) {
820 if (s->cur_addr) {
821 s->data[0] = s->pi->id[2];
822 s->data[1] = s->pi->id[0];
823 } else {
824 s->data[0] = s->pi->id[0];
825 s->data[1] = s->pi->id[2];
826 }
827 s->pos = 0;
828 s->len = 2;
829 s->data_read_loop = true;
830 s->state = STATE_READING_DATA;
831 } else {
832 qemu_log_mask(LOG_GUEST_ERROR,
833 "M25P80: Invalid read id address\n");
834 }
835 } else {
836 qemu_log_mask(LOG_GUEST_ERROR,
837 "M25P80: Read id (command 0x90/0xAB) is not supported"
838 " by device\n");
839 }
840 break;
841
842 case RDSFDP:
843 s->state = STATE_READING_SFDP;
844 break;
845
846 default:
847 break;
848 }
849}
850
851static void reset_memory(Flash *s)
852{
853 s->cmd_in_progress = NOP;
854 s->cur_addr = 0;
855 s->ear = 0;
856 s->four_bytes_address_mode = false;
857 s->len = 0;
858 s->needed_bytes = 0;
859 s->pos = 0;
860 s->state = STATE_IDLE;
861 s->write_enable = false;
862 s->reset_enable = false;
863 s->quad_enable = false;
864 s->aai_enable = false;
865
866 switch (get_man(s)) {
867 case MAN_NUMONYX:
868 s->volatile_cfg = 0;
869 s->volatile_cfg |= VCFG_DUMMY;
870 s->volatile_cfg |= VCFG_WRAP_SEQUENTIAL;
871 if ((s->nonvolatile_cfg & NVCFG_XIP_MODE_MASK)
872 == NVCFG_XIP_MODE_DISABLED) {
873 s->volatile_cfg |= VCFG_XIP_MODE_DISABLED;
874 }
875 s->volatile_cfg |= deposit32(s->volatile_cfg,
876 VCFG_DUMMY_CLK_POS,
877 CFG_DUMMY_CLK_LEN,
878 extract32(s->nonvolatile_cfg,
879 NVCFG_DUMMY_CLK_POS,
880 CFG_DUMMY_CLK_LEN)
881 );
882
883 s->enh_volatile_cfg = 0;
884 s->enh_volatile_cfg |= EVCFG_OUT_DRIVER_STRENGTH_DEF;
885 s->enh_volatile_cfg |= EVCFG_VPP_ACCELERATOR;
886 s->enh_volatile_cfg |= EVCFG_RESET_HOLD_ENABLED;
887 if (s->nonvolatile_cfg & NVCFG_DUAL_IO_MASK) {
888 s->enh_volatile_cfg |= EVCFG_DUAL_IO_DISABLED;
889 }
890 if (s->nonvolatile_cfg & NVCFG_QUAD_IO_MASK) {
891 s->enh_volatile_cfg |= EVCFG_QUAD_IO_DISABLED;
892 }
893 if (!(s->nonvolatile_cfg & NVCFG_4BYTE_ADDR_MASK)) {
894 s->four_bytes_address_mode = true;
895 }
896 if (!(s->nonvolatile_cfg & NVCFG_LOWER_SEGMENT_MASK)) {
897 s->ear = s->size / MAX_3BYTES_SIZE - 1;
898 }
899 break;
900 case MAN_MACRONIX:
901 s->volatile_cfg = 0x7;
902 break;
903 case MAN_SPANSION:
904 s->spansion_cr1v = s->spansion_cr1nv;
905 s->spansion_cr2v = s->spansion_cr2nv;
906 s->spansion_cr3v = s->spansion_cr3nv;
907 s->spansion_cr4v = s->spansion_cr4nv;
908 s->quad_enable = extract32(s->spansion_cr1v,
909 SPANSION_QUAD_CFG_POS,
910 SPANSION_QUAD_CFG_LEN
911 );
912 s->four_bytes_address_mode = extract32(s->spansion_cr2v,
913 SPANSION_ADDR_LEN_POS,
914 SPANSION_ADDR_LEN_LEN
915 );
916 break;
917 default:
918 break;
919 }
920
921 trace_m25p80_reset_done(s);
922}
923
924static uint8_t numonyx_mode(Flash *s)
925{
926 if (!(s->enh_volatile_cfg & EVCFG_QUAD_IO_DISABLED)) {
927 return MODE_QIO;
928 } else if (!(s->enh_volatile_cfg & EVCFG_DUAL_IO_DISABLED)) {
929 return MODE_DIO;
930 } else {
931 return MODE_STD;
932 }
933}
934
935static uint8_t numonyx_extract_cfg_num_dummies(Flash *s)
936{
937 uint8_t num_dummies;
938 uint8_t mode;
939 assert(get_man(s) == MAN_NUMONYX);
940
941 mode = numonyx_mode(s);
942 num_dummies = extract32(s->volatile_cfg, 4, 4);
943
944 if (num_dummies == 0x0 || num_dummies == 0xf) {
945 switch (s->cmd_in_progress) {
946 case QIOR:
947 case QIOR4:
948 num_dummies = 10;
949 break;
950 default:
951 num_dummies = (mode == MODE_QIO) ? 10 : 8;
952 break;
953 }
954 }
955
956 return num_dummies;
957}
958
959static void decode_fast_read_cmd(Flash *s)
960{
961 s->needed_bytes = get_addr_length(s);
962 switch (get_man(s)) {
963
964 case MAN_SST:
965 s->needed_bytes += 1;
966 break;
967 case MAN_WINBOND:
968 s->needed_bytes += 8;
969 break;
970 case MAN_NUMONYX:
971 s->needed_bytes += numonyx_extract_cfg_num_dummies(s);
972 break;
973 case MAN_MACRONIX:
974 if (extract32(s->volatile_cfg, 6, 2) == 1) {
975 s->needed_bytes += 6;
976 } else {
977 s->needed_bytes += 8;
978 }
979 break;
980 case MAN_SPANSION:
981 s->needed_bytes += extract32(s->spansion_cr2v,
982 SPANSION_DUMMY_CLK_POS,
983 SPANSION_DUMMY_CLK_LEN
984 );
985 break;
986 case MAN_ISSI:
987
988
989
990
991
992
993
994
995
996
997 s->needed_bytes += 1;
998 break;
999 default:
1000 break;
1001 }
1002 s->pos = 0;
1003 s->len = 0;
1004 s->state = STATE_COLLECTING_DATA;
1005}
1006
1007static void decode_dio_read_cmd(Flash *s)
1008{
1009 s->needed_bytes = get_addr_length(s);
1010
1011 switch (get_man(s)) {
1012 case MAN_WINBOND:
1013 s->needed_bytes += WINBOND_CONTINUOUS_READ_MODE_CMD_LEN;
1014 break;
1015 case MAN_SPANSION:
1016 s->needed_bytes += SPANSION_CONTINUOUS_READ_MODE_CMD_LEN;
1017 s->needed_bytes += extract32(s->spansion_cr2v,
1018 SPANSION_DUMMY_CLK_POS,
1019 SPANSION_DUMMY_CLK_LEN
1020 );
1021 break;
1022 case MAN_NUMONYX:
1023 s->needed_bytes += numonyx_extract_cfg_num_dummies(s);
1024 break;
1025 case MAN_MACRONIX:
1026 switch (extract32(s->volatile_cfg, 6, 2)) {
1027 case 1:
1028 s->needed_bytes += 6;
1029 break;
1030 case 2:
1031 s->needed_bytes += 8;
1032 break;
1033 default:
1034 s->needed_bytes += 4;
1035 break;
1036 }
1037 break;
1038 case MAN_ISSI:
1039
1040
1041
1042
1043
1044
1045
1046 s->needed_bytes += 1;
1047 break;
1048 default:
1049 break;
1050 }
1051 s->pos = 0;
1052 s->len = 0;
1053 s->state = STATE_COLLECTING_DATA;
1054}
1055
1056static void decode_qio_read_cmd(Flash *s)
1057{
1058 s->needed_bytes = get_addr_length(s);
1059
1060 switch (get_man(s)) {
1061 case MAN_WINBOND:
1062 s->needed_bytes += WINBOND_CONTINUOUS_READ_MODE_CMD_LEN;
1063 s->needed_bytes += 4;
1064 break;
1065 case MAN_SPANSION:
1066 s->needed_bytes += SPANSION_CONTINUOUS_READ_MODE_CMD_LEN;
1067 s->needed_bytes += extract32(s->spansion_cr2v,
1068 SPANSION_DUMMY_CLK_POS,
1069 SPANSION_DUMMY_CLK_LEN
1070 );
1071 break;
1072 case MAN_NUMONYX:
1073 s->needed_bytes += numonyx_extract_cfg_num_dummies(s);
1074 break;
1075 case MAN_MACRONIX:
1076 switch (extract32(s->volatile_cfg, 6, 2)) {
1077 case 1:
1078 s->needed_bytes += 4;
1079 break;
1080 case 2:
1081 s->needed_bytes += 8;
1082 break;
1083 default:
1084 s->needed_bytes += 6;
1085 break;
1086 }
1087 break;
1088 case MAN_ISSI:
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099 s->needed_bytes += 3;
1100 break;
1101 default:
1102 break;
1103 }
1104 s->pos = 0;
1105 s->len = 0;
1106 s->state = STATE_COLLECTING_DATA;
1107}
1108
1109static bool is_valid_aai_cmd(uint32_t cmd)
1110{
1111 return cmd == AAI_WP || cmd == WRDI || cmd == RDSR;
1112}
1113
1114static void decode_new_cmd(Flash *s, uint32_t value)
1115{
1116 int i;
1117
1118 s->cmd_in_progress = value;
1119 trace_m25p80_command_decoded(s, value);
1120
1121 if (value != RESET_MEMORY) {
1122 s->reset_enable = false;
1123 }
1124
1125 if (get_man(s) == MAN_SST && s->aai_enable && !is_valid_aai_cmd(value)) {
1126 qemu_log_mask(LOG_GUEST_ERROR,
1127 "M25P80: Invalid cmd within AAI programming sequence");
1128 }
1129
1130 switch (value) {
1131
1132 case ERASE_4K:
1133 case ERASE4_4K:
1134 case ERASE_32K:
1135 case ERASE4_32K:
1136 case ERASE_SECTOR:
1137 case ERASE4_SECTOR:
1138 case PP:
1139 case PP4:
1140 case DIE_ERASE:
1141 case RDID_90:
1142 case RDID_AB:
1143 s->needed_bytes = get_addr_length(s);
1144 s->pos = 0;
1145 s->len = 0;
1146 s->state = STATE_COLLECTING_DATA;
1147 break;
1148 case READ:
1149 case READ4:
1150 if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) == MODE_STD) {
1151 s->needed_bytes = get_addr_length(s);
1152 s->pos = 0;
1153 s->len = 0;
1154 s->state = STATE_COLLECTING_DATA;
1155 } else {
1156 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
1157 "DIO or QIO mode\n", s->cmd_in_progress);
1158 }
1159 break;
1160 case DPP:
1161 if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_QIO) {
1162 s->needed_bytes = get_addr_length(s);
1163 s->pos = 0;
1164 s->len = 0;
1165 s->state = STATE_COLLECTING_DATA;
1166 } else {
1167 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
1168 "QIO mode\n", s->cmd_in_progress);
1169 }
1170 break;
1171 case QPP:
1172 case QPP_4:
1173 case PP4_4:
1174 if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_DIO) {
1175 s->needed_bytes = get_addr_length(s);
1176 s->pos = 0;
1177 s->len = 0;
1178 s->state = STATE_COLLECTING_DATA;
1179 } else {
1180 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
1181 "DIO mode\n", s->cmd_in_progress);
1182 }
1183 break;
1184
1185 case FAST_READ:
1186 case FAST_READ4:
1187 decode_fast_read_cmd(s);
1188 break;
1189 case DOR:
1190 case DOR4:
1191 if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_QIO) {
1192 decode_fast_read_cmd(s);
1193 } else {
1194 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
1195 "QIO mode\n", s->cmd_in_progress);
1196 }
1197 break;
1198 case QOR:
1199 case QOR4:
1200 if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_DIO) {
1201 decode_fast_read_cmd(s);
1202 } else {
1203 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
1204 "DIO mode\n", s->cmd_in_progress);
1205 }
1206 break;
1207
1208 case DIOR:
1209 case DIOR4:
1210 if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_QIO) {
1211 decode_dio_read_cmd(s);
1212 } else {
1213 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
1214 "QIO mode\n", s->cmd_in_progress);
1215 }
1216 break;
1217
1218 case QIOR:
1219 case QIOR4:
1220 if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) != MODE_DIO) {
1221 decode_qio_read_cmd(s);
1222 } else {
1223 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute cmd %x in "
1224 "DIO mode\n", s->cmd_in_progress);
1225 }
1226 break;
1227
1228 case WRSR:
1229
1230
1231
1232
1233
1234
1235
1236 if ((s->wp_level == 0 && s->status_register_write_disabled)
1237 || !s->write_enable) {
1238 qemu_log_mask(LOG_GUEST_ERROR,
1239 "M25P80: Status register write is disabled!\n");
1240 break;
1241 }
1242
1243 switch (get_man(s)) {
1244 case MAN_SPANSION:
1245 s->needed_bytes = 2;
1246 s->state = STATE_COLLECTING_DATA;
1247 break;
1248 case MAN_MACRONIX:
1249 s->needed_bytes = 2;
1250 s->state = STATE_COLLECTING_VAR_LEN_DATA;
1251 break;
1252 default:
1253 s->needed_bytes = 1;
1254 s->state = STATE_COLLECTING_DATA;
1255 }
1256 s->pos = 0;
1257 break;
1258
1259 case WRDI:
1260 s->write_enable = false;
1261 if (get_man(s) == MAN_SST) {
1262 s->aai_enable = false;
1263 }
1264 break;
1265 case WREN:
1266 s->write_enable = true;
1267 break;
1268
1269 case RDSR:
1270 s->data[0] = (!!s->write_enable) << 1;
1271 s->data[0] |= (!!s->status_register_write_disabled) << 7;
1272 s->data[0] |= (!!s->block_protect0) << 2;
1273 s->data[0] |= (!!s->block_protect1) << 3;
1274 s->data[0] |= (!!s->block_protect2) << 4;
1275 if (s->pi->flags & HAS_SR_TB) {
1276 s->data[0] |= (!!s->top_bottom_bit) << 5;
1277 }
1278 if (s->pi->flags & HAS_SR_BP3_BIT6) {
1279 s->data[0] |= (!!s->block_protect3) << 6;
1280 }
1281
1282 if (get_man(s) == MAN_MACRONIX || get_man(s) == MAN_ISSI) {
1283 s->data[0] |= (!!s->quad_enable) << 6;
1284 }
1285 if (get_man(s) == MAN_SST) {
1286 s->data[0] |= (!!s->aai_enable) << 6;
1287 }
1288
1289 s->pos = 0;
1290 s->len = 1;
1291 s->data_read_loop = true;
1292 s->state = STATE_READING_DATA;
1293 break;
1294
1295 case READ_FSR:
1296 s->data[0] = FSR_FLASH_READY;
1297 if (s->four_bytes_address_mode) {
1298 s->data[0] |= FSR_4BYTE_ADDR_MODE_ENABLED;
1299 }
1300 s->pos = 0;
1301 s->len = 1;
1302 s->data_read_loop = true;
1303 s->state = STATE_READING_DATA;
1304 break;
1305
1306 case JEDEC_READ:
1307 if (get_man(s) != MAN_NUMONYX || numonyx_mode(s) == MODE_STD) {
1308 trace_m25p80_populated_jedec(s);
1309 for (i = 0; i < s->pi->id_len; i++) {
1310 s->data[i] = s->pi->id[i];
1311 }
1312 for (; i < SPI_NOR_MAX_ID_LEN; i++) {
1313 s->data[i] = 0;
1314 }
1315
1316 s->len = SPI_NOR_MAX_ID_LEN;
1317 s->pos = 0;
1318 s->state = STATE_READING_DATA;
1319 } else {
1320 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Cannot execute JEDEC read "
1321 "in DIO or QIO mode\n");
1322 }
1323 break;
1324
1325 case RDCR:
1326 s->data[0] = s->volatile_cfg & 0xFF;
1327 s->data[0] |= (!!s->four_bytes_address_mode) << 5;
1328 s->pos = 0;
1329 s->len = 1;
1330 s->state = STATE_READING_DATA;
1331 break;
1332
1333 case BULK_ERASE_60:
1334 case BULK_ERASE:
1335 if (s->write_enable) {
1336 trace_m25p80_chip_erase(s);
1337 flash_erase(s, 0, BULK_ERASE);
1338 } else {
1339 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: chip erase with write "
1340 "protect!\n");
1341 }
1342 break;
1343 case NOP:
1344 break;
1345 case EN_4BYTE_ADDR:
1346 s->four_bytes_address_mode = true;
1347 break;
1348 case EX_4BYTE_ADDR:
1349 s->four_bytes_address_mode = false;
1350 break;
1351 case BRRD:
1352 case EXTEND_ADDR_READ:
1353 s->data[0] = s->ear;
1354 s->pos = 0;
1355 s->len = 1;
1356 s->state = STATE_READING_DATA;
1357 break;
1358 case BRWR:
1359 case EXTEND_ADDR_WRITE:
1360 if (s->write_enable) {
1361 s->needed_bytes = 1;
1362 s->pos = 0;
1363 s->len = 0;
1364 s->state = STATE_COLLECTING_DATA;
1365 }
1366 break;
1367 case RNVCR:
1368 s->data[0] = s->nonvolatile_cfg & 0xFF;
1369 s->data[1] = (s->nonvolatile_cfg >> 8) & 0xFF;
1370 s->pos = 0;
1371 s->len = 2;
1372 s->state = STATE_READING_DATA;
1373 break;
1374 case WNVCR:
1375 if (s->write_enable && get_man(s) == MAN_NUMONYX) {
1376 s->needed_bytes = 2;
1377 s->pos = 0;
1378 s->len = 0;
1379 s->state = STATE_COLLECTING_DATA;
1380 }
1381 break;
1382 case RVCR:
1383 s->data[0] = s->volatile_cfg & 0xFF;
1384 s->pos = 0;
1385 s->len = 1;
1386 s->state = STATE_READING_DATA;
1387 break;
1388 case WVCR:
1389 if (s->write_enable) {
1390 s->needed_bytes = 1;
1391 s->pos = 0;
1392 s->len = 0;
1393 s->state = STATE_COLLECTING_DATA;
1394 }
1395 break;
1396 case REVCR:
1397 s->data[0] = s->enh_volatile_cfg & 0xFF;
1398 s->pos = 0;
1399 s->len = 1;
1400 s->state = STATE_READING_DATA;
1401 break;
1402 case WEVCR:
1403 if (s->write_enable) {
1404 s->needed_bytes = 1;
1405 s->pos = 0;
1406 s->len = 0;
1407 s->state = STATE_COLLECTING_DATA;
1408 }
1409 break;
1410 case RESET_ENABLE:
1411 s->reset_enable = true;
1412 break;
1413 case RESET_MEMORY:
1414 if (s->reset_enable) {
1415 reset_memory(s);
1416 }
1417 break;
1418 case RDCR_EQIO:
1419 switch (get_man(s)) {
1420 case MAN_SPANSION:
1421 s->data[0] = (!!s->quad_enable) << 1;
1422 s->pos = 0;
1423 s->len = 1;
1424 s->state = STATE_READING_DATA;
1425 break;
1426 case MAN_MACRONIX:
1427 s->quad_enable = true;
1428 break;
1429 default:
1430 break;
1431 }
1432 break;
1433 case RSTQIO:
1434 s->quad_enable = false;
1435 break;
1436 case AAI_WP:
1437 if (get_man(s) == MAN_SST) {
1438 if (s->write_enable) {
1439 if (s->aai_enable) {
1440 s->state = STATE_PAGE_PROGRAM;
1441 } else {
1442 s->aai_enable = true;
1443 s->needed_bytes = get_addr_length(s);
1444 s->state = STATE_COLLECTING_DATA;
1445 }
1446 } else {
1447 qemu_log_mask(LOG_GUEST_ERROR,
1448 "M25P80: AAI_WP with write protect\n");
1449 }
1450 } else {
1451 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Unknown cmd %x\n", value);
1452 }
1453 break;
1454 case RDSFDP:
1455 if (s->pi->sfdp_read) {
1456 s->needed_bytes = get_addr_length(s) + 1;
1457 s->pos = 0;
1458 s->len = 0;
1459 s->state = STATE_COLLECTING_DATA;
1460 break;
1461 }
1462
1463
1464 default:
1465 s->pos = 0;
1466 s->len = 1;
1467 s->state = STATE_READING_DATA;
1468 s->data_read_loop = true;
1469 s->data[0] = 0;
1470 qemu_log_mask(LOG_GUEST_ERROR, "M25P80: Unknown cmd %x\n", value);
1471 break;
1472 }
1473}
1474
1475static int m25p80_cs(SSIPeripheral *ss, bool select)
1476{
1477 Flash *s = M25P80(ss);
1478
1479 if (select) {
1480 if (s->state == STATE_COLLECTING_VAR_LEN_DATA) {
1481 complete_collecting_data(s);
1482 }
1483 s->len = 0;
1484 s->pos = 0;
1485 s->state = STATE_IDLE;
1486 flash_sync_dirty(s, -1);
1487 s->data_read_loop = false;
1488 }
1489
1490 trace_m25p80_select(s, select ? "de" : "");
1491
1492 return 0;
1493}
1494
1495static uint32_t m25p80_transfer8(SSIPeripheral *ss, uint32_t tx)
1496{
1497 Flash *s = M25P80(ss);
1498 uint32_t r = 0;
1499
1500 trace_m25p80_transfer(s, s->state, s->len, s->needed_bytes, s->pos,
1501 s->cur_addr, (uint8_t)tx);
1502
1503 switch (s->state) {
1504
1505 case STATE_PAGE_PROGRAM:
1506 trace_m25p80_page_program(s, s->cur_addr, (uint8_t)tx);
1507 flash_write8(s, s->cur_addr, (uint8_t)tx);
1508 s->cur_addr = (s->cur_addr + 1) & (s->size - 1);
1509
1510 if (get_man(s) == MAN_SST && s->aai_enable && s->cur_addr == 0) {
1511
1512
1513
1514
1515
1516 s->write_enable = false;
1517 s->aai_enable = false;
1518 }
1519
1520 break;
1521
1522 case STATE_READ:
1523 r = s->storage[s->cur_addr];
1524 trace_m25p80_read_byte(s, s->cur_addr, (uint8_t)r);
1525 s->cur_addr = (s->cur_addr + 1) & (s->size - 1);
1526 break;
1527
1528 case STATE_COLLECTING_DATA:
1529 case STATE_COLLECTING_VAR_LEN_DATA:
1530
1531 if (s->len >= M25P80_INTERNAL_DATA_BUFFER_SZ) {
1532 qemu_log_mask(LOG_GUEST_ERROR,
1533 "M25P80: Write overrun internal data buffer. "
1534 "SPI controller (QEMU emulator or guest driver) "
1535 "is misbehaving\n");
1536 s->len = s->pos = 0;
1537 s->state = STATE_IDLE;
1538 break;
1539 }
1540
1541 s->data[s->len] = (uint8_t)tx;
1542 s->len++;
1543
1544 if (s->len == s->needed_bytes) {
1545 complete_collecting_data(s);
1546 }
1547 break;
1548
1549 case STATE_READING_DATA:
1550
1551 if (s->pos >= M25P80_INTERNAL_DATA_BUFFER_SZ) {
1552 qemu_log_mask(LOG_GUEST_ERROR,
1553 "M25P80: Read overrun internal data buffer. "
1554 "SPI controller (QEMU emulator or guest driver) "
1555 "is misbehaving\n");
1556 s->len = s->pos = 0;
1557 s->state = STATE_IDLE;
1558 break;
1559 }
1560
1561 r = s->data[s->pos];
1562 trace_m25p80_read_data(s, s->pos, (uint8_t)r);
1563 s->pos++;
1564 if (s->pos == s->len) {
1565 s->pos = 0;
1566 if (!s->data_read_loop) {
1567 s->state = STATE_IDLE;
1568 }
1569 }
1570 break;
1571 case STATE_READING_SFDP:
1572 assert(s->pi->sfdp_read);
1573 r = s->pi->sfdp_read(s->cur_addr);
1574 trace_m25p80_read_sfdp(s, s->cur_addr, (uint8_t)r);
1575 s->cur_addr = (s->cur_addr + 1) & (M25P80_SFDP_MAX_SIZE - 1);
1576 break;
1577
1578 default:
1579 case STATE_IDLE:
1580 decode_new_cmd(s, (uint8_t)tx);
1581 break;
1582 }
1583
1584 return r;
1585}
1586
1587static void m25p80_write_protect_pin_irq_handler(void *opaque, int n, int level)
1588{
1589 Flash *s = M25P80(opaque);
1590
1591 assert(n == 0);
1592 s->wp_level = !!level;
1593}
1594
1595static void m25p80_realize(SSIPeripheral *ss, Error **errp)
1596{
1597 Flash *s = M25P80(ss);
1598 M25P80Class *mc = M25P80_GET_CLASS(s);
1599 int ret;
1600
1601 s->pi = mc->pi;
1602
1603 s->size = s->pi->sector_size * s->pi->n_sectors;
1604 s->dirty_page = -1;
1605
1606 if (s->blk) {
1607 uint64_t perm = BLK_PERM_CONSISTENT_READ |
1608 (blk_supports_write_perm(s->blk) ? BLK_PERM_WRITE : 0);
1609 ret = blk_set_perm(s->blk, perm, BLK_PERM_ALL, errp);
1610 if (ret < 0) {
1611 return;
1612 }
1613
1614 trace_m25p80_binding(s);
1615 s->storage = blk_blockalign(s->blk, s->size);
1616
1617 if (blk_pread(s->blk, 0, s->size, s->storage, 0) < 0) {
1618 error_setg(errp, "failed to read the initial flash content");
1619 return;
1620 }
1621 } else {
1622 trace_m25p80_binding_no_bdrv(s);
1623 s->storage = blk_blockalign(NULL, s->size);
1624 memset(s->storage, 0xFF, s->size);
1625 }
1626
1627 qdev_init_gpio_in_named(DEVICE(s),
1628 m25p80_write_protect_pin_irq_handler, "WP#", 1);
1629}
1630
1631static void m25p80_reset(DeviceState *d)
1632{
1633 Flash *s = M25P80(d);
1634
1635 s->wp_level = true;
1636 s->status_register_write_disabled = false;
1637 s->block_protect0 = false;
1638 s->block_protect1 = false;
1639 s->block_protect2 = false;
1640 s->block_protect3 = false;
1641 s->top_bottom_bit = false;
1642
1643 reset_memory(s);
1644}
1645
1646static int m25p80_pre_save(void *opaque)
1647{
1648 flash_sync_dirty((Flash *)opaque, -1);
1649
1650 return 0;
1651}
1652
1653static Property m25p80_properties[] = {
1654
1655 DEFINE_PROP_BOOL("write-enable", Flash, write_enable, false),
1656 DEFINE_PROP_UINT32("nonvolatile-cfg", Flash, nonvolatile_cfg, 0x8FFF),
1657 DEFINE_PROP_UINT8("spansion-cr1nv", Flash, spansion_cr1nv, 0x0),
1658 DEFINE_PROP_UINT8("spansion-cr2nv", Flash, spansion_cr2nv, 0x8),
1659 DEFINE_PROP_UINT8("spansion-cr3nv", Flash, spansion_cr3nv, 0x2),
1660 DEFINE_PROP_UINT8("spansion-cr4nv", Flash, spansion_cr4nv, 0x10),
1661 DEFINE_PROP_DRIVE("drive", Flash, blk),
1662 DEFINE_PROP_END_OF_LIST(),
1663};
1664
1665static int m25p80_pre_load(void *opaque)
1666{
1667 Flash *s = (Flash *)opaque;
1668
1669 s->data_read_loop = false;
1670 return 0;
1671}
1672
1673static bool m25p80_data_read_loop_needed(void *opaque)
1674{
1675 Flash *s = (Flash *)opaque;
1676
1677 return s->data_read_loop;
1678}
1679
1680static const VMStateDescription vmstate_m25p80_data_read_loop = {
1681 .name = "m25p80/data_read_loop",
1682 .version_id = 1,
1683 .minimum_version_id = 1,
1684 .needed = m25p80_data_read_loop_needed,
1685 .fields = (VMStateField[]) {
1686 VMSTATE_BOOL(data_read_loop, Flash),
1687 VMSTATE_END_OF_LIST()
1688 }
1689};
1690
1691static bool m25p80_aai_enable_needed(void *opaque)
1692{
1693 Flash *s = (Flash *)opaque;
1694
1695 return s->aai_enable;
1696}
1697
1698static const VMStateDescription vmstate_m25p80_aai_enable = {
1699 .name = "m25p80/aai_enable",
1700 .version_id = 1,
1701 .minimum_version_id = 1,
1702 .needed = m25p80_aai_enable_needed,
1703 .fields = (VMStateField[]) {
1704 VMSTATE_BOOL(aai_enable, Flash),
1705 VMSTATE_END_OF_LIST()
1706 }
1707};
1708
1709static bool m25p80_wp_level_srwd_needed(void *opaque)
1710{
1711 Flash *s = (Flash *)opaque;
1712
1713 return !s->wp_level || s->status_register_write_disabled;
1714}
1715
1716static const VMStateDescription vmstate_m25p80_write_protect = {
1717 .name = "m25p80/write_protect",
1718 .version_id = 1,
1719 .minimum_version_id = 1,
1720 .needed = m25p80_wp_level_srwd_needed,
1721 .fields = (VMStateField[]) {
1722 VMSTATE_BOOL(wp_level, Flash),
1723 VMSTATE_BOOL(status_register_write_disabled, Flash),
1724 VMSTATE_END_OF_LIST()
1725 }
1726};
1727
1728static bool m25p80_block_protect_needed(void *opaque)
1729{
1730 Flash *s = (Flash *)opaque;
1731
1732 return s->block_protect0 ||
1733 s->block_protect1 ||
1734 s->block_protect2 ||
1735 s->block_protect3 ||
1736 s->top_bottom_bit;
1737}
1738
1739static const VMStateDescription vmstate_m25p80_block_protect = {
1740 .name = "m25p80/block_protect",
1741 .version_id = 1,
1742 .minimum_version_id = 1,
1743 .needed = m25p80_block_protect_needed,
1744 .fields = (VMStateField[]) {
1745 VMSTATE_BOOL(block_protect0, Flash),
1746 VMSTATE_BOOL(block_protect1, Flash),
1747 VMSTATE_BOOL(block_protect2, Flash),
1748 VMSTATE_BOOL(block_protect3, Flash),
1749 VMSTATE_BOOL(top_bottom_bit, Flash),
1750 VMSTATE_END_OF_LIST()
1751 }
1752};
1753
1754static const VMStateDescription vmstate_m25p80 = {
1755 .name = "m25p80",
1756 .version_id = 0,
1757 .minimum_version_id = 0,
1758 .pre_save = m25p80_pre_save,
1759 .pre_load = m25p80_pre_load,
1760 .fields = (VMStateField[]) {
1761 VMSTATE_UINT8(state, Flash),
1762 VMSTATE_UINT8_ARRAY(data, Flash, M25P80_INTERNAL_DATA_BUFFER_SZ),
1763 VMSTATE_UINT32(len, Flash),
1764 VMSTATE_UINT32(pos, Flash),
1765 VMSTATE_UINT8(needed_bytes, Flash),
1766 VMSTATE_UINT8(cmd_in_progress, Flash),
1767 VMSTATE_UINT32(cur_addr, Flash),
1768 VMSTATE_BOOL(write_enable, Flash),
1769 VMSTATE_BOOL(reset_enable, Flash),
1770 VMSTATE_UINT8(ear, Flash),
1771 VMSTATE_BOOL(four_bytes_address_mode, Flash),
1772 VMSTATE_UINT32(nonvolatile_cfg, Flash),
1773 VMSTATE_UINT32(volatile_cfg, Flash),
1774 VMSTATE_UINT32(enh_volatile_cfg, Flash),
1775 VMSTATE_BOOL(quad_enable, Flash),
1776 VMSTATE_UINT8(spansion_cr1nv, Flash),
1777 VMSTATE_UINT8(spansion_cr2nv, Flash),
1778 VMSTATE_UINT8(spansion_cr3nv, Flash),
1779 VMSTATE_UINT8(spansion_cr4nv, Flash),
1780 VMSTATE_END_OF_LIST()
1781 },
1782 .subsections = (const VMStateDescription * []) {
1783 &vmstate_m25p80_data_read_loop,
1784 &vmstate_m25p80_aai_enable,
1785 &vmstate_m25p80_write_protect,
1786 &vmstate_m25p80_block_protect,
1787 NULL
1788 }
1789};
1790
1791static void m25p80_class_init(ObjectClass *klass, void *data)
1792{
1793 DeviceClass *dc = DEVICE_CLASS(klass);
1794 SSIPeripheralClass *k = SSI_PERIPHERAL_CLASS(klass);
1795 M25P80Class *mc = M25P80_CLASS(klass);
1796
1797 k->realize = m25p80_realize;
1798 k->transfer = m25p80_transfer8;
1799 k->set_cs = m25p80_cs;
1800 k->cs_polarity = SSI_CS_LOW;
1801 dc->vmsd = &vmstate_m25p80;
1802 device_class_set_props(dc, m25p80_properties);
1803 dc->reset = m25p80_reset;
1804 mc->pi = data;
1805}
1806
1807static const TypeInfo m25p80_info = {
1808 .name = TYPE_M25P80,
1809 .parent = TYPE_SSI_PERIPHERAL,
1810 .instance_size = sizeof(Flash),
1811 .class_size = sizeof(M25P80Class),
1812 .abstract = true,
1813};
1814
1815static void m25p80_register_types(void)
1816{
1817 int i;
1818
1819 type_register_static(&m25p80_info);
1820 for (i = 0; i < ARRAY_SIZE(known_devices); ++i) {
1821 TypeInfo ti = {
1822 .name = known_devices[i].part_name,
1823 .parent = TYPE_M25P80,
1824 .class_init = m25p80_class_init,
1825 .class_data = (void *)&known_devices[i],
1826 };
1827 type_register(&ti);
1828 }
1829}
1830
1831type_init(m25p80_register_types)
1832