Corrected Linux usage of cs_change, added config overrides.

pull/268/head
Bill Phipps 2023-04-18 13:18:33 -07:00
parent f032c5c569
commit 052d8f5bc6
1 changed files with 62 additions and 37 deletions

View File

@ -68,28 +68,34 @@
#define TPM2_I2C_HZ 400000 /* 400kHz */ #define TPM2_I2C_HZ 400000 /* 400kHz */
#else #else
/* SPI */ /* SPI */
#ifdef WOLFTPM_MICROCHIP #ifndef TPM2_SPI_DEV_CS
/* Microchip ATTPM20 uses CE0 */ #ifdef WOLFTPM_MICROCHIP
#define TPM2_SPI_DEV_CS "0" /* Microchip ATTPM20 uses CE0 */
#elif defined(WOLFTPM_ST33) #define TPM2_SPI_DEV_CS "0"
/* STM ST33HTPH SPI uses CE0 */ #elif defined(WOLFTPM_ST33)
#define TPM2_SPI_DEV_CS "0" /* STM ST33HTPH SPI uses CE0 */
#elif defined(WOLFTPM_NUVOTON) #define TPM2_SPI_DEV_CS "0"
/* Nuvoton NPCT75x uses CE0 */ #elif defined(WOLFTPM_NUVOTON)
#define TPM2_SPI_DEV_CS "0" /* Nuvoton NPCT75x uses CE0 */
#else #define TPM2_SPI_DEV_CS "0"
/* OPTIGA SLB9670/SLB9762 and LetsTrust TPM use CE1 */ #else
#define TPM2_SPI_DEV_CS "1" /* OPTIGA SLB9670/SLB9762 and LetsTrust TPM use CE1 */
#define TPM2_SPI_DEV_CS "0"
#endif
#endif
#ifndef TPM2_SPI_DEV_PATH
#define TPM2_SPI_DEV_PATH "/dev/spidev0."
#endif #endif
#ifdef WOLFTPM_AUTODETECT #ifdef WOLFTPM_AUTODETECT
#undef TPM2_SPI_DEV #undef TPM2_SPI_DEV
/* this will try incrementing spidev chip selects */ /* this will try incrementing spidev chip selects */
static char TPM2_SPI_DEV[] = "/dev/spidev0.0"; static char TPM2_SPI_DEV[] = TPM2_SPI_DEV_PATH TPM2_SPI_DEV_CS;
#define MAX_SPI_DEV_CS '4' #define MAX_SPI_DEV_CS '4'
static int foundSpiDev = 0; static int foundSpiDev = 0;
#else #else
#define TPM2_SPI_DEV "/dev/spidev0."TPM2_SPI_DEV_CS #define TPM2_SPI_DEV TPM2_SPI_DEV_PATH TPM2_SPI_DEV_CS
#endif #endif
#endif #endif
#endif #endif
@ -193,11 +199,14 @@
int TPM2_IoCb_Linux_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf, int TPM2_IoCb_Linux_SPI(TPM2_CTX* ctx, const byte* txBuf, byte* rxBuf,
word16 xferSz, void* userCtx) word16 xferSz, void* userCtx)
{ {
int ret = TPM_RC_FAILURE; int ret;
int spiDev; int spiDev;
#ifdef WOLFTPM_CHECK_WAIT_STATE #ifdef WOLFTPM_CHECK_WAIT_STATE
int timeout; int timeout;
#endif #endif
#ifdef WOLFTPM_AUTODETECT
int devLen;
#endif
/* Note: PI has issue with 5-10Mhz on packets sized over 130 bytes */ /* Note: PI has issue with 5-10Mhz on packets sized over 130 bytes */
unsigned int maxSpeed = TPM2_SPI_HZ; unsigned int maxSpeed = TPM2_SPI_HZ;
@ -212,10 +221,11 @@
} }
#endif #endif
#endif #endif
ret = TPM_RC_SUCCESS;
#ifdef WOLFTPM_CHECK_WAIT_STATE #ifdef WOLFTPM_CHECK_WAIT_STATE
timeout = TPM_SPI_WAIT_RETRY; timeout = TPM_SPI_WAIT_RETRY;
#endif #endif
spiDev = open(TPM2_SPI_DEV, O_RDWR); spiDev = open(TPM2_SPI_DEV, O_RDWR);
if (spiDev >= 0) { if (spiDev >= 0) {
struct spi_ioc_transfer spi; struct spi_ioc_transfer spi;
@ -226,48 +236,59 @@
ioctl(spiDev, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word); ioctl(spiDev, SPI_IOC_WR_BITS_PER_WORD, &bits_per_word);
XMEMSET(&spi, 0, sizeof(spi)); XMEMSET(&spi, 0, sizeof(spi));
spi.cs_change = 1; /* strobe CS between transfers */
#ifdef WOLFTPM_CHECK_WAIT_STATE #ifdef WOLFTPM_CHECK_WAIT_STATE
/* Keep CS asserted for header and flow control transfers */
spi.cs_change = 1;
/* Send Header */ /* Send Header */
spi.tx_buf = (unsigned long)txBuf; spi.tx_buf = (unsigned long)txBuf;
spi.rx_buf = (unsigned long)rxBuf; spi.rx_buf = (unsigned long)rxBuf;
spi.len = TPM_TIS_HEADER_SZ; spi.len = TPM_TIS_HEADER_SZ;
size = ioctl(spiDev, SPI_IOC_MESSAGE(1), &spi); size = ioctl(spiDev, SPI_IOC_MESSAGE(1), &spi);
if (size != TPM_TIS_HEADER_SZ) { if (size != TPM_TIS_HEADER_SZ) {
close(spiDev); ret = TPM_RC_FAILURE;
return TPM_RC_FAILURE;
} }
/* Handle SPI wait states (ST33 typical wait is 2 bytes) */ /* Handle SPI wait states (ST33 typical wait is 2 bytes) */
if ((rxBuf[TPM_TIS_HEADER_SZ-1] & TPM_TIS_READY_MASK) == 0) { if ((ret == TPM_RC_SUCCESS) &&
((rxBuf[TPM_TIS_HEADER_SZ-1] & TPM_TIS_READY_MASK) == 0)) {
/* Place flow control byte in last header response byte*/
spi.rx_buf = (unsigned long)&rxBuf[TPM_TIS_HEADER_SZ-1];
spi.len = 1;
do { do {
/* Check for SPI ready */ /* Check for SPI ready */
spi.len = 1;
size = ioctl(spiDev, SPI_IOC_MESSAGE(1), &spi); size = ioctl(spiDev, SPI_IOC_MESSAGE(1), &spi);
if (rxBuf[0] & TPM_TIS_READY_MASK) } while (
break; (size == 1) &&
} while (size == 1 && --timeout > 0); ((rxBuf[TPM_TIS_HEADER_SZ-1] & TPM_TIS_READY_MASK)==0) &&
(--timeout > 0));
#ifdef WOLFTPM_DEBUG_TIMEOUT #ifdef WOLFTPM_DEBUG_TIMEOUT
printf("SPI Ready Timeout %d\n", TPM_SPI_WAIT_RETRY - timeout); printf("SPI Ready Timeout %d\n", TPM_SPI_WAIT_RETRY - timeout);
#endif #endif
if (size == 1 && timeout > 0) { if (size != 1 )
ret = TPM_RC_SUCCESS; ret = TPM_RC_FAILURE;
} else if (timeout <= 0)
} ret = TPM_RC_FAILURE; /* Timeout */
else {
ret = TPM_RC_SUCCESS;
} }
/* Remainder of message */
if (ret == TPM_RC_SUCCESS) { if (ret == TPM_RC_SUCCESS) {
/* Remainder of message */ spi.cs_change = 0; /* Deassert cs after transfer */
spi.tx_buf = (unsigned long)&txBuf[TPM_TIS_HEADER_SZ]; spi.tx_buf = (unsigned long)&txBuf[TPM_TIS_HEADER_SZ];
spi.rx_buf = (unsigned long)&rxBuf[TPM_TIS_HEADER_SZ]; spi.rx_buf = (unsigned long)&rxBuf[TPM_TIS_HEADER_SZ];
spi.len = xferSz - TPM_TIS_HEADER_SZ; spi.len = xferSz - TPM_TIS_HEADER_SZ;
size = ioctl(spiDev, SPI_IOC_MESSAGE(1), &spi); size = ioctl(spiDev, SPI_IOC_MESSAGE(1), &spi);
if (size != (size_t)xferSz - TPM_TIS_HEADER_SZ)
ret = TPM_RC_FAILURE;
}
if (size == (size_t)xferSz - TPM_TIS_HEADER_SZ) /* Send 1 byte dummy message to deassert cs if needed */
ret = TPM_RC_SUCCESS; if (spi.cs_change == 1) {
spi.cs_change = 0;
spi.len = 1;
size = ioctl(spiDev, SPI_IOC_MESSAGE(1), &spi);
(void)size; /* Ignore result */
} }
#else #else
/* Send Entire Message - no wait states */ /* Send Entire Message - no wait states */
@ -275,24 +296,28 @@
spi.rx_buf = (unsigned long)rxBuf; spi.rx_buf = (unsigned long)rxBuf;
spi.len = xferSz; spi.len = xferSz;
size = ioctl(spiDev, SPI_IOC_MESSAGE(1), &spi); size = ioctl(spiDev, SPI_IOC_MESSAGE(1), &spi);
if (size == (size_t)xferSz) if (size != (size_t)xferSz)
ret = TPM_RC_SUCCESS; ret = TPM_RC_FAILURE;
#endif /* WOLFTPM_CHECK_WAIT_STATE */ #endif /* WOLFTPM_CHECK_WAIT_STATE */
close(spiDev); close(spiDev);
} }
else {
/* Failed to open device */
ret = TPM_RC_FAILURE;
}
#ifdef WOLFTPM_AUTODETECT #ifdef WOLFTPM_AUTODETECT
/* if response is not 0xFF then we "found" something */ /* if response is not 0xFF then we "found" something */
if (!foundSpiDev) { if (!foundSpiDev) {
if (ret == TPM_RC_SUCCESS && rxBuf[0] != 0xFF) { if ((ret == TPM_RC_SUCCESS) && (rxBuf[TPM_TIS_HEADER_SZ-1] != 0xFF)) {
#ifdef DEBUG_WOLFTPM #ifdef DEBUG_WOLFTPM
printf("Found TPM @ %s\n", TPM2_SPI_DEV); printf("Found TPM @ %s\n", TPM2_SPI_DEV);
#endif #endif
foundSpiDev = 1; foundSpiDev = 1;
} }
else { else {
int devLen = (int)XSTRLEN(TPM2_SPI_DEV); devLen = (int)XSTRLEN(TPM2_SPI_DEV);
/* tries spidev0.[0-4] */ /* tries spidev0.[0-4] */
if (TPM2_SPI_DEV[devLen-1] <= MAX_SPI_DEV_CS) { if (TPM2_SPI_DEV[devLen-1] <= MAX_SPI_DEV_CS) {
TPM2_SPI_DEV[devLen-1]++; TPM2_SPI_DEV[devLen-1]++;