Skip to content

Commit 6898e84

Browse files
authored
Merge pull request #451 from aidangarske/uboot-support
Update U-boot Support with SPI use
2 parents 1458001 + 01a2bb2 commit 6898e84

File tree

2 files changed

+153
-20
lines changed

2 files changed

+153
-20
lines changed

hal/tpm_io_uboot.c

Lines changed: 152 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,10 @@
1919
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
2020
*/
2121

22-
/* This example shows IO interfaces for U-boot */
22+
/* This example shows IO interfaces for U-boot using raw SPI
23+
* For Raspberry Pi 4 with Infineon SLB9672 TPM HAT
24+
* Reference: https://github.com/wolfSSL/wolfTPM/pull/451
25+
*/
2326

2427
#include <wolftpm/tpm2.h>
2528
#include <wolftpm/tpm2_tis.h>
@@ -43,36 +46,166 @@
4346

4447
#if defined(__UBOOT__)
4548
#include <config.h>
49+
#include <spi.h>
50+
#include <asm/io.h>
51+
#include <dm/device.h>
52+
#include <dm/device-internal.h>
53+
#include <dm/uclass.h>
54+
55+
/* SPI bus and chip select configuration for TPM
56+
* These can be overridden in user_settings.h or board config
57+
* Official Raspberry Pi tpm-slb9670 overlay uses CE1 (GPIO7) */
58+
#ifndef TPM_SPI_BUS
59+
#define TPM_SPI_BUS 0
60+
#endif
61+
#ifndef TPM_SPI_CS
62+
#define TPM_SPI_CS 1 /* CE1 (GPIO7) - matches Linux tpm-slb9670 overlay */
63+
#endif
64+
#ifndef TPM_SPI_MAX_HZ
65+
#define TPM_SPI_MAX_HZ 1000000 /* 1 MHz - safe default */
66+
#endif
67+
#define TPM_SPI_MODE SPI_MODE_0 /* Mode 0 (CPOL=0, CPHA=0) */
68+
69+
/* Maximum SPI frame size */
70+
#define MAX_SPI_FRAMESIZE 64
71+
72+
/* Static SPI device handles */
73+
static struct udevice *g_spi_bus = NULL;
74+
static struct spi_slave *g_spi_slave = NULL;
75+
static int g_spi_initialized = 0;
76+
77+
/* Initialize SPI for TPM communication */
78+
static int uboot_spi_init(void)
79+
{
80+
int ret;
81+
82+
if (g_spi_initialized) {
83+
return 0;
84+
}
85+
86+
#ifdef DEBUG_WOLFTPM
87+
printf("wolfTPM: Initializing SPI bus=%d, cs=%d, hz=%d\n",
88+
TPM_SPI_BUS, TPM_SPI_CS, TPM_SPI_MAX_HZ);
89+
#endif
90+
91+
/* Get or create SPI bus and slave device */
92+
ret = _spi_get_bus_and_cs(TPM_SPI_BUS, TPM_SPI_CS,
93+
TPM_SPI_MAX_HZ, TPM_SPI_MODE,
94+
"spi_generic_drv", "wolftpm_spi",
95+
&g_spi_bus, &g_spi_slave);
96+
if (ret != 0) {
97+
#ifdef DEBUG_WOLFTPM
98+
printf("wolfTPM: SPI init failed: %d\n", ret);
99+
#endif
100+
return ret;
101+
}
102+
103+
g_spi_initialized = 1;
104+
105+
#ifdef DEBUG_WOLFTPM
106+
printf("wolfTPM: SPI initialized successfully\n");
107+
#endif
108+
109+
return 0;
110+
}
111+
112+
/* Raw SPI transfer for wolfTPM TIS layer
113+
* This is called by wolfTPM's TIS implementation for register read/write.
114+
* The txBuf/rxBuf contain TIS-formatted SPI data including the 4-byte header.
115+
*/
46116
int TPM2_IoCb_Uboot_SPI(TPM2_CTX* ctx, const byte* txBuf,
47117
byte* rxBuf, word16 xferSz, void* userCtx)
48118
{
49-
int ret = 0;
50-
struct udevice *dev;
119+
int ret;
120+
#ifdef WOLFTPM_CHECK_WAIT_STATE
121+
int timeout = TPM_SPI_WAIT_RETRY;
122+
byte tmp_rx;
123+
#endif
51124

52-
/* Get the TPM device */
53-
if (ret == 0) {
54-
ret = tcg2_platform_get_tpm2(&dev);
55-
if ( ret != 0 || dev == NULL) {
56-
#ifdef DEBUG_WOLFTPM
57-
printf("Failed to get TPM device with error: %d\n", ret);
58-
#endif
59-
return TPM_RC_FAILURE;
60-
}
125+
(void)ctx;
126+
(void)userCtx;
127+
128+
/* Initialize SPI if needed */
129+
ret = uboot_spi_init();
130+
if (ret != 0) {
131+
return TPM_RC_FAILURE;
132+
}
133+
134+
/* Claim the SPI bus */
135+
ret = spi_claim_bus(g_spi_slave);
136+
if (ret != 0) {
137+
#ifdef DEBUG_WOLFTPM
138+
printf("wolfTPM: Failed to claim SPI bus: %d\n", ret);
139+
#endif
140+
return TPM_RC_FAILURE;
141+
}
142+
143+
#ifdef WOLFTPM_CHECK_WAIT_STATE
144+
/* Send TIS header first (4 bytes) with CS held */
145+
ret = spi_xfer(g_spi_slave, TPM_TIS_HEADER_SZ * 8,
146+
txBuf, rxBuf, SPI_XFER_BEGIN);
147+
if (ret != 0) {
148+
#ifdef DEBUG_WOLFTPM
149+
printf("wolfTPM: SPI header xfer failed: %d\n", ret);
150+
#endif
151+
goto cleanup;
61152
}
62153

63-
/* Transfer the device data using tpm_xfer */
64-
if (ret == 0) {
65-
ret = tpm_xfer(dev, txBuf, xferSz, rxBuf, &xferSz);
66-
if (ret != 0) {
154+
/* Check for wait state - TPM holds ready bit low if busy */
155+
if ((rxBuf[TPM_TIS_HEADER_SZ - 1] & TPM_TIS_READY_MASK) == 0) {
156+
/* Poll for ready */
157+
do {
158+
ret = spi_xfer(g_spi_slave, 8, NULL, &tmp_rx, 0);
159+
if (ret != 0) {
160+
break;
161+
}
162+
if (tmp_rx & TPM_TIS_READY_MASK) {
163+
break;
164+
}
165+
} while (--timeout > 0);
166+
167+
if (timeout <= 0 || ret != 0) {
67168
#ifdef DEBUG_WOLFTPM
68-
printf("tpm_xfer failed with error: %d\n", ret);
169+
printf("wolfTPM: SPI wait state timeout\n");
69170
#endif
70-
return TPM_RC_FAILURE;
171+
/* Deassert CS */
172+
spi_xfer(g_spi_slave, 0, NULL, NULL, SPI_XFER_END);
173+
ret = TPM_RC_FAILURE;
174+
goto cleanup;
71175
}
72176
}
73177

74-
return TPM_RC_SUCCESS;
178+
/* Transfer remainder of data with CS deasserted at end */
179+
if (xferSz > TPM_TIS_HEADER_SZ) {
180+
ret = spi_xfer(g_spi_slave, (xferSz - TPM_TIS_HEADER_SZ) * 8,
181+
&txBuf[TPM_TIS_HEADER_SZ],
182+
&rxBuf[TPM_TIS_HEADER_SZ],
183+
SPI_XFER_END);
184+
} else {
185+
/* Just deassert CS if no more data */
186+
ret = spi_xfer(g_spi_slave, 0, NULL, NULL, SPI_XFER_END);
187+
}
188+
189+
#else
190+
/* No wait state handling - send entire message at once */
191+
ret = spi_xfer(g_spi_slave, xferSz * 8, txBuf, rxBuf,
192+
SPI_XFER_BEGIN | SPI_XFER_END);
193+
#endif /* WOLFTPM_CHECK_WAIT_STATE */
194+
195+
if (ret != 0) {
196+
ret = TPM_RC_FAILURE;
197+
} else {
198+
ret = TPM_RC_SUCCESS;
199+
}
200+
201+
#ifdef WOLFTPM_CHECK_WAIT_STATE
202+
cleanup:
203+
#endif
204+
spi_release_bus(g_spi_slave);
205+
206+
return ret;
75207
}
208+
76209
#endif /* __UBOOT__ */
77210
#endif /* WOLFTPM_LINUX_DEV || WOLFTPM_SWTPM || WOLFTPM_WINAPI */
78211
#endif /* WOLFTPM_INCLUDE_IO_FILE */

src/tpm2.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -729,7 +729,7 @@ TPM_RC TPM2_Cleanup(TPM2_CTX* ctx)
729729
}
730730
#endif /* !WOLFTPM2_NO_WOLFCRYPT */
731731

732-
#ifdef WOLFTPM_LINUX_DEV
732+
#if defined(WOLFTPM_LINUX_DEV) && !defined(__UBOOT__)
733733
if (ctx->fd >= 0)
734734
close(ctx->fd);
735735
#endif

0 commit comments

Comments
 (0)