aboutsummaryrefslogtreecommitdiff
path: root/hw/block/pflash_cfi02.c
diff options
context:
space:
mode:
Diffstat (limited to 'hw/block/pflash_cfi02.c')
-rw-r--r--hw/block/pflash_cfi02.c316
1 files changed, 160 insertions, 156 deletions
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 7962cff745..25c053693c 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -48,14 +48,6 @@
#include "migration/vmstate.h"
#include "trace.h"
-#define PFLASH_DEBUG false
-#define DPRINTF(fmt, ...) \
-do { \
- if (PFLASH_DEBUG) { \
- fprintf(stderr, "PFLASH: " fmt, ## __VA_ARGS__); \
- } \
-} while (0)
-
#define PFLASH_LAZY_ROMD_THRESHOLD 42
/*
@@ -100,14 +92,15 @@ struct PFlashCFI02 {
uint16_t unlock_addr1;
uint8_t cfi_table[0x4d];
QEMUTimer timer;
- /* The device replicates the flash memory across its memory space. Emulate
+ /*
+ * The device replicates the flash memory across its memory space. Emulate
* that by having a container (.mem) filled with an array of aliases
* (.mem_mappings) pointing to the flash memory (.orig_mem).
*/
MemoryRegion mem;
MemoryRegion *mem_mappings; /* array; one per mapping */
MemoryRegion orig_mem;
- int rom_mode;
+ bool rom_mode;
int read_counter; /* used for lazy switch-back to rom mode */
int sectors_to_erase;
uint64_t erase_time_remaining;
@@ -180,12 +173,22 @@ static void pflash_setup_mappings(PFlashCFI02 *pfl)
"pflash-alias", &pfl->orig_mem, 0, size);
memory_region_add_subregion(&pfl->mem, i * size, &pfl->mem_mappings[i]);
}
+ pfl->rom_mode = true;
}
-static void pflash_register_memory(PFlashCFI02 *pfl, int rom_mode)
+static void pflash_reset_state_machine(PFlashCFI02 *pfl)
{
- memory_region_rom_device_set_romd(&pfl->orig_mem, rom_mode);
- pfl->rom_mode = rom_mode;
+ trace_pflash_reset(pfl->name);
+ pfl->cmd = 0x00;
+ pfl->wcycle = 0;
+}
+
+static void pflash_mode_read_array(PFlashCFI02 *pfl)
+{
+ trace_pflash_mode_read_array(pfl->name);
+ pflash_reset_state_machine(pfl);
+ pfl->rom_mode = true;
+ memory_region_rom_device_set_romd(&pfl->orig_mem, true);
}
static size_t pflash_regions_count(PFlashCFI02 *pfl)
@@ -220,7 +223,7 @@ static void pflash_timer(void *opaque)
{
PFlashCFI02 *pfl = opaque;
- trace_pflash_timer_expired(pfl->cmd);
+ trace_pflash_timer_expired(pfl->name, pfl->cmd);
if (pfl->cmd == 0x30) {
/*
* Sector erase. If DQ3 is 0 when the timer expires, then the 50
@@ -233,11 +236,10 @@ static void pflash_timer(void *opaque)
uint64_t timeout = pflash_erase_time(pfl);
timer_mod(&pfl->timer,
qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + timeout);
- DPRINTF("%s: erase timeout fired; erasing %d sectors\n",
- __func__, pfl->sectors_to_erase);
+ trace_pflash_erase_timeout(pfl->name, pfl->sectors_to_erase);
return;
}
- DPRINTF("%s: sector erase complete\n", __func__);
+ trace_pflash_erase_complete(pfl->name);
bitmap_zero(pfl->sector_erase_map, pfl->total_sectors);
pfl->sectors_to_erase = 0;
reset_dq3(pfl);
@@ -247,11 +249,10 @@ static void pflash_timer(void *opaque)
toggle_dq7(pfl);
if (pfl->bypass) {
pfl->wcycle = 2;
+ pfl->cmd = 0;
} else {
- pflash_register_memory(pfl, 1);
- pfl->wcycle = 0;
+ pflash_mode_read_array(pfl);
}
- pfl->cmd = 0;
}
/*
@@ -262,7 +263,7 @@ static uint64_t pflash_data_read(PFlashCFI02 *pfl, hwaddr offset,
{
uint8_t *p = (uint8_t *)pfl->storage + offset;
uint64_t ret = pfl->be ? ldn_be_p(p, width) : ldn_le_p(p, width);
- trace_pflash_data_read(offset, width, ret);
+ trace_pflash_data_read(pfl->name, offset, width, ret);
return ret;
}
@@ -313,7 +314,7 @@ static uint64_t pflash_read(void *opaque, hwaddr offset, unsigned int width)
/* Lazy reset to ROMD mode after a certain amount of read accesses */
if (!pfl->rom_mode && pfl->wcycle == 0 &&
++pfl->read_counter > PFLASH_LAZY_ROMD_THRESHOLD) {
- pflash_register_memory(pfl, 1);
+ pflash_mode_read_array(pfl);
}
offset &= pfl->chip_len - 1;
boff = offset & 0xFF;
@@ -325,9 +326,8 @@ static uint64_t pflash_read(void *opaque, hwaddr offset, unsigned int width)
switch (pfl->cmd) {
default:
/* This should never happen : reset state & treat it as a read*/
- DPRINTF("%s: unknown command state: %x\n", __func__, pfl->cmd);
- pfl->wcycle = 0;
- pfl->cmd = 0;
+ trace_pflash_read_unknown_state(pfl->name, pfl->cmd);
+ pflash_reset_state_machine(pfl);
/* fall through to the read code */
case 0x80: /* Erase (unlock) */
/* We accept reads during second unlock sequence... */
@@ -338,7 +338,7 @@ static uint64_t pflash_read(void *opaque, hwaddr offset, unsigned int width)
toggle_dq2(pfl);
/* Status register read */
ret = pfl->status;
- DPRINTF("%s: status %" PRIx64 "\n", __func__, ret);
+ trace_pflash_read_status(pfl->name, ret);
break;
}
/* Flash area read */
@@ -363,7 +363,7 @@ static uint64_t pflash_read(void *opaque, hwaddr offset, unsigned int width)
default:
ret = pflash_data_read(pfl, offset, width);
}
- DPRINTF("%s: ID " TARGET_FMT_plx " %" PRIx64 "\n", __func__, boff, ret);
+ trace_pflash_read_done(pfl->name, boff, ret);
break;
case 0x10: /* Chip Erase */
case 0x30: /* Sector Erase */
@@ -375,7 +375,7 @@ static uint64_t pflash_read(void *opaque, hwaddr offset, unsigned int width)
toggle_dq6(pfl);
/* Status register read */
ret = pfl->status;
- DPRINTF("%s: status %" PRIx64 "\n", __func__, ret);
+ trace_pflash_read_status(pfl->name, ret);
break;
case 0x98:
/* CFI query mode */
@@ -386,7 +386,7 @@ static uint64_t pflash_read(void *opaque, hwaddr offset, unsigned int width)
}
break;
}
- trace_pflash_io_read(offset, width, ret, pfl->cmd, pfl->wcycle);
+ trace_pflash_io_read(pfl->name, offset, width, ret, pfl->cmd, pfl->wcycle);
return ret;
}
@@ -415,9 +415,8 @@ static void pflash_sector_erase(PFlashCFI02 *pfl, hwaddr offset)
SectorInfo sector_info = pflash_sector_info(pfl, offset);
uint64_t sector_len = sector_info.len;
offset &= ~(sector_len - 1);
- DPRINTF("%s: start sector erase at %0*" PRIx64 "-%0*" PRIx64 "\n",
- __func__, pfl->width * 2, offset,
- pfl->width * 2, offset + sector_len - 1);
+ trace_pflash_sector_erase_start(pfl->name, pfl->width * 2, offset,
+ pfl->width * 2, offset + sector_len - 1);
if (!pfl->ro) {
uint8_t *p = pfl->storage;
memset(p + offset, 0xff, sector_len);
@@ -438,7 +437,7 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
uint8_t *p;
uint8_t cmd;
- trace_pflash_io_write(offset, width, value, pfl->wcycle);
+ trace_pflash_io_write(pfl->name, offset, width, value, pfl->wcycle);
cmd = value;
if (pfl->cmd != 0xA0) {
/* Reset does nothing during chip erase and sector erase. */
@@ -465,8 +464,10 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
switch (pfl->wcycle) {
case 0:
/* Set the device in I/O access mode if required */
- if (pfl->rom_mode)
- pflash_register_memory(pfl, 0);
+ if (pfl->rom_mode) {
+ pfl->rom_mode = false;
+ memory_region_rom_device_set_romd(&pfl->orig_mem, false);
+ }
pfl->read_counter = 0;
/* We're in read mode */
check_unlock0:
@@ -496,27 +497,25 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
return;
}
if (boff != pfl->unlock_addr0 || cmd != 0xAA) {
- DPRINTF("%s: unlock0 failed " TARGET_FMT_plx " %02x %04x\n",
- __func__, boff, cmd, pfl->unlock_addr0);
+ trace_pflash_unlock0_failed(pfl->name, boff,
+ cmd, pfl->unlock_addr0);
goto reset_flash;
}
- DPRINTF("%s: unlock sequence started\n", __func__);
+ trace_pflash_write(pfl->name, "unlock sequence started");
break;
case 1:
/* We started an unlock sequence */
check_unlock1:
if (boff != pfl->unlock_addr1 || cmd != 0x55) {
- DPRINTF("%s: unlock1 failed " TARGET_FMT_plx " %02x\n", __func__,
- boff, cmd);
+ trace_pflash_unlock1_failed(pfl->name, boff, cmd);
goto reset_flash;
}
- DPRINTF("%s: unlock sequence done\n", __func__);
+ trace_pflash_write(pfl->name, "unlock sequence done");
break;
case 2:
/* We finished an unlock sequence */
if (!pfl->bypass && boff != pfl->unlock_addr0) {
- DPRINTF("%s: command failed " TARGET_FMT_plx " %02x\n", __func__,
- boff, cmd);
+ trace_pflash_write_failed(pfl->name, boff, cmd);
goto reset_flash;
}
switch (cmd) {
@@ -527,10 +526,10 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
case 0x90: /* Autoselect */
case 0xA0: /* Program */
pfl->cmd = cmd;
- DPRINTF("%s: starting command %02x\n", __func__, cmd);
+ trace_pflash_write_start(pfl->name, cmd);
break;
default:
- DPRINTF("%s: unknown command %02x\n", __func__, cmd);
+ trace_pflash_write_unknown(pfl->name, cmd);
goto reset_flash;
}
break;
@@ -548,7 +547,7 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
}
goto reset_flash;
}
- trace_pflash_data_write(offset, width, value, 0);
+ trace_pflash_data_write(pfl->name, offset, width, value, 0);
if (!pfl->ro) {
p = (uint8_t *)pfl->storage + offset;
if (pfl->be) {
@@ -586,8 +585,7 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
}
/* fall through */
default:
- DPRINTF("%s: invalid write for command %02x\n",
- __func__, pfl->cmd);
+ trace_pflash_write_invalid(pfl->name, pfl->cmd);
goto reset_flash;
}
case 4:
@@ -600,8 +598,7 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
goto check_unlock1;
default:
/* Should never happen */
- DPRINTF("%s: invalid command state %02x (wc 4)\n",
- __func__, pfl->cmd);
+ trace_pflash_write_invalid_state(pfl->name, pfl->cmd, 5);
goto reset_flash;
}
break;
@@ -613,12 +610,11 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
switch (cmd) {
case 0x10: /* Chip Erase */
if (boff != pfl->unlock_addr0) {
- DPRINTF("%s: chip erase: invalid address " TARGET_FMT_plx "\n",
- __func__, offset);
+ trace_pflash_chip_erase_invalid(pfl->name, offset);
goto reset_flash;
}
/* Chip erase */
- DPRINTF("%s: start chip erase\n", __func__);
+ trace_pflash_chip_erase_start(pfl->name);
if (!pfl->ro) {
memset(pfl->storage, 0xff, pfl->chip_len);
pflash_update(pfl, 0, pfl->chip_len);
@@ -632,7 +628,7 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
pflash_sector_erase(pfl, offset);
break;
default:
- DPRINTF("%s: invalid command %02x (wc 5)\n", __func__, cmd);
+ trace_pflash_write_invalid_command(pfl->name, cmd);
goto reset_flash;
}
pfl->cmd = cmd;
@@ -663,8 +659,7 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
}
reset_dq3(pfl);
timer_del(&pfl->timer);
- pfl->wcycle = 0;
- pfl->cmd = 0;
+ pflash_reset_state_machine(pfl);
return;
}
/*
@@ -683,19 +678,18 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
return;
default:
/* Should never happen */
- DPRINTF("%s: invalid command state %02x (wc 6)\n",
- __func__, pfl->cmd);
+ trace_pflash_write_invalid_state(pfl->name, pfl->cmd, 6);
goto reset_flash;
}
break;
/* Special values for CFI queries */
case WCYCLE_CFI:
case WCYCLE_AUTOSELECT_CFI:
- DPRINTF("%s: invalid write in CFI query mode\n", __func__);
+ trace_pflash_write(pfl->name, "invalid write in CFI query mode");
goto reset_flash;
default:
/* Should never happen */
- DPRINTF("%s: invalid write state (wc 7)\n", __func__);
+ trace_pflash_write(pfl->name, "invalid write state (wc 7)");
goto reset_flash;
}
pfl->wcycle++;
@@ -704,10 +698,8 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
/* Reset flash */
reset_flash:
- trace_pflash_reset();
pfl->bypass = 0;
- pfl->wcycle = 0;
- pfl->cmd = 0;
+ pflash_reset_state_machine(pfl);
return;
do_bypass:
@@ -723,6 +715,104 @@ static const MemoryRegionOps pflash_cfi02_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};
+static void pflash_cfi02_fill_cfi_table(PFlashCFI02 *pfl, int nb_regions)
+{
+ /* Hardcoded CFI table (mostly from SG29 Spansion flash) */
+ const uint16_t pri_ofs = 0x40;
+ /* Standard "QRY" string */
+ pfl->cfi_table[0x10] = 'Q';
+ pfl->cfi_table[0x11] = 'R';
+ pfl->cfi_table[0x12] = 'Y';
+ /* Command set (AMD/Fujitsu) */
+ pfl->cfi_table[0x13] = 0x02;
+ pfl->cfi_table[0x14] = 0x00;
+ /* Primary extended table address */
+ pfl->cfi_table[0x15] = pri_ofs;
+ pfl->cfi_table[0x16] = pri_ofs >> 8;
+ /* Alternate command set (none) */
+ pfl->cfi_table[0x17] = 0x00;
+ pfl->cfi_table[0x18] = 0x00;
+ /* Alternate extended table (none) */
+ pfl->cfi_table[0x19] = 0x00;
+ pfl->cfi_table[0x1A] = 0x00;
+ /* Vcc min */
+ pfl->cfi_table[0x1B] = 0x27;
+ /* Vcc max */
+ pfl->cfi_table[0x1C] = 0x36;
+ /* Vpp min (no Vpp pin) */
+ pfl->cfi_table[0x1D] = 0x00;
+ /* Vpp max (no Vpp pin) */
+ pfl->cfi_table[0x1E] = 0x00;
+ /* Timeout per single byte/word write (128 ms) */
+ pfl->cfi_table[0x1F] = 0x07;
+ /* Timeout for min size buffer write (NA) */
+ pfl->cfi_table[0x20] = 0x00;
+ /* Typical timeout for block erase (512 ms) */
+ pfl->cfi_table[0x21] = 0x09;
+ /* Typical timeout for full chip erase (4096 ms) */
+ pfl->cfi_table[0x22] = 0x0C;
+ /* Reserved */
+ pfl->cfi_table[0x23] = 0x01;
+ /* Max timeout for buffer write (NA) */
+ pfl->cfi_table[0x24] = 0x00;
+ /* Max timeout for block erase */
+ pfl->cfi_table[0x25] = 0x0A;
+ /* Max timeout for chip erase */
+ pfl->cfi_table[0x26] = 0x0D;
+ /* Device size */
+ pfl->cfi_table[0x27] = ctz32(pfl->chip_len);
+ /* Flash device interface (8 & 16 bits) */
+ pfl->cfi_table[0x28] = 0x02;
+ pfl->cfi_table[0x29] = 0x00;
+ /* Max number of bytes in multi-bytes write */
+ /*
+ * XXX: disable buffered write as it's not supported
+ * pfl->cfi_table[0x2A] = 0x05;
+ */
+ pfl->cfi_table[0x2A] = 0x00;
+ pfl->cfi_table[0x2B] = 0x00;
+ /* Number of erase block regions */
+ pfl->cfi_table[0x2c] = nb_regions;
+ /* Erase block regions */
+ for (int i = 0; i < nb_regions; ++i) {
+ uint32_t sector_len_per_device = pfl->sector_len[i];
+ pfl->cfi_table[0x2d + 4 * i] = pfl->nb_blocs[i] - 1;
+ pfl->cfi_table[0x2e + 4 * i] = (pfl->nb_blocs[i] - 1) >> 8;
+ pfl->cfi_table[0x2f + 4 * i] = sector_len_per_device >> 8;
+ pfl->cfi_table[0x30 + 4 * i] = sector_len_per_device >> 16;
+ }
+ assert(0x2c + 4 * nb_regions < pri_ofs);
+
+ /* Extended */
+ pfl->cfi_table[0x00 + pri_ofs] = 'P';
+ pfl->cfi_table[0x01 + pri_ofs] = 'R';
+ pfl->cfi_table[0x02 + pri_ofs] = 'I';
+
+ /* Extended version 1.0 */
+ pfl->cfi_table[0x03 + pri_ofs] = '1';
+ pfl->cfi_table[0x04 + pri_ofs] = '0';
+
+ /* Address sensitive unlock required. */
+ pfl->cfi_table[0x05 + pri_ofs] = 0x00;
+ /* Erase suspend to read/write. */
+ pfl->cfi_table[0x06 + pri_ofs] = 0x02;
+ /* Sector protect not supported. */
+ pfl->cfi_table[0x07 + pri_ofs] = 0x00;
+ /* Temporary sector unprotect not supported. */
+ pfl->cfi_table[0x08 + pri_ofs] = 0x00;
+
+ /* Sector protect/unprotect scheme. */
+ pfl->cfi_table[0x09 + pri_ofs] = 0x00;
+
+ /* Simultaneous operation not supported. */
+ pfl->cfi_table[0x0a + pri_ofs] = 0x00;
+ /* Burst mode not supported. */
+ pfl->cfi_table[0x0b + pri_ofs] = 0x00;
+ /* Page mode not supported. */
+ pfl->cfi_table[0x0c + pri_ofs] = 0x00;
+ assert(0x0c + pri_ofs < ARRAY_SIZE(pfl->cfi_table));
+}
+
static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
{
ERRP_GUARD();
@@ -828,106 +918,19 @@ static void pflash_cfi02_realize(DeviceState *dev, Error **errp)
pfl->sector_erase_map = bitmap_new(pfl->total_sectors);
pflash_setup_mappings(pfl);
- pfl->rom_mode = 1;
sysbus_init_mmio(SYS_BUS_DEVICE(dev), &pfl->mem);
timer_init_ns(&pfl->timer, QEMU_CLOCK_VIRTUAL, pflash_timer, pfl);
- pfl->wcycle = 0;
- pfl->cmd = 0;
pfl->status = 0;
- /* Hardcoded CFI table (mostly from SG29 Spansion flash) */
- const uint16_t pri_ofs = 0x40;
- /* Standard "QRY" string */
- pfl->cfi_table[0x10] = 'Q';
- pfl->cfi_table[0x11] = 'R';
- pfl->cfi_table[0x12] = 'Y';
- /* Command set (AMD/Fujitsu) */
- pfl->cfi_table[0x13] = 0x02;
- pfl->cfi_table[0x14] = 0x00;
- /* Primary extended table address */
- pfl->cfi_table[0x15] = pri_ofs;
- pfl->cfi_table[0x16] = pri_ofs >> 8;
- /* Alternate command set (none) */
- pfl->cfi_table[0x17] = 0x00;
- pfl->cfi_table[0x18] = 0x00;
- /* Alternate extended table (none) */
- pfl->cfi_table[0x19] = 0x00;
- pfl->cfi_table[0x1A] = 0x00;
- /* Vcc min */
- pfl->cfi_table[0x1B] = 0x27;
- /* Vcc max */
- pfl->cfi_table[0x1C] = 0x36;
- /* Vpp min (no Vpp pin) */
- pfl->cfi_table[0x1D] = 0x00;
- /* Vpp max (no Vpp pin) */
- pfl->cfi_table[0x1E] = 0x00;
- /* Timeout per single byte/word write (128 ms) */
- pfl->cfi_table[0x1F] = 0x07;
- /* Timeout for min size buffer write (NA) */
- pfl->cfi_table[0x20] = 0x00;
- /* Typical timeout for block erase (512 ms) */
- pfl->cfi_table[0x21] = 0x09;
- /* Typical timeout for full chip erase (4096 ms) */
- pfl->cfi_table[0x22] = 0x0C;
- /* Reserved */
- pfl->cfi_table[0x23] = 0x01;
- /* Max timeout for buffer write (NA) */
- pfl->cfi_table[0x24] = 0x00;
- /* Max timeout for block erase */
- pfl->cfi_table[0x25] = 0x0A;
- /* Max timeout for chip erase */
- pfl->cfi_table[0x26] = 0x0D;
- /* Device size */
- pfl->cfi_table[0x27] = ctz32(pfl->chip_len);
- /* Flash device interface (8 & 16 bits) */
- pfl->cfi_table[0x28] = 0x02;
- pfl->cfi_table[0x29] = 0x00;
- /* Max number of bytes in multi-bytes write */
- /* XXX: disable buffered write as it's not supported */
- // pfl->cfi_table[0x2A] = 0x05;
- pfl->cfi_table[0x2A] = 0x00;
- pfl->cfi_table[0x2B] = 0x00;
- /* Number of erase block regions */
- pfl->cfi_table[0x2c] = nb_regions;
- /* Erase block regions */
- for (int i = 0; i < nb_regions; ++i) {
- uint32_t sector_len_per_device = pfl->sector_len[i];
- pfl->cfi_table[0x2d + 4 * i] = pfl->nb_blocs[i] - 1;
- pfl->cfi_table[0x2e + 4 * i] = (pfl->nb_blocs[i] - 1) >> 8;
- pfl->cfi_table[0x2f + 4 * i] = sector_len_per_device >> 8;
- pfl->cfi_table[0x30 + 4 * i] = sector_len_per_device >> 16;
- }
- assert(0x2c + 4 * nb_regions < pri_ofs);
-
- /* Extended */
- pfl->cfi_table[0x00 + pri_ofs] = 'P';
- pfl->cfi_table[0x01 + pri_ofs] = 'R';
- pfl->cfi_table[0x02 + pri_ofs] = 'I';
-
- /* Extended version 1.0 */
- pfl->cfi_table[0x03 + pri_ofs] = '1';
- pfl->cfi_table[0x04 + pri_ofs] = '0';
-
- /* Address sensitive unlock required. */
- pfl->cfi_table[0x05 + pri_ofs] = 0x00;
- /* Erase suspend to read/write. */
- pfl->cfi_table[0x06 + pri_ofs] = 0x02;
- /* Sector protect not supported. */
- pfl->cfi_table[0x07 + pri_ofs] = 0x00;
- /* Temporary sector unprotect not supported. */
- pfl->cfi_table[0x08 + pri_ofs] = 0x00;
+ pflash_cfi02_fill_cfi_table(pfl, nb_regions);
+}
- /* Sector protect/unprotect scheme. */
- pfl->cfi_table[0x09 + pri_ofs] = 0x00;
+static void pflash_cfi02_reset(DeviceState *dev)
+{
+ PFlashCFI02 *pfl = PFLASH_CFI02(dev);
- /* Simultaneous operation not supported. */
- pfl->cfi_table[0x0a + pri_ofs] = 0x00;
- /* Burst mode not supported. */
- pfl->cfi_table[0x0b + pri_ofs] = 0x00;
- /* Page mode not supported. */
- pfl->cfi_table[0x0c + pri_ofs] = 0x00;
- assert(0x0c + pri_ofs < ARRAY_SIZE(pfl->cfi_table));
+ pflash_reset_state_machine(pfl);
}
static Property pflash_cfi02_properties[] = {
@@ -967,6 +970,7 @@ static void pflash_cfi02_class_init(ObjectClass *klass, void *data)
DeviceClass *dc = DEVICE_CLASS(klass);
dc->realize = pflash_cfi02_realize;
+ dc->reset = pflash_cfi02_reset;
dc->unrealize = pflash_cfi02_unrealize;
device_class_set_props(dc, pflash_cfi02_properties);
set_bit(DEVICE_CATEGORY_STORAGE, dc->categories);