Source-Changes-HG archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
[src/trunk]: src/sys/dev Add suspend support for TPM 2.0 chips. Check the TPM...
details: https://anonhg.NetBSD.org/src/rev/036ea639946f
branches: trunk
changeset: 965988:036ea639946f
user: maxv <maxv%NetBSD.org@localhost>
date: Wed Oct 09 07:30:58 2019 +0000
description:
Add suspend support for TPM 2.0 chips. Check the TPM response also for 1.2
chips. Unfortunately I cannot really test this change since ACPI suspend
does not work on any of my laptops.
diffstat:
sys/dev/acpi/tpm_acpi.c | 6 ++-
sys/dev/ic/tpm.c | 84 ++++++++++++++++++++++++++++++++++++------------
sys/dev/ic/tpmreg.h | 18 +++++++++-
sys/dev/ic/tpmvar.h | 6 +-
sys/dev/isa/tpm_isa.c | 8 ++--
5 files changed, 90 insertions(+), 32 deletions(-)
diffs (252 lines):
diff -r 9d6fd4da9bf1 -r 036ea639946f sys/dev/acpi/tpm_acpi.c
--- a/sys/dev/acpi/tpm_acpi.c Wed Oct 09 05:59:51 2019 +0000
+++ b/sys/dev/acpi/tpm_acpi.c Wed Oct 09 07:30:58 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tpm_acpi.c,v 1.9 2019/10/08 18:43:02 maxv Exp $ */
+/* $NetBSD: tpm_acpi.c,v 1.10 2019/10/09 07:30:58 maxv Exp $ */
/*
* Copyright (c) 2012, 2019 The NetBSD Foundation, Inc.
@@ -30,7 +30,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tpm_acpi.c,v 1.9 2019/10/08 18:43:02 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tpm_acpi.c,v 1.10 2019/10/09 07:30:58 maxv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -148,6 +148,8 @@
goto out1;
}
+ if (!pmf_device_register(self, tpm_suspend, tpm_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
acpi_resource_cleanup(&res);
return;
diff -r 9d6fd4da9bf1 -r 036ea639946f sys/dev/ic/tpm.c
--- a/sys/dev/ic/tpm.c Wed Oct 09 05:59:51 2019 +0000
+++ b/sys/dev/ic/tpm.c Wed Oct 09 07:30:58 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tpm.c,v 1.14 2019/10/08 18:43:02 maxv Exp $ */
+/* $NetBSD: tpm.c,v 1.15 2019/10/09 07:30:58 maxv Exp $ */
/*
* Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tpm.c,v 1.14 2019/10/08 18:43:02 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tpm.c,v 1.15 2019/10/09 07:30:58 maxv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -65,8 +65,9 @@
#include "ioconf.h"
+CTASSERT(sizeof(struct tpm_header) == 10);
+
#define TPM_BUFSIZ 1024
-#define TPM_HDRSIZE 10
#define TPM_PARAM_SIZE 0x0001 /* that's a flag */
@@ -163,31 +164,69 @@
/* -------------------------------------------------------------------------- */
-/*
- * Save TPM state on suspend. On resume we don't do anything, since the BIOS
- * is supposed to restore the previously saved state.
- */
-
-bool
-tpm12_suspend(device_t dev, const pmf_qual_t *qual)
+static bool
+tpm12_suspend(struct tpm_softc *sc)
{
- struct tpm_softc *sc = device_private(dev);
- static const uint8_t command[] = {
- 0, 0xC1, /* TPM_TAG_RQU_COMMAND */
- 0, 0, 0, 10, /* Length in bytes */
- 0, 0, 0, 0x98 /* TPM_ORD_SaveState */
+ static const uint8_t command[10] = {
+ 0x00, 0xC1, /* TPM_TAG_RQU_COMMAND */
+ 0x00, 0x00, 0x00, 10, /* Length in bytes */
+ 0x00, 0x00, 0x00, 0x98 /* TPM_ORD_SaveState */
};
- uint8_t scratch[sizeof(command)];
+ struct tpm_header response;
+
+ if ((*sc->sc_write)(sc, &command, sizeof(command)) != 0)
+ return false;
+ if ((*sc->sc_read)(sc, &response, sizeof(response), NULL, 0) != 0)
+ return false;
+ if (TPM_BE32(response.code) != 0)
+ return false;
+
+ return true;
+}
- (*sc->sc_write)(sc, &command, sizeof(command));
- (*sc->sc_read)(sc, &scratch, sizeof(scratch), NULL, 0);
+static bool
+tpm20_suspend(struct tpm_softc *sc)
+{
+ static const uint8_t command[12] = {
+ 0x80, 0x01, /* TPM_ST_NO_SESSIONS */
+ 0x00, 0x00, 0x00, 12, /* Length in bytes */
+ 0x00, 0x00, 0x01, 0x45, /* TPM_CC_Shutdown */
+ 0x00, 0x01 /* TPM_SU_STATE */
+ };
+ struct tpm_header response;
+
+ if ((*sc->sc_write)(sc, &command, sizeof(command)) != 0)
+ return false;
+ if ((*sc->sc_read)(sc, &response, sizeof(response), NULL, 0) != 0)
+ return false;
+ if (TPM_BE32(response.code) != 0)
+ return false;
return true;
}
bool
-tpm12_resume(device_t dev, const pmf_qual_t *qual)
+tpm_suspend(device_t dev, const pmf_qual_t *qual)
{
+ struct tpm_softc *sc = device_private(dev);
+
+ switch (sc->sc_ver) {
+ case TPM_1_2:
+ return tpm12_suspend(sc);
+ case TPM_2_0:
+ return tpm20_suspend(sc);
+ default:
+ panic("%s: impossible", __func__);
+ }
+}
+
+bool
+tpm_resume(device_t dev, const pmf_qual_t *qual)
+{
+ /*
+ * Don't do anything, the BIOS is supposed to restore the previously
+ * saved state.
+ */
return true;
}
@@ -508,6 +547,7 @@
tpmread(dev_t dev, struct uio *uio, int flags)
{
struct tpm_softc *sc = device_lookup_private(&tpm_cd, minor(dev));
+ struct tpm_header hdr;
uint8_t buf[TPM_BUFSIZ];
size_t cnt, len, n;
int rv;
@@ -519,11 +559,11 @@
goto out;
/* Get the header. */
- if ((rv = (*sc->sc_read)(sc, buf, TPM_HDRSIZE, &cnt, 0))) {
+ if ((rv = (*sc->sc_read)(sc, &hdr, sizeof(hdr), &cnt, 0))) {
(*sc->sc_end)(sc, UIO_READ, rv);
goto out;
}
- len = (buf[2] << 24) | (buf[3] << 16) | (buf[4] << 8) | buf[5];
+ len = TPM_BE32(hdr.length);
if (len > uio->uio_resid || len < cnt) {
rv = EIO;
(*sc->sc_end)(sc, UIO_READ, rv);
@@ -531,7 +571,7 @@
}
/* Copy out the header. */
- if ((rv = uiomove(buf, cnt, uio))) {
+ if ((rv = uiomove(&hdr, cnt, uio))) {
(*sc->sc_end)(sc, UIO_READ, rv);
goto out;
}
diff -r 9d6fd4da9bf1 -r 036ea639946f sys/dev/ic/tpmreg.h
--- a/sys/dev/ic/tpmreg.h Wed Oct 09 05:59:51 2019 +0000
+++ b/sys/dev/ic/tpmreg.h Wed Oct 09 07:30:58 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tpmreg.h,v 1.5 2019/10/08 18:43:02 maxv Exp $ */
+/* $NetBSD: tpmreg.h,v 1.6 2019/10/09 07:30:58 maxv Exp $ */
/*
* Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -29,6 +29,22 @@
* POSSIBILITY OF SUCH DAMAGE.
*/
+#if (BYTE_ORDER == LITTLE_ENDIAN)
+#define TPM_BE16(a) bswap16(a)
+#define TPM_BE32(a) bswap32(a)
+#else
+#define TPM_BE16(a) (a)
+#define TPM_BE32(a) (a)
+#endif
+
+struct tpm_header {
+ uint16_t tag;
+ uint32_t length;
+ uint32_t code;
+} __packed;
+
+/* -------------------------------------------------------------------------- */
+
/*
* TPM Interface Specification 1.2 (TIS12).
*/
diff -r 9d6fd4da9bf1 -r 036ea639946f sys/dev/ic/tpmvar.h
--- a/sys/dev/ic/tpmvar.h Wed Oct 09 05:59:51 2019 +0000
+++ b/sys/dev/ic/tpmvar.h Wed Oct 09 07:30:58 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tpmvar.h,v 1.5 2019/10/08 18:43:02 maxv Exp $ */
+/* $NetBSD: tpmvar.h,v 1.6 2019/10/09 07:30:58 maxv Exp $ */
/*
* Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -69,8 +69,8 @@
uint32_t sc_caps;
};
-bool tpm12_suspend(device_t, const pmf_qual_t *);
-bool tpm12_resume(device_t, const pmf_qual_t *);
+bool tpm_suspend(device_t, const pmf_qual_t *);
+bool tpm_resume(device_t, const pmf_qual_t *);
int tpm_tis12_probe(bus_space_tag_t, bus_space_handle_t);
int tpm_tis12_init(struct tpm_softc *);
diff -r 9d6fd4da9bf1 -r 036ea639946f sys/dev/isa/tpm_isa.c
--- a/sys/dev/isa/tpm_isa.c Wed Oct 09 05:59:51 2019 +0000
+++ b/sys/dev/isa/tpm_isa.c Wed Oct 09 07:30:58 2019 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: tpm_isa.c,v 1.5 2019/10/08 18:43:03 maxv Exp $ */
+/* $NetBSD: tpm_isa.c,v 1.6 2019/10/09 07:30:58 maxv Exp $ */
/*
* Copyright (c) 2019 The NetBSD Foundation, Inc.
@@ -48,7 +48,7 @@
*/
#include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: tpm_isa.c,v 1.5 2019/10/08 18:43:03 maxv Exp $");
+__KERNEL_RCSID(0, "$NetBSD: tpm_isa.c,v 1.6 2019/10/09 07:30:58 maxv Exp $");
#include <sys/param.h>
#include <sys/systm.h>
@@ -133,6 +133,6 @@
return;
}
- if (!pmf_device_register(sc->sc_dev, tpm12_suspend, tpm12_resume))
- aprint_error_dev(sc->sc_dev, "couldn't establish power handler\n");
+ if (!pmf_device_register(self, tpm_suspend, tpm_resume))
+ aprint_error_dev(self, "couldn't establish power handler\n");
}
Home |
Main Index |
Thread Index |
Old Index