Skip site navigation (1)Skip section navigation (2)
Date:      Sat, 15 Nov 2025 02:22:46 GMT
From:      Kyle Evans <kevans@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: cca34aa1d005 - main - tpm: crb: factor out idle/ready state transitions
Message-ID:  <202511150222.5AF2MkO8089280@gitrepo.freebsd.org>

index | next in thread | raw e-mail

The branch main has been updated by kevans:

URL: https://cgit.FreeBSD.org/src/commit/?id=cca34aa1d005ffc859704331a3221b8c506d2f06

commit cca34aa1d005ffc859704331a3221b8c506d2f06
Author:     Kyle Evans <kevans@FreeBSD.org>
AuthorDate: 2025-11-15 02:22:10 +0000
Commit:     Kyle Evans <kevans@FreeBSD.org>
CommitDate: 2025-11-15 02:22:10 +0000

    tpm: crb: factor out idle/ready state transitions
    
    Some TPM implementations have a different start method that requires
    an additional notification for some state changes; for instance, the
    "Pluton" start method.  Just factor these transitions out for now, and
    the coming commits will introduce points that the start method can hook
    in at.
    
    Reviewed by:    obrien
    Differential Revision:  https://reviews.freebsd.org/D53682
---
 sys/dev/tpm/tpm_crb.c | 61 +++++++++++++++++++++++++++++++++++++++++----------
 1 file changed, 50 insertions(+), 11 deletions(-)

diff --git a/sys/dev/tpm/tpm_crb.c b/sys/dev/tpm/tpm_crb.c
index 017ebd45c7ea..28b4f21eccfb 100644
--- a/sys/dev/tpm/tpm_crb.c
+++ b/sys/dev/tpm/tpm_crb.c
@@ -301,6 +301,48 @@ tpmcrb_cancel_cmd(struct tpm_sc *sc)
 	return (true);
 }
 
+static bool
+tpmcrb_state_idle(struct tpmcrb_sc *crb_sc, bool wait)
+{
+	struct tpm_sc *sc;
+	int mask, timeout;
+
+	timeout = wait ? TPM_TIMEOUT_C : 0;
+
+	sc = &crb_sc->base;
+	OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_IDLE);
+
+	if (timeout > 0) {
+		mask = TPM_CRB_CTRL_STS_IDLE_BIT;
+		if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS, mask, mask,
+		    timeout))
+			return (false);
+	}
+
+	return (true);
+}
+
+static bool
+tpmcrb_state_ready(struct tpmcrb_sc *crb_sc, bool wait)
+{
+	struct tpm_sc *sc;
+	int mask, timeout;
+
+	timeout = wait ? TPM_TIMEOUT_C : 0;
+
+	sc = &crb_sc->base;
+	OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_READY);
+
+	if (timeout > 0) {
+		mask = TPM_CRB_CTRL_REQ_GO_READY;
+		if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS, mask, !mask,
+		    timeout))
+			return (false);
+	}
+
+	return (true);
+}
+
 int
 tpmcrb_transmit(device_t dev, size_t length)
 {
@@ -335,22 +377,15 @@ tpmcrb_transmit(device_t dev, size_t length)
 
 	/* Switch device to idle state if necessary */
 	if (!(TPM_READ_4(dev, TPM_CRB_CTRL_STS) & TPM_CRB_CTRL_STS_IDLE_BIT)) {
-		OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_IDLE);
-
-		mask = TPM_CRB_CTRL_STS_IDLE_BIT;
-		if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS,
-			    mask, mask, TPM_TIMEOUT_C)) {
+		if (!tpmcrb_state_idle(crb_sc, true)) {
 			device_printf(dev,
 			    "Failed to transition to idle state\n");
 			return (EIO);
 		}
 	}
-	/* Switch to ready state */
-	OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_READY);
 
-	mask = TPM_CRB_CTRL_REQ_GO_READY;
-	if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS,
-		    mask, !mask, TPM_TIMEOUT_C)) {
+	/* Switch to ready state */
+	if (!tpmcrb_state_ready(crb_sc, true)) {
 		device_printf(dev,
 		    "Failed to transition to ready state\n");
 		return (EIO);
@@ -394,7 +429,11 @@ tpmcrb_transmit(device_t dev, size_t length)
 	bus_read_region_stream_1(sc->mem_res, crb_sc->rsp_off + TPM_HEADER_SIZE,
 	      &sc->buf[TPM_HEADER_SIZE], bytes_available - TPM_HEADER_SIZE);
 
-	OR4(sc, TPM_CRB_CTRL_REQ, TPM_CRB_CTRL_REQ_GO_IDLE);
+	if (!tpmcrb_state_idle(crb_sc, false)) {
+		device_printf(dev,
+		    "Failed to transition to idle state post-send\n");
+		return (EIO);
+	}
 
 	tpmcrb_relinquish_locality(sc);
 	sc->pending_data_length = bytes_available;


home | help

Want to link to this message? Use this
URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202511150222.5AF2MkO8089280>