qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

acpi: build TPM Physical Presence interface

The TPM Physical Presence interface consists of an ACPI part, a shared
memory part, and code in the firmware. Users can send messages to the
firmware by writing a code into the shared memory through invoking the
ACPI code. When a reboot happens, the firmware looks for the code and
acts on it by sending sequences of commands to the TPM.

This patch adds the ACPI code. It is similar to the one in EDK2 but doesn't
assume that SMIs are necessary to use. It uses a similar datastructure for
the shared memory as EDK2 does so that EDK2 and SeaBIOS could both make use
of it. I extended the shared memory data structure with an array of 256
bytes, one for each code that could be implemented. The array contains
flags describing the individual codes. This decouples the ACPI implementation
from the firmware implementation.

The underlying TCG specification is accessible from the following page.

https://trustedcomputinggroup.org/tcg-physical-presence-interface-specification/

This patch implements version 1.30.

Signed-off-by: Stefan Berger <stefanb@linux.vnet.ibm.com>
[ Marc-André - ACPI code improvements and windows fixes ]
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Acked-by: Michael S. Tsirkin <mst@redhat.com>
Reviewed-by: Igor Mammedov <imammedo@redhat.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Tested-by: Stefan Berger <stefanb@linux.ibm.com>
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>

authored by

Stefan Berger and committed by
Michael S. Tsirkin
ac6dd31e 0fe24669

+514 -3
+83
docs/specs/tpm.txt
··· 76 76 77 77 https://trustedcomputinggroup.org/tcg-acpi-specification/ 78 78 79 + == ACPI PPI Interface == 80 + 81 + QEMU supports the Physical Presence Interface (PPI) for TPM 1.2 and TPM 2. This 82 + interface requires ACPI and firmware support. The specification can be found at 83 + the following URL: 84 + 85 + https://trustedcomputinggroup.org/resource/tcg-physical-presence-interface-specification/ 86 + 87 + PPI enables a system administrator (root) to request a modification to the 88 + TPM upon reboot. The PPI specification defines the operation requests and the 89 + actions the firmware has to take. The system administrator passes the operation 90 + request number to the firmware through an ACPI interface which writes this 91 + number to a memory location that the firmware knows. Upon reboot, the firmware 92 + finds the number and sends commands to the the TPM. The firmware writes the TPM 93 + result code and the operation request number to a memory location that ACPI can 94 + read from and pass the result on to the administrator. 95 + 96 + The PPI specification defines a set of mandatory and optional operations for 97 + the firmware to implement. The ACPI interface also allows an administrator to 98 + list the supported operations. In QEMU the ACPI code is generated by QEMU, yet 99 + the firmware needs to implement support on a per-operations basis, and 100 + different firmwares may support a different subset. Therefore, QEMU introduces 101 + the virtual memory device for PPI where the firmware can indicate which 102 + operations it supports and ACPI can enable the ones that are supported and 103 + disable all others. This interface lies in main memory and has the following 104 + layout: 105 + 106 + +----------+--------+--------+-------------------------------------------+ 107 + | Field | Length | Offset | Description | 108 + +----------+--------+--------+-------------------------------------------+ 109 + | func | 0x100 | 0x000 | Firmware sets values for each supported | 110 + | | | | operation. See defined values below. | 111 + +----------+--------+--------+-------------------------------------------+ 112 + | ppin | 0x1 | 0x100 | SMI interrupt to use. Set by firmware. | 113 + | | | | Not supported. | 114 + +----------+--------+--------+-------------------------------------------+ 115 + | ppip | 0x4 | 0x101 | ACPI function index to pass to SMM code. | 116 + | | | | Set by ACPI. Not supported. | 117 + +----------+--------+--------+-------------------------------------------+ 118 + | pprp | 0x4 | 0x105 | Result of last executed operation. Set by | 119 + | | | | firmware. See function index 5 for values.| 120 + +----------+--------+--------+-------------------------------------------+ 121 + | pprq | 0x4 | 0x109 | Operation request number to execute. See | 122 + | | | | 'Physical Presence Interface Operation | 123 + | | | | Summary' tables in specs. Set by ACPI. | 124 + +----------+--------+--------+-------------------------------------------+ 125 + | pprm | 0x4 | 0x10d | Operation request optional parameter. | 126 + | | | | Values depend on operation. Set by ACPI. | 127 + +----------+--------+--------+-------------------------------------------+ 128 + | lppr | 0x4 | 0x111 | Last executed operation request number. | 129 + | | | | Copied from pprq field by firmware. | 130 + +----------+--------+--------+-------------------------------------------+ 131 + | fret | 0x4 | 0x115 | Result code from SMM function. | 132 + | | | | Not supported. | 133 + +----------+--------+--------+-------------------------------------------+ 134 + | res1 | 0x40 | 0x119 | Reserved for future use | 135 + +----------+--------+--------+-------------------------------------------+ 136 + | next_step| 0x1 | 0x159 | Operation to execute after reboot by | 137 + | | | | firmware. Used by firmware. | 138 + +----------+--------+--------+-------------------------------------------+ 139 + 140 + The following values are supported for the 'func' field. They correspond 141 + to the values used by ACPI function index 8. 142 + 143 + +----------+-------------------------------------------------------------+ 144 + | value | Description | 145 + +----------+-------------------------------------------------------------+ 146 + | 0 | Operation is not implemented. | 147 + +----------+-------------------------------------------------------------+ 148 + | 1 | Operation is only accessible through firmware. | 149 + +----------+-------------------------------------------------------------+ 150 + | 2 | Operation is blocked for OS by firmware configuration. | 151 + +----------+-------------------------------------------------------------+ 152 + | 3 | Operation is allowed and physically present user required. | 153 + +----------+-------------------------------------------------------------+ 154 + | 4 | Operation is allowed and physically present user is not | 155 + | | required. | 156 + +----------+-------------------------------------------------------------+ 157 + 158 + The location of the table is given by the fw_cfg tpmppi_address field. 159 + The PPI memory region size is 0x400 (TPM_PPI_ADDR_SIZE) to leave 160 + enough room for future updates. 161 + 79 162 80 163 QEMU files related to TPM ACPI tables: 81 164 - hw/i386/acpi-build.c
+1
hw/acpi/Makefile.objs
··· 11 11 common-obj-y += acpi_interface.o 12 12 common-obj-y += bios-linker-loader.o 13 13 common-obj-y += aml-build.o 14 + common-obj-$(CONFIG_TPM) += tpm.o 14 15 15 16 common-obj-$(CONFIG_IPMI) += ipmi.o 16 17 common-obj-$(call lnot,$(CONFIG_IPMI)) += ipmi-stub.o
+404
hw/acpi/tpm.c
··· 1 + /* Support for generating ACPI TPM tables 2 + * 3 + * Copyright (C) 2018 IBM, Corp. 4 + * Copyright (C) 2018 Red Hat Inc 5 + * 6 + * This program is free software; you can redistribute it and/or modify 7 + * it under the terms of the GNU General Public License as published by 8 + * the Free Software Foundation; either version 2 of the License, or 9 + * (at your option) any later version. 10 + 11 + * This program is distributed in the hope that it will be useful, 12 + * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 + * GNU General Public License for more details. 15 + 16 + * You should have received a copy of the GNU General Public License along 17 + * with this program; if not, see <http://www.gnu.org/licenses/>. 18 + */ 19 + #include "qemu/osdep.h" 20 + #include "qapi/error.h" 21 + #include "hw/acpi/tpm.h" 22 + 23 + void 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 + * TPP2 is for the registers that ACPI code used to pass 39 + * the PPI code and parameter (PPRQ, PPRM) to the firmware. 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 + /* 57 + * DerefOf in Windows is broken with SYSTEM_MEMORY. Use a dynamic 58 + * operation region inside of a method for getting FUNC[op]. 59 + */ 60 + method = aml_method("TPFN", 1, AML_SERIALIZED); 61 + { 62 + Aml *op = aml_arg(0); 63 + ifctx = aml_if(aml_lgreater_equal(op, aml_int(0x100))); 64 + { 65 + aml_append(ifctx, aml_return(zero)); 66 + } 67 + aml_append(method, ifctx); 68 + 69 + aml_append(method, 70 + aml_operation_region("TPP1", AML_SYSTEM_MEMORY, 71 + aml_add(aml_int(TPM_PPI_ADDR_BASE), op, NULL), 0x1)); 72 + field = aml_field("TPP1", AML_BYTE_ACC, AML_NOLOCK, AML_PRESERVE); 73 + aml_append(field, aml_named_field("TPPF", 8)); 74 + aml_append(method, field); 75 + aml_append(method, aml_return(aml_name("TPPF"))); 76 + } 77 + aml_append(dev, method); 78 + 79 + /* 80 + * Use global TPM2 & TPM3 variables to workaround Windows ACPI bug 81 + * when returning packages. 82 + */ 83 + pak = aml_package(2); 84 + aml_append(pak, zero); 85 + aml_append(pak, zero); 86 + aml_append(dev, aml_name_decl("TPM2", pak)); 87 + tpm2 = aml_name("TPM2"); 88 + 89 + pak = aml_package(3); 90 + aml_append(pak, zero); 91 + aml_append(pak, zero); 92 + aml_append(pak, zero); 93 + aml_append(dev, aml_name_decl("TPM3", pak)); 94 + tpm3 = aml_name("TPM3"); 95 + 96 + method = aml_method("_DSM", 4, AML_SERIALIZED); 97 + { 98 + uint8_t zerobyte[1] = { 0 }; 99 + Aml *function, *arguments, *rev, *op, *op_arg, *op_flags, *uuid; 100 + 101 + uuid = aml_arg(0); 102 + rev = aml_arg(1); 103 + function = aml_arg(2); 104 + arguments = aml_arg(3); 105 + op = aml_local(0); 106 + op_flags = aml_local(1); 107 + 108 + /* Physical Presence Interface */ 109 + ifctx = aml_if( 110 + aml_equal(uuid, 111 + aml_touuid("3DDDFAA6-361B-4EB4-A424-8D10089D1653"))); 112 + { 113 + /* standard DSM query function */ 114 + ifctx2 = aml_if(aml_equal(function, zero)); 115 + { 116 + uint8_t byte_list[2] = { 0xff, 0x01 }; /* functions 1-8 */ 117 + 118 + aml_append(ifctx2, 119 + aml_return(aml_buffer(sizeof(byte_list), 120 + byte_list))); 121 + } 122 + aml_append(ifctx, ifctx2); 123 + 124 + /* 125 + * PPI 1.0: 2.1.1 Get Physical Presence Interface Version 126 + * 127 + * Arg 2 (Integer): Function Index = 1 128 + * Arg 3 (Package): Arguments = Empty Package 129 + * Returns: Type: String 130 + */ 131 + ifctx2 = aml_if(aml_equal(function, one)); 132 + { 133 + aml_append(ifctx2, aml_return(aml_string("1.3"))); 134 + } 135 + aml_append(ifctx, ifctx2); 136 + 137 + /* 138 + * PPI 1.0: 2.1.3 Submit TPM Operation Request to Pre-OS Environment 139 + * 140 + * Arg 2 (Integer): Function Index = 2 141 + * Arg 3 (Package): Arguments = Package: Type: Integer 142 + * Operation Value of the Request 143 + * Returns: Type: Integer 144 + * 0: Success 145 + * 1: Operation Value of the Request Not Supported 146 + * 2: General Failure 147 + */ 148 + ifctx2 = aml_if(aml_equal(function, aml_int(2))); 149 + { 150 + /* get opcode */ 151 + aml_append(ifctx2, 152 + aml_store(aml_derefof(aml_index(arguments, 153 + zero)), op)); 154 + 155 + /* get opcode flags */ 156 + aml_append(ifctx2, 157 + aml_store(aml_call1("TPFN", op), op_flags)); 158 + 159 + /* if func[opcode] & TPM_PPI_FUNC_NOT_IMPLEMENTED */ 160 + ifctx3 = aml_if( 161 + aml_equal( 162 + aml_and(op_flags, func_mask, NULL), 163 + not_implemented)); 164 + { 165 + /* 1: Operation Value of the Request Not Supported */ 166 + aml_append(ifctx3, aml_return(one)); 167 + } 168 + aml_append(ifctx2, ifctx3); 169 + 170 + aml_append(ifctx2, aml_store(op, pprq)); 171 + aml_append(ifctx2, aml_store(zero, pprm)); 172 + /* 0: success */ 173 + aml_append(ifctx2, aml_return(zero)); 174 + } 175 + aml_append(ifctx, ifctx2); 176 + 177 + /* 178 + * PPI 1.0: 2.1.4 Get Pending TPM Operation Requested By the OS 179 + * 180 + * Arg 2 (Integer): Function Index = 3 181 + * Arg 3 (Package): Arguments = Empty Package 182 + * Returns: Type: Package of Integers 183 + * Integer 1: Function Return code 184 + * 0: Success 185 + * 1: General Failure 186 + * Integer 2: Pending operation requested by the OS 187 + * 0: None 188 + * >0: Operation Value of the Pending Request 189 + * Integer 3: Optional argument to pending operation 190 + * requested by the OS 191 + * 0: None 192 + * >0: Argument Value of the Pending Request 193 + */ 194 + ifctx2 = aml_if(aml_equal(function, aml_int(3))); 195 + { 196 + /* 197 + * Revision ID of 1, no integer parameter beyond 198 + * parameter two are expected 199 + */ 200 + ifctx3 = aml_if(aml_equal(rev, one)); 201 + { 202 + /* TPM2[1] = PPRQ */ 203 + aml_append(ifctx3, 204 + aml_store(pprq, aml_index(tpm2, one))); 205 + aml_append(ifctx3, aml_return(tpm2)); 206 + } 207 + aml_append(ifctx2, ifctx3); 208 + 209 + /* 210 + * A return value of {0, 23, 1} indicates that 211 + * operation 23 with argument 1 is pending. 212 + */ 213 + ifctx3 = aml_if(aml_equal(rev, aml_int(2))); 214 + { 215 + /* TPM3[1] = PPRQ */ 216 + aml_append(ifctx3, 217 + aml_store(pprq, aml_index(tpm3, one))); 218 + /* TPM3[2] = PPRM */ 219 + aml_append(ifctx3, 220 + aml_store(pprm, aml_index(tpm3, aml_int(2)))); 221 + aml_append(ifctx3, aml_return(tpm3)); 222 + } 223 + aml_append(ifctx2, ifctx3); 224 + } 225 + aml_append(ifctx, ifctx2); 226 + 227 + /* 228 + * PPI 1.0: 2.1.5 Get Platform-Specific Action to Transition to 229 + * Pre-OS Environment 230 + * 231 + * Arg 2 (Integer): Function Index = 4 232 + * Arg 3 (Package): Arguments = Empty Package 233 + * Returns: Type: Integer 234 + * 0: None 235 + * 1: Shutdown 236 + * 2: Reboot 237 + * 3: OS Vendor-specific 238 + */ 239 + ifctx2 = aml_if(aml_equal(function, aml_int(4))); 240 + { 241 + /* reboot */ 242 + aml_append(ifctx2, aml_return(aml_int(2))); 243 + } 244 + aml_append(ifctx, ifctx2); 245 + 246 + /* 247 + * PPI 1.0: 2.1.6 Return TPM Operation Response to OS Environment 248 + * 249 + * Arg 2 (Integer): Function Index = 5 250 + * Arg 3 (Package): Arguments = Empty Package 251 + * Returns: Type: Package of Integer 252 + * Integer 1: Function Return code 253 + * 0: Success 254 + * 1: General Failure 255 + * Integer 2: Most recent operation request 256 + * 0: None 257 + * >0: Operation Value of the most recent request 258 + * Integer 3: Response to the most recent operation request 259 + * 0: Success 260 + * 0x00000001..0x00000FFF: Corresponding TPM 261 + * error code 262 + * 0xFFFFFFF0: User Abort or timeout of dialog 263 + * 0xFFFFFFF1: firmware Failure 264 + */ 265 + ifctx2 = aml_if(aml_equal(function, aml_int(5))); 266 + { 267 + /* TPM3[1] = LPPR */ 268 + aml_append(ifctx2, 269 + aml_store(aml_name("LPPR"), 270 + aml_index(tpm3, one))); 271 + /* TPM3[2] = PPRP */ 272 + aml_append(ifctx2, 273 + aml_store(aml_name("PPRP"), 274 + aml_index(tpm3, aml_int(2)))); 275 + aml_append(ifctx2, aml_return(tpm3)); 276 + } 277 + aml_append(ifctx, ifctx2); 278 + 279 + /* 280 + * PPI 1.0: 2.1.7 Submit preferred user language 281 + * 282 + * Arg 2 (Integer): Function Index = 6 283 + * Arg 3 (Package): Arguments = String Package 284 + * Preferred language code 285 + * Returns: Type: Integer 286 + * Function Return Code 287 + * 3: Not implemented 288 + */ 289 + ifctx2 = aml_if(aml_equal(function, aml_int(6))); 290 + { 291 + /* 3 = not implemented */ 292 + aml_append(ifctx2, aml_return(aml_int(3))); 293 + } 294 + aml_append(ifctx, ifctx2); 295 + 296 + /* 297 + * PPI 1.1: 2.1.7 Submit TPM Operation Request to 298 + * Pre-OS Environment 2 299 + * 300 + * Arg 2 (Integer): Function Index = 7 301 + * Arg 3 (Package): Arguments = Package: Type: Integer 302 + * Integer 1: Operation Value of the Request 303 + * Integer 2: Argument for Operation (optional) 304 + * Returns: Type: Integer 305 + * 0: Success 306 + * 1: Not Implemented 307 + * 2: General Failure 308 + * 3: Operation blocked by current firmware settings 309 + */ 310 + ifctx2 = aml_if(aml_equal(function, aml_int(7))); 311 + { 312 + /* get opcode */ 313 + aml_append(ifctx2, aml_store(aml_derefof(aml_index(arguments, 314 + zero)), 315 + op)); 316 + 317 + /* get opcode flags */ 318 + aml_append(ifctx2, aml_store(aml_call1("TPFN", op), 319 + op_flags)); 320 + /* if func[opcode] & TPM_PPI_FUNC_NOT_IMPLEMENTED */ 321 + ifctx3 = aml_if( 322 + aml_equal( 323 + aml_and(op_flags, func_mask, NULL), 324 + not_implemented)); 325 + { 326 + /* 1: not implemented */ 327 + aml_append(ifctx3, aml_return(one)); 328 + } 329 + aml_append(ifctx2, ifctx3); 330 + 331 + /* if func[opcode] & TPM_PPI_FUNC_BLOCKED */ 332 + ifctx3 = aml_if( 333 + aml_equal( 334 + aml_and(op_flags, func_mask, NULL), 335 + aml_int(TPM_PPI_FUNC_BLOCKED))); 336 + { 337 + /* 3: blocked by firmware */ 338 + aml_append(ifctx3, aml_return(aml_int(3))); 339 + } 340 + aml_append(ifctx2, ifctx3); 341 + 342 + /* revision to integer */ 343 + ifctx3 = aml_if(aml_equal(rev, one)); 344 + { 345 + /* revision 1 */ 346 + /* PPRQ = op */ 347 + aml_append(ifctx3, aml_store(op, pprq)); 348 + /* no argument, PPRM = 0 */ 349 + aml_append(ifctx3, aml_store(zero, pprm)); 350 + } 351 + aml_append(ifctx2, ifctx3); 352 + 353 + ifctx3 = aml_if(aml_equal(rev, aml_int(2))); 354 + { 355 + /* revision 2 */ 356 + /* PPRQ = op */ 357 + op_arg = aml_derefof(aml_index(arguments, one)); 358 + aml_append(ifctx3, aml_store(op, pprq)); 359 + /* PPRM = arg3[1] */ 360 + aml_append(ifctx3, aml_store(op_arg, pprm)); 361 + } 362 + aml_append(ifctx2, ifctx3); 363 + /* 0: success */ 364 + aml_append(ifctx2, aml_return(zero)); 365 + } 366 + aml_append(ifctx, ifctx2); 367 + 368 + /* 369 + * PPI 1.1: 2.1.8 Get User Confirmation Status for Operation 370 + * 371 + * Arg 2 (Integer): Function Index = 8 372 + * Arg 3 (Package): Arguments = Package: Type: Integer 373 + * Operation Value that may need user confirmation 374 + * Returns: Type: Integer 375 + * 0: Not implemented 376 + * 1: Firmware only 377 + * 2: Blocked for OS by firmware configuration 378 + * 3: Allowed and physically present user required 379 + * 4: Allowed and physically present user not required 380 + */ 381 + ifctx2 = aml_if(aml_equal(function, aml_int(8))); 382 + { 383 + /* get opcode */ 384 + aml_append(ifctx2, 385 + aml_store(aml_derefof(aml_index(arguments, 386 + zero)), 387 + op)); 388 + 389 + /* get opcode flags */ 390 + aml_append(ifctx2, aml_store(aml_call1("TPFN", op), 391 + op_flags)); 392 + /* return confirmation status code */ 393 + aml_append(ifctx2, 394 + aml_return( 395 + aml_and(op_flags, func_mask, NULL))); 396 + } 397 + aml_append(ifctx, ifctx2); 398 + 399 + aml_append(ifctx, aml_return(aml_buffer(1, zerobyte))); 400 + } 401 + aml_append(method, ifctx); 402 + } 403 + aml_append(dev, method); 404 + }
+9 -3
hw/i386/acpi-build.c
··· 1802 1802 uint32_t nr_mem = machine->ram_slots; 1803 1803 int root_bus_limit = 0xFF; 1804 1804 PCIBus *bus = NULL; 1805 + TPMIf *tpm = tpm_find(); 1805 1806 int i; 1806 1807 1807 1808 dsdt = init_aml_allocator(); ··· 2139 2140 /* Scan all PCI buses. Generate tables to support hotplug. */ 2140 2141 build_append_pci_bus_devices(scope, bus, pm->pcihp_bridge_en); 2141 2142 2142 - if (TPM_IS_TIS(tpm_find())) { 2143 + if (TPM_IS_TIS(tpm)) { 2143 2144 dev = aml_device("ISA.TPM"); 2144 2145 aml_append(dev, aml_name_decl("_HID", aml_eisaid("PNP0C31"))); 2145 2146 aml_append(dev, aml_name_decl("_STA", aml_int(0xF))); ··· 2153 2154 */ 2154 2155 /* aml_append(crs, aml_irq_no_flags(TPM_TIS_IRQ)); */ 2155 2156 aml_append(dev, aml_name_decl("_CRS", crs)); 2157 + 2158 + tpm_build_ppi_acpi(tpm, dev); 2159 + 2156 2160 aml_append(scope, dev); 2157 2161 } 2158 2162 ··· 2160 2164 } 2161 2165 } 2162 2166 2163 - if (TPM_IS_CRB(tpm_find())) { 2167 + if (TPM_IS_CRB(tpm)) { 2164 2168 dev = aml_device("TPM"); 2165 2169 aml_append(dev, aml_name_decl("_HID", aml_string("MSFT0101"))); 2166 2170 crs = aml_resource_template(); ··· 2171 2175 method = aml_method("_STA", 0, AML_NOTSERIALIZED); 2172 2176 aml_append(method, aml_return(aml_int(0x0f))); 2173 2177 aml_append(dev, method); 2178 + 2179 + tpm_build_ppi_acpi(tpm, dev); 2174 2180 2175 2181 aml_append(sb_scope, dev); 2176 2182 } ··· 2894 2900 tpm_config = (FwCfgTPMConfig) { 2895 2901 .tpmppi_address = cpu_to_le32(TPM_PPI_ADDR_BASE), 2896 2902 .tpm_version = tpm_get_version(tpm), 2897 - .tpmppi_version = TPM_PPI_VERSION_NONE 2903 + .tpmppi_version = TPM_PPI_VERSION_1_30 2898 2904 }; 2899 2905 fw_cfg_add_file(pcms->fw_cfg, "etc/tpm/config", 2900 2906 &tpm_config, sizeof tpm_config);
+12
include/hw/acpi/tpm.h
··· 18 18 19 19 #include "qemu/units.h" 20 20 #include "hw/registerfields.h" 21 + #include "hw/acpi/aml-build.h" 22 + #include "sysemu/tpm.h" 21 23 22 24 #define TPM_TIS_ADDR_BASE 0xFED40000 23 25 #define TPM_TIS_ADDR_SIZE 0x5000 ··· 196 198 197 199 #define TPM_PPI_VERSION_NONE 0 198 200 #define TPM_PPI_VERSION_1_30 1 201 + 202 + /* whether function is blocked by BIOS settings; bits 0, 1, 2 */ 203 + #define TPM_PPI_FUNC_NOT_IMPLEMENTED (0 << 0) 204 + #define TPM_PPI_FUNC_BIOS_ONLY (1 << 0) 205 + #define TPM_PPI_FUNC_BLOCKED (2 << 0) 206 + #define TPM_PPI_FUNC_ALLOWED_USR_REQ (3 << 0) 207 + #define TPM_PPI_FUNC_ALLOWED_USR_NOT_REQ (4 << 0) 208 + #define TPM_PPI_FUNC_MASK (7 << 0) 209 + 210 + void tpm_build_ppi_acpi(TPMIf *tpm, Aml *dev); 199 211 200 212 #endif /* HW_ACPI_TPM_H */
+5
stubs/tpm.c
··· 8 8 #include "qemu/osdep.h" 9 9 #include "qapi/qapi-commands-tpm.h" 10 10 #include "sysemu/tpm.h" 11 + #include "hw/acpi/tpm.h" 11 12 12 13 void tpm_init(void) 13 14 { ··· 31 32 { 32 33 return NULL; 33 34 } 35 + 36 + void tpm_build_ppi_acpi(TPMIf *tpm, Aml *dev) 37 + { 38 + }