@samitouri / QOSamiQemu / commits / 27961a043c

Revert "aspeed/smc: snoop SPI transfers to fake dummy cycles"

This reverts commit f95c4bffdc4c53b29f89762cab4adc5a43f95daf. The m25p80 model now accounts for fast-read dummy bytes in its command decoder. In ASPEED SMC model user mode, guest software already sends the complete byte stream, including any dummy bytes needed by the flash. Hence the model should just forward exactly the bytes supplied by the guest without the need of decoding guest-supplied flash op codes to inject extra dummy transfers. Signed-off-by: Bin Meng <bin.meng@processmission.com> Reviewed-by: Cédric Le Goater <clg@redhat.com> Tested-by: Cédric Le Goater <clg@redhat.com> Message-ID: <20260707083431.219671-10-bin.meng@processmission.com> Signed-off-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com>

Bin Meng committed Jul 7, 2026 at 16:34 UTC 27961a043c14e802a4112de1f49e0dd0f8c2f583
3 files changed +2 -115
hw/ssi/aspeed_smc.c
+2 -112
@@ -197,9 +197,6 @@
197 /* Flash opcodes. */
198 #define SPI_OP_READ 0x03 /* Read data bytes (low frequency) */
199
200 -#define SNOOP_OFF 0xFF
201 -#define SNOOP_START 0x0
202 -
200 /*
201 * Default segments mapping addresses and size for each peripheral per
202 * controller. These can be changed when board is initialized with the
@@ -537,104 +534,6 @@ static MemTxResult aspeed_smc_flash_read(void *opaque, hwaddr addr,
534 return MEMTX_OK;
535 }
536
540 -/*
541 - * TODO (clg@kaod.org): stolen from xilinx_spips.c. Should move to a
542 - * common include header.
543 - */
544 -typedef enum {
545 - READ = 0x3, READ_4 = 0x13,
546 - FAST_READ = 0xb, FAST_READ_4 = 0x0c,
547 - DOR = 0x3b, DOR_4 = 0x3c,
548 - QOR = 0x6b, QOR_4 = 0x6c,
549 - DIOR = 0xbb, DIOR_4 = 0xbc,
550 - QIOR = 0xeb, QIOR_4 = 0xec,
551 -
552 - PP = 0x2, PP_4 = 0x12,
553 - DPP = 0xa2,
554 - QPP = 0x32, QPP_4 = 0x34,
555 -} FlashCMD;
556 -
557 -static int aspeed_smc_num_dummies(uint8_t command)
558 -{
559 - switch (command) { /* check for dummies */
560 - case READ: /* no dummy bytes/cycles */
561 - case PP:
562 - case DPP:
563 - case QPP:
564 - case READ_4:
565 - case PP_4:
566 - case QPP_4:
567 - return 0;
568 - case FAST_READ:
569 - case DOR:
570 - case QOR:
571 - case DOR_4:
572 - case QOR_4:
573 - return 1;
574 - case DIOR:
575 - case FAST_READ_4:
576 - case DIOR_4:
577 - return 2;
578 - case QIOR:
579 - case QIOR_4:
580 - return 4;
581 - default:
582 - return -1;
583 - }
584 -}
585 -
586 -static bool aspeed_smc_do_snoop(AspeedSMCFlash *fl, uint64_t data,
587 - unsigned size)
588 -{
589 - AspeedSMCState *s = fl->controller;
590 - uint8_t addr_width = aspeed_smc_flash_addr_width(fl);
591 -
592 - trace_aspeed_smc_do_snoop(fl->cs, s->snoop_index, s->snoop_dummies,
593 - (uint8_t) data & 0xff);
594 -
595 - if (s->snoop_index == SNOOP_OFF) {
596 - return false; /* Do nothing */
597 -
598 - } else if (s->snoop_index == SNOOP_START) {
599 - uint8_t cmd = data & 0xff;
600 - int ndummies = aspeed_smc_num_dummies(cmd);
601 -
602 - /*
603 - * No dummy cycles are expected with the current command. Turn
604 - * off snooping and let the transfer proceed normally.
605 - */
606 - if (ndummies <= 0) {
607 - s->snoop_index = SNOOP_OFF;
608 - return false;
609 - }
610 -
611 - s->snoop_dummies = ndummies * 8;
612 -
613 - } else if (s->snoop_index >= addr_width + 1) {
614 -
615 - /* The SPI transfer has reached the dummy cycles sequence */
616 - for (; s->snoop_dummies; s->snoop_dummies--) {
617 - ssi_transfer(s->spi, s->regs[R_DUMMY_DATA] & 0xff);
618 - }
619 -
620 - /* If no more dummy cycles are expected, turn off snooping */
621 - if (!s->snoop_dummies) {
622 - s->snoop_index = SNOOP_OFF;
623 - } else {
624 - s->snoop_index += size;
625 - }
626 -
627 - /*
628 - * Dummy cycles have been faked already. Ignore the current
629 - * SPI transfer
630 - */
631 - return true;
632 - }
633 -
634 - s->snoop_index += size;
635 - return false;
636 -}
637 -
537 static MemTxResult aspeed_smc_flash_write(void *opaque, hwaddr addr,
538 uint64_t data, unsigned size, MemTxAttrs attrs)
539 {
@@ -652,10 +551,6 @@ static MemTxResult aspeed_smc_flash_write(void *opaque, hwaddr addr,
551
552 switch (aspeed_smc_flash_mode(fl)) {
553 case CTRL_USERMODE:
655 - if (aspeed_smc_do_snoop(fl, data, size)) {
656 - break;
657 - }
658 -
554 for (i = 0; i < size; i++) {
555 ssi_transfer(s->spi, (data >> (8 * i)) & 0xff);
556 }
@@ -717,7 +612,6 @@ static void aspeed_smc_flash_update_ctrl(AspeedSMCFlash *fl, uint32_t value)
612 s->regs[s->r_ctrl0 + fl->cs] = value;
613
614 if (unselect != s->unselect) {
720 - s->snoop_index = unselect ? SNOOP_OFF : SNOOP_START;
615 aspeed_smc_flash_do_select(fl, unselect);
616 }
617 }
@@ -763,9 +657,6 @@ static void aspeed_smc_reset_hold(Object *obj, ResetType type)
657 aspeed_smc_flash_set_segment_region(s, i,
658 asc->segment_to_reg(s, &asc->segments[i]));
659 }
766 -
767 - s->snoop_index = SNOOP_OFF;
768 - s->snoop_dummies = 0;
660 }
661
662 static MemTxResult aspeed_smc_read(void *opaque, hwaddr addr, uint64_t *data,
@@ -1293,11 +1184,10 @@ static void aspeed_smc_realize(DeviceState *dev, Error **errp)
1184 static const VMStateDescription vmstate_aspeed_smc = {
1185 .name = "aspeed.smc",
1186 .version_id = 3,
1296 - .minimum_version_id = 2,
1187 + .minimum_version_id = 1,
1188 .fields = (const VMStateField[]) {
1189 VMSTATE_UINT32_ARRAY(regs, AspeedSMCState, ASPEED_SMC_R_MAX),
1299 - VMSTATE_UINT8(snoop_index, AspeedSMCState),
1300 - VMSTATE_UINT8(snoop_dummies, AspeedSMCState),
1190 + VMSTATE_UNUSED_V(2, 2), /* was snoop_index/snoop_dummies */
1191 VMSTATE_BOOL_V(unselect, AspeedSMCState, 3),
1192 VMSTATE_END_OF_LIST()
1193 }
hw/ssi/trace-events
-1
@@ -2,7 +2,6 @@
2
3 aspeed_smc_flash_set_segment(int cs, uint64_t reg, uint64_t start, uint64_t end) "CS%d segreg=0x%"PRIx64" [ 0x%"PRIx64" - 0x%"PRIx64" ]"
4 aspeed_smc_flash_read(int cs, uint64_t addr, uint32_t size, uint64_t data, int mode) "CS%d @0x%" PRIx64 " size %u: 0x%" PRIx64" mode:%d"
5 -aspeed_smc_do_snoop(int cs, int index, int dummies, int data) "CS%d index:0x%x dummies:%d data:0x%x"
5 aspeed_smc_flash_write(int cs, uint64_t addr, uint32_t size, uint64_t data, int mode) "CS%d @0x%" PRIx64 " size %u: 0x%" PRIx64" mode:%d"
6 aspeed_smc_read(uint64_t addr, uint32_t size, uint64_t data) "@0x%" PRIx64 " size %u: 0x%" PRIx64
7 aspeed_smc_dma_checksum(uint32_t addr, uint32_t data) "0x%08x: 0x%08x"
include/hw/ssi/aspeed_smc.h
-2
@@ -80,8 +80,6 @@ struct AspeedSMCState {
80
81 AspeedSMCFlash flashes[ASPEED_SMC_CS_MAX];
82
83 - uint8_t snoop_index;
84 - uint8_t snoop_dummies;
83 bool unselect;
84 };
85