aboutsummaryrefslogtreecommitdiff
path: root/hw/block/pflash_cfi02.c
diff options
context:
space:
mode:
authorStephen Checkoway <stephen.checkoway@oberlin.edu>2019-04-26 12:26:20 -0400
committerPhilippe Mathieu-Daudé <philmd@redhat.com>2019-07-02 02:32:39 +0200
commit46fb7809b5520e2cb77bdc86270b0c393e4b1210 (patch)
tree656050926d78f466393fa5793abcfc93fb4fa532 /hw/block/pflash_cfi02.c
parent8a508e7064bbe7d434a93f3284e6d93881c68a44 (diff)
downloadqemu-46fb7809b5520e2cb77bdc86270b0c393e4b1210.zip
qemu-46fb7809b5520e2cb77bdc86270b0c393e4b1210.tar.gz
qemu-46fb7809b5520e2cb77bdc86270b0c393e4b1210.tar.bz2
hw/block/pflash_cfi02: Fix CFI in autoselect mode
After a flash device enters CFI mode from autoselect mode, the reset command returns the device to autoselect mode. An additional reset command is necessary to return to read array mode. Signed-off-by: Stephen Checkoway <stephen.checkoway@oberlin.edu> Message-Id: <20190426162624.55977-7-stephen.checkoway@oberlin.edu> Tested-by: Philippe Mathieu-Daudé <philmd@redhat.com> Acked-by: Thomas Huth <thuth@redhat.com> Acked-by: Alistair Francis <alistair.francis@wdc.com> Acked-by: Philippe Mathieu-Daudé <philmd@redhat.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@redhat.com>
Diffstat (limited to 'hw/block/pflash_cfi02.c')
-rw-r--r--hw/block/pflash_cfi02.c22
1 files changed, 18 insertions, 4 deletions
diff --git a/hw/block/pflash_cfi02.c b/hw/block/pflash_cfi02.c
index 08b2bc8..13f76fa 100644
--- a/hw/block/pflash_cfi02.c
+++ b/hw/block/pflash_cfi02.c
@@ -66,6 +66,7 @@ do { \
/* Special write cycles for CFI queries. */
enum {
WCYCLE_CFI = 7,
+ WCYCLE_AUTOSELECT_CFI = 8,
};
struct PFlashCFI02 {
@@ -311,6 +312,12 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
cmd = value;
if (pfl->cmd != 0xA0) {
if (cmd == 0xF0) {
+ if (pfl->wcycle == WCYCLE_AUTOSELECT_CFI) {
+ /* Return to autoselect mode. */
+ pfl->wcycle = 3;
+ pfl->cmd = 0x90;
+ return;
+ }
goto reset_flash;
}
}
@@ -333,7 +340,6 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
/* We're in read mode */
check_unlock0:
if (boff == 0x55 && cmd == 0x98) {
- enter_CFI_mode:
/* Enter CFI query mode */
pfl->wcycle = WCYCLE_CFI;
pfl->cmd = 0x98;
@@ -410,9 +416,16 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
/* Unlock bypass reset */
goto reset_flash;
}
- /* We can enter CFI query mode from autoselect mode */
- if (boff == 0x55 && cmd == 0x98)
- goto enter_CFI_mode;
+ /*
+ * We can enter CFI query mode from autoselect mode, but we must
+ * return to autoselect mode after a reset.
+ */
+ if (boff == 0x55 && cmd == 0x98) {
+ /* Enter autoselect CFI query mode */
+ pfl->wcycle = WCYCLE_AUTOSELECT_CFI;
+ pfl->cmd = 0x98;
+ return;
+ }
/* No break here */
default:
DPRINTF("%s: invalid write for command %02x\n",
@@ -493,6 +506,7 @@ static void pflash_write(void *opaque, hwaddr offset, uint64_t value,
break;
/* Special values for CFI queries */
case WCYCLE_CFI:
+ case WCYCLE_AUTOSELECT_CFI:
DPRINTF("%s: invalid write in CFI query mode\n", __func__);
goto reset_flash;
default: