REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3169 This change separated the original Tcg2Smm module into 2 drivers: the SMM driver that registers callback for physical presence and memory clear; the Tcg2Acpi driver that patches and publishes ACPI table for runtime use. Tcg2Smm introduced an SMI root handler to allow Tcg2Acpi to communicate the NVS region used by Tpm.asl and exchange the registered SwSmiValue. Lastly, Tcg2Smm driver will publish gTcg2MmSwSmiRegisteredGuid at the end of entrypoint to ensure Tcg2Acpi to load after Tcg2Smm is ready to communicate. Cc: Jiewen Yao <jiewen.yao@intel.com> Cc: Jian J Wang <jian.j.wang@intel.com> Cc: Qi Zhang <qi1.zhang@intel.com> Cc: Rahul Kumar <rahul1.kumar@intel.com> Signed-off-by: Kun Qin <kun.q@outlook.com> Reviewed-by: Jiewen Yao <Jiewen.yao@intel.com> Message-Id: <MWHPR06MB310295CC623EF7C062844DFFF3969@MWHPR06MB3102.namprd06.prod.outlook.com>
518 lines
14 KiB
Plaintext
518 lines
14 KiB
Plaintext
/** @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})
|
|
}
|
|
}
|
|
}
|
|
}
|