Patchwork [V1,2/8] Provide ACPI SSDT table for TPM device + S3 resume support

login
register
mail settings
Submitter Stefan Berger
Date March 30, 2011, 5:55 p.m.
Message ID <20110330175558.493257530@linux.vnet.ibm.com>
Download mbox | patch
Permalink /patch/88948/
State New
Headers show

Comments

Stefan Berger - March 30, 2011, 5:55 p.m.
This patch provides ACPI support for the TPM device. It probes for the TPM
device and only if a TPM device is found then the TPM's SSDT and TCPA table
are created. This patch also connects them to the RSDT.

Since the logging area in the TCPA table requires 64kb, the memory reserved
for ACPI tables (config.h) is increased to 96kb in case CONFIG_TCGBIOS
is enabled.

This patch requires the subsequent patch for it to compile and work.

The IRQ description in the TPM's SSDT is commented since it will be
'safer' to run the TPM in polling mode - the Linux TPM TIS driver for example
has too many issues when run in interrupt mode.

The description of the TCPA (client) table can be found here:

http://www.trustedcomputinggroup.org/resources/server_work_group_acpi_general_specification_version_10

The compiled SSDT description is also part of this patch.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>

---
 Makefile              |    9 ++++++++-
 src/acpi-tpm-ssdt.dsl |   22 ++++++++++++++++++++++
 src/acpi-tpm-ssdt.hex |   34 ++++++++++++++++++++++++++++++++++
 src/acpi.c            |   41 +++++++++++++++++++++++++++++++++++++++++
 src/acpi.h            |   20 ++++++++++++++++++++
 src/config.h          |    6 +++++-
 6 files changed, 130 insertions(+), 2 deletions(-)
Kevin O'Connor - April 4, 2011, 4:17 a.m.
On Wed, Mar 30, 2011 at 01:55:36PM -0400, Stefan Berger wrote:
> This patch provides ACPI support for the TPM device. It probes for the TPM
> device and only if a TPM device is found then the TPM's SSDT and TCPA table
> are created. This patch also connects them to the RSDT.
[...]
>  // Space to reserve in high-memory for tables
> -#define CONFIG_MAX_HIGHTABLE (64*1024)
> +#if CONFIG_TCGBIOS
> +# define CONFIG_MAX_HIGHTABLE (96*1024)
> +#else
> +# define CONFIG_MAX_HIGHTABLE (64*1024)
> +#endif

I'm a bit confused on patch ordering - it seems CONFIG_TCGBIOS is
defined in patch 4 but used in patch 2.

Also, I'd prefer to avoid ifdefs - just up the size to 96 always, or
do something like:

#define CONFIG_MAX_HIGHTABLE ((64*1024) + CONFIG_TCGBIOS*(32*1024))

-Kevin
Stefan Berger - April 4, 2011, 2:52 p.m.
On 04/04/2011 12:17 AM, Kevin O'Connor wrote:
> On Wed, Mar 30, 2011 at 01:55:36PM -0400, Stefan Berger wrote:
>> This patch provides ACPI support for the TPM device. It probes for the TPM
>> device and only if a TPM device is found then the TPM's SSDT and TCPA table
>> are created. This patch also connects them to the RSDT.
> [...]
>>   // Space to reserve in high-memory for tables
>> -#define CONFIG_MAX_HIGHTABLE (64*1024)
>> +#if CONFIG_TCGBIOS
>> +# define CONFIG_MAX_HIGHTABLE (96*1024)
>> +#else
>> +# define CONFIG_MAX_HIGHTABLE (64*1024)
>> +#endif
> I'm a bit confused on patch ordering - it seems CONFIG_TCGBIOS is
> defined in patch 4 but used in patch 2.
I had it in patch 2 since there I am allocating 64kb in the high memory...
I'll move it to patch 4.
> Also, I'd prefer to avoid ifdefs - just up the size to 96 always, or
> do something like:
>
> #define CONFIG_MAX_HIGHTABLE ((64*1024) + CONFIG_TCGBIOS*(32*1024))
>
Done that.

    Stefan
> -Kevin

Patch

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,34 @@ 
+/*
+ * 
+ * Intel ACPI Component Architecture
+ * ASL Optimizing Compiler version 20101013-64 [Nov 21 2010]
+ * Copyright (c) 2000 - 2010 Intel Corporation
+ * 
+ * Compilation of "out/.dsl.i" - Sun Mar 13 20:44:32 2011
+ * 
+ * C source code output
+ * AML code block contains 0x93 bytes
+ *
+ */
+unsigned char AmlCode_TPM[] =
+{
+    0x53,0x53,0x44,0x54,0x93,0x00,0x00,0x00,  /* 00000000    "SSDT...." */
+    0x01,0xC3,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,0x4D,0x06,  /* 00000020    "... [.M." */
+    0x54,0x50,0x4D,0x5F,0x08,0x5F,0x48,0x49,  /* 00000028    "TPM_._HI" */
+    0x44,0x0C,0x41,0xD0,0x0C,0x31,0x08,0x5F,  /* 00000030    "D.A..1._" */
+    0x53,0x54,0x52,0x11,0x33,0x0A,0x30,0x45,  /* 00000038    "STR.3.0E" */
+    0x00,0x6D,0x00,0x75,0x00,0x6C,0x00,0x61,  /* 00000040    ".m.u.l.a" */
+    0x00,0x74,0x00,0x65,0x00,0x64,0x00,0x20,  /* 00000048    ".t.e.d. " */
+    0x00,0x54,0x00,0x50,0x00,0x4D,0x00,0x20,  /* 00000050    ".T.P.M. " */
+    0x00,0x54,0x00,0x49,0x00,0x53,0x00,0x20,  /* 00000058    ".T.I.S. " */
+    0x00,0x64,0x00,0x65,0x00,0x76,0x00,0x69,  /* 00000060    ".d.e.v.i" */
+    0x00,0x63,0x00,0x65,0x00,0x00,0x00,0x08,  /* 00000068    ".c.e...." */
+    0x5F,0x43,0x52,0x53,0x11,0x14,0x0A,0x11,  /* 00000070    "_CRS...." */
+    0x86,0x09,0x00,0x01,0x00,0x00,0xD4,0xFE,  /* 00000078    "........" */
+    0x00,0x50,0x00,0x00,0x22,0x00,0x08,0x79,  /* 00000080    ".P.."..y" */
+    0x00,0x14,0x09,0x5F,0x53,0x54,0x41,0x00,  /* 00000088    "..._STA." */
+    0xA4,0x0A,0x0F                            /* 00000090    "..."      */
+};
Index: seabios/Makefile
===================================================================
--- seabios.orig/Makefile
+++ seabios/Makefile
@@ -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,11 @@ 
 // 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)
+#if CONFIG_TCGBIOS
+# define CONFIG_MAX_HIGHTABLE (96*1024)
+#else
+# define CONFIG_MAX_HIGHTABLE (64*1024)
+#endif
 // Largest supported externaly facing drive id
 #define CONFIG_MAX_EXTDRIVE 16