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>
