1 | /* $Id: DevTpmPpi.cpp 105041 2024-06-27 08:52:03Z vboxsync $ */
|
---|
2 | /** @file
|
---|
3 | * DevTpmPpi - Guest platform <-> VirtualBox TPM Physical Presence Interface Integration Framework.
|
---|
4 | *
|
---|
5 | * Based on: https://github.com/qemu/qemu/blob/master/docs/specs/tpm.rst (2024-06-26).
|
---|
6 | */
|
---|
7 |
|
---|
8 | /*
|
---|
9 | * Copyright (C) 2024 Oracle and/or its affiliates.
|
---|
10 | *
|
---|
11 | * This file is part of VirtualBox base platform packages, as
|
---|
12 | * available from https://www.virtualbox.org.
|
---|
13 | *
|
---|
14 | * This program is free software; you can redistribute it and/or
|
---|
15 | * modify it under the terms of the GNU General Public License
|
---|
16 | * as published by the Free Software Foundation, in version 3 of the
|
---|
17 | * License.
|
---|
18 | *
|
---|
19 | * This program is distributed in the hope that it will be useful, but
|
---|
20 | * WITHOUT ANY WARRANTY; without even the implied warranty of
|
---|
21 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
---|
22 | * General Public License for more details.
|
---|
23 | *
|
---|
24 | * You should have received a copy of the GNU General Public License
|
---|
25 | * along with this program; if not, see <https://www.gnu.org/licenses>.
|
---|
26 | *
|
---|
27 | * SPDX-License-Identifier: GPL-3.0-only
|
---|
28 | */
|
---|
29 |
|
---|
30 |
|
---|
31 | /*********************************************************************************************************************************
|
---|
32 | * Header Files *
|
---|
33 | *********************************************************************************************************************************/
|
---|
34 | #define LOG_GROUP LOG_GROUP_DEV_TPM
|
---|
35 |
|
---|
36 | #include <VBox/vmm/pdmdev.h>
|
---|
37 | #include <VBox/log.h>
|
---|
38 | #include <VBox/err.h>
|
---|
39 | #include <VBox/param.h>
|
---|
40 |
|
---|
41 | #include <iprt/asm.h>
|
---|
42 | #include <iprt/assert.h>
|
---|
43 | #include <iprt/ctype.h>
|
---|
44 |
|
---|
45 | #include "VBoxDD.h"
|
---|
46 |
|
---|
47 |
|
---|
48 | /*********************************************************************************************************************************
|
---|
49 | * Defined Constants And Macros *
|
---|
50 | *********************************************************************************************************************************/
|
---|
51 |
|
---|
52 | /** The TPM saved state version. */
|
---|
53 | #define TPM_PPI_SAVED_STATE_VERSION 1
|
---|
54 |
|
---|
55 | /** The TPM PPI MMIO base default (compatible with qemu). */
|
---|
56 | #define TPM_PPI_MMIO_BASE_DEFAULT UINT64_C(0xfed45000)
|
---|
57 | /** The size of the TPM PPI MMIO area. */
|
---|
58 | #define TPM_PPI_MMIO_SIZE _4K
|
---|
59 |
|
---|
60 | /** @name QEMU compatible PPI interface layout.
|
---|
61 | * @{ */
|
---|
62 | /**
|
---|
63 | * The PPI structure layout (yes, it really is misaligned).
|
---|
64 | */
|
---|
65 | #pragma pack(1)
|
---|
66 | typedef union QEMUTPMPPI
|
---|
67 | {
|
---|
68 | /** The byte view. */
|
---|
69 | uint8_t ab[0x400];
|
---|
70 | /** The structured view. */
|
---|
71 | struct
|
---|
72 | {
|
---|
73 | /** Supported operation flags set by the firmware for each operation. */
|
---|
74 | uint8_t abFunc[0x100];
|
---|
75 | /** SMI interrupt to use, set by firmware. Not supported. */
|
---|
76 | uint8_t bPpin;
|
---|
77 | /** ACPI function index to pass to SMM code, set by ACPI. Not supported. */
|
---|
78 | uint32_t u32Ppip;
|
---|
79 | /** Result of last executed operation, set by firmware. */
|
---|
80 | uint32_t u32Pprp;
|
---|
81 | /** Operation request number to execute, set by ACPI. */
|
---|
82 | uint32_t u32Pprq;
|
---|
83 | /** Operation request optional parameter, set by ACPI. */
|
---|
84 | uint32_t u32Pprm;
|
---|
85 | /** Last executed operation request number, copied from QEMUTPMPPI::u32PPrq field by firmware. */
|
---|
86 | uint32_t u32Lppr;
|
---|
87 | /** Result code from SMM function, not supported. */
|
---|
88 | uint32_t u32Fret;
|
---|
89 | /** Reserved for future use. */
|
---|
90 | uint8_t abRsvd[0x40];
|
---|
91 | /** Operation to execute after reboot by firmware, used by firmware. */
|
---|
92 | uint8_t bNextStep;
|
---|
93 | /** Memory overwrite variable. */
|
---|
94 | uint8_t bMovv;
|
---|
95 | } s;
|
---|
96 | } QEMUTPMPPI;
|
---|
97 | #pragma pack()
|
---|
98 | AssertCompileSize(QEMUTPMPPI, 0x400);
|
---|
99 | /** Pointer to the QEMU PPI structure layout. */
|
---|
100 | typedef QEMUTPMPPI *PQEMUTPMPPI;
|
---|
101 | /** Pointer to a const QEMU PPI structure layout. */
|
---|
102 | typedef const QEMUTPMPPI *PCQEMUTPMPPI;
|
---|
103 | /** @} */
|
---|
104 |
|
---|
105 |
|
---|
106 | /*********************************************************************************************************************************
|
---|
107 | * Structures and Typedefs *
|
---|
108 | *********************************************************************************************************************************/
|
---|
109 |
|
---|
110 | /**
|
---|
111 | * Shared TPM PPI device state.
|
---|
112 | */
|
---|
113 | typedef struct DEVTPMPPI
|
---|
114 | {
|
---|
115 | /** Base MMIO address of the TPM PPI area. */
|
---|
116 | RTGCPHYS GCPhysMmio;
|
---|
117 | /** The handle of the MMIO region. */
|
---|
118 | IOMMMIOHANDLE hMmio;
|
---|
119 | /** The QEMU PPI state. */
|
---|
120 | QEMUTPMPPI Ppi;
|
---|
121 | } DEVTPMPPI;
|
---|
122 | /** Pointer to the shared TPM PPI device state. */
|
---|
123 | typedef DEVTPMPPI *PDEVTPMPPI;
|
---|
124 |
|
---|
125 | /**
|
---|
126 | * TPM PPI device state for ring-3.
|
---|
127 | */
|
---|
128 | typedef struct DEVTPMPPIR3
|
---|
129 | {
|
---|
130 | /** Pointer to the device instance. */
|
---|
131 | PPDMDEVINS pDevIns;
|
---|
132 | } DEVTPMPPIR3;
|
---|
133 | /** Pointer to the TPM device state for ring-3. */
|
---|
134 | typedef DEVTPMPPIR3 *PDEVTPMPPIR3;
|
---|
135 |
|
---|
136 |
|
---|
137 | /**
|
---|
138 | * TPM PPI device state for ring-0.
|
---|
139 | */
|
---|
140 | typedef struct DEVTPMPPIR0
|
---|
141 | {
|
---|
142 | uint32_t u32Dummy;
|
---|
143 |
|
---|
144 | } DEVTPMPPIR0;
|
---|
145 | /** Pointer to the TPM device state for ring-0. */
|
---|
146 | typedef DEVTPMPPIR0 *PDEVTPMPPIR0;
|
---|
147 |
|
---|
148 |
|
---|
149 | /**
|
---|
150 | * TPM PPI device state for raw-mode.
|
---|
151 | */
|
---|
152 | typedef struct DEVTPMPPIRC
|
---|
153 | {
|
---|
154 | uint32_t u32Dummy;
|
---|
155 | } DEVTPMPPIRC;
|
---|
156 | /** Pointer to the TPM device state for raw-mode. */
|
---|
157 | typedef DEVTPMPPIRC *PDEVTPMPPIRC;
|
---|
158 |
|
---|
159 | /** The TPM PI device state for the current context. */
|
---|
160 | typedef CTX_SUFF(DEVTPMPPI) DEVTPMPPICC;
|
---|
161 | /** Pointer to the TPM PPI device state for the current context. */
|
---|
162 | typedef CTX_SUFF(PDEVTPMPPI) PDEVTPMPPICC;
|
---|
163 |
|
---|
164 |
|
---|
165 | /*********************************************************************************************************************************
|
---|
166 | * Defined Constants And Macros *
|
---|
167 | *********************************************************************************************************************************/
|
---|
168 |
|
---|
169 |
|
---|
170 | /*********************************************************************************************************************************
|
---|
171 | * Global Variables *
|
---|
172 | *********************************************************************************************************************************/
|
---|
173 |
|
---|
174 | #ifdef IN_RING3
|
---|
175 | /**
|
---|
176 | * SSM descriptor table for the TPM PPI structure.
|
---|
177 | */
|
---|
178 | static SSMFIELD const g_aTpmPpiFields[] =
|
---|
179 | {
|
---|
180 | SSMFIELD_ENTRY(QEMUTPMPPI, s.abFunc),
|
---|
181 | SSMFIELD_ENTRY(QEMUTPMPPI, s.bPpin),
|
---|
182 | SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Ppip),
|
---|
183 | SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Pprp),
|
---|
184 | SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Pprq),
|
---|
185 | SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Pprm),
|
---|
186 | SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Lppr),
|
---|
187 | SSMFIELD_ENTRY(QEMUTPMPPI, s.u32Fret),
|
---|
188 | SSMFIELD_ENTRY(QEMUTPMPPI, s.bNextStep),
|
---|
189 | SSMFIELD_ENTRY(QEMUTPMPPI, s.bMovv),
|
---|
190 | SSMFIELD_ENTRY_TERM()
|
---|
191 | };
|
---|
192 | #endif
|
---|
193 |
|
---|
194 |
|
---|
195 | /* -=-=-=-=-=- MMIO callbacks -=-=-=-=-=- */
|
---|
196 |
|
---|
197 | /**
|
---|
198 | * @callback_method_impl{FNIOMMMIONEWREAD}
|
---|
199 | */
|
---|
200 | static DECLCALLBACK(VBOXSTRICTRC) tpmPpiMmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
|
---|
201 | {
|
---|
202 | PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
|
---|
203 | RT_NOREF(pvUser);
|
---|
204 |
|
---|
205 | LogFlowFunc(("off=%RGp cb=%u\n", off, cb));
|
---|
206 | if (off + cb > sizeof(pThis->Ppi))
|
---|
207 | return VINF_IOM_MMIO_UNUSED_FF;
|
---|
208 |
|
---|
209 | memcpy(pv, &pThis->Ppi.ab[off], cb);
|
---|
210 | return VINF_SUCCESS;
|
---|
211 | }
|
---|
212 |
|
---|
213 |
|
---|
214 | /**
|
---|
215 | * @callback_method_impl{FNIOMMMIONEWWRITE}
|
---|
216 | */
|
---|
217 | static DECLCALLBACK(VBOXSTRICTRC) tpmPpiMmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb)
|
---|
218 | {
|
---|
219 | PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
|
---|
220 | RT_NOREF(pvUser);
|
---|
221 |
|
---|
222 | LogFlowFunc(("off=%RGp cb=%u\n", off, cb));
|
---|
223 | if (off + cb > sizeof(pThis->Ppi))
|
---|
224 | return VINF_SUCCESS;
|
---|
225 |
|
---|
226 | memcpy(&pThis->Ppi.ab[off], pv, cb);
|
---|
227 | return VINF_SUCCESS;
|
---|
228 | }
|
---|
229 |
|
---|
230 |
|
---|
231 | #ifdef IN_RING3
|
---|
232 |
|
---|
233 | /* -=-=-=-=-=-=-=-=- Saved State -=-=-=-=-=-=-=-=- */
|
---|
234 |
|
---|
235 | /**
|
---|
236 | * @callback_method_impl{FNSSMDEVLIVEEXEC}
|
---|
237 | */
|
---|
238 | static DECLCALLBACK(int) tpmPpiR3LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
|
---|
239 | {
|
---|
240 | PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
|
---|
241 | PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
|
---|
242 | RT_NOREF(uPass);
|
---|
243 |
|
---|
244 | /* Save the part of the config used for verification purposes when restoring. */
|
---|
245 | pHlp->pfnSSMPutGCPhys(pSSM, pThis->GCPhysMmio);
|
---|
246 |
|
---|
247 | return VINF_SSM_DONT_CALL_AGAIN;
|
---|
248 | }
|
---|
249 |
|
---|
250 |
|
---|
251 | /**
|
---|
252 | * @callback_method_impl{FNSSMDEVSAVEEXEC}
|
---|
253 | */
|
---|
254 | static DECLCALLBACK(int) tpmPpiR3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
|
---|
255 | {
|
---|
256 | PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
|
---|
257 | PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
|
---|
258 |
|
---|
259 | tpmPpiR3LiveExec(pDevIns, pSSM, SSM_PASS_FINAL);
|
---|
260 |
|
---|
261 | int rc = pHlp->pfnSSMPutStructEx(pSSM, &pThis->Ppi, sizeof(pThis->Ppi), 0 /*fFlags*/, &g_aTpmPpiFields[0], NULL);
|
---|
262 | AssertRCReturn(rc, rc);
|
---|
263 |
|
---|
264 | return pHlp->pfnSSMPutU32(pSSM, UINT32_MAX); /* sanity/terminator */
|
---|
265 | }
|
---|
266 |
|
---|
267 |
|
---|
268 | /**
|
---|
269 | * @callback_method_impl{FNSSMDEVLOADEXEC}
|
---|
270 | */
|
---|
271 | static DECLCALLBACK(int) tpmPpiR3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
|
---|
272 | {
|
---|
273 | PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
|
---|
274 | PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
|
---|
275 | RTGCPHYS GCPhysMmio;
|
---|
276 |
|
---|
277 | Assert(uPass == SSM_PASS_FINAL); RT_NOREF(uPass);
|
---|
278 | AssertMsgReturn(uVersion == TPM_PPI_SAVED_STATE_VERSION, ("%d\n", uVersion), VERR_SSM_UNSUPPORTED_DATA_UNIT_VERSION);
|
---|
279 |
|
---|
280 | /* Verify the config first. */
|
---|
281 | int rc = pHlp->pfnSSMGetGCPhys(pSSM, &GCPhysMmio);
|
---|
282 | AssertRCReturn(rc, rc);
|
---|
283 | if (GCPhysMmio != pThis->GCPhysMmio)
|
---|
284 | return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS,
|
---|
285 | N_("Config mismatch - saved GCPhysMmio=%#RGp; configured GCPhysMmio=%#RGp"),
|
---|
286 | GCPhysMmio, pThis->GCPhysMmio);
|
---|
287 |
|
---|
288 | if (uPass == SSM_PASS_FINAL)
|
---|
289 | {
|
---|
290 | rc = pHlp->pfnSSMGetStructEx(pSSM, &pThis->Ppi, sizeof(pThis->Ppi), 0 /*fFlags*/, &g_aTpmPpiFields[0], NULL);
|
---|
291 | AssertRCReturn(rc, rc);
|
---|
292 |
|
---|
293 | /* The marker. */
|
---|
294 | uint32_t u32;
|
---|
295 | rc = pHlp->pfnSSMGetU32(pSSM, &u32);
|
---|
296 | AssertRCReturn(rc, rc);
|
---|
297 | AssertMsgReturn(u32 == UINT32_MAX, ("%#x\n", u32), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
|
---|
298 | }
|
---|
299 |
|
---|
300 | return VINF_SUCCESS;
|
---|
301 | }
|
---|
302 |
|
---|
303 |
|
---|
304 | /**
|
---|
305 | * @interface_method_impl{PDMDEVREG,pfnDestruct}
|
---|
306 | */
|
---|
307 | static DECLCALLBACK(int) tpmPpiR3Destruct(PPDMDEVINS pDevIns)
|
---|
308 | {
|
---|
309 | PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
|
---|
310 | return VINF_SUCCESS;
|
---|
311 | }
|
---|
312 |
|
---|
313 |
|
---|
314 | /**
|
---|
315 | * @interface_method_impl{PDMDEVREG,pfnConstruct}
|
---|
316 | */
|
---|
317 | static DECLCALLBACK(int) tpmPpiR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
|
---|
318 | {
|
---|
319 | PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
|
---|
320 | PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
|
---|
321 | PDEVTPMPPICC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVTPMPPICC);
|
---|
322 | PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
|
---|
323 | int rc;
|
---|
324 |
|
---|
325 | RT_NOREF(iInstance);
|
---|
326 | Assert(iInstance == 0);
|
---|
327 |
|
---|
328 | /*
|
---|
329 | * Initalize the basic variables so that the destructor always works.
|
---|
330 | */
|
---|
331 | pThisCC->pDevIns = pDevIns;
|
---|
332 |
|
---|
333 | /*
|
---|
334 | * Validate and read the configuration.
|
---|
335 | */
|
---|
336 | PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "MmioBase", "");
|
---|
337 |
|
---|
338 | rc = pHlp->pfnCFGMQueryU64Def(pCfg, "MmioBase", &pThis->GCPhysMmio, TPM_PPI_MMIO_BASE_DEFAULT);
|
---|
339 | if (RT_FAILURE(rc))
|
---|
340 | return PDMDEV_SET_ERROR(pDevIns, rc,
|
---|
341 | N_("Configuration error: Failed to get the \"MmioBase\" value"));
|
---|
342 |
|
---|
343 | /*
|
---|
344 | * Register the MMIO range, PDM API requests page aligned
|
---|
345 | * addresses and sizes.
|
---|
346 | */
|
---|
347 | rc = PDMDevHlpMmioCreateAndMap(pDevIns, pThis->GCPhysMmio, TPM_PPI_MMIO_SIZE, tpmPpiMmioWrite, tpmPpiMmioRead,
|
---|
348 | IOMMMIO_FLAGS_READ_PASSTHRU | IOMMMIO_FLAGS_WRITE_PASSTHRU,
|
---|
349 | "TPM PPI MMIO", &pThis->hMmio);
|
---|
350 | AssertRCReturn(rc, rc);
|
---|
351 |
|
---|
352 | /*
|
---|
353 | * Saved state.
|
---|
354 | */
|
---|
355 | rc = PDMDevHlpSSMRegister3(pDevIns, TPM_PPI_SAVED_STATE_VERSION, sizeof(*pThis),
|
---|
356 | tpmPpiR3LiveExec, tpmPpiR3SaveExec, tpmPpiR3LoadExec);
|
---|
357 | AssertRCReturn(rc, rc);
|
---|
358 |
|
---|
359 | return VINF_SUCCESS;
|
---|
360 | }
|
---|
361 |
|
---|
362 |
|
---|
363 | #else /* !IN_RING3 */
|
---|
364 |
|
---|
365 | /**
|
---|
366 | * @callback_method_impl{PDMDEVREGR0,pfnConstruct}
|
---|
367 | */
|
---|
368 | static DECLCALLBACK(int) tpmPpiRZConstruct(PPDMDEVINS pDevIns)
|
---|
369 | {
|
---|
370 | PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
|
---|
371 | PDEVTPMPPI pThis = PDMDEVINS_2_DATA(pDevIns, PDEVTPMPPI);
|
---|
372 |
|
---|
373 | int rc = PDMDevHlpMmioSetUpContext(pDevIns, pThis->hMmio, tpmPpiMmioWrite, tpmPpiMmioRead, NULL /*pvUser*/);
|
---|
374 | AssertRCReturn(rc, rc);
|
---|
375 |
|
---|
376 | return VINF_SUCCESS;
|
---|
377 | }
|
---|
378 |
|
---|
379 | #endif /* !IN_RING3 */
|
---|
380 |
|
---|
381 |
|
---|
382 | /**
|
---|
383 | * The device registration structure.
|
---|
384 | */
|
---|
385 | const PDMDEVREG g_DeviceTpmPpi =
|
---|
386 | {
|
---|
387 | /* .u32Version = */ PDM_DEVREG_VERSION,
|
---|
388 | /* .uReserved0 = */ 0,
|
---|
389 | /* .szName = */ "tpm-ppi",
|
---|
390 | /* .fFlags = */ PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_NEW_STYLE,
|
---|
391 | /* .fClass = */ PDM_DEVREG_CLASS_ARCH_BIOS,
|
---|
392 | /* .cMaxInstances = */ 1,
|
---|
393 | /* .uSharedVersion = */ 42,
|
---|
394 | /* .cbInstanceShared = */ sizeof(DEVTPMPPI),
|
---|
395 | /* .cbInstanceCC = */ sizeof(DEVTPMPPICC),
|
---|
396 | /* .cbInstanceRC = */ sizeof(DEVTPMPPIRC),
|
---|
397 | /* .cMaxPciDevices = */ 0,
|
---|
398 | /* .cMaxMsixVectors = */ 0,
|
---|
399 | /* .pszDescription = */ "Device implementing the TPM Physical Presence Interface (PPI)\n",
|
---|
400 | #if defined(IN_RING3)
|
---|
401 | /* .pszRCMod = */ "",
|
---|
402 | /* .pszR0Mod = */ "",
|
---|
403 | /* .pfnConstruct = */ tpmPpiR3Construct,
|
---|
404 | /* .pfnDestruct = */ tpmPpiR3Destruct,
|
---|
405 | /* .pfnRelocate = */ NULL,
|
---|
406 | /* .pfnMemSetup = */ NULL,
|
---|
407 | /* .pfnPowerOn = */ NULL,
|
---|
408 | /* .pfnReset = */ NULL,
|
---|
409 | /* .pfnSuspend = */ NULL,
|
---|
410 | /* .pfnResume = */ NULL,
|
---|
411 | /* .pfnAttach = */ NULL,
|
---|
412 | /* .pfnDetach = */ NULL,
|
---|
413 | /* .pfnQueryInterface = */ NULL,
|
---|
414 | /* .pfnInitComplete = */ NULL,
|
---|
415 | /* .pfnPowerOff = */ NULL,
|
---|
416 | /* .pfnSoftReset = */ NULL,
|
---|
417 | /* .pfnReserved0 = */ NULL,
|
---|
418 | /* .pfnReserved1 = */ NULL,
|
---|
419 | /* .pfnReserved2 = */ NULL,
|
---|
420 | /* .pfnReserved3 = */ NULL,
|
---|
421 | /* .pfnReserved4 = */ NULL,
|
---|
422 | /* .pfnReserved5 = */ NULL,
|
---|
423 | /* .pfnReserved6 = */ NULL,
|
---|
424 | /* .pfnReserved7 = */ NULL,
|
---|
425 | #elif defined(IN_RING0)
|
---|
426 | /* .pfnEarlyConstruct = */ NULL,
|
---|
427 | /* .pfnConstruct = */ tpmPpiRZConstruct,
|
---|
428 | /* .pfnDestruct = */ NULL,
|
---|
429 | /* .pfnFinalDestruct = */ NULL,
|
---|
430 | /* .pfnRequest = */ NULL,
|
---|
431 | /* .pfnReserved0 = */ NULL,
|
---|
432 | /* .pfnReserved1 = */ NULL,
|
---|
433 | /* .pfnReserved2 = */ NULL,
|
---|
434 | /* .pfnReserved3 = */ NULL,
|
---|
435 | /* .pfnReserved4 = */ NULL,
|
---|
436 | /* .pfnReserved5 = */ NULL,
|
---|
437 | /* .pfnReserved6 = */ NULL,
|
---|
438 | /* .pfnReserved7 = */ NULL,
|
---|
439 | #elif defined(IN_RC)
|
---|
440 | /* .pfnConstruct = */ tpmPpiRZConstruct,
|
---|
441 | /* .pfnReserved0 = */ NULL,
|
---|
442 | /* .pfnReserved1 = */ NULL,
|
---|
443 | /* .pfnReserved2 = */ NULL,
|
---|
444 | /* .pfnReserved3 = */ NULL,
|
---|
445 | /* .pfnReserved4 = */ NULL,
|
---|
446 | /* .pfnReserved5 = */ NULL,
|
---|
447 | /* .pfnReserved6 = */ NULL,
|
---|
448 | /* .pfnReserved7 = */ NULL,
|
---|
449 | #else
|
---|
450 | # error "Not in IN_RING3, IN_RING0 or IN_RC!"
|
---|
451 | #endif
|
---|
452 | /* .u32VersionEnd = */ PDM_DEVREG_VERSION
|
---|
453 | };
|
---|