xref: /aosp_15_r20/external/coreboot/src/drivers/tpm/ppi.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <types.h>
4 #include <acpi/acpigen.h>
5 #include <acpi/acpi_device.h>
6 #include <cbmem.h>
7 #include <console/console.h>
8 #include <security/tpm/tss.h>
9 
10 #include "tpm_ppi.h"
11 
12 #define BCD(x, y) (((x) << 4) | ((y) << 0))
13 
set_package_element_op(const char * package_name,unsigned int element,uint8_t src_op)14 static void set_package_element_op(const char *package_name, unsigned int element,
15 				   uint8_t src_op)
16 {
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 */
23 }
24 
set_package_element_name(const char * package_name,unsigned int element,const char * src)25 static void set_package_element_name(const char *package_name, unsigned int element,
26 				     const char *src)
27 {
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 */
34 }
35 
36 /* PPI function is passed in src_op. Converted to Local2. Clobbers Local1 and Local2 */
verify_supported_ppi(uint8_t src_op)37 static void verify_supported_ppi(uint8_t src_op)
38 {
39 	enum tpm_family family = tlcl_get_family();
40 
41 	/*
42 	 * Old OSes incorrectly pass a Buffer instead of a Package.
43 	 * See TCG Physical Presence Interface Specification Chapter 8.1.2 for details.
44 	 */
45 
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);
53 	acpigen_pop_len();
54 
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);
62 	acpigen_pop_len();
63 
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);
71 
72 	/*
73 	 * Note: Must fake success for 1-4, 6-13, 15-16, 19-20
74 	 * see "Trusted Execution Environment ACPI Profile"
75 	 *
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.
81 	 */
82 
83 	/*
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.
86 	 */
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);
92 
93 	acpigen_write_if_lequal_op_int(LOCAL1_OP, 1);
94 	acpigen_write_return_integer(PPI2_RET_SUCCESS);	/* As per TPM spec */
95 	acpigen_pop_len();
96 	acpigen_write_return_integer(PPI2_RET_NOT_SUPPORTED);
97 
98 	acpigen_pop_len();
99 }
100 
101 /* TPM PPI functions */
102 
tpm_ppi_func0_cb(void * arg)103 static void tpm_ppi_func0_cb(void *arg)
104 {
105 	/* Functions 1-8. */
106 	u8 buf[] = {0xff, 0x01};
107 	acpigen_write_return_byte_buffer(buf, 2);
108 }
109 
110  /*
111  * PPI 1.0: 2.1.1 Get Physical Presence Interface Version
112  *
113  * Arg2 (Integer): Function Index = 1
114  * Arg3 (Package): Arguments = Empty Package
115  *
116  * Returns: Type: String
117  */
tpm_ppi_func1_cb(void * arg)118 static void tpm_ppi_func1_cb(void *arg)
119 {
120 	if (tlcl_get_family() == TPM_2)
121 		/* Interface version: 1.3 */
122 		acpigen_write_return_string("1.3");
123 	else
124 		/* Interface version: 1.2 */
125 		acpigen_write_return_string("1.2");
126 }
127 
128 /*
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
131  *
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
137  *
138  * Returns: Type: Integer
139  *          0: Success
140  *          1: Operation Value of the Request Not Supported
141  *          2: General Failure
142  */
tpm_ppi_func2_cb(void * arg)143 static void tpm_ppi_func2_cb(void *arg)
144 {
145 	/* Revision 1 */
146 	acpigen_write_to_integer(ARG1_OP, LOCAL0_OP);
147 	acpigen_write_if_lequal_op_int(LOCAL0_OP, 1);
148 
149 	/* Local2 = ConvertAndVerify(Arg3) */
150 	verify_supported_ppi(ARG3_OP);
151 
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");
155 
156 	acpigen_write_return_integer(PPI2_RET_SUCCESS);
157 	acpigen_pop_len();
158 
159 	acpigen_write_return_integer(PPI2_RET_GENERAL_FAILURE);
160 }
161 
162 /*
163  * PPI 1.0: 2.1.4 Get Pending TPM Operation Requested By the OS
164  *
165  * Supported Revisions: 1, 2
166  * Arg1 (Integer): Revision
167  * Arg2 (Integer): Function Index = 3
168  * Arg3 (Package): Empty package
169  *
170  * Returns: Type: Package(Integer, Integer, Integer (optional))
171  *      Integer 1:
172  *          0: Success
173  *          1: General Failure
174  *      Integer 2:
175  *          Pending TPM operation requested by OS
176  *      Integer 3:
177  *           Pending TPM operation argument requested by OS
178  */
tpm_ppi_func3_cb(void * arg)179 static void tpm_ppi_func3_cb(void *arg)
180 {
181 	acpigen_write_store();
182 	acpigen_write_integer(PPI3_RET_GENERAL_FAILURE);
183 	acpigen_emit_byte(LOCAL0_OP);
184 
185 	/* ^TPM3 [0] = PPI3_RET_GENERAL_FAILURE */
186 	set_package_element_op("^TPM3", 0, LOCAL0_OP);
187 
188 	/* ^TPM2 [0] = PPI3_RET_GENERAL_FAILURE */
189 	set_package_element_op("^TPM2", 0, LOCAL0_OP);
190 
191 	acpigen_write_to_integer(ARG1_OP, LOCAL0_OP);
192 
193 	/* Revision 1 */
194 	acpigen_write_if_lequal_op_int(LOCAL0_OP, 1);
195 
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);
201 
202 	/* ^TPM2 [1] = ^CMDR */
203 	set_package_element_name("^TPM2", 1, "^CMDR");
204 
205 	acpigen_emit_byte(RETURN_OP);
206 	acpigen_emit_namestring("^TPM2");
207 	acpigen_pop_len();
208 
209 	/*
210 	 * A return value of {0, 23, 1} indicates that operation 23
211 	 * with argument 1 is pending.
212 	 */
213 
214 	/* Revision 2 */
215 	acpigen_write_if_lequal_op_int(LOCAL0_OP, 2);
216 
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);
222 
223 	/* ^TPM3 [1] = ^CMDR */
224 	set_package_element_name("^TPM3", 1, "^CMDR");
225 
226 	/* ^TPM3 [2] = ^OARG */
227 	set_package_element_name("^TPM3", 2, "^OARG");
228 
229 	acpigen_emit_byte(RETURN_OP);
230 	acpigen_emit_namestring("^TPM3");
231 	acpigen_pop_len();
232 
233 	acpigen_emit_byte(RETURN_OP);
234 	acpigen_emit_namestring("^TPM3");
235 }
236 
237 /*
238  * PPI 1.0: 2.1.5 Get Platform-Specific Action to Transition to Pre-OS Environment
239  *
240  * Arg1 (Integer): Revision
241  * Arg2 (Integer): Function Index = 4
242  * Arg3 (Package): Empty package
243  *
244  * Returns: Type: Integer
245  *          0: None
246  *          1: Shutdown
247  *          2: Reboot
248  *          3: Vendor specific
249  */
tpm_ppi_func4_cb(void * arg)250 static void tpm_ppi_func4_cb(void *arg)
251 {
252 	/* Pre-OS transition method: reboot. */
253 	acpigen_write_return_byte(PPI4_RET_REBOOT);
254 }
255 
256 /*
257  * PPI 1.0: 2.1.6 Return TPM Operation Response to OS Environment
258  *
259  * Supported Revisions: 1
260  * Arg1 (Integer): Revision
261  * Arg2 (Integer): Function Index = 5
262  * Arg3 (Package): Empty package
263  *
264  * Returns: Type: Package(Integer, Integer, Integer)
265  *      Integer 1:
266  *          0: Success
267  *          1: General Failure
268  *      Integer 2:
269  *          Most recent TPM operation requested by OS
270  *      Integer 3:
271  *          Response to most recent TPM operation requested by OS
272  */
tpm_ppi_func5_cb(void * arg)273 static void tpm_ppi_func5_cb(void *arg)
274 {
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);
280 
281 	acpigen_write_to_integer(ARG1_OP, LOCAL0_OP);
282 
283 	/* Revision 1 */
284 	acpigen_write_if_lequal_op_int(LOCAL0_OP, 1);
285 
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);
291 
292 	/* ^TPM3 [1] = ^LCMD */
293 	set_package_element_name("^TPM3", 1, "^LCMD");
294 
295 	/* ^TPM3 [2] = ^RESU */
296 	set_package_element_name("^TPM3", 2, "^RESU");
297 
298 	acpigen_pop_len();
299 
300 	acpigen_emit_byte(RETURN_OP);
301 	acpigen_emit_namestring("^TPM3");
302 }
303 
304 /*
305  * PPI 1.2: 2.1.6 Submit preferred user language [Windows optional]
306  *
307  * Arg1 (Integer): Revision
308  * Arg2 (Integer): Function Index = 5
309  * Arg3 (Package): Empty package
310  */
tpm_ppi_func6_cb(void * arg)311 static void tpm_ppi_func6_cb(void *arg)
312 {
313 	/*
314 	 * Set preferred user language: deprecated and must return 3 aka
315 	 * "not implemented".
316 	 */
317 	acpigen_write_return_byte(PPI6_RET_NOT_IMPLEMENTED);
318 }
319 
320 /*
321  * PPI 1.2: 2.1.7 Submit TPM Operation Request to Pre-OS Environment 2
322  *
323  * Supported Revisions: 1, 2
324  * Arg1 (Integer): Revision
325  * Arg2 (Integer): Function Index = 7
326  * Arg3 (Package): Integer
327  *
328  * Returns: Type: Integer
329  *          0: Success
330  *          1: Not implemented
331  *          2: General Failure
332  *          3: Blocked by current BIOS settings
333  */
tpm_ppi_func7_cb(void * arg)334 static void tpm_ppi_func7_cb(void *arg)
335 {
336 	acpigen_write_to_integer(ARG1_OP, LOCAL0_OP);
337 
338 	/* Local2 = ConvertAndVerify(Arg3) */
339 	verify_supported_ppi(ARG3_OP);
340 
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);
347 
348 	/* Enforce use of Revision 1 that doesn't take an optional argument. */
349 
350 	/* Local0 = One */
351 	acpigen_write_store();
352 	acpigen_emit_byte(ONE_OP);
353 	acpigen_emit_byte(LOCAL0_OP);
354 
355 	acpigen_pop_len();
356 
357 	// FIXME: Only advertise supported functions
358 
359 	/* Revision 1 */
360 	acpigen_write_if_lequal_op_int(LOCAL0_OP, 1);
361 
362 	/* ^CMDR = Local2 */
363 	acpigen_write_store_op_to_namestr(LOCAL2_OP, "^CMDR");
364 
365 	/* ^OARG = Zero */
366 	acpigen_write_store_op_to_namestr(ZERO_OP, "^OARG");
367 
368 	acpigen_write_return_byte(PPI7_RET_SUCCESS);
369 	acpigen_pop_len();
370 
371 	/* Revision 2 */
372 	acpigen_write_if_lequal_op_int(LOCAL0_OP, 2);
373 	/* ^CMDR = Local2 */
374 	acpigen_write_store_op_to_namestr(LOCAL2_OP, "^CMDR");
375 
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");
381 
382 	acpigen_write_return_byte(PPI7_RET_SUCCESS);
383 	acpigen_pop_len();
384 
385 	acpigen_write_return_byte(PPI7_RET_GENERAL_FAILURE);
386 }
387 
388 /*
389  * PPI 1.2: 2.1.8 Get User Confirmation Status for Operation
390  *
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
396  *
397  * Returns: Type: Integer
398  *          0: Not implemented
399  *          1: BIOS only
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
403  */
tpm_ppi_func8_cb(void * arg)404 static void tpm_ppi_func8_cb(void *arg)
405 {
406 	enum tpm_family family = tlcl_get_family();
407 
408 	acpigen_write_to_integer(ARG1_OP, LOCAL0_OP);
409 
410 	/* Revision 1 */
411 	acpigen_write_if_lequal_op_int(LOCAL0_OP, 1);
412 	acpigen_get_package_op_element(ARG3_OP, 0, LOCAL2_OP);
413 
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 */
422 	acpigen_pop_len();
423 
424 	// FIXME: Only advertise supported functions
425 
426 	if (family == TPM_1) {
427 		/*
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.
430 		 */
431 		static const u32 tpm1_funcs[] = {
432 			TPM_NOOP,
433 			TPM_SET_NOPPICLEAR_TRUE,
434 			TPM_SET_NOPPIMAINTAINANCE_TRUE,
435 			TPM_SET_NOPPIPROVISION_TRUE,
436 		};
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 */
441 		}
442 	} else if (family == TPM_2) {
443 		/*
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.
446 		 */
447 		static const u32 tpm2_funcs[] = {
448 			TPM2_NOOP,
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,
456 		};
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 */
461 		}
462 	}
463 	acpigen_write_return_integer(PPI8_RET_ALLOWED_WITH_PP);
464 
465 	acpigen_pop_len();
466 
467 	acpigen_write_return_integer(PPI8_RET_NOT_IMPLEMENTED);
468 }
469 
470 static void (*tpm_ppi_callbacks[])(void *) = {
471 	tpm_ppi_func0_cb,
472 	tpm_ppi_func1_cb,
473 	tpm_ppi_func2_cb,
474 	tpm_ppi_func3_cb,
475 	tpm_ppi_func4_cb,
476 	tpm_ppi_func5_cb,
477 	tpm_ppi_func6_cb,
478 	tpm_ppi_func7_cb,
479 	tpm_ppi_func8_cb,
480 };
481 
tpm_mci_func0_cb(void * arg)482 static void tpm_mci_func0_cb(void *arg)
483 {
484 	/* Function 1. */
485 	acpigen_write_return_singleton_buffer(0x3);
486 }
tpm_mci_func1_cb(void * arg)487 static void tpm_mci_func1_cb(void *arg)
488 {
489 	/* Just return success. */
490 	acpigen_write_return_byte(0);
491 }
492 
493 static void (*tpm_mci_callbacks[])(void *) = {
494 	tpm_mci_func0_cb,
495 	tpm_mci_func1_cb,
496 };
497 
tpm_ppi_acpi_fill_ssdt(const struct device * dev)498 void tpm_ppi_acpi_fill_ssdt(const struct device *dev)
499 {
500 	struct cb_tpm_ppi_payload_handshake *ppib;
501 
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
511 	};
512 	static const u8 tpm1_funcs[] = {
513 		TPM_NOOP,
514 		TPM_ENABLE,
515 		TPM_DISABLE,
516 		TPM_ACTIVATE,
517 		TPM_DEACTIVATE,
518 		TPM_CLEAR,
519 		TPM_ENABLE_ACTIVATE,
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,
530 	};
531 	static const u8 tpm2_funcs[] = {
532 		TPM2_NOOP,
533 		TPM2_ENABLE,
534 		TPM2_DISABLE,
535 		TPM2_CLEAR,
536 		TPM2_CLEAR_ENABLE_ACTIVE,
537 		TPM2_SET_PP_REQUIRED_FOR_CLEAR_TRUE,
538 		TPM2_SET_PP_REQUIRED_FOR_CLEAR_FALSE,
539 		TPM2_ENABLE_CLEAR,
540 		TPM2_ENABLE_CLEAR2,
541 		TPM2_SET_PCR_BANKS,
542 		TPM2_CHANGE_EPS,
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,
551 		TPM2_LOG_ALL_DIGEST,
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,
559 	};
560 
561 	/*
562 	 * On hot reset/ACPI S3 the contents are preserved.
563 	 */
564 	ppib = (void *)cbmem_add(CBMEM_ID_TPM_PPI, sizeof(*ppib));
565 	if (!ppib) {
566 		printk(BIOS_ERR, "PPI: Failed to add CBMEM\n");
567 		return;
568 	}
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);
571 
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__);
575 		return;
576 	}
577 
578 	/* Clear unsupported fields */
579 	ppib->next_step = 0;
580 	ppib->ppin = 1; // Not used by ACPI. Read by EDK-2, must be 1.
581 	ppib->ppip = 0;
582 	ppib->fret = 0;
583 	ppib->next_step = 0;
584 
585 	bool found = false;
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])
592 				found = true;
593 		}
594 	} else {
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])
598 				found = true;
599 		}
600 	}
601 	if (!found) {
602 		// Set sane defaults
603 		ppib->pprq = 0;
604 		ppib->pprm = 0;
605 		ppib->pprp = 0;
606 	}
607 
608 	/* Physical Presence OpRegion */
609 	struct opregion opreg = OPREGION("PPOP", SYSTEMMEMORY, (uintptr_t)ppib,
610 		sizeof(*ppib));
611 
612 	acpigen_write_opregion(&opreg);
613 	acpigen_write_field(opreg.name, list, ARRAY_SIZE(list),
614 			    FIELD_ANYACC | FIELD_NOLOCK | FIELD_PRESERVE);
615 
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 */
621 
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 */
628 
629 	/*
630 	 * Returns One if the firmware implements this function.
631 	 *
632 	 * Arg0: Integer PPI function
633 	 */
634 	acpigen_write_method_serialized("FUNC", 1);
635 
636 	acpigen_write_to_integer(ARG0_OP, LOCAL0_OP);
637 	acpigen_write_to_integer(ARG1_OP, LOCAL1_OP);
638 	acpigen_write_if();
639 	acpigen_emit_byte(LGREATER_OP);
640 	acpigen_emit_byte(LOCAL0_OP);
641 	acpigen_write_integer(VENDOR_SPECIFIC_OFFSET);
642 	acpigen_write_return_integer(0);
643 	acpigen_pop_len(); /* If */
644 
645 	/* TPPF = CreateField("PPOP", Local0) */
646 	acpigen_emit_byte(CREATE_BYTE_OP);
647 	acpigen_emit_namestring("PPOP");
648 	acpigen_emit_byte(LOCAL0_OP);
649 	acpigen_emit_namestring("TPPF");
650 
651 	/* Local0 = ToInteger("TPPF") */
652 	acpigen_emit_byte(TO_INTEGER_OP);
653 	acpigen_emit_namestring("TPPF");
654 	acpigen_emit_byte(LOCAL0_OP);
655 
656 	acpigen_write_return_op(LOCAL0_OP);
657 	acpigen_pop_len(); /* Method */
658 
659 	/*
660 	 * Returns One if the PPI spec supports this functions.
661 	 * That doesn't necessarily mean that the firmware implements it, or the
662 	 * TPM can execute the function.
663 	 *
664 	 * Arg0: Integer PPI function
665 	 * Arg1: Integer TPMversion (0: TPM2, 1: TPM1.2)
666 	 */
667 	acpigen_write_method("FSUP", 2);
668 
669 	acpigen_write_to_integer(ARG0_OP, LOCAL0_OP);
670 	acpigen_write_to_integer(ARG1_OP, LOCAL1_OP);
671 	acpigen_write_if();
672 	acpigen_emit_byte(LGREATER_OP);
673 	acpigen_emit_byte(LOCAL0_OP);
674 	acpigen_write_integer(VENDOR_SPECIFIC_OFFSET);
675 	acpigen_write_return_integer(0);
676 	acpigen_pop_len(); /* If */
677 
678 	acpigen_write_if_lequal_op_int(LOCAL1_OP, 1);
679 	for (size_t i = 0; i < ARRAY_SIZE(tpm1_funcs); i++) {
680 		acpigen_write_if_lequal_op_int(LOCAL0_OP, tpm1_funcs[i]);
681 		acpigen_write_return_integer(1);
682 		acpigen_pop_len();	/* Pop : If */
683 	}
684 	acpigen_pop_len(); /* If */
685 
686 	acpigen_write_if_lequal_op_int(LOCAL1_OP, 0);
687 
688 	for (size_t i = 0; i < ARRAY_SIZE(tpm2_funcs); i++) {
689 		acpigen_write_if_lequal_op_int(LOCAL0_OP, tpm2_funcs[i]);
690 		acpigen_write_return_integer(1);
691 		acpigen_pop_len();	/* Pop : If */
692 	}
693 	acpigen_pop_len(); /* If */
694 
695 	acpigen_write_return_integer(0);
696 	acpigen_pop_len(); /* Method */
697 
698 	/*
699 	 * _DSM method
700 	 */
701 	struct dsm_uuid ids[] = {
702 		/* Physical presence interface.
703 		 * This is used to submit commands like "Clear TPM" to
704 		 * be run at next reboot provided that user confirms
705 		 * them.
706 		 */
707 		DSM_UUID(TPM_PPI_UUID, &tpm_ppi_callbacks[0],
708 			ARRAY_SIZE(tpm_ppi_callbacks), NULL),
709 		/* Memory clearing on boot: just a dummy. */
710 		DSM_UUID(TPM_MCI_UUID, &tpm_mci_callbacks[0],
711 			ARRAY_SIZE(tpm_mci_callbacks), NULL),
712 	};
713 
714 	acpigen_write_dsm_uuid_arr(ids, ARRAY_SIZE(ids));
715 }
716 
lb_tpm_ppi(struct lb_header * header)717 void lb_tpm_ppi(struct lb_header *header)
718 {
719 	struct lb_tpm_physical_presence *tpm_ppi;
720 	enum tpm_family family;
721 	void *ppib;
722 
723 	ppib = cbmem_find(CBMEM_ID_TPM_PPI);
724 	if (!ppib)
725 		return;
726 
727 	family = tlcl_get_family();
728 	if (family == TPM_UNKNOWN) {
729 		printk(BIOS_WARNING, "PPI: %s: aborting, because no TPM detected\n", __func__);
730 		return;
731 	}
732 
733 	tpm_ppi = (struct lb_tpm_physical_presence *)lb_new_record(header);
734 	tpm_ppi->tag = LB_TAG_TPM_PPI_HANDOFF;
735 	tpm_ppi->size = sizeof(*tpm_ppi);
736 	tpm_ppi->ppi_address = (uintptr_t)ppib;
737 	tpm_ppi->tpm_version = family == TPM_1 ? LB_TPM_VERSION_TPM_VERSION_1_2 :
738 		LB_TPM_VERSION_TPM_VERSION_2;
739 
740 	tpm_ppi->ppi_version = BCD(1, 3);
741 }
742