Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107084513
D45069.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
35 KB
Referenced Files
None
Subscribers
None
D45069.diff
View Options
diff --git a/sys/conf/files b/sys/conf/files
--- a/sys/conf/files
+++ b/sys/conf/files
@@ -3194,6 +3194,13 @@
dev/tcp_log/tcp_log_dev.c optional tcp_blackbox inet | tcp_blackbox inet6
dev/tdfx/tdfx_pci.c optional tdfx pci
dev/ti/if_ti.c optional ti pci
+dev/tpm/tpm20.c optional tpm
+dev/tpm/tpm_bus.c optional tpm acpi
+dev/tpm/tpm_if.m optional tpm
+dev/tpm/tpm_spibus.c optional tpm spibus fdt
+dev/tpm/tpm_tis_acpi.c optional tpm acpi
+dev/tpm/tpm_tis_core.c optional tpm
+dev/tpm/tpm_tis_spibus.c optional tpm spibus fdt
dev/tws/tws.c optional tws
dev/tws/tws_cam.c optional tws
dev/tws/tws_hdm.c optional tws
diff --git a/sys/conf/files.amd64 b/sys/conf/files.amd64
--- a/sys/conf/files.amd64
+++ b/sys/conf/files.amd64
@@ -372,9 +372,7 @@
dev/smartpqi/smartpqi_tag.c optional smartpqi
dev/sume/if_sume.c optional sume
dev/syscons/apm/apm_saver.c optional apm_saver apm
-dev/tpm/tpm20.c optional tpm
dev/tpm/tpm_crb.c optional tpm acpi
-dev/tpm/tpm_tis.c optional tpm acpi
dev/tpm/tpm_acpi.c optional tpm acpi
dev/tpm/tpm_isa.c optional tpm isa
dev/p2sb/p2sb.c optional p2sb pci
diff --git a/sys/dev/tpm/tpm20.h b/sys/dev/tpm/tpm20.h
--- a/sys/dev/tpm/tpm20.h
+++ b/sys/dev/tpm/tpm20.h
@@ -28,6 +28,7 @@
#ifndef _TPM20_H_
#define _TPM20_H_
+#include "opt_acpi.h"
#include <sys/cdefs.h>
#include <sys/endian.h>
#include <sys/param.h>
@@ -39,6 +40,7 @@
#include <sys/bus.h>
#include <sys/callout.h>
#include <sys/conf.h>
+#include <sys/lock.h>
#include <sys/module.h>
#include <sys/rman.h>
#include <sys/sx.h>
@@ -49,12 +51,14 @@
#include <machine/md_var.h>
#include <machine/resource.h>
+#ifdef DEV_ACPI
#include <contrib/dev/acpica/include/acpi.h>
#include <contrib/dev/acpica/include/accommon.h>
#include <dev/acpica/acpivar.h>
-#include "opt_acpi.h"
+#endif
#include "opt_tpm.h"
+#include "tpm_if.h"
#define BIT(x) (1 << (x))
@@ -136,55 +140,36 @@
int tpm20_init(struct tpm_sc *sc);
void tpm20_release(struct tpm_sc *sc);
-/* Small helper routines for io ops */
-static inline uint8_t
-RD1(struct tpm_sc *sc, bus_size_t off)
-{
-
- return (bus_read_1(sc->mem_res, off));
-}
-static inline uint32_t
-RD4(struct tpm_sc *sc, bus_size_t off)
-{
-
- return (bus_read_4(sc->mem_res, off));
-}
-#ifdef __amd64__
-static inline uint64_t
-RD8(struct tpm_sc *sc, bus_size_t off)
-{
+/* Mode driver types */
+DECLARE_CLASS(tpmtis_driver);
+int tpmtis_attach(device_t dev);
- return (bus_read_8(sc->mem_res, off));
-}
-#endif
-static inline void
-WR1(struct tpm_sc *sc, bus_size_t off, uint8_t val)
-{
+DECLARE_CLASS(tpmcrb_driver);
- bus_write_1(sc->mem_res, off, val);
-}
-static inline void
-WR4(struct tpm_sc *sc, bus_size_t off, uint32_t val)
-{
+/* Bus driver types */
+DECLARE_CLASS(tpm_bus_driver);
+DECLARE_CLASS(tpm_spi_driver);
- bus_write_4(sc->mem_res, off, val);
-}
+/* Small helper routines for io ops */
static inline void
AND4(struct tpm_sc *sc, bus_size_t off, uint32_t val)
{
+ uint32_t v = TPM_READ_4(sc->dev, off);
- WR4(sc, off, RD4(sc, off) & val);
+ TPM_WRITE_4(sc->dev, off, v & val);
}
static inline void
OR1(struct tpm_sc *sc, bus_size_t off, uint8_t val)
{
+ uint8_t v = TPM_READ_1(sc->dev, off);
- WR1(sc, off, RD1(sc, off) | val);
+ TPM_WRITE_1(sc->dev, off, v | val);
}
static inline void
OR4(struct tpm_sc *sc, bus_size_t off, uint32_t val)
{
+ uint32_t v = TPM_READ_1(sc->dev, off);
- WR4(sc, off, RD4(sc, off) | val);
+ TPM_WRITE_4(sc->dev, off, v | val);
}
#endif /* _TPM20_H_ */
diff --git a/sys/dev/tpm/tpm20.c b/sys/dev/tpm/tpm20.c
--- a/sys/dev/tpm/tpm20.c
+++ b/sys/dev/tpm/tpm20.c
@@ -127,7 +127,7 @@
return (result);
}
- result = sc->transmit(sc, byte_count);
+ result = TPM_TRANSMIT(sc->dev, byte_count);
if (result == 0) {
callout_reset(&sc->discard_buffer_callout,
@@ -267,7 +267,7 @@
cv_wait(&sc->buf_cv, &sc->dev_lock);
memcpy(sc->buf, cmd, sizeof(cmd));
- result = sc->transmit(sc, sizeof(cmd));
+ result = TPM_TRANSMIT(sc->dev, sizeof(cmd));
if (result != 0) {
sx_xunlock(&sc->dev_lock);
return;
@@ -319,7 +319,7 @@
sx_xlock(&sc->dev_lock);
memcpy(sc->buf, save_cmd, sizeof(save_cmd));
- sc->transmit(sc, sizeof(save_cmd));
+ TPM_TRANSMIT(sc->dev, sizeof(save_cmd));
sx_xunlock(&sc->dev_lock);
diff --git a/sys/dev/tpm/tpm_bus.c b/sys/dev/tpm/tpm_bus.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/tpm/tpm_bus.c
@@ -0,0 +1,99 @@
+/*-
+ * Copyright (c) 2023 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/bus.h>
+#include "tpm_if.h"
+#include "tpm20.h"
+
+/* Override accessors */
+static uint8_t
+tpm_read_1(device_t dev, bus_size_t off)
+{
+ struct tpm_sc *sc = device_get_softc(dev);
+
+ return (bus_read_1(sc->mem_res, off));
+}
+
+static uint32_t
+tpm_read_4(device_t dev, bus_size_t off)
+{
+ struct tpm_sc *sc = device_get_softc(dev);
+
+ return (bus_read_4(sc->mem_res, off));
+}
+
+/*
+ * Only i386 is missing bus_space_read_8.
+ */
+#ifndef __i386__
+static uint64_t
+tpm_read_8(device_t dev, bus_size_t off)
+{
+ struct tpm_sc *sc = device_get_softc(dev);
+
+ return (bus_read_8(sc->mem_res, off));
+}
+#endif
+
+static void
+tpm_write_1(device_t dev, bus_size_t off, uint8_t val)
+{
+ struct tpm_sc *sc = device_get_softc(dev);
+
+ bus_write_1(sc->mem_res, off, val);
+}
+
+static void
+tpm_write_4(device_t dev, bus_size_t off, uint32_t val)
+{
+ struct tpm_sc *sc = device_get_softc(dev);
+
+ bus_write_4(sc->mem_res, off, val);
+}
+
+static void
+tpm_write_barrier(device_t dev, bus_addr_t off, bus_size_t length)
+{
+ struct tpm_sc *sc = device_get_softc(dev);
+
+ bus_barrier(sc->mem_res, off, length, BUS_SPACE_BARRIER_WRITE);
+}
+
+static device_method_t tpm_bus_methods[] = {
+ DEVMETHOD(tpm_read_1, tpm_read_1),
+ DEVMETHOD(tpm_read_4, tpm_read_4),
+#ifndef __i386__
+ DEVMETHOD(tpm_read_8, tpm_read_8),
+#endif
+ DEVMETHOD(tpm_write_1, tpm_write_1),
+ DEVMETHOD(tpm_write_4, tpm_write_4),
+ DEVMETHOD(tpm_write_barrier, tpm_write_barrier),
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_0(tpm_lbc, tpm_bus_driver, tpm_bus_methods, sizeof(struct tpm_sc));
diff --git a/sys/dev/tpm/tpm_crb.c b/sys/dev/tpm/tpm_crb.c
--- a/sys/dev/tpm/tpm_crb.c
+++ b/sys/dev/tpm/tpm_crb.c
@@ -83,7 +83,7 @@
size_t rsp_buf_size;
};
-int tpmcrb_transmit(struct tpm_sc *sc, size_t size);
+int tpmcrb_transmit(device_t dev, size_t size);
static int tpmcrb_acpi_probe(device_t dev);
static int tpmcrb_attach(device_t dev);
@@ -185,15 +185,15 @@
* stored in a single 8 byte one.
*/
#ifdef __amd64__
- crb_sc->rsp_off = RD8(sc, TPM_CRB_CTRL_RSP_ADDR);
+ crb_sc->rsp_off = TPM_READ_8(sc->dev, TPM_CRB_CTRL_RSP_ADDR);
#else
- crb_sc->rsp_off = RD4(sc, TPM_CRB_CTRL_RSP_ADDR);
- crb_sc->rsp_off |= ((uint64_t) RD4(sc, TPM_CRB_CTRL_RSP_HADDR) << 32);
+ crb_sc->rsp_off = TPM_READ_4(sc->dev, TPM_CRB_CTRL_RSP_ADDR);
+ crb_sc->rsp_off |= ((uint64_t) TPM_READ_4(sc->dev, TPM_CRB_CTRL_RSP_HADDR) << 32);
#endif
- crb_sc->cmd_off = RD4(sc, TPM_CRB_CTRL_CMD_LADDR);
- crb_sc->cmd_off |= ((uint64_t) RD4(sc, TPM_CRB_CTRL_CMD_HADDR) << 32);
- crb_sc->cmd_buf_size = RD4(sc, TPM_CRB_CTRL_CMD_SIZE);
- crb_sc->rsp_buf_size = RD4(sc, TPM_CRB_CTRL_RSP_SIZE);
+ crb_sc->cmd_off = TPM_READ_4(sc->dev, TPM_CRB_CTRL_CMD_LADDR);
+ crb_sc->cmd_off |= ((uint64_t) TPM_READ_4(sc->dev, TPM_CRB_CTRL_CMD_HADDR) << 32);
+ crb_sc->cmd_buf_size = TPM_READ_4(sc->dev, TPM_CRB_CTRL_CMD_SIZE);
+ crb_sc->rsp_buf_size = TPM_READ_4(sc->dev, TPM_CRB_CTRL_RSP_SIZE);
tpmcrb_relinquish_locality(sc);
@@ -218,8 +218,6 @@
}
}
- sc->transmit = tpmcrb_transmit;
-
result = tpm20_init(sc);
if (result != 0)
tpmcrb_detach(dev);
@@ -248,11 +246,11 @@
{
/* Check for condition */
- if ((RD4(sc, off) & mask) == val)
+ if ((TPM_READ_4(sc->dev, off) & mask) == val)
return (true);
while (timeout > 0) {
- if ((RD4(sc, off) & mask) == val)
+ if ((TPM_READ_4(sc->dev, off) & mask) == val)
return (true);
pause("TPM in polling mode", 1);
@@ -291,7 +289,7 @@
{
uint32_t mask = ~0;
- WR4(sc, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CMD);
+ TPM_WRITE_4(sc->dev, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CMD);
if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_START,
mask, ~mask, TPM_TIMEOUT_B)) {
device_printf(sc->dev,
@@ -299,48 +297,50 @@
return (false);
}
- WR4(sc, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CLEAR);
+ TPM_WRITE_4(sc->dev, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CLEAR);
return (true);
}
int
-tpmcrb_transmit(struct tpm_sc *sc, size_t length)
+tpmcrb_transmit(device_t dev, size_t length)
{
struct tpmcrb_sc *crb_sc;
+ struct tpm_sc *sc;
uint32_t mask, curr_cmd;
int timeout, bytes_available;
- crb_sc = (struct tpmcrb_sc *)sc;
+ crb_sc = device_get_softc(dev);
+ sc = &crb_sc->base;
sx_assert(&sc->dev_lock, SA_XLOCKED);
if (length > crb_sc->cmd_buf_size) {
- device_printf(sc->dev,
+ device_printf(dev,
"Requested transfer is bigger than buffer size\n");
return (E2BIG);
}
- if (RD4(sc, TPM_CRB_CTRL_STS) & TPM_CRB_CTRL_STS_ERR_BIT) {
- device_printf(sc->dev,
+ if (TPM_READ_4(dev, TPM_CRB_CTRL_STS) & TPM_CRB_CTRL_STS_ERR_BIT) {
+ device_printf(dev,
"Device has Error bit set\n");
return (EIO);
}
if (!tpmcrb_request_locality(sc, 0)) {
- device_printf(sc->dev,
+ device_printf(dev,
"Failed to obtain locality\n");
return (EIO);
}
/* Clear cancellation bit */
- WR4(sc, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CLEAR);
+ TPM_WRITE_4(dev, TPM_CRB_CTRL_CANCEL, TPM_CRB_CTRL_CANCEL_CLEAR);
/* Switch device to idle state if necessary */
- if (!(RD4(sc, TPM_CRB_CTRL_STS) & TPM_CRB_CTRL_STS_IDLE_BIT)) {
+ 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)) {
- device_printf(sc->dev,
+ device_printf(dev,
"Failed to transition to idle state\n");
return (EIO);
}
@@ -351,7 +351,7 @@
mask = TPM_CRB_CTRL_REQ_GO_READY;
if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_STS,
mask, !mask, TPM_TIMEOUT_C)) {
- device_printf(sc->dev,
+ device_printf(dev,
"Failed to transition to ready state\n");
return (EIO);
}
@@ -366,16 +366,14 @@
/* Send command and tell device to process it. */
bus_write_region_stream_1(sc->mem_res, crb_sc->cmd_off,
sc->buf, length);
- bus_barrier(sc->mem_res, crb_sc->cmd_off,
- length, BUS_SPACE_BARRIER_WRITE);
+ TPM_WRITE_BARRIER(dev, crb_sc->cmd_off, length);
- WR4(sc, TPM_CRB_CTRL_START, TPM_CRB_CTRL_START_CMD);
- bus_barrier(sc->mem_res, TPM_CRB_CTRL_START,
- 4, BUS_SPACE_BARRIER_WRITE);
+ TPM_WRITE_4(dev, TPM_CRB_CTRL_START, TPM_CRB_CTRL_START_CMD);
+ TPM_WRITE_BARRIER(dev, TPM_CRB_CTRL_START, 4);
mask = ~0;
if (!tpm_wait_for_u32(sc, TPM_CRB_CTRL_START, mask, ~mask, timeout)) {
- device_printf(sc->dev,
+ device_printf(dev,
"Timeout while waiting for device to process cmd\n");
if (!tpmcrb_cancel_cmd(sc))
return (EIO);
@@ -387,7 +385,7 @@
bytes_available = be32toh(*(uint32_t *) (&sc->buf[2]));
if (bytes_available > TPM_BUFSIZE || bytes_available < TPM_HEADER_SIZE) {
- device_printf(sc->dev,
+ device_printf(dev,
"Incorrect response size: %d\n",
bytes_available);
return (EIO);
@@ -411,11 +409,11 @@
DEVMETHOD(device_detach, tpmcrb_detach),
DEVMETHOD(device_shutdown, tpm20_shutdown),
DEVMETHOD(device_suspend, tpm20_suspend),
+ DEVMETHOD(tpm_transmit, tpmcrb_transmit),
{0, 0}
};
-static driver_t tpmcrb_driver = {
- "tpmcrb", tpmcrb_methods, sizeof(struct tpmcrb_sc),
-};
+DEFINE_CLASS_1(tpmcrb, tpmcrb_driver, tpmcrb_methods, sizeof(struct tpmcrb_sc),
+ tpm_bus_driver);
DRIVER_MODULE(tpmcrb, acpi, tpmcrb_driver, 0, 0);
diff --git a/sys/dev/tpm/tpm_if.m b/sys/dev/tpm/tpm_if.m
new file mode 100644
--- /dev/null
+++ b/sys/dev/tpm/tpm_if.m
@@ -0,0 +1,76 @@
+#-
+# Copyright (c) 2023 Juniper Networks, Inc.
+# All Rights Reserved
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions
+# are met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in the
+# documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+#
+
+#include <sys/bus.h>
+#include <dev/tpm/tpm20.h>
+
+INTERFACE tpm;
+
+#
+# Transfer data to the TPM data buffer
+#
+METHOD int transmit {
+ device_t dev;
+ size_t length;
+};
+
+
+METHOD uint64_t read_8 {
+ device_t dev;
+ bus_addr_t addr;
+}
+
+#
+# Read 4 bytes (host endian) from a TPM register
+#
+METHOD uint32_t read_4 {
+ device_t dev;
+ bus_addr_t addr;
+};
+
+METHOD uint8_t read_1 {
+ device_t dev;
+ bus_addr_t addr;
+};
+
+METHOD void write_4 {
+ device_t dev;
+ bus_addr_t addr;
+ uint32_t value;
+};
+
+METHOD void write_1 {
+ device_t dev;
+ bus_addr_t addr;
+ uint8_t value;
+};
+
+METHOD void write_barrier {
+ device_t dev;
+ bus_addr_t off;
+ bus_size_t length;
+}
diff --git a/sys/dev/tpm/tpm_spibus.c b/sys/dev/tpm/tpm_spibus.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/tpm/tpm_spibus.c
@@ -0,0 +1,166 @@
+/*-
+ * Copyright (c) 2023 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include <sys/types.h>
+#include <sys/bus.h>
+
+#include <dev/spibus/spi.h>
+#include "spibus_if.h"
+#include "tpm_if.h"
+#include "tpm20.h"
+
+#define TPM_BASE_ADDR 0xD40000
+#define TPM_SPI_HEADER_SIZE 4
+#define TPM_WAIT_STATES 50
+
+static void
+tpm_insert_wait(device_t dev)
+{
+ device_t parent = device_get_parent(dev);
+ int wait = TPM_WAIT_STATES;
+ struct spi_command spic = SPI_COMMAND_INITIALIZER;
+
+ uint8_t txb = 0;
+ uint8_t rxb = 0;
+
+ spic.tx_cmd = &txb;
+ spic.rx_cmd = &rxb;
+ spic.tx_cmd_sz = 1;
+ spic.rx_cmd_sz = 1;
+ spic.flags = SPI_FLAG_KEEP_CS;
+ do {
+ SPIBUS_TRANSFER(parent, dev, &spic);
+ } while (--wait > 0 && (rxb & 0x1) == 0);
+}
+
+static inline int
+tpm_spi_read_n(device_t dev, bus_size_t off, void *buf, size_t size)
+{
+ struct spi_command spic = SPI_COMMAND_INITIALIZER;
+ uint8_t tx[4] = {0};
+ uint8_t rx[4] = {0};
+ int err;
+
+ if (size > sizeof(rx))
+ return (EINVAL);
+ off += TPM_BASE_ADDR;
+ tx[0] = 0x80 | (size - 1); /* Write (size) bytes */
+ tx[1] = (off >> 16) & 0xff;
+ tx[2] = (off >> 8) & 0xff;
+ tx[3] = off & 0xff;
+
+ spic.tx_cmd = tx;
+ spic.tx_cmd_sz = sizeof(tx);
+ spic.rx_cmd = rx;
+ spic.rx_cmd_sz = sizeof(tx);
+ spic.flags = SPI_FLAG_KEEP_CS;
+
+ err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &spic);
+
+ if (!(rx[3] & 0x1)) {
+ tpm_insert_wait(dev);
+ }
+ memset(tx, 0, sizeof(tx));
+ spic.tx_cmd_sz = spic.rx_cmd_sz = size;
+ spic.flags = 0;
+ err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &spic);
+ memcpy(buf, &rx[0], size);
+
+ return (err);
+}
+
+static inline int
+tpm_spi_write_n(device_t dev, bus_size_t off, void *buf, size_t size)
+{
+ struct spi_command spic = SPI_COMMAND_INITIALIZER;
+ uint8_t tx[8] = {0};
+ uint8_t rx[8] = {0};
+ int err;
+
+ off += TPM_BASE_ADDR;
+ tx[0] = 0x00 | (size - 1); /* Write (size) bytes */
+ tx[1] = (off >> 16) & 0xff;
+ tx[2] = (off >> 8) & 0xff;
+ tx[3] = off & 0xff;
+
+ memcpy(&tx[4], buf, size);
+
+ spic.tx_cmd = tx;
+ spic.tx_cmd_sz = size + TPM_SPI_HEADER_SIZE;
+ spic.rx_cmd = rx;
+ spic.rx_cmd_sz = size + TPM_SPI_HEADER_SIZE;
+
+ err = SPIBUS_TRANSFER(device_get_parent(dev), dev, &spic);
+
+ return (err);
+}
+
+/* Override accessors */
+static inline uint8_t
+spi_read_1(device_t dev, bus_size_t off)
+{
+ uint8_t rx_byte;
+
+ tpm_spi_read_n(dev, off, &rx_byte, 1);
+
+ return (rx_byte);
+}
+
+static inline uint32_t
+spi_read_4(device_t dev, bus_size_t off)
+{
+ uint32_t rx_word = 0;
+
+ tpm_spi_read_n(dev, off, &rx_word, 4);
+ rx_word = le32toh(rx_word);
+
+ return (rx_word);
+}
+
+static inline void
+spi_write_1(device_t dev, bus_size_t off, uint8_t val)
+{
+ tpm_spi_write_n(dev, off, &val, 1);
+}
+
+static inline void
+spi_write_4(device_t dev, bus_size_t off, uint32_t val)
+{
+ uint32_t tmp = htole32(val);
+ tpm_spi_write_n(dev, off, &tmp, 4);
+}
+
+static device_method_t tpm_spibus_methods[] = {
+ DEVMETHOD(tpm_read_4, spi_read_4),
+ DEVMETHOD(tpm_read_1, spi_read_1),
+ DEVMETHOD(tpm_write_4, spi_write_4),
+ DEVMETHOD(tpm_write_1, spi_write_1),
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_0(tpm_spi, tpm_spi_driver, tpm_spibus_methods,
+ sizeof(struct tpm_sc));
diff --git a/sys/dev/tpm/tpm_tis_acpi.c b/sys/dev/tpm/tpm_tis_acpi.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/tpm/tpm_tis_acpi.c
@@ -0,0 +1,86 @@
+/*-
+ * Copyright (c) 2018 Stormshield.
+ * Copyright (c) 2018 Semihalf.
+ * Copyright (c) 2023 Juniper Networks, Inc.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include <sys/cdefs.h>
+#include "tpm20.h"
+#include "tpm_if.h"
+
+static int tpmtis_acpi_probe(device_t dev);
+
+char *tpmtis_ids[] = {"MSFT0101", NULL};
+
+static int
+tpmtis_acpi_probe(device_t dev)
+{
+ int err;
+ ACPI_TABLE_TPM23 *tbl;
+ ACPI_STATUS status;
+
+ err = ACPI_ID_PROBE(device_get_parent(dev), dev, tpmtis_ids, NULL);
+ if (err > 0)
+ return (err);
+ /*Find TPM2 Header*/
+ status = AcpiGetTable(ACPI_SIG_TPM2, 1, (ACPI_TABLE_HEADER **) &tbl);
+ if(ACPI_FAILURE(status) ||
+ tbl->StartMethod != TPM2_START_METHOD_TIS)
+ err = ENXIO;
+
+ device_set_desc(dev, "Trusted Platform Module 2.0, FIFO mode");
+ return (err);
+}
+
+static int
+tpmtis_acpi_attach(device_t dev)
+{
+ struct tpm_sc *sc = device_get_softc(dev);
+
+ sc->mem_rid = 0;
+ sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
+ RF_ACTIVE);
+ if (sc->mem_res == NULL) {
+ return (ENXIO);
+ }
+
+ /*
+ * If tpmtis_attach() fails, tpmtis_detach() will automatically free
+ * sc->mem_res (not-NULL).
+ */
+ return (tpmtis_attach(dev));
+}
+
+/* ACPI Driver */
+static device_method_t tpmtis_methods[] = {
+ DEVMETHOD(device_attach, tpmtis_acpi_attach),
+ DEVMETHOD(device_probe, tpmtis_acpi_probe),
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_2(tpmtis, tpmtis_acpi_driver, tpmtis_methods,
+ sizeof(struct tpm_sc), tpmtis_driver, tpm_bus_driver);
+
+DRIVER_MODULE(tpmtis, acpi, tpmtis_driver, 0, 0);
diff --git a/sys/dev/tpm/tpm_tis.c b/sys/dev/tpm/tpm_tis_core.c
rename from sys/dev/tpm/tpm_tis.c
rename to sys/dev/tpm/tpm_tis_core.c
--- a/sys/dev/tpm/tpm_tis.c
+++ b/sys/dev/tpm/tpm_tis_core.c
@@ -27,6 +27,7 @@
#include <sys/cdefs.h>
#include "tpm20.h"
+#include "tpm_if.h"
/*
* TIS register space as defined in
@@ -72,10 +73,8 @@
#define TPM_STS_BURST_MASK 0xFFFF00
#define TPM_STS_BURST_OFFSET 0x8
-static int tpmtis_transmit(struct tpm_sc *sc, size_t length);
+static int tpmtis_transmit(device_t dev, size_t length);
-static int tpmtis_acpi_probe(device_t dev);
-static int tpmtis_attach(device_t dev);
static int tpmtis_detach(device_t dev);
static void tpmtis_intr_handler(void *arg);
@@ -93,29 +92,7 @@
static uint16_t tpmtis_wait_for_burst(struct tpm_sc *sc);
-char *tpmtis_ids[] = {"MSFT0101", NULL};
-
-static int
-tpmtis_acpi_probe(device_t dev)
-{
- int err;
- ACPI_TABLE_TPM23 *tbl;
- ACPI_STATUS status;
-
- err = ACPI_ID_PROBE(device_get_parent(dev), dev, tpmtis_ids, NULL);
- if (err > 0)
- return (err);
- /*Find TPM2 Header*/
- status = AcpiGetTable(ACPI_SIG_TPM2, 1, (ACPI_TABLE_HEADER **) &tbl);
- if(ACPI_FAILURE(status) ||
- tbl->StartMethod != TPM2_START_METHOD_TIS)
- err = ENXIO;
-
- device_set_desc(dev, "Trusted Platform Module 2.0, FIFO mode");
- return (err);
-}
-
-static int
+int
tpmtis_attach(device_t dev)
{
struct tpm_sc *sc;
@@ -123,20 +100,11 @@
sc = device_get_softc(dev);
sc->dev = dev;
- sc->transmit = tpmtis_transmit;
sc->intr_type = -1;
sx_init(&sc->dev_lock, "TPM driver lock");
sc->buf = malloc(TPM_BUFSIZE, M_TPM20, M_WAITOK);
- sc->mem_rid = 0;
- sc->mem_res = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid,
- RF_ACTIVE);
- if (sc->mem_res == NULL) {
- tpmtis_detach(dev);
- return (ENXIO);
- }
-
sc->irq_rid = 0;
sc->irq_res = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid,
RF_ACTIVE | RF_SHAREABLE);
@@ -198,7 +166,7 @@
sx_xlock(&sc->dev_lock);
memcpy(sc->buf, cmd, sizeof(cmd));
- tpmtis_transmit(sc, sizeof(cmd));
+ tpmtis_transmit(sc->dev, sizeof(cmd));
sc->pending_data_length = 0;
sx_xunlock(&sc->dev_lock);
}
@@ -222,19 +190,19 @@
if(!tpmtis_request_locality(sc, 0))
sc->interrupts = false;
- WR1(sc, TPM_INT_VECTOR, irq);
+ TPM_WRITE_1(sc->dev, TPM_INT_VECTOR, irq);
/* Clear all pending interrupts. */
- reg = RD4(sc, TPM_INT_STS);
- WR4(sc, TPM_INT_STS, reg);
+ reg = TPM_READ_4(sc->dev, TPM_INT_STS);
+ TPM_WRITE_4(sc->dev, TPM_INT_STS, reg);
- reg = RD4(sc, TPM_INT_ENABLE);
+ reg = TPM_READ_4(sc->dev, TPM_INT_ENABLE);
reg |= TPM_INT_ENABLE_GLOBAL_ENABLE |
TPM_INT_ENABLE_DATA_AVAIL |
TPM_INT_ENABLE_LOC_CHANGE |
TPM_INT_ENABLE_CMD_RDY |
TPM_INT_ENABLE_STS_VALID;
- WR4(sc, TPM_INT_ENABLE, reg);
+ TPM_WRITE_4(sc->dev, TPM_INT_ENABLE, reg);
tpmtis_relinquish_locality(sc);
tpmtis_test_intr(sc);
@@ -247,9 +215,9 @@
uint32_t status;
sc = (struct tpm_sc *)arg;
- status = RD4(sc, TPM_INT_STS);
+ status = TPM_READ_4(sc->dev, TPM_INT_STS);
- WR4(sc, TPM_INT_STS, status);
+ TPM_WRITE_4(sc->dev, TPM_INT_STS, status);
/* Check for stray interrupts. */
if (sc->intr_type == -1 || (sc->intr_type & status) == 0)
@@ -265,7 +233,7 @@
{
/* Check for condition */
- if ((RD4(sc, off) & mask) == val)
+ if ((TPM_READ_4(sc->dev, off) & mask) == val)
return (true);
/* If interrupts are enabled sleep for timeout duration */
@@ -273,12 +241,12 @@
tsleep(sc, PWAIT, "TPM WITH INTERRUPTS", timeout / tick);
sc->intr_type = -1;
- return ((RD4(sc, off) & mask) == val);
+ return ((TPM_READ_4(sc->dev, off) & mask) == val);
}
/* If we don't have interrupts poll the device every tick */
while (timeout > 0) {
- if ((RD4(sc, off) & mask) == val)
+ if ((TPM_READ_4(sc->dev, off) & mask) == val)
return (true);
pause("TPM POLLING", 1);
@@ -296,7 +264,7 @@
timeout = TPM_TIMEOUT_A;
while (timeout-- > 0) {
- burst_count = (RD4(sc, TPM_STS) & TPM_STS_BURST_MASK) >>
+ burst_count = (TPM_READ_4(sc->dev, TPM_STS) & TPM_STS_BURST_MASK) >>
TPM_STS_BURST_OFFSET;
if (burst_count > 0)
break;
@@ -320,7 +288,7 @@
count -= burst_count;
while (burst_count-- > 0)
- *buf++ = RD1(sc, TPM_DATA_FIFO);
+ *buf++ = TPM_READ_1(sc->dev, TPM_DATA_FIFO);
}
return (true);
@@ -340,7 +308,7 @@
count -= burst_count;
while (burst_count-- > 0)
- WR1(sc, TPM_DATA_FIFO, *buf++);
+ TPM_WRITE_1(sc->dev, TPM_DATA_FIFO, *buf++);
}
return (true);
@@ -360,14 +328,14 @@
timeout = TPM_TIMEOUT_A;
sc->intr_type = TPM_INT_STS_LOC_CHANGE;
- WR1(sc, TPM_ACCESS, TPM_ACCESS_LOC_REQ);
- bus_barrier(sc->mem_res, TPM_ACCESS, 1, BUS_SPACE_BARRIER_WRITE);
+ TPM_WRITE_1(sc->dev, TPM_ACCESS, TPM_ACCESS_LOC_REQ);
+ TPM_WRITE_BARRIER(sc->dev, TPM_ACCESS, 1);
if(sc->interrupts) {
tsleep(sc, PWAIT, "TPMLOCREQUEST with INTR", timeout / tick);
- return ((RD1(sc, TPM_ACCESS) & mask) == mask);
+ return ((TPM_READ_1(sc->dev, TPM_ACCESS) & mask) == mask);
} else {
while(timeout > 0) {
- if ((RD1(sc, TPM_ACCESS) & mask) == mask)
+ if ((TPM_READ_1(sc->dev, TPM_ACCESS) & mask) == mask)
return (true);
pause("TPMLOCREQUEST POLLING", 1);
@@ -387,7 +355,7 @@
* Clear them now in case interrupt handler didn't make it in time.
*/
if(sc->interrupts)
- AND4(sc, TPM_INT_STS, RD4(sc, TPM_INT_STS));
+ AND4(sc, TPM_INT_STS, TPM_READ_4(sc->dev, TPM_INT_STS));
OR1(sc, TPM_ACCESS, TPM_ACCESS_LOC_RELINQUISH);
}
@@ -400,8 +368,8 @@
mask = TPM_STS_CMD_RDY;
sc->intr_type = TPM_INT_STS_CMD_RDY;
- WR4(sc, TPM_STS, TPM_STS_CMD_RDY);
- bus_barrier(sc->mem_res, TPM_STS, 4, BUS_SPACE_BARRIER_WRITE);
+ TPM_WRITE_4(sc->dev, TPM_STS, TPM_STS_CMD_RDY);
+ TPM_WRITE_BARRIER(sc->dev, TPM_STS, 4);
if (!tpm_wait_for_u32(sc, TPM_STS, mask, mask, TPM_TIMEOUT_B))
return (false);
@@ -409,26 +377,28 @@
}
static int
-tpmtis_transmit(struct tpm_sc *sc, size_t length)
+tpmtis_transmit(device_t dev, size_t length)
{
+ struct tpm_sc *sc;
size_t bytes_available;
uint32_t mask, curr_cmd;
int timeout;
+ sc = device_get_softc(dev);
sx_assert(&sc->dev_lock, SA_XLOCKED);
if (!tpmtis_request_locality(sc, 0)) {
- device_printf(sc->dev,
+ device_printf(dev,
"Failed to obtain locality\n");
return (EIO);
}
if (!tpmtis_go_ready(sc)) {
- device_printf(sc->dev,
+ device_printf(dev,
"Failed to switch to ready state\n");
return (EIO);
}
if (!tpmtis_write_bytes(sc, length, sc->buf)) {
- device_printf(sc->dev,
+ device_printf(dev,
"Failed to write cmd to device\n");
return (EIO);
}
@@ -436,12 +406,12 @@
mask = TPM_STS_VALID;
sc->intr_type = TPM_INT_STS_VALID;
if (!tpm_wait_for_u32(sc, TPM_STS, mask, mask, TPM_TIMEOUT_C)) {
- device_printf(sc->dev,
+ device_printf(dev,
"Timeout while waiting for valid bit\n");
return (EIO);
}
- if (RD4(sc, TPM_STS) & TPM_STS_DATA_EXPECTED) {
- device_printf(sc->dev,
+ if (TPM_READ_4(dev, TPM_STS) & TPM_STS_DATA_EXPECTED) {
+ device_printf(dev,
"Device expects more data even though we already"
" sent everything we had\n");
return (EIO);
@@ -454,13 +424,13 @@
curr_cmd = be32toh(*(uint32_t *) (&sc->buf[6]));
timeout = tpm20_get_timeout(curr_cmd);
- WR4(sc, TPM_STS, TPM_STS_CMD_START);
- bus_barrier(sc->mem_res, TPM_STS, 4, BUS_SPACE_BARRIER_WRITE);
+ TPM_WRITE_4(dev, TPM_STS, TPM_STS_CMD_START);
+ TPM_WRITE_BARRIER(dev, TPM_STS, 4);
mask = TPM_STS_DATA_AVAIL | TPM_STS_VALID;
sc->intr_type = TPM_INT_STS_DATA_AVAIL;
if (!tpm_wait_for_u32(sc, TPM_STS, mask, mask, timeout)) {
- device_printf(sc->dev,
+ device_printf(dev,
"Timeout while waiting for device to process cmd\n");
/*
* Switching to ready state also cancels processing
@@ -479,21 +449,21 @@
}
/* Read response header. Length is passed in bytes 2 - 6. */
if(!tpmtis_read_bytes(sc, TPM_HEADER_SIZE, sc->buf)) {
- device_printf(sc->dev,
+ device_printf(dev,
"Failed to read response header\n");
return (EIO);
}
bytes_available = be32toh(*(uint32_t *) (&sc->buf[2]));
if (bytes_available > TPM_BUFSIZE || bytes_available < TPM_HEADER_SIZE) {
- device_printf(sc->dev,
+ device_printf(dev,
"Incorrect response size: %zu\n",
bytes_available);
return (EIO);
}
if(!tpmtis_read_bytes(sc, bytes_available - TPM_HEADER_SIZE,
&sc->buf[TPM_HEADER_SIZE])) {
- device_printf(sc->dev,
+ device_printf(dev,
"Failed to read response\n");
return (EIO);
}
@@ -505,16 +475,12 @@
/* ACPI Driver */
static device_method_t tpmtis_methods[] = {
- DEVMETHOD(device_probe, tpmtis_acpi_probe),
DEVMETHOD(device_attach, tpmtis_attach),
DEVMETHOD(device_detach, tpmtis_detach),
DEVMETHOD(device_shutdown, tpm20_shutdown),
DEVMETHOD(device_suspend, tpm20_suspend),
- {0, 0}
-};
-
-static driver_t tpmtis_driver = {
- "tpmtis", tpmtis_methods, sizeof(struct tpm_sc),
+ DEVMETHOD(tpm_transmit, tpmtis_transmit),
+ DEVMETHOD_END
};
-DRIVER_MODULE(tpmtis, acpi, tpmtis_driver, 0, 0);
+DEFINE_CLASS_0(tpmtis, tpmtis_driver, tpmtis_methods, sizeof(struct tpm_sc));
diff --git a/sys/dev/tpm/tpm_tis_spibus.c b/sys/dev/tpm/tpm_tis_spibus.c
new file mode 100644
--- /dev/null
+++ b/sys/dev/tpm/tpm_tis_spibus.c
@@ -0,0 +1,91 @@
+/*
+ * Copyright (c) 2023 Juniper Networks, Inc.
+ * All rights reserved.
+ */
+/*-
+ * Copyright (c) 2018 Stormshield.
+ * Copyright (c) 2018 Semihalf.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
+ * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+ * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
+ * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/* Based *heavily* on the tpm_tis driver. */
+
+#include "opt_platform.h"
+
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+#include <sys/kernel.h>
+#include <sys/lock.h>
+#include <sys/module.h>
+#include <sys/sx.h>
+
+#include <dev/spibus/spi.h>
+#include <dev/tpm/tpm20.h>
+
+#include "spibus_if.h"
+#include "tpm_if.h"
+
+#include <dev/ofw/ofw_bus.h>
+#include <dev/ofw/ofw_bus_subr.h>
+
+static struct ofw_compat_data compatible_data[] = {
+ {"infineon,slb9670", true},
+ {"tcg,tpm_tis-spi", true},
+ {NULL, false}
+};
+
+static int
+tpm_spi_probe(device_t dev)
+{
+ if (!ofw_bus_status_okay(dev))
+ return (ENXIO);
+
+ if (!ofw_bus_search_compatible(dev, compatible_data)->ocd_data)
+ return (ENXIO);
+
+ device_set_desc(dev, "Trusted Platform Module 2.0, SPI Mode");
+
+ return (BUS_PROBE_DEFAULT);
+}
+
+static device_method_t tpm_methods[] = {
+ DEVMETHOD(device_probe, tpm_spi_probe),
+ DEVMETHOD_END
+};
+
+DEFINE_CLASS_2(tpm, tpm_driver, tpm_methods, sizeof(struct tpm_sc),
+ tpmtis_driver, tpm_spi_driver);
+
+#if __FreeBSD_version < 1400067
+static devclass_t tpm_devclass;
+
+DRIVER_MODULE(tpm, spibus, tpm_driver, tpm_devclass, NULL, NULL);
+#else
+DRIVER_MODULE(tpm, spibus, tpm_driver, NULL, NULL);
+#endif
+MODULE_DEPEND(tpm, spibus, 1, 1, 1);
+MODULE_VERSION(tpm, 1);
diff --git a/sys/modules/Makefile b/sys/modules/Makefile
--- a/sys/modules/Makefile
+++ b/sys/modules/Makefile
@@ -391,7 +391,7 @@
${_ti} \
tmpfs \
${_toecore} \
- ${_tpm} \
+ tpm \
tws \
uart \
udf \
@@ -814,7 +814,6 @@
_s3= s3
_sdhci_acpi= sdhci_acpi
_superio= superio
-_tpm= tpm
_vesa= vesa
_viawd= viawd
_vmd= vmd
diff --git a/sys/modules/tpm/Makefile b/sys/modules/tpm/Makefile
--- a/sys/modules/tpm/Makefile
+++ b/sys/modules/tpm/Makefile
@@ -3,10 +3,25 @@
KMOD= tpm
-SRCS= tpm.c bus_if.h device_if.h
+SRCS= bus_if.h device_if.h tpm_if.c tpm_if.h
+SRCS+= opt_acpi.h opt_tpm.h
+
#Bus specific stuff.
-SRCS+= tpm_isa.c tpm_acpi.c isa_if.h opt_acpi.h acpi_if.h
+.if ${MACHINE_ARCH:Namd64:Ni386} == ""
+SRCS+= tpm.c
+SRCS+= tpm_acpi.c tpm_isa.c
+SRCS+= isa_if.h
+.endif
+
#TPM 2.0
-SRCS+= tpm20.c tpm_crb.c tpm_tis.c opt_tpm.h
+SRCS+= tpm20.c tpm_tis_core.c
+.if defined(${OPT_FDT})
+SRCS+= tpm_spibus.c tpm_tis_spibus.c spibus_if.h
+.endif
+.if ${MACHINE_ARCH:Namd64:Ni386:Narm64} == ""
+SRCS+= acpi_if.h
+SRCS+= tpm_tis_acpi.c
+SRCS+= tpm_crb.c
+.endif
.include <bsd.kmod.mk>
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 10, 9:05 PM (15 h, 53 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15746626
Default Alt Text
D45069.diff (35 KB)
Attached To
Mode
D45069: tpm: Refactor TIS and add a SPI attachment
Attached
Detach File
Event Timeline
Log In to Comment