1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19#include "qemu/osdep.h"
20#include "qapi/error.h"
21#include "hw/acpi/tpm.h"
22
23void tpm_build_ppi_acpi(TPMIf *tpm, Aml *dev)
24{
25 Aml *method, *field, *ifctx, *ifctx2, *ifctx3, *func_mask,
26 *not_implemented, *pak, *tpm2, *tpm3, *pprm, *pprq, *zero, *one;
27
28 if (!object_property_get_bool(OBJECT(tpm), "ppi", &error_abort)) {
29 return;
30 }
31
32 zero = aml_int(0);
33 one = aml_int(1);
34 func_mask = aml_int(TPM_PPI_FUNC_MASK);
35 not_implemented = aml_int(TPM_PPI_FUNC_NOT_IMPLEMENTED);
36
37
38
39
40
41 aml_append(dev,
42 aml_operation_region("TPP2", AML_SYSTEM_MEMORY,
43 aml_int(TPM_PPI_ADDR_BASE + 0x100),
44 0x5A));
45 field = aml_field("TPP2", AML_ANY_ACC, AML_NOLOCK, AML_PRESERVE);
46 aml_append(field, aml_named_field("PPIN", 8));
47 aml_append(field, aml_named_field("PPIP", 32));
48 aml_append(field, aml_named_field("PPRP", 32));
49 aml_append(field, aml_named_field("PPRQ", 32));
50 aml_append(field, aml_named_field("PPRM", 32));
51 aml_append(field, aml_named_field("LPPR", 32));
52 aml_append(dev, field);
53 pprq = aml_name("PPRQ");
54 pprm = aml_name("PPRM");
55
56 aml_append(dev,
57 aml_operation_region(
58 "TPP3", AML_SYSTEM_MEMORY,
59 aml_int(TPM_PPI_ADDR_BASE +
60 0x15a ),
61 0x1));
62 field = aml_field("TPP3", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE);
63 aml_append(field, aml_named_field("MOVV", 8));
64 aml_append(dev, field);
65
66
67
68
69
70 method = aml_method("TPFN", 1, AML_SERIALIZED);
71 {
72 Aml *op = aml_arg(0);
73 ifctx = aml_if(aml_lgreater_equal(op, aml_int(0x100)));
74 {
75 aml_append(ifctx, aml_return(zero));
76 }
77 aml_append(method, ifctx);
78
79 aml_append(method,
80 aml_operation_region("TPP1", AML_SYSTEM_MEMORY,
81 aml_add(aml_int(TPM_PPI_ADDR_BASE), op, NULL), 0x1));
82 field = aml_field("TPP1", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE);
83 aml_append(field, aml_named_field("TPPF", 8));
84 aml_append(method, field);
85 aml_append(method, aml_return(aml_name("TPPF")));
86 }
87 aml_append(dev, method);
88
89
90
91
92
93 pak = aml_package(2);
94 aml_append(pak, zero);
95 aml_append(pak, zero);
96 aml_append(dev, aml_name_decl("TPM2", pak));
97 tpm2 = aml_name("TPM2");
98
99 pak = aml_package(3);
100 aml_append(pak, zero);
101 aml_append(pak, zero);
102 aml_append(pak, zero);
103 aml_append(dev, aml_name_decl("TPM3", pak));
104 tpm3 = aml_name("TPM3");
105
106 method = aml_method("_DSM", 4, AML_SERIALIZED);
107 {
108 uint8_t zerobyte[1] = { 0 };
109 Aml *function, *arguments, *rev, *op, *op_arg, *op_flags, *uuid;
110
111 uuid = aml_arg(0);
112 rev = aml_arg(1);
113 function = aml_arg(2);
114 arguments = aml_arg(3);
115 op = aml_local(0);
116 op_flags = aml_local(1);
117
118
119 ifctx = aml_if(
120 aml_equal(uuid,
121 aml_touuid("3DDDFAA6-361B-4EB4-A424-8D10089D1653")));
122 {
123
124 ifctx2 = aml_if(aml_equal(function, zero));
125 {
126 uint8_t byte_list[2] = { 0xff, 0x01 };
127
128 aml_append(ifctx2,
129 aml_return(aml_buffer(sizeof(byte_list),
130 byte_list)));
131 }
132 aml_append(ifctx, ifctx2);
133
134
135
136
137
138
139
140
141 ifctx2 = aml_if(aml_equal(function, one));
142 {
143 aml_append(ifctx2, aml_return(aml_string("1.3")));
144 }
145 aml_append(ifctx, ifctx2);
146
147
148
149
150
151
152
153
154
155
156
157
158 ifctx2 = aml_if(aml_equal(function, aml_int(2)));
159 {
160
161 aml_append(ifctx2,
162 aml_store(aml_derefof(aml_index(arguments,
163 zero)), op));
164
165
166 aml_append(ifctx2,
167 aml_store(aml_call1("TPFN", op), op_flags));
168
169
170 ifctx3 = aml_if(
171 aml_equal(
172 aml_and(op_flags, func_mask, NULL),
173 not_implemented));
174 {
175
176 aml_append(ifctx3, aml_return(one));
177 }
178 aml_append(ifctx2, ifctx3);
179
180 aml_append(ifctx2, aml_store(op, pprq));
181 aml_append(ifctx2, aml_store(zero, pprm));
182
183 aml_append(ifctx2, aml_return(zero));
184 }
185 aml_append(ifctx, ifctx2);
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204 ifctx2 = aml_if(aml_equal(function, aml_int(3)));
205 {
206
207
208
209
210 ifctx3 = aml_if(aml_equal(rev, one));
211 {
212
213 aml_append(ifctx3,
214 aml_store(pprq, aml_index(tpm2, one)));
215 aml_append(ifctx3, aml_return(tpm2));
216 }
217 aml_append(ifctx2, ifctx3);
218
219
220
221
222
223 ifctx3 = aml_if(aml_equal(rev, aml_int(2)));
224 {
225
226 aml_append(ifctx3,
227 aml_store(pprq, aml_index(tpm3, one)));
228
229 aml_append(ifctx3,
230 aml_store(pprm, aml_index(tpm3, aml_int(2))));
231 aml_append(ifctx3, aml_return(tpm3));
232 }
233 aml_append(ifctx2, ifctx3);
234 }
235 aml_append(ifctx, ifctx2);
236
237
238
239
240
241
242
243
244
245
246
247
248
249 ifctx2 = aml_if(aml_equal(function, aml_int(4)));
250 {
251
252 aml_append(ifctx2, aml_return(aml_int(2)));
253 }
254 aml_append(ifctx, ifctx2);
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275 ifctx2 = aml_if(aml_equal(function, aml_int(5)));
276 {
277
278 aml_append(ifctx2,
279 aml_store(aml_name("LPPR"),
280 aml_index(tpm3, one)));
281
282 aml_append(ifctx2,
283 aml_store(aml_name("PPRP"),
284 aml_index(tpm3, aml_int(2))));
285 aml_append(ifctx2, aml_return(tpm3));
286 }
287 aml_append(ifctx, ifctx2);
288
289
290
291
292
293
294
295
296
297
298
299 ifctx2 = aml_if(aml_equal(function, aml_int(6)));
300 {
301
302 aml_append(ifctx2, aml_return(aml_int(3)));
303 }
304 aml_append(ifctx, ifctx2);
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320 ifctx2 = aml_if(aml_equal(function, aml_int(7)));
321 {
322
323 aml_append(ifctx2, aml_store(aml_derefof(aml_index(arguments,
324 zero)),
325 op));
326
327
328 aml_append(ifctx2, aml_store(aml_call1("TPFN", op),
329 op_flags));
330
331 ifctx3 = aml_if(
332 aml_equal(
333 aml_and(op_flags, func_mask, NULL),
334 not_implemented));
335 {
336
337 aml_append(ifctx3, aml_return(one));
338 }
339 aml_append(ifctx2, ifctx3);
340
341
342 ifctx3 = aml_if(
343 aml_equal(
344 aml_and(op_flags, func_mask, NULL),
345 aml_int(TPM_PPI_FUNC_BLOCKED)));
346 {
347
348 aml_append(ifctx3, aml_return(aml_int(3)));
349 }
350 aml_append(ifctx2, ifctx3);
351
352
353 ifctx3 = aml_if(aml_equal(rev, one));
354 {
355
356
357 aml_append(ifctx3, aml_store(op, pprq));
358
359 aml_append(ifctx3, aml_store(zero, pprm));
360 }
361 aml_append(ifctx2, ifctx3);
362
363 ifctx3 = aml_if(aml_equal(rev, aml_int(2)));
364 {
365
366
367 op_arg = aml_derefof(aml_index(arguments, one));
368 aml_append(ifctx3, aml_store(op, pprq));
369
370 aml_append(ifctx3, aml_store(op_arg, pprm));
371 }
372 aml_append(ifctx2, ifctx3);
373
374 aml_append(ifctx2, aml_return(zero));
375 }
376 aml_append(ifctx, ifctx2);
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391 ifctx2 = aml_if(aml_equal(function, aml_int(8)));
392 {
393
394 aml_append(ifctx2,
395 aml_store(aml_derefof(aml_index(arguments,
396 zero)),
397 op));
398
399
400 aml_append(ifctx2, aml_store(aml_call1("TPFN", op),
401 op_flags));
402
403 aml_append(ifctx2,
404 aml_return(
405 aml_and(op_flags, func_mask, NULL)));
406 }
407 aml_append(ifctx, ifctx2);
408
409 aml_append(ifctx, aml_return(aml_buffer(1, zerobyte)));
410 }
411 aml_append(method, ifctx);
412
413
414
415
416
417 ifctx = aml_if(
418 aml_equal(uuid,
419 aml_touuid("376054ED-CC13-4675-901C-4756D7F2D45D")));
420 {
421
422 ifctx2 = aml_if(aml_equal(function, zero));
423 {
424 uint8_t byte_list[1] = { 0x03 };
425
426 aml_append(ifctx2,
427 aml_return(aml_buffer(sizeof(byte_list),
428 byte_list)));
429 }
430 aml_append(ifctx, ifctx2);
431
432
433
434
435
436
437
438
439
440
441
442 ifctx2 = aml_if(aml_equal(function, one));
443 {
444 aml_append(ifctx2,
445 aml_store(aml_derefof(aml_index(arguments, zero)),
446 op));
447 {
448 aml_append(ifctx2, aml_store(op, aml_name("MOVV")));
449
450
451 aml_append(ifctx2, aml_return(zero));
452 }
453 }
454 aml_append(ifctx, ifctx2);
455 }
456 aml_append(method, ifctx);
457 }
458 aml_append(dev, method);
459}
460