/** @file | |
The TPM2 definition block in ACPI table for TCG2 physical presence | |
and MemoryClear. | |
Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR> | |
(c)Copyright 2016 HP Development Company, L.P.<BR> | |
Copyright (c) Microsoft Corporation.<BR> | |
SPDX-License-Identifier: BSD-2-Clause-Patent | |
**/ | |
DefinitionBlock ( | |
"Tpm.aml", | |
"SSDT", | |
2, | |
"INTEL ", | |
"Tpm2Tabl", | |
0x1000 | |
) | |
{ | |
Scope (\_SB) | |
{ | |
Device (TPM) | |
{ | |
// | |
// TCG2 | |
// | |
// | |
// TAG for patching TPM2.0 _HID | |
// | |
Name (_HID, "NNNN0000") | |
Name (_CID, "MSFT0101") | |
// | |
// Readable name of this device, don't know if this way is correct yet | |
// | |
Name (_STR, Unicode ("TPM 2.0 Device")) | |
// | |
// Operational region for Smi port access | |
// | |
OperationRegion (SMIP, SystemIO, FixedPcdGet16 (PcdSmiCommandIoPort), 1) | |
Field (SMIP, ByteAcc, NoLock, Preserve) | |
{ | |
IOPN, 8 | |
} | |
// | |
// Operational region for TPM access | |
// | |
OperationRegion (TPMR, SystemMemory, 0xfed40000, 0x5000) | |
Field (TPMR, AnyAcc, NoLock, Preserve) | |
{ | |
ACC0, 8, // TPM_ACCESS_0 | |
Offset(0x8), | |
INTE, 32, // TPM_INT_ENABLE_0 | |
INTV, 8, // TPM_INT_VECTOR_0 | |
Offset(0x10), | |
INTS, 32, // TPM_INT_STATUS_0 | |
INTF, 32, // TPM_INTF_CAPABILITY_0 | |
STS0, 32, // TPM_STS_0 | |
Offset(0x24), | |
FIFO, 32, // TPM_DATA_FIFO_0 | |
Offset(0x30), | |
TID0, 32, // TPM_INTERFACE_ID_0 | |
// ignore the rest | |
} | |
// | |
// Operational region for TPM support, TPM Physical Presence and TPM Memory Clear | |
// Region Offset 0xFFFF0000 and Length 0xF0 will be fixed in C code. | |
// | |
OperationRegion (TNVS, SystemMemory, 0xFFFF0000, 0xF0) | |
Field (TNVS, AnyAcc, NoLock, Preserve) | |
{ | |
PPIN, 8, // Software SMI for Physical Presence Interface | |
PPIP, 32, // Used for save physical presence parameter | |
PPRP, 32, // Physical Presence request operation response | |
PPRQ, 32, // Physical Presence request operation | |
PPRM, 32, // Physical Presence request operation parameter | |
LPPR, 32, // Last Physical Presence request operation | |
FRET, 32, // Physical Presence function return code | |
MCIN, 8, // Software SMI for Memory Clear Interface | |
MCIP, 32, // Used for save the Mor parameter | |
MORD, 32, // Memory Overwrite Request Data | |
MRET, 32, // Memory Overwrite function return code | |
UCRQ, 32, // Physical Presence request operation to Get User Confirmation Status | |
IRQN, 32, // IRQ Number for _CRS | |
SFRB, 8 // Is shortformed Pkglength for resource buffer | |
} | |
// | |
// Possible resource settings returned by _PRS method | |
// RESS : ResourceTemplate with PkgLength <=63 | |
// RESL : ResourceTemplate with PkgLength > 63 | |
// | |
// The format of the data has to follow the same format as | |
// _CRS (according to ACPI spec). | |
// | |
Name (RESS, ResourceTemplate() { | |
Memory32Fixed (ReadWrite, 0xfed40000, 0x5000) | |
Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {1,2,3,4,5,6,7,8,9,10} | |
}) | |
Name (RESL, ResourceTemplate() { | |
Memory32Fixed (ReadWrite, 0xfed40000, 0x5000) | |
Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15} | |
}) | |
// | |
// Current resource settings for _CRS method | |
// | |
Name(RES0, ResourceTemplate () { | |
Memory32Fixed (ReadWrite, 0xfed40000, 0x5000, REG0) | |
Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , INTR) {12} | |
}) | |
Name(RES1, ResourceTemplate () { | |
Memory32Fixed (ReadWrite, 0xfed40000, 0x5000, REG1) | |
}) | |
// | |
// Return the resource consumed by TPM device. | |
// | |
Method(_CRS,0,Serialized) | |
{ | |
// | |
// IRQNum = 0 means disable IRQ support | |
// | |
If (LEqual(IRQN, 0)) { | |
Return (RES1) | |
} | |
Else | |
{ | |
CreateDWordField(RES0, ^INTR._INT, LIRQ) | |
Store(IRQN, LIRQ) | |
Return (RES0) | |
} | |
} | |
// | |
// Set resources consumed by the TPM device. This is used to | |
// assign an interrupt number to the device. The input byte stream | |
// has to be the same as returned by _CRS (according to ACPI spec). | |
// | |
// Platform may choose to override this function with specific interrupt | |
// programing logic to replace FIFO/TIS SIRQ registers programing | |
// | |
Method(_SRS,1,Serialized) | |
{ | |
// | |
// Do not configure Interrupt if IRQ Num is configured 0 by default | |
// | |
If (LNotEqual(IRQN, 0)) { | |
// | |
// Update resource descriptor | |
// Use the field name to identify the offsets in the argument | |
// buffer and RES0 buffer. | |
// | |
CreateDWordField(Arg0, ^INTR._INT, IRQ0) | |
CreateDWordField(RES0, ^INTR._INT, LIRQ) | |
Store(IRQ0, LIRQ) | |
Store(IRQ0, IRQN) | |
CreateBitField(Arg0, ^INTR._HE, ITRG) | |
CreateBitField(RES0, ^INTR._HE, LTRG) | |
Store(ITRG, LTRG) | |
CreateBitField(Arg0, ^INTR._LL, ILVL) | |
CreateBitField(RES0, ^INTR._LL, LLVL) | |
Store(ILVL, LLVL) | |
// | |
// Update TPM FIFO PTP/TIS interface only, identified by TPM_INTERFACE_ID_x lowest | |
// nibble. | |
// 0000 - FIFO interface as defined in PTP for TPM 2.0 is active | |
// 1111 - FIFO interface as defined in TIS1.3 is active | |
// | |
If (LOr(LEqual (And (TID0, 0x0F), 0x00), LEqual (And (TID0, 0x0F), 0x0F))) { | |
// | |
// If FIFO interface, interrupt vector register is | |
// available. TCG PTP specification allows only | |
// values 1..15 in this field. For other interrupts | |
// the field should stay 0. | |
// | |
If (LLess (IRQ0, 16)) { | |
Store (And(IRQ0, 0xF), INTV) | |
} | |
// | |
// Interrupt enable register (TPM_INT_ENABLE_x) bits 3:4 | |
// contains settings for interrupt polarity. | |
// The other bits of the byte enable individual interrupts. | |
// They should be all be zero, but to avoid changing the | |
// configuration, the other bits are be preserved. | |
// 00 - high level | |
// 01 - low level | |
// 10 - rising edge | |
// 11 - falling edge | |
// | |
// ACPI spec definitions: | |
// _HE: '1' is Edge, '0' is Level | |
// _LL: '1' is ActiveHigh, '0' is ActiveLow (inverted from TCG spec) | |
// | |
If (LEqual (ITRG, 1)) { | |
Or(INTE, 0x00000010, INTE) | |
} Else { | |
And(INTE, 0xFFFFFFEF, INTE) | |
} | |
if (LEqual (ILVL, 0)) { | |
Or(INTE, 0x00000008, INTE) | |
} Else { | |
And(INTE, 0xFFFFFFF7, INTE) | |
} | |
} | |
} | |
} | |
Method(_PRS,0,Serialized) | |
{ | |
// | |
// IRQNum = 0 means disable IRQ support | |
// | |
If (LEqual(IRQN, 0)) { | |
Return (RES1) | |
} ElseIf(LEqual(SFRB, 0)) { | |
// | |
// Long format. Possible resources PkgLength > 63 | |
// | |
Return (RESL) | |
} Else { | |
// | |
// Short format. Possible resources PkgLength <=63 | |
// | |
Return (RESS) | |
} | |
} | |
Method (PTS, 1, Serialized) | |
{ | |
// | |
// Detect Sx state for MOR, only S4, S5 need to handle | |
// | |
If (LAnd (LLess (Arg0, 6), LGreater (Arg0, 3))) | |
{ | |
// | |
// Bit4 -- DisableAutoDetect. 0 -- Firmware MAY autodetect. | |
// | |
If (LNot (And (MORD, 0x10))) | |
{ | |
// | |
// Trigger the SMI through ACPI _PTS method. | |
// | |
Store (0x02, MCIP) | |
// | |
// Trigger the SMI interrupt | |
// | |
Store (MCIN, IOPN) | |
} | |
} | |
Return (0) | |
} | |
Method (_STA, 0) | |
{ | |
if (LEqual (ACC0, 0xff)) | |
{ | |
Return (0) | |
} | |
Return (0x0f) | |
} | |
// | |
// TCG Hardware Information | |
// | |
Method (HINF, 1, Serialized, 0, {BuffObj, PkgObj}, {UnknownObj}) // IntObj | |
{ | |
// | |
// Switch by function index | |
// | |
Switch (ToInteger(Arg0)) | |
{ | |
Case (0) | |
{ | |
// | |
// Standard query | |
// | |
Return (Buffer () {0x03}) | |
} | |
Case (1) | |
{ | |
// | |
// Return failure if no TPM present | |
// | |
Name(TPMV, Package () {0x01, Package () {0x2, 0x0}}) | |
if (LEqual (_STA (), 0x00)) | |
{ | |
Return (Package () {0x00}) | |
} | |
// | |
// Return TPM version | |
// | |
Return (TPMV) | |
} | |
Default {BreakPoint} | |
} | |
Return (Buffer () {0}) | |
} | |
Name(TPM2, Package (0x02){ | |
Zero, | |
Zero | |
}) | |
Name(TPM3, Package (0x03){ | |
Zero, | |
Zero, | |
Zero | |
}) | |
// | |
// TCG Physical Presence Interface | |
// | |
Method (TPPI, 2, Serialized, 0, {BuffObj, PkgObj, IntObj, StrObj}, {UnknownObj, UnknownObj}) // IntObj, PkgObj | |
{ | |
// | |
// Switch by function index | |
// | |
Switch (ToInteger(Arg0)) | |
{ | |
Case (0) | |
{ | |
// | |
// Standard query, supports function 1-8 | |
// | |
Return (Buffer () {0xFF, 0x01}) | |
} | |
Case (1) | |
{ | |
// | |
// a) Get Physical Presence Interface Version | |
// | |
Return ("$PV") | |
} | |
Case (2) | |
{ | |
// | |
// b) Submit TPM Operation Request to Pre-OS Environment | |
// | |
Store (DerefOf (Index (Arg1, 0x00)), PPRQ) | |
Store (0, PPRM) | |
Store (0x02, PPIP) | |
// | |
// Trigger the SMI interrupt | |
// | |
Store (PPIN, IOPN) | |
Return (FRET) | |
} | |
Case (3) | |
{ | |
// | |
// c) Get Pending TPM Operation Requested By the OS | |
// | |
Store (PPRQ, Index (TPM2, 0x01)) | |
Return (TPM2) | |
} | |
Case (4) | |
{ | |
// | |
// d) Get Platform-Specific Action to Transition to Pre-OS Environment | |
// | |
Return (2) | |
} | |
Case (5) | |
{ | |
// | |
// e) Return TPM Operation Response to OS Environment | |
// | |
Store (0x05, PPIP) | |
// | |
// Trigger the SMI interrupt | |
// | |
Store (PPIN, IOPN) | |
Store (LPPR, Index (TPM3, 0x01)) | |
Store (PPRP, Index (TPM3, 0x02)) | |
Return (TPM3) | |
} | |
Case (6) | |
{ | |
// | |
// f) Submit preferred user language (Not implemented) | |
// | |
Return (3) | |
} | |
Case (7) | |
{ | |
// | |
// g) Submit TPM Operation Request to Pre-OS Environment 2 | |
// | |
Store (7, PPIP) | |
Store (DerefOf (Index (Arg1, 0x00)), PPRQ) | |
Store (0, PPRM) | |
If (LEqual (PPRQ, 23)) { | |
Store (DerefOf (Index (Arg1, 0x01)), PPRM) | |
} | |
// | |
// Trigger the SMI interrupt | |
// | |
Store (PPIN, IOPN) | |
Return (FRET) | |
} | |
Case (8) | |
{ | |
// | |
// e) Get User Confirmation Status for Operation | |
// | |
Store (8, PPIP) | |
Store (DerefOf (Index (Arg1, 0x00)), UCRQ) | |
// | |
// Trigger the SMI interrupt | |
// | |
Store (PPIN, IOPN) | |
Return (FRET) | |
} | |
Default {BreakPoint} | |
} | |
Return (1) | |
} | |
Method (TMCI, 2, Serialized, 0, IntObj, {UnknownObj, UnknownObj}) // IntObj, PkgObj | |
{ | |
// | |
// Switch by function index | |
// | |
Switch (ToInteger (Arg0)) | |
{ | |
Case (0) | |
{ | |
// | |
// Standard query, supports function 1-1 | |
// | |
Return (Buffer () {0x03}) | |
} | |
Case (1) | |
{ | |
// | |
// Save the Operation Value of the Request to MORD (reserved memory) | |
// | |
Store (DerefOf (Index (Arg1, 0x00)), MORD) | |
// | |
// Trigger the SMI through ACPI _DSM method. | |
// | |
Store (0x01, MCIP) | |
// | |
// Trigger the SMI interrupt | |
// | |
Store (MCIN, IOPN) | |
Return (MRET) | |
} | |
Default {BreakPoint} | |
} | |
Return (1) | |
} | |
Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj, PkgObj}) | |
{ | |
// | |
// TCG Hardware Information | |
// | |
If(LEqual(Arg0, ToUUID ("cf8e16a5-c1e8-4e25-b712-4f54a96702c8"))) | |
{ | |
Return (HINF (Arg2)) | |
} | |
// | |
// TCG Physical Presence Interface | |
// | |
If(LEqual(Arg0, ToUUID ("3dddfaa6-361b-4eb4-a424-8d10089d1653"))) | |
{ | |
Return (TPPI (Arg2, Arg3)) | |
} | |
// | |
// TCG Memory Clear Interface | |
// | |
If(LEqual(Arg0, ToUUID ("376054ed-cc13-4675-901c-4756d7f2d45d"))) | |
{ | |
Return (TMCI (Arg2, Arg3)) | |
} | |
Return (Buffer () {0}) | |
} | |
} | |
} | |
} |