VirtualBox

source: vbox/trunk/src/VBox/Devices/Misc/DevPL031.cpp@ 99844

Last change on this file since 99844 was 99739, checked in by vboxsync, 19 months ago

*: doxygen corrections (mostly about removing @returns from functions returning void).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 21.2 KB
Line 
1/* $Id: DevPL031.cpp 99739 2023-05-11 01:01:08Z vboxsync $ */
2/** @file
3 * DevPL031 - ARM PL011 PrimeCell RTC.
4 *
5 * The documentation for this device was taken from
6 * https://developer.arm.com/documentation/ddi0224/c (2023-04-27).
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_RTC
36#include <VBox/vmm/pdmdev.h>
37#include <VBox/vmm/pdmifs.h>
38#include <iprt/assert.h>
39#include <iprt/uuid.h>
40#include <iprt/string.h>
41#include <iprt/semaphore.h>
42#include <iprt/critsect.h>
43
44#include "VBoxDD.h"
45
46
47/*********************************************************************************************************************************
48* Defined Constants And Macros *
49*********************************************************************************************************************************/
50
51/** The current serial code saved state version. */
52#define PL031_SAVED_STATE_VERSION 1
53
54/** PL011 MMIO region size in bytes. */
55#define PL031_MMIO_SIZE _4K
56
57/** The offset of the RTCDR register from the beginning of the region. */
58#define PL031_REG_RTCDR_INDEX 0x0
59/** The offset of the RTCMR register from the beginning of the region. */
60#define PL031_REG_RTCMR_INDEX 0x4
61/** The offset of the RTCLR register from the beginning of the region. */
62#define PL031_REG_RTCLR_INDEX 0x8
63
64/** The offset of the RTCCR register from the beginning of the region. */
65#define PL031_REG_RTCCR_INDEX 0xc
66/** RTC start bit. */
67# define PL031_REG_RTCCR_RTC_START RT_BIT(0)
68
69/** The offset of the RTCIMSC register from the beginning of the region. */
70#define PL031_REG_RTCIMSC_INDEX 0x10
71/** Interrupt mask bit. */
72# define PL031_REG_RTCIMSC_MASK RT_BIT(0)
73
74/** The offset of the RTCRIS register from the beginning of the region. */
75#define PL031_REG_RTCRIS_INDEX 0x14
76/** Raw interrupt status bit. */
77# define PL031_REG_RTCRIS_STS RT_BIT(0)
78
79/** The offset of the RTCMIS register from the beginning of the region. */
80#define PL031_REG_RTCMIS_INDEX 0x18
81/** Masked interrupt status bit. */
82# define PL031_REG_RTCMIS_STS RT_BIT(0)
83
84/** The offset of the RTCICR register from the beginning of the region. */
85#define PL031_REG_RTCICR_INDEX 0x1c
86/** Interrupt clear bit. */
87# define PL031_REG_RTCICR_CLR RT_BIT(0)
88
89/** The offset of the UARTPeriphID0 register from the beginning of the region. */
90#define PL031_REG_RTC_PERIPH_ID0_INDEX 0xfe0
91/** The offset of the UARTPeriphID1 register from the beginning of the region. */
92#define PL031_REG_RTC_PERIPH_ID1_INDEX 0xfe4
93/** The offset of the UARTPeriphID2 register from the beginning of the region. */
94#define PL031_REG_RTC_PERIPH_ID2_INDEX 0xfe8
95/** The offset of the UARTPeriphID3 register from the beginning of the region. */
96#define PL031_REG_RTC_PERIPH_ID3_INDEX 0xfec
97/** The offset of the UARTPCellID0 register from the beginning of the region. */
98#define PL031_REG_RTC_PCELL_ID0_INDEX 0xff0
99/** The offset of the UARTPCellID1 register from the beginning of the region. */
100#define PL031_REG_RTC_PCELL_ID1_INDEX 0xff4
101/** The offset of the UARTPCellID2 register from the beginning of the region. */
102#define PL031_REG_RTC_PCELL_ID2_INDEX 0xff8
103/** The offset of the UARTPCellID3 register from the beginning of the region. */
104#define PL031_REG_RTC_PCELL_ID3_INDEX 0xffc
105
106
107/*********************************************************************************************************************************
108* Structures and Typedefs *
109*********************************************************************************************************************************/
110
111/**
112 * Shared RTC device state.
113 */
114typedef struct DEVPL031
115{
116 /** The MMIO handle. */
117 IOMMMIOHANDLE hMmio;
118 /** The second timer (pl031TimerSecond). */
119 TMTIMERHANDLE hTimerSecond;
120 /** The base MMIO address the device is registered at. */
121 RTGCPHYS GCPhysMmioBase;
122 /** The IRQ value. */
123 uint16_t u16Irq;
124
125 /** @name Registers.
126 * @{ */
127 /** Data register. */
128 uint32_t u32RtcDr;
129 /** Match register. */
130 uint32_t u32RtcMr;
131 /** Load register. */
132 uint32_t u32RtcLr;
133 /** RTC start bit from the control register. */
134 bool fRtcStarted;
135 /** RTC interrupt masked status. */
136 bool fRtcIrqMasked;
137 /** RTC raw interrupt status. */
138 bool fRtcIrqSts;
139 /** @} */
140
141} DEVPL031;
142/** Pointer to the shared RTC device state. */
143typedef DEVPL031 *PDEVPL031;
144
145
146/**
147 * Serial device state for ring-3.
148 */
149typedef struct DEVPL031R3
150{
151 uint32_t u32Dummy;
152} DEVPL031R3;
153/** Pointer to the serial device state for ring-3. */
154typedef DEVPL031R3 *PDEVPL031R3;
155
156
157/**
158 * Serial device state for ring-0.
159 */
160typedef struct DEVPL031R0
161{
162 /** Dummy .*/
163 uint8_t bDummy;
164} DEVPL031R0;
165/** Pointer to the serial device state for ring-0. */
166typedef DEVPL031R0 *PDEVPL031R0;
167
168
169/**
170 * Serial device state for raw-mode.
171 */
172typedef struct DEVPL031RC
173{
174 /** Dummy .*/
175 uint8_t bDummy;
176} DEVPL031RC;
177/** Pointer to the serial device state for raw-mode. */
178typedef DEVPL031RC *PDEVPL031RC;
179
180/** The serial device state for the current context. */
181typedef CTX_SUFF(DEVPL031) DEVPL031CC;
182/** Pointer to the serial device state for the current context. */
183typedef CTX_SUFF(PDEVPL031) PDEVPL031CC;
184
185
186/*********************************************************************************************************************************
187* Internal Functions *
188*********************************************************************************************************************************/
189
190#ifndef VBOX_DEVICE_STRUCT_TESTCASE
191
192/**
193 * Updates the IRQ state based on the current device state.
194 *
195 * @param pDevIns The device instance.
196 * @param pThis The shared RTC instance data.
197 */
198DECLINLINE(void) pl031IrqUpdate(PPDMDEVINS pDevIns, PDEVPL031 pThis)
199{
200 LogFlowFunc(("pThis=%#p\n", pThis));
201 if (pThis->fRtcIrqSts && !pThis->fRtcIrqMasked) /** @todo ISA is x86 specific. */
202 PDMDevHlpISASetIrqNoWait(pDevIns, pThis->u16Irq, 1);
203 else
204 PDMDevHlpISASetIrqNoWait(pDevIns, pThis->u16Irq, 0);
205}
206
207
208/**
209 * @callback_method_impl{FNTMTIMERDEV, Second timer.}
210 */
211static DECLCALLBACK(void) pl031TimerSecond(PPDMDEVINS pDevIns, TMTIMERHANDLE hTimer, void *pvUser)
212{
213 PDEVPL031 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL031);
214
215 Assert(PDMDevHlpTimerIsLockOwner(pDevIns, hTimer));
216 Assert(PDMDevHlpCritSectIsOwner(pDevIns, pDevIns->CTX_SUFF(pCritSectRo)));
217 RT_NOREF(pvUser, hTimer);
218
219 if (pThis->fRtcStarted)
220 {
221 pThis->u32RtcDr++;
222 if (pThis->u32RtcDr + pThis->u32RtcLr == pThis->u32RtcMr)
223 {
224 /* Set interrupt. */
225 pThis->fRtcIrqSts = true;
226 pl031IrqUpdate(pDevIns, pThis);
227 }
228
229 PDMDevHlpTimerSetMillies(pDevIns, hTimer, RT_MS_1SEC);
230 }
231}
232
233
234/* -=-=-=-=-=- MMIO callbacks -=-=-=-=-=- */
235
236
237/**
238 * @callback_method_impl{FNIOMMMIONEWREAD}
239 */
240static DECLCALLBACK(VBOXSTRICTRC) pl031MmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, unsigned cb)
241{
242 PDEVPL031 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL031);
243 NOREF(pvUser);
244 Assert(cb == 4 || cb == 8);
245 Assert(!(off & (cb - 1)));
246
247 LogFlowFunc(("%RGp cb=%u\n", off, cb));
248
249 uint32_t u32Val = 0;
250 VBOXSTRICTRC rc = VINF_SUCCESS;
251 switch (off)
252 {
253 case PL031_REG_RTCDR_INDEX:
254 u32Val = pThis->u32RtcDr + pThis->u32RtcLr;
255 break;
256 case PL031_REG_RTCMR_INDEX:
257 u32Val = pThis->u32RtcMr;
258 break;
259 case PL031_REG_RTCLR_INDEX:
260 u32Val = pThis->u32RtcLr;
261 break;
262 case PL031_REG_RTCCR_INDEX:
263 u32Val = pThis->fRtcStarted ? PL031_REG_RTCCR_RTC_START : 0;
264 break;
265 case PL031_REG_RTCIMSC_INDEX:
266 u32Val = pThis->fRtcIrqMasked ? PL031_REG_RTCIMSC_MASK : 0;
267 break;
268 case PL031_REG_RTCRIS_INDEX:
269 u32Val = pThis->fRtcIrqSts ? PL031_REG_RTCRIS_STS : 0;
270 break;
271 case PL031_REG_RTCMIS_INDEX:
272 u32Val = (pThis->fRtcIrqSts && !pThis->fRtcIrqMasked) ? PL031_REG_RTCMIS_STS : 0;
273 break;
274 case PL031_REG_RTC_PERIPH_ID0_INDEX:
275 u32Val = 0x31;
276 break;
277 case PL031_REG_RTC_PERIPH_ID1_INDEX:
278 u32Val = 0x10;
279 break;
280 case PL031_REG_RTC_PERIPH_ID2_INDEX:
281 u32Val = 0x04;
282 break;
283 case PL031_REG_RTC_PERIPH_ID3_INDEX:
284 u32Val = 0x00;
285 break;
286 case PL031_REG_RTC_PCELL_ID0_INDEX:
287 u32Val = 0x0d;
288 break;
289 case PL031_REG_RTC_PCELL_ID1_INDEX:
290 u32Val = 0xf0;
291 break;
292 case PL031_REG_RTC_PCELL_ID2_INDEX:
293 u32Val = 0x05;
294 break;
295 case PL031_REG_RTC_PCELL_ID3_INDEX:
296 u32Val = 0xb1;
297 break;
298 case PL031_REG_RTCICR_INDEX: /* Writeonly */
299 default:
300 break;
301 }
302
303 if (rc == VINF_SUCCESS)
304 *(uint32_t *)pv = u32Val;
305
306 return rc;
307}
308
309
310/**
311 * @callback_method_impl{FNIOMMMIONEWWRITE}
312 */
313static DECLCALLBACK(VBOXSTRICTRC) pl031MmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, unsigned cb)
314{
315 PDEVPL031 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL031);
316 LogFlowFunc(("cb=%u reg=%RGp val=%llx\n", cb, off, cb == 4 ? *(uint32_t *)pv : cb == 8 ? *(uint64_t *)pv : 0xdeadbeef));
317 RT_NOREF(pvUser);
318 Assert(cb == 4 || cb == 8);
319 Assert(!(off & (cb - 1)));
320
321 VBOXSTRICTRC rcStrict = VINF_SUCCESS;
322 uint32_t u32Val = *(uint32_t *)pv;
323 switch (off)
324 {
325 case PL031_REG_RTCMR_INDEX:
326 pThis->u32RtcMr = u32Val;
327 break;
328 case PL031_REG_RTCLR_INDEX:
329 pThis->u32RtcLr = u32Val;
330 break;
331 case PL031_REG_RTCCR_INDEX:
332 {
333 /* Writing this resets the data register in any case. */
334 pThis->u32RtcDr = 0;
335 bool fRtcStart = RT_BOOL(u32Val & PL031_REG_RTCCR_RTC_START);
336 if (fRtcStart ^ pThis->fRtcStarted)
337 {
338 pThis->fRtcStarted = fRtcStart;
339 if (fRtcStart)
340 {
341 PDMDevHlpTimerLockClock(pDevIns, pThis->hTimerSecond, VERR_IGNORED);
342 rcStrict = PDMDevHlpTimerSet(pDevIns, pThis->hTimerSecond, RT_MS_1SEC);
343 PDMDevHlpTimerUnlockClock(pDevIns, pThis->hTimerSecond);
344 }
345 else
346 PDMDevHlpTimerStop(pDevIns, pThis->hTimerSecond);
347 }
348 break;
349 }
350 case PL031_REG_RTCIMSC_INDEX:
351 pThis->fRtcIrqMasked = RT_BOOL(u32Val & PL031_REG_RTCIMSC_MASK);
352 pl031IrqUpdate(pDevIns, pThis);
353 break;
354 case PL031_REG_RTCDR_INDEX: /* Readonly */
355 case PL031_REG_RTCMIS_INDEX:
356 case PL031_REG_RTCRIS_INDEX:
357 default:
358 break;
359 }
360 return rcStrict;
361}
362
363
364#ifdef IN_RING3
365
366/* -=-=-=-=-=-=-=-=- Saved State -=-=-=-=-=-=-=-=- */
367
368/**
369 * @callback_method_impl{FNSSMDEVLIVEEXEC}
370 */
371static DECLCALLBACK(int) pl031R3LiveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uPass)
372{
373 PDEVPL031 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL031);
374 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
375 RT_NOREF(uPass);
376
377 pHlp->pfnSSMPutU16(pSSM, pThis->u16Irq);
378 pHlp->pfnSSMPutGCPhys(pSSM, pThis->GCPhysMmioBase);
379 return VINF_SSM_DONT_CALL_AGAIN;
380}
381
382
383/**
384 * @callback_method_impl{FNSSMDEVSAVEEXEC}
385 */
386static DECLCALLBACK(int) pl031R3SaveExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
387{
388 PDEVPL031 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL031);
389 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
390
391 pHlp->pfnSSMPutU16(pSSM, pThis->u16Irq);
392 pHlp->pfnSSMPutGCPhys(pSSM, pThis->GCPhysMmioBase);
393
394 return pHlp->pfnSSMPutU32(pSSM, UINT32_MAX); /* sanity/terminator */
395}
396
397
398/**
399 * @callback_method_impl{FNSSMDEVLOADEXEC}
400 */
401static DECLCALLBACK(int) pl031R3LoadExec(PPDMDEVINS pDevIns, PSSMHANDLE pSSM, uint32_t uVersion, uint32_t uPass)
402{
403 PDEVPL031 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL031);
404 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
405 uint16_t u16Irq;
406 RTGCPHYS GCPhysMmioBase;
407 int rc;
408
409 RT_NOREF(uVersion);
410
411 pHlp->pfnSSMGetU16( pSSM, &u16Irq);
412 pHlp->pfnSSMGetGCPhys(pSSM, &GCPhysMmioBase);
413 if (uPass == SSM_PASS_FINAL)
414 {
415 rc = VERR_NOT_IMPLEMENTED;
416 AssertRCReturn(rc, rc);
417 }
418
419 if (uPass == SSM_PASS_FINAL)
420 {
421 /* The marker. */
422 uint32_t u32;
423 rc = pHlp->pfnSSMGetU32(pSSM, &u32);
424 AssertRCReturn(rc, rc);
425 AssertMsgReturn(u32 == UINT32_MAX, ("%#x\n", u32), VERR_SSM_DATA_UNIT_FORMAT_CHANGED);
426 }
427
428 /*
429 * Check the config.
430 */
431 if ( pThis->u16Irq != u16Irq
432 || pThis->GCPhysMmioBase != GCPhysMmioBase)
433 return pHlp->pfnSSMSetCfgError(pSSM, RT_SRC_POS,
434 N_("Config mismatch - saved Irq=%#x GCPhysMmioBase=%#RGp; configured Irq=%#x GCPhysMmioBase=%#RGp"),
435 u16Irq, GCPhysMmioBase, pThis->u16Irq, pThis->GCPhysMmioBase);
436
437 return VINF_SUCCESS;
438}
439
440
441/**
442 * @callback_method_impl{FNSSMDEVLOADDONE}
443 */
444static DECLCALLBACK(int) pl031R3LoadDone(PPDMDEVINS pDevIns, PSSMHANDLE pSSM)
445{
446 PDEVPL031 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL031);
447 PDEVPL031CC pThisCC = PDMDEVINS_2_DATA_CC(pDevIns, PDEVPL031CC);
448
449 RT_NOREF(pThis, pThisCC, pSSM);
450 return VERR_NOT_IMPLEMENTED;
451}
452
453
454/* -=-=-=-=-=-=-=-=- PDMDEVREG -=-=-=-=-=-=-=-=- */
455
456/**
457 * @interface_method_impl{PDMDEVREG,pfnReset}
458 */
459static DECLCALLBACK(void) pl031R3Reset(PPDMDEVINS pDevIns)
460{
461 PDEVPL031 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL031);
462
463 pThis->u32RtcDr = 0;
464 pThis->u32RtcMr = 0;
465 pThis->u32RtcLr = 0;
466 pThis->fRtcStarted = false;
467 pThis->fRtcIrqMasked = false;
468 pThis->fRtcIrqSts = false;
469}
470
471
472/**
473 * @interface_method_impl{PDMDEVREG,pfnDestruct}
474 */
475static DECLCALLBACK(int) pl031R3Destruct(PPDMDEVINS pDevIns)
476{
477 PDMDEV_CHECK_VERSIONS_RETURN_QUIET(pDevIns);
478
479 /* Nothing to do. */
480 return VINF_SUCCESS;
481}
482
483
484/**
485 * @interface_method_impl{PDMDEVREG,pfnConstruct}
486 */
487static DECLCALLBACK(int) pl031R3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
488{
489 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
490 PDEVPL031 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL031);
491 PCPDMDEVHLPR3 pHlp = pDevIns->pHlpR3;
492 int rc;
493
494 Assert(iInstance < 4);
495
496 /*
497 * Validate and read the configuration.
498 */
499 PDMDEV_VALIDATE_CONFIG_RETURN(pDevIns, "Irq|MmioBase", "");
500
501 uint16_t u16Irq = 0;
502 rc = pHlp->pfnCFGMQueryU16(pCfg, "Irq", &u16Irq);
503 if (RT_FAILURE(rc))
504 return PDMDEV_SET_ERROR(pDevIns, rc, N_("Configuration error: Failed to get the \"Irq\" value"));
505
506 RTGCPHYS GCPhysMmioBase = 0;
507 rc = pHlp->pfnCFGMQueryU64(pCfg, "MmioBase", &GCPhysMmioBase);
508 if (RT_FAILURE(rc))
509 return PDMDEV_SET_ERROR(pDevIns, rc,
510 N_("Configuration error: Failed to get the \"MmioBase\" value"));
511
512 pThis->u16Irq = u16Irq;
513 pThis->GCPhysMmioBase = GCPhysMmioBase;
514
515 /*
516 * Register and map the MMIO region.
517 */
518 rc = PDMDevHlpMmioCreateAndMap(pDevIns, GCPhysMmioBase, PL031_MMIO_SIZE, pl031MmioWrite, pl031MmioRead,
519 IOMMMIO_FLAGS_READ_DWORD | IOMMMIO_FLAGS_WRITE_DWORD_ZEROED, "PL031-RTC", &pThis->hMmio);
520 AssertRCReturn(rc, rc);
521
522 /* Seconds timer. */
523 rc = PDMDevHlpTimerCreate(pDevIns, TMCLOCK_VIRTUAL_SYNC, pl031TimerSecond, pThis,
524 TMTIMER_FLAGS_DEFAULT_CRIT_SECT | TMTIMER_FLAGS_RING0,
525 "PL031 RTC Second", &pThis->hTimerSecond);
526 AssertRCReturn(rc, rc);
527
528 /*
529 * Saved state.
530 */
531 rc = PDMDevHlpSSMRegisterEx(pDevIns, PL031_SAVED_STATE_VERSION, sizeof(*pThis), NULL,
532 NULL, pl031R3LiveExec, NULL,
533 NULL, pl031R3SaveExec, NULL,
534 NULL, pl031R3LoadExec, pl031R3LoadDone);
535 AssertRCReturn(rc, rc);
536
537 pl031R3Reset(pDevIns);
538 return VINF_SUCCESS;
539}
540
541#else /* !IN_RING3 */
542
543/**
544 * @callback_method_impl{PDMDEVREGR0,pfnConstruct}
545 */
546static DECLCALLBACK(int) pl031RZConstruct(PPDMDEVINS pDevIns)
547{
548 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
549 PDEVPL031 pThis = PDMDEVINS_2_DATA(pDevIns, PDEVPL031);
550
551 int rc = PDMDevHlpMmioSetUpContext(pDevIns, pThis->hMmio, pl031MmioWrite, pl031MmioRead, NULL /*pvUser*/);
552 AssertRCReturn(rc, rc);
553
554 return VINF_SUCCESS;
555}
556
557#endif /* !IN_RING3 */
558
559/**
560 * The device registration structure.
561 */
562const PDMDEVREG g_DevicePl031Rtc =
563{
564 /* .u32Version = */ PDM_DEVREG_VERSION,
565 /* .uReserved0 = */ 0,
566 /* .szName = */ "arm-pl031-rtc",
567 /* .fFlags = */ PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_RZ | PDM_DEVREG_FLAGS_NEW_STYLE,
568 /* .fClass = */ PDM_DEVREG_CLASS_RTC,
569 /* .cMaxInstances = */ UINT32_MAX,
570 /* .uSharedVersion = */ 42,
571 /* .cbInstanceShared = */ sizeof(DEVPL031),
572 /* .cbInstanceCC = */ sizeof(DEVPL031CC),
573 /* .cbInstanceRC = */ sizeof(DEVPL031RC),
574 /* .cMaxPciDevices = */ 0,
575 /* .cMaxMsixVectors = */ 0,
576 /* .pszDescription = */ "ARM PL031 PrimeCell RTC",
577#if defined(IN_RING3)
578 /* .pszRCMod = */ "VBoxDDRC.rc",
579 /* .pszR0Mod = */ "VBoxDDR0.r0",
580 /* .pfnConstruct = */ pl031R3Construct,
581 /* .pfnDestruct = */ pl031R3Destruct,
582 /* .pfnRelocate = */ NULL,
583 /* .pfnMemSetup = */ NULL,
584 /* .pfnPowerOn = */ NULL,
585 /* .pfnReset = */ pl031R3Reset,
586 /* .pfnSuspend = */ NULL,
587 /* .pfnResume = */ NULL,
588 /* .pfnAttach = */ NULL,
589 /* .pfnDetach = */ NULL,
590 /* .pfnQueryInterface = */ NULL,
591 /* .pfnInitComplete = */ NULL,
592 /* .pfnPowerOff = */ NULL,
593 /* .pfnSoftReset = */ NULL,
594 /* .pfnReserved0 = */ NULL,
595 /* .pfnReserved1 = */ NULL,
596 /* .pfnReserved2 = */ NULL,
597 /* .pfnReserved3 = */ NULL,
598 /* .pfnReserved4 = */ NULL,
599 /* .pfnReserved5 = */ NULL,
600 /* .pfnReserved6 = */ NULL,
601 /* .pfnReserved7 = */ NULL,
602#elif defined(IN_RING0)
603 /* .pfnEarlyConstruct = */ NULL,
604 /* .pfnConstruct = */ pl031RZConstruct,
605 /* .pfnDestruct = */ NULL,
606 /* .pfnFinalDestruct = */ NULL,
607 /* .pfnRequest = */ NULL,
608 /* .pfnReserved0 = */ NULL,
609 /* .pfnReserved1 = */ NULL,
610 /* .pfnReserved2 = */ NULL,
611 /* .pfnReserved3 = */ NULL,
612 /* .pfnReserved4 = */ NULL,
613 /* .pfnReserved5 = */ NULL,
614 /* .pfnReserved6 = */ NULL,
615 /* .pfnReserved7 = */ NULL,
616#elif defined(IN_RC)
617 /* .pfnConstruct = */ pl031RZConstruct,
618 /* .pfnReserved0 = */ NULL,
619 /* .pfnReserved1 = */ NULL,
620 /* .pfnReserved2 = */ NULL,
621 /* .pfnReserved3 = */ NULL,
622 /* .pfnReserved4 = */ NULL,
623 /* .pfnReserved5 = */ NULL,
624 /* .pfnReserved6 = */ NULL,
625 /* .pfnReserved7 = */ NULL,
626#else
627# error "Not in IN_RING3, IN_RING0 or IN_RC!"
628#endif
629 /* .u32VersionEnd = */ PDM_DEVREG_VERSION
630};
631
632#endif /* !VBOX_DEVICE_STRUCT_TESTCASE */
633
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette