aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hw/block/pflash_cfi01.c71
-rw-r--r--hw/block/pflash_cfi02.c8
2 files changed, 42 insertions, 37 deletions
diff --git a/hw/block/pflash_cfi01.c b/hw/block/pflash_cfi01.c
index 8e8887253d..11922c0f96 100644
--- a/hw/block/pflash_cfi01.c
+++ b/hw/block/pflash_cfi01.c
@@ -42,7 +42,7 @@
#include "hw/qdev-properties.h"
#include "sysemu/block-backend.h"
#include "qapi/error.h"
-#include "qemu/timer.h"
+#include "qemu/error-report.h"
#include "qemu/bitops.h"
#include "qemu/error-report.h"
#include "qemu/host-utils.h"
@@ -91,7 +91,6 @@ struct PFlashCFI01 {
uint8_t cfi_table[0x52];
uint64_t counter;
unsigned int writeblock_size;
- QEMUTimer *timer;
MemoryRegion mem;
char *name;
void *storage;
@@ -115,18 +114,6 @@ static const VMStateDescription vmstate_pflash = {
}
};
-static void pflash_timer (void *opaque)
-{
- PFlashCFI01 *pfl = opaque;
-
- trace_pflash_timer_expired(pfl->cmd);
- /* Reset flash */
- pfl->status ^= 0x80;
- memory_region_rom_device_set_romd(&pfl->mem, true);
- pfl->wcycle = 0;
- pfl->cmd = 0;
-}
-
/* Perform a CFI query based on the bank width of the flash.
* If this code is called we know we have a device_width set for
* this flash.
@@ -292,9 +279,13 @@ static uint32_t pflash_read(PFlashCFI01 *pfl, hwaddr offset,
/* 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;
+ /*
+ * The command 0x00 is not assigned by the CFI open standard,
+ * but QEMU historically uses it for the READ_ARRAY command (0xff).
+ */
+ pfl->cmd = 0x00;
/* fall through to read code */
- case 0x00:
+ case 0x00: /* This model reset value for READ_ARRAY (not CFI compliant) */
/* Flash area read */
ret = pflash_data_read(pfl, offset, width, be);
break;
@@ -399,13 +390,18 @@ static void pflash_update(PFlashCFI01 *pfl, int offset,
int size)
{
int offset_end;
+ int ret;
if (pfl->blk) {
offset_end = offset + size;
/* widen to sector boundaries */
offset = QEMU_ALIGN_DOWN(offset, BDRV_SECTOR_SIZE);
offset_end = QEMU_ALIGN_UP(offset_end, BDRV_SECTOR_SIZE);
- blk_pwrite(pfl->blk, offset, pfl->storage + offset,
+ ret = blk_pwrite(pfl->blk, offset, pfl->storage + offset,
offset_end - offset, 0);
+ if (ret < 0) {
+ /* TODO set error bit in status */
+ error_report("Could not update PFLASH: %s", strerror(-ret));
+ }
}
}
@@ -463,8 +459,8 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
case 0:
/* read mode */
switch (cmd) {
- case 0x00: /* ??? */
- goto reset_flash;
+ case 0x00: /* This model reset value for READ_ARRAY (not CFI) */
+ goto mode_read_array;
case 0x10: /* Single Byte Program */
case 0x40: /* Single Byte Program */
DPRINTF("%s: Single Byte Program\n", __func__);
@@ -487,7 +483,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
case 0x50: /* Clear status bits */
DPRINTF("%s: Clear status bits\n", __func__);
pfl->status = 0x0;
- goto reset_flash;
+ goto mode_read_array;
case 0x60: /* Block (un)lock */
DPRINTF("%s: Block unlock\n", __func__);
break;
@@ -512,10 +508,10 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
break;
case 0xf0: /* Probe for AMD flash */
DPRINTF("%s: Probe for AMD flash\n", __func__);
- goto reset_flash;
- case 0xff: /* Read array mode */
+ goto mode_read_array;
+ case 0xff: /* Read Array */
DPRINTF("%s: Read array mode\n", __func__);
- goto reset_flash;
+ goto mode_read_array;
default:
goto error_flash;
}
@@ -541,8 +537,8 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
if (cmd == 0xd0) { /* confirm */
pfl->wcycle = 0;
pfl->status |= 0x80;
- } else if (cmd == 0xff) { /* read array mode */
- goto reset_flash;
+ } else if (cmd == 0xff) { /* Read Array */
+ goto mode_read_array;
} else
goto error_flash;
@@ -568,16 +564,16 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
} else if (cmd == 0x01) {
pfl->wcycle = 0;
pfl->status |= 0x80;
- } else if (cmd == 0xff) {
- goto reset_flash;
+ } else if (cmd == 0xff) { /* Read Array */
+ goto mode_read_array;
} else {
DPRINTF("%s: Unknown (un)locking command\n", __func__);
- goto reset_flash;
+ goto mode_read_array;
}
break;
case 0x98:
- if (cmd == 0xff) {
- goto reset_flash;
+ if (cmd == 0xff) { /* Read Array */
+ goto mode_read_array;
} else {
DPRINTF("%s: leaving query mode\n", __func__);
}
@@ -637,7 +633,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
" the data is already written to storage!\n"
"Flash device reset into READ mode.\n",
__func__);
- goto reset_flash;
+ goto mode_read_array;
}
break;
default:
@@ -647,7 +643,7 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
default:
/* Should never happen */
DPRINTF("%s: invalid write state\n", __func__);
- goto reset_flash;
+ goto mode_read_array;
}
return;
@@ -656,11 +652,11 @@ static void pflash_write(PFlashCFI01 *pfl, hwaddr offset,
"(offset " TARGET_FMT_plx ", wcycle 0x%x cmd 0x%x value 0x%x)"
"\n", __func__, offset, pfl->wcycle, pfl->cmd, value);
- reset_flash:
+ mode_read_array:
trace_pflash_reset();
memory_region_rom_device_set_romd(&pfl->mem, true);
pfl->wcycle = 0;
- pfl->cmd = 0;
+ pfl->cmd = 0x00; /* This model reset value for READ_ARRAY (not CFI) */
}
@@ -775,9 +771,12 @@ static void pflash_cfi01_realize(DeviceState *dev, Error **errp)
pfl->max_device_width = pfl->device_width;
}
- pfl->timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, pflash_timer, pfl);
pfl->wcycle = 0;
- pfl->cmd = 0;
+ /*
+ * The command 0x00 is not assigned by the CFI open standard,
+ * but QEMU historically uses it for the READ_ARRAY command (0xff).
+ */
+ pfl->cmd = 0x00;
pfl->status = 0x80; /* WSM ready */
/* Hardcoded CFI table */
/* Standard "QRY" string */
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index c277b0309d..ac7e34ecbf 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -37,6 +37,7 @@
#include "hw/block/flash.h"
#include "hw/qdev-properties.h"
#include "qapi/error.h"
+#include "qemu/error-report.h"
#include "qemu/bitmap.h"
#include "qemu/timer.h"
#include "sysemu/block-backend.h"
@@ -393,13 +394,18 @@ static uint64_t pflash_read(void *opaque, hwaddr offset, unsigned int width)
static void pflash_update(PFlashCFI02 *pfl, int offset, int size)
{
int offset_end;
+ int ret;
if (pfl->blk) {
offset_end = offset + size;
/* widen to sector boundaries */
offset = QEMU_ALIGN_DOWN(offset, BDRV_SECTOR_SIZE);
offset_end = QEMU_ALIGN_UP(offset_end, BDRV_SECTOR_SIZE);
- blk_pwrite(pfl->blk, offset, pfl->storage + offset,
+ ret = blk_pwrite(pfl->blk, offset, pfl->storage + offset,
offset_end - offset, 0);
+ if (ret < 0) {
+ /* TODO set error bit in status */
+ error_report("Could not update PFLASH: %s", strerror(-ret));
+ }
}
}