qemu/hw/ssi
Jamin Lin 05d501a1ea aspeed/smc: Fix write incorrect data into flash in user mode
According to the design of ASPEED SPI controllers user mode, users write the
data to flash, the SPI drivers set the Control Register(0x10) bit 0 and 1
enter user mode. Then, SPI drivers send flash commands for writing data.
Finally, SPI drivers set the Control Register (0x10) bit 2 to stop
active control and restore bit 0 and 1.

According to the design of ASPEED SMC model, firmware writes the
Control Register and the "aspeed_smc_flash_update_ctrl" function is called.
Then, this function verify Control Register(0x10) bit 0 and 1. If it set user
mode, the value of s->snoop_index is SNOOP_START else SNOOP_OFF.
If s->snoop_index is SNOOP_START, the "aspeed_smc_do_snoop" function verify
the first incomming data is a new flash command and writes the corresponding
dummy bytes if need.

However, it did not check the current unselect status. If current unselect
status is "false" and firmware set the IO MODE by Control Register bit 31:28,
the value of s->snoop_index will be changed to SNOOP_START again and
"aspeed_smc_do_snoop" misunderstand that the incomming data is the new flash
command and it causes writing unexpected data into flash.

Example:
1. Firmware set user mode by Control Register bit 0 and 1(0x03)
2. SMC model set s->snoop SNOOP_START
3. Firmware set Quad Page Program with 4-Byte Address command (0x34)
4. SMC model verify this flash command and it needs 4 dummy bytes.
5. Firmware send 4 bytes address.
6. SMC model receives 4 bytes address
7. Firmware set QPI IO MODE by Control Register bit 31. (0x80000003)
8. SMC model verify new user mode by Control Register bit 0 and 1.
   Then, set s->snoop SNOOP_START again. (It is the wrong behavior.)
9. Firmware send 0xebd8c134 data and it should be written into flash.
   However, SMC model misunderstand that the first incoming data, 0x34,
   is the new command because the value of s->snoop is changed to SNOOP_START.
   Finally, SMC sned the incorrect data to flash model.

Introduce a new unselect attribute in AspeedSMCState to save the current
unselect status for user mode and set it "true" by default.
Update "aspeed_smc_flash_update_ctrl" function to check the previous unselect
status. If both new unselect status and previous unselect status is different,
update s->snoop_index value and call "aspeed_smc_flash_do_select".

Increase VMStateDescription version.

Signed-off-by: Jamin Lin <jamin_lin@aspeedtech.com>
Reviewed-by: Cédric Le Goater <clg@redhat.com>
[ clg: - Replaced VMSTATE_BOOL -> VMSTATE_BOOL_V ]
Signed-off-by: Cédric Le Goater <clg@redhat.com>
2024-10-24 07:57:47 +02:00
..
allwinner-a10-spi.c hw/ssi: Allwinner A10 SPI emulation 2024-10-15 15:16:17 +01:00
aspeed_smc.c aspeed/smc: Fix write incorrect data into flash in user mode 2024-10-24 07:57:47 +02:00
bcm2835_spi.c hw: Use device_class_set_legacy_reset() instead of opencoding 2024-09-13 15:31:44 +01:00
ibex_spi_host.c hw: Use device_class_set_legacy_reset() instead of opencoding 2024-09-13 15:31:44 +01:00
imx_spi.c hw: Use device_class_set_legacy_reset() instead of opencoding 2024-09-13 15:31:44 +01:00
Kconfig hw/ssi: Allwinner A10 SPI emulation 2024-10-15 15:16:17 +01:00
meson.build hw/ssi: Allwinner A10 SPI emulation 2024-10-15 15:16:17 +01:00
mss-spi.c hw: Use device_class_set_legacy_reset() instead of opencoding 2024-09-13 15:31:44 +01:00
npcm7xx_fiu.c hw, target: Add ResetType argument to hold and exit phase methods 2024-04-25 10:21:06 +01:00
npcm_pspi.c hw/ssi: Constify VMState 2023-12-30 07:38:06 +11:00
pl022.c hw: Use device_class_set_legacy_reset() instead of opencoding 2024-09-13 15:31:44 +01:00
pnv_spi.c hw: Use device_class_set_legacy_reset() instead of opencoding 2024-09-13 15:31:44 +01:00
sifive_spi.c hw: Use device_class_set_legacy_reset() instead of opencoding 2024-09-13 15:31:44 +01:00
ssi.c hw/ssi: Constify VMState 2023-12-30 07:38:06 +11:00
stm32f2xx_spi.c hw: Use device_class_set_legacy_reset() instead of opencoding 2024-09-13 15:31:44 +01:00
trace-events hw/ssi: Allwinner A10 SPI emulation 2024-10-15 15:16:17 +01:00
trace.h trace: switch position of headers to what Meson requires 2020-08-21 06:18:24 -04:00
xilinx_spi.c hw: Use device_class_set_legacy_reset() instead of opencoding 2024-09-13 15:31:44 +01:00
xilinx_spips.c hw/ssi/xilinx_spips: Fix flash erase assert in dual parallel configuration 2024-10-01 13:55:38 +01:00
xlnx-versal-ospi.c hw: Use device_class_set_legacy_reset() instead of opencoding 2024-09-13 15:31:44 +01:00