xref: /openbmc/qemu/hw/block/pflash_cfi01.c (revision 1b111dc1)
1 /*
2  *  CFI parallel flash with Intel command set emulation
3  *
4  *  Copyright (c) 2006 Thorsten Zitterell
5  *  Copyright (c) 2005 Jocelyn Mayer
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library 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 GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, see <http://www.gnu.org/licenses/>.
19  */
20 
21 /*
22  * For now, this code can emulate flashes of 1, 2 or 4 bytes width.
23  * Supported commands/modes are:
24  * - flash read
25  * - flash write
26  * - flash ID read
27  * - sector erase
28  * - CFI queries
29  *
30  * It does not support timings
31  * It does not support flash interleaving
32  * It does not implement software data protection as found in many real chips
33  * It does not implement erase suspend/resume commands
34  * It does not implement multiple sectors erase
35  *
36  * It does not implement much more ...
37  */
38 
39 #include "hw/hw.h"
40 #include "hw/block/flash.h"
41 #include "block/block.h"
42 #include "qemu/timer.h"
43 #include "qemu/bitops.h"
44 #include "exec/address-spaces.h"
45 #include "qemu/host-utils.h"
46 #include "hw/sysbus.h"
47 
48 #define PFLASH_BUG(fmt, ...) \
49 do { \
50     fprintf(stderr, "PFLASH: Possible BUG - " fmt, ## __VA_ARGS__); \
51     exit(1); \
52 } while(0)
53 
54 /* #define PFLASH_DEBUG */
55 #ifdef PFLASH_DEBUG
56 #define DPRINTF(fmt, ...)                                   \
57 do {                                                        \
58     fprintf(stderr, "PFLASH: " fmt , ## __VA_ARGS__);       \
59 } while (0)
60 #else
61 #define DPRINTF(fmt, ...) do { } while (0)
62 #endif
63 
64 #define TYPE_CFI_PFLASH01 "cfi.pflash01"
65 #define CFI_PFLASH01(obj) OBJECT_CHECK(pflash_t, (obj), TYPE_CFI_PFLASH01)
66 
67 struct pflash_t {
68     /*< private >*/
69     SysBusDevice parent_obj;
70     /*< public >*/
71 
72     BlockDriverState *bs;
73     uint32_t nb_blocs;
74     uint64_t sector_len;
75     uint8_t bank_width;
76     uint8_t device_width; /* If 0, device width not specified. */
77     uint8_t max_device_width;  /* max device width in bytes */
78     uint8_t be;
79     uint8_t wcycle; /* if 0, the flash is read normally */
80     int ro;
81     uint8_t cmd;
82     uint8_t status;
83     uint16_t ident0;
84     uint16_t ident1;
85     uint16_t ident2;
86     uint16_t ident3;
87     uint8_t cfi_len;
88     uint8_t cfi_table[0x52];
89     uint64_t counter;
90     unsigned int writeblock_size;
91     QEMUTimer *timer;
92     MemoryRegion mem;
93     char *name;
94     void *storage;
95 };
96 
97 static const VMStateDescription vmstate_pflash = {
98     .name = "pflash_cfi01",
99     .version_id = 1,
100     .minimum_version_id = 1,
101     .fields = (VMStateField[]) {
102         VMSTATE_UINT8(wcycle, pflash_t),
103         VMSTATE_UINT8(cmd, pflash_t),
104         VMSTATE_UINT8(status, pflash_t),
105         VMSTATE_UINT64(counter, pflash_t),
106         VMSTATE_END_OF_LIST()
107     }
108 };
109 
110 static void pflash_timer (void *opaque)
111 {
112     pflash_t *pfl = opaque;
113 
114     DPRINTF("%s: command %02x done\n", __func__, pfl->cmd);
115     /* Reset flash */
116     pfl->status ^= 0x80;
117     memory_region_rom_device_set_romd(&pfl->mem, true);
118     pfl->wcycle = 0;
119     pfl->cmd = 0;
120 }
121 
122 /* Perform a CFI query based on the bank width of the flash.
123  * If this code is called we know we have a device_width set for
124  * this flash.
125  */
126 static uint32_t pflash_cfi_query(pflash_t *pfl, hwaddr offset)
127 {
128     int i;
129     uint32_t resp = 0;
130     hwaddr boff;
131 
132     /* Adjust incoming offset to match expected device-width
133      * addressing. CFI query addresses are always specified in terms of
134      * the maximum supported width of the device.  This means that x8
135      * devices and x8/x16 devices in x8 mode behave differently.  For
136      * devices that are not used at their max width, we will be
137      * provided with addresses that use higher address bits than
138      * expected (based on the max width), so we will shift them lower
139      * so that they will match the addresses used when
140      * device_width==max_device_width.
141      */
142     boff = offset >> (ctz32(pfl->bank_width) +
143                       ctz32(pfl->max_device_width) - ctz32(pfl->device_width));
144 
145     if (boff > pfl->cfi_len) {
146         return 0;
147     }
148     /* Now we will construct the CFI response generated by a single
149      * device, then replicate that for all devices that make up the
150      * bus.  For wide parts used in x8 mode, CFI query responses
151      * are different than native byte-wide parts.
152      */
153     resp = pfl->cfi_table[boff];
154     if (pfl->device_width != pfl->max_device_width) {
155         /* The only case currently supported is x8 mode for a
156          * wider part.
157          */
158         if (pfl->device_width != 1 || pfl->bank_width > 4) {
159             DPRINTF("%s: Unsupported device configuration: "
160                     "device_width=%d, max_device_width=%d\n",
161                     __func__, pfl->device_width,
162                     pfl->max_device_width);
163             return 0;
164         }
165         /* CFI query data is repeated, rather than zero padded for
166          * wide devices used in x8 mode.
167          */
168         for (i = 1; i < pfl->max_device_width; i++) {
169             resp = deposit32(resp, 8 * i, 8, pfl->cfi_table[boff]);
170         }
171     }
172     /* Replicate responses for each device in bank. */
173     if (pfl->device_width < pfl->bank_width) {
174         for (i = pfl->device_width;
175              i < pfl->bank_width; i += pfl->device_width) {
176             resp = deposit32(resp, 8 * i, 8 * pfl->device_width, resp);
177         }
178     }
179 
180     return resp;
181 }
182 
183 
184 
185 /* Perform a device id query based on the bank width of the flash. */
186 static uint32_t pflash_devid_query(pflash_t *pfl, hwaddr offset)
187 {
188     int i;
189     uint32_t resp;
190     hwaddr boff;
191 
192     /* Adjust incoming offset to match expected device-width
193      * addressing. Device ID read addresses are always specified in
194      * terms of the maximum supported width of the device.  This means
195      * that x8 devices and x8/x16 devices in x8 mode behave
196      * differently. For devices that are not used at their max width,
197      * we will be provided with addresses that use higher address bits
198      * than expected (based on the max width), so we will shift them
199      * lower so that they will match the addresses used when
200      * device_width==max_device_width.
201      */
202     boff = offset >> (ctz32(pfl->bank_width) +
203                       ctz32(pfl->max_device_width) - ctz32(pfl->device_width));
204 
205     /* Mask off upper bits which may be used in to query block
206      * or sector lock status at other addresses.
207      * Offsets 2/3 are block lock status, is not emulated.
208      */
209     switch (boff & 0xFF) {
210     case 0:
211         resp = pfl->ident0;
212         DPRINTF("%s: Manufacturer Code %04x\n", __func__, ret);
213         break;
214     case 1:
215         resp = pfl->ident1;
216         DPRINTF("%s: Device ID Code %04x\n", __func__, ret);
217         break;
218     default:
219         DPRINTF("%s: Read Device Information offset=%x\n", __func__,
220                 (unsigned)offset);
221         return 0;
222         break;
223     }
224     /* Replicate responses for each device in bank. */
225     if (pfl->device_width < pfl->bank_width) {
226         for (i = pfl->device_width;
227               i < pfl->bank_width; i += pfl->device_width) {
228             resp = deposit32(resp, 8 * i, 8 * pfl->device_width, resp);
229         }
230     }
231 
232     return resp;
233 }
234 
235 static uint32_t pflash_read (pflash_t *pfl, hwaddr offset,
236                              int width, int be)
237 {
238     hwaddr boff;
239     uint32_t ret;
240     uint8_t *p;
241 
242     ret = -1;
243 
244 #if 0
245     DPRINTF("%s: reading offset " TARGET_FMT_plx " under cmd %02x width %d\n",
246             __func__, offset, pfl->cmd, width);
247 #endif
248     switch (pfl->cmd) {
249     default:
250         /* This should never happen : reset state & treat it as a read */
251         DPRINTF("%s: unknown command state: %x\n", __func__, pfl->cmd);
252         pfl->wcycle = 0;
253         pfl->cmd = 0;
254         /* fall through to read code */
255     case 0x00:
256         /* Flash area read */
257         p = pfl->storage;
258         switch (width) {
259         case 1:
260             ret = p[offset];
261             DPRINTF("%s: data offset " TARGET_FMT_plx " %02x\n",
262                     __func__, offset, ret);
263             break;
264         case 2:
265             if (be) {
266                 ret = p[offset] << 8;
267                 ret |= p[offset + 1];
268             } else {
269                 ret = p[offset];
270                 ret |= p[offset + 1] << 8;
271             }
272             DPRINTF("%s: data offset " TARGET_FMT_plx " %04x\n",
273                     __func__, offset, ret);
274             break;
275         case 4:
276             if (be) {
277                 ret = p[offset] << 24;
278                 ret |= p[offset + 1] << 16;
279                 ret |= p[offset + 2] << 8;
280                 ret |= p[offset + 3];
281             } else {
282                 ret = p[offset];
283                 ret |= p[offset + 1] << 8;
284                 ret |= p[offset + 2] << 16;
285                 ret |= p[offset + 3] << 24;
286             }
287             DPRINTF("%s: data offset " TARGET_FMT_plx " %08x\n",
288                     __func__, offset, ret);
289             break;
290         default:
291             DPRINTF("BUG in %s\n", __func__);
292         }
293 
294         break;
295     case 0x10: /* Single byte program */
296     case 0x20: /* Block erase */
297     case 0x28: /* Block erase */
298     case 0x40: /* single byte program */
299     case 0x50: /* Clear status register */
300     case 0x60: /* Block /un)lock */
301     case 0x70: /* Status Register */
302     case 0xe8: /* Write block */
303         /* Status register read.  Return status from each device in
304          * bank.
305          */
306         ret = pfl->status;
307         if (pfl->device_width && width > pfl->device_width) {
308             int shift = pfl->device_width * 8;
309             while (shift + pfl->device_width * 8 <= width * 8) {
310                 ret |= pfl->status << shift;
311                 shift += pfl->device_width * 8;
312             }
313         } else if (!pfl->device_width && width > 2) {
314             /* Handle 32 bit flash cases where device width is not
315              * set. (Existing behavior before device width added.)
316              */
317             ret |= pfl->status << 16;
318         }
319         DPRINTF("%s: status %x\n", __func__, ret);
320         break;
321     case 0x90:
322         if (!pfl->device_width) {
323             /* Preserve old behavior if device width not specified */
324             boff = offset & 0xFF;
325             if (pfl->bank_width == 2) {
326                 boff = boff >> 1;
327             } else if (pfl->bank_width == 4) {
328                 boff = boff >> 2;
329             }
330 
331             switch (boff) {
332             case 0:
333                 ret = pfl->ident0 << 8 | pfl->ident1;
334                 DPRINTF("%s: Manufacturer Code %04x\n", __func__, ret);
335                 break;
336             case 1:
337                 ret = pfl->ident2 << 8 | pfl->ident3;
338                 DPRINTF("%s: Device ID Code %04x\n", __func__, ret);
339                 break;
340             default:
341                 DPRINTF("%s: Read Device Information boff=%x\n", __func__,
342                         (unsigned)boff);
343                 ret = 0;
344                 break;
345             }
346         } else {
347             /* If we have a read larger than the bank_width, combine multiple
348              * manufacturer/device ID queries into a single response.
349              */
350             int i;
351             for (i = 0; i < width; i += pfl->bank_width) {
352                 ret = deposit32(ret, i * 8, pfl->bank_width * 8,
353                                 pflash_devid_query(pfl,
354                                                  offset + i * pfl->bank_width));
355             }
356         }
357         break;
358     case 0x98: /* Query mode */
359         if (!pfl->device_width) {
360             /* Preserve old behavior if device width not specified */
361             boff = offset & 0xFF;
362             if (pfl->bank_width == 2) {
363                 boff = boff >> 1;
364             } else if (pfl->bank_width == 4) {
365                 boff = boff >> 2;
366             }
367 
368             if (boff > pfl->cfi_len) {
369                 ret = 0;
370             } else {
371                 ret = pfl->cfi_table[boff];
372             }
373         } else {
374             /* If we have a read larger than the bank_width, combine multiple
375              * CFI queries into a single response.
376              */
377             int i;
378             for (i = 0; i < width; i += pfl->bank_width) {
379                 ret = deposit32(ret, i * 8, pfl->bank_width * 8,
380                                 pflash_cfi_query(pfl,
381                                                  offset + i * pfl->bank_width));
382             }
383         }
384 
385         break;
386     }
387     return ret;
388 }
389 
390 /* update flash content on disk */
391 static void pflash_update(pflash_t *pfl, int offset,
392                           int size)
393 {
394     int offset_end;
395     if (pfl->bs) {
396         offset_end = offset + size;
397         /* round to sectors */
398         offset = offset >> 9;
399         offset_end = (offset_end + 511) >> 9;
400         bdrv_write(pfl->bs, offset, pfl->storage + (offset << 9),
401                    offset_end - offset);
402     }
403 }
404 
405 static inline void pflash_data_write(pflash_t *pfl, hwaddr offset,
406                                      uint32_t value, int width, int be)
407 {
408     uint8_t *p = pfl->storage;
409 
410     DPRINTF("%s: block write offset " TARGET_FMT_plx
411             " value %x counter %016" PRIx64 "\n",
412             __func__, offset, value, pfl->counter);
413     switch (width) {
414     case 1:
415         p[offset] = value;
416         break;
417     case 2:
418         if (be) {
419             p[offset] = value >> 8;
420             p[offset + 1] = value;
421         } else {
422             p[offset] = value;
423             p[offset + 1] = value >> 8;
424         }
425         break;
426     case 4:
427         if (be) {
428             p[offset] = value >> 24;
429             p[offset + 1] = value >> 16;
430             p[offset + 2] = value >> 8;
431             p[offset + 3] = value;
432         } else {
433             p[offset] = value;
434             p[offset + 1] = value >> 8;
435             p[offset + 2] = value >> 16;
436             p[offset + 3] = value >> 24;
437         }
438         break;
439     }
440 
441 }
442 
443 static void pflash_write(pflash_t *pfl, hwaddr offset,
444                          uint32_t value, int width, int be)
445 {
446     uint8_t *p;
447     uint8_t cmd;
448 
449     cmd = value;
450 
451     DPRINTF("%s: writing offset " TARGET_FMT_plx " value %08x width %d wcycle 0x%x\n",
452             __func__, offset, value, width, pfl->wcycle);
453 
454     if (!pfl->wcycle) {
455         /* Set the device in I/O access mode */
456         memory_region_rom_device_set_romd(&pfl->mem, false);
457     }
458 
459     switch (pfl->wcycle) {
460     case 0:
461         /* read mode */
462         switch (cmd) {
463         case 0x00: /* ??? */
464             goto reset_flash;
465         case 0x10: /* Single Byte Program */
466         case 0x40: /* Single Byte Program */
467             DPRINTF("%s: Single Byte Program\n", __func__);
468             break;
469         case 0x20: /* Block erase */
470             p = pfl->storage;
471             offset &= ~(pfl->sector_len - 1);
472 
473             DPRINTF("%s: block erase at " TARGET_FMT_plx " bytes %x\n",
474                     __func__, offset, (unsigned)pfl->sector_len);
475 
476             if (!pfl->ro) {
477                 memset(p + offset, 0xff, pfl->sector_len);
478                 pflash_update(pfl, offset, pfl->sector_len);
479             } else {
480                 pfl->status |= 0x20; /* Block erase error */
481             }
482             pfl->status |= 0x80; /* Ready! */
483             break;
484         case 0x50: /* Clear status bits */
485             DPRINTF("%s: Clear status bits\n", __func__);
486             pfl->status = 0x0;
487             goto reset_flash;
488         case 0x60: /* Block (un)lock */
489             DPRINTF("%s: Block unlock\n", __func__);
490             break;
491         case 0x70: /* Status Register */
492             DPRINTF("%s: Read status register\n", __func__);
493             pfl->cmd = cmd;
494             return;
495         case 0x90: /* Read Device ID */
496             DPRINTF("%s: Read Device information\n", __func__);
497             pfl->cmd = cmd;
498             return;
499         case 0x98: /* CFI query */
500             DPRINTF("%s: CFI query\n", __func__);
501             break;
502         case 0xe8: /* Write to buffer */
503             DPRINTF("%s: Write to buffer\n", __func__);
504             pfl->status |= 0x80; /* Ready! */
505             break;
506         case 0xf0: /* Probe for AMD flash */
507             DPRINTF("%s: Probe for AMD flash\n", __func__);
508             goto reset_flash;
509         case 0xff: /* Read array mode */
510             DPRINTF("%s: Read array mode\n", __func__);
511             goto reset_flash;
512         default:
513             goto error_flash;
514         }
515         pfl->wcycle++;
516         pfl->cmd = cmd;
517         break;
518     case 1:
519         switch (pfl->cmd) {
520         case 0x10: /* Single Byte Program */
521         case 0x40: /* Single Byte Program */
522             DPRINTF("%s: Single Byte Program\n", __func__);
523             if (!pfl->ro) {
524                 pflash_data_write(pfl, offset, value, width, be);
525                 pflash_update(pfl, offset, width);
526             } else {
527                 pfl->status |= 0x10; /* Programming error */
528             }
529             pfl->status |= 0x80; /* Ready! */
530             pfl->wcycle = 0;
531         break;
532         case 0x20: /* Block erase */
533         case 0x28:
534             if (cmd == 0xd0) { /* confirm */
535                 pfl->wcycle = 0;
536                 pfl->status |= 0x80;
537             } else if (cmd == 0xff) { /* read array mode */
538                 goto reset_flash;
539             } else
540                 goto error_flash;
541 
542             break;
543         case 0xe8:
544             /* Mask writeblock size based on device width, or bank width if
545              * device width not specified.
546              */
547             if (pfl->device_width) {
548                 value = extract32(value, 0, pfl->device_width * 8);
549             } else {
550                 value = extract32(value, 0, pfl->bank_width * 8);
551             }
552             DPRINTF("%s: block write of %x bytes\n", __func__, value);
553             pfl->counter = value;
554             pfl->wcycle++;
555             break;
556         case 0x60:
557             if (cmd == 0xd0) {
558                 pfl->wcycle = 0;
559                 pfl->status |= 0x80;
560             } else if (cmd == 0x01) {
561                 pfl->wcycle = 0;
562                 pfl->status |= 0x80;
563             } else if (cmd == 0xff) {
564                 goto reset_flash;
565             } else {
566                 DPRINTF("%s: Unknown (un)locking command\n", __func__);
567                 goto reset_flash;
568             }
569             break;
570         case 0x98:
571             if (cmd == 0xff) {
572                 goto reset_flash;
573             } else {
574                 DPRINTF("%s: leaving query mode\n", __func__);
575             }
576             break;
577         default:
578             goto error_flash;
579         }
580         break;
581     case 2:
582         switch (pfl->cmd) {
583         case 0xe8: /* Block write */
584             if (!pfl->ro) {
585                 pflash_data_write(pfl, offset, value, width, be);
586             } else {
587                 pfl->status |= 0x10; /* Programming error */
588             }
589 
590             pfl->status |= 0x80;
591 
592             if (!pfl->counter) {
593                 hwaddr mask = pfl->writeblock_size - 1;
594                 mask = ~mask;
595 
596                 DPRINTF("%s: block write finished\n", __func__);
597                 pfl->wcycle++;
598                 if (!pfl->ro) {
599                     /* Flush the entire write buffer onto backing storage.  */
600                     pflash_update(pfl, offset & mask, pfl->writeblock_size);
601                 } else {
602                     pfl->status |= 0x10; /* Programming error */
603                 }
604             }
605 
606             pfl->counter--;
607             break;
608         default:
609             goto error_flash;
610         }
611         break;
612     case 3: /* Confirm mode */
613         switch (pfl->cmd) {
614         case 0xe8: /* Block write */
615             if (cmd == 0xd0) {
616                 pfl->wcycle = 0;
617                 pfl->status |= 0x80;
618             } else {
619                 DPRINTF("%s: unknown command for \"write block\"\n", __func__);
620                 PFLASH_BUG("Write block confirm");
621                 goto reset_flash;
622             }
623             break;
624         default:
625             goto error_flash;
626         }
627         break;
628     default:
629         /* Should never happen */
630         DPRINTF("%s: invalid write state\n",  __func__);
631         goto reset_flash;
632     }
633     return;
634 
635  error_flash:
636     qemu_log_mask(LOG_UNIMP, "%s: Unimplemented flash cmd sequence "
637                   "(offset " TARGET_FMT_plx ", wcycle 0x%x cmd 0x%x value 0x%x)"
638                   "\n", __func__, offset, pfl->wcycle, pfl->cmd, value);
639 
640  reset_flash:
641     memory_region_rom_device_set_romd(&pfl->mem, true);
642 
643     pfl->wcycle = 0;
644     pfl->cmd = 0;
645 }
646 
647 
648 static uint32_t pflash_readb_be(void *opaque, hwaddr addr)
649 {
650     return pflash_read(opaque, addr, 1, 1);
651 }
652 
653 static uint32_t pflash_readb_le(void *opaque, hwaddr addr)
654 {
655     return pflash_read(opaque, addr, 1, 0);
656 }
657 
658 static uint32_t pflash_readw_be(void *opaque, hwaddr addr)
659 {
660     pflash_t *pfl = opaque;
661 
662     return pflash_read(pfl, addr, 2, 1);
663 }
664 
665 static uint32_t pflash_readw_le(void *opaque, hwaddr addr)
666 {
667     pflash_t *pfl = opaque;
668 
669     return pflash_read(pfl, addr, 2, 0);
670 }
671 
672 static uint32_t pflash_readl_be(void *opaque, hwaddr addr)
673 {
674     pflash_t *pfl = opaque;
675 
676     return pflash_read(pfl, addr, 4, 1);
677 }
678 
679 static uint32_t pflash_readl_le(void *opaque, hwaddr addr)
680 {
681     pflash_t *pfl = opaque;
682 
683     return pflash_read(pfl, addr, 4, 0);
684 }
685 
686 static void pflash_writeb_be(void *opaque, hwaddr addr,
687                              uint32_t value)
688 {
689     pflash_write(opaque, addr, value, 1, 1);
690 }
691 
692 static void pflash_writeb_le(void *opaque, hwaddr addr,
693                              uint32_t value)
694 {
695     pflash_write(opaque, addr, value, 1, 0);
696 }
697 
698 static void pflash_writew_be(void *opaque, hwaddr addr,
699                              uint32_t value)
700 {
701     pflash_t *pfl = opaque;
702 
703     pflash_write(pfl, addr, value, 2, 1);
704 }
705 
706 static void pflash_writew_le(void *opaque, hwaddr addr,
707                              uint32_t value)
708 {
709     pflash_t *pfl = opaque;
710 
711     pflash_write(pfl, addr, value, 2, 0);
712 }
713 
714 static void pflash_writel_be(void *opaque, hwaddr addr,
715                              uint32_t value)
716 {
717     pflash_t *pfl = opaque;
718 
719     pflash_write(pfl, addr, value, 4, 1);
720 }
721 
722 static void pflash_writel_le(void *opaque, hwaddr addr,
723                              uint32_t value)
724 {
725     pflash_t *pfl = opaque;
726 
727     pflash_write(pfl, addr, value, 4, 0);
728 }
729 
730 static const MemoryRegionOps pflash_cfi01_ops_be = {
731     .old_mmio = {
732         .read = { pflash_readb_be, pflash_readw_be, pflash_readl_be, },
733         .write = { pflash_writeb_be, pflash_writew_be, pflash_writel_be, },
734     },
735     .endianness = DEVICE_NATIVE_ENDIAN,
736 };
737 
738 static const MemoryRegionOps pflash_cfi01_ops_le = {
739     .old_mmio = {
740         .read = { pflash_readb_le, pflash_readw_le, pflash_readl_le, },
741         .write = { pflash_writeb_le, pflash_writew_le, pflash_writel_le, },
742     },
743     .endianness = DEVICE_NATIVE_ENDIAN,
744 };
745 
746 static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
747 {
748     pflash_t *pfl = CFI_PFLASH01(dev);
749     uint64_t total_len;
750     int ret;
751 
752     total_len = pfl->sector_len * pfl->nb_blocs;
753 
754     /* XXX: to be fixed */
755 #if 0
756     if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) &&
757         total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024))
758         return NULL;
759 #endif
760 
761     memory_region_init_rom_device(
762         &pfl->mem, OBJECT(dev),
763         pfl->be ? &pflash_cfi01_ops_be : &pflash_cfi01_ops_le, pfl,
764         pfl->name, total_len);
765     vmstate_register_ram(&pfl->mem, DEVICE(pfl));
766     pfl->storage = memory_region_get_ram_ptr(&pfl->mem);
767     sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem);
768 
769     if (pfl->bs) {
770         /* read the initial flash content */
771         ret = bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9);
772 
773         if (ret < 0) {
774             vmstate_unregister_ram(&pfl->mem, DEVICE(pfl));
775             memory_region_destroy(&pfl->mem);
776             error_setg(errp, "failed to read the initial flash content");
777             return;
778         }
779     }
780 
781     if (pfl->bs) {
782         pfl->ro = bdrv_is_read_only(pfl->bs);
783     } else {
784         pfl->ro = 0;
785     }
786 
787     /* Default to devices being used at their maximum device width. This was
788      * assumed before the device_width support was added.
789      */
790     if (!pfl->max_device_width) {
791         pfl->max_device_width = pfl->device_width;
792     }
793 
794     pfl->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pflash_timer, pfl);
795     pfl->wcycle = 0;
796     pfl->cmd = 0;
797     pfl->status = 0;
798     /* Hardcoded CFI table */
799     pfl->cfi_len = 0x52;
800     /* Standard "QRY" string */
801     pfl->cfi_table[0x10] = 'Q';
802     pfl->cfi_table[0x11] = 'R';
803     pfl->cfi_table[0x12] = 'Y';
804     /* Command set (Intel) */
805     pfl->cfi_table[0x13] = 0x01;
806     pfl->cfi_table[0x14] = 0x00;
807     /* Primary extended table address (none) */
808     pfl->cfi_table[0x15] = 0x31;
809     pfl->cfi_table[0x16] = 0x00;
810     /* Alternate command set (none) */
811     pfl->cfi_table[0x17] = 0x00;
812     pfl->cfi_table[0x18] = 0x00;
813     /* Alternate extended table (none) */
814     pfl->cfi_table[0x19] = 0x00;
815     pfl->cfi_table[0x1A] = 0x00;
816     /* Vcc min */
817     pfl->cfi_table[0x1B] = 0x45;
818     /* Vcc max */
819     pfl->cfi_table[0x1C] = 0x55;
820     /* Vpp min (no Vpp pin) */
821     pfl->cfi_table[0x1D] = 0x00;
822     /* Vpp max (no Vpp pin) */
823     pfl->cfi_table[0x1E] = 0x00;
824     /* Reserved */
825     pfl->cfi_table[0x1F] = 0x07;
826     /* Timeout for min size buffer write */
827     pfl->cfi_table[0x20] = 0x07;
828     /* Typical timeout for block erase */
829     pfl->cfi_table[0x21] = 0x0a;
830     /* Typical timeout for full chip erase (4096 ms) */
831     pfl->cfi_table[0x22] = 0x00;
832     /* Reserved */
833     pfl->cfi_table[0x23] = 0x04;
834     /* Max timeout for buffer write */
835     pfl->cfi_table[0x24] = 0x04;
836     /* Max timeout for block erase */
837     pfl->cfi_table[0x25] = 0x04;
838     /* Max timeout for chip erase */
839     pfl->cfi_table[0x26] = 0x00;
840     /* Device size */
841     pfl->cfi_table[0x27] = ctz32(total_len); // + 1;
842     /* Flash device interface (8 & 16 bits) */
843     pfl->cfi_table[0x28] = 0x02;
844     pfl->cfi_table[0x29] = 0x00;
845     /* Max number of bytes in multi-bytes write */
846     if (pfl->bank_width == 1) {
847         pfl->cfi_table[0x2A] = 0x08;
848     } else {
849         pfl->cfi_table[0x2A] = 0x0B;
850     }
851     pfl->writeblock_size = 1 << pfl->cfi_table[0x2A];
852 
853     pfl->cfi_table[0x2B] = 0x00;
854     /* Number of erase block regions (uniform) */
855     pfl->cfi_table[0x2C] = 0x01;
856     /* Erase block region 1 */
857     pfl->cfi_table[0x2D] = pfl->nb_blocs - 1;
858     pfl->cfi_table[0x2E] = (pfl->nb_blocs - 1) >> 8;
859     pfl->cfi_table[0x2F] = pfl->sector_len >> 8;
860     pfl->cfi_table[0x30] = pfl->sector_len >> 16;
861 
862     /* Extended */
863     pfl->cfi_table[0x31] = 'P';
864     pfl->cfi_table[0x32] = 'R';
865     pfl->cfi_table[0x33] = 'I';
866 
867     pfl->cfi_table[0x34] = '1';
868     pfl->cfi_table[0x35] = '0';
869 
870     pfl->cfi_table[0x36] = 0x00;
871     pfl->cfi_table[0x37] = 0x00;
872     pfl->cfi_table[0x38] = 0x00;
873     pfl->cfi_table[0x39] = 0x00;
874 
875     pfl->cfi_table[0x3a] = 0x00;
876 
877     pfl->cfi_table[0x3b] = 0x00;
878     pfl->cfi_table[0x3c] = 0x00;
879 
880     pfl->cfi_table[0x3f] = 0x01; /* Number of protection fields */
881 }
882 
883 static Property pflash_cfi01_properties[] = {
884     DEFINE_PROP_DRIVE("drive", struct pflash_t, bs),
885     DEFINE_PROP_UINT32("num-blocks", struct pflash_t, nb_blocs, 0),
886     DEFINE_PROP_UINT64("sector-length", struct pflash_t, sector_len, 0),
887     /* width here is the overall width of this QEMU device in bytes.
888      * The QEMU device may be emulating a number of flash devices
889      * wired up in parallel; the width of each individual flash
890      * device should be specified via device-width. If the individual
891      * devices have a maximum width which is greater than the width
892      * they are being used for, this maximum width should be set via
893      * max-device-width (which otherwise defaults to device-width).
894      * So for instance a 32-bit wide QEMU flash device made from four
895      * 16-bit flash devices used in 8-bit wide mode would be configured
896      * with width = 4, device-width = 1, max-device-width = 2.
897      *
898      * If device-width is not specified we default to backwards
899      * compatible behaviour which is a bad emulation of two
900      * 16 bit devices making up a 32 bit wide QEMU device. This
901      * is deprecated for new uses of this device.
902      */
903     DEFINE_PROP_UINT8("width", struct pflash_t, bank_width, 0),
904     DEFINE_PROP_UINT8("device-width", struct pflash_t, device_width, 0),
905     DEFINE_PROP_UINT8("max-device-width", struct pflash_t, max_device_width, 0),
906     DEFINE_PROP_UINT8("big-endian", struct pflash_t, be, 0),
907     DEFINE_PROP_UINT16("id0", struct pflash_t, ident0, 0),
908     DEFINE_PROP_UINT16("id1", struct pflash_t, ident1, 0),
909     DEFINE_PROP_UINT16("id2", struct pflash_t, ident2, 0),
910     DEFINE_PROP_UINT16("id3", struct pflash_t, ident3, 0),
911     DEFINE_PROP_STRING("name", struct pflash_t, name),
912     DEFINE_PROP_END_OF_LIST(),
913 };
914 
915 static void pflash_cfi01_class_init(ObjectClass *klass, void *data)
916 {
917     DeviceClass *dc = DEVICE_CLASS(klass);
918 
919     dc->realize = pflash_cfi01_realize;
920     dc->props = pflash_cfi01_properties;
921     dc->vmsd = &vmstate_pflash;
922     set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
923 }
924 
925 
926 static const TypeInfo pflash_cfi01_info = {
927     .name           = TYPE_CFI_PFLASH01,
928     .parent         = TYPE_SYS_BUS_DEVICE,
929     .instance_size  = sizeof(struct pflash_t),
930     .class_init     = pflash_cfi01_class_init,
931 };
932 
933 static void pflash_cfi01_register_types(void)
934 {
935     type_register_static(&pflash_cfi01_info);
936 }
937 
938 type_init(pflash_cfi01_register_types)
939 
940 pflash_t *pflash_cfi01_register(hwaddr base,
941                                 DeviceState *qdev, const char *name,
942                                 hwaddr size,
943                                 BlockDriverState *bs,
944                                 uint32_t sector_len, int nb_blocs,
945                                 int bank_width, uint16_t id0, uint16_t id1,
946                                 uint16_t id2, uint16_t id3, int be)
947 {
948     DeviceState *dev = qdev_create(NULL, TYPE_CFI_PFLASH01);
949 
950     if (bs && qdev_prop_set_drive(dev, "drive", bs)) {
951         abort();
952     }
953     qdev_prop_set_uint32(dev, "num-blocks", nb_blocs);
954     qdev_prop_set_uint64(dev, "sector-length", sector_len);
955     qdev_prop_set_uint8(dev, "width", bank_width);
956     qdev_prop_set_uint8(dev, "big-endian", !!be);
957     qdev_prop_set_uint16(dev, "id0", id0);
958     qdev_prop_set_uint16(dev, "id1", id1);
959     qdev_prop_set_uint16(dev, "id2", id2);
960     qdev_prop_set_uint16(dev, "id3", id3);
961     qdev_prop_set_string(dev, "name", name);
962     qdev_init_nofail(dev);
963 
964     sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
965     return CFI_PFLASH01(dev);
966 }
967 
968 MemoryRegion *pflash_cfi01_get_memory(pflash_t *fl)
969 {
970     return &fl->mem;
971 }
972