1/** @file
2  The TPM2 definition block in ACPI table for TCG2 physical presence
3  and MemoryClear.
4
5Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
6(c)Copyright 2016 HP Development Company, L.P.<BR>
7Copyright (c) 2017, Microsoft Corporation.  All rights reserved. <BR>
8SPDX-License-Identifier: BSD-2-Clause-Patent
9
10**/
11
12DefinitionBlock (
13  "Tpm.aml",
14  "SSDT",
15  2,
16  "INTEL ",
17  "Tpm2Tabl",
18  0x1000
19  )
20{
21  Scope (\_SB)
22  {
23    Device (TPM)
24    {
25      //
26      // TCG2
27      //
28
29      //
30      //  TAG for patching TPM2.0 _HID
31      //
32      Name (_HID, "NNNN0000")
33
34      Name (_CID, "MSFT0101")
35
36      //
37      // Readable name of this device, don't know if this way is correct yet
38      //
39      Name (_STR, Unicode ("TPM 2.0 Device"))
40
41      //
42      // Operational region for Smi port access
43      //
44      OperationRegion (SMIP, SystemIO, 0xB2, 1)
45      Field (SMIP, ByteAcc, NoLock, Preserve)
46      {
47          IOB2, 8
48      }
49
50      //
51      // Operational region for TPM access
52      //
53      OperationRegion (TPMR, SystemMemory, 0xfed40000, 0x5000)
54      Field (TPMR, AnyAcc, NoLock, Preserve)
55      {
56        ACC0, 8,  // TPM_ACCESS_0
57        Offset(0x8),
58        INTE, 32, // TPM_INT_ENABLE_0
59        INTV, 8,  // TPM_INT_VECTOR_0
60        Offset(0x10),
61        INTS, 32, // TPM_INT_STATUS_0
62        INTF, 32, // TPM_INTF_CAPABILITY_0
63        STS0, 32, // TPM_STS_0
64        Offset(0x24),
65        FIFO, 32, // TPM_DATA_FIFO_0
66        Offset(0x30),
67        TID0, 32, // TPM_INTERFACE_ID_0
68                  // ignore the rest
69      }
70
71      //
72      // Operational region for TPM support, TPM Physical Presence and TPM Memory Clear
73      // Region Offset 0xFFFF0000 and Length 0xF0 will be fixed in C code.
74      //
75      OperationRegion (TNVS, SystemMemory, 0xFFFF0000, 0xF0)
76      Field (TNVS, AnyAcc, NoLock, Preserve)
77      {
78        PPIN,   8,  //   Software SMI for Physical Presence Interface
79        PPIP,   32, //   Used for save physical presence paramter
80        PPRP,   32, //   Physical Presence request operation response
81        PPRQ,   32, //   Physical Presence request operation
82        PPRM,   32, //   Physical Presence request operation parameter
83        LPPR,   32, //   Last Physical Presence request operation
84        FRET,   32, //   Physical Presence function return code
85        MCIN,   8,  //   Software SMI for Memory Clear Interface
86        MCIP,   32, //   Used for save the Mor paramter
87        MORD,   32, //   Memory Overwrite Request Data
88        MRET,   32, //   Memory Overwrite function return code
89        UCRQ,   32, //   Phyical Presence request operation to Get User Confirmation Status
90        IRQN,   32, //   IRQ Number for _CRS
91        SFRB,   8   //   Is shortformed Pkglength for resource buffer
92      }
93
94      //
95      // Possible resource settings returned by  _PRS method
96      //   RESS : ResourceTemplate with PkgLength <=63
97      //   RESL : ResourceTemplate with PkgLength > 63
98      //
99      // The format of the data has to follow the same format as
100      // _CRS (according to ACPI spec).
101      //
102      Name (RESS, ResourceTemplate() {
103        Memory32Fixed (ReadWrite, 0xfed40000, 0x5000)
104        Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {1,2,3,4,5,6,7,8,9,10}
105      })
106
107      Name (RESL, ResourceTemplate() {
108        Memory32Fixed (ReadWrite, 0xfed40000, 0x5000)
109        Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , ) {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15}
110      })
111
112      //
113      // Current resource settings for _CRS method
114      //
115      Name(RES0, ResourceTemplate () {
116        Memory32Fixed (ReadWrite, 0xfed40000, 0x5000, REG0)
117        Interrupt(ResourceConsumer, Level, ActiveLow, Shared, , , INTR) {12}
118      })
119
120      Name(RES1, ResourceTemplate () {
121        Memory32Fixed (ReadWrite, 0xfed40000, 0x5000, REG1)
122      })
123
124
125      //
126      // Return the resource consumed by TPM device.
127      //
128      Method(_CRS,0,Serialized)
129      {
130        //
131        // IRQNum = 0 means disable IRQ support
132        //
133        If (LEqual(IRQN, 0)) {
134          Return (RES1)
135        }
136        Else
137        {
138          CreateDWordField(RES0, ^INTR._INT, LIRQ)
139          Store(IRQN, LIRQ)
140          Return (RES0)
141        }
142      }
143
144      //
145      // Set resources consumed by the TPM device. This is used to
146      // assign an interrupt number to the device. The input byte stream
147      // has to be the same as returned by _CRS (according to ACPI spec).
148      //
149      // Platform may choose to override this function with specific interrupt
150      // programing logic to replace FIFO/TIS SIRQ registers programing
151      //
152      Method(_SRS,1,Serialized)
153      {
154        //
155        // Do not configure Interrupt if IRQ Num is configured 0 by default
156        //
157        If (LNotEqual(IRQN, 0)) {
158          //
159          // Update resource descriptor
160          // Use the field name to identify the offsets in the argument
161          // buffer and RES0 buffer.
162          //
163          CreateDWordField(Arg0, ^INTR._INT, IRQ0)
164          CreateDWordField(RES0, ^INTR._INT, LIRQ)
165          Store(IRQ0, LIRQ)
166          Store(IRQ0, IRQN)
167
168          CreateBitField(Arg0, ^INTR._HE, ITRG)
169          CreateBitField(RES0, ^INTR._HE, LTRG)
170          Store(ITRG, LTRG)
171
172          CreateBitField(Arg0, ^INTR._LL, ILVL)
173          CreateBitField(RES0, ^INTR._LL, LLVL)
174          Store(ILVL, LLVL)
175
176          //
177          // Update TPM FIFO PTP/TIS interface only, identified by TPM_INTERFACE_ID_x lowest
178          // nibble.
179          // 0000 - FIFO interface as defined in PTP for TPM 2.0 is active
180          // 1111 - FIFO interface as defined in TIS1.3 is active
181          //
182          If (LOr(LEqual (And (TID0, 0x0F), 0x00), LEqual (And (TID0, 0x0F), 0x0F))) {
183            //
184            // If FIFO interface, interrupt vector register is
185            // available. TCG PTP specification allows only
186            // values 1..15 in this field. For other interrupts
187            // the field should stay 0.
188            //
189            If (LLess (IRQ0, 16)) {
190              Store (And(IRQ0, 0xF), INTV)
191            }
192            //
193            // Interrupt enable register (TPM_INT_ENABLE_x) bits 3:4
194            // contains settings for interrupt polarity.
195            // The other bits of the byte enable individual interrupts.
196            // They should be all be zero, but to avoid changing the
197            // configuration, the other bits are be preserved.
198            // 00 - high level
199            // 01 - low level
200            // 10 - rising edge
201            // 11 - falling edge
202            //
203            // ACPI spec definitions:
204            // _HE: '1' is Edge, '0' is Level
205            // _LL: '1' is ActiveHigh, '0' is ActiveLow (inverted from TCG spec)
206            //
207            If (LEqual (ITRG, 1)) {
208              Or(INTE, 0x00000010, INTE)
209            } Else {
210              And(INTE, 0xFFFFFFEF, INTE)
211            }
212            if (LEqual (ILVL, 0)) {
213              Or(INTE, 0x00000008, INTE)
214            } Else {
215              And(INTE, 0xFFFFFFF7, INTE)
216            }
217          }
218        }
219      }
220
221      Method(_PRS,0,Serialized)
222      {
223        //
224        // IRQNum = 0 means disable IRQ support
225        //
226        If (LEqual(IRQN, 0)) {
227          Return (RES1)
228        } ElseIf(LEqual(SFRB, 0)) {
229          //
230          // Long format. Possible resources PkgLength > 63
231          //
232          Return (RESL)
233        } Else {
234          //
235          // Short format. Possible resources PkgLength <=63
236          //
237          Return (RESS)
238        }
239      }
240
241      Method (PTS, 1, Serialized)
242      {
243        //
244        // Detect Sx state for MOR, only S4, S5 need to handle
245        //
246        If (LAnd (LLess (Arg0, 6), LGreater (Arg0, 3)))
247        {
248          //
249          // Bit4 -- DisableAutoDetect. 0 -- Firmware MAY autodetect.
250          //
251          If (LNot (And (MORD, 0x10)))
252          {
253            //
254            // Trigger the SMI through ACPI _PTS method.
255            //
256            Store (0x02, MCIP)
257
258            //
259            // Trigger the SMI interrupt
260            //
261            Store (MCIN, IOB2)
262          }
263        }
264        Return (0)
265      }
266
267      Method (_STA, 0)
268      {
269        if (LEqual (ACC0, 0xff))
270        {
271            Return (0)
272        }
273        Return (0x0f)
274      }
275
276      //
277      // TCG Hardware Information
278      //
279      Method (HINF, 1, Serialized, 0, {BuffObj, PkgObj}, {UnknownObj}) // IntObj
280      {
281        //
282        // Switch by function index
283        //
284        Switch (ToInteger(Arg0))
285        {
286          Case (0)
287          {
288            //
289            // Standard query
290            //
291            Return (Buffer () {0x03})
292          }
293          Case (1)
294          {
295            //
296            // Return failure if no TPM present
297            //
298            Name(TPMV, Package () {0x01, Package () {0x2, 0x0}})
299            if (LEqual (_STA (), 0x00))
300            {
301              Return (Package () {0x00})
302            }
303
304            //
305            // Return TPM version
306            //
307            Return (TPMV)
308          }
309          Default {BreakPoint}
310        }
311        Return (Buffer () {0})
312      }
313
314      Name(TPM2, Package (0x02){
315        Zero,
316        Zero
317      })
318
319      Name(TPM3, Package (0x03){
320        Zero,
321        Zero,
322        Zero
323      })
324
325      //
326      // TCG Physical Presence Interface
327      //
328      Method (TPPI, 2, Serialized, 0, {BuffObj, PkgObj, IntObj, StrObj}, {UnknownObj, UnknownObj}) // IntObj, PkgObj
329      {
330        //
331        // Switch by function index
332        //
333        Switch (ToInteger(Arg0))
334        {
335          Case (0)
336          {
337            //
338            // Standard query, supports function 1-8
339            //
340            Return (Buffer () {0xFF, 0x01})
341          }
342          Case (1)
343          {
344            //
345            // a) Get Physical Presence Interface Version
346            //
347            Return ("$PV")
348          }
349          Case (2)
350          {
351            //
352            // b) Submit TPM Operation Request to Pre-OS Environment
353            //
354
355            Store (DerefOf (Index (Arg1, 0x00)), PPRQ)
356            Store (0, PPRM)
357            Store (0x02, PPIP)
358
359            //
360            // Trigger the SMI interrupt
361            //
362            Store (PPIN, IOB2)
363            Return (FRET)
364
365
366          }
367          Case (3)
368          {
369            //
370            // c) Get Pending TPM Operation Requested By the OS
371            //
372
373            Store (PPRQ, Index (TPM2, 0x01))
374            Return (TPM2)
375          }
376          Case (4)
377          {
378            //
379            // d) Get Platform-Specific Action to Transition to Pre-OS Environment
380            //
381            Return (2)
382          }
383          Case (5)
384          {
385            //
386            // e) Return TPM Operation Response to OS Environment
387            //
388            Store (0x05, PPIP)
389
390            //
391            // Trigger the SMI interrupt
392            //
393            Store (PPIN, IOB2)
394
395            Store (LPPR, Index (TPM3, 0x01))
396            Store (PPRP, Index (TPM3, 0x02))
397
398            Return (TPM3)
399          }
400          Case (6)
401          {
402
403            //
404            // f) Submit preferred user language (Not implemented)
405            //
406
407            Return (3)
408
409          }
410          Case (7)
411          {
412            //
413            // g) Submit TPM Operation Request to Pre-OS Environment 2
414            //
415            Store (7, PPIP)
416            Store (DerefOf (Index (Arg1, 0x00)), PPRQ)
417            Store (0, PPRM)
418            If (LEqual (PPRQ, 23)) {
419              Store (DerefOf (Index (Arg1, 0x01)), PPRM)
420            }
421
422            //
423            // Trigger the SMI interrupt
424            //
425            Store (PPIN, IOB2)
426            Return (FRET)
427          }
428          Case (8)
429          {
430            //
431            // e) Get User Confirmation Status for Operation
432            //
433            Store (8, PPIP)
434            Store (DerefOf (Index (Arg1, 0x00)), UCRQ)
435
436            //
437            // Trigger the SMI interrupt
438            //
439            Store (PPIN, IOB2)
440
441            Return (FRET)
442          }
443
444          Default {BreakPoint}
445        }
446        Return (1)
447      }
448
449      Method (TMCI, 2, Serialized, 0, IntObj, {UnknownObj, UnknownObj}) // IntObj, PkgObj
450      {
451        //
452        // Switch by function index
453        //
454        Switch (ToInteger (Arg0))
455        {
456          Case (0)
457          {
458            //
459            // Standard query, supports function 1-1
460            //
461            Return (Buffer () {0x03})
462          }
463          Case (1)
464          {
465            //
466            // Save the Operation Value of the Request to MORD (reserved memory)
467            //
468            Store (DerefOf (Index (Arg1, 0x00)), MORD)
469
470            //
471            // Trigger the SMI through ACPI _DSM method.
472            //
473            Store (0x01, MCIP)
474
475            //
476            // Trigger the SMI interrupt
477            //
478            Store (MCIN, IOB2)
479            Return (MRET)
480          }
481          Default {BreakPoint}
482        }
483        Return (1)
484      }
485
486      Method (_DSM, 4, Serialized, 0, UnknownObj, {BuffObj, IntObj, IntObj, PkgObj})
487      {
488
489        //
490        // TCG Hardware Information
491        //
492        If(LEqual(Arg0, ToUUID ("cf8e16a5-c1e8-4e25-b712-4f54a96702c8")))
493        {
494          Return (HINF (Arg2))
495        }
496
497        //
498        // TCG Physical Presence Interface
499        //
500        If(LEqual(Arg0, ToUUID ("3dddfaa6-361b-4eb4-a424-8d10089d1653")))
501        {
502          Return (TPPI (Arg2, Arg3))
503        }
504
505        //
506        // TCG Memory Clear Interface
507        //
508        If(LEqual(Arg0, ToUUID ("376054ed-cc13-4675-901c-4756d7f2d45d")))
509        {
510          Return (TMCI (Arg2, Arg3))
511        }
512
513        Return (Buffer () {0})
514      }
515    }
516  }
517}
518