2 * CFI parallel flash with AMD command set emulation
4 * Copyright (c) 2005 Jocelyn Mayer
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, see <http://www.gnu.org/licenses/>.
21 * For now, this code can emulate flashes of 1, 2 or 4 bytes width.
22 * Supported commands/modes are:
28 * - unlock bypass command
31 * It does not support flash interleaving.
32 * It does not implement boot blocs with reduced size
33 * It does not implement software data protection as found in many real chips
34 * It does not implement erase suspend/resume commands
35 * It does not implement multiple sectors erase
38 #include "qemu/osdep.h"
40 #include "hw/block/block.h"
41 #include "hw/block/flash.h"
42 #include "qapi/error.h"
43 #include "qemu/timer.h"
44 #include "sysemu/block-backend.h"
45 #include "qemu/host-utils.h"
46 #include "hw/sysbus.h"
49 //#define PFLASH_DEBUG
51 #define DPRINTF(fmt, ...) \
53 fprintf(stderr, "PFLASH: " fmt , ## __VA_ARGS__); \
56 #define DPRINTF(fmt, ...) do { } while (0)
59 #define PFLASH_LAZY_ROMD_THRESHOLD 42
63 SysBusDevice parent_obj;
73 int wcycle; /* if 0, the flash is read normally */
78 /* FIXME: implement array device properties */
83 uint16_t unlock_addr0;
84 uint16_t unlock_addr1;
85 uint8_t cfi_table[0x52];
87 /* The device replicates the flash memory across its memory space. Emulate
88 * that by having a container (.mem) filled with an array of aliases
89 * (.mem_mappings) pointing to the flash memory (.orig_mem).
92 MemoryRegion *mem_mappings; /* array; one per mapping */
93 MemoryRegion orig_mem;
95 int read_counter; /* used for lazy switch-back to rom mode */
101 * Set up replicated mappings of the same region.
103 static void pflash_setup_mappings(PFlashCFI02 *pfl)
106 hwaddr size = memory_region_size(&pfl->orig_mem);
108 memory_region_init(&pfl->mem, OBJECT(pfl), "pflash", pfl->mappings * size);
109 pfl->mem_mappings = g_new(MemoryRegion, pfl->mappings);
110 for (i = 0; i < pfl->mappings; ++i) {
111 memory_region_init_alias(&pfl->mem_mappings[i], OBJECT(pfl),
112 "pflash-alias", &pfl->orig_mem, 0, size);
113 memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]);
117 static void pflash_register_memory(PFlashCFI02 *pfl, int rom_mode)
119 memory_region_rom_device_set_romd(&pfl->orig_mem, rom_mode);
120 pfl->rom_mode = rom_mode;
123 static void pflash_timer (void *opaque)
125 PFlashCFI02 *pfl = opaque;
127 trace_pflash_timer_expired(pfl->cmd);
133 pflash_register_memory(pfl, 1);
139 static uint32_t pflash_read(PFlashCFI02 *pfl, hwaddr offset,
147 trace_pflash_read(offset, pfl->cmd, width, pfl->wcycle);
148 /* Lazy reset to ROMD mode after a certain amount of read accesses */
149 if (!pfl->rom_mode && pfl->wcycle == 0 &&
150 ++pfl->read_counter > PFLASH_LAZY_ROMD_THRESHOLD) {
151 pflash_register_memory(pfl, 1);
153 offset &= pfl->chip_len - 1;
154 boff = offset & 0xFF;
157 else if (pfl->width == 4)
161 /* This should never happen : reset state & treat it as a read*/
162 DPRINTF("%s: unknown command state: %x\n", __func__, pfl->cmd);
165 /* fall through to the read code */
167 /* We accept reads during second unlock sequence... */
170 /* Flash area read */
175 trace_pflash_data_read8(offset, ret);
179 ret = p[offset] << 8;
180 ret |= p[offset + 1];
183 ret |= p[offset + 1] << 8;
185 trace_pflash_data_read16(offset, ret);
189 ret = p[offset] << 24;
190 ret |= p[offset + 1] << 16;
191 ret |= p[offset + 2] << 8;
192 ret |= p[offset + 3];
195 ret |= p[offset + 1] << 8;
196 ret |= p[offset + 2] << 16;
197 ret |= p[offset + 3] << 24;
199 trace_pflash_data_read32(offset, ret);
208 ret = boff & 0x01 ? pfl->ident1 : pfl->ident0;
211 ret = 0x00; /* Pretend all sectors are unprotected */
215 ret = boff & 0x01 ? pfl->ident3 : pfl->ident2;
216 if (ret == (uint8_t)-1) {
223 DPRINTF("%s: ID " TARGET_FMT_plx " %x\n", __func__, boff, ret);
228 /* Status register read */
230 DPRINTF("%s: status %x\n", __func__, ret);
236 if (boff < sizeof(pfl->cfi_table)) {
237 ret = pfl->cfi_table[boff];
247 /* update flash content on disk */
248 static void pflash_update(PFlashCFI02 *pfl, int offset,
253 offset_end = offset + size;
254 /* widen to sector boundaries */
255 offset = QEMU_ALIGN_DOWN(offset, BDRV_SECTOR_SIZE);
256 offset_end = QEMU_ALIGN_UP(offset_end, BDRV_SECTOR_SIZE);
257 blk_pwrite(pfl->blk, offset, pfl->storage + offset,
258 offset_end - offset, 0);
262 static void pflash_write(PFlashCFI02 *pfl, hwaddr offset,
263 uint32_t value, int width, int be)
270 if (pfl->cmd != 0xA0 && cmd == 0xF0) {
272 DPRINTF("%s: flash reset asked (%02x %02x)\n",
273 __func__, pfl->cmd, cmd);
277 trace_pflash_write(offset, value, width, pfl->wcycle);
278 offset &= pfl->chip_len - 1;
280 DPRINTF("%s: offset " TARGET_FMT_plx " %08x %d\n", __func__,
281 offset, value, width);
282 boff = offset & (pfl->sector_len - 1);
285 else if (pfl->width == 4)
287 switch (pfl->wcycle) {
289 /* Set the device in I/O access mode if required */
291 pflash_register_memory(pfl, 0);
292 pfl->read_counter = 0;
293 /* We're in read mode */
295 if (boff == 0x55 && cmd == 0x98) {
297 /* Enter CFI query mode */
302 if (boff != pfl->unlock_addr0 || cmd != 0xAA) {
303 DPRINTF("%s: unlock0 failed " TARGET_FMT_plx " %02x %04x\n",
304 __func__, boff, cmd, pfl->unlock_addr0);
307 DPRINTF("%s: unlock sequence started\n", __func__);
310 /* We started an unlock sequence */
312 if (boff != pfl->unlock_addr1 || cmd != 0x55) {
313 DPRINTF("%s: unlock1 failed " TARGET_FMT_plx " %02x\n", __func__,
317 DPRINTF("%s: unlock sequence done\n", __func__);
320 /* We finished an unlock sequence */
321 if (!pfl->bypass && boff != pfl->unlock_addr0) {
322 DPRINTF("%s: command failed " TARGET_FMT_plx " %02x\n", __func__,
334 DPRINTF("%s: starting command %02x\n", __func__, cmd);
337 DPRINTF("%s: unknown command %02x\n", __func__, cmd);
344 /* We need another unlock sequence */
347 trace_pflash_data_write(offset, value, width, 0);
353 pflash_update(pfl, offset, 1);
357 p[offset] &= value >> 8;
358 p[offset + 1] &= value;
361 p[offset + 1] &= value >> 8;
363 pflash_update(pfl, offset, 2);
367 p[offset] &= value >> 24;
368 p[offset + 1] &= value >> 16;
369 p[offset + 2] &= value >> 8;
370 p[offset + 3] &= value;
373 p[offset + 1] &= value >> 8;
374 p[offset + 2] &= value >> 16;
375 p[offset + 3] &= value >> 24;
377 pflash_update(pfl, offset, 4);
381 pfl->status = 0x00 | ~(value & 0x80);
382 /* Let's pretend write is immediate */
387 if (pfl->bypass && cmd == 0x00) {
388 /* Unlock bypass reset */
391 /* We can enter CFI query mode from autoselect mode */
392 if (boff == 0x55 && cmd == 0x98)
396 DPRINTF("%s: invalid write for command %02x\n",
403 /* Ignore writes while flash data write is occurring */
404 /* As we suppose write is immediate, this should never happen */
409 /* Should never happen */
410 DPRINTF("%s: invalid command state %02x (wc 4)\n",
418 if (boff != pfl->unlock_addr0) {
419 DPRINTF("%s: chip erase: invalid address " TARGET_FMT_plx "\n",
424 DPRINTF("%s: start chip erase\n", __func__);
426 memset(pfl->storage, 0xFF, pfl->chip_len);
427 pflash_update(pfl, 0, pfl->chip_len);
430 /* Let's wait 5 seconds before chip erase is done */
431 timer_mod(&pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
432 (NANOSECONDS_PER_SECOND * 5));
437 offset &= ~(pfl->sector_len - 1);
438 DPRINTF("%s: start sector erase at " TARGET_FMT_plx "\n", __func__,
441 memset(p + offset, 0xFF, pfl->sector_len);
442 pflash_update(pfl, offset, pfl->sector_len);
445 /* Let's wait 1/2 second before sector erase is done */
446 timer_mod(&pfl->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) +
447 (NANOSECONDS_PER_SECOND / 2));
450 DPRINTF("%s: invalid command %02x (wc 5)\n", __func__, cmd);
458 /* Ignore writes during chip erase */
461 /* Ignore writes during sector erase */
464 /* Should never happen */
465 DPRINTF("%s: invalid command state %02x (wc 6)\n",
470 case 7: /* Special value for CFI queries */
471 DPRINTF("%s: invalid write in CFI query mode\n", __func__);
474 /* Should never happen */
475 DPRINTF("%s: invalid write state (wc 7)\n", __func__);
484 trace_pflash_reset();
495 static uint64_t pflash_be_readfn(void *opaque, hwaddr addr, unsigned size)
497 return pflash_read(opaque, addr, size, 1);
500 static void pflash_be_writefn(void *opaque, hwaddr addr,
501 uint64_t value, unsigned size)
503 pflash_write(opaque, addr, value, size, 1);
506 static uint64_t pflash_le_readfn(void *opaque, hwaddr addr, unsigned size)
508 return pflash_read(opaque, addr, size, 0);
511 static void pflash_le_writefn(void *opaque, hwaddr addr,
512 uint64_t value, unsigned size)
514 pflash_write(opaque, addr, value, size, 0);
517 static const MemoryRegionOps pflash_cfi02_ops_be = {
518 .read = pflash_be_readfn,
519 .write = pflash_be_writefn,
520 .valid.min_access_size = 1,
521 .valid.max_access_size = 4,
522 .endianness = DEVICE_NATIVE_ENDIAN,
525 static const MemoryRegionOps pflash_cfi02_ops_le = {
526 .read = pflash_le_readfn,
527 .write = pflash_le_writefn,
528 .valid.min_access_size = 1,
529 .valid.max_access_size = 4,
530 .endianness = DEVICE_NATIVE_ENDIAN,
533 static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
535 PFlashCFI02 *pfl = PFLASH_CFI02(dev);
538 Error *local_err = NULL;
540 if (pfl->sector_len == 0) {
541 error_setg(errp, "attribute \"sector-length\" not specified or zero.");
544 if (pfl->nb_blocs == 0) {
545 error_setg(errp, "attribute \"num-blocks\" not specified or zero.");
548 if (pfl->name == NULL) {
549 error_setg(errp, "attribute \"name\" not specified.");
553 chip_len = pfl->sector_len * pfl->nb_blocs;
554 /* XXX: to be fixed */
556 if (total_len != (8 * 1024 * 1024) && total_len != (16 * 1024 * 1024) &&
557 total_len != (32 * 1024 * 1024) && total_len != (64 * 1024 * 1024))
561 memory_region_init_rom_device(&pfl->orig_mem, OBJECT(pfl), pfl->be ?
562 &pflash_cfi02_ops_be : &pflash_cfi02_ops_le,
563 pfl, pfl->name, chip_len, &local_err);
565 error_propagate(errp, local_err);
569 pfl->storage = memory_region_get_ram_ptr(&pfl->orig_mem);
570 pfl->chip_len = chip_len;
574 pfl->ro = blk_is_read_only(pfl->blk);
575 perm = BLK_PERM_CONSISTENT_READ | (pfl->ro ? 0 : BLK_PERM_WRITE);
576 ret = blk_set_perm(pfl->blk, perm, BLK_PERM_ALL, errp);
585 if (!blk_check_size_and_read_all(pfl->blk, pfl->storage, chip_len,
587 vmstate_unregister_ram(&pfl->orig_mem, DEVICE(pfl));
592 pflash_setup_mappings(pfl);
594 sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem);
596 timer_init_ns(&pfl->timer, QEMU_CLOCK_VIRTUAL, pflash_timer, pfl);
600 /* Hardcoded CFI table (mostly from SG29 Spansion flash) */
601 /* Standard "QRY" string */
602 pfl->cfi_table[0x10] = 'Q';
603 pfl->cfi_table[0x11] = 'R';
604 pfl->cfi_table[0x12] = 'Y';
605 /* Command set (AMD/Fujitsu) */
606 pfl->cfi_table[0x13] = 0x02;
607 pfl->cfi_table[0x14] = 0x00;
608 /* Primary extended table address */
609 pfl->cfi_table[0x15] = 0x31;
610 pfl->cfi_table[0x16] = 0x00;
611 /* Alternate command set (none) */
612 pfl->cfi_table[0x17] = 0x00;
613 pfl->cfi_table[0x18] = 0x00;
614 /* Alternate extended table (none) */
615 pfl->cfi_table[0x19] = 0x00;
616 pfl->cfi_table[0x1A] = 0x00;
618 pfl->cfi_table[0x1B] = 0x27;
620 pfl->cfi_table[0x1C] = 0x36;
621 /* Vpp min (no Vpp pin) */
622 pfl->cfi_table[0x1D] = 0x00;
623 /* Vpp max (no Vpp pin) */
624 pfl->cfi_table[0x1E] = 0x00;
626 pfl->cfi_table[0x1F] = 0x07;
627 /* Timeout for min size buffer write (NA) */
628 pfl->cfi_table[0x20] = 0x00;
629 /* Typical timeout for block erase (512 ms) */
630 pfl->cfi_table[0x21] = 0x09;
631 /* Typical timeout for full chip erase (4096 ms) */
632 pfl->cfi_table[0x22] = 0x0C;
634 pfl->cfi_table[0x23] = 0x01;
635 /* Max timeout for buffer write (NA) */
636 pfl->cfi_table[0x24] = 0x00;
637 /* Max timeout for block erase */
638 pfl->cfi_table[0x25] = 0x0A;
639 /* Max timeout for chip erase */
640 pfl->cfi_table[0x26] = 0x0D;
642 pfl->cfi_table[0x27] = ctz32(chip_len);
643 /* Flash device interface (8 & 16 bits) */
644 pfl->cfi_table[0x28] = 0x02;
645 pfl->cfi_table[0x29] = 0x00;
646 /* Max number of bytes in multi-bytes write */
647 /* XXX: disable buffered write as it's not supported */
648 // pfl->cfi_table[0x2A] = 0x05;
649 pfl->cfi_table[0x2A] = 0x00;
650 pfl->cfi_table[0x2B] = 0x00;
651 /* Number of erase block regions (uniform) */
652 pfl->cfi_table[0x2C] = 0x01;
653 /* Erase block region 1 */
654 pfl->cfi_table[0x2D] = pfl->nb_blocs - 1;
655 pfl->cfi_table[0x2E] = (pfl->nb_blocs - 1) >> 8;
656 pfl->cfi_table[0x2F] = pfl->sector_len >> 8;
657 pfl->cfi_table[0x30] = pfl->sector_len >> 16;
660 pfl->cfi_table[0x31] = 'P';
661 pfl->cfi_table[0x32] = 'R';
662 pfl->cfi_table[0x33] = 'I';
664 pfl->cfi_table[0x34] = '1';
665 pfl->cfi_table[0x35] = '0';
667 pfl->cfi_table[0x36] = 0x00;
668 pfl->cfi_table[0x37] = 0x00;
669 pfl->cfi_table[0x38] = 0x00;
670 pfl->cfi_table[0x39] = 0x00;
672 pfl->cfi_table[0x3a] = 0x00;
674 pfl->cfi_table[0x3b] = 0x00;
675 pfl->cfi_table[0x3c] = 0x00;
678 static Property pflash_cfi02_properties[] = {
679 DEFINE_PROP_DRIVE("drive", PFlashCFI02, blk),
680 DEFINE_PROP_UINT32("num-blocks", PFlashCFI02, nb_blocs, 0),
681 DEFINE_PROP_UINT32("sector-length", PFlashCFI02, sector_len, 0),
682 DEFINE_PROP_UINT8("width", PFlashCFI02, width, 0),
683 DEFINE_PROP_UINT8("mappings", PFlashCFI02, mappings, 0),
684 DEFINE_PROP_UINT8("big-endian", PFlashCFI02, be, 0),
685 DEFINE_PROP_UINT16("id0", PFlashCFI02, ident0, 0),
686 DEFINE_PROP_UINT16("id1", PFlashCFI02, ident1, 0),
687 DEFINE_PROP_UINT16("id2", PFlashCFI02, ident2, 0),
688 DEFINE_PROP_UINT16("id3", PFlashCFI02, ident3, 0),
689 DEFINE_PROP_UINT16("unlock-addr0", PFlashCFI02, unlock_addr0, 0),
690 DEFINE_PROP_UINT16("unlock-addr1", PFlashCFI02, unlock_addr1, 0),
691 DEFINE_PROP_STRING("name", PFlashCFI02, name),
692 DEFINE_PROP_END_OF_LIST(),
695 static void pflash_cfi02_unrealize(DeviceState *dev, Error **errp)
697 PFlashCFI02 *pfl = PFLASH_CFI02(dev);
698 timer_del(&pfl->timer);
701 static void pflash_cfi02_class_init(ObjectClass *klass, void *data)
703 DeviceClass *dc = DEVICE_CLASS(klass);
705 dc->realize = pflash_cfi02_realize;
706 dc->unrealize = pflash_cfi02_unrealize;
707 dc->props = pflash_cfi02_properties;
708 set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);
711 static const TypeInfo pflash_cfi02_info = {
712 .name = TYPE_PFLASH_CFI02,
713 .parent = TYPE_SYS_BUS_DEVICE,
714 .instance_size = sizeof(PFlashCFI02),
715 .class_init = pflash_cfi02_class_init,
718 static void pflash_cfi02_register_types(void)
720 type_register_static(&pflash_cfi02_info);
723 type_init(pflash_cfi02_register_types)
725 PFlashCFI02 *pflash_cfi02_register(hwaddr base,
730 int nb_mappings, int width,
731 uint16_t id0, uint16_t id1,
732 uint16_t id2, uint16_t id3,
733 uint16_t unlock_addr0,
734 uint16_t unlock_addr1,
737 DeviceState *dev = qdev_create(NULL, TYPE_PFLASH_CFI02);
740 qdev_prop_set_drive(dev, "drive", blk, &error_abort);
742 assert(size % sector_len == 0);
743 qdev_prop_set_uint32(dev, "num-blocks", size / sector_len);
744 qdev_prop_set_uint32(dev, "sector-length", sector_len);
745 qdev_prop_set_uint8(dev, "width", width);
746 qdev_prop_set_uint8(dev, "mappings", nb_mappings);
747 qdev_prop_set_uint8(dev, "big-endian", !!be);
748 qdev_prop_set_uint16(dev, "id0", id0);
749 qdev_prop_set_uint16(dev, "id1", id1);
750 qdev_prop_set_uint16(dev, "id2", id2);
751 qdev_prop_set_uint16(dev, "id3", id3);
752 qdev_prop_set_uint16(dev, "unlock-addr0", unlock_addr0);
753 qdev_prop_set_uint16(dev, "unlock-addr1", unlock_addr1);
754 qdev_prop_set_string(dev, "name", name);
755 qdev_init_nofail(dev);
757 sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, base);
758 return PFLASH_CFI02(dev);