From d4e53ae638b22b053ecccfddab535f639ba9f790 Mon Sep 17 00:00:00 2001 From: Evan Reichard Date: Mon, 20 Jul 2026 09:03:16 -0400 Subject: [PATCH] fix(m25p80): answer Read-ID 0x90/0xAB for all chips, not just SST CrossPoint flash detection sends Read-ID (0x90/0xAB); the model only handled it for SST chips, so the is25lp128 returned nothing and detection fell into an SFDP/garbage path that crashed QEMU. Return manufacturer + device id for any chip, as real hardware does. --- qemu/patches/0002-qemu-wasm.patch | 43 +++++++++++++++++++++++++++++++ 1 file changed, 43 insertions(+) diff --git a/qemu/patches/0002-qemu-wasm.patch b/qemu/patches/0002-qemu-wasm.patch index 0a3812b..4e4f6ee 100644 --- a/qemu/patches/0002-qemu-wasm.patch +++ b/qemu/patches/0002-qemu-wasm.patch @@ -324,6 +324,49 @@ index 89087429c7..4d38b3e13c 100644 : ADC_MAX; } return s->regs[addr / 4]; +diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c +index 46dbe7c521..4f05caf34e 100644 +--- a/hw/block/m25p80.c ++++ b/hw/block/m25p80.c +@@ -856,28 +856,18 @@ static void complete_collecting_data(Flash *s) + break; + case RDID_90: + case RDID_AB: +- if (get_man(s) == MAN_SST) { +- if (s->cur_addr <= 1) { +- if (s->cur_addr) { +- s->data[0] = s->pi->id[2]; +- s->data[1] = s->pi->id[0]; +- } else { +- s->data[0] = s->pi->id[0]; +- s->data[1] = s->pi->id[2]; +- } +- s->pos = 0; +- s->len = 2; +- s->data_read_loop = true; +- s->state = STATE_READING_DATA; +- } else { +- qemu_log_mask(LOG_GUEST_ERROR, +- "M25P80: Invalid read id address\n"); +- } ++ // Read Manufacturer/Device ID - The address low bit selects which of the manufacturer/device pair comes first; real chips answer regardless of vendor, so this is not gated on MAN_SST. Reused for 0xAB (Release Power-Down + Device ID), whose trailing byte reads back the device id. ++ if (s->cur_addr) { ++ s->data[0] = s->pi->id[2]; ++ s->data[1] = s->pi->id[0]; + } else { +- qemu_log_mask(LOG_GUEST_ERROR, +- "M25P80: Read id (command 0x90/0xAB) is not supported" +- " by device\n"); ++ s->data[0] = s->pi->id[0]; ++ s->data[1] = s->pi->id[2]; + } ++ s->pos = 0; ++ s->len = 2; ++ s->data_read_loop = true; ++ s->state = STATE_READING_DATA; + break; + + case RDSFDP: diff --git a/hw/display/xteink_x3_eink.c b/hw/display/xteink_x3_eink.c index b699abae4e..8a177e9159 100644 --- a/hw/display/xteink_x3_eink.c