22 * QEMU OpenTitan SPI Device controller
33 *
44 * Copyright (c) 2023-2025 Rivos, Inc.
5+ * Copyright (c) 2025 lowRISC contributors.
56 *
67 * Author(s):
78 * Emmanuel Blot <[email protected] > @@ -379,6 +380,7 @@ typedef enum {
379380 SPI_BUS_TPM ,
380381 SPI_BUS_DISCARD ,
381382 SPI_BUS_ERROR ,
383+ SPI_BUS_DISCARD_PACKET ,
382384} OtSpiBusState ;
383385
384386typedef enum {
@@ -641,6 +643,7 @@ static const char *BUS_STATE_NAMES[] = {
641643 STATE_NAME_ENTRY (SPI_BUS_TPM ),
642644 STATE_NAME_ENTRY (SPI_BUS_DISCARD ),
643645 STATE_NAME_ENTRY (SPI_BUS_ERROR ),
646+ STATE_NAME_ENTRY (SPI_BUS_DISCARD_PACKET ),
644647};
645648
646649static const char * FLASH_STATE_NAMES [] = {
@@ -2028,6 +2031,12 @@ static void ot_spi_device_chr_handle_header(OtSPIDeviceState *s)
20282031 return ;
20292032 }
20302033
2034+ /* discard the packet if we're within a failed transaction */
2035+ if (s -> bus .state == SPI_BUS_DISCARD_PACKET ) {
2036+ BUS_CHANGE_STATE (s , DISCARD );
2037+ return ;
2038+ }
2039+
20312040 /* @todo: Check that the tpm chip-select was assigned.*/
20322041 if (ot_spi_device_is_tpm_enabled (s )) {
20332042 ot_spi_device_tpm_init_buffers (s );
@@ -2242,6 +2251,7 @@ static int ot_spi_device_chr_can_receive(void *opaque)
22422251 unsigned length = 0u ;
22432252
22442253 switch (bus -> state ) {
2254+ case SPI_BUS_DISCARD_PACKET :
22452255 case SPI_BUS_IDLE :
22462256 length = fifo8_num_free (& bus -> chr_fifo );
22472257 break ;
@@ -2274,6 +2284,7 @@ static void ot_spi_device_chr_receive(void *opaque, const uint8_t *buf,
22742284
22752285 switch (bus -> state ) {
22762286 case SPI_BUS_IDLE :
2287+ case SPI_BUS_DISCARD_PACKET :
22772288 g_assert (size <= fifo8_num_free (& bus -> chr_fifo ));
22782289 while (size -- ) {
22792290 fifo8_push (& bus -> chr_fifo , * buf ++ );
@@ -2298,12 +2309,33 @@ static void ot_spi_device_chr_receive(void *opaque, const uint8_t *buf,
22982309 break ;
22992310 }
23002311
2301- if (!bus -> byte_count ) {
2302- if (bus -> release ) {
2303- ot_spi_device_release (s );
2304- } else {
2305- BUS_CHANGE_STATE (s , IDLE );
2306- }
2312+ if (bus -> byte_count ) {
2313+ /* there is more to process in this state */
2314+ return ;
2315+ }
2316+
2317+ if (bus -> release ) {
2318+ /* final packet in transaction, release CS */
2319+ ot_spi_device_release (s );
2320+ return ;
2321+ }
2322+
2323+ /*
2324+ * more packets to process in transaction, prepare to receive another header
2325+ */
2326+ switch (bus -> state ) {
2327+ case SPI_BUS_IDLE :
2328+ case SPI_BUS_FLASH :
2329+ case SPI_BUS_DISCARD_PACKET :
2330+ BUS_CHANGE_STATE (s , IDLE );
2331+ break ;
2332+ case SPI_BUS_DISCARD :
2333+ case SPI_BUS_ERROR :
2334+ BUS_CHANGE_STATE (s , DISCARD_PACKET );
2335+ break ;
2336+ default :
2337+ g_assert_not_reached ();
2338+ break ;
23072339 }
23082340}
23092341
0 commit comments