fix(spid): DIF SPID to write full word to TPM Rd FIFO Revise dif_spi_device to write full word to RdFIFO and unittest too Signed-off-by: Eunchan Kim <eunchan@opentitan.org>
diff --git a/sw/device/lib/dif/dif_spi_device.c b/sw/device/lib/dif/dif_spi_device.c index d8a33aa..2366cf1 100644 --- a/sw/device/lib/dif/dif_spi_device.c +++ b/sw/device/lib/dif/dif_spi_device.c
@@ -1542,15 +1542,28 @@ } dif_spi_device_tpm_data_status_t status; dif_result_t result = dif_spi_device_tpm_get_data_status(spi, &status); + uint8_t offset = length & 0x3; // lower two bits of length + uint32_t rdfifo_wdata; + if (result != kDifOk) { return result; } if (DIF_SPI_DEVICE_TPM_FIFO_DEPTH - status.read_fifo_occupancy < length) { return kDifOutOfRange; } - for (int i = 0; i < length; i++) { + for (int i = 0; i < length; i += 4) { + if (i + 4 > length) { + // Send partial + rdfifo_wdata = 0; + for (int j = 0; j <= offset; j++) { + rdfifo_wdata |= buf[i + j] << (8 * j); + } + } else { + // Type casting to uint32_t then fetch + rdfifo_wdata = *((uint32_t *)buf + (i >> 2)); + } mmio_region_write32(spi->dev.base_addr, SPI_DEVICE_TPM_READ_FIFO_REG_OFFSET, - buf[i]); + rdfifo_wdata); } return kDifOk; }
diff --git a/sw/device/lib/dif/dif_spi_device_unittest.cc b/sw/device/lib/dif/dif_spi_device_unittest.cc index 29e3bb8..7a3c0b0 100644 --- a/sw/device/lib/dif/dif_spi_device_unittest.cc +++ b/sw/device/lib/dif/dif_spi_device_unittest.cc
@@ -1815,9 +1815,9 @@ {SPI_DEVICE_TPM_STATUS_RDFIFO_DEPTH_OFFSET, 1}, {SPI_DEVICE_TPM_STATUS_WRFIFO_DEPTH_OFFSET, 4}, }); - for (int i = 0; i < 3; i++) { - EXPECT_WRITE32(SPI_DEVICE_TPM_READ_FIFO_REG_OFFSET, data[i]); - } + EXPECT_WRITE32(SPI_DEVICE_TPM_READ_FIFO_REG_OFFSET, + (data[3] << 24) | (data[2] << 16) | (data[1] << 8) | data[0]); + EXPECT_DIF_OK(dif_spi_device_tpm_write_data(&spi_, /*length=*/3, data)); EXPECT_READ32(SPI_DEVICE_TPM_STATUS_REG_OFFSET,