19e13d632d6b25f74f571b88d78949387429dca5
[sdk/emulator/qemu.git] / hw / pflash_cfi01.c
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.h"
40 #include "flash.h"
41 #include "block.h"
42 #include "qemu-timer.h"
43
44 #define PFLASH_BUG(fmt, ...) \
45 do { \
46     printf("PFLASH: Possible BUG - " fmt, ## __VA_ARGS__); \
47     exit(1); \
48 } while(0)
49
50 /* #define PFLASH_DEBUG */
51 #ifdef PFLASH_DEBUG
52 #define DPRINTF(fmt, ...)                          \
53 do {                                               \
54     printf("PFLASH: " fmt , ## __VA_ARGS__);       \
55 } while (0)
56 #else
57 #define DPRINTF(fmt, ...) do { } while (0)
58 #endif
59
60 struct pflash_t {
61     BlockDriverState *bs;
62     target_phys_addr_t base;
63     target_phys_addr_t sector_len;
64     target_phys_addr_t total_len;
65     int width;
66     int wcycle; /* if 0, the flash is read normally */
67     int bypass;
68     int ro;
69     uint8_t cmd;
70     uint8_t status;
71     uint16_t ident[4];
72     uint8_t cfi_len;
73     uint8_t cfi_table[0x52];
74     target_phys_addr_t counter;
75     unsigned int writeblock_size;
76     QEMUTimer *timer;
77     ram_addr_t off;
78     int fl_mem;
79     void *storage;
80 };
81
82 static void pflash_timer (void *opaque)
83 {
84     pflash_t *pfl = opaque;
85
86     DPRINTF("%s: command %02x done\n", __func__, pfl->cmd);
87     /* Reset flash */
88     pfl->status ^= 0x80;
89     if (pfl->bypass) {
90         pfl->wcycle = 2;
91     } else {
92         cpu_register_physical_memory(pfl->base, pfl->total_len,
93                         pfl->off | IO_MEM_ROMD | pfl->fl_mem);
94         pfl->wcycle = 0;
95     }
96     pfl->cmd = 0;
97 }
98
99 static uint32_t pflash_read (pflash_t *pfl, target_phys_addr_t offset,
100                              int width, int be)
101 {
102     target_phys_addr_t boff;
103     uint32_t ret;
104     uint8_t *p;
105
106     ret = -1;
107     boff = offset & 0xFF; /* why this here ?? */
108
109     if (pfl->width == 2)
110         boff = boff >> 1;
111     else if (pfl->width == 4)
112         boff = boff >> 2;
113
114 #if 0
115     DPRINTF("%s: reading offset " TARGET_FMT_plx " under cmd %02x width %d\n",
116             __func__, offset, pfl->cmd, width);
117 #endif
118     switch (pfl->cmd) {
119     case 0x00:
120         /* Flash area read */
121         p = pfl->storage;
122         switch (width) {
123         case 1:
124             ret = p[offset];
125             DPRINTF("%s: data offset " TARGET_FMT_plx " %02x\n",
126                     __func__, offset, ret);
127             break;
128         case 2:
129             if (be) {
130                 ret = p[offset] << 8;
131                 ret |= p[offset + 1];
132             } else {
133                 ret = p[offset];
134                 ret |= p[offset + 1] << 8;
135             }
136             DPRINTF("%s: data offset " TARGET_FMT_plx " %04x\n",
137                     __func__, offset, ret);
138             break;
139         case 4:
140             if (be) {
141                 ret = p[offset] << 24;
142                 ret |= p[offset + 1] << 16;
143                 ret |= p[offset + 2] << 8;
144                 ret |= p[offset + 3];
145             } else {
146                 ret = p[offset];
147                 ret |= p[offset + 1] << 8;
148                 ret |= p[offset + 1] << 8;
149                 ret |= p[offset + 2] << 16;
150                 ret |= p[offset + 3] << 24;
151             }
152             DPRINTF("%s: data offset " TARGET_FMT_plx " %08x\n",
153                     __func__, offset, ret);
154             break;
155         default:
156             DPRINTF("BUG in %s\n", __func__);
157         }
158
159         break;
160     case 0x20: /* Block erase */
161     case 0x50: /* Clear status register */
162     case 0x60: /* Block /un)lock */
163     case 0x70: /* Status Register */
164     case 0xe8: /* Write block */
165         /* Status register read */
166         ret = pfl->status;
167         DPRINTF("%s: status %x\n", __func__, ret);
168         break;
169     case 0x90:
170         switch (boff) {
171         case 0:
172             ret = pfl->ident[0] << 8 | pfl->ident[1];
173             DPRINTF("%s: Manufacturer Code %04x\n", __func__, ret);
174             break;
175         case 1:
176             ret = pfl->ident[2] << 8 | pfl->ident[3];
177             DPRINTF("%s: Device ID Code %04x\n", __func__, ret);
178             break;
179         default:
180             DPRINTF("%s: Read Device Information boff=%x\n", __func__, boff);
181             ret = 0;
182             break;
183         }
184         break;
185     case 0x98: /* Query mode */
186         if (boff > pfl->cfi_len)
187             ret = 0;
188         else
189             ret = pfl->cfi_table[boff];
190         break;
191     default:
192         /* This should never happen : reset state & treat it as a read */
193         DPRINTF("%s: unknown command state: %x\n", __func__, pfl->cmd);
194         pfl->wcycle = 0;
195         pfl->cmd = 0;
196     }
197     return ret;
198 }
199
200 /* update flash content on disk */
201 static void pflash_update(pflash_t *pfl, int offset,
202                           int size)
203 {
204     int offset_end;
205     if (pfl->bs) {
206         offset_end = offset + size;
207         /* round to sectors */
208         offset = offset >> 9;
209         offset_end = (offset_end + 511) >> 9;
210         bdrv_write(pfl->bs, offset, pfl->storage + (offset << 9),
211                    offset_end - offset);
212     }
213 }
214
215 static inline void pflash_data_write(pflash_t *pfl, target_phys_addr_t offset,
216                                      uint32_t value, int width, int be)
217 {
218     uint8_t *p = pfl->storage;
219
220     DPRINTF("%s: block write offset " TARGET_FMT_plx
221             " value %x counter " TARGET_FMT_plx "\n",
222             __func__, offset, value, pfl->counter);
223     switch (width) {
224     case 1:
225         p[offset] = value;
226         break;
227     case 2:
228         if (be) {
229             p[offset] = value >> 8;
230             p[offset + 1] = value;
231         } else {
232             p[offset] = value;
233             p[offset + 1] = value >> 8;
234         }
235         break;
236     case 4:
237         if (be) {
238             p[offset] = value >> 24;
239             p[offset + 1] = value >> 16;
240             p[offset + 2] = value >> 8;
241             p[offset + 3] = value;
242         } else {
243             p[offset] = value;
244             p[offset + 1] = value >> 8;
245             p[offset + 2] = value >> 16;
246             p[offset + 3] = value >> 24;
247         }
248         break;
249     }
250
251 }
252
253 static void pflash_write(pflash_t *pfl, target_phys_addr_t offset,
254                          uint32_t value, int width, int be)
255 {
256     uint8_t *p;
257     uint8_t cmd;
258
259     cmd = value;
260
261     DPRINTF("%s: writing offset " TARGET_FMT_plx " value %08x width %d wcycle 0x%x\n",
262             __func__, offset, value, width, pfl->wcycle);
263
264     if (!pfl->wcycle) {
265         /* Set the device in I/O access mode */
266         cpu_register_physical_memory(pfl->base, pfl->total_len, pfl->fl_mem);
267     }
268
269     switch (pfl->wcycle) {
270     case 0:
271         /* read mode */
272         switch (cmd) {
273         case 0x00: /* ??? */
274             goto reset_flash;
275         case 0x10: /* Single Byte Program */
276         case 0x40: /* Single Byte Program */
277             DPRINTF("%s: Single Byte Program\n", __func__);
278             break;
279         case 0x20: /* Block erase */
280             p = pfl->storage;
281             offset &= ~(pfl->sector_len - 1);
282
283             DPRINTF("%s: block erase at " TARGET_FMT_plx " bytes "
284                     TARGET_FMT_plx "\n",
285                     __func__, offset, pfl->sector_len);
286
287             memset(p + offset, 0xff, pfl->sector_len);
288             pflash_update(pfl, offset, pfl->sector_len);
289             pfl->status |= 0x80; /* Ready! */
290             break;
291         case 0x50: /* Clear status bits */
292             DPRINTF("%s: Clear status bits\n", __func__);
293             pfl->status = 0x0;
294             goto reset_flash;
295         case 0x60: /* Block (un)lock */
296             DPRINTF("%s: Block unlock\n", __func__);
297             break;
298         case 0x70: /* Status Register */
299             DPRINTF("%s: Read status register\n", __func__);
300             pfl->cmd = cmd;
301             return;
302         case 0x90: /* Read Device ID */
303             DPRINTF("%s: Read Device information\n", __func__);
304             pfl->cmd = cmd;
305             return;
306         case 0x98: /* CFI query */
307             DPRINTF("%s: CFI query\n", __func__);
308             break;
309         case 0xe8: /* Write to buffer */
310             DPRINTF("%s: Write to buffer\n", __func__);
311             pfl->status |= 0x80; /* Ready! */
312             break;
313         case 0xff: /* Read array mode */
314             DPRINTF("%s: Read array mode\n", __func__);
315             goto reset_flash;
316         default:
317             goto error_flash;
318         }
319         pfl->wcycle++;
320         pfl->cmd = cmd;
321         return;
322     case 1:
323         switch (pfl->cmd) {
324         case 0x10: /* Single Byte Program */
325         case 0x40: /* Single Byte Program */
326             DPRINTF("%s: Single Byte Program\n", __func__);
327             pflash_data_write(pfl, offset, value, width, be);
328             pflash_update(pfl, offset, width);
329             pfl->status |= 0x80; /* Ready! */
330             pfl->wcycle = 0;
331         break;
332         case 0x20: /* Block erase */
333         case 0x28:
334             if (cmd == 0xd0) { /* confirm */
335                 pfl->wcycle = 0;
336                 pfl->status |= 0x80;
337             } else if (cmd == 0xff) { /* read array mode */
338                 goto reset_flash;
339             } else
340                 goto error_flash;
341
342             break;
343         case 0xe8:
344             DPRINTF("%s: block write of %x bytes\n", __func__, value);
345             pfl->counter = value;
346             pfl->wcycle++;
347             break;
348         case 0x60:
349             if (cmd == 0xd0) {
350                 pfl->wcycle = 0;
351                 pfl->status |= 0x80;
352             } else if (cmd == 0x01) {
353                 pfl->wcycle = 0;
354                 pfl->status |= 0x80;
355             } else if (cmd == 0xff) {
356                 goto reset_flash;
357             } else {
358                 DPRINTF("%s: Unknown (un)locking command\n", __func__);
359                 goto reset_flash;
360             }
361             break;
362         case 0x98:
363             if (cmd == 0xff) {
364                 goto reset_flash;
365             } else {
366                 DPRINTF("%s: leaving query mode\n", __func__);
367             }
368             break;
369         default:
370             goto error_flash;
371         }
372         return;
373     case 2:
374         switch (pfl->cmd) {
375         case 0xe8: /* Block write */
376             pflash_data_write(pfl, offset, value, width, be);
377
378             pfl->status |= 0x80;
379
380             if (!pfl->counter) {
381                 target_phys_addr_t mask = pfl->writeblock_size - 1;
382                 mask = ~mask;
383
384                 DPRINTF("%s: block write finished\n", __func__);
385                 pfl->wcycle++;
386                 /* Flush the entire write buffer onto backing storage.  */
387                 pflash_update(pfl, offset & mask, pfl->writeblock_size);
388             }
389
390             pfl->counter--;
391             break;
392         default:
393             goto error_flash;
394         }
395         return;
396     case 3: /* Confirm mode */
397         switch (pfl->cmd) {
398         case 0xe8: /* Block write */
399             if (cmd == 0xd0) {
400                 pfl->wcycle = 0;
401                 pfl->status |= 0x80;
402             } else {
403                 DPRINTF("%s: unknown command for \"write block\"\n", __func__);
404                 PFLASH_BUG("Write block confirm");
405                 goto reset_flash;
406             }
407             break;
408         default:
409             goto error_flash;
410         }
411         return;
412     default:
413         /* Should never happen */
414         DPRINTF("%s: invalid write state\n",  __func__);
415         goto reset_flash;
416     }
417     return;
418
419  error_flash:
420     printf("%s: Unimplemented flash cmd sequence "
421            "(offset " TARGET_FMT_plx ", wcycle 0x%x cmd 0x%x value 0x%x)\n",
422            __func__, offset, pfl->wcycle, pfl->cmd, value);
423
424  reset_flash:
425     cpu_register_physical_memory(pfl->base, pfl->total_len,
426                     pfl->off | IO_MEM_ROMD | pfl->fl_mem);
427
428     pfl->bypass = 0;
429     pfl->wcycle = 0;
430     pfl->cmd = 0;
431     return;
432 }
433
434
435 static uint32_t pflash_readb_be(void *opaque, target_phys_addr_t addr)
436 {
437     return pflash_read(opaque, addr, 1, 1);
438 }
439
440 static uint32_t pflash_readb_le(void *opaque, target_phys_addr_t addr)
441 {
442     return pflash_read(opaque, addr, 1, 0);
443 }
444
445 static uint32_t pflash_readw_be(void *opaque, target_phys_addr_t addr)
446 {
447     pflash_t *pfl = opaque;
448
449     return pflash_read(pfl, addr, 2, 1);
450 }
451
452 static uint32_t pflash_readw_le(void *opaque, target_phys_addr_t addr)
453 {
454     pflash_t *pfl = opaque;
455
456     return pflash_read(pfl, addr, 2, 0);
457 }
458
459 static uint32_t pflash_readl_be(void *opaque, target_phys_addr_t addr)
460 {
461     pflash_t *pfl = opaque;
462
463     return pflash_read(pfl, addr, 4, 1);
464 }
465
466 static uint32_t pflash_readl_le(void *opaque, target_phys_addr_t addr)
467 {
468     pflash_t *pfl = opaque;
469
470     return pflash_read(pfl, addr, 4, 0);
471 }
472
473 static void pflash_writeb_be(void *opaque, target_phys_addr_t addr,
474                              uint32_t value)
475 {
476     pflash_write(opaque, addr, value, 1, 1);
477 }
478
479 static void pflash_writeb_le(void *opaque, target_phys_addr_t addr,
480                              uint32_t value)
481 {
482     pflash_write(opaque, addr, value, 1, 0);
483 }
484
485 static void pflash_writew_be(void *opaque, target_phys_addr_t addr,
486                              uint32_t value)
487 {
488     pflash_t *pfl = opaque;
489
490     pflash_write(pfl, addr, value, 2, 1);
491 }
492
493 static void pflash_writew_le(void *opaque, target_phys_addr_t addr,
494                              uint32_t value)
495 {
496     pflash_t *pfl = opaque;
497
498     pflash_write(pfl, addr, value, 2, 0);
499 }
500
501 static void pflash_writel_be(void *opaque, target_phys_addr_t addr,
502                              uint32_t value)
503 {
504     pflash_t *pfl = opaque;
505
506     pflash_write(pfl, addr, value, 4, 1);
507 }
508
509 static void pflash_writel_le(void *opaque, target_phys_addr_t addr,
510                              uint32_t value)
511 {
512     pflash_t *pfl = opaque;
513
514     pflash_write(pfl, addr, value, 4, 0);
515 }
516
517 static CPUWriteMemoryFunc * const pflash_write_ops_be[] = {
518     &pflash_writeb_be,
519     &pflash_writew_be,
520     &pflash_writel_be,
521 };
522
523 static CPUReadMemoryFunc * const pflash_read_ops_be[] = {
524     &pflash_readb_be,
525     &pflash_readw_be,
526     &pflash_readl_be,
527 };
528
529 static CPUWriteMemoryFunc * const pflash_write_ops_le[] = {
530     &pflash_writeb_le,
531     &pflash_writew_le,
532     &pflash_writel_le,
533 };
534
535 static CPUReadMemoryFunc * const pflash_read_ops_le[] = {
536     &pflash_readb_le,
537     &pflash_readw_le,
538     &pflash_readl_le,
539 };
540
541 /* Count trailing zeroes of a 32 bits quantity */
542 static int ctz32 (uint32_t n)
543 {
544     int ret;
545
546     ret = 0;
547     if (!(n & 0xFFFF)) {
548         ret += 16;
549         n = n >> 16;
550     }
551     if (!(n & 0xFF)) {
552         ret += 8;
553         n = n >> 8;
554     }
555     if (!(n & 0xF)) {
556         ret += 4;
557         n = n >> 4;
558     }
559     if (!(n & 0x3)) {
560         ret += 2;
561         n = n >> 2;
562     }
563     if (!(n & 0x1)) {
564         ret++;
565 #if 0 /* This is not necessary as n is never 0 */
566         n = n >> 1;
567 #endif
568     }
569 #if 0 /* This is not necessary as n is never 0 */
570     if (!n)
571         ret++;
572 #endif
573
574     return ret;
575 }
576
577 pflash_t *pflash_cfi01_register(target_phys_addr_t base, ram_addr_t off,
578                                 BlockDriverState *bs, uint32_t sector_len,
579                                 int nb_blocs, int width,
580                                 uint16_t id0, uint16_t id1,
581                                 uint16_t id2, uint16_t id3,
582                                 int be)
583 {
584     pflash_t *pfl;
585     target_phys_addr_t total_len;
586     int ret;
587
588     total_len = sector_len * nb_blocs;
589
590     /* XXX: to be fixed */
591 #if 0
592     if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) &&
593         total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024))
594         return NULL;
595 #endif
596
597     pfl = qemu_mallocz(sizeof(pflash_t));
598
599     /* FIXME: Allocate ram ourselves.  */
600     pfl->storage = qemu_get_ram_ptr(off);
601     if (be) {
602         pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_be,
603                                              pflash_write_ops_be, pfl);
604     } else {
605         pfl->fl_mem = cpu_register_io_memory(pflash_read_ops_le,
606                                              pflash_write_ops_le, pfl);
607     }
608     pfl->off = off;
609     cpu_register_physical_memory(base, total_len,
610                     off | pfl->fl_mem | IO_MEM_ROMD);
611
612     pfl->bs = bs;
613     if (pfl->bs) {
614         /* read the initial flash content */
615         ret = bdrv_read(pfl->bs, 0, pfl->storage, total_len >> 9);
616         if (ret < 0) {
617             cpu_unregister_io_memory(pfl->fl_mem);
618             qemu_free(pfl);
619             return NULL;
620         }
621     }
622 #if 0 /* XXX: there should be a bit to set up read-only,
623        *      the same way the hardware does (with WP pin).
624        */
625     pfl->ro = 1;
626 #else
627     pfl->ro = 0;
628 #endif
629     pfl->timer = qemu_new_timer(vm_clock, pflash_timer, pfl);
630     pfl->base = base;
631     pfl->sector_len = sector_len;
632     pfl->total_len = total_len;
633     pfl->width = width;
634     pfl->wcycle = 0;
635     pfl->cmd = 0;
636     pfl->status = 0;
637     pfl->ident[0] = id0;
638     pfl->ident[1] = id1;
639     pfl->ident[2] = id2;
640     pfl->ident[3] = id3;
641     /* Hardcoded CFI table */
642     pfl->cfi_len = 0x52;
643     /* Standard "QRY" string */
644     pfl->cfi_table[0x10] = 'Q';
645     pfl->cfi_table[0x11] = 'R';
646     pfl->cfi_table[0x12] = 'Y';
647     /* Command set (Intel) */
648     pfl->cfi_table[0x13] = 0x01;
649     pfl->cfi_table[0x14] = 0x00;
650     /* Primary extended table address (none) */
651     pfl->cfi_table[0x15] = 0x31;
652     pfl->cfi_table[0x16] = 0x00;
653     /* Alternate command set (none) */
654     pfl->cfi_table[0x17] = 0x00;
655     pfl->cfi_table[0x18] = 0x00;
656     /* Alternate extended table (none) */
657     pfl->cfi_table[0x19] = 0x00;
658     pfl->cfi_table[0x1A] = 0x00;
659     /* Vcc min */
660     pfl->cfi_table[0x1B] = 0x45;
661     /* Vcc max */
662     pfl->cfi_table[0x1C] = 0x55;
663     /* Vpp min (no Vpp pin) */
664     pfl->cfi_table[0x1D] = 0x00;
665     /* Vpp max (no Vpp pin) */
666     pfl->cfi_table[0x1E] = 0x00;
667     /* Reserved */
668     pfl->cfi_table[0x1F] = 0x07;
669     /* Timeout for min size buffer write */
670     pfl->cfi_table[0x20] = 0x07;
671     /* Typical timeout for block erase */
672     pfl->cfi_table[0x21] = 0x0a;
673     /* Typical timeout for full chip erase (4096 ms) */
674     pfl->cfi_table[0x22] = 0x00;
675     /* Reserved */
676     pfl->cfi_table[0x23] = 0x04;
677     /* Max timeout for buffer write */
678     pfl->cfi_table[0x24] = 0x04;
679     /* Max timeout for block erase */
680     pfl->cfi_table[0x25] = 0x04;
681     /* Max timeout for chip erase */
682     pfl->cfi_table[0x26] = 0x00;
683     /* Device size */
684     pfl->cfi_table[0x27] = ctz32(total_len); // + 1;
685     /* Flash device interface (8 & 16 bits) */
686     pfl->cfi_table[0x28] = 0x02;
687     pfl->cfi_table[0x29] = 0x00;
688     /* Max number of bytes in multi-bytes write */
689     if (width == 1) {
690         pfl->cfi_table[0x2A] = 0x08;
691     } else {
692         pfl->cfi_table[0x2A] = 0x0B;
693     }
694     pfl->writeblock_size = 1 << pfl->cfi_table[0x2A];
695
696     pfl->cfi_table[0x2B] = 0x00;
697     /* Number of erase block regions (uniform) */
698     pfl->cfi_table[0x2C] = 0x01;
699     /* Erase block region 1 */
700     pfl->cfi_table[0x2D] = nb_blocs - 1;
701     pfl->cfi_table[0x2E] = (nb_blocs - 1) >> 8;
702     pfl->cfi_table[0x2F] = sector_len >> 8;
703     pfl->cfi_table[0x30] = sector_len >> 16;
704
705     /* Extended */
706     pfl->cfi_table[0x31] = 'P';
707     pfl->cfi_table[0x32] = 'R';
708     pfl->cfi_table[0x33] = 'I';
709
710     pfl->cfi_table[0x34] = '1';
711     pfl->cfi_table[0x35] = '1';
712
713     pfl->cfi_table[0x36] = 0x00;
714     pfl->cfi_table[0x37] = 0x00;
715     pfl->cfi_table[0x38] = 0x00;
716     pfl->cfi_table[0x39] = 0x00;
717
718     pfl->cfi_table[0x3a] = 0x00;
719
720     pfl->cfi_table[0x3b] = 0x00;
721     pfl->cfi_table[0x3c] = 0x00;
722
723     return pfl;
724 }