/** @file The TPM2 definition block in ACPI table for TCG2 physical presence and MemoryClear. Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.
(c)Copyright 2016 HP Development Company, L.P.
Copyright (c) 2017, Microsoft Corporation. All rights reserved.
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, 0xB2, 1) Field (SMIP, ByteAcc, NoLock, Preserve) { IOB2, 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, IOB2) } } 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, IOB2) 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, IOB2) 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, IOB2) 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, IOB2) 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, IOB2) 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}) } } } }