Index: seabios/src/acpi-tpm-ssdt.dsl
===================================================================
--- /dev/null
+++ seabios/src/acpi-tpm-ssdt.dsl
@@ -0,0 +1,22 @@
+DefinitionBlock (
+    "acpi-tpm-ssdt.aml",// Output Filename
+    "SSDT",             // Signature
+    0x01,               // SSDT Compliance Revision
+    "BXPC",             // OEMID
+    "BXSSDT",           // TABLE ID
+    0x1                 // OEM Revision
+    )
+{
+    /* TPM with emulated TPM TIS interface */
+    Device (TPM) {
+        Name (_HID, EisaID ("PNP0C31"))
+        Name (_CRS, ResourceTemplate ()
+        {
+                Memory32Fixed (ReadWrite, 0xFED40000, 0x00005000)
+                //IRQNoFlags () {11}
+        })
+        Method (_STA, 0, NotSerialized) {
+            Return (0x0F)
+        }
+    }
+}
Index: seabios/src/acpi-tpm-ssdt.hex
===================================================================
--- /dev/null
+++ seabios/src/acpi-tpm-ssdt.hex
@@ -0,0 +1,26 @@
+/*
+ * 
+ * Intel ACPI Component Architecture
+ * ASL Optimizing Compiler version 20101013-64 [Nov 21 2010]
+ * Copyright (c) 2000 - 2010 Intel Corporation
+ * 
+ * Compilation of "out/.dsl.i" - Mon Apr  4 15:44:33 2011
+ * 
+ * C source code output
+ * AML code block contains 0x56 bytes
+ *
+ */
+unsigned char AmlCode_TPM[] =
+{
+    0x53,0x53,0x44,0x54,0x56,0x00,0x00,0x00,  /* 00000000    "SSDTV..." */
+    0x01,0x13,0x42,0x58,0x50,0x43,0x00,0x00,  /* 00000008    "..BXPC.." */
+    0x42,0x58,0x53,0x53,0x44,0x54,0x00,0x00,  /* 00000010    "BXSSDT.." */
+    0x01,0x00,0x00,0x00,0x49,0x4E,0x54,0x4C,  /* 00000018    "....INTL" */
+    0x13,0x10,0x10,0x20,0x5B,0x82,0x30,0x54,  /* 00000020    "... [.0T" */
+    0x50,0x4D,0x5F,0x08,0x5F,0x48,0x49,0x44,  /* 00000028    "PM_._HID" */
+    0x0C,0x41,0xD0,0x0C,0x31,0x08,0x5F,0x43,  /* 00000030    ".A..1._C" */
+    0x52,0x53,0x11,0x11,0x0A,0x0E,0x86,0x09,  /* 00000038    "RS......" */
+    0x00,0x01,0x00,0x00,0xD4,0xFE,0x00,0x50,  /* 00000040    ".......P" */
+    0x00,0x00,0x79,0x00,0x14,0x09,0x5F,0x53,  /* 00000048    "..y..._S" */
+    0x54,0x41,0x00,0xA4,0x0A,0x0F             /* 00000050    "TA...."   */
+};
Index: seabios/Makefile
===================================================================
--- seabios.orig/Makefile
+++ seabios/Makefile
@@ -20,7 +20,7 @@ SRC16=$(SRCBOTH) system.c disk.c font.c
 SRC32FLAT=$(SRCBOTH) post.c shadow.c memmap.c coreboot.c boot.c \
       acpi.c smm.c mptable.c smbios.c pciinit.c optionroms.c mtrr.c \
       lzmadecode.c bootsplash.c jpeg.c usb-hub.c paravirt.c dev-i440fx.c \
-      pci_region.c
+      pci_region.c tcgbios.c tpm_drivers.c
 SRC32SEG=util.c output.c pci.c pcibios.c apm.c stacks.c
 
 cc-option = $(shell if test -z "`$(1) $(2) -S -o /dev/null -xc \
@@ -192,13 +192,20 @@ $(OUT)vgabios.bin: $(OUT)vgabios.bin.raw
 	$(Q)./tools/buildrom.py $< $@
 
 ####### dsdt build rules
+src/acpi-tpm-ssdt.hex: src/acpi-tpm-ssdt.dsl
+	@echo "Compiling TPM SSDT"
+	$(Q)cpp -P $< > $(OUT)$*.dsl.i
+	$(Q)iasl -tc -p $(OUT)$* $(OUT)$*.dsl.i
+	$(Q)cp $(OUT)$*.hex $@
+	$(Q)sed -i 's/AmlCode/AmlCode_TPM/' $@
+
 src/%.hex: src/%.dsl
 	@echo "Compiling DSDT"
 	$(Q)cpp -P $< > $(OUT)$*.dsl.i
 	$(Q)iasl -tc -p $(OUT)$* $(OUT)$*.dsl.i
 	$(Q)cp $(OUT)$*.hex $@
 
-$(OUT)ccode32flat.o: src/acpi-dsdt.hex
+$(OUT)ccode32flat.o: src/acpi-dsdt.hex src/acpi-tpm-ssdt.hex
 
 ####### Kconfig rules
 export HOSTCC             := $(CC)
Index: seabios/src/acpi.c
===================================================================
--- seabios.orig/src/acpi.c
+++ seabios/src/acpi.c
@@ -13,6 +13,8 @@
 #include "pci_regs.h" // PCI_INTERRUPT_LINE
 #include "paravirt.h"
 #include "dev-i440fx.h" // piix4_fadt_init
+#include "acpi-tpm-ssdt.hex"
+#include "tcgbios.h" // has_working_tpm
 
 /****************************************************/
 /* ACPI tables init */
@@ -586,6 +588,39 @@ static const struct pci_device_id acpi_f
     PCI_DEVICE_END,
 };
 
+
+static u32 add_tpm_device(void **tpm_addr, void **tcpa_addr)
+{
+    struct tcpa_descriptor_rev2 *tcpa;
+
+    *tpm_addr = NULL;
+    *tcpa_addr = NULL;
+
+    if (has_working_tpm()) {
+        u32 laml = 64 * 1024;
+        *tpm_addr = malloc_high(sizeof(AmlCode_TPM));
+
+        tcpa = malloc_high(sizeof(*tcpa) + laml);
+        if (!tcpa || !*tpm_addr) {
+            warn_noalloc();
+            return 1;
+        }
+
+        if (*tpm_addr)
+            memcpy(*tpm_addr, AmlCode_TPM, sizeof(AmlCode_TPM));
+
+        memset(tcpa, 0x0, sizeof(*tcpa) + laml);
+        u64 lasa = (u32)tcpa + sizeof(*tcpa);
+
+        tcpa->laml = laml;
+        tcpa->lasa = lasa;
+        build_header((void*)tcpa, TCPA_SIGNATURE, sizeof(*tcpa), 2);
+
+        *tcpa_addr = tcpa;
+    }
+    return 0;
+}
+
 struct rsdp_descriptor *RsdpAddr;
 
 #define MAX_ACPI_TABLES 20
@@ -642,6 +677,12 @@ acpi_bios_init(void)
         }
     }
 
+    void *tcpa, *tpm;
+    if (add_tpm_device(&tpm, &tcpa))
+        return;
+    ACPI_INIT_TABLE(tpm);
+    ACPI_INIT_TABLE(tcpa);
+
     struct rsdt_descriptor_rev1 *rsdt;
     size_t rsdt_len = sizeof(*rsdt) + sizeof(u32) * tbl_idx;
     rsdt = malloc_high(rsdt_len);
Index: seabios/src/acpi.h
===================================================================
--- seabios.orig/src/acpi.h
+++ seabios/src/acpi.h
@@ -98,4 +98,24 @@ struct fadt_descriptor_rev1
 #endif
 } PACKED;
 
+
+struct rsdt_descriptor {
+    ACPI_TABLE_HEADER_DEF
+    u32 entry[1];
+} PACKED;
+
+#define TCPA_SIGNATURE 0x41504354
+struct tcpa_descriptor_rev2
+{
+    ACPI_TABLE_HEADER_DEF
+    u16  platform_class;
+    u32  laml;
+    u64  lasa;
+} PACKED;
+
+/* TCPA ACPI definitions */
+#define TCPA_ACPI_CLASS_CLIENT          0
+#define TCPA_ACPI_CLASS_SERVER          1
+
+
 #endif // acpi.h
Index: seabios/src/config.h
===================================================================
--- seabios.orig/src/config.h
+++ seabios/src/config.h
@@ -26,7 +26,7 @@
 // Space to reserve in f-segment for dynamic allocations
 #define CONFIG_MAX_BIOSTABLE 2048
 // Space to reserve in high-memory for tables
-#define CONFIG_MAX_HIGHTABLE (64*1024)
+#define CONFIG_MAX_HIGHTABLE (96*1024)
 // Largest supported externaly facing drive id
 #define CONFIG_MAX_EXTDRIVE 16
 
Index: seabios/src/tcgbios.c
===================================================================
--- /dev/null
+++ seabios/src/tcgbios.c
@@ -0,0 +1,72 @@
+//  Implementation of the TCG BIOS extension according to the specification
+//  described in
+//  https://www.trustedcomputinggroup.org/specs/PCClient/TCG_PCClientImplementationforBIOS_1-20_1-00.pdf
+//
+//  Copyright (C) 2006-2011 IBM Corporation
+//  Copyright (C) 2006-2011 Stefan Berger <stefanb@us.ibm.com>
+//
+// This file may be distributed under the terms of the GNU LGPLv3 license.
+
+
+#include "config.h"
+
+#include "types.h"
+#include "tpm_drivers.h" // tpm_drivers[]
+
+
+typedef struct {
+    u8            tpm_probed:1;
+    u8            tpm_found:1;
+    u8            tpm_working:1;
+    u8            if_shutdown:1;
+    u8            tpm_driver_to_use:4;
+} tcpa_state_t;
+
+
+static tcpa_state_t tcpa_state = {
+    .tpm_driver_to_use = TPM_INVALID_DRIVER,
+};
+
+extern struct tpm_driver tpm_drivers[];
+
+
+/********************************************************
+  Extensions for TCG-enabled BIOS
+ *******************************************************/
+
+
+static u32
+is_tpm_present(void)
+{
+    u32 rc = 0;
+    unsigned int i;
+
+    for (i = 0; i < TPM_NUM_DRIVERS; i++) {
+        struct tpm_driver *td = &tpm_drivers[i];
+        if (td->probe() != 0) {
+            td->init();
+            tcpa_state.tpm_driver_to_use = i;
+            rc = 1;
+            break;
+        }
+    }
+
+    return rc;
+}
+
+
+int
+has_working_tpm(void)
+{
+    if (!tcpa_state.tpm_probed) {
+        tcpa_state.tpm_probed = 1;
+        tcpa_state.tpm_found = (is_tpm_present() != 0);
+        tcpa_state.tpm_working = 1;
+    }
+    if (!tcpa_state.tpm_working)
+        return 0;
+
+    return tcpa_state.tpm_found;
+}
+
+
Index: seabios/src/tcgbios.h
===================================================================
--- /dev/null
+++ seabios/src/tcgbios.h
@@ -0,0 +1,57 @@
+#ifndef TCGBIOS_H
+#define TCGBIOS_H
+
+
+#define TPM_OK                          0x0
+#define TPM_RET_BASE                    0x1
+#define TCG_GENERAL_ERROR               (TPM_RET_BASE + 0x0)
+#define TCG_TPM_IS_LOCKED               (TPM_RET_BASE + 0x1)
+#define TCG_NO_RESPONSE                 (TPM_RET_BASE + 0x2)
+#define TCG_INVALID_RESPONSE            (TPM_RET_BASE + 0x3)
+#define TCG_INVALID_ACCESS_REQUEST      (TPM_RET_BASE + 0x4)
+#define TCG_FIRMWARE_ERROR              (TPM_RET_BASE + 0x5)
+#define TCG_INTEGRITY_CHECK_FAILED      (TPM_RET_BASE + 0x6)
+#define TCG_INVALID_DEVICE_ID           (TPM_RET_BASE + 0x7)
+#define TCG_INVALID_VENDOR_ID           (TPM_RET_BASE + 0x8)
+#define TCG_UNABLE_TO_OPEN              (TPM_RET_BASE + 0x9)
+#define TCG_UNABLE_TO_CLOSE             (TPM_RET_BASE + 0xa)
+#define TCG_RESPONSE_TIMEOUT            (TPM_RET_BASE + 0xb)
+#define TCG_INVALID_COM_REQUEST         (TPM_RET_BASE + 0xc)
+#define TCG_INVALID_ADR_REQUEST         (TPM_RET_BASE + 0xd)
+#define TCG_WRITE_BYTE_ERROR            (TPM_RET_BASE + 0xe)
+#define TCG_READ_BYTE_ERROR             (TPM_RET_BASE + 0xf)
+#define TCG_BLOCK_WRITE_TIMEOUT         (TPM_RET_BASE + 0x10)
+#define TCG_CHAR_WRITE_TIMEOUT          (TPM_RET_BASE + 0x11)
+#define TCG_CHAR_READ_TIMEOUT           (TPM_RET_BASE + 0x12)
+#define TCG_BLOCK_READ_TIMEOUT          (TPM_RET_BASE + 0x13)
+#define TCG_TRANSFER_ABORT              (TPM_RET_BASE + 0x14)
+#define TCG_INVALID_DRV_FUNCTION        (TPM_RET_BASE + 0x15)
+#define TCG_OUTPUT_BUFFER_TOO_SHORT     (TPM_RET_BASE + 0x16)
+#define TCG_FATAL_COM_ERROR             (TPM_RET_BASE + 0x17)
+#define TCG_INVALID_INPUT_PARA          (TPM_RET_BASE + 0x18)
+#define TCG_TCG_COMMAND_ERROR           (TPM_RET_BASE + 0x19)
+#define TCG_INTERFACE_SHUTDOWN          (TPM_RET_BASE + 0x20)
+//define TCG_PC_UNSUPPORTED             (TPM_RET_BASE + 0x21)
+#define TCG_PC_TPM_NOT_PRESENT          (TPM_RET_BASE + 0x22)
+#define TCG_PC_TPM_DEACTIVATED          (TPM_RET_BASE + 0x23)
+
+
+#define TPM_INVALID_ADR_REQUEST          TCG_INVALID_ADR_REQUEST
+#define TPM_IS_LOCKED                    TCG_TPM_IS_LOCKED
+#define TPM_INVALID_DEVICE_ID            TCG_INVALID_DEVICE_ID
+#define TPM_INVALID_VENDOR_ID            TCG_INVALID_VENDOR_ID
+//define TPM_RESERVED_REG_INVALID
+#define TPM_FIRMWARE_ERROR               TCG_FIRMWARE_ERROR
+#define TPM_UNABLE_TO_OPEN               TCG_UNABLE_TO_OPEN
+#define TPM_UNABLE_TO_CLOSE              TCG_UNABLE_TO_CLOSE
+#define TPM_INVALID_RESPONSE             TCG_INVALID_RESPONSE
+#define TPM_RESPONSE_TIMEOUT             TCG_RESPONSE_TIMEOUT
+#define TPM_INVALID_ACCESS_REQUEST       TCG_INVALID_ACCESS_REQUEST
+#define TPM_TRANSFER_ABORT               TCG_TRANSFER_ABORT
+#define TPM_GENERAL_ERROR                TCG_GENERAL_ERROR
+
+
+int has_working_tpm(void);
+
+
+#endif /* TCGBIOS_H */
