From 66ad05dfd7751f0351fce39e923da5523c08f261 Mon Sep 17 00:00:00 2001 From: Scott Date: Fri, 23 Sep 2016 12:36:28 -0700 Subject: [PATCH] Cr50: I2CS: Fixed i2cs word aligned fifo write function Fixed an issue with word aligned write to fifo routine. There were two errors. In the top section, the fifo was being read always from the beginning word or the hw fito, but the updated word was written back to the proper location. The same error was in the section that dealt with the last < 4 bytes. Both have been corrected. The error in the top section would in practice be invisible because flow control prevents TPM fifo reads from happening while one is in progress. The error in the bottom section was responsible for the problem as described in chrome-os-partner:57782. BRANCH=none BUG=chrome-os-partner:57782 TEST=manual Used special AP fw build that supports a 'tpm_raw' command to initiate the Cr50 TPM fifo write/read. 'tpm_raw 0x80 0x01 0x00 0x00 0x00 0x16 0x00 0x00 0x01 0x7a 0x00 0x00 0x00 0x06 0x00 0x00 0x02 0x00 0x00 0x00 0x00 0x7f' Without this CL, the 1st two bytes were incorrect ~50% of the time. With the fix in place, verified that the first two bytes returned were always correct. Change-Id: Iff7620561eee463d599abfa6c07455c56bb5a5a6 Signed-off-by: Scott Reviewed-on: https://chromium-review.googlesource.com/388785 Commit-Ready: Scott Collyer Tested-by: Scott Collyer Reviewed-by: Bill Richardson --- chip/g/i2cs.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/chip/g/i2cs.c b/chip/g/i2cs.c index 77a39a5a1e..77c451079f 100644 --- a/chip/g/i2cs.c +++ b/chip/g/i2cs.c @@ -216,7 +216,7 @@ void i2cs_post_read_fill_fifo(uint8_t *buffer, size_t len) /* Insert bytes until fifo is word aligned */ if (remainder_bytes) { /* mask the bytes to be kept */ - word_out_value = *value_addr; + word_out_value = value_addr[addr_offset]; word_out_value &= (1 << (8 * start_offset)) - 1; /* Write in remainder bytes */ for (i = 0; i < remainder_bytes; i++) @@ -244,7 +244,7 @@ void i2cs_post_read_fill_fifo(uint8_t *buffer, size_t len) remainder_bytes = len; if (remainder_bytes) { /* read from HW fifo */ - word_out_value = *value_addr; + word_out_value = value_addr[addr_offset]; /* Mask bytes that need to be kept */ word_out_value &= (0xffffffff << (8 * remainder_bytes)); for (i = 0; i < remainder_bytes; i++)