@@ -100,6 +100,8 @@ int TPM2_IoCb_Mmio(TPM2_CTX *ctx, int isRead, word32 addr, byte* buf, word16 siz
100100{
101101 size_t i ;
102102 word32 effectiveAddr ;
103+ word32 regOffset ;
104+ int isFifo ;
103105
104106 /* Bounds check to prevent address wrap-around */
105107 if (addr >= TPM_MMIO_MAX_OFFSET ) {
@@ -108,12 +110,21 @@ int TPM2_IoCb_Mmio(TPM2_CTX *ctx, int isRead, word32 addr, byte* buf, word16 siz
108110
109111 effectiveAddr = MIMO_BASE_ADDRESS + addr ;
110112
113+ /* FIFO registers use the same address for every access
114+ * (hardware auto-increments internally).
115+ * Non-FIFO registers need the address advanced for multi-byte access.
116+ * TPM_DATA_FIFO offset=0x0024, TPM_XDATA_FIFO offset=0x0083 */
117+ regOffset = addr & 0x0FFFu ;
118+ isFifo = (regOffset == 0x0024u || regOffset == 0x0083u );
119+
111120 /* IO for 32-bit aligned */
112121 for (i = 0 ; ((size_t )size - i ) >= sizeof (word32 ); i += sizeof (word32 )) {
113122 if (isRead )
114123 TPM2_Mmio_Read32 (effectiveAddr , buf + i );
115124 else
116125 TPM2_Mmio_Write32 (effectiveAddr , buf + i );
126+ if (!isFifo )
127+ effectiveAddr += sizeof (word32 );
117128 }
118129
119130 /* IO for unaligned remainder */
@@ -122,6 +133,8 @@ int TPM2_IoCb_Mmio(TPM2_CTX *ctx, int isRead, word32 addr, byte* buf, word16 siz
122133 TPM2_Mmio_Read8 (effectiveAddr , buf + i );
123134 else
124135 TPM2_Mmio_Write8 (effectiveAddr , buf + i );
136+ if (!isFifo )
137+ effectiveAddr ++ ;
125138 }
126139
127140 (void )ctx ;
0 commit comments