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