VirtualBox

source: vbox/trunk/src/VBox/Devices/Gpio/DevPL061.cpp@ 100768

Last change on this file since 100768 was 100768, checked in by vboxsync, 10 months ago

Devices/Gpio/DevPL061: Stub the saved state logic as there is nothing to really save and restore currently, bugref:10453

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 19.5 KB
Line 
1/* $Id: DevPL061.cpp 100768 2023-08-01 10:59:45Z vboxsync $ */
2/** @file
3 * DevPL061 - ARM PL061 PrimeCell GPIO.
4 *
5 * The documentation for this device was taken from
6 * https://developer.arm.com/documentation/ddi0190/b/programmer-s-model/summary-of-primecell-gpio-registers (2023-05-22).
7 */
8
9/*
10 * Copyright (C) 2023 Oracle and/or its affiliates.
11 *
12 * This file is part of VirtualBox base platform packages, as
13 * available from https://www.virtualbox.org.
14 *
15 * This program is free software; you can redistribute it and/or
16 * modify it under the terms of the GNU General Public License
17 * as published by the Free Software Foundation, in version 3 of the
18 * License.
19 *
20 * This program is distributed in the hope that it will be useful, but
21 * WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
23 * General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see <https://www.gnu.org/licenses>.
27 *
28 * SPDX-License-Identifier: GPL-3.0-only
29 */
30
31
32/*********************************************************************************************************************************
33* Header Files *
34*********************************************************************************************************************************/
35#define LOG_GROUP LOG_GROUP_DEV_SERIAL /** @todo */
36#include <VBox/vmm/pdmdev.h>
37#include <iprt/assert.h>
38#include <iprt/uuid.h>
39#include <iprt/string.h>
40#include <iprt/semaphore.h>
41#include <iprt/critsect.h>
42
43#include "VBoxDD.h"
44
45
46/*********************************************************************************************************************************
47* Defined Constants And Macros *
48*********************************************************************************************************************************/
49
50/** The current serial code saved state version. */
51#define PL061_SAVED_STATE_VERSION 1
52
53/** PL061 MMIO region size in bytes. */
54#define PL061_MMIO_SIZE _4K
55
56/** The offset of the GPIODATA register from the beginning of the region. */
57#define PL061_REG_GPIODATA_INDEX 0x0
58
59/** The offset of the GPIOPeriphID0 register from the beginning of the region. */
60#define PL061_REG_GPIO_PERIPH_ID0_INDEX 0xfe0
61/** The offset of the GPIOPeriphID1 register from the beginning of the region. */
62#define PL061_REG_GPIO_PERIPH_ID1_INDEX 0xfe4
63/** The offset of the GPIOPeriphID2 register from the beginning of the region. */
64#define PL061_REG_GPIO_PERIPH_ID2_INDEX 0xfe8
65/** The offset of the GPIOPeriphID3 register from the beginning of the region. */
66#define PL061_REG_GPIO_PERIPH_ID3_INDEX 0xfec
67/** The offset of the GPIOPCellID0 register from the beginning of the region. */
68#define PL061_REG_GPIO_PCELL_ID0_INDEX 0xff0
69/** The offset of the GPIOPCellID1 register from the beginning of the region. */
70#define PL061_REG_GPIO_PCELL_ID1_INDEX 0xff4
71/** The offset of the GPIOPCellID2 register from the beginning of the region. */
72#define PL061_REG_GPIO_PCELL_ID2_INDEX 0xff8
73/** The offset of the GPIOPCellID3 register from the beginning of the region. */
74#define PL061_REG_GPIO_PCELL_ID3_INDEX 0xffc
75
76/** Set the specified bits in the given register. */
77#define PL061_REG_SET(a_Reg, a_Set) ((a_Reg) |= (a_Set))
78/** Clear the specified bits in the given register. */
79#define PL061_REG_CLR(a_Reg, a_Clr) ((a_Reg) &= ~(a_Clr))
80
81
82/*********************************************************************************************************************************
83* Structures and Typedefs *
84*********************************************************************************************************************************/
85
86/**
87 * Shared PL061 GPIO device state.
88 */
89typedef struct DEVPL061
90{
91 /** The MMIO handle. */
92 IOMMMIOHANDLE hMmio;
93 /** The base MMIO address the device is registered at. */
94 RTGCPHYS GCPhysMmioBase;
95 /** The IRQ value. */
96 uint16_t u16Irq;
97
98 /** @name Registers.
99 * @{ */
100 /** @todo */
101 /** @} */
102} DEVPL061;
103/** Pointer to the shared serial device state. */
104typedef DEVPL061 *PDEVPL061;
105
106
107/**
108 * PL061 device state for ring-3.
109 */
110typedef struct DEVPL061R3
111{
112 /** LUN\#0: The base interface. */
113 PDMIBASE IBase;
114 /** Pointer to the attached base driver. */
115 R3PTRTYPE(PPDMIBASE) pDrvBase;
116 /** Pointer to the device instance - only for getting our bearings in
117 * interface methods. */
118 PPDMDEVINS pDevIns;
119} DEVPL061R3;
120/** Pointer to the PL061 device state for ring-3. */
121typedef DEVPL061R3 *PDEVPL061R3;
122
123
124/**
125 * PL061 device state for ring-0.
126 */
127typedef struct DEVPL061R0
128{
129 /** Dummy .*/
130 uint8_t bDummy;
131} DEVPL061R0;
132/** Pointer to the PL061 device state for ring-0. */
133typedef DEVPL061R0 *PDEVPL061R0;
134
135
136/**
137 * PL061 device state for raw-mode.
138 */
139typedef struct DEVPL061RC
140{
141 /** Dummy .*/
142 uint8_t bDummy;
143} DEVPL061RC;
144/** Pointer to the serial device state for raw-mode. */
145typedef DEVPL061RC *PDEVPL061RC;
146
147/** The PL061 device state for the current context. */
148typedef CTX_SUFF(DEVPL061) DEVPL061CC;
149/** Pointer to the PL016 device state for the current context. */
150typedef CTX_SUFF(PDEVPL061) PDEVPL061CC;
151
152
153/*********************************************************************************************************************************
154* Internal Functions *
155*********************************************************************************************************************************/
156
157#ifndef VBOX_DEVICE_STRUCT_TESTCASE
158
159#if 0 /* unused */
160/**
161 * Updates the IRQ state based on the current device state.
162 *
163 * @param pDevIns The device instance.
164 * @param pThis The shared PL061 instance data.
165 * @param pThisCC The PL061 instance data for the current context.
166 */
167static void pl061IrqUpdate(PPDMDEVINS pDevIns, PDEVPL061 pThis, PDEVPL061CC pThisCC)
168{
169 LogFlowFunc(("pThis=%#p\n", pThis));
170 RT_NOREF(pDevIns, pThis, pThisCC);
171}
172#endif
173
174
175/* -=-=-=-=-=- MMIO callbacks -=-=-=-=-=- */
176
177
178/**
179 * @callback_method_impl{FNIOMMMIONEWREAD}
180 */
181static DECLCALLBACK(VBOXSTRICTRC) pl061MmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
182{
183 PDEVPL061 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL061);
184 RT_NOREF(pvUser);
185 Assert(cb == 4);
186 Assert(!(off & (cb - 1))); RT_NOREF(cb);
187
188 LogFlowFunc(("%RGp cb=%u\n", off, cb));
189
190 uint32_t u32Val = 0;
191 VBOXSTRICTRC rc = VINF_SUCCESS;
192 switch (off)
193 {
194 /** @todo */ RT_NOREF(pThis);
195 case PL061_REG_GPIO_PERIPH_ID0_INDEX:
196 u32Val = 0x61;
197 break;
198 case PL061_REG_GPIO_PERIPH_ID1_INDEX:
199 u32Val = 0x10;
200 break;
201 case PL061_REG_GPIO_PERIPH_ID2_INDEX:
202 u32Val = 0x04;
203 break;
204 case PL061_REG_GPIO_PERIPH_ID3_INDEX:
205 u32Val = 0x00;
206 break;
207 case PL061_REG_GPIO_PCELL_ID0_INDEX:
208 u32Val = 0x0d;
209 break;
210 case PL061_REG_GPIO_PCELL_ID1_INDEX:
211 u32Val = 0xf0;
212 break;
213 case PL061_REG_GPIO_PCELL_ID2_INDEX:
214 u32Val = 0x05;
215 break;
216 case PL061_REG_GPIO_PCELL_ID3_INDEX:
217 u32Val = 0xb1;
218 break;
219 default:
220 break;
221 }
222
223 if (rc == VINF_SUCCESS)
224 *(uint32_t *)pv = u32Val;
225
226 return rc;
227}
228
229
230/**
231 * @callback_method_impl{FNIOMMMIONEWWRITE}
232 */
233static DECLCALLBACK(VBOXSTRICTRC) pl061MmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb)
234{
235 PDEVPL061 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL061);
236 PDEVPL061CC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVPL061CC);
237 LogFlowFunc(("cb=%u reg=%RGp val=%llx\n", cb, off, cb == 4 ? *(uint32_t *)pv : cb == 8 ? *(uint64_t *)pv : 0xdeadbeef));
238 RT_NOREF(pvUser);
239 Assert(cb == 4 || cb == 8);
240 Assert(!(off & (cb - 1)));
241
242 VBOXSTRICTRC rcStrict = VINF_SUCCESS;
243 uint32_t u32Val = *(uint32_t *)pv;
244 switch (off)
245 {
246 /** @todo */ RT_NOREF(pThis, pThisCC, u32Val, cb);
247 default:
248 break;
249
250 }
251 return rcStrict;
252}
253
254
255#ifdef IN_RING3
256
257/* -=-=-=-=-=-=-=-=- PDMIBASE -=-=-=-=-=-=-=-=- */
258
259/**
260 * @interface_method_impl{PDMIBASE,pfnQueryInterface}
261 */
262static DECLCALLBACK(void *) pl061R3QueryInterface(PPDMIBASE pInterface, const char *pszIID)
263{
264 PDEVPL061CC pThisCC = RT_FROM_MEMBER(pInterface, DEVPL061CC, IBase);
265 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThisCC->IBase);
266 return NULL;
267}
268
269
270/* -=-=-=-=-=-=-=-=- Saved State -=-=-=-=-=-=-=-=- */
271
272/**
273 * @callback_method_impl{FNSSMDEVLIVEEXEC}
274 */
275static DECLCALLBACK(int) pl061R3LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
276{
277 PDEVPL061 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL061);
278 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
279 RT_NOREF(uPass);
280
281 pHlp->pfnSSMPutU16(pSSM, pThis->u16Irq);
282 pHlp->pfnSSMPutGCPhys(pSSM, pThis->GCPhysMmioBase);
283 return VINF_SSM_DONT_CALL_AGAIN;
284}
285
286
287/**
288 * @callback_method_impl{FNSSMDEVSAVEEXEC}
289 */
290static DECLCALLBACK(int) pl061R3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
291{
292 PDEVPL061 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL061);
293 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
294
295 pHlp->pfnSSMPutU16(pSSM, pThis->u16Irq);
296 pHlp->pfnSSMPutGCPhys(pSSM, pThis->GCPhysMmioBase);
297
298 return pHlp->pfnSSMPutU32(pSSM, UINT32_MAX); /* sanity/terminator */
299}
300
301
302/**
303 * @callback_method_impl{FNSSMDEVLOADEXEC}
304 */
305static DECLCALLBACK(int) pl061R3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
306{
307 PDEVPL061 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL061);
308 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
309 uint16_t u16Irq;
310 RTGCPHYS GCPhysMmioBase;
311 int rc;
312
313 RT_NOREF(uVersion);
314
315 pHlp->pfnSSMGetU16( pSSM, &u16Irq);
316 pHlp->pfnSSMGetGCPhys(pSSM, &GCPhysMmioBase);
317 if (uPass == SSM_PASS_FINAL)
318 {
319 rc = VINF_SUCCESS;
320 AssertRCReturn(rc, rc);
321 }
322
323 if (uPass == SSM_PASS_FINAL)
324 {
325 /* The marker. */
326 uint32_t u32;
327 rc = pHlp->pfnSSMGetU32(pSSM, &u32);
328 AssertRCReturn(rc, rc);
329 AssertMsgReturn(u32 == UINT32_MAX, ("%#x\n", u32), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
330 }
331
332 /*
333 * Check the config.
334 */
335 if ( pThis->u16Irq != u16Irq
336 || pThis->GCPhysMmioBase != GCPhysMmioBase)
337 return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS,
338 N_("Config mismatch - saved Irq=%#x GCPhysMmioBase=%#RGp; configured Irq=%#x GCPhysMmioBase=%#RGp"),
339 u16Irq, GCPhysMmioBase, pThis->u16Irq, pThis->GCPhysMmioBase);
340
341 return VINF_SUCCESS;
342}
343
344
345/**
346 * @callback_method_impl{FNSSMDEVLOADDONE}
347 */
348static DECLCALLBACK(int) pl061R3LoadDone(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
349{
350 PDEVPL061 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL061);
351 PDEVPL061CC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVPL061CC);
352
353 RT_NOREF(pThis, pThisCC, pSSM);
354 return VINF_SUCCESS;
355}
356
357
358/* -=-=-=-=-=-=-=-=- PDMDEVREG -=-=-=-=-=-=-=-=- */
359
360/**
361 * @interface_method_impl{PDMDEVREG,pfnReset}
362 */
363static DECLCALLBACK(void) pl061R3Reset(PPDMDEVINS pDevIns)
364{
365 PDEVPL061 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL061);
366 PDEVPL061CC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVPL061CC);
367
368 /** @todo */
369 RT_NOREF(pThis, pThisCC);
370}
371
372
373/**
374 * @interface_method_impl{PDMDEVREG,pfnAttach}
375 */
376static DECLCALLBACK(int) pl061R3Attach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
377{
378 PDEVPL061 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL061);
379 PDEVPL061CC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVPL061CC);
380 RT_NOREF(fFlags);
381 AssertReturn(iLUN == 0, VERR_PDM_LUN_NOT_FOUND);
382
383 int rc = PDMDevHlpDriverAttach(pDevIns, iLUN, &pThisCC->IBase, &pThisCC->pDrvBase, "PL016 Gpio");
384 if (RT_SUCCESS(rc))
385 {
386 /** @todo */ RT_NOREF(pThis);
387 }
388 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
389 {
390 pThisCC->pDrvBase = NULL;
391 LogRel(("PL061#%d: no unit\n", pDevIns->iInstance));
392 }
393 else /* Don't call VMSetError here as we assume that the driver already set an appropriate error */
394 LogRel(("PL061#%d: Failed to attach to GPIO driver. rc=%Rrc\n", pDevIns->iInstance, rc));
395
396 return rc;
397}
398
399
400/**
401 * @interface_method_impl{PDMDEVREG,pfnDetach}
402 */
403static DECLCALLBACK(void) pl061R3Detach(PPDMDEVINS pDevIns, unsigned iLUN, uint32_t fFlags)
404{
405 PDEVPL061 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL061);
406 PDEVPL061CC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVPL061CC);
407 RT_NOREF(fFlags);
408 AssertReturnVoid(iLUN == 0);
409
410 /* Zero out important members. */
411 pThisCC->pDrvBase = NULL;
412 /** @todo */ RT_NOREF(pThis);
413}
414
415
416/**
417 * @interface_method_impl{PDMDEVREG,pfnDestruct}
418 */
419static DECLCALLBACK(int) pl061R3Destruct(PPDMDEVINS pDevIns)
420{
421 PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
422
423 /* Nothing to do (for now). */
424 return VINF_SUCCESS;
425}
426
427
428/**
429 * @interface_method_impl{PDMDEVREG,pfnConstruct}
430 */
431static DECLCALLBACK(int) pl061R3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
432{
433 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
434 PDEVPL061 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL061);
435 PDEVPL061CC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVPL061CC);
436 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
437 int rc;
438
439 Assert(iInstance < 4);
440
441 pThisCC->pDevIns = pDevIns;
442
443 /* IBase */
444 pThisCC->IBase.pfnQueryInterface = pl061R3QueryInterface;
445
446 /** @todo Interface. */
447
448 /*
449 * Validate and read the configuration.
450 */
451 PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "Irq|MmioBase", "");
452
453 uint16_t u16Irq = 0;
454 rc = pHlp->pfnCFGMQueryU16(pCfg, "Irq", &u16Irq);
455 if (RT_FAILURE(rc))
456 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to get the \"Irq\" value"));
457
458 RTGCPHYS GCPhysMmioBase = 0;
459 rc = pHlp->pfnCFGMQueryU64(pCfg, "MmioBase", &GCPhysMmioBase);
460 if (RT_FAILURE(rc))
461 return PDMDEV_SET_ERROR(pDevIns, rc,
462 N_("Configuration error: Failed to get the \"IOBase\" value"));
463
464 pThis->u16Irq = u16Irq;
465 pThis->GCPhysMmioBase = GCPhysMmioBase;
466
467 /*
468 * Register and map the MMIO region.
469 */
470 rc = PDMDevHlpMmioCreateAndMap(pDevIns, GCPhysMmioBase, PL061_MMIO_SIZE, pl061MmioWrite, pl061MmioRead,
471 IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_DWORD_ZEROED, "PL061", &pThis->hMmio);
472 AssertRCReturn(rc, rc);
473
474
475 /*
476 * Saved state.
477 */
478 rc = PDMDevHlpSSMRegisterEx(pDevIns, PL061_SAVED_STATE_VERSION, sizeof(*pThis), NULL,
479 NULL, pl061R3LiveExec, NULL,
480 NULL, pl061R3SaveExec, NULL,
481 NULL, pl061R3LoadExec, pl061R3LoadDone);
482 AssertRCReturn(rc, rc);
483
484 /*
485 * Attach the GPIO driver and get the interfaces.
486 */
487 rc = PDMDevHlpDriverAttach(pDevIns, 0 /*iLUN*/, &pThisCC->IBase, &pThisCC->pDrvBase, "GPIO");
488 if (RT_SUCCESS(rc))
489 {
490 /** @todo */
491 }
492 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
493 {
494 pThisCC->pDrvBase = NULL;
495 LogRel(("PL061#%d: no unit\n", iInstance));
496 }
497 else
498 {
499 AssertLogRelMsgFailed(("PL061#%d: Failed to attach to gpio driver. rc=%Rrc\n", iInstance, rc));
500 /* Don't call VMSetError here as we assume that the driver already set an appropriate error */
501 return rc;
502 }
503
504 pl061R3Reset(pDevIns);
505 return VINF_SUCCESS;
506}
507
508#else /* !IN_RING3 */
509
510/**
511 * @callback_method_impl{PDMDEVREGR0,pfnConstruct}
512 */
513static DECLCALLBACK(int) pl061RZConstruct(PPDMDEVINS pDevIns)
514{
515 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
516 PDEVPL061 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL061);
517 PDEVPL061CC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVPL061CC);
518
519 int rc = PDMDevHlpMmioSetUpContext(pDevIns, pThis->hMmio, pl061MmioWrite, pl061MmioRead, NULL /*pvUser*/);
520 AssertRCReturn(rc, rc);
521
522 return VINF_SUCCESS;
523}
524
525#endif /* !IN_RING3 */
526
527/**
528 * The device registration structure.
529 */
530const PDMDEVREG g_DevicePl061Gpio =
531{
532 /* .u32Version = */ PDM_DEVREG_VERSION,
533 /* .uReserved0 = */ 0,
534 /* .szName = */ "arm-pl061-gpio",
535 /* .fFlags = */ PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RZ | PDM_DEVREG_FLAGS_NEW_STYLE,
536 /* .fClass = */ PDM_DEVREG_CLASS_SERIAL, /** @todo */
537 /* .cMaxInstances = */ UINT32_MAX,
538 /* .uSharedVersion = */ 42,
539 /* .cbInstanceShared = */ sizeof(DEVPL061),
540 /* .cbInstanceCC = */ sizeof(DEVPL061CC),
541 /* .cbInstanceRC = */ sizeof(DEVPL061RC),
542 /* .cMaxPciDevices = */ 0,
543 /* .cMaxMsixVectors = */ 0,
544 /* .pszDescription = */ "ARM PL061 PrimeCell GPIO",
545#if defined(IN_RING3)
546 /* .pszRCMod = */ "VBoxDDRC.rc",
547 /* .pszR0Mod = */ "VBoxDDR0.r0",
548 /* .pfnConstruct = */ pl061R3Construct,
549 /* .pfnDestruct = */ pl061R3Destruct,
550 /* .pfnRelocate = */ NULL,
551 /* .pfnMemSetup = */ NULL,
552 /* .pfnPowerOn = */ NULL,
553 /* .pfnReset = */ pl061R3Reset,
554 /* .pfnSuspend = */ NULL,
555 /* .pfnResume = */ NULL,
556 /* .pfnAttach = */ pl061R3Attach,
557 /* .pfnDetach = */ pl061R3Detach,
558 /* .pfnQueryInterface = */ NULL,
559 /* .pfnInitComplete = */ NULL,
560 /* .pfnPowerOff = */ NULL,
561 /* .pfnSoftReset = */ NULL,
562 /* .pfnReserved0 = */ NULL,
563 /* .pfnReserved1 = */ NULL,
564 /* .pfnReserved2 = */ NULL,
565 /* .pfnReserved3 = */ NULL,
566 /* .pfnReserved4 = */ NULL,
567 /* .pfnReserved5 = */ NULL,
568 /* .pfnReserved6 = */ NULL,
569 /* .pfnReserved7 = */ NULL,
570#elif defined(IN_RING0)
571 /* .pfnEarlyConstruct = */ NULL,
572 /* .pfnConstruct = */ pl061RZConstruct,
573 /* .pfnDestruct = */ NULL,
574 /* .pfnFinalDestruct = */ NULL,
575 /* .pfnRequest = */ NULL,
576 /* .pfnReserved0 = */ NULL,
577 /* .pfnReserved1 = */ NULL,
578 /* .pfnReserved2 = */ NULL,
579 /* .pfnReserved3 = */ NULL,
580 /* .pfnReserved4 = */ NULL,
581 /* .pfnReserved5 = */ NULL,
582 /* .pfnReserved6 = */ NULL,
583 /* .pfnReserved7 = */ NULL,
584#elif defined(IN_RC)
585 /* .pfnConstruct = */ pl061RZConstruct,
586 /* .pfnReserved0 = */ NULL,
587 /* .pfnReserved1 = */ NULL,
588 /* .pfnReserved2 = */ NULL,
589 /* .pfnReserved3 = */ NULL,
590 /* .pfnReserved4 = */ NULL,
591 /* .pfnReserved5 = */ NULL,
592 /* .pfnReserved6 = */ NULL,
593 /* .pfnReserved7 = */ NULL,
594#else
595# error "Not in IN_RING3, IN_RING0 or IN_RC!"
596#endif
597 /* .u32VersionEnd = */ PDM_DEVREG_VERSION
598};
599
600#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
601
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use