[2/5] hdata/tpmrel.c: add eventlog info to tpm devices

Message ID 1504165372-15971-3-git-send-email-cclaudio@linux.vnet.ibm.com
State Under Review
Headers show
Series
  • hdata: add and parse the tpmrel structure
Related show

Commit Message

Claudio Carvalho Aug. 31, 2017, 7:42 a.m.
This parses the TPMREL secureboot_tpm_info structure in order to add the
event log info to i2c tpm devices.

There can be multiple secureboot_tpm_info entries with each entry
corresponding to a master processor that has a tpm device.

Signed-off-by: Claudio Carvalho <cclaudio@linux.vnet.ibm.com>
---
 hdata/spira.h  | 28 ++++++++++++++++++++++++++++
 hdata/tpmrel.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 2 files changed, 81 insertions(+), 1 deletion(-)

Patch

diff --git a/hdata/spira.h b/hdata/spira.h
index d2a70c1..78ff33d 100644
--- a/hdata/spira.h
+++ b/hdata/spira.h
@@ -1098,6 +1098,34 @@  struct ipmi_sensors {
  */
 #define STB_HDIF_SIG	"TPMREL"
 
+/*
+ * Idata index 0 : Secure Boot and TPM Instance Info
+ *
+ * There can be multiple entries with each entry corresponding to
+ * a master processor that has a TPM device
+ */
+#define TPMREL_IDATA_SECUREBOOT_TPM_INFO	0
+
+struct secureboot_tpm_info {
+	__be32 chip_id;
+	__be32 dbob_id;
+	uint8_t locality1;
+	uint8_t locality2;
+	uint8_t locality3;
+	uint8_t locality4;
+#define TPM_PRESENT_AND_FUNCTIONAL	0x01
+#define TPM_PRESENT_AND_NOT_FUNCTIONAL	0x02
+#define TPM_NOT_PRESENT			0x03
+	uint8_t tpm_status;
+	uint8_t reserved[3];
+	/* zero indicates no tpm log data */
+	__be32 srtm_log_offset;
+	__be32 srtm_log_size;
+	/* zero indicates no tpm log data */
+	__be32 drtm_log_offset;
+	__be32 drtm_log_size;
+} __packed;
+
 static inline const char *cpu_state(u32 flags)
 {
 	switch ((flags & CPU_ID_VERIFY_MASK) >> CPU_ID_VERIFY_SHIFT) {
diff --git a/hdata/tpmrel.c b/hdata/tpmrel.c
index 7ded404..f2e2ec8 100644
--- a/hdata/tpmrel.c
+++ b/hdata/tpmrel.c
@@ -19,11 +19,62 @@ 
 #endif
 
 #include <skiboot.h>
+#include <device.h>
 
 #include "spira.h"
 #include "hdata.h"
 #include "hdif.h"
 
+#define TPM_SRTM_EVENTLOG_MAX_SIZE 0x10000
+
+static void add_tpmrel_tpm_eventlog(const struct HDIF_common_hdr *hdif_hdr)
+{
+	const struct secureboot_tpm_info *stinfo;
+	struct dt_node *xscom, *node;
+	uint64_t addr;
+	bool tpmfound = false;
+	int count, i;
+
+	count = HDIF_get_iarray_size(hdif_hdr, TPMREL_IDATA_SECUREBOOT_TPM_INFO);
+	if (count > 1) {
+		prerror("multinode not supported, count=%d\n",
+			count);
+		return;
+	}
+
+	for (i = 0; i < count; i++) {
+
+		stinfo = HDIF_get_iarray_item(hdif_hdr,
+					      TPMREL_IDATA_SECUREBOOT_TPM_INFO,
+					      i, NULL);
+
+		xscom = find_xscom_for_chip(be32_to_cpu(stinfo->chip_id));
+		if (xscom) {
+			dt_for_each_node(xscom, node) {
+				if (dt_has_node_property(node, "label", "tpm")) {
+					tpmfound=true;
+					addr = (uint64_t) stinfo +
+						be32_to_cpu(stinfo->srtm_log_offset);
+					dt_add_property_u64s(node, "linux,sml-base", addr);
+					dt_add_property_cells(node, "linux,sml-size",
+							      TPM_SRTM_EVENTLOG_MAX_SIZE);
+					break;
+				}
+			}
+			if (!tpmfound &&
+			    stinfo->tpm_status == TPM_PRESENT_AND_FUNCTIONAL) {
+				prerror("TPM functional but not found for chip_id=%d.\n",
+					stinfo->chip_id);
+				continue;
+			}
+		} else {
+			prerror("could not add TPM device, chip_id=%d invalid\n",
+				stinfo->chip_id);
+			continue;
+		}
+	}
+}
+
 void node_stb_parse(void)
 {
 	struct HDIF_common_hdr *hdif_hdr;
@@ -34,7 +85,8 @@  void node_stb_parse(void)
 		return;
 	}
 
-	/* TODO: Idata 0: Secure Boot and TPM Instance Info */
+	add_tpmrel_tpm_eventlog(hdif_hdr);
+
 	/* TODO: Idata 1: User Physical Interaction Mechanism Info */
 	/* TODO: Idata 2: Hash and Verification Function Offset Array */
 }