1 /* SPDX-License-Identifier: GPL-2.0-only */
4 #include <acpi/acpigen.h>
5 #include <acpi/acpi_device.h>
7 #include <console/console.h>
8 #include <security/tpm/tss.h>
12 #define BCD(x, y) (((x) << 4) | ((y) << 0))
14 static void set_package_element_op(const char *package_name
, unsigned int element
,
17 acpigen_write_store();
18 acpigen_emit_byte(src_op
);
19 acpigen_emit_byte(INDEX_OP
);
20 acpigen_emit_namestring(package_name
);
21 acpigen_write_integer(element
);
22 acpigen_emit_byte(ZERO_OP
); /* Ignore Index() Destination */
25 static void set_package_element_name(const char *package_name
, unsigned int element
,
28 acpigen_write_store();
29 acpigen_emit_namestring(src
);
30 acpigen_emit_byte(INDEX_OP
);
31 acpigen_emit_namestring(package_name
);
32 acpigen_write_integer(element
);
33 acpigen_emit_byte(ZERO_OP
); /* Ignore Index() Destination */
36 /* PPI function is passed in src_op. Converted to Local2. Clobbers Local1 and Local2 */
37 static void verify_supported_ppi(uint8_t src_op
)
39 enum tpm_family family
= tlcl_get_family();
42 * Old OSes incorrectly pass a Buffer instead of a Package.
43 * See TCG Physical Presence Interface Specification Chapter 8.1.2 for details.
46 /* If (ObjectType(Arg3) == Package) */
47 acpigen_write_store();
48 acpigen_emit_byte(OBJ_TYPE_OP
);
49 acpigen_emit_byte(src_op
);
50 acpigen_emit_byte(LOCAL1_OP
);
51 acpigen_write_if_lequal_op_int(LOCAL1_OP
, 4);
52 acpigen_get_package_op_element(src_op
, 0, LOCAL2_OP
);
55 /* If (ObjectType(Arg3) == Buffer) */
56 acpigen_write_store();
57 acpigen_emit_byte(OBJ_TYPE_OP
);
58 acpigen_emit_byte(src_op
);
59 acpigen_emit_byte(LOCAL1_OP
);
60 acpigen_write_if_lequal_op_int(LOCAL1_OP
, 3);
61 acpigen_write_to_integer(src_op
, LOCAL2_OP
);
64 /* Check if it's a valid PPI function */
65 acpigen_write_store();
66 acpigen_emit_namestring("^FSUP");
67 acpigen_emit_byte(LOCAL2_OP
);
68 acpigen_emit_byte(family
== TPM_1
? ONE_OP
: ZERO_OP
);
69 acpigen_emit_byte(LOCAL1_OP
);
70 acpigen_write_if_lequal_op_int(LOCAL1_OP
, 0);
73 * Note: Must fake success for 1-4, 6-13, 15-16, 19-20
74 * see "Trusted Execution Environment ACPI Profile"
76 * Even if not available, the TPM 1.2 PPI must be advertised as
77 * supported. Tests showed that Windows relies on it, even when
78 * a TPM2.0 is present!
79 * The functions aren't actually used when a TPM2.0 is present...
80 * Without this the Windows TPM 2.0 stack refuses to work.
84 * Check if we have TPM1.2 but a TPM2 PPI function was called
85 * or if we have TPM2.0 but a TPM1.2 PPI function was called.
87 acpigen_write_store();
88 acpigen_emit_namestring("^FSUP");
89 acpigen_emit_byte(LOCAL2_OP
);
90 acpigen_emit_byte(family
== TPM_1
? ZERO_OP
: ONE_OP
);
91 acpigen_emit_byte(LOCAL1_OP
);
93 acpigen_write_if_lequal_op_int(LOCAL1_OP
, 1);
94 acpigen_write_return_integer(PPI2_RET_SUCCESS
); /* As per TPM spec */
96 acpigen_write_return_integer(PPI2_RET_NOT_SUPPORTED
);
101 /* TPM PPI functions */
103 static void tpm_ppi_func0_cb(void *arg
)
106 u8 buf
[] = {0xff, 0x01};
107 acpigen_write_return_byte_buffer(buf
, 2);
111 * PPI 1.0: 2.1.1 Get Physical Presence Interface Version
113 * Arg2 (Integer): Function Index = 1
114 * Arg3 (Package): Arguments = Empty Package
116 * Returns: Type: String
118 static void tpm_ppi_func1_cb(void *arg
)
120 if (tlcl_get_family() == TPM_2
)
121 /* Interface version: 1.3 */
122 acpigen_write_return_string("1.3");
124 /* Interface version: 1.2 */
125 acpigen_write_return_string("1.2");
129 * Submit TPM Operation Request to Pre-OS Environment [Windows optional]
130 * PPI 1.0: 2.1.3 Submit TPM Operation Request to Pre-OS Environment
132 * Supported Revisions: 1
133 * Arg1 (Integer): Revision
134 * Arg2 (Integer): Function Index = 2
135 * Arg3 (Package): Arguments = Package: Type: Integer
136 * Operation Value of the Request
138 * Returns: Type: Integer
140 * 1: Operation Value of the Request Not Supported
143 static void tpm_ppi_func2_cb(void *arg
)
146 acpigen_write_to_integer(ARG1_OP
, LOCAL0_OP
);
147 acpigen_write_if_lequal_op_int(LOCAL0_OP
, 1);
149 /* Local2 = ConvertAndVerify(Arg3) */
150 verify_supported_ppi(ARG3_OP
);
152 acpigen_write_store_op_to_namestr(LOCAL2_OP
, "^CMDR");
153 acpigen_write_store_op_to_namestr(ZERO_OP
, "^OARG");
154 acpigen_write_store_op_to_namestr(ZERO_OP
, "^USER");
156 acpigen_write_return_integer(PPI2_RET_SUCCESS
);
159 acpigen_write_return_integer(PPI2_RET_GENERAL_FAILURE
);
163 * PPI 1.0: 2.1.4 Get Pending TPM Operation Requested By the OS
165 * Supported Revisions: 1, 2
166 * Arg1 (Integer): Revision
167 * Arg2 (Integer): Function Index = 3
168 * Arg3 (Package): Empty package
170 * Returns: Type: Package(Integer, Integer, Integer (optional))
175 * Pending TPM operation requested by OS
177 * Pending TPM operation argument requested by OS
179 static void tpm_ppi_func3_cb(void *arg
)
181 acpigen_write_store();
182 acpigen_write_integer(PPI3_RET_GENERAL_FAILURE
);
183 acpigen_emit_byte(LOCAL0_OP
);
185 /* ^TPM3 [0] = PPI3_RET_GENERAL_FAILURE */
186 set_package_element_op("^TPM3", 0, LOCAL0_OP
);
188 /* ^TPM2 [0] = PPI3_RET_GENERAL_FAILURE */
189 set_package_element_op("^TPM2", 0, LOCAL0_OP
);
191 acpigen_write_to_integer(ARG1_OP
, LOCAL0_OP
);
194 acpigen_write_if_lequal_op_int(LOCAL0_OP
, 1);
196 /* ^TPM2 [0] = PPI3_RET_SUCCESS */
197 acpigen_write_store();
198 acpigen_write_integer(PPI3_RET_SUCCESS
);
199 acpigen_emit_byte(LOCAL1_OP
);
200 set_package_element_op("^TPM2", 0, LOCAL1_OP
);
202 /* ^TPM2 [1] = ^CMDR */
203 set_package_element_name("^TPM2", 1, "^CMDR");
205 acpigen_emit_byte(RETURN_OP
);
206 acpigen_emit_namestring("^TPM2");
210 * A return value of {0, 23, 1} indicates that operation 23
211 * with argument 1 is pending.
215 acpigen_write_if_lequal_op_int(LOCAL0_OP
, 2);
217 /* ^TPM3 [0] = PPI3_RET_SUCCESS */
218 acpigen_write_store();
219 acpigen_write_integer(PPI3_RET_SUCCESS
);
220 acpigen_emit_byte(LOCAL1_OP
);
221 set_package_element_op("^TPM3", 0, LOCAL1_OP
);
223 /* ^TPM3 [1] = ^CMDR */
224 set_package_element_name("^TPM3", 1, "^CMDR");
226 /* ^TPM3 [2] = ^OARG */
227 set_package_element_name("^TPM3", 2, "^OARG");
229 acpigen_emit_byte(RETURN_OP
);
230 acpigen_emit_namestring("^TPM3");
233 acpigen_emit_byte(RETURN_OP
);
234 acpigen_emit_namestring("^TPM3");
238 * PPI 1.0: 2.1.5 Get Platform-Specific Action to Transition to Pre-OS Environment
240 * Arg1 (Integer): Revision
241 * Arg2 (Integer): Function Index = 4
242 * Arg3 (Package): Empty package
244 * Returns: Type: Integer
250 static void tpm_ppi_func4_cb(void *arg
)
252 /* Pre-OS transition method: reboot. */
253 acpigen_write_return_byte(PPI4_RET_REBOOT
);
257 * PPI 1.0: 2.1.6 Return TPM Operation Response to OS Environment
259 * Supported Revisions: 1
260 * Arg1 (Integer): Revision
261 * Arg2 (Integer): Function Index = 5
262 * Arg3 (Package): Empty package
264 * Returns: Type: Package(Integer, Integer, Integer)
269 * Most recent TPM operation requested by OS
271 * Response to most recent TPM operation requested by OS
273 static void tpm_ppi_func5_cb(void *arg
)
275 /* ^TPM3 [0] = PPI5_RET_GENERAL_FAILURE */
276 acpigen_write_store();
277 acpigen_write_integer(PPI5_RET_GENERAL_FAILURE
);
278 acpigen_emit_byte(LOCAL1_OP
);
279 set_package_element_op("^TPM3", 0, LOCAL1_OP
);
281 acpigen_write_to_integer(ARG1_OP
, LOCAL0_OP
);
284 acpigen_write_if_lequal_op_int(LOCAL0_OP
, 1);
286 /* ^TPM3 [0] = PPI5_RET_SUCCESS */
287 acpigen_write_store();
288 acpigen_write_integer(PPI5_RET_SUCCESS
);
289 acpigen_emit_byte(LOCAL1_OP
);
290 set_package_element_op("^TPM3", 0, LOCAL1_OP
);
292 /* ^TPM3 [1] = ^LCMD */
293 set_package_element_name("^TPM3", 1, "^LCMD");
295 /* ^TPM3 [2] = ^RESU */
296 set_package_element_name("^TPM3", 2, "^RESU");
300 acpigen_emit_byte(RETURN_OP
);
301 acpigen_emit_namestring("^TPM3");
305 * PPI 1.2: 2.1.6 Submit preferred user language [Windows optional]
307 * Arg1 (Integer): Revision
308 * Arg2 (Integer): Function Index = 5
309 * Arg3 (Package): Empty package
311 static void tpm_ppi_func6_cb(void *arg
)
314 * Set preferred user language: deprecated and must return 3 aka
317 acpigen_write_return_byte(PPI6_RET_NOT_IMPLEMENTED
);
321 * PPI 1.2: 2.1.7 Submit TPM Operation Request to Pre-OS Environment 2
323 * Supported Revisions: 1, 2
324 * Arg1 (Integer): Revision
325 * Arg2 (Integer): Function Index = 7
326 * Arg3 (Package): Integer
328 * Returns: Type: Integer
332 * 3: Blocked by current BIOS settings
334 static void tpm_ppi_func7_cb(void *arg
)
336 acpigen_write_to_integer(ARG1_OP
, LOCAL0_OP
);
338 /* Local2 = ConvertAndVerify(Arg3) */
339 verify_supported_ppi(ARG3_OP
);
341 /* If (ObjectType(Arg3) == Buffer) */
342 acpigen_write_store();
343 acpigen_emit_byte(OBJ_TYPE_OP
);
344 acpigen_emit_byte(ARG3_OP
);
345 acpigen_emit_byte(LOCAL1_OP
);
346 acpigen_write_if_lequal_op_int(LOCAL1_OP
, 3);
348 /* Enforce use of Revision 1 that doesn't take an optional argument. */
351 acpigen_write_store();
352 acpigen_emit_byte(ONE_OP
);
353 acpigen_emit_byte(LOCAL0_OP
);
357 // FIXME: Only advertise supported functions
360 acpigen_write_if_lequal_op_int(LOCAL0_OP
, 1);
363 acpigen_write_store_op_to_namestr(LOCAL2_OP
, "^CMDR");
366 acpigen_write_store_op_to_namestr(ZERO_OP
, "^OARG");
368 acpigen_write_return_byte(PPI7_RET_SUCCESS
);
372 acpigen_write_if_lequal_op_int(LOCAL0_OP
, 2);
374 acpigen_write_store_op_to_namestr(LOCAL2_OP
, "^CMDR");
376 /* ^OARG = Arg3 [1] */
377 acpigen_get_package_op_element(ARG3_OP
, 1, LOCAL3_OP
);
378 acpigen_write_store();
379 acpigen_emit_byte(LOCAL3_OP
);
380 acpigen_emit_namestring("^OARG");
382 acpigen_write_return_byte(PPI7_RET_SUCCESS
);
385 acpigen_write_return_byte(PPI7_RET_GENERAL_FAILURE
);
389 * PPI 1.2: 2.1.8 Get User Confirmation Status for Operation
391 * Returns if a command is supported and allowed by firmware
392 * Supported Revisions: 1
393 * Arg1 (Integer): Revision
394 * Arg2 (Integer): Function Index = 7
395 * Arg3 (Package): Integer
397 * Returns: Type: Integer
400 * 2: Blocked for OS by BIOS settings
401 * 3: Allowed and physical present user required
402 * 4: Allowed and physical present user not required
404 static void tpm_ppi_func8_cb(void *arg
)
406 enum tpm_family family
= tlcl_get_family();
408 acpigen_write_to_integer(ARG1_OP
, LOCAL0_OP
);
411 acpigen_write_if_lequal_op_int(LOCAL0_OP
, 1);
412 acpigen_get_package_op_element(ARG3_OP
, 0, LOCAL2_OP
);
414 /* Check if it's a valid PPI function */
415 acpigen_write_store();
416 acpigen_emit_namestring("^FSUP");
417 acpigen_emit_byte(LOCAL2_OP
);
418 acpigen_emit_byte(family
== TPM_1
? ONE_OP
: ZERO_OP
);
419 acpigen_emit_byte(LOCAL1_OP
);
420 acpigen_write_if_lequal_op_int(LOCAL1_OP
, 0);
421 acpigen_write_return_byte(0); /* Not implemented */
424 // FIXME: Only advertise supported functions
426 if (family
== TPM_1
) {
428 * Some functions do not require PP depending on configuration.
429 * Those aren't listed here, so the 'required PP' is always set for those.
431 static const u32 tpm1_funcs
[] = {
433 TPM_SET_NOPPICLEAR_TRUE
,
434 TPM_SET_NOPPIMAINTAINANCE_TRUE
,
435 TPM_SET_NOPPIPROVISION_TRUE
,
437 for (size_t i
= 0; i
< ARRAY_SIZE(tpm1_funcs
); i
++) {
438 acpigen_write_if_lequal_op_int(LOCAL2_OP
, tpm1_funcs
[i
]);
439 acpigen_write_return_integer(PPI8_RET_ALLOWED
);
440 acpigen_pop_len(); /* Pop : If */
442 } else if (family
== TPM_2
) {
444 * Some functions do not require PP depending on configuration.
445 * Those aren't listed here, so the 'required PP' is always set for those.
447 static const u32 tpm2_funcs
[] = {
449 TPM2_SET_PP_REQUIRED_FOR_CLEAR_TRUE
,
450 TPM2_SET_PP_REQUIRED_FOR_CHANGE_PCRS_TRUE
,
451 TPM2_SET_PP_REQUIRED_FOR_TURN_ON_TRUE
,
452 TPM2_SET_PP_REQUIRED_FOR_CHANGE_EPS_TRUE
,
453 TPM2_SET_PP_REQUIRED_FOR_TURN_OFF_TRUE
,
454 TPM2_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_TRUE
,
455 TPM2_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_TRUE
,
457 for (size_t i
= 0; i
< ARRAY_SIZE(tpm2_funcs
); i
++) {
458 acpigen_write_if_lequal_op_int(LOCAL2_OP
, tpm2_funcs
[i
]);
459 acpigen_write_return_integer(PPI8_RET_ALLOWED
);
460 acpigen_pop_len(); /* Pop : If */
463 acpigen_write_return_integer(PPI8_RET_ALLOWED_WITH_PP
);
467 acpigen_write_return_integer(PPI8_RET_NOT_IMPLEMENTED
);
470 static void (*tpm_ppi_callbacks
[])(void *) = {
482 static void tpm_mci_func0_cb(void *arg
)
485 acpigen_write_return_singleton_buffer(0x3);
487 static void tpm_mci_func1_cb(void *arg
)
489 /* Just return success. */
490 acpigen_write_return_byte(0);
493 static void (*tpm_mci_callbacks
[])(void *) = {
498 void tpm_ppi_acpi_fill_ssdt(const struct device
*dev
)
500 struct cb_tpm_ppi_payload_handshake
*ppib
;
502 static const struct fieldlist list
[] = {
503 FIELDLIST_OFFSET(0x100),// FIXME: Add support for func
504 FIELDLIST_NAMESTR("PPIN", 8),// Not used
505 FIELDLIST_NAMESTR("PPIP", 32),// Not used
506 FIELDLIST_NAMESTR("RESU", 32),// Result of the last operation (TPM error code)
507 FIELDLIST_NAMESTR("CMDR", 32),// The command requested by OS. 0 for NOP
508 FIELDLIST_NAMESTR("OARG", 32),// The command optional argument requested by OS
509 FIELDLIST_NAMESTR("LCMD", 32),// The last command requested by OS.
510 FIELDLIST_NAMESTR("FRET", 32),// Not used
512 static const u8 tpm1_funcs
[] = {
520 TPM_DEACTIVATE_DISABLE
,
521 TPM_SETOWNERINSTALL_TRUE
,
522 TPM_SETOWNERINSTALL_FALSE
,
523 TPM_ENABLE_ACTIVATE_SETOWNERINSTALL_TRUE
,
524 TPM_SETOWNERINSTALL_FALSE_DEACTIVATE_DISABLE
,
525 TPM_CLEAR_ENABLE_ACTIVATE
,
526 TPM_SET_NOPPIPROVISION_FALSE
,
527 TPM_SET_NOPPIPROVISION_TRUE
,
528 TPM_ENABLE_ACTIVE_CLEAR
,
529 TPM_ENABLE_ACTIVE_CLEAR_ENABLE_ACTIVE
,
531 static const u8 tpm2_funcs
[] = {
536 TPM2_CLEAR_ENABLE_ACTIVE
,
537 TPM2_SET_PP_REQUIRED_FOR_CLEAR_TRUE
,
538 TPM2_SET_PP_REQUIRED_FOR_CLEAR_FALSE
,
543 TPM2_SET_PP_REQUIRED_FOR_CHANGE_PCRS_FALSE
,
544 TPM2_SET_PP_REQUIRED_FOR_CHANGE_PCRS_TRUE
,
545 TPM2_SET_PP_REQUIRED_FOR_TURN_ON_FALSE
,
546 TPM2_SET_PP_REQUIRED_FOR_TURN_ON_TRUE
,
547 TPM2_SET_PP_REQUIRED_FOR_TURN_OFF_FALSE
,
548 TPM2_SET_PP_REQUIRED_FOR_TURN_OFF_TRUE
,
549 TPM2_SET_PP_REQUIRED_FOR_CHANGE_EPS_FALSE
,
550 TPM2_SET_PP_REQUIRED_FOR_CHANGE_EPS_TRUE
,
552 TPM2_DISABLE_ENDORSMENT_ENABLE_STORAGE_HISTORY
,
553 TPM2_ENABLE_BLOCK_SID
,
554 TPM2_DISABLE_BLOCK_SID
,
555 TPM2_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_TRUE
,
556 TPM2_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FALSE
,
557 TPM2_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_TRUE
,
558 TPM2_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FALSE
,
562 * On hot reset/ACPI S3 the contents are preserved.
564 ppib
= (void *)cbmem_add(CBMEM_ID_TPM_PPI
, sizeof(*ppib
));
566 printk(BIOS_ERR
, "PPI: Failed to add CBMEM\n");
569 printk(BIOS_DEBUG
, "PPI: Pending OS request: 0x%x (0x%x)\n", ppib
->pprq
, ppib
->pprm
);
570 printk(BIOS_DEBUG
, "PPI: OS response: CMD 0x%x = 0x%x\n", ppib
->lppr
, ppib
->pprp
);
572 enum tpm_family family
= tlcl_get_family();
573 if (family
== TPM_UNKNOWN
) {
574 printk(BIOS_WARNING
, "PPI: %s: aborting, because no TPM detected\n", __func__
);
578 /* Clear unsupported fields */
580 ppib
->ppin
= 1; // Not used by ACPI. Read by EDK-2, must be 1.
586 /* Fill in defaults, the TPM command executor may overwrite this list */
587 memset(ppib
->func
, 0, sizeof(ppib
->func
));
588 if (family
== TPM_1
) {
589 for (size_t i
= 0; i
< ARRAY_SIZE(tpm1_funcs
); i
++) {
590 ppib
->func
[tpm1_funcs
[i
]] = 1;
591 if (ppib
->pprq
== tpm1_funcs
[i
])
595 for (size_t i
= 0; i
< ARRAY_SIZE(tpm2_funcs
); i
++) {
596 ppib
->func
[tpm2_funcs
[i
]] = 1;
597 if (ppib
->pprq
== tpm2_funcs
[i
])
608 /* Physical Presence OpRegion */
609 struct opregion opreg
= OPREGION("PPOP", SYSTEMMEMORY
, (uintptr_t)ppib
,
612 acpigen_write_opregion(&opreg
);
613 acpigen_write_field(opreg
.name
, list
, ARRAY_SIZE(list
),
614 FIELD_ANYACC
| FIELD_NOLOCK
| FIELD_PRESERVE
);
616 acpigen_write_name("TPM2");
617 acpigen_write_package(2);
618 acpigen_write_dword(0);
619 acpigen_write_dword(0);
620 acpigen_pop_len(); /* Package */
622 acpigen_write_name("TPM3");
623 acpigen_write_package(3);
624 acpigen_write_dword(0);
625 acpigen_write_dword(0);
626 acpigen_write_dword(0);
627 acpigen_pop_len(); /* Package */
630 * Returns One if the firmware implements this function.
632 * Arg0: Integer PPI function
634 acpigen_write_method_serialized("FUNC", 1);
636 acpigen_write_to_integer(ARG0_OP
, LOCAL0_OP
);
638 acpigen_emit_byte(LGREATER_OP
);
639 acpigen_emit_byte(LOCAL0_OP
);
640 acpigen_write_integer(VENDOR_SPECIFIC_OFFSET
);
641 acpigen_write_return_integer(0);
642 acpigen_pop_len(); /* If */
644 /* TPPF = CreateField("PPOP", Local0) */
645 acpigen_emit_byte(CREATE_BYTE_OP
);
646 acpigen_emit_namestring("PPOP");
647 acpigen_emit_byte(LOCAL0_OP
);
648 acpigen_emit_namestring("TPPF");
650 /* Local0 = ToInteger("TPPF") */
651 acpigen_emit_byte(TO_INTEGER_OP
);
652 acpigen_emit_namestring("TPPF");
653 acpigen_emit_byte(LOCAL0_OP
);
655 acpigen_write_return_op(LOCAL0_OP
);
656 acpigen_pop_len(); /* Method */
659 * Returns One if the PPI spec supports this functions.
660 * That doesn't necessarily mean that the firmware implements it, or the
661 * TPM can execute the function.
663 * Arg0: Integer PPI function
664 * Arg1: Integer TPMversion (0: TPM2, 1: TPM1.2)
666 acpigen_write_method("FSUP", 2);
668 acpigen_write_to_integer(ARG0_OP
, LOCAL0_OP
);
669 acpigen_write_to_integer(ARG1_OP
, LOCAL1_OP
);
671 acpigen_emit_byte(LGREATER_OP
);
672 acpigen_emit_byte(LOCAL0_OP
);
673 acpigen_write_integer(VENDOR_SPECIFIC_OFFSET
);
674 acpigen_write_return_integer(0);
675 acpigen_pop_len(); /* If */
677 acpigen_write_if_lequal_op_int(LOCAL1_OP
, 1);
678 for (size_t i
= 0; i
< ARRAY_SIZE(tpm1_funcs
); i
++) {
679 acpigen_write_if_lequal_op_int(LOCAL0_OP
, tpm1_funcs
[i
]);
680 acpigen_write_return_integer(1);
681 acpigen_pop_len(); /* Pop : If */
683 acpigen_pop_len(); /* If */
685 acpigen_write_if_lequal_op_int(LOCAL1_OP
, 0);
687 for (size_t i
= 0; i
< ARRAY_SIZE(tpm2_funcs
); i
++) {
688 acpigen_write_if_lequal_op_int(LOCAL0_OP
, tpm2_funcs
[i
]);
689 acpigen_write_return_integer(1);
690 acpigen_pop_len(); /* Pop : If */
692 acpigen_pop_len(); /* If */
694 acpigen_write_return_integer(0);
695 acpigen_pop_len(); /* Method */
700 struct dsm_uuid ids
[] = {
701 /* Physical presence interface.
702 * This is used to submit commands like "Clear TPM" to
703 * be run at next reboot provided that user confirms
706 DSM_UUID(TPM_PPI_UUID
, &tpm_ppi_callbacks
[0],
707 ARRAY_SIZE(tpm_ppi_callbacks
), NULL
),
708 /* Memory clearing on boot: just a dummy. */
709 DSM_UUID(TPM_MCI_UUID
, &tpm_mci_callbacks
[0],
710 ARRAY_SIZE(tpm_mci_callbacks
), NULL
),
713 acpigen_write_dsm_uuid_arr(ids
, ARRAY_SIZE(ids
));
716 void lb_tpm_ppi(struct lb_header
*header
)
718 struct lb_tpm_physical_presence
*tpm_ppi
;
719 enum tpm_family family
;
722 ppib
= cbmem_find(CBMEM_ID_TPM_PPI
);
726 family
= tlcl_get_family();
727 if (family
== TPM_UNKNOWN
) {
728 printk(BIOS_WARNING
, "PPI: %s: aborting, because no TPM detected\n", __func__
);
732 tpm_ppi
= (struct lb_tpm_physical_presence
*)lb_new_record(header
);
733 tpm_ppi
->tag
= LB_TAG_TPM_PPI_HANDOFF
;
734 tpm_ppi
->size
= sizeof(*tpm_ppi
);
735 tpm_ppi
->ppi_address
= (uintptr_t)ppib
;
736 tpm_ppi
->tpm_version
= family
== TPM_1
? LB_TPM_VERSION_TPM_VERSION_1_2
:
737 LB_TPM_VERSION_TPM_VERSION_2
;
739 tpm_ppi
->ppi_version
= BCD(1, 3);