* [PATCH 0/4] Rename ssi_transfer to ssi_transfer8
@ 2026-08-25 4:04 stephensportia
2026-08-25 4:04 ` [PATCH 1/4] hw/ssi: " stephensportia
` (5 more replies)
0 siblings, 6 replies; 26+ messages in thread
From: stephensportia @ 2026-08-25 4:04 UTC (permalink / raw)
To: qemu-devel
Cc: Palmer Dabbelt, Peter Maydell, Jamin Lin, qemu-ppc,
Cédric Le Goater, Steven Lee, Andrew Jeffery,
Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee,
Edgar E. Iglesias, Philippe Mathieu-Daudé, Alistair Francis,
Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin,
Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu,
Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens
From: Portia Stephens <portias@oss.tenstorrent.com>
The ssi_transfer function comments say that it takes a word varying
between 8-bits and 32-bits. ssi_transfer takes a 32-bit arg to transfer
but there is no means to indicate the number of bits that should
actually be transferred. All child classes of SSI_PERIPHERAL class have
transfer functions that, despite accepting a 32-bit tx, only transfer a
single byte; m25p80_transfer8(), ssi_sd_transfer(), ssd0323_transfer().
The current implementation depends on the SSI model to know
what peripheral model will be attached and what transfer size it
expects which is error prone. If a SSI_PERIPHERAL model was written that
accepted 32-bit transfers, it could not attach to any existing SSI
models.
This change updates the the naming of ssi_transfer to ssi_transfer8, as
well as changes the return value and transmit argument to be 8-bit.
Most ssi models handle this correctly already, sending a single byte at
a time. There are a few models that are written to support non 8-bit
transfers but there are no in-tree use cases that connect a peripheral
to the SSI device. These have been updated to use 8-bit transfers.
Portia Stephens (4):
hw/ssi: Rename ssi_transfer to ssi_transfer8
hw/ssi/pl022: Fix dropped upper bytes of ssi transfer
hw/arm/strongarm: Fix dropped upper byte of ssi transfer
hw/ssi/pnv_spi: Fix dropped upper bytes of ssi transfer
hw/arm/strongarm.c | 7 +++++--
hw/ssi/allwinner-a10-spi.c | 2 +-
hw/ssi/aspeed_smc.c | 14 ++++++-------
hw/ssi/bcm2835_spi.c | 2 +-
hw/ssi/ibex_spi_host.c | 5 +++--
hw/ssi/imx_spi.c | 2 +-
hw/ssi/mss-spi.c | 2 +-
hw/ssi/npcm7xx_fiu.c | 42 +++++++++++++++++++-------------------
hw/ssi/npcm_pspi.c | 4 ++--
hw/ssi/pl022.c | 12 +++++++----
hw/ssi/pnv_spi.c | 28 ++++++++++---------------
hw/ssi/sifive_spi.c | 2 +-
hw/ssi/ssi.c | 4 ++--
hw/ssi/stm32f2xx_spi.c | 2 +-
hw/ssi/xilinx_spi.c | 10 ++++-----
hw/ssi/xilinx_spips.c | 4 ++--
hw/ssi/xlnx-versal-ospi.c | 4 ++--
include/hw/ssi/ssi.h | 17 ++++++++-------
18 files changed, 82 insertions(+), 81 deletions(-)
--
2.43.0
^ permalink raw reply [flat|nested] 26+ messages in thread* [PATCH 1/4] hw/ssi: Rename ssi_transfer to ssi_transfer8 2026-08-25 4:04 [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 stephensportia @ 2026-08-25 4:04 ` stephensportia 2026-08-27 5:25 ` Alistair 2026-08-25 4:04 ` [PATCH 2/4] hw/ssi/pl022: Fix dropped upper bytes of ssi transfer stephensportia ` (4 subsequent siblings) 5 siblings, 1 reply; 26+ messages in thread From: stephensportia @ 2026-08-25 4:04 UTC (permalink / raw) To: qemu-devel Cc: Palmer Dabbelt, Peter Maydell, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Alistair Francis, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens From: Portia Stephens <portias@oss.tenstorrent.com> The ssi_transfer function comments say that it takes a word varying between 8-bits and 32-bits. ssi_transfer takes a 32-bit arg to transfer but there is no means to indicate the number of bits that should actually be transferred. All child classes of SSI_PERIPHERAL class have transfer functions that, despite accepting a 32-bit tx, only transfer a single byte; m25p80_transfer8(), ssi_sd_transfer(), ssd0323_transfer(). The current implementation depends on the SSI model to know what peripheral model will be attached and what transfer size it expects which is error prone. If a SSI_PERIPHERAL model was written that accepted 32-bit transfers, it could not attach to any existing SSI models. This change updates the naming of ssi_transfer to ssi_transfer8, as well as changes the return value and transmit argument to be 8-bit. Signed-off-by: Portia Stephens <portias@oss.tenstorrent.com> --- hw/arm/strongarm.c | 2 +- hw/ssi/allwinner-a10-spi.c | 2 +- hw/ssi/aspeed_smc.c | 14 ++++++------- hw/ssi/bcm2835_spi.c | 2 +- hw/ssi/ibex_spi_host.c | 5 +++-- hw/ssi/imx_spi.c | 2 +- hw/ssi/mss-spi.c | 2 +- hw/ssi/npcm7xx_fiu.c | 42 +++++++++++++++++++------------------- hw/ssi/npcm_pspi.c | 4 ++-- hw/ssi/pl022.c | 2 +- hw/ssi/pnv_spi.c | 2 +- hw/ssi/sifive_spi.c | 2 +- hw/ssi/ssi.c | 4 ++-- hw/ssi/stm32f2xx_spi.c | 2 +- hw/ssi/xilinx_spi.c | 10 ++++----- hw/ssi/xilinx_spips.c | 4 ++-- hw/ssi/xlnx-versal-ospi.c | 4 ++-- include/hw/ssi/ssi.h | 17 ++++++++------- 18 files changed, 61 insertions(+), 61 deletions(-) diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c index 5a3242195a..e400f0a185 100644 --- a/hw/arm/strongarm.c +++ b/hw/arm/strongarm.c @@ -1516,7 +1516,7 @@ static void strongarm_ssp_write(void *opaque, hwaddr addr, if (s->sscr[1] & SSCR1_LBM) { readval = value; } else { - readval = ssi_transfer(s->bus, value); + readval = ssi_transfer8(s->bus, value); } if (s->rx_level < 0x08) { diff --git a/hw/ssi/allwinner-a10-spi.c b/hw/ssi/allwinner-a10-spi.c index 69920b935a..5758e81c10 100644 --- a/hw/ssi/allwinner-a10-spi.c +++ b/hw/ssi/allwinner-a10-spi.c @@ -300,7 +300,7 @@ static void allwinner_a10_spi_flush_txfifo(AWA10SPIState *s) trace_allwinner_a10_spi_tx(tx); /* Write one byte at a time */ - rx = ssi_transfer(s->bus, tx); + rx = ssi_transfer8(s->bus, tx); trace_allwinner_a10_spi_rx(rx); diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c index bf596f7b2d..f6e8dd9457 100644 --- a/hw/ssi/aspeed_smc.c +++ b/hw/ssi/aspeed_smc.c @@ -488,10 +488,10 @@ static void aspeed_smc_flash_setup(AspeedSMCFlash *fl, uint32_t addr) /* Flash access can not exceed CS segment */ addr = aspeed_smc_check_segment_addr(fl, addr); - ssi_transfer(s->spi, cmd); + ssi_transfer8(s->spi, cmd); while (i--) { if (aspeed_smc_addr_byte_enabled(s, i)) { - ssi_transfer(s->spi, (addr >> (i * 8)) & 0xff); + ssi_transfer8(s->spi, (addr >> (i * 8)) & 0xff); } } @@ -503,7 +503,7 @@ static void aspeed_smc_flash_setup(AspeedSMCFlash *fl, uint32_t addr) */ if (aspeed_smc_flash_mode(fl) == CTRL_FREADMODE) { for (i = 0; i < aspeed_smc_flash_dummy_bytes(fl); i++) { - ssi_transfer(fl->controller->spi, s->regs[R_DUMMY_DATA] & 0xff); + ssi_transfer8(fl->controller->spi, s->regs[R_DUMMY_DATA] & 0xff); } } } @@ -519,7 +519,7 @@ static MemTxResult aspeed_smc_flash_read(void *opaque, hwaddr addr, switch (aspeed_smc_flash_mode(fl)) { case CTRL_USERMODE: for (i = 0; i < size; i++) { - *data |= (uint64_t) ssi_transfer(s->spi, 0x0) << (8 * i); + *data |= (uint64_t) ssi_transfer8(s->spi, 0x0) << (8 * i); } break; case CTRL_READMODE: @@ -528,7 +528,7 @@ static MemTxResult aspeed_smc_flash_read(void *opaque, hwaddr addr, aspeed_smc_flash_setup(fl, addr); for (i = 0; i < size; i++) { - *data |= (uint64_t) ssi_transfer(s->spi, 0x0) << (8 * i); + *data |= (uint64_t) ssi_transfer8(s->spi, 0x0) << (8 * i); } aspeed_smc_flash_unselect(fl); @@ -561,7 +561,7 @@ static MemTxResult aspeed_smc_flash_write(void *opaque, hwaddr addr, switch (aspeed_smc_flash_mode(fl)) { case CTRL_USERMODE: for (i = 0; i < size; i++) { - ssi_transfer(s->spi, (data >> (8 * i)) & 0xff); + ssi_transfer8(s->spi, (data >> (8 * i)) & 0xff); } break; case CTRL_WRITEMODE: @@ -569,7 +569,7 @@ static MemTxResult aspeed_smc_flash_write(void *opaque, hwaddr addr, aspeed_smc_flash_setup(fl, addr); for (i = 0; i < size; i++) { - ssi_transfer(s->spi, (data >> (8 * i)) & 0xff); + ssi_transfer8(s->spi, (data >> (8 * i)) & 0xff); } aspeed_smc_flash_unselect(fl); diff --git a/hw/ssi/bcm2835_spi.c b/hw/ssi/bcm2835_spi.c index 01763c458c..7a0a8fa392 100644 --- a/hw/ssi/bcm2835_spi.c +++ b/hw/ssi/bcm2835_spi.c @@ -91,7 +91,7 @@ static void bcm2835_spi_flush_tx_fifo(BCM2835SPIState *s) while (!fifo8_is_empty(&s->tx_fifo) && !fifo8_is_full(&s->rx_fifo)) { tx_byte = fifo8_pop(&s->tx_fifo); - rx_byte = ssi_transfer(s->bus, tx_byte); + rx_byte = ssi_transfer8(s->bus, tx_byte); fifo8_push(&s->rx_fifo, rx_byte); } diff --git a/hw/ssi/ibex_spi_host.c b/hw/ssi/ibex_spi_host.c index 1e574c3fcb..b5e556eedc 100644 --- a/hw/ssi/ibex_spi_host.c +++ b/hw/ssi/ibex_spi_host.c @@ -236,7 +236,8 @@ static void ibex_spi_host_irq(IbexSPIHostState *s) static void ibex_spi_host_transfer(IbexSPIHostState *s) { - uint32_t rx, tx, data; + uint32_t data; + uint8_t rx, tx; /* Get num of one byte transfers */ uint8_t segment_len = FIELD_EX32(s->regs[IBEX_SPI_HOST_COMMAND], COMMAND, LEN); @@ -254,7 +255,7 @@ static void ibex_spi_host_transfer(IbexSPIHostState *s) tx = fifo8_pop(&s->tx_fifo); } - rx = ssi_transfer(s->ssi, tx); + rx = ssi_transfer8(s->ssi, tx); trace_ibex_spi_host_transfer(tx, rx); diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c index 8e014b7a7b..b25cf6c559 100644 --- a/hw/ssi/imx_spi.c +++ b/hw/ssi/imx_spi.c @@ -194,7 +194,7 @@ static void imx_spi_flush_txfifo(IMXSPIState *s) DPRINTF("writing 0x%02x\n", (uint32_t)byte); /* We need to write one byte at a time */ - byte = ssi_transfer(s->bus, byte); + byte = ssi_transfer8(s->bus, byte); DPRINTF("0x%02x read\n", (uint32_t)byte); diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c index 3c118fc0f8..8a7af68a8a 100644 --- a/hw/ssi/mss-spi.c +++ b/hw/ssi/mss-spi.c @@ -234,7 +234,7 @@ static void spi_flush_txfifo(MSSSpiState *s) tx = fifo32_pop(&s->tx_fifo); DB_PRINT("data tx:0x%" PRIx32, tx); - rx = ssi_transfer(s->spi, tx); + rx = ssi_transfer8(s->spi, tx); DB_PRINT("data rx:0x%" PRIx32, rx); if (fifo32_num_used(&s->rx_fifo) == s->fifo_depth) { diff --git a/hw/ssi/npcm7xx_fiu.c b/hw/ssi/npcm7xx_fiu.c index d41d877cfb..b0be46aa18 100644 --- a/hw/ssi/npcm7xx_fiu.c +++ b/hw/ssi/npcm7xx_fiu.c @@ -162,16 +162,16 @@ static uint64_t npcm7xx_fiu_flash_read(void *opaque, hwaddr addr, npcm7xx_fiu_select(fiu, npcm7xx_fiu_cs_index(fiu, f)); drd_cfg = fiu->regs[NPCM7XX_FIU_DRD_CFG]; - ssi_transfer(fiu->spi, FIU_DRD_CFG_RDCMD(drd_cfg)); + ssi_transfer8(fiu->spi, FIU_DRD_CFG_RDCMD(drd_cfg)); switch (FIU_DRD_CFG_ADDSIZ(drd_cfg)) { case FIU_ADDSIZ_4BYTES: - ssi_transfer(fiu->spi, extract32(addr, 24, 8)); + ssi_transfer8(fiu->spi, extract32(addr, 24, 8)); /* fall through */ case FIU_ADDSIZ_3BYTES: - ssi_transfer(fiu->spi, extract32(addr, 16, 8)); - ssi_transfer(fiu->spi, extract32(addr, 8, 8)); - ssi_transfer(fiu->spi, extract32(addr, 0, 8)); + ssi_transfer8(fiu->spi, extract32(addr, 16, 8)); + ssi_transfer8(fiu->spi, extract32(addr, 8, 8)); + ssi_transfer8(fiu->spi, extract32(addr, 0, 8)); break; default: @@ -182,11 +182,11 @@ static uint64_t npcm7xx_fiu_flash_read(void *opaque, hwaddr addr, dummy_bytes = FIU_DRD_CFG_DBW(drd_cfg); for (i = 0; i < dummy_bytes; i++) { - ssi_transfer(fiu->spi, 0); + ssi_transfer8(fiu->spi, 0); } for (i = 0; i < size; i++) { - value = deposit64(value, 8 * i, 8, ssi_transfer(fiu->spi, 0)); + value = deposit64(value, 8 * i, 8, ssi_transfer8(fiu->spi, 0)); } trace_npcm7xx_fiu_flash_read(DEVICE(fiu)->canonical_path, fiu->active_cs, @@ -219,16 +219,16 @@ static void npcm7xx_fiu_flash_write(void *opaque, hwaddr addr, uint64_t v, npcm7xx_fiu_select(fiu, cs_id); dwr_cfg = fiu->regs[NPCM7XX_FIU_DWR_CFG]; - ssi_transfer(fiu->spi, FIU_DWR_CFG_WRCMD(dwr_cfg)); + ssi_transfer8(fiu->spi, FIU_DWR_CFG_WRCMD(dwr_cfg)); switch (FIU_DWR_CFG_ADDSIZ(dwr_cfg)) { case FIU_ADDSIZ_4BYTES: - ssi_transfer(fiu->spi, extract32(addr, 24, 8)); + ssi_transfer8(fiu->spi, extract32(addr, 24, 8)); /* fall through */ case FIU_ADDSIZ_3BYTES: - ssi_transfer(fiu->spi, extract32(addr, 16, 8)); - ssi_transfer(fiu->spi, extract32(addr, 8, 8)); - ssi_transfer(fiu->spi, extract32(addr, 0, 8)); + ssi_transfer8(fiu->spi, extract32(addr, 16, 8)); + ssi_transfer8(fiu->spi, extract32(addr, 8, 8)); + ssi_transfer8(fiu->spi, extract32(addr, 0, 8)); break; default: @@ -238,7 +238,7 @@ static void npcm7xx_fiu_flash_write(void *opaque, hwaddr addr, uint64_t v, } for (i = 0; i < size; i++) { - ssi_transfer(fiu->spi, extract64(v, i * 8, 8)); + ssi_transfer8(fiu->spi, extract64(v, i * 8, 8)); } npcm7xx_fiu_deselect(fiu); @@ -287,16 +287,16 @@ static void send_address(SSIBus *spi, unsigned int addsiz, uint32_t addr) { switch (addsiz) { case 4: - ssi_transfer(spi, extract32(addr, 24, 8)); + ssi_transfer8(spi, extract32(addr, 24, 8)); /* fall through */ case 3: - ssi_transfer(spi, extract32(addr, 16, 8)); + ssi_transfer8(spi, extract32(addr, 16, 8)); /* fall through */ case 2: - ssi_transfer(spi, extract32(addr, 8, 8)); + ssi_transfer8(spi, extract32(addr, 8, 8)); /* fall through */ case 1: - ssi_transfer(spi, extract32(addr, 0, 8)); + ssi_transfer8(spi, extract32(addr, 0, 8)); /* fall through */ case 0: break; @@ -309,7 +309,7 @@ static void send_dummy_bytes(SSIBus *spi, uint32_t uma_cfg) unsigned int i; for (i = 0; i < FIU_UMA_CFG_DBSIZ(uma_cfg); i++) { - ssi_transfer(spi, 0); + ssi_transfer8(spi, 0); } } @@ -329,7 +329,7 @@ static void npcm7xx_fiu_uma_transaction(NPCM7xxFIUState *s) /* Send command, if present. */ uma_cfg = s->regs[NPCM7XX_FIU_UMA_CFG]; if (FIU_UMA_CFG_CMDSIZ(uma_cfg) > 0) { - ssi_transfer(s->spi, extract32(s->regs[NPCM7XX_FIU_UMA_CMD], 0, 8)); + ssi_transfer8(s->spi, extract32(s->regs[NPCM7XX_FIU_UMA_CMD], 0, 8)); } /* Send address, if present. */ @@ -342,7 +342,7 @@ static void npcm7xx_fiu_uma_transaction(NPCM7xxFIUState *s) (i < 16) ? (NPCM7XX_FIU_UMA_DW0 + i / 4) : NPCM7XX_FIU_UMA_DW3; unsigned int field = (i % 4) * 8; - ssi_transfer(s->spi, extract32(s->regs[reg], field, 8)); + ssi_transfer8(s->spi, extract32(s->regs[reg], field, 8)); } /* Send dummy bytes, if present */ @@ -354,7 +354,7 @@ static void npcm7xx_fiu_uma_transaction(NPCM7xxFIUState *s) unsigned int field = (i % 4) * 8; uint8_t c; - c = ssi_transfer(s->spi, 0); + c = ssi_transfer8(s->spi, 0); if (reg <= NPCM7XX_FIU_UMA_DR3) { s->regs[reg] = deposit32(s->regs[reg], field, 8, c); } diff --git a/hw/ssi/npcm_pspi.c b/hw/ssi/npcm_pspi.c index 2e05d5dacb..38ae6e0972 100644 --- a/hw/ssi/npcm_pspi.c +++ b/hw/ssi/npcm_pspi.c @@ -77,9 +77,9 @@ static void npcm_pspi_write_data(NPCMPSPIState *s, uint16_t data) uint16_t value = 0; if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, MOD)) { - value = ssi_transfer(s->spi, extract16(data, 8, 8)) << 8; + value = ssi_transfer8(s->spi, extract16(data, 8, 8)) << 8; } - value |= ssi_transfer(s->spi, extract16(data, 0, 8)); + value |= ssi_transfer8(s->spi, extract16(data, 0, 8)); s->regs[R_PSPI_DATA] = value; /* Mark data as available */ diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c index 715a2d21f4..eaac664ec5 100644 --- a/hw/ssi/pl022.c +++ b/hw/ssi/pl022.c @@ -103,7 +103,7 @@ static void pl022_xfer(PL022State *s) if (s->cr1 & PL022_CR1_LBM) { /* Loopback mode. */ } else { - val = ssi_transfer(s->ssi, val); + val = ssi_transfer8(s->ssi, val); } s->rx_fifo[o] = val & s->bitmask; i = (i + 1) & 7; diff --git a/hw/ssi/pnv_spi.c b/hw/ssi/pnv_spi.c index f3add8cab9..e2a8a710da 100644 --- a/hw/ssi/pnv_spi.c +++ b/hw/ssi/pnv_spi.c @@ -209,7 +209,7 @@ static void transfer(PnvSpi *s) qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: TX_FIFO underflow\n"); } } - rx = ssi_transfer(s->ssi_bus, tx); + rx = ssi_transfer8(s->ssi_bus, tx); for (int i = 0; i < s->transfer_len; i++) { if ((offset + i) >= payload_len) { break; diff --git a/hw/ssi/sifive_spi.c b/hw/ssi/sifive_spi.c index 2ece78053b..1a2aac2daa 100644 --- a/hw/ssi/sifive_spi.c +++ b/hw/ssi/sifive_spi.c @@ -134,7 +134,7 @@ static void sifive_spi_flush_txfifo(SiFiveSPIState *s) while (!fifo8_is_empty(&s->tx_fifo)) { tx = fifo8_pop(&s->tx_fifo); - rx = ssi_transfer(s->spi, tx); + rx = ssi_transfer8(s->spi, tx); if (!fifo8_is_full(&s->rx_fifo)) { if (!(s->regs[R_FMT] & FMT_DIR)) { diff --git a/hw/ssi/ssi.c b/hw/ssi/ssi.c index 3a4fade2d5..ce2325bbd4 100644 --- a/hw/ssi/ssi.c +++ b/hw/ssi/ssi.c @@ -153,11 +153,11 @@ SSIBus *ssi_create_bus(DeviceState *parent, const char *name) return SSI_BUS(bus); } -uint32_t ssi_transfer(SSIBus *bus, uint32_t val) +uint8_t ssi_transfer8(SSIBus *bus, uint8_t val) { BusState *b = BUS(bus); BusChild *kid; - uint32_t r = 0; + uint8_t r = 0; QTAILQ_FOREACH(kid, &b->children, sibling) { SSIPeripheral *p = SSI_PERIPHERAL(kid->child); diff --git a/hw/ssi/stm32f2xx_spi.c b/hw/ssi/stm32f2xx_spi.c index 871d57324d..eca0b93f3f 100644 --- a/hw/ssi/stm32f2xx_spi.c +++ b/hw/ssi/stm32f2xx_spi.c @@ -59,7 +59,7 @@ static void stm32f2xx_spi_transfer(STM32F2XXSPIState *s) { DB_PRINT("Data to send: 0x%x\n", s->spi_dr); - s->spi_dr = ssi_transfer(s->ssi, s->spi_dr); + s->spi_dr = ssi_transfer8(s->ssi, s->spi_dr); s->spi_sr |= STM_SPI_SR_RXNE; DB_PRINT("Data received: 0x%x\n", s->spi_dr); diff --git a/hw/ssi/xilinx_spi.c b/hw/ssi/xilinx_spi.c index 79f3e8bfae..45e9459396 100644 --- a/hw/ssi/xilinx_spi.c +++ b/hw/ssi/xilinx_spi.c @@ -176,18 +176,18 @@ static inline int spi_master_enabled(XilinxSPI *s) static void spi_flush_txfifo(XilinxSPI *s) { - uint32_t tx; - uint32_t rx; + uint8_t tx; + uint8_t rx; while (!fifo8_is_empty(&s->tx_fifo)) { - tx = (uint32_t)fifo8_pop(&s->tx_fifo); + tx = fifo8_pop(&s->tx_fifo); DB_PRINT("data tx:%x\n", tx); - rx = ssi_transfer(s->spi, tx); + rx = ssi_transfer8(s->spi, tx); DB_PRINT("data rx:%x\n", rx); if (fifo8_is_full(&s->rx_fifo)) { s->regs[R_IPISR] |= IRQ_DRR_OVERRUN; } else { - fifo8_push(&s->rx_fifo, (uint8_t)rx); + fifo8_push(&s->rx_fifo, rx); if (fifo8_is_full(&s->rx_fifo)) { s->regs[R_SPISR] |= SR_RX_FULL; s->regs[R_IPISR] |= IRQ_DRR_FULL; diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c index e4fce2c195..b915000770 100644 --- a/hw/ssi/xilinx_spips.c +++ b/hw/ssi/xilinx_spips.c @@ -576,7 +576,7 @@ static void xlnx_zynqmp_qspips_flush_fifo_g(XlnxZynqMPQSPIPS *s) busses = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, DATA_BUS_SELECT); for (i = 0; i < 2; ++i) { DB_PRINT_L(1, "bus %d tx = %02x\n", i, tx_rx[i]); - tx_rx[i] = ssi_transfer(XILINX_SPIPS(s)->spi[i], tx_rx[i]); + tx_rx[i] = ssi_transfer8(XILINX_SPIPS(s)->spi[i], tx_rx[i]); DB_PRINT_L(1, "bus %d rx = %02x\n", i, tx_rx[i]); } if (s->regs[R_GQSPI_DATA_STS] > 1 && @@ -696,7 +696,7 @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS *s) int bus = num_effective_busses(s) - 1 - i; DB_PRINT_L(debug_level, "tx = %02x\n", tx_rx[i]); - tx_rx[i] = ssi_transfer(s->spi[bus], (uint32_t)tx_rx[i]); + tx_rx[i] = ssi_transfer8(s->spi[bus], tx_rx[i]); DB_PRINT_L(debug_level, "rx = %02x\n", tx_rx[i]); } diff --git a/hw/ssi/xlnx-versal-ospi.c b/hw/ssi/xlnx-versal-ospi.c index e25e4c26c2..8f2cb71414 100644 --- a/hw/ssi/xlnx-versal-ospi.c +++ b/hw/ssi/xlnx-versal-ospi.c @@ -631,9 +631,9 @@ static void ospi_disable_cs(XlnxVersalOspi *s) static void ospi_flush_txfifo(XlnxVersalOspi *s) { while (!fifo8_is_empty(&s->tx_fifo)) { - uint32_t tx_rx = fifo8_pop(&s->tx_fifo); + uint8_t tx_rx = fifo8_pop(&s->tx_fifo); - tx_rx = ssi_transfer(s->spi, tx_rx); + tx_rx = ssi_transfer8(s->spi, tx_rx); fifo8_push(&s->rx_fifo, tx_rx); } } diff --git a/include/hw/ssi/ssi.h b/include/hw/ssi/ssi.h index 6d6d8ccb3d..e8be6c2023 100644 --- a/include/hw/ssi/ssi.h +++ b/include/hw/ssi/ssi.h @@ -38,7 +38,7 @@ struct SSIPeripheralClass { /* if you have standard or no CS behaviour, just override transfer. * This is called when the device cs is active (true by default). - * See ssi_transfer(). + * See ssi_transfer8(). */ uint32_t (*transfer)(SSIPeripheral *dev, uint32_t val); /* called when the CS line changes. Optional, devices only need to implement @@ -53,7 +53,7 @@ struct SSIPeripheralClass { * of the CS behaviour at the device level. transfer, set_cs, and * cs_polarity are unused if this is overwritten. Transfer_raw will * always be called for the device for every txrx access to the parent bus - * See ssi_transfer(). + * See ssi_transfer8(). */ uint32_t (*transfer_raw)(SSIPeripheral *dev, uint32_t val); }; @@ -113,18 +113,17 @@ bool ssi_realize_and_unref(DeviceState *dev, SSIBus *bus, Error **errp); SSIBus *ssi_create_bus(DeviceState *parent, const char *name); /** - * Transfer a word on a SSI bus + * Transfer a byte on a SSI bus * @bus: SSI bus - * @val: word to transmit + * @val: byte to transmit * - * At the same time, read a word and write the @val one on the SSI bus. + * At the same time, read a byte and write the @val one on the SSI bus. * - * SSI words might vary between 8 and 32 bits. The same number of bits - * written is received. + * SSI always transfers and receives 8-bits. * - * Return: word value received + * Return: byte received */ -uint32_t ssi_transfer(SSIBus *bus, uint32_t val); +uint8_t ssi_transfer8(SSIBus *bus, uint8_t val); DeviceState *ssi_get_cs(SSIBus *bus, uint8_t cs_index); -- 2.43.0 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH 1/4] hw/ssi: Rename ssi_transfer to ssi_transfer8 2026-08-25 4:04 ` [PATCH 1/4] hw/ssi: " stephensportia @ 2026-08-27 5:25 ` Alistair 0 siblings, 0 replies; 26+ messages in thread From: Alistair @ 2026-08-27 5:25 UTC (permalink / raw) To: stephensportia, qemu-devel Cc: Palmer Dabbelt, Peter Maydell, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Tue, 2026-08-25 at 14:04 +1000, stephensportia@gmail.com wrote: > From: Portia Stephens <portias@oss.tenstorrent.com> > > The ssi_transfer function comments say that it takes a word varying > between 8-bits and 32-bits. ssi_transfer takes a 32-bit arg to > transfer > but there is no means to indicate the number of bits that should > actually be transferred. All child classes of SSI_PERIPHERAL class > have > transfer functions that, despite accepting a 32-bit tx, only transfer > a > single byte; m25p80_transfer8(), ssi_sd_transfer(), > ssd0323_transfer(). > > The current implementation depends on the SSI model to know > what peripheral model will be attached and what transfer size it > expects which is error prone. If a SSI_PERIPHERAL model was written > that > accepted 32-bit transfers, it could not attach to any existing SSI > models. > > This change updates the naming of ssi_transfer to ssi_transfer8, as > well as changes the return value and transmit argument to be 8-bit. > > Signed-off-by: Portia Stephens <portias@oss.tenstorrent.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > hw/arm/strongarm.c | 2 +- > hw/ssi/allwinner-a10-spi.c | 2 +- > hw/ssi/aspeed_smc.c | 14 ++++++------- > hw/ssi/bcm2835_spi.c | 2 +- > hw/ssi/ibex_spi_host.c | 5 +++-- > hw/ssi/imx_spi.c | 2 +- > hw/ssi/mss-spi.c | 2 +- > hw/ssi/npcm7xx_fiu.c | 42 +++++++++++++++++++----------------- > -- > hw/ssi/npcm_pspi.c | 4 ++-- > hw/ssi/pl022.c | 2 +- > hw/ssi/pnv_spi.c | 2 +- > hw/ssi/sifive_spi.c | 2 +- > hw/ssi/ssi.c | 4 ++-- > hw/ssi/stm32f2xx_spi.c | 2 +- > hw/ssi/xilinx_spi.c | 10 ++++----- > hw/ssi/xilinx_spips.c | 4 ++-- > hw/ssi/xlnx-versal-ospi.c | 4 ++-- > include/hw/ssi/ssi.h | 17 ++++++++------- > 18 files changed, 61 insertions(+), 61 deletions(-) > > diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c > index 5a3242195a..e400f0a185 100644 > --- a/hw/arm/strongarm.c > +++ b/hw/arm/strongarm.c > @@ -1516,7 +1516,7 @@ static void strongarm_ssp_write(void *opaque, > hwaddr addr, > if (s->sscr[1] & SSCR1_LBM) { > readval = value; > } else { > - readval = ssi_transfer(s->bus, value); > + readval = ssi_transfer8(s->bus, value); > } > > if (s->rx_level < 0x08) { > diff --git a/hw/ssi/allwinner-a10-spi.c b/hw/ssi/allwinner-a10-spi.c > index 69920b935a..5758e81c10 100644 > --- a/hw/ssi/allwinner-a10-spi.c > +++ b/hw/ssi/allwinner-a10-spi.c > @@ -300,7 +300,7 @@ static void > allwinner_a10_spi_flush_txfifo(AWA10SPIState *s) > trace_allwinner_a10_spi_tx(tx); > > /* Write one byte at a time */ > - rx = ssi_transfer(s->bus, tx); > + rx = ssi_transfer8(s->bus, tx); > > trace_allwinner_a10_spi_rx(rx); > > diff --git a/hw/ssi/aspeed_smc.c b/hw/ssi/aspeed_smc.c > index bf596f7b2d..f6e8dd9457 100644 > --- a/hw/ssi/aspeed_smc.c > +++ b/hw/ssi/aspeed_smc.c > @@ -488,10 +488,10 @@ static void > aspeed_smc_flash_setup(AspeedSMCFlash *fl, uint32_t addr) > /* Flash access can not exceed CS segment */ > addr = aspeed_smc_check_segment_addr(fl, addr); > > - ssi_transfer(s->spi, cmd); > + ssi_transfer8(s->spi, cmd); > while (i--) { > if (aspeed_smc_addr_byte_enabled(s, i)) { > - ssi_transfer(s->spi, (addr >> (i * 8)) & 0xff); > + ssi_transfer8(s->spi, (addr >> (i * 8)) & 0xff); > } > } > > @@ -503,7 +503,7 @@ static void aspeed_smc_flash_setup(AspeedSMCFlash > *fl, uint32_t addr) > */ > if (aspeed_smc_flash_mode(fl) == CTRL_FREADMODE) { > for (i = 0; i < aspeed_smc_flash_dummy_bytes(fl); i++) { > - ssi_transfer(fl->controller->spi, s->regs[R_DUMMY_DATA] > & 0xff); > + ssi_transfer8(fl->controller->spi, s->regs[R_DUMMY_DATA] > & 0xff); > } > } > } > @@ -519,7 +519,7 @@ static MemTxResult aspeed_smc_flash_read(void > *opaque, hwaddr addr, > switch (aspeed_smc_flash_mode(fl)) { > case CTRL_USERMODE: > for (i = 0; i < size; i++) { > - *data |= (uint64_t) ssi_transfer(s->spi, 0x0) << (8 * > i); > + *data |= (uint64_t) ssi_transfer8(s->spi, 0x0) << (8 * > i); > } > break; > case CTRL_READMODE: > @@ -528,7 +528,7 @@ static MemTxResult aspeed_smc_flash_read(void > *opaque, hwaddr addr, > aspeed_smc_flash_setup(fl, addr); > > for (i = 0; i < size; i++) { > - *data |= (uint64_t) ssi_transfer(s->spi, 0x0) << (8 * > i); > + *data |= (uint64_t) ssi_transfer8(s->spi, 0x0) << (8 * > i); > } > > aspeed_smc_flash_unselect(fl); > @@ -561,7 +561,7 @@ static MemTxResult aspeed_smc_flash_write(void > *opaque, hwaddr addr, > switch (aspeed_smc_flash_mode(fl)) { > case CTRL_USERMODE: > for (i = 0; i < size; i++) { > - ssi_transfer(s->spi, (data >> (8 * i)) & 0xff); > + ssi_transfer8(s->spi, (data >> (8 * i)) & 0xff); > } > break; > case CTRL_WRITEMODE: > @@ -569,7 +569,7 @@ static MemTxResult aspeed_smc_flash_write(void > *opaque, hwaddr addr, > aspeed_smc_flash_setup(fl, addr); > > for (i = 0; i < size; i++) { > - ssi_transfer(s->spi, (data >> (8 * i)) & 0xff); > + ssi_transfer8(s->spi, (data >> (8 * i)) & 0xff); > } > > aspeed_smc_flash_unselect(fl); > diff --git a/hw/ssi/bcm2835_spi.c b/hw/ssi/bcm2835_spi.c > index 01763c458c..7a0a8fa392 100644 > --- a/hw/ssi/bcm2835_spi.c > +++ b/hw/ssi/bcm2835_spi.c > @@ -91,7 +91,7 @@ static void > bcm2835_spi_flush_tx_fifo(BCM2835SPIState *s) > > while (!fifo8_is_empty(&s->tx_fifo) && !fifo8_is_full(&s- > >rx_fifo)) { > tx_byte = fifo8_pop(&s->tx_fifo); > - rx_byte = ssi_transfer(s->bus, tx_byte); > + rx_byte = ssi_transfer8(s->bus, tx_byte); > fifo8_push(&s->rx_fifo, rx_byte); > } > > diff --git a/hw/ssi/ibex_spi_host.c b/hw/ssi/ibex_spi_host.c > index 1e574c3fcb..b5e556eedc 100644 > --- a/hw/ssi/ibex_spi_host.c > +++ b/hw/ssi/ibex_spi_host.c > @@ -236,7 +236,8 @@ static void ibex_spi_host_irq(IbexSPIHostState > *s) > > static void ibex_spi_host_transfer(IbexSPIHostState *s) > { > - uint32_t rx, tx, data; > + uint32_t data; > + uint8_t rx, tx; > /* Get num of one byte transfers */ > uint8_t segment_len = FIELD_EX32(s->regs[IBEX_SPI_HOST_COMMAND], > COMMAND, LEN); > @@ -254,7 +255,7 @@ static void > ibex_spi_host_transfer(IbexSPIHostState *s) > tx = fifo8_pop(&s->tx_fifo); > } > > - rx = ssi_transfer(s->ssi, tx); > + rx = ssi_transfer8(s->ssi, tx); > > trace_ibex_spi_host_transfer(tx, rx); > > diff --git a/hw/ssi/imx_spi.c b/hw/ssi/imx_spi.c > index 8e014b7a7b..b25cf6c559 100644 > --- a/hw/ssi/imx_spi.c > +++ b/hw/ssi/imx_spi.c > @@ -194,7 +194,7 @@ static void imx_spi_flush_txfifo(IMXSPIState *s) > DPRINTF("writing 0x%02x\n", (uint32_t)byte); > > /* We need to write one byte at a time */ > - byte = ssi_transfer(s->bus, byte); > + byte = ssi_transfer8(s->bus, byte); > > DPRINTF("0x%02x read\n", (uint32_t)byte); > > diff --git a/hw/ssi/mss-spi.c b/hw/ssi/mss-spi.c > index 3c118fc0f8..8a7af68a8a 100644 > --- a/hw/ssi/mss-spi.c > +++ b/hw/ssi/mss-spi.c > @@ -234,7 +234,7 @@ static void spi_flush_txfifo(MSSSpiState *s) > > tx = fifo32_pop(&s->tx_fifo); > DB_PRINT("data tx:0x%" PRIx32, tx); > - rx = ssi_transfer(s->spi, tx); > + rx = ssi_transfer8(s->spi, tx); > DB_PRINT("data rx:0x%" PRIx32, rx); > > if (fifo32_num_used(&s->rx_fifo) == s->fifo_depth) { > diff --git a/hw/ssi/npcm7xx_fiu.c b/hw/ssi/npcm7xx_fiu.c > index d41d877cfb..b0be46aa18 100644 > --- a/hw/ssi/npcm7xx_fiu.c > +++ b/hw/ssi/npcm7xx_fiu.c > @@ -162,16 +162,16 @@ static uint64_t npcm7xx_fiu_flash_read(void > *opaque, hwaddr addr, > npcm7xx_fiu_select(fiu, npcm7xx_fiu_cs_index(fiu, f)); > > drd_cfg = fiu->regs[NPCM7XX_FIU_DRD_CFG]; > - ssi_transfer(fiu->spi, FIU_DRD_CFG_RDCMD(drd_cfg)); > + ssi_transfer8(fiu->spi, FIU_DRD_CFG_RDCMD(drd_cfg)); > > switch (FIU_DRD_CFG_ADDSIZ(drd_cfg)) { > case FIU_ADDSIZ_4BYTES: > - ssi_transfer(fiu->spi, extract32(addr, 24, 8)); > + ssi_transfer8(fiu->spi, extract32(addr, 24, 8)); > /* fall through */ > case FIU_ADDSIZ_3BYTES: > - ssi_transfer(fiu->spi, extract32(addr, 16, 8)); > - ssi_transfer(fiu->spi, extract32(addr, 8, 8)); > - ssi_transfer(fiu->spi, extract32(addr, 0, 8)); > + ssi_transfer8(fiu->spi, extract32(addr, 16, 8)); > + ssi_transfer8(fiu->spi, extract32(addr, 8, 8)); > + ssi_transfer8(fiu->spi, extract32(addr, 0, 8)); > break; > > default: > @@ -182,11 +182,11 @@ static uint64_t npcm7xx_fiu_flash_read(void > *opaque, hwaddr addr, > > dummy_bytes = FIU_DRD_CFG_DBW(drd_cfg); > for (i = 0; i < dummy_bytes; i++) { > - ssi_transfer(fiu->spi, 0); > + ssi_transfer8(fiu->spi, 0); > } > > for (i = 0; i < size; i++) { > - value = deposit64(value, 8 * i, 8, ssi_transfer(fiu->spi, > 0)); > + value = deposit64(value, 8 * i, 8, ssi_transfer8(fiu->spi, > 0)); > } > > trace_npcm7xx_fiu_flash_read(DEVICE(fiu)->canonical_path, fiu- > >active_cs, > @@ -219,16 +219,16 @@ static void npcm7xx_fiu_flash_write(void > *opaque, hwaddr addr, uint64_t v, > npcm7xx_fiu_select(fiu, cs_id); > > dwr_cfg = fiu->regs[NPCM7XX_FIU_DWR_CFG]; > - ssi_transfer(fiu->spi, FIU_DWR_CFG_WRCMD(dwr_cfg)); > + ssi_transfer8(fiu->spi, FIU_DWR_CFG_WRCMD(dwr_cfg)); > > switch (FIU_DWR_CFG_ADDSIZ(dwr_cfg)) { > case FIU_ADDSIZ_4BYTES: > - ssi_transfer(fiu->spi, extract32(addr, 24, 8)); > + ssi_transfer8(fiu->spi, extract32(addr, 24, 8)); > /* fall through */ > case FIU_ADDSIZ_3BYTES: > - ssi_transfer(fiu->spi, extract32(addr, 16, 8)); > - ssi_transfer(fiu->spi, extract32(addr, 8, 8)); > - ssi_transfer(fiu->spi, extract32(addr, 0, 8)); > + ssi_transfer8(fiu->spi, extract32(addr, 16, 8)); > + ssi_transfer8(fiu->spi, extract32(addr, 8, 8)); > + ssi_transfer8(fiu->spi, extract32(addr, 0, 8)); > break; > > default: > @@ -238,7 +238,7 @@ static void npcm7xx_fiu_flash_write(void *opaque, > hwaddr addr, uint64_t v, > } > > for (i = 0; i < size; i++) { > - ssi_transfer(fiu->spi, extract64(v, i * 8, 8)); > + ssi_transfer8(fiu->spi, extract64(v, i * 8, 8)); > } > > npcm7xx_fiu_deselect(fiu); > @@ -287,16 +287,16 @@ static void send_address(SSIBus *spi, unsigned > int addsiz, uint32_t addr) > { > switch (addsiz) { > case 4: > - ssi_transfer(spi, extract32(addr, 24, 8)); > + ssi_transfer8(spi, extract32(addr, 24, 8)); > /* fall through */ > case 3: > - ssi_transfer(spi, extract32(addr, 16, 8)); > + ssi_transfer8(spi, extract32(addr, 16, 8)); > /* fall through */ > case 2: > - ssi_transfer(spi, extract32(addr, 8, 8)); > + ssi_transfer8(spi, extract32(addr, 8, 8)); > /* fall through */ > case 1: > - ssi_transfer(spi, extract32(addr, 0, 8)); > + ssi_transfer8(spi, extract32(addr, 0, 8)); > /* fall through */ > case 0: > break; > @@ -309,7 +309,7 @@ static void send_dummy_bytes(SSIBus *spi, > uint32_t uma_cfg) > unsigned int i; > > for (i = 0; i < FIU_UMA_CFG_DBSIZ(uma_cfg); i++) { > - ssi_transfer(spi, 0); > + ssi_transfer8(spi, 0); > } > } > > @@ -329,7 +329,7 @@ static void > npcm7xx_fiu_uma_transaction(NPCM7xxFIUState *s) > /* Send command, if present. */ > uma_cfg = s->regs[NPCM7XX_FIU_UMA_CFG]; > if (FIU_UMA_CFG_CMDSIZ(uma_cfg) > 0) { > - ssi_transfer(s->spi, extract32(s->regs[NPCM7XX_FIU_UMA_CMD], > 0, 8)); > + ssi_transfer8(s->spi, extract32(s- > >regs[NPCM7XX_FIU_UMA_CMD], 0, 8)); > } > > /* Send address, if present. */ > @@ -342,7 +342,7 @@ static void > npcm7xx_fiu_uma_transaction(NPCM7xxFIUState *s) > (i < 16) ? (NPCM7XX_FIU_UMA_DW0 + i / 4) : > NPCM7XX_FIU_UMA_DW3; > unsigned int field = (i % 4) * 8; > > - ssi_transfer(s->spi, extract32(s->regs[reg], field, 8)); > + ssi_transfer8(s->spi, extract32(s->regs[reg], field, 8)); > } > > /* Send dummy bytes, if present */ > @@ -354,7 +354,7 @@ static void > npcm7xx_fiu_uma_transaction(NPCM7xxFIUState *s) > unsigned int field = (i % 4) * 8; > uint8_t c; > > - c = ssi_transfer(s->spi, 0); > + c = ssi_transfer8(s->spi, 0); > if (reg <= NPCM7XX_FIU_UMA_DR3) { > s->regs[reg] = deposit32(s->regs[reg], field, 8, c); > } > diff --git a/hw/ssi/npcm_pspi.c b/hw/ssi/npcm_pspi.c > index 2e05d5dacb..38ae6e0972 100644 > --- a/hw/ssi/npcm_pspi.c > +++ b/hw/ssi/npcm_pspi.c > @@ -77,9 +77,9 @@ static void npcm_pspi_write_data(NPCMPSPIState *s, > uint16_t data) > uint16_t value = 0; > > if (FIELD_EX16(s->regs[R_PSPI_CTL1], PSPI_CTL1, MOD)) { > - value = ssi_transfer(s->spi, extract16(data, 8, 8)) << 8; > + value = ssi_transfer8(s->spi, extract16(data, 8, 8)) << 8; > } > - value |= ssi_transfer(s->spi, extract16(data, 0, 8)); > + value |= ssi_transfer8(s->spi, extract16(data, 0, 8)); > s->regs[R_PSPI_DATA] = value; > > /* Mark data as available */ > diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c > index 715a2d21f4..eaac664ec5 100644 > --- a/hw/ssi/pl022.c > +++ b/hw/ssi/pl022.c > @@ -103,7 +103,7 @@ static void pl022_xfer(PL022State *s) > if (s->cr1 & PL022_CR1_LBM) { > /* Loopback mode. */ > } else { > - val = ssi_transfer(s->ssi, val); > + val = ssi_transfer8(s->ssi, val); > } > s->rx_fifo[o] = val & s->bitmask; > i = (i + 1) & 7; > diff --git a/hw/ssi/pnv_spi.c b/hw/ssi/pnv_spi.c > index f3add8cab9..e2a8a710da 100644 > --- a/hw/ssi/pnv_spi.c > +++ b/hw/ssi/pnv_spi.c > @@ -209,7 +209,7 @@ static void transfer(PnvSpi *s) > qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: TX_FIFO > underflow\n"); > } > } > - rx = ssi_transfer(s->ssi_bus, tx); > + rx = ssi_transfer8(s->ssi_bus, tx); > for (int i = 0; i < s->transfer_len; i++) { > if ((offset + i) >= payload_len) { > break; > diff --git a/hw/ssi/sifive_spi.c b/hw/ssi/sifive_spi.c > index 2ece78053b..1a2aac2daa 100644 > --- a/hw/ssi/sifive_spi.c > +++ b/hw/ssi/sifive_spi.c > @@ -134,7 +134,7 @@ static void > sifive_spi_flush_txfifo(SiFiveSPIState *s) > > while (!fifo8_is_empty(&s->tx_fifo)) { > tx = fifo8_pop(&s->tx_fifo); > - rx = ssi_transfer(s->spi, tx); > + rx = ssi_transfer8(s->spi, tx); > > if (!fifo8_is_full(&s->rx_fifo)) { > if (!(s->regs[R_FMT] & FMT_DIR)) { > diff --git a/hw/ssi/ssi.c b/hw/ssi/ssi.c > index 3a4fade2d5..ce2325bbd4 100644 > --- a/hw/ssi/ssi.c > +++ b/hw/ssi/ssi.c > @@ -153,11 +153,11 @@ SSIBus *ssi_create_bus(DeviceState *parent, > const char *name) > return SSI_BUS(bus); > } > > -uint32_t ssi_transfer(SSIBus *bus, uint32_t val) > +uint8_t ssi_transfer8(SSIBus *bus, uint8_t val) > { > BusState *b = BUS(bus); > BusChild *kid; > - uint32_t r = 0; > + uint8_t r = 0; > > QTAILQ_FOREACH(kid, &b->children, sibling) { > SSIPeripheral *p = SSI_PERIPHERAL(kid->child); > diff --git a/hw/ssi/stm32f2xx_spi.c b/hw/ssi/stm32f2xx_spi.c > index 871d57324d..eca0b93f3f 100644 > --- a/hw/ssi/stm32f2xx_spi.c > +++ b/hw/ssi/stm32f2xx_spi.c > @@ -59,7 +59,7 @@ static void > stm32f2xx_spi_transfer(STM32F2XXSPIState *s) > { > DB_PRINT("Data to send: 0x%x\n", s->spi_dr); > > - s->spi_dr = ssi_transfer(s->ssi, s->spi_dr); > + s->spi_dr = ssi_transfer8(s->ssi, s->spi_dr); > s->spi_sr |= STM_SPI_SR_RXNE; > > DB_PRINT("Data received: 0x%x\n", s->spi_dr); > diff --git a/hw/ssi/xilinx_spi.c b/hw/ssi/xilinx_spi.c > index 79f3e8bfae..45e9459396 100644 > --- a/hw/ssi/xilinx_spi.c > +++ b/hw/ssi/xilinx_spi.c > @@ -176,18 +176,18 @@ static inline int spi_master_enabled(XilinxSPI > *s) > > static void spi_flush_txfifo(XilinxSPI *s) > { > - uint32_t tx; > - uint32_t rx; > + uint8_t tx; > + uint8_t rx; > > while (!fifo8_is_empty(&s->tx_fifo)) { > - tx = (uint32_t)fifo8_pop(&s->tx_fifo); > + tx = fifo8_pop(&s->tx_fifo); > DB_PRINT("data tx:%x\n", tx); > - rx = ssi_transfer(s->spi, tx); > + rx = ssi_transfer8(s->spi, tx); > DB_PRINT("data rx:%x\n", rx); > if (fifo8_is_full(&s->rx_fifo)) { > s->regs[R_IPISR] |= IRQ_DRR_OVERRUN; > } else { > - fifo8_push(&s->rx_fifo, (uint8_t)rx); > + fifo8_push(&s->rx_fifo, rx); > if (fifo8_is_full(&s->rx_fifo)) { > s->regs[R_SPISR] |= SR_RX_FULL; > s->regs[R_IPISR] |= IRQ_DRR_FULL; > diff --git a/hw/ssi/xilinx_spips.c b/hw/ssi/xilinx_spips.c > index e4fce2c195..b915000770 100644 > --- a/hw/ssi/xilinx_spips.c > +++ b/hw/ssi/xilinx_spips.c > @@ -576,7 +576,7 @@ static void > xlnx_zynqmp_qspips_flush_fifo_g(XlnxZynqMPQSPIPS *s) > busses = ARRAY_FIELD_EX32(s->regs, GQSPI_GF_SNAPSHOT, > DATA_BUS_SELECT); > for (i = 0; i < 2; ++i) { > DB_PRINT_L(1, "bus %d tx = %02x\n", i, tx_rx[i]); > - tx_rx[i] = ssi_transfer(XILINX_SPIPS(s)->spi[i], > tx_rx[i]); > + tx_rx[i] = ssi_transfer8(XILINX_SPIPS(s)->spi[i], > tx_rx[i]); > DB_PRINT_L(1, "bus %d rx = %02x\n", i, tx_rx[i]); > } > if (s->regs[R_GQSPI_DATA_STS] > 1 && > @@ -696,7 +696,7 @@ static void xilinx_spips_flush_txfifo(XilinxSPIPS > *s) > int bus = num_effective_busses(s) - 1 - i; > > DB_PRINT_L(debug_level, "tx = %02x\n", tx_rx[i]); > - tx_rx[i] = ssi_transfer(s->spi[bus], > (uint32_t)tx_rx[i]); > + tx_rx[i] = ssi_transfer8(s->spi[bus], tx_rx[i]); > DB_PRINT_L(debug_level, "rx = %02x\n", tx_rx[i]); > } > > diff --git a/hw/ssi/xlnx-versal-ospi.c b/hw/ssi/xlnx-versal-ospi.c > index e25e4c26c2..8f2cb71414 100644 > --- a/hw/ssi/xlnx-versal-ospi.c > +++ b/hw/ssi/xlnx-versal-ospi.c > @@ -631,9 +631,9 @@ static void ospi_disable_cs(XlnxVersalOspi *s) > static void ospi_flush_txfifo(XlnxVersalOspi *s) > { > while (!fifo8_is_empty(&s->tx_fifo)) { > - uint32_t tx_rx = fifo8_pop(&s->tx_fifo); > + uint8_t tx_rx = fifo8_pop(&s->tx_fifo); > > - tx_rx = ssi_transfer(s->spi, tx_rx); > + tx_rx = ssi_transfer8(s->spi, tx_rx); > fifo8_push(&s->rx_fifo, tx_rx); > } > } > diff --git a/include/hw/ssi/ssi.h b/include/hw/ssi/ssi.h > index 6d6d8ccb3d..e8be6c2023 100644 > --- a/include/hw/ssi/ssi.h > +++ b/include/hw/ssi/ssi.h > @@ -38,7 +38,7 @@ struct SSIPeripheralClass { > > /* if you have standard or no CS behaviour, just override > transfer. > * This is called when the device cs is active (true by > default). > - * See ssi_transfer(). > + * See ssi_transfer8(). > */ > uint32_t (*transfer)(SSIPeripheral *dev, uint32_t val); > /* called when the CS line changes. Optional, devices only need > to implement > @@ -53,7 +53,7 @@ struct SSIPeripheralClass { > * of the CS behaviour at the device level. transfer, set_cs, > and > * cs_polarity are unused if this is overwritten. Transfer_raw > will > * always be called for the device for every txrx access to the > parent bus > - * See ssi_transfer(). > + * See ssi_transfer8(). > */ > uint32_t (*transfer_raw)(SSIPeripheral *dev, uint32_t val); > }; > @@ -113,18 +113,17 @@ bool ssi_realize_and_unref(DeviceState *dev, > SSIBus *bus, Error **errp); > SSIBus *ssi_create_bus(DeviceState *parent, const char *name); > > /** > - * Transfer a word on a SSI bus > + * Transfer a byte on a SSI bus > * @bus: SSI bus > - * @val: word to transmit > + * @val: byte to transmit > * > - * At the same time, read a word and write the @val one on the SSI > bus. > + * At the same time, read a byte and write the @val one on the SSI > bus. > * > - * SSI words might vary between 8 and 32 bits. The same number of > bits > - * written is received. > + * SSI always transfers and receives 8-bits. > * > - * Return: word value received > + * Return: byte received > */ > -uint32_t ssi_transfer(SSIBus *bus, uint32_t val); > +uint8_t ssi_transfer8(SSIBus *bus, uint8_t val); > > DeviceState *ssi_get_cs(SSIBus *bus, uint8_t cs_index); > ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 2/4] hw/ssi/pl022: Fix dropped upper bytes of ssi transfer 2026-08-25 4:04 [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 stephensportia 2026-08-25 4:04 ` [PATCH 1/4] hw/ssi: " stephensportia @ 2026-08-25 4:04 ` stephensportia 2026-08-27 5:27 ` Alistair 2026-08-25 4:04 ` [PATCH 3/4] hw/arm/strongarm: Fix dropped upper byte " stephensportia ` (3 subsequent siblings) 5 siblings, 1 reply; 26+ messages in thread From: stephensportia @ 2026-08-25 4:04 UTC (permalink / raw) To: qemu-devel Cc: Palmer Dabbelt, Peter Maydell, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Alistair Francis, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens From: Portia Stephens <portias@oss.tenstorrent.com> The pl022 model suports transferring a 8-bit or 16-bit frame width. The 16-bit transfer is broken since the upper 8-bits are being dropped by the SSI peripheral transfer function. Fix this by adding a second call to ssi_transfer8() when the frame wdith is 16-bits. Signed-off-by: Portia Stephens <portias@oss.tenstorrent.com> --- hw/ssi/pl022.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c index eaac664ec5..f4ade45ca9 100644 --- a/hw/ssi/pl022.c +++ b/hw/ssi/pl022.c @@ -74,7 +74,6 @@ static void pl022_xfer(PL022State *s) { int i; int o; - int val; if ((s->cr1 & PL022_CR1_SSE) == 0) { pl022_update(s); @@ -99,13 +98,18 @@ static void pl022_xfer(PL022State *s) the transfer has completed. */ while (s->tx_fifo_len && s->rx_fifo_len < 8) { DPRINTF("xfer\n"); - val = s->tx_fifo[i]; + uint16_t tx = s->tx_fifo[i]; + uint16_t rx = 0; if (s->cr1 & PL022_CR1_LBM) { /* Loopback mode. */ + rx = tx; } else { - val = ssi_transfer8(s->ssi, val); + if (s->bitmask > 0xff) { + rx |= (ssi_transfer8(s->ssi, (tx >> 8) & 0xff) << 8); + } + rx |= ssi_transfer8(s->ssi, tx & 0xff); } - s->rx_fifo[o] = val & s->bitmask; + s->rx_fifo[o] = rx & s->bitmask; i = (i + 1) & 7; o = (o + 1) & 7; s->tx_fifo_len--; -- 2.43.0 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH 2/4] hw/ssi/pl022: Fix dropped upper bytes of ssi transfer 2026-08-25 4:04 ` [PATCH 2/4] hw/ssi/pl022: Fix dropped upper bytes of ssi transfer stephensportia @ 2026-08-27 5:27 ` Alistair 0 siblings, 0 replies; 26+ messages in thread From: Alistair @ 2026-08-27 5:27 UTC (permalink / raw) To: stephensportia, qemu-devel Cc: Palmer Dabbelt, Peter Maydell, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Tue, 2026-08-25 at 14:04 +1000, stephensportia@gmail.com wrote: > From: Portia Stephens <portias@oss.tenstorrent.com> > > The pl022 model suports transferring a 8-bit or 16-bit frame width. > The > 16-bit transfer is broken since the upper 8-bits are being dropped by > the SSI peripheral transfer function. Fix this by adding a second > call > to ssi_transfer8() when the frame wdith is 16-bits. > > Signed-off-by: Portia Stephens <portias@oss.tenstorrent.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > hw/ssi/pl022.c | 12 ++++++++---- > 1 file changed, 8 insertions(+), 4 deletions(-) > > diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c > index eaac664ec5..f4ade45ca9 100644 > --- a/hw/ssi/pl022.c > +++ b/hw/ssi/pl022.c > @@ -74,7 +74,6 @@ static void pl022_xfer(PL022State *s) > { > int i; > int o; > - int val; > > if ((s->cr1 & PL022_CR1_SSE) == 0) { > pl022_update(s); > @@ -99,13 +98,18 @@ static void pl022_xfer(PL022State *s) > the transfer has completed. */ > while (s->tx_fifo_len && s->rx_fifo_len < 8) { > DPRINTF("xfer\n"); > - val = s->tx_fifo[i]; > + uint16_t tx = s->tx_fifo[i]; > + uint16_t rx = 0; > if (s->cr1 & PL022_CR1_LBM) { > /* Loopback mode. */ > + rx = tx; > } else { > - val = ssi_transfer8(s->ssi, val); > + if (s->bitmask > 0xff) { > + rx |= (ssi_transfer8(s->ssi, (tx >> 8) & 0xff) << > 8); > + } > + rx |= ssi_transfer8(s->ssi, tx & 0xff); > } > - s->rx_fifo[o] = val & s->bitmask; > + s->rx_fifo[o] = rx & s->bitmask; > i = (i + 1) & 7; > o = (o + 1) & 7; > s->tx_fifo_len--; ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 3/4] hw/arm/strongarm: Fix dropped upper byte of ssi transfer 2026-08-25 4:04 [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 stephensportia 2026-08-25 4:04 ` [PATCH 1/4] hw/ssi: " stephensportia 2026-08-25 4:04 ` [PATCH 2/4] hw/ssi/pl022: Fix dropped upper bytes of ssi transfer stephensportia @ 2026-08-25 4:04 ` stephensportia 2026-08-27 5:29 ` Alistair 2026-08-27 9:09 ` Peter Maydell 2026-08-25 4:04 ` [PATCH 4/4] hw/ssi/pnv_spi: Fix dropped upper bytes " stephensportia ` (2 subsequent siblings) 5 siblings, 2 replies; 26+ messages in thread From: stephensportia @ 2026-08-25 4:04 UTC (permalink / raw) To: qemu-devel Cc: Palmer Dabbelt, Peter Maydell, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Alistair Francis, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens From: Portia Stephens <portias@oss.tenstorrent.com> The strongarm model intends to transfer a 16-bit value over SSI. There is no machine using this model with a peripheral attached so it is impossible to know what the intended SSI peripheral is. There is no in-tree peripheral support for 16-bit transfer, update to use 8-bit transfer. Signed-off-by: Portia Stephens <portias@oss.tenstorrent.com> --- hw/arm/strongarm.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c index e400f0a185..2df895c75b 100644 --- a/hw/arm/strongarm.c +++ b/hw/arm/strongarm.c @@ -1512,11 +1512,14 @@ static void strongarm_ssp_write(void *opaque, hwaddr addr, * there directly to the slave, no need to buffer it. */ if (s->sscr[0] & SSCR0_SSE) { - uint32_t readval; + uint32_t readval = 0; if (s->sscr[1] & SSCR1_LBM) { readval = value; } else { - readval = ssi_transfer8(s->bus, value); + if (SSCR0_DSS(s->sscr[0]) > 8) { + readval |= ssi_transfer8(s->bus, (value >> 8) & 0xff) << 8; + } + readval |= ssi_transfer8(s->bus, value & 0xff); } if (s->rx_level < 0x08) { -- 2.43.0 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH 3/4] hw/arm/strongarm: Fix dropped upper byte of ssi transfer 2026-08-25 4:04 ` [PATCH 3/4] hw/arm/strongarm: Fix dropped upper byte " stephensportia @ 2026-08-27 5:29 ` Alistair 2026-08-27 9:09 ` Peter Maydell 1 sibling, 0 replies; 26+ messages in thread From: Alistair @ 2026-08-27 5:29 UTC (permalink / raw) To: stephensportia, qemu-devel Cc: Palmer Dabbelt, Peter Maydell, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Tue, 2026-08-25 at 14:04 +1000, stephensportia@gmail.com wrote: > From: Portia Stephens <portias@oss.tenstorrent.com> > > The strongarm model intends to transfer a 16-bit value over SSI. > There > is no machine using this model with a peripheral attached so it is > impossible to know what the intended SSI peripheral is. > There is no in-tree peripheral support for 16-bit transfer, update to > use 8-bit transfer. > > Signed-off-by: Portia Stephens <portias@oss.tenstorrent.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > hw/arm/strongarm.c | 7 +++++-- > 1 file changed, 5 insertions(+), 2 deletions(-) > > diff --git a/hw/arm/strongarm.c b/hw/arm/strongarm.c > index e400f0a185..2df895c75b 100644 > --- a/hw/arm/strongarm.c > +++ b/hw/arm/strongarm.c > @@ -1512,11 +1512,14 @@ static void strongarm_ssp_write(void *opaque, > hwaddr addr, > * there directly to the slave, no need to buffer it. > */ > if (s->sscr[0] & SSCR0_SSE) { > - uint32_t readval; > + uint32_t readval = 0; > if (s->sscr[1] & SSCR1_LBM) { > readval = value; > } else { > - readval = ssi_transfer8(s->bus, value); > + if (SSCR0_DSS(s->sscr[0]) > 8) { > + readval |= ssi_transfer8(s->bus, (value >> 8) & > 0xff) << 8; > + } > + readval |= ssi_transfer8(s->bus, value & 0xff); > } > > if (s->rx_level < 0x08) { ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 3/4] hw/arm/strongarm: Fix dropped upper byte of ssi transfer 2026-08-25 4:04 ` [PATCH 3/4] hw/arm/strongarm: Fix dropped upper byte " stephensportia 2026-08-27 5:29 ` Alistair @ 2026-08-27 9:09 ` Peter Maydell 2026-08-27 10:53 ` Portia Stephens 1 sibling, 1 reply; 26+ messages in thread From: Peter Maydell @ 2026-08-27 9:09 UTC (permalink / raw) To: stephensportia Cc: qemu-devel, Palmer Dabbelt, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Alistair Francis, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Tue, 25 Aug 2026 at 05:05, <stephensportia@gmail.com> wrote: > > From: Portia Stephens <portias@oss.tenstorrent.com> > > The strongarm model intends to transfer a 16-bit value over SSI. There > is no machine using this model with a peripheral attached so it is > impossible to know what the intended SSI peripheral is. > There is no in-tree peripheral support for 16-bit transfer, update to > use 8-bit transfer. This is the strongarm synchronous serial port; the manual says it "is used to interface to a variety of analog-to-digital converters, audio and telecom codecs, memory chips and keypad controllers as well as other miscellaneous serial devices". I don't know if it's actually connected to anything on real 'collie' hardware, but if it is then I don't think QEMU's ever emulated the connected hardware. The data is between 4 and 16 bits long. I think the intention both for this hardware and for QEMU's ssi_transfer() API is that the guest software is supposed to know what the device on the other end of the SSI connection is, and program the controller appropriately. If it programs the controller to transfer 16 bits to a device that only expects 8 then things will go wrong in both hardware and QEMU; conversely if it sends 8 bits to a device that needs 16 that will also break. -- PMM ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 3/4] hw/arm/strongarm: Fix dropped upper byte of ssi transfer 2026-08-27 9:09 ` Peter Maydell @ 2026-08-27 10:53 ` Portia Stephens 2026-08-27 11:04 ` Peter Maydell 0 siblings, 1 reply; 26+ messages in thread From: Portia Stephens @ 2026-08-27 10:53 UTC (permalink / raw) To: Peter Maydell Cc: qemu-devel, Palmer Dabbelt, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Alistair Francis, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Thu, Aug 27, 2026 at 7:09 PM Peter Maydell <peter.maydell@linaro.org> wrote: > > On Tue, 25 Aug 2026 at 05:05, <stephensportia@gmail.com> wrote: > > > > From: Portia Stephens <portias@oss.tenstorrent.com> > > > > The strongarm model intends to transfer a 16-bit value over SSI. There > > is no machine using this model with a peripheral attached so it is > > impossible to know what the intended SSI peripheral is. > > There is no in-tree peripheral support for 16-bit transfer, update to > > use 8-bit transfer. > > This is the strongarm synchronous serial port; the manual says it > "is used to interface to a variety of analog-to-digital converters, > audio and telecom codecs, memory chips and keypad controllers > as well as other miscellaneous serial devices". I don't know > if it's actually connected to anything on real 'collie' hardware, > but if it is then I don't think QEMU's ever emulated the connected > hardware. > > The data is between 4 and 16 bits long. I think the intention In this case, how can the device transfer function know what the expected transfer width is? From my reading of the current implementation, there is no way for the device's transfer function to know what the transfer width the controller or guest software expects, only a value is passed, or am I missing something? > both for this hardware and for QEMU's ssi_transfer() API > is that the guest software is supposed to know what the device > on the other end of the SSI connection is, and program the > controller appropriately. If it programs the controller to > transfer 16 bits to a device that only expects 8 then things > will go wrong in both hardware and QEMU; conversely if it > sends 8 bits to a device that needs 16 that will also break. > > -- PMM ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 3/4] hw/arm/strongarm: Fix dropped upper byte of ssi transfer 2026-08-27 10:53 ` Portia Stephens @ 2026-08-27 11:04 ` Peter Maydell 0 siblings, 0 replies; 26+ messages in thread From: Peter Maydell @ 2026-08-27 11:04 UTC (permalink / raw) To: Portia Stephens Cc: qemu-devel, Palmer Dabbelt, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Alistair Francis, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Thu, 27 Aug 2026 at 11:53, Portia Stephens <stephensportia@gmail.com> wrote: > > On Thu, Aug 27, 2026 at 7:09 PM Peter Maydell <peter.maydell@linaro.org> wrote: > > > > On Tue, 25 Aug 2026 at 05:05, <stephensportia@gmail.com> wrote: > > > > > > From: Portia Stephens <portias@oss.tenstorrent.com> > > > > > > The strongarm model intends to transfer a 16-bit value over SSI. There > > > is no machine using this model with a peripheral attached so it is > > > impossible to know what the intended SSI peripheral is. > > > There is no in-tree peripheral support for 16-bit transfer, update to > > > use 8-bit transfer. > > > > This is the strongarm synchronous serial port; the manual says it > > "is used to interface to a variety of analog-to-digital converters, > > audio and telecom codecs, memory chips and keypad controllers > > as well as other miscellaneous serial devices". I don't know > > if it's actually connected to anything on real 'collie' hardware, > > but if it is then I don't think QEMU's ever emulated the connected > > hardware. > > > > The data is between 4 and 16 bits long. I think the intention > > In this case, how can the device transfer function know what the > expected transfer width is? From my reading of the current > implementation, there is no way for the device's transfer function to > know what the transfer width the controller or guest software expects, > only a value is passed, or am I missing something? The device is just implemented as "I am a device which has a fixed transfer width of X". The software running in the guest knows "the device on the other end of this PL022 is specific device A which has a transfer width of X", and it programs the PL022 with that width X. thanks -- PMM ^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 4/4] hw/ssi/pnv_spi: Fix dropped upper bytes of ssi transfer 2026-08-25 4:04 [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 stephensportia ` (2 preceding siblings ...) 2026-08-25 4:04 ` [PATCH 3/4] hw/arm/strongarm: Fix dropped upper byte " stephensportia @ 2026-08-25 4:04 ` stephensportia 2026-08-27 5:31 ` Alistair 2026-08-27 5:37 ` [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 Alistair 2026-08-27 9:19 ` Peter Maydell 5 siblings, 1 reply; 26+ messages in thread From: stephensportia @ 2026-08-25 4:04 UTC (permalink / raw) To: qemu-devel Cc: Palmer Dabbelt, Peter Maydell, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Alistair Francis, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens From: Portia Stephens <portias@oss.tenstorrent.com> The pnv_spi model supports transaction sizes of 4 bytes however there are no in-tree SSI peripherals that support this. Update the model to use a 8-bit transfer function. Signed-off-by: Portia Stephens <portias@oss.tenstorrent.com> --- hw/ssi/pnv_spi.c | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/hw/ssi/pnv_spi.c b/hw/ssi/pnv_spi.c index e2a8a710da..481798b1fa 100644 --- a/hw/ssi/pnv_spi.c +++ b/hw/ssi/pnv_spi.c @@ -194,32 +194,26 @@ static void spi_response(PnvSpi *s) static void transfer(PnvSpi *s) { - uint32_t tx, rx, payload_len; + uint32_t payload_len; uint8_t rx_byte; payload_len = fifo8_num_used(&s->tx_fifo); for (int offset = 0; offset < payload_len; offset += s->transfer_len) { - tx = 0; - for (int i = 0; i < s->transfer_len; i++) { - if ((offset + i) >= payload_len) { - tx <<= 8; - } else if (!fifo8_is_empty(&s->tx_fifo)) { - tx = (tx << 8) | fifo8_pop(&s->tx_fifo); - } else { - qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: TX_FIFO underflow\n"); - } - } - rx = ssi_transfer8(s->ssi_bus, tx); for (int i = 0; i < s->transfer_len; i++) { if ((offset + i) >= payload_len) { break; } - rx_byte = (rx >> (8 * (s->transfer_len - 1) - i * 8)) & 0xFF; - if (!fifo8_is_full(&s->rx_fifo)) { - fifo8_push(&s->rx_fifo, rx_byte); + + if (!fifo8_is_empty(&s->tx_fifo)) { + rx_byte = ssi_transfer8(s->ssi_bus, fifo8_pop(&s->tx_fifo)); + if (!fifo8_is_full(&s->rx_fifo)) { + fifo8_push(&s->rx_fifo, rx_byte); + } else { + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: RX_FIFO is full\n"); + break; + } } else { - qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: RX_FIFO is full\n"); - break; + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: TX_FIFO underflow\n"); } } } -- 2.43.0 ^ permalink raw reply related [flat|nested] 26+ messages in thread
* Re: [PATCH 4/4] hw/ssi/pnv_spi: Fix dropped upper bytes of ssi transfer 2026-08-25 4:04 ` [PATCH 4/4] hw/ssi/pnv_spi: Fix dropped upper bytes " stephensportia @ 2026-08-27 5:31 ` Alistair 0 siblings, 0 replies; 26+ messages in thread From: Alistair @ 2026-08-27 5:31 UTC (permalink / raw) To: stephensportia, qemu-devel Cc: Palmer Dabbelt, Peter Maydell, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Tue, 2026-08-25 at 14:04 +1000, stephensportia@gmail.com wrote: > From: Portia Stephens <portias@oss.tenstorrent.com> > > The pnv_spi model supports transaction sizes of 4 bytes however there > are no in-tree SSI peripherals that support this. Update the model to > use a 8-bit transfer function. > > Signed-off-by: Portia Stephens <portias@oss.tenstorrent.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Alistair > --- > hw/ssi/pnv_spi.c | 28 +++++++++++----------------- > 1 file changed, 11 insertions(+), 17 deletions(-) > > diff --git a/hw/ssi/pnv_spi.c b/hw/ssi/pnv_spi.c > index e2a8a710da..481798b1fa 100644 > --- a/hw/ssi/pnv_spi.c > +++ b/hw/ssi/pnv_spi.c > @@ -194,32 +194,26 @@ static void spi_response(PnvSpi *s) > > static void transfer(PnvSpi *s) > { > - uint32_t tx, rx, payload_len; > + uint32_t payload_len; > uint8_t rx_byte; > > payload_len = fifo8_num_used(&s->tx_fifo); > for (int offset = 0; offset < payload_len; offset += s- > >transfer_len) { > - tx = 0; > - for (int i = 0; i < s->transfer_len; i++) { > - if ((offset + i) >= payload_len) { > - tx <<= 8; > - } else if (!fifo8_is_empty(&s->tx_fifo)) { > - tx = (tx << 8) | fifo8_pop(&s->tx_fifo); > - } else { > - qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: TX_FIFO > underflow\n"); > - } > - } > - rx = ssi_transfer8(s->ssi_bus, tx); > for (int i = 0; i < s->transfer_len; i++) { > if ((offset + i) >= payload_len) { > break; > } > - rx_byte = (rx >> (8 * (s->transfer_len - 1) - i * 8)) & > 0xFF; > - if (!fifo8_is_full(&s->rx_fifo)) { > - fifo8_push(&s->rx_fifo, rx_byte); > + > + if (!fifo8_is_empty(&s->tx_fifo)) { > + rx_byte = ssi_transfer8(s->ssi_bus, fifo8_pop(&s- > >tx_fifo)); > + if (!fifo8_is_full(&s->rx_fifo)) { > + fifo8_push(&s->rx_fifo, rx_byte); > + } else { > + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: RX_FIFO > is full\n"); > + break; > + } > } else { > - qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: RX_FIFO is > full\n"); > - break; > + qemu_log_mask(LOG_GUEST_ERROR, "pnv_spi: TX_FIFO > underflow\n"); > } > } > } ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 2026-08-25 4:04 [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 stephensportia ` (3 preceding siblings ...) 2026-08-25 4:04 ` [PATCH 4/4] hw/ssi/pnv_spi: Fix dropped upper bytes " stephensportia @ 2026-08-27 5:37 ` Alistair 2026-08-27 9:20 ` Peter Maydell 2026-08-27 10:31 ` Philippe Mathieu-Daudé 2026-08-27 9:19 ` Peter Maydell 5 siblings, 2 replies; 26+ messages in thread From: Alistair @ 2026-08-27 5:37 UTC (permalink / raw) To: stephensportia, qemu-devel Cc: Palmer Dabbelt, Peter Maydell, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Tue, 2026-08-25 at 14:04 +1000, stephensportia@gmail.com wrote: > From: Portia Stephens <portias@oss.tenstorrent.com> > > The ssi_transfer function comments say that it takes a word varying > between 8-bits and 32-bits. ssi_transfer takes a 32-bit arg to > transfer > but there is no means to indicate the number of bits that should > actually be transferred. All child classes of SSI_PERIPHERAL class > have > transfer functions that, despite accepting a 32-bit tx, only transfer > a > single byte; m25p80_transfer8(), ssi_sd_transfer(), > ssd0323_transfer(). > > The current implementation depends on the SSI model to know > what peripheral model will be attached and what transfer size it > expects which is error prone. If a SSI_PERIPHERAL model was written > that > accepted 32-bit transfers, it could not attach to any existing SSI > models. > > This change updates the the naming of ssi_transfer to ssi_transfer8, > as > well as changes the return value and transmit argument to be 8-bit. > > Most ssi models handle this correctly already, sending a single byte > at > a time. There are a few models that are written to support non 8-bit > transfers but there are no in-tree use cases that connect a > peripheral > to the SSI device. These have been updated to use 8-bit transfers. > > Portia Stephens (4): > hw/ssi: Rename ssi_transfer to ssi_transfer8 > hw/ssi/pl022: Fix dropped upper bytes of ssi transfer > hw/arm/strongarm: Fix dropped upper byte of ssi transfer > hw/ssi/pnv_spi: Fix dropped upper bytes of ssi transfer Thanks! Applied to riscv-to-apply.next Alistair > > hw/arm/strongarm.c | 7 +++++-- > hw/ssi/allwinner-a10-spi.c | 2 +- > hw/ssi/aspeed_smc.c | 14 ++++++------- > hw/ssi/bcm2835_spi.c | 2 +- > hw/ssi/ibex_spi_host.c | 5 +++-- > hw/ssi/imx_spi.c | 2 +- > hw/ssi/mss-spi.c | 2 +- > hw/ssi/npcm7xx_fiu.c | 42 +++++++++++++++++++----------------- > -- > hw/ssi/npcm_pspi.c | 4 ++-- > hw/ssi/pl022.c | 12 +++++++---- > hw/ssi/pnv_spi.c | 28 ++++++++++--------------- > hw/ssi/sifive_spi.c | 2 +- > hw/ssi/ssi.c | 4 ++-- > hw/ssi/stm32f2xx_spi.c | 2 +- > hw/ssi/xilinx_spi.c | 10 ++++----- > hw/ssi/xilinx_spips.c | 4 ++-- > hw/ssi/xlnx-versal-ospi.c | 4 ++-- > include/hw/ssi/ssi.h | 17 ++++++++------- > 18 files changed, 82 insertions(+), 81 deletions(-) ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 2026-08-27 5:37 ` [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 Alistair @ 2026-08-27 9:20 ` Peter Maydell 2026-08-27 11:06 ` Alistair 2026-08-27 10:31 ` Philippe Mathieu-Daudé 1 sibling, 1 reply; 26+ messages in thread From: Peter Maydell @ 2026-08-27 9:20 UTC (permalink / raw) To: Alistair Cc: stephensportia, qemu-devel, Palmer Dabbelt, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Thu, 27 Aug 2026 at 06:37, Alistair <alistair@alistair23.me> wrote: > > On Tue, 2026-08-25 at 14:04 +1000, stephensportia@gmail.com wrote: > > From: Portia Stephens <portias@oss.tenstorrent.com> > > > > The ssi_transfer function comments say that it takes a word varying > > between 8-bits and 32-bits. ssi_transfer takes a 32-bit arg to > > transfer > > but there is no means to indicate the number of bits that should > > actually be transferred. All child classes of SSI_PERIPHERAL class > > have > > transfer functions that, despite accepting a 32-bit tx, only transfer > > a > > single byte; m25p80_transfer8(), ssi_sd_transfer(), > > ssd0323_transfer(). > > > > The current implementation depends on the SSI model to know > > what peripheral model will be attached and what transfer size it > > expects which is error prone. If a SSI_PERIPHERAL model was written > > that > > accepted 32-bit transfers, it could not attach to any existing SSI > > models. > > > > This change updates the the naming of ssi_transfer to ssi_transfer8, > > as > > well as changes the return value and transmit argument to be 8-bit. > > > > Most ssi models handle this correctly already, sending a single byte > > at > > a time. There are a few models that are written to support non 8-bit > > transfers but there are no in-tree use cases that connect a > > peripheral > > to the SSI device. These have been updated to use 8-bit transfers. > > > > Portia Stephens (4): > > hw/ssi: Rename ssi_transfer to ssi_transfer8 > > hw/ssi/pl022: Fix dropped upper bytes of ssi transfer > > hw/arm/strongarm: Fix dropped upper byte of ssi transfer > > hw/ssi/pnv_spi: Fix dropped upper bytes of ssi transfer > > Thanks! > > Applied to riscv-to-apply.next Would you mind holding off on that until we figure out whether this is a correct change and why we need it, please? thanks -- PMM ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 2026-08-27 9:20 ` Peter Maydell @ 2026-08-27 11:06 ` Alistair 0 siblings, 0 replies; 26+ messages in thread From: Alistair @ 2026-08-27 11:06 UTC (permalink / raw) To: Peter Maydell Cc: stephensportia, qemu-devel, Palmer Dabbelt, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Thu, 2026-08-27 at 10:20 +0100, Peter Maydell wrote: > On Thu, 27 Aug 2026 at 06:37, Alistair <alistair@alistair23.me> > wrote: > > > > On Tue, 2026-08-25 at 14:04 +1000, stephensportia@gmail.com wrote: > > > From: Portia Stephens <portias@oss.tenstorrent.com> > > > > > > The ssi_transfer function comments say that it takes a word > > > varying > > > between 8-bits and 32-bits. ssi_transfer takes a 32-bit arg to > > > transfer > > > but there is no means to indicate the number of bits that should > > > actually be transferred. All child classes of SSI_PERIPHERAL > > > class > > > have > > > transfer functions that, despite accepting a 32-bit tx, only > > > transfer > > > a > > > single byte; m25p80_transfer8(), ssi_sd_transfer(), > > > ssd0323_transfer(). > > > > > > The current implementation depends on the SSI model to know > > > what peripheral model will be attached and what transfer size it > > > expects which is error prone. If a SSI_PERIPHERAL model was > > > written > > > that > > > accepted 32-bit transfers, it could not attach to any existing > > > SSI > > > models. > > > > > > This change updates the the naming of ssi_transfer to > > > ssi_transfer8, > > > as > > > well as changes the return value and transmit argument to be 8- > > > bit. > > > > > > Most ssi models handle this correctly already, sending a single > > > byte > > > at > > > a time. There are a few models that are written to support non 8- > > > bit > > > transfers but there are no in-tree use cases that connect a > > > peripheral > > > to the SSI device. These have been updated to use 8-bit > > > transfers. > > > > > > Portia Stephens (4): > > > hw/ssi: Rename ssi_transfer to ssi_transfer8 > > > hw/ssi/pl022: Fix dropped upper bytes of ssi transfer > > > hw/arm/strongarm: Fix dropped upper byte of ssi transfer > > > hw/ssi/pnv_spi: Fix dropped upper bytes of ssi transfer > > > > Thanks! > > > > Applied to riscv-to-apply.next > > Would you mind holding off on that until we figure out whether > this is a correct change and why we need it, please? Sure. Sorry I thought no one else was interested in reading it. Will drop it until discussions are sorted Alistair > > thanks > -- PMM ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 2026-08-27 5:37 ` [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 Alistair 2026-08-27 9:20 ` Peter Maydell @ 2026-08-27 10:31 ` Philippe Mathieu-Daudé 1 sibling, 0 replies; 26+ messages in thread From: Philippe Mathieu-Daudé @ 2026-08-27 10:31 UTC (permalink / raw) To: Alistair, stephensportia, qemu-devel, Bin Meng Cc: Palmer Dabbelt, Peter Maydell, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens Hi Alistair, On 27/8/26 07:37, Alistair wrote: > On Tue, 2026-08-25 at 14:04 +1000, stephensportia@gmail.com wrote: >> From: Portia Stephens <portias@oss.tenstorrent.com> >> >> The ssi_transfer function comments say that it takes a word varying >> between 8-bits and 32-bits. ssi_transfer takes a 32-bit arg to >> transfer >> but there is no means to indicate the number of bits that should >> actually be transferred. All child classes of SSI_PERIPHERAL class >> have >> transfer functions that, despite accepting a 32-bit tx, only transfer >> a >> single byte; m25p80_transfer8(), ssi_sd_transfer(), >> ssd0323_transfer(). >> >> The current implementation depends on the SSI model to know >> what peripheral model will be attached and what transfer size it >> expects which is error prone. If a SSI_PERIPHERAL model was written >> that >> accepted 32-bit transfers, it could not attach to any existing SSI >> models. >> >> This change updates the the naming of ssi_transfer to ssi_transfer8, >> as >> well as changes the return value and transmit argument to be 8-bit. >> >> Most ssi models handle this correctly already, sending a single byte >> at >> a time. There are a few models that are written to support non 8-bit >> transfers but there are no in-tree use cases that connect a >> peripheral >> to the SSI device. These have been updated to use 8-bit transfers. >> >> Portia Stephens (4): >> hw/ssi: Rename ssi_transfer to ssi_transfer8 >> hw/ssi/pl022: Fix dropped upper bytes of ssi transfer >> hw/arm/strongarm: Fix dropped upper byte of ssi transfer >> hw/ssi/pnv_spi: Fix dropped upper bytes of ssi transfer > > Thanks! > > Applied to riscv-to-apply.next Can you hold on before merging this please (or drop it from your riscv queue)? I tagged this series to review but didn't got a sufficient large enough slot to look at it. In short, the reason I think this isn't the correct way to go is SPI "words" can be any number of bits. While QEMU only models 8-bit word devices, I have be working with 16-bit and even 24-bit words ones, so I believe the current implementation is right. I have be thinking of a better way to model this granularity in our class hooks, but haven't find a good one yet. Restricting some devices to 8-bit to simplify them move part of the complexity to the host controller so I'm not sure it is useful. I'll return with clearer comments when I get more time. Thanks, Phil. ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 2026-08-25 4:04 [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 stephensportia ` (4 preceding siblings ...) 2026-08-27 5:37 ` [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 Alistair @ 2026-08-27 9:19 ` Peter Maydell 2026-08-27 10:35 ` Philippe Mathieu-Daudé 2026-08-27 10:37 ` Portia Stephens 5 siblings, 2 replies; 26+ messages in thread From: Peter Maydell @ 2026-08-27 9:19 UTC (permalink / raw) To: stephensportia Cc: qemu-devel, Palmer Dabbelt, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Alistair Francis, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Tue, 25 Aug 2026 at 05:05, <stephensportia@gmail.com> wrote: > > From: Portia Stephens <portias@oss.tenstorrent.com> > > The ssi_transfer function comments say that it takes a word varying > between 8-bits and 32-bits. ssi_transfer takes a 32-bit arg to transfer > but there is no means to indicate the number of bits that should > actually be transferred. All child classes of SSI_PERIPHERAL class have > transfer functions that, despite accepting a 32-bit tx, only transfer a > single byte; m25p80_transfer8(), ssi_sd_transfer(), ssd0323_transfer(). > > The current implementation depends on the SSI model to know > what peripheral model will be attached and what transfer size it > expects which is error prone. If a SSI_PERIPHERAL model was written that > accepted 32-bit transfers, it could not attach to any existing SSI > models. What is the motivation for this change? As far as I know for the hardware SSI protocol, it is indeed the case that the SSI controller (and/or the guest software) needs to know what transfer size the attached device expects: the controller just transmits (or expects to receive) however many bits it is programmed for. > This change updates the the naming of ssi_transfer to ssi_transfer8, as > well as changes the return value and transmit argument to be 8-bit. This means that the API will no longer work for a controller and device that aren't 8-bit. We happen not to have any of those devices today, but why specifically stop them working? thanks -- PMM ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 2026-08-27 9:19 ` Peter Maydell @ 2026-08-27 10:35 ` Philippe Mathieu-Daudé 2026-08-27 10:37 ` Portia Stephens 1 sibling, 0 replies; 26+ messages in thread From: Philippe Mathieu-Daudé @ 2026-08-27 10:35 UTC (permalink / raw) To: Peter Maydell, stephensportia Cc: qemu-devel, Palmer Dabbelt, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Alistair Francis, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On 27/8/26 11:19, Peter Maydell wrote: > On Tue, 25 Aug 2026 at 05:05, <stephensportia@gmail.com> wrote: >> >> From: Portia Stephens <portias@oss.tenstorrent.com> >> >> The ssi_transfer function comments say that it takes a word varying >> between 8-bits and 32-bits. ssi_transfer takes a 32-bit arg to transfer >> but there is no means to indicate the number of bits that should >> actually be transferred. All child classes of SSI_PERIPHERAL class have >> transfer functions that, despite accepting a 32-bit tx, only transfer a >> single byte; m25p80_transfer8(), ssi_sd_transfer(), ssd0323_transfer(). >> >> The current implementation depends on the SSI model to know >> what peripheral model will be attached and what transfer size it >> expects which is error prone. If a SSI_PERIPHERAL model was written that >> accepted 32-bit transfers, it could not attach to any existing SSI >> models. > > What is the motivation for this change? > > As far as I know for the hardware SSI protocol, it is indeed > the case that the SSI controller (and/or the guest software) needs > to know what transfer size the attached device expects: the > controller just transmits (or expects to receive) however many > bits it is programmed for. > >> This change updates the the naming of ssi_transfer to ssi_transfer8, as >> well as changes the return value and transmit argument to be 8-bit. > > This means that the API will no longer work for a controller > and device that aren't 8-bit. Yes exactly. Clearer than the mail I just wrote, thanks hehe. > We happen not to have any of those > devices today, but why specifically stop them working? I guess remembering having see forks with 16-bit devices, but that was few years ago (I know forks don't have they voice here, but just to mention the current API is working for them). ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 2026-08-27 9:19 ` Peter Maydell 2026-08-27 10:35 ` Philippe Mathieu-Daudé @ 2026-08-27 10:37 ` Portia Stephens 2026-08-27 10:53 ` Peter Maydell 1 sibling, 1 reply; 26+ messages in thread From: Portia Stephens @ 2026-08-27 10:37 UTC (permalink / raw) To: Peter Maydell Cc: qemu-devel, Palmer Dabbelt, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Alistair Francis, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Thu, Aug 27, 2026 at 7:19 PM Peter Maydell <peter.maydell@linaro.org> wrote: > > On Tue, 25 Aug 2026 at 05:05, <stephensportia@gmail.com> wrote: > > > > From: Portia Stephens <portias@oss.tenstorrent.com> > > > > The ssi_transfer function comments say that it takes a word varying > > between 8-bits and 32-bits. ssi_transfer takes a 32-bit arg to transfer > > but there is no means to indicate the number of bits that should > > actually be transferred. All child classes of SSI_PERIPHERAL class have > > transfer functions that, despite accepting a 32-bit tx, only transfer a > > single byte; m25p80_transfer8(), ssi_sd_transfer(), ssd0323_transfer(). > > > > The current implementation depends on the SSI model to know > > what peripheral model will be attached and what transfer size it > > expects which is error prone. If a SSI_PERIPHERAL model was written that > > accepted 32-bit transfers, it could not attach to any existing SSI > > models. > > What is the motivation for this change? The motivation came from reviewing the designware ssi driver [1] and realizing how error prone it was. The designware ssi supports varying frame width but there is no way for the controller logic to know what the transfer size an attached device expects. It seems like all the code, that is actually connected to devices, is just written to expect 8-bit transfers so it should be made explicit. https://www.mail-archive.com/qemu-devel@nongnu.org/msg1218153.html > > As far as I know for the hardware SSI protocol, it is indeed > the case that the SSI controller (and/or the guest software) needs > to know what transfer size the attached device expects: the > controller just transmits (or expects to receive) however many > bits it is programmed for. This is true but do the devices currently model only support 8-bit transfers in hardware, do they not support multiframe transfer? SPI supports varying framewidth but the devices are not actually modeled in this way. A better solution may be to have multiple transfer functions, ssi_transfer8, ssi_transfer32, etc. This would require the device to explicitly set what it is expecting. It is challenging since the only model's not using 8-bit transfer don't have any devices connected upstream so testing is challenging. > > > This change updates the the naming of ssi_transfer to ssi_transfer8, as > > well as changes the return value and transmit argument to be 8-bit. > > This means that the API will no longer work for a controller > and device that aren't 8-bit. We happen not to have any of those > devices today, but why specifically stop them working? > > thanks > -- PMM ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 2026-08-27 10:37 ` Portia Stephens @ 2026-08-27 10:53 ` Peter Maydell 2026-08-27 11:03 ` Alistair 2026-08-27 12:52 ` Portia Stephens 0 siblings, 2 replies; 26+ messages in thread From: Peter Maydell @ 2026-08-27 10:53 UTC (permalink / raw) To: Portia Stephens Cc: qemu-devel, Palmer Dabbelt, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Alistair Francis, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Thu, 27 Aug 2026 at 11:37, Portia Stephens <stephensportia@gmail.com> wrote: > > On Thu, Aug 27, 2026 at 7:19 PM Peter Maydell <peter.maydell@linaro.org> wrote: > > > > On Tue, 25 Aug 2026 at 05:05, <stephensportia@gmail.com> wrote: > > > > > > From: Portia Stephens <portias@oss.tenstorrent.com> > > > > > > The ssi_transfer function comments say that it takes a word varying > > > between 8-bits and 32-bits. ssi_transfer takes a 32-bit arg to transfer > > > but there is no means to indicate the number of bits that should > > > actually be transferred. All child classes of SSI_PERIPHERAL class have > > > transfer functions that, despite accepting a 32-bit tx, only transfer a > > > single byte; m25p80_transfer8(), ssi_sd_transfer(), ssd0323_transfer(). > > > > > > The current implementation depends on the SSI model to know > > > what peripheral model will be attached and what transfer size it > > > expects which is error prone. If a SSI_PERIPHERAL model was written that > > > accepted 32-bit transfers, it could not attach to any existing SSI > > > models. > > > > What is the motivation for this change? > > The motivation came from reviewing the designware ssi driver [1] and > realizing how error prone it was. The designware ssi supports varying > frame width but there is no way for the controller logic to know what > the transfer size an attached device expects. But isn't this just the way the SSI specification is? If we're modelling a "you just have to get this right in software" bit of hardware then we don't need to somehow try to add extra checks in QEMU for whether the software hasn't actually done things right. > It seems like all the > code, that is actually connected to devices, is just written to expect > 8-bit transfers so it should be made explicit. > > https://www.mail-archive.com/qemu-devel@nongnu.org/msg1218153.html > > > > > As far as I know for the hardware SSI protocol, it is indeed > > the case that the SSI controller (and/or the guest software) needs > > to know what transfer size the attached device expects: the > > controller just transmits (or expects to receive) however many > > bits it is programmed for. > > This is true but do the devices currently model only support 8-bit > transfers in hardware, do they not support multiframe transfer? SPI > supports varying framewidth but the devices are not actually modeled > in this way. Do the actual devices we implement support varying framewidth, or do they actually have exactly one frame width that the controller needs to be programmed by the guest to use ? > A better solution may be to have multiple transfer functions, > ssi_transfer8, ssi_transfer32, etc. This would require the device to > explicitly set what it is expecting. It is challenging since the only > model's not using 8-bit transfer don't have any devices connected > upstream so testing is challenging. This doesn't allow for bit widths that aren't a multiple of 8. thanks -- PMM ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 2026-08-27 10:53 ` Peter Maydell @ 2026-08-27 11:03 ` Alistair 2026-08-27 11:17 ` Peter Maydell 2026-08-27 12:52 ` Portia Stephens 1 sibling, 1 reply; 26+ messages in thread From: Alistair @ 2026-08-27 11:03 UTC (permalink / raw) To: Peter Maydell, Portia Stephens Cc: qemu-devel, Palmer Dabbelt, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Thu, 2026-08-27 at 11:53 +0100, Peter Maydell wrote: > On Thu, 27 Aug 2026 at 11:37, Portia Stephens > <stephensportia@gmail.com> wrote: > > > > On Thu, Aug 27, 2026 at 7:19 PM Peter Maydell > > <peter.maydell@linaro.org> wrote: > > > > > > On Tue, 25 Aug 2026 at 05:05, <stephensportia@gmail.com> wrote: > > > > > > > > From: Portia Stephens <portias@oss.tenstorrent.com> > > > > > > > > The ssi_transfer function comments say that it takes a word > > > > varying > > > > between 8-bits and 32-bits. ssi_transfer takes a 32-bit arg to > > > > transfer > > > > but there is no means to indicate the number of bits that > > > > should > > > > actually be transferred. All child classes of SSI_PERIPHERAL > > > > class have > > > > transfer functions that, despite accepting a 32-bit tx, only > > > > transfer a > > > > single byte; m25p80_transfer8(), ssi_sd_transfer(), > > > > ssd0323_transfer(). > > > > > > > > The current implementation depends on the SSI model to know > > > > what peripheral model will be attached and what transfer size > > > > it > > > > expects which is error prone. If a SSI_PERIPHERAL model was > > > > written that > > > > accepted 32-bit transfers, it could not attach to any existing > > > > SSI > > > > models. > > > > > > What is the motivation for this change? > > > > The motivation came from reviewing the designware ssi driver [1] > > and > > realizing how error prone it was. The designware ssi supports > > varying > > frame width but there is no way for the controller logic to know > > what > > the transfer size an attached device expects. > > But isn't this just the way the SSI specification is? If we're > modelling a "you just have to get this right in software" bit > of hardware then we don't need to somehow try to add extra > checks in QEMU for whether the software hasn't actually done > things right. From my reading of things this is a bug in QEMU, not a guest issue. The fact that aspeed_smc_flash_setup() for example iterates over a larger value to send a single byte at a time shows that currently everyone *thinks* think function should send a single byte. So it does seem broken today. Making the current function clear seems like a good step. Supporting different or larger transfers in the future is then possible. > > > It seems like all the > > code, that is actually connected to devices, is just written to > > expect > > 8-bit transfers so it should be made explicit. > > > > https://www.mail-archive.com/qemu-devel@nongnu.org/msg1218153.html > > > > > > > > As far as I know for the hardware SSI protocol, it is indeed > > > the case that the SSI controller (and/or the guest software) > > > needs > > > to know what transfer size the attached device expects: the > > > controller just transmits (or expects to receive) however many > > > bits it is programmed for. > > > > This is true but do the devices currently model only support 8-bit > > transfers in hardware, do they not support multiframe transfer? SPI > > supports varying framewidth but the devices are not actually > > modeled > > in this way. > > Do the actual devices we implement support varying framewidth, > or do they actually have exactly one frame width that the controller > needs to be programmed by the guest to use ? > > > A better solution may be to have multiple transfer functions, > > ssi_transfer8, ssi_transfer32, etc. This would require the device > > to > > explicitly set what it is expecting. It is challenging since the > > only > > model's not using 8-bit transfer don't have any devices connected > > upstream so testing is challenging. > > This doesn't allow for bit widths that aren't a multiple of 8. Wouldn't a ssi_transfer32() just be the same as today? Alistair > > thanks > -- PMM ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 2026-08-27 11:03 ` Alistair @ 2026-08-27 11:17 ` Peter Maydell 2026-08-28 0:07 ` Alistair 0 siblings, 1 reply; 26+ messages in thread From: Peter Maydell @ 2026-08-27 11:17 UTC (permalink / raw) To: Alistair Cc: Portia Stephens, qemu-devel, Palmer Dabbelt, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Thu, 27 Aug 2026 at 12:03, Alistair <alistair@alistair23.me> wrote: > > On Thu, 2026-08-27 at 11:53 +0100, Peter Maydell wrote: > > But isn't this just the way the SSI specification is? If we're > > modelling a "you just have to get this right in software" bit > > of hardware then we don't need to somehow try to add extra > > checks in QEMU for whether the software hasn't actually done > > things right. > > From my reading of things this is a bug in QEMU, not a guest issue. > > The fact that aspeed_smc_flash_setup() for example iterates over a > larger value to send a single byte at a time shows that currently > everyone *thinks* think function should send a single byte. Doesn't that just show that the aspeed flash controller knows it is always talking to an 8-bit SSI device ? It wouldn't surprise me if the SPI-NOR standard in particular insisted on 8-bit transfers, though I can't find anything claiming to be that standard. > So it does seem broken today. Making the current function clear seems > like a good step. Supporting different or larger transfers in the > future is then possible. I think the current interface already supports different or larger transfers. We just happen to not be using that. -- PMM ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 2026-08-27 11:17 ` Peter Maydell @ 2026-08-28 0:07 ` Alistair 2026-08-31 13:00 ` Cédric Le Goater 0 siblings, 1 reply; 26+ messages in thread From: Alistair @ 2026-08-28 0:07 UTC (permalink / raw) To: Peter Maydell Cc: Portia Stephens, qemu-devel, Palmer Dabbelt, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Thu, 2026-08-27 at 12:17 +0100, Peter Maydell wrote: > On Thu, 27 Aug 2026 at 12:03, Alistair <alistair@alistair23.me> > wrote: > > > > On Thu, 2026-08-27 at 11:53 +0100, Peter Maydell wrote: > > > But isn't this just the way the SSI specification is? If we're > > > modelling a "you just have to get this right in software" bit > > > of hardware then we don't need to somehow try to add extra > > > checks in QEMU for whether the software hasn't actually done > > > things right. > > > > From my reading of things this is a bug in QEMU, not a guest issue. > > > > The fact that aspeed_smc_flash_setup() for example iterates over a > > larger value to send a single byte at a time shows that currently > > everyone *thinks* think function should send a single byte. > > Doesn't that just show that the aspeed flash controller knows > it is always talking to an 8-bit SSI device ? It wouldn't But I don't think that's guaranteed to be true. On real hardware the software could know that it's only ever connected to an 8-bit SSI device, and set the driver accordingly. That seems entirely possible. But the hardware seems to support larger sizes reading [1]. In this case the QEMU code is the hardware, and I don't see how we know we are only ever accessing an 8-bit device. 1: https://patchew.org/linux/20220304083643.1079142-1-clg@kaod.org/20220304083643.1079142-5-clg@kaod.org/ > surprise me if the SPI-NOR standard in particular insisted on > 8-bit transfers, though I can't find anything claiming to be > that standard. > > > So it does seem broken today. Making the current function clear > > seems > > like a good step. Supporting different or larger transfers in the > > future is then possible. > > I think the current interface already supports different or > larger transfers. We just happen to not be using that. Kind of. It does support larger transfers, but there is no size argument. So how can the SSI device know how much was sent? Everything seems to just assume a single byte, but it has no way to actually know that. Alistair > > -- PMM ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 2026-08-28 0:07 ` Alistair @ 2026-08-31 13:00 ` Cédric Le Goater 2026-09-01 8:56 ` Bin Meng 0 siblings, 1 reply; 26+ messages in thread From: Cédric Le Goater @ 2026-08-31 13:00 UTC (permalink / raw) To: Alistair, Peter Maydell Cc: Portia Stephens, qemu-devel, Palmer Dabbelt, Jamin Lin, qemu-ppc, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On 8/28/26 02:07, Alistair wrote: > On Thu, 2026-08-27 at 12:17 +0100, Peter Maydell wrote: >> On Thu, 27 Aug 2026 at 12:03, Alistair <alistair@alistair23.me> >> wrote: >>> >>> On Thu, 2026-08-27 at 11:53 +0100, Peter Maydell wrote: >>>> But isn't this just the way the SSI specification is? If we're >>>> modelling a "you just have to get this right in software" bit >>>> of hardware then we don't need to somehow try to add extra >>>> checks in QEMU for whether the software hasn't actually done >>>> things right. >>> >>> From my reading of things this is a bug in QEMU, not a guest issue. >>> >>> The fact that aspeed_smc_flash_setup() for example iterates over a >>> larger value to send a single byte at a time shows that currently >>> everyone *thinks* think function should send a single byte. >> >> Doesn't that just show that the aspeed flash controller knows >> it is always talking to an 8-bit SSI device ? It wouldn't > > But I don't think that's guaranteed to be true. > > On real hardware the software could know that it's only ever connected > to an 8-bit SSI device, and set the driver accordingly. That seems > entirely possible. > > But the hardware seems to support larger sizes reading [1]. > > In this case the QEMU code is the hardware, and I don't see how we know > we are only ever accessing an 8-bit device. > > 1: > https://patchew.org/linux/20220304083643.1079142-1-clg@kaod.org/20220304083643.1079142-5-clg@kaod.org/ On the Aspeed SoC, MMIO accesses (1, 2, 4 bytes) to the SPI controller are converted by the hardware into SPI bus transfers. The exact serialization is hardware-specific. QEMU's choice is to generate byte-oriented SPI transfers. In any case, SPI is generally byte-oriented, with bits shifted over 1/2/4/8 I/O lines. So byte transfer is sufficient. C. > >> surprise me if the SPI-NOR standard in particular insisted on >> 8-bit transfers, though I can't find anything claiming to be >> that standard. >> >>> So it does seem broken today. Making the current function clear >>> seems >>> like a good step. Supporting different or larger transfers in the >>> future is then possible. >> >> I think the current interface already supports different or >> larger transfers. We just happen to not be using that. > > Kind of. It does support larger transfers, but there is no size > argument. So how can the SSI device know how much was sent? Everything > seems to just assume a single byte, but it has no way to actually know > that. > > Alistair > >> >> -- PMM ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 2026-08-31 13:00 ` Cédric Le Goater @ 2026-09-01 8:56 ` Bin Meng 0 siblings, 0 replies; 26+ messages in thread From: Bin Meng @ 2026-09-01 8:56 UTC (permalink / raw) To: Cédric Le Goater Cc: Alistair, Peter Maydell, Portia Stephens, qemu-devel, Palmer Dabbelt, Jamin Lin, qemu-ppc, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Mon, Aug 31, 2026 at 9:03 PM Cédric Le Goater <clg@kaod.org> wrote: > > On 8/28/26 02:07, Alistair wrote: > > On Thu, 2026-08-27 at 12:17 +0100, Peter Maydell wrote: > >> On Thu, 27 Aug 2026 at 12:03, Alistair <alistair@alistair23.me> > >> wrote: > >>> > >>> On Thu, 2026-08-27 at 11:53 +0100, Peter Maydell wrote: > >>>> But isn't this just the way the SSI specification is? If we're > >>>> modelling a "you just have to get this right in software" bit > >>>> of hardware then we don't need to somehow try to add extra > >>>> checks in QEMU for whether the software hasn't actually done > >>>> things right. > >>> > >>> From my reading of things this is a bug in QEMU, not a guest issue. > >>> > >>> The fact that aspeed_smc_flash_setup() for example iterates over a > >>> larger value to send a single byte at a time shows that currently > >>> everyone *thinks* think function should send a single byte. > >> > >> Doesn't that just show that the aspeed flash controller knows > >> it is always talking to an 8-bit SSI device ? It wouldn't > > > > But I don't think that's guaranteed to be true. > > > > On real hardware the software could know that it's only ever connected > > to an 8-bit SSI device, and set the driver accordingly. That seems > > entirely possible. > > > > But the hardware seems to support larger sizes reading [1]. > > > > In this case the QEMU code is the hardware, and I don't see how we know > > we are only ever accessing an 8-bit device. > > > > 1: > > https://patchew.org/linux/20220304083643.1079142-1-clg@kaod.org/20220304083643.1079142-5-clg@kaod.org/ > > On the Aspeed SoC, MMIO accesses (1, 2, 4 bytes) to the SPI controller > are converted by the hardware into SPI bus transfers. The exact > serialization is hardware-specific. QEMU's choice is to generate > byte-oriented SPI transfers. > > In any case, SPI is generally byte-oriented, with bits shifted over > 1/2/4/8 I/O lines. So byte transfer is sufficient. Correct, one evidence is the spi-mem driver interface in the Linux kernel for the spi-nor dummy cycles is converted to bytes. Although some spi-nor devices do support different bit widths other than 8-bit/16-bit/24-bit/32-bit, other bit widths that are not multiple of 8 are currently not supported in the kernel, neither does QEMU. > > C. > > > > >> surprise me if the SPI-NOR standard in particular insisted on > >> 8-bit transfers, though I can't find anything claiming to be > >> that standard. > >> > >>> So it does seem broken today. Making the current function clear > >>> seems > >>> like a good step. Supporting different or larger transfers in the > >>> future is then possible. > >> > >> I think the current interface already supports different or > >> larger transfers. We just happen to not be using that. > > > > Kind of. It does support larger transfers, but there is no size > > argument. So how can the SSI device know how much was sent? Everything > > seems to just assume a single byte, but it has no way to actually know > > that. > > Regards, Bin ^ permalink raw reply [flat|nested] 26+ messages in thread
* Re: [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 2026-08-27 10:53 ` Peter Maydell 2026-08-27 11:03 ` Alistair @ 2026-08-27 12:52 ` Portia Stephens 1 sibling, 0 replies; 26+ messages in thread From: Portia Stephens @ 2026-08-27 12:52 UTC (permalink / raw) To: Peter Maydell Cc: qemu-devel, Palmer Dabbelt, Jamin Lin, qemu-ppc, Cédric Le Goater, Steven Lee, Andrew Jeffery, Harsh Prateek Bora, Subbaraya Sundeep, Troy Lee, Edgar E. Iglesias, Philippe Mathieu-Daudé, Alistair Francis, Strahinja Jankovic, qemu-arm, Tyrone Ting, Nicholas Piggin, Aditya Gupta, Kane Chen, Francisco Iglesias, Joel Stanley, Hao Wu, Glenn Miles, qemu-riscv, Jean-Christophe Dubois, Portia Stephens On Thu, Aug 27, 2026 at 8:53 PM Peter Maydell <peter.maydell@linaro.org> wrote: > > On Thu, 27 Aug 2026 at 11:37, Portia Stephens <stephensportia@gmail.com> wrote: > > > > On Thu, Aug 27, 2026 at 7:19 PM Peter Maydell <peter.maydell@linaro.org> wrote: > > > > > > On Tue, 25 Aug 2026 at 05:05, <stephensportia@gmail.com> wrote: > > > > > > > > From: Portia Stephens <portias@oss.tenstorrent.com> > > > > > > > > The ssi_transfer function comments say that it takes a word varying > > > > between 8-bits and 32-bits. ssi_transfer takes a 32-bit arg to transfer > > > > but there is no means to indicate the number of bits that should > > > > actually be transferred. All child classes of SSI_PERIPHERAL class have > > > > transfer functions that, despite accepting a 32-bit tx, only transfer a > > > > single byte; m25p80_transfer8(), ssi_sd_transfer(), ssd0323_transfer(). > > > > > > > > The current implementation depends on the SSI model to know > > > > what peripheral model will be attached and what transfer size it > > > > expects which is error prone. If a SSI_PERIPHERAL model was written that > > > > accepted 32-bit transfers, it could not attach to any existing SSI > > > > models. > > > > > > What is the motivation for this change? > > > > The motivation came from reviewing the designware ssi driver [1] and > > realizing how error prone it was. The designware ssi supports varying > > frame width but there is no way for the controller logic to know what > > the transfer size an attached device expects. > > But isn't this just the way the SSI specification is? If we're > modelling a "you just have to get this right in software" bit > of hardware then we don't need to somehow try to add extra > checks in QEMU for whether the software hasn't actually done > things right. > > > It seems like all the > > code, that is actually connected to devices, is just written to expect > > 8-bit transfers so it should be made explicit. > > > > https://www.mail-archive.com/qemu-devel@nongnu.org/msg1218153.html > > > > > > > > As far as I know for the hardware SSI protocol, it is indeed > > > the case that the SSI controller (and/or the guest software) needs > > > to know what transfer size the attached device expects: the > > > controller just transmits (or expects to receive) however many > > > bits it is programmed for. > > > > This is true but do the devices currently model only support 8-bit > > transfers in hardware, do they not support multiframe transfer? SPI > > supports varying framewidth but the devices are not actually modeled > > in this way. > > Do the actual devices we implement support varying framewidth, > or do they actually have exactly one frame width that the controller > needs to be programmed by the guest to use ? From my reading of the m25p80 spec, it does not have a fixed frame width. The frame would be determined by the CS being driven and the clock running. A frame could be 1 byte cmd + 3 byte address for a register read. For read mode, 1 byte cmd + 3 byte address + variable length read data. I don't understand how the 8-bit transfer size actually maps to what hardware does. When writing a controller that supports varying framewidths, it requires the controller model to know what transfer width will be expected from the device connected. You could have guest software that correctly sets the controller framewidth to 32-bits and connects a device that provides a 32-bit transfer function. How can the controller differentiate this from the case where the guest software correctly sets a 32-bit framewidth on the controller for a m25p80 read which has a 8-bit transfer size and the controller needs to call the transfer function 4 times to clock out the requested read data. Maybe I am misunderstanding what a transfer is or what a framewidth actually is or what the realistic use cases are here. > > > A better solution may be to have multiple transfer functions, > > ssi_transfer8, ssi_transfer32, etc. This would require the device to > > explicitly set what it is expecting. It is challenging since the only > > model's not using 8-bit transfer don't have any devices connected > > upstream so testing is challenging. > > This doesn't allow for bit widths that aren't a multiple of 8. > > thanks > -- PMM ^ permalink raw reply [flat|nested] 26+ messages in thread
end of thread, other threads:[~2026-09-01 8:57 UTC | newest] Thread overview: 26+ messages (download: mbox.gz follow: Atom feed -- links below jump to the message on this page -- 2026-08-25 4:04 [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 stephensportia 2026-08-25 4:04 ` [PATCH 1/4] hw/ssi: " stephensportia 2026-08-27 5:25 ` Alistair 2026-08-25 4:04 ` [PATCH 2/4] hw/ssi/pl022: Fix dropped upper bytes of ssi transfer stephensportia 2026-08-27 5:27 ` Alistair 2026-08-25 4:04 ` [PATCH 3/4] hw/arm/strongarm: Fix dropped upper byte " stephensportia 2026-08-27 5:29 ` Alistair 2026-08-27 9:09 ` Peter Maydell 2026-08-27 10:53 ` Portia Stephens 2026-08-27 11:04 ` Peter Maydell 2026-08-25 4:04 ` [PATCH 4/4] hw/ssi/pnv_spi: Fix dropped upper bytes " stephensportia 2026-08-27 5:31 ` Alistair 2026-08-27 5:37 ` [PATCH 0/4] Rename ssi_transfer to ssi_transfer8 Alistair 2026-08-27 9:20 ` Peter Maydell 2026-08-27 11:06 ` Alistair 2026-08-27 10:31 ` Philippe Mathieu-Daudé 2026-08-27 9:19 ` Peter Maydell 2026-08-27 10:35 ` Philippe Mathieu-Daudé 2026-08-27 10:37 ` Portia Stephens 2026-08-27 10:53 ` Peter Maydell 2026-08-27 11:03 ` Alistair 2026-08-27 11:17 ` Peter Maydell 2026-08-28 0:07 ` Alistair 2026-08-31 13:00 ` Cédric Le Goater 2026-09-01 8:56 ` Bin Meng 2026-08-27 12:52 ` Portia Stephens
This is an external index of several public inboxes, see mirroring instructions on how to clone and mirror all data and code used by this external index.