diff mbox series

[v2] tpm_i2c_nuvoton: check TPM vendor id register during probe

Message ID 20200306171316.13998-1-erichte@linux.ibm.com
State Accepted
Headers show
Series [v2] tpm_i2c_nuvoton: check TPM vendor id register during probe | expand

Checks

Context Check Description
snowpatch_ozlabs/apply_patch success Successfully applied on branch master (82aed17a5468aff6b600ee1694a10a60f942c018)
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot success Test snowpatch/job/snowpatch-skiboot on branch master
snowpatch_ozlabs/snowpatch_job_snowpatch-skiboot-dco success Signed-off-by present

Commit Message

Eric Richter March 6, 2020, 5:13 p.m. UTC
The driver for the nuvoton i2c TPM does not currently check if there is
a functional TPM at the bus and address given by the device tree.

This patch adds a simple check of the TPM vendor id register, compares
against the known expected value for the chip, skips registering it if
the chip is inaccessible or returns an unexpected id.

Signed-off-by: Eric Richter <erichte@linux.ibm.com>
---
V2:
 - split multi-line conditional into two separate checks
 - errors break loop and disable node rather than continuing
 - s/TPM_650_VENDOR_ID/TPM_NUVOTON_650_ID

 libstb/drivers/tpm_i2c_nuvoton.c | 14 ++++++++++++++
 1 file changed, 14 insertions(+)

Comments

Oliver O'Halloran March 30, 2020, 6:36 a.m. UTC | #1
On Sat, Mar 7, 2020 at 4:42 AM Eric Richter <erichte@linux.ibm.com> wrote:
>
> The driver for the nuvoton i2c TPM does not currently check if there is
> a functional TPM at the bus and address given by the device tree.
>
> This patch adds a simple check of the TPM vendor id register, compares
> against the known expected value for the chip, skips registering it if
> the chip is inaccessible or returns an unexpected id.
>
> Signed-off-by: Eric Richter <erichte@linux.ibm.com>

Thanks, merged as c2ba08e8ec3745d9c6a917a21d81d196160fd977
diff mbox series

Patch

diff --git a/libstb/drivers/tpm_i2c_nuvoton.c b/libstb/drivers/tpm_i2c_nuvoton.c
index 3679ddaf..b6dde324 100644
--- a/libstb/drivers/tpm_i2c_nuvoton.c
+++ b/libstb/drivers/tpm_i2c_nuvoton.c
@@ -30,6 +30,7 @@ 
 #define TPM_BURST_COUNT		0x01
 #define TPM_DATA_FIFO_W		0x20
 #define TPM_DATA_FIFO_R		0x40
+#define TPM_VID_DID		0x60
 
 /* Bit masks for the TPM STATUS register */
 #define TPM_STS_VALID		0x80
@@ -42,6 +43,8 @@ 
 /* TPM Driver values */
 #define MAX_STSVALID_POLLS 	5
 #define TPM_TIMEOUT_INTERVAL	10
+#define TPM_NUVOTON_650_ID	0x5010FE00
+#define TPM_VENDOR_ID_MASK	0xFFFFFF00
 
 static struct tpm_dev *tpm_device = NULL;
 
@@ -552,6 +555,7 @@  void tpm_i2c_nuvoton_probe(void)
 	struct dt_node *node = NULL;
 	struct i2c_bus *bus;
 	const char *name;
+	uint32_t vendor = 0;
 
 	dt_for_each_compatible(dt_root, node, "nuvoton,npct650") {
 		if (!dt_node_is_enabled(node))
@@ -588,6 +592,16 @@  void tpm_i2c_nuvoton_probe(void)
 			      "found, tpm node parent %p\n", node->parent);
 			goto disable;
 		}
+		/* ensure there's really the TPM we expect at that address */
+		if (tpm_i2c_request_send(tpm_device, SMBUS_READ, TPM_VID_DID,
+					 1, &vendor, sizeof(vendor))) {
+			prlog(PR_ERR, "NUVOTON: i2c device inaccessible\n");
+			goto disable;
+		}
+		if ((vendor & TPM_VENDOR_ID_MASK) != TPM_NUVOTON_650_ID) {
+			prlog(PR_ERR, "NUVOTON: expected vendor id mismatch\n");
+			goto disable;
+		}
 		if (tpm_register_chip(node, tpm_device,
 				      &tpm_i2c_nuvoton_driver)) {
 			free(tpm_device);