summaryrefslogtreecommitdiffstats
path: root/src/VBox/Devices/testcase/tstDeviceInternal.h
blob: 477eb5337ac0b9749d6a9254605878f089fa050e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
/** @file
 * tstDevice: Shared definitions between the framework and the shim library.
 */

/*
 * Copyright (C) 2017-2023 Oracle and/or its affiliates.
 *
 * This file is part of VirtualBox base platform packages, as
 * available from https://www.virtualbox.org.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License
 * as published by the Free Software Foundation, in version 3 of the
 * License.
 *
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see <https://www.gnu.org/licenses>.
 *
 * SPDX-License-Identifier: GPL-3.0-only
 */

#ifndef VBOX_INCLUDED_SRC_testcase_tstDeviceInternal_h
#define VBOX_INCLUDED_SRC_testcase_tstDeviceInternal_h
#ifndef RT_WITHOUT_PRAGMA_ONCE
# pragma once
#endif

#include <VBox/param.h>
#include <VBox/types.h>
#include <iprt/assert.h>
#include <iprt/list.h>
#include <iprt/semaphore.h>
#include <iprt/critsect.h>

#include "tstDeviceCfg.h"
#include "tstDevicePlugin.h"

RT_C_DECLS_BEGIN

#define PDM_MAX_DEVICE_INSTANCE_SIZE      _4M

/** Converts PDM device instance to the device under test structure. */
#define TSTDEV_PDMDEVINS_2_DUT(a_pDevIns) ((a_pDevIns)->Internal.s.pDut)

/** Forward declaration of internal test device instance data. */
typedef struct TSTDEVDUTINT *PTSTDEVDUTINT;


/** Pointer to a const PDM module descriptor. */
typedef const struct TSTDEVPDMMOD *PCTSTDEVPDMMOD;


/**
 * PDM device descriptor.
 */
typedef struct TSTDEVPDMDEV
{
    /** Node for the known device list. */
    RTLISTNODE                      NdPdmDevs;
    /** Pointer to the PDM module containing the device. */
    PCTSTDEVPDMMOD                  pPdmMod;
    /** Device registration structure. */
    const struct PDMDEVREGR3        *pReg;
} TSTDEVPDMDEV;
/** Pointer to a PDM device descriptor .*/
typedef TSTDEVPDMDEV *PTSTDEVPDMDEV;
/** Pointer to a constant PDM device descriptor .*/
typedef const TSTDEVPDMDEV *PCTSTDEVPDMDEV;


/**
 * CFGM node structure.
 */
typedef struct CFGMNODE
{
    /** Device under test this CFGM node is for. */
    PTSTDEVDUTINT        pDut;
    /** @todo: */
} CFGMNODE;


/**
 * Private device instance data.
 */
typedef struct PDMDEVINSINTR3
{
    /** Pointer to the device under test the PDM device instance is for. */
    PTSTDEVDUTINT                   pDut;
} PDMDEVINSINTR3;
AssertCompile(sizeof(PDMDEVINSINTR3) <= (HC_ARCH_BITS == 32 ? 72 : 112 + 0x28));

/**
 * Private device instance data.
 */
typedef struct PDMDEVINSINTR0
{
    /** Pointer to the device under test the PDM device instance is for. */
    PTSTDEVDUTINT                   pDut;
} PDMDEVINSINTR0;
AssertCompile(sizeof(PDMDEVINSINTR0) <= (HC_ARCH_BITS == 32 ? 72 : 112 + 0x28));

/**
 * Private device instance data.
 */
typedef struct PDMDEVINSINTRC
{
    /** Pointer to the device under test the PDM device instance is for. */
    PTSTDEVDUTINT                   pDut;
} PDMDEVINSINTRC;
AssertCompile(sizeof(PDMDEVINSINTRC) <= (HC_ARCH_BITS == 32 ? 72 : 112 + 0x28));

typedef struct PDMPCIDEVINT
{
    bool                            fRegistered;
} PDMPCIDEVINT;


/**
 * Internal PDM critical section structure.
 */
typedef struct PDMCRITSECTINT
{
    /** The actual critical section used for emulation. */
    RTCRITSECT           CritSect;
} PDMCRITSECTINT;
AssertCompile(sizeof(PDMCRITSECTINT) <= (HC_ARCH_BITS == 32 ? 0x80 : 0xc0));


/**
 * SSM handle state.
 */
typedef struct SSMHANDLE
{
    /** Pointer to the device under test the handle is for. */
    PTSTDEVDUTINT                   pDut;
    /** The saved state data buffer. */
    uint8_t                         *pbSavedState;
    /** Size of the saved state. */
    size_t                          cbSavedState;
    /** Current offset into the data buffer. */
    uint32_t                        offDataBuffer;
    /** Current unit version. */
    uint32_t                        uCurUnitVer;
    /** Status code. */
    int                             rc;
} SSMHANDLE;


/**
 * MM Heap allocation.
 */
typedef struct TSTDEVMMHEAPALLOC
{
    /** Node for the list of allocations. */
    RTLISTNODE                      NdMmHeap;
    /** Pointer to the device under test the allocation was made for. */
    PTSTDEVDUTINT                   pDut;
    /** Size of the allocation. */
    size_t                          cbAlloc;
    /** Start of the real allocation. */
    RT_FLEXIBLE_ARRAY_EXTENSION
    uint8_t                         abAlloc[RT_FLEXIBLE_ARRAY];
} TSTDEVMMHEAPALLOC;
/** Pointer to a MM Heap allocation. */
typedef TSTDEVMMHEAPALLOC *PTSTDEVMMHEAPALLOC;
/** Pointer to a const MM Heap allocation. */
typedef const TSTDEVMMHEAPALLOC *PCTSTDEVMMHEAPALLOC;

AssertCompileMemberAlignment(TSTDEVMMHEAPALLOC, abAlloc, HC_ARCH_BITS == 64 ? 16 : 8);


/**
 * The usual device/driver/internal/external stuff.
 */
typedef enum
{
    /** The usual invalid entry. */
    PDMTHREADTYPE_INVALID = 0,
    /** Device type. */
    PDMTHREADTYPE_DEVICE,
    /** USB Device type. */
    PDMTHREADTYPE_USB,
    /** Driver type. */
    PDMTHREADTYPE_DRIVER,
    /** Internal type. */
    PDMTHREADTYPE_INTERNAL,
    /** External type. */
    PDMTHREADTYPE_EXTERNAL,
    /** The usual 32-bit hack. */
    PDMTHREADTYPE_32BIT_HACK = 0x7fffffff
} PDMTHREADTYPE;


/**
 * The internal structure for the thread.
 */
typedef struct PDMTHREADINT
{
    /** Node for the list of threads. */
    RTLISTNODE                      NdPdmThrds;
    /** Pointer to the device under test the allocation was made for. */
    PTSTDEVDUTINT                   pDut;
    /** The event semaphore the thread blocks on when not running. */
    RTSEMEVENTMULTI                 BlockEvent;
    /** The event semaphore the thread sleeps on while running. */
    RTSEMEVENTMULTI                 SleepEvent;
    /** The thread type. */
    PDMTHREADTYPE                   enmType;
} PDMTHREADINT;


#define PDMTHREADINT_DECLARED
#define PDMCRITSECTINT_DECLARED
#define PDMDEVINSINT_DECLARED
#define PDMPCIDEVINT_DECLARED
#define VMM_INCLUDED_SRC_include_VMInternal_h
#define VMM_INCLUDED_SRC_include_VMMInternal_h
RT_C_DECLS_END
#include <VBox/vmm/pdmcritsect.h>
#include <VBox/vmm/pdmthread.h>
#include <VBox/vmm/pdmdev.h>
#include <VBox/vmm/pdmpci.h>
#include <VBox/vmm/pdmdrv.h>
#include <VBox/vmm/tm.h>
RT_C_DECLS_BEGIN


/**
 * TM timer structure.
 */
typedef struct TMTIMER
{
    /** List of timers created by the device. */
    RTLISTNODE           NdDevTimers;
    /** Clock this timer belongs to. */
    TMCLOCK              enmClock;
    /** Callback to call when the timer expires. */
    PFNTMTIMERDEV        pfnCallbackDev;
    /** Opaque user data to pass to the callback. */
    void                 *pvUser;
    /** Flags. */
    uint32_t             fFlags;
    /** Assigned critical section. */
    PPDMCRITSECT         pCritSect;
    /** @todo: */
} TMTIMER;


/**
 * PDM module descriptor type.
 */
typedef enum TSTDEVPDMMODTYPE
{
    /** Invalid module type. */
    TSTDEVPDMMODTYPE_INVALID = 0,
    /** Ring 3 module. */
    TSTDEVPDMMODTYPE_R3,
    /** Ring 0 module. */
    TSTDEVPDMMODTYPE_R0,
    /** Raw context module. */
    TSTDEVPDMMODTYPE_RC,
    /** 32bit hack. */
    TSTDEVPDMMODTYPE_32BIT_HACK = 0x7fffffff
} TSTDEVPDMMODTYPE;

/**
 * Registered I/O port access handler.
 */
typedef struct RTDEVDUTIOPORT
{
    /** Node for the list of registered handlers. */
    RTLISTNODE                      NdIoPorts;
    /** Start I/O port the handler is for. */
    RTIOPORT                        PortStart;
    /** Number of ports handled. */
    RTIOPORT                        cPorts;
    /** Opaque user data - R3. */
    void                            *pvUserR3;
    /** Out handler - R3. */
    PFNIOMIOPORTNEWOUT              pfnOutR3;
    /** In handler - R3. */
    PFNIOMIOPORTNEWIN               pfnInR3;
    /** Out string handler - R3. */
    PFNIOMIOPORTNEWOUTSTRING        pfnOutStrR3;
    /** In string handler - R3. */
    PFNIOMIOPORTNEWINSTRING         pfnInStrR3;

    /** Opaque user data - R0. */
    void                            *pvUserR0;
    /** Out handler - R0. */
    PFNIOMIOPORTNEWOUT              pfnOutR0;
    /** In handler - R0. */
    PFNIOMIOPORTNEWIN               pfnInR0;
    /** Out string handler - R0. */
    PFNIOMIOPORTNEWOUTSTRING        pfnOutStrR0;
    /** In string handler - R0. */
    PFNIOMIOPORTNEWINSTRING         pfnInStrR0;

#ifdef TSTDEV_SUPPORTS_RC
    /** Opaque user data - RC. */
    void                            *pvUserRC;
    /** Out handler - RC. */
    PFNIOMIOPORTNEWOUT              pfnOutRC;
    /** In handler - RC. */
    PFNIOMIOPORTNEWIN               pfnInRC;
    /** Out string handler - RC. */
    PFNIOMIOPORTNEWOUTSTRING        pfnOutStrRC;
    /** In string handler - RC. */
    PFNIOMIOPORTNEWINSTRING         pfnInStrRC;
#endif
} RTDEVDUTIOPORT;
/** Pointer to a registered I/O port handler. */
typedef RTDEVDUTIOPORT *PRTDEVDUTIOPORT;
/** Pointer to a const I/O port handler. */
typedef const RTDEVDUTIOPORT *PCRTDEVDUTIOPORT;


/**
 * Registered MMIO port access handler.
 */
typedef struct RTDEVDUTMMIO
{
    /** Node for the list of registered handlers. */
    RTLISTNODE                      NdMmio;
    /** Start address of the MMIO region when mapped. */
    RTGCPHYS                        GCPhysStart;
    /** Size of the MMIO region in bytes. */
    RTGCPHYS                        cbRegion;
    /** Opaque user data - R3. */
    void                            *pvUserR3;
    /** Write handler - R3. */
    PFNIOMMMIONEWWRITE              pfnWriteR3;
    /** Read handler - R3. */
    PFNIOMMMIONEWREAD               pfnReadR3;
    /** Fill handler - R3. */
    PFNIOMMMIONEWFILL               pfnFillR3;

    /** Opaque user data - R0. */
    void                            *pvUserR0;
    /** Write handler - R0. */
    PFNIOMMMIONEWWRITE              pfnWriteR0;
    /** Read handler - R0. */
    PFNIOMMMIONEWREAD               pfnReadR0;
    /** Fill handler - R0. */
    PFNIOMMMIONEWFILL               pfnFillR0;

#ifdef TSTDEV_SUPPORTS_RC
    /** Opaque user data - RC. */
    void                            *pvUserRC;
    /** Write handler - RC. */
    PFNIOMMMIONEWWRITE              pfnWriteRC;
    /** Read handler - RC. */
    PFNIOMMMIONEWREAD               pfnReadRC;
    /** Fill handler - RC. */
    PFNIOMMMIONEWFILL               pfnFillRC;
#endif
} RTDEVDUTMMIO;
/** Pointer to a registered MMIO handler. */
typedef RTDEVDUTMMIO *PRTDEVDUTMMIO;
/** Pointer to a const MMIO handler. */
typedef const RTDEVDUTMMIO *PCRTDEVDUTMMIO;


#ifdef IN_RING3
/**
 * Registered SSM handlers.
 */
typedef struct TSTDEVDUTSSM
{
    /** Node for the list of registered SSM handlers. */
    RTLISTNODE                      NdSsm;
    /** Version */
    uint32_t                        uVersion;
    PFNSSMDEVLIVEPREP               pfnLivePrep;
    PFNSSMDEVLIVEEXEC               pfnLiveExec;
    PFNSSMDEVLIVEVOTE               pfnLiveVote;
    PFNSSMDEVSAVEPREP               pfnSavePrep;
    PFNSSMDEVSAVEEXEC               pfnSaveExec;
    PFNSSMDEVSAVEDONE               pfnSaveDone;
    PFNSSMDEVLOADPREP               pfnLoadPrep;
    PFNSSMDEVLOADEXEC               pfnLoadExec;
    PFNSSMDEVLOADDONE               pfnLoadDone;
} TSTDEVDUTSSM;
/** Pointer to the registered SSM handlers. */
typedef TSTDEVDUTSSM *PTSTDEVDUTSSM;
/** Pointer to a const SSM handler. */
typedef const TSTDEVDUTSSM *PCTSTDEVDUTSSM;
#endif


/**
 * The Support Driver session state.
 */
typedef struct TSTDEVSUPDRVSESSION
{
    /** Pointer to the owning device under test instance. */
    PTSTDEVDUTINT                   pDut;
    /** List of event semaphores. */
    RTLISTANCHOR                    LstSupSem;
} TSTDEVSUPDRVSESSION;
/** Pointer to the Support Driver session state. */
typedef TSTDEVSUPDRVSESSION *PTSTDEVSUPDRVSESSION;

/** Converts a Support Driver session handle to the internal state. */
#define TSTDEV_PSUPDRVSESSION_2_PTSTDEVSUPDRVSESSION(a_pSession) ((PTSTDEVSUPDRVSESSION)(a_pSession))
/** Converts the internal session state to a Support Driver session handle. */
#define TSTDEV_PTSTDEVSUPDRVSESSION_2_PSUPDRVSESSION(a_pSession) ((PSUPDRVSESSION)(a_pSession))

/**
 * Support driver event semaphore.
 */
typedef struct TSTDEVSUPSEMEVENT
{
    /** Node for the event semaphore list. */
    RTLISTNODE                      NdSupSem;
    /** Flag whether this is multi event semaphore. */
    bool                            fMulti;
    /** Event smeaphore handles depending on the flag above. */
    union
    {
        RTSEMEVENT                  hSemEvt;
        RTSEMEVENTMULTI             hSemEvtMulti;
    } u;
} TSTDEVSUPSEMEVENT;
/** Pointer to a support event semaphore state. */
typedef TSTDEVSUPSEMEVENT *PTSTDEVSUPSEMEVENT;

/** Converts a Support event semaphore handle to the internal state. */
#define TSTDEV_SUPSEMEVENT_2_PTSTDEVSUPSEMEVENT(a_pSupSemEvt) ((PTSTDEVSUPSEMEVENT)(a_pSupSemEvt))
/** Converts the internal session state to a Support event semaphore handle. */
#define TSTDEV_PTSTDEVSUPSEMEVENT_2_SUPSEMEVENT(a_pSupSemEvt) ((SUPSEMEVENT)(a_pSupSemEvt))

/**
 * The contex the device under test is currently in.
 */
typedef enum TSTDEVDUTCTX
{
    /** Invalid context. */
    TSTDEVDUTCTX_INVALID = 0,
    /** R3 context. */
    TSTDEVDUTCTX_R3,
    /** R0 context. */
    TSTDEVDUTCTX_R0,
    /** RC context. */
    TSTDEVDUTCTX_RC,
    /** 32bit hack. */
    TSTDEVDUTCTX_32BIT_HACK = 0x7fffffff
} TSTDEVDUTCTX;

/**
 * PCI region descriptor.
 */
typedef struct TSTDEVDUTPCIREGION
{
    /** Size of the region. */
    RTGCPHYS                        cbRegion;
    /** Address space type. */
    PCIADDRESSSPACE                 enmType;
    /** Region mapping callback. */
    PFNPCIIOREGIONMAP               pfnRegionMap;
} TSTDEVDUTPCIREGION;
/** Pointer to a PCI region descriptor. */
typedef TSTDEVDUTPCIREGION *PTSTDEVDUTPCIREGION;
/** Pointer to a const PCI region descriptor. */
typedef const TSTDEVDUTPCIREGION *PCTSTDEVDUTPCIREGION;

/**
 * Device under test instance data.
 */
typedef struct TSTDEVDUTINT
{
    /** Pointer to the test this device is running under. */
    PCTSTDEVTEST                    pTest;
    /** The PDM device registration record. */
    PCTSTDEVPDMDEV                  pPdmDev;
    /** Pointer to the PDM device instance. */
    struct PDMDEVINSR3             *pDevIns;
    /** Pointer to the PDM R0 device instance. */
    struct PDMDEVINSR0             *pDevInsR0;
    /** CFGM root config node for the device. */
    CFGMNODE                        Cfg;
    /** Current device context. */
    TSTDEVDUTCTX                    enmCtx;
    /** Critical section protecting the lists below. */
    RTCRITSECTRW                    CritSectLists;
    /** List of registered I/O port handlers. */
    RTLISTANCHOR                    LstIoPorts;
    /** List of timers registered. */
    RTLISTANCHOR                    LstTimers;
    /** List of registered MMIO regions. */
    RTLISTANCHOR                    LstMmio;
    /** List of MM Heap allocations. */
    RTLISTANCHOR                    LstMmHeap;
    /** List of PDM threads. */
    RTLISTANCHOR                    LstPdmThreads;
    /** List of SSM handlers (just one normally). */
    RTLISTANCHOR                    LstSsmHandlers;
    /** The SUP session we emulate. */
    TSTDEVSUPDRVSESSION             SupSession;
    /** The NOP critical section. */
    PDMCRITSECT                     CritSectNop;
    /** The VM state associated with this device. */
    PVM                             pVm;
    /** The registered PCI device instance if this is a PCI device. */
    PPDMPCIDEV                      pPciDev;
    /** PCI Region descriptors. */
    TSTDEVDUTPCIREGION              aPciRegions[VBOX_PCI_NUM_REGIONS];
    /** The status port interface we implement. */
    PDMIBASE                        IBaseSts;
    /**  */
} TSTDEVDUTINT;


#ifdef IN_RING3
extern const PDMDEVHLPR3 g_tstDevPdmDevHlpR3;
#endif
extern const PDMDEVHLPR0 g_tstDevPdmDevHlpR0;

DECLHIDDEN(int) tstDevPdmLdrGetSymbol(PTSTDEVDUTINT pThis, const char *pszMod, TSTDEVPDMMODTYPE enmModType,
                                      const char *pszSymbol, PFNRT *ppfn);


DECLINLINE(int) tstDevDutLockShared(PTSTDEVDUTINT pThis)
{
    return RTCritSectRwEnterShared(&pThis->CritSectLists);
}

DECLINLINE(int) tstDevDutUnlockShared(PTSTDEVDUTINT pThis)
{
    return RTCritSectRwLeaveShared(&pThis->CritSectLists);
}

DECLINLINE(int) tstDevDutLockExcl(PTSTDEVDUTINT pThis)
{
    return RTCritSectRwEnterExcl(&pThis->CritSectLists);
}

DECLINLINE(int) tstDevDutUnlockExcl(PTSTDEVDUTINT pThis)
{
    return RTCritSectRwLeaveExcl(&pThis->CritSectLists);
}

DECLHIDDEN(int) tstDevPdmR3ThreadCreateDevice(PTSTDEVDUTINT pDut, PPDMDEVINS pDevIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDEV pfnThread,
                                              PFNPDMTHREADWAKEUPDEV pfnWakeUp, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
DECLHIDDEN(int) tstDevPdmR3ThreadCreateUsb(PTSTDEVDUTINT pDut, PPDMUSBINS pUsbIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADUSB pfnThread,
                                           PFNPDMTHREADWAKEUPUSB pfnWakeUp, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
DECLHIDDEN(int) tstDevPdmR3ThreadCreateDriver(PTSTDEVDUTINT pDut, PPDMDRVINS pDrvIns, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADDRV pfnThread,
                                              PFNPDMTHREADWAKEUPDRV pfnWakeUp, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
DECLHIDDEN(int) tstDevPdmR3ThreadCreate(PTSTDEVDUTINT pDut, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADINT pfnThread,
                                        PFNPDMTHREADWAKEUPINT pfnWakeUp, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
DECLHIDDEN(int) tstDevPdmR3ThreadCreateExternal(PTSTDEVDUTINT pDut, PPPDMTHREAD ppThread, void *pvUser, PFNPDMTHREADEXT pfnThread,
                                                PFNPDMTHREADWAKEUPEXT pfnWakeUp, size_t cbStack, RTTHREADTYPE enmType, const char *pszName);
DECLHIDDEN(int) tstDevPdmR3ThreadDestroy(PPDMTHREAD pThread, int *pRcThread);
DECLHIDDEN(int) tstDevPdmR3ThreadDestroyDevice(PTSTDEVDUTINT pDut, PPDMDEVINS pDevIns);
DECLHIDDEN(int) tstDevPdmR3ThreadDestroyUsb(PTSTDEVDUTINT pDut, PPDMUSBINS pUsbIns);
DECLHIDDEN(int) tstDevPdmR3ThreadDestroyDriver(PTSTDEVDUTINT pDut, PPDMDRVINS pDrvIns);
DECLHIDDEN(void) tstDevPdmR3ThreadDestroyAll(PTSTDEVDUTINT pDut);
DECLHIDDEN(int) tstDevPdmR3ThreadIAmSuspending(PPDMTHREAD pThread);
DECLHIDDEN(int) tstDevPdmR3ThreadIAmRunning(PPDMTHREAD pThread);
DECLHIDDEN(int) tstDevPdmR3ThreadSleep(PPDMTHREAD pThread, RTMSINTERVAL cMillies);
DECLHIDDEN(int) tstDevPdmR3ThreadSuspend(PPDMTHREAD pThread);
DECLHIDDEN(int) tstDevPdmR3ThreadResume(PPDMTHREAD pThread);


DECLHIDDEN(PCTSTDEVPDMDEV) tstDevPdmDeviceFind(const char *pszName, PCPDMDEVREGR0 *ppR0Reg);
DECLHIDDEN(int) tstDevPdmDeviceR3Construct(PTSTDEVDUTINT pDut);

DECLHIDDEN(int) tstDevPdmDevR0R3Create(const char *pszName, bool fRCEnabled, PTSTDEVDUTINT pDut);


RT_C_DECLS_END

#endif /* !VBOX_INCLUDED_SRC_testcase_tstDeviceInternal_h */