[Skiboot] [PATCH v2 10/31] libstb: add tpm_chip interface

Claudio Carvalho cclaudio at linux.vnet.ibm.com
Wed Sep 28 18:01:09 AEST 2016


This adds the TPM chip interface for libstb:

- tpm_init(): call drivers' probe to find TPM devices that are
  compatible with them.

- tpm_register_chip(): register a TPM chip which includes pointers to
  the TPM device and TPM driver structures.

- tpm_add_status_property(): add the status device tree property for
  each registered TPM device.

The TPM chip interface is documented in 'libstb/tpm_chip.h' and the tpm device
tree node is documented in 'doc/device-tree/tpm.rst'

Signed-off-by: Claudio Carvalho <cclaudio at linux.vnet.ibm.com>
---
 libstb/Makefile.inc   |   2 +-
 libstb/status_codes.h |  23 ++++++++++
 libstb/tpm_chip.c     | 123 ++++++++++++++++++++++++++++++++++++++++++++++++++
 libstb/tpm_chip.h     |  73 ++++++++++++++++++++++++++++++
 4 files changed, 220 insertions(+), 1 deletion(-)
 create mode 100644 libstb/status_codes.h
 create mode 100644 libstb/tpm_chip.c
 create mode 100644 libstb/tpm_chip.h

diff --git a/libstb/Makefile.inc b/libstb/Makefile.inc
index 3beafba..8b057de 100644
--- a/libstb/Makefile.inc
+++ b/libstb/Makefile.inc
@@ -4,7 +4,7 @@ LIBSTB_DIR = libstb
 
 SUBDIRS += $(LIBSTB_DIR)
 
-LIBSTB_SRCS = container.c rom.c
+LIBSTB_SRCS = container.c rom.c tpm_chip.c
 LIBSTB_OBJS = $(LIBSTB_SRCS:%.c=%.o)
 LIBSTB = $(LIBSTB_DIR)/built-in.o
 
diff --git a/libstb/status_codes.h b/libstb/status_codes.h
new file mode 100644
index 0000000..240cd95
--- /dev/null
+++ b/libstb/status_codes.h
@@ -0,0 +1,23 @@
+/* Copyright 2013-2016 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __STB_STATUS_CODES_H
+#define __STB_STATUS_CODES_H
+
+/*  general return codes */
+#define STB_ERROR		-1
+
+#endif /* __STB_STATUS_CODES_H */
diff --git a/libstb/tpm_chip.c b/libstb/tpm_chip.c
new file mode 100644
index 0000000..72d15b5
--- /dev/null
+++ b/libstb/tpm_chip.c
@@ -0,0 +1,123 @@
+/* Copyright 2013-2016 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <skiboot.h>
+#include <device.h>
+#include <string.h>
+
+#include "status_codes.h"
+#include "container.h"
+#include "tpm_chip.h"
+
+static struct list_head tpm_list = LIST_HEAD_INIT(tpm_list);
+
+int tpm_register_chip(struct dt_node *node, struct tpm_dev *dev,
+		       struct tpm_driver *driver)
+{
+	int i, rc;
+	struct tpm_chip *tpm;
+
+	i = 0;
+	list_for_each(&tpm_list, tpm, link) {
+		if (tpm->node == node) {
+			/**
+			 * @fwts-label TPMAlreadyRegistered
+			 * @fwts-advice TPM node already registered. The same
+			 * node is being registered twice or there is a
+			 * tpm node duplicate in the device tree
+			 */
+			prlog(PR_WARNING, "TPM: tpm%d already registered\n",
+			      tpm->id);
+			return STB_ERROR;
+		}
+		i++;
+	}
+
+	tpm = (struct tpm_chip*) malloc(sizeof(struct tpm_chip));
+	assert(tpm);
+	tpm->id = i;
+
+	tpm->enabled = true;
+	tpm->node = node;
+	tpm->dev = dev;
+	tpm->driver = driver;
+
+	list_add_tail(&tpm_list, &tpm->link);
+
+	prlog(PR_NOTICE, "TPM: tpm%d registered: driver=%s\n",
+	      tpm->id, tpm->driver->name);
+
+	return 0;
+
+disable:
+	dt_add_property_string(node, "status", "disabled");
+	prlog(PR_NOTICE, "TPM: tpm node %p disabled\n", node);
+	free(tpm);
+	return STB_ERROR;
+}
+
+void tpm_init(void)
+{
+	if (!list_empty(&tpm_list)) {
+		/**
+		 * @fwts-label TPMAlreadyInitialized
+		 * @fwts-advice TPM already initialized. Check if tpm is being
+		 * initialized more than once.
+		 */
+		prlog(PR_WARNING, "TPM: tpm device(s) already initialized\n");
+		return;
+	}
+
+	list_head_init(&tpm_list);
+
+	/* tpm drivers supported */
+
+	if (list_empty(&tpm_list))
+		/**
+		 * @fwts-label TPMNotInitialized
+		 * @fwts-advice No TPM chip has been initialized. We may not
+		 * have a compatible tpm driver or there is no tpm node in the
+		 * device tree with the expected bindings.
+		 */
+		prlog(PR_ERR, "TPM: no tpm chip has been initialized\n");
+
+}
+
+void tpm_cleanup(void)
+{
+	struct tpm_chip *tpm = NULL;
+
+	tpm = list_pop(&tpm_list, struct tpm_chip, link);
+
+	while (tpm) {
+		/* deallocate memory */
+		if (tpm->dev)
+			free(tpm->dev);
+		tpm->driver = NULL;
+		free(tpm);
+		tpm = list_pop(&tpm_list, struct tpm_chip, link);
+	}
+
+	list_head_init(&tpm_list);
+}
+
+void tpm_add_status_property(void) {
+	struct tpm_chip *tpm;
+	list_for_each(&tpm_list, tpm, link) {
+		dt_add_property_string(tpm->node, "status",
+				       tpm->enabled ? "okay" : "disabled");
+	}
+}
diff --git a/libstb/tpm_chip.h b/libstb/tpm_chip.h
new file mode 100644
index 0000000..70f5c97
--- /dev/null
+++ b/libstb/tpm_chip.h
@@ -0,0 +1,73 @@
+/* Copyright 2013-2016 IBM Corp.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TPM_H
+#define __TPM_H
+
+#include <device.h>
+
+struct tpm_dev {
+
+	/* TPM bus id */
+	int bus_id;
+
+	/* TPM address in the bus */
+	int xscom_base;
+};
+
+struct tpm_driver {
+
+	/* Driver name */
+	const char* name;
+
+	/* Transmit the TPM command stored in buf to the tpm device */
+	int (*transmit)(struct tpm_dev *dev, uint8_t* buf, size_t cmdlen,
+			size_t *buflen);
+};
+
+struct tpm_chip {
+
+	/* TPM chip id */
+	int id;
+
+	/* Indicates whether or not the device and log are functional */
+	bool enabled;
+
+	/* TPM device tree node */
+	struct dt_node *node;
+
+	/* TPM device handler */
+	struct tpm_dev    *dev;
+
+	/* TPM driver handler */
+	struct tpm_driver *driver;
+
+	struct list_node link;
+};
+
+/*
+ * Register a tpm chip by binding the driver to dev.
+ */
+extern int tpm_register_chip(struct dt_node *node, struct tpm_dev *dev,
+			     struct tpm_driver *driver);
+
+/* Add status property to the TPM devices */
+extern void tpm_add_status_property(void);
+
+extern void tpm_init(void);
+extern void tpm_cleanup(void);
+
+#endif /* __TPM_H */
-- 
1.9.1



More information about the Skiboot mailing list