Add support for TPM 1.2 and TPM 2 physical presence interface
(PPI). A shared memory structure is located at 0xffff 0000 -
0xffff 00ff that SeaBIOS initializes unless it has already
been intialized and then searches for a code it is supposed
to act upon. A code typically requires that one or more TPM
commands are being sent.
The underlying spec can be accessed from this page here:
https://trustedcomputinggroup.org/tcg-physical-presence-interface-specification/
Version 1.20 is implemented.
Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
---
src/post.c | 4 ++++
src/std/tcg.h | 18 ++++++++++++++++++
src/tcgbios.c | 61 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
src/tcgbios.h | 3 +++
4 files changed, 86 insertions(+)
diff --git a/src/post.c b/src/post.c
index f93106a..f451013 100644
--- a/src/post.c
+++ b/src/post.c
@@ -201,6 +201,7 @@ maininit(void)
// Setup platform devices.
platform_hardware_setup();
+ tpm_ppi_init();
// Start hardware initialization (if threads allowed during optionroms)
if (threads_during_optionroms())
@@ -220,6 +221,9 @@ maininit(void)
// Run option roms
optionrom_setup();
+ // Process user-requested TPM state change
+ tpm_ppi_process();
+
// Allow user to modify overall boot order.
interactive_bootmenu();
wait_threads();
diff --git a/src/std/tcg.h b/src/std/tcg.h
index 09a92d8..0aeafe8 100644
--- a/src/std/tcg.h
+++ b/src/std/tcg.h
@@ -551,4 +551,22 @@ struct pcctes_romex
#define TPM_PPI_OP_SET_OWNERINSTALL_TRUE 8
#define TPM_PPI_OP_SET_OWNERINSTALL_FALSE 9
+#define TPM_PPI_ADDR_BASE 0xffff0000
+
+struct tpm_ppi {
+ u8 ppin; // 1 = initialized
+ u32 ppip; // not used
+ u32 pprp; // response from TPM; set by BIOS
+ u32 pprq; // opcode; set by ACPI
+ u32 pprm; // parameter for opcode; set by ACPI
+ u32 lppr; // last opcode; set by BIOS
+ u32 fret; // not used
+ u8 res1; // reserved
+ u32 res[4]; // reserved
+ u32 fail; // set by BIOS (0 = success)
+} PACKED;
+
+void tpm_ppi_init(void);
+void tpm_ppi_process(void);
+
#endif // tcg.h
diff --git a/src/tcgbios.c b/src/tcgbios.c
index 40b3028..2adca71 100644
--- a/src/tcgbios.c
+++ b/src/tcgbios.c
@@ -1774,6 +1774,18 @@ tpm20_process_cfg(tpm_ppi_code msgCode, int verbose)
}
static int
+tpm_process_cfg(tpm_ppi_code msgCode, int verbose)
+{
+ switch (TPM_version) {
+ case TPM_VERSION_1_2:
+ return tpm12_process_cfg(msgCode, verbose);
+ case TPM_VERSION_2:
+ return tpm20_process_cfg(msgCode, verbose);
+ }
+ return -1;
+}
+
+static int
tpm12_get_tpm_state(void)
{
int state = 0;
@@ -2012,3 +2024,52 @@ tpm_can_show_menu(void)
}
return 0;
}
+
+static struct tpm_ppi *tp;
+static u8 next_step; /* next opcode to execute after reboot */
+
+void
+tpm_ppi_init(void)
+{
+ tp = (struct tpm_ppi *)TPM_PPI_ADDR_BASE;
+
+ dprintf(DEBUG_tcg, "TCGBIOS: TPM PPI struct at %p\n", tp);
+
+ if (!tp->ppin) {
+ tp->ppin = 1;
+ tp->pprq = 0;
+ tp->lppr = 0;
+ tp->fail = 0;
+ }
+}
+
+void
+tpm_ppi_process(void)
+{
+ tpm_ppi_code op;
+
+ if (tp) {
+ op = tp->pprq;
+ if (!op) {
+ /* intermediate step after a reboot? */
+ op = next_step;
+ } else {
+ /* last full opcode */
+ tp->lppr = op;
+ }
+ if (op) {
+ /*
+ * Reset the opcode so we don't permanently reboot upon
+ * code 3 (Activate).
+ */
+ tp->pprq = 0;
+
+ printf("Processing TPM PPI opcode %d\n", op);
+ tp->fail = (tpm_process_cfg(op, 0) != 0);
+ if (tp->fail)
+ tp->pprp = 0x0badc0de;
+ else
+ tp->pprp = 0;
+ }
+ }
+}
diff --git a/src/tcgbios.h b/src/tcgbios.h
index 32fb941..52b86f2 100644
--- a/src/tcgbios.h
+++ b/src/tcgbios.h
@@ -16,4 +16,7 @@ void tpm_option_rom(const void *addr, u32 len);
int tpm_can_show_menu(void);
void tpm_menu(void);
+void tpm_ppi_init(void);
+void tpm_ppi_process(void);
+
#endif /* TCGBIOS_H */
--
2.5.5
_______________________________________________
SeaBIOS mailing list
SeaBIOS@seabios.org
https://mail.coreboot.org/mailman/listinfo/seabios
© 2016 - 2025 Red Hat, Inc.