diff options
author | Duncan Laurie <dlaurie@chromium.org> | 2014-10-30 15:20:19 -0700 |
---|---|---|
committer | Stefan Reinauer <stefan.reinauer@coreboot.org> | 2015-04-10 19:32:46 +0200 |
commit | dd281edcfab464c4bf9df3fa9d86db5639c845e0 (patch) | |
tree | e7881cbc206a662386c20a7fbed9040f9e1b3731 /src/drivers/pc80/tpm/acpi | |
parent | 1ab1eac63ec4c13655e917eb34c86bbf290802a2 (diff) |
tpm: Add ramstage driver and interrupt configuration
This adds a ramstage driver for the TPM and allows the interrupt
to be configured in devicetree.cb.
The interrupt vector is set like other PNP devices, and the
interrupt polarity is set with a register configuration variable.
These values are written into locality 0 TPM_INT_VECTOR and
TPM_INT_ENABLE and then all interrupts are disabled so they are
not used in firmware but can be enabled by the OS.
It also adds an ACPI device for the TPM which will configure the
reported interrupt based on what has been written into the TPM
during ramstage. The _STA method returns enabled if CONFIG_LPC_TPM
is enabled, and the _CRS method will only report an interrupt if one
has been set in the TPM itself.
The TPM memory address is added by the driver and declared in the
ACPI code. In order to access it in ACPI a Kconfig entry is added for
the default TPM TIS 1.2 base address. Note that IO address 0x2e is
required to be declared in ACPI for the kernel driver to probe correctly.
BUG=chrome-os-partner:33385
BRANCH=samus,auron
TEST=manual testing on samus:
1) Add TPM device in devicetree.cb with configured interrupt and
ensure that it is functional in the OS.
2) Test with active high and active low, edge triggered and level
triggered setups.
3) Ensure that with no device added to devicetree.cb that the TPM
is still functional in polling mode.
Change-Id: Iee2a1832394dfe32f3ea3700753b8ecc443c7fbf
Signed-off-by: Stefan Reinauer <reinauer@chromium.org>
Original-Commit-Id: fc2c106caae939467fb07f3a0207adee71dda48e
Original-Change-Id: Id8a5a251f193c71ab2209f85fb470120a3b6a80d
Original-Signed-off-by: Duncan Laurie <dlaurie@chromium.org>
Original-Reviewed-on: https://chromium-review.googlesource.com/226661
Original-Reviewed-by: Aaron Durbin <adurbin@chromium.org>
Reviewed-on: http://review.coreboot.org/9469
Tested-by: build bot (Jenkins)
Reviewed-by: Patrick Georgi <pgeorgi@google.com>
Diffstat (limited to 'src/drivers/pc80/tpm/acpi')
-rw-r--r-- | src/drivers/pc80/tpm/acpi/tpm.asl | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/src/drivers/pc80/tpm/acpi/tpm.asl b/src/drivers/pc80/tpm/acpi/tpm.asl new file mode 100644 index 0000000000..7500211570 --- /dev/null +++ b/src/drivers/pc80/tpm/acpi/tpm.asl @@ -0,0 +1,104 @@ +/* + * This file is part of the coreboot project. + * + * Copyright (C) 2014 Google Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA + */ + +/* Trusted Platform Module */ + +Device (TPM) +{ + Name (_HID, EISAID ("PNP0C31")) + Name (_CID, 0x310cd041) + Name (_UID, 1) + + Method (_STA, 0) + { + If (CONFIG_LPC_TPM) { + Return (0xf) + } Else { + Return (0x0) + } + } + + Name (IBUF, ResourceTemplate () + { + /* Updated based on TPM interrupt for Locality 0 */ + Interrupt (ResourceConsumer, Edge, ActiveHigh, + Exclusive, , , TIRQ) { 0 } + }) + + Name (RBUF, ResourceTemplate () + { + IO (Decode16, 0x2e, 0x2e, 0x01, 0x02) + Memory32Fixed (ReadWrite, CONFIG_TPM_TIS_BASE_ADDRESS, 0x5000) + }) + + Method (_CRS, 0, NotSerialized) + { + OperationRegion (TREG, SystemMemory, + CONFIG_TPM_TIS_BASE_ADDRESS, 0x5000) + Field (TREG, ByteAcc, NoLock, Preserve) + { + /* TPM_INT_ENABLE_0 */ + Offset (0x0008), + , 3, + ITPL, 2, /* Interrupt type and polarity */ + + /* TPM_INT_VECTOR_0 */ + Offset (0x000C), + IVEC, 4, /* SERIRQ vector */ + } + + If (LGreater (IVEC, 0)) { + /* Update interrupt vector */ + CreateField (^IBUF, ^TIRQ._INT, 32, TVEC) + Store (IVEC, TVEC) + + /* Update interrupt type and polarity */ + CreateBitField (^IBUF, ^TIRQ._HE, TTYP) + CreateBitField (^IBUF, ^TIRQ._LL, TPOL) + CreateBitField (^IBUF, ^TIRQ._SHR, TSHR) + + If (LEqual (ITPL, 0x0)) { + /* Active-High Level-Triggered Shared */ + Store (Zero, TPOL) + Store (Zero, TTYP) + Store (One, TSHR) + } ElseIf (LEqual (ITPL, 0x1)) { + /* Active-Low Level-Triggered Shared */ + Store (One, TPOL) + Store (Zero, TTYP) + Store (One, TSHR) + } ElseIf (LEqual (ITPL, 0x2)) { + /* Active-High Edge-Triggered Exclusive */ + Store (Zero, TPOL) + Store (One, TTYP) + Store (Zero, TSHR) + } ElseIf (LEqual (ITPL, 0x3)) { + /* Active-Low Edge-Triggered Exclusive */ + Store (One, TPOL) + Store (One, TTYP) + Store (Zero, TSHR) + } + + /* Merge IRQ with base address */ + Return (ConcatenateResTemplate (RBUF, IBUF)) + } Else { + Return (RBUF) + } + } +} |