VirtualBox

source: vbox/trunk/src/VBox/Devices/testcase/tstDeviceVMMInternal.h@ 69162

Last change on this file since 69162 was 69162, checked in by vboxsync, 7 years ago

Devices/testcase: Skeleton for PDM device unit test framework, disabled by default (for backup purposes and to move more easily between hosts)

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 15.9 KB
Line 
1/* $Id: tstDeviceVMMInternal.h 69162 2017-10-23 11:10:23Z vboxsync $ */
2/** @file
3 * tstDevice - Test framework for PDM devices/drivers, definitions of VMM internal types.
4 */
5
6/*
7 * Copyright (C) 2017 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17#ifndef ___tstDeviceVMMInternal_h
18#define ___tstDeviceVMMInternal_h
19
20#include <VBox/types.h>
21#include <VBox/vmm/tm.h>
22#include <iprt/critsect.h>
23#include <iprt/list.h>
24
25RT_C_DECLS_BEGIN
26
27/** Pointer to a VMM callback table. */
28typedef struct TSTDEVVMMCALLBACKS *PTSTDEVVMMCALLBACKS;
29/** Pointer to a constant VMM callback table. */
30typedef const struct TSTDEVVMMCALLBACKS *PCTSTDEVVMMCALLBACKS;
31
32/** Pointer to the internal device under test instance. */
33typedef struct TSTDEVDUTINT *PTSTDEVDUTINT;
34/** Pointer to a constant device under test instance. */
35typedef const struct TSTDEVDUTINT *PCTSTDEVDUTINT;
36
37/**
38 * Private device instance data.
39 */
40typedef struct PDMDEVINSINT
41{
42 /** Pointer to the callback table. */
43 PCTSTDEVVMMCALLBACKS pVmmCallbacks;
44 /** Pointer to the device under test the PDM device instance is for. */
45 PTSTDEVDUTINT pDut;
46} PDMDEVINSINT;
47AssertCompile(sizeof(PDMDEVINSINT) <= (HC_ARCH_BITS == 32 ? 72 : 112 + 0x28));
48
49/**
50 * CFGM node structure.
51 */
52typedef struct CFGMNODE
53{
54 /** Pointer to the callback table. */
55 PCTSTDEVVMMCALLBACKS pVmmCallbacks;
56 /** Device under test this CFGM node is for. */
57 PTSTDEVDUTINT pDut;
58 /** @todo: */
59} CFGMNODE;
60
61/**
62 * PDM queue structure.
63 */
64typedef struct PDMQUEUE
65{
66 /** Pointer to the callback table. */
67 PCTSTDEVVMMCALLBACKS pVmmCallbacks;
68 /** @todo: */
69} PDMQUEUE;
70
71/**
72 * TM timer structure.
73 */
74typedef struct TMTIMER
75{
76 /** Pointer to the callback table. */
77 PCTSTDEVVMMCALLBACKS pVmmCallbacks;
78 /** List of timers created by the device. */
79 RTLISTNODE NdDevTimers;
80 /** Clock this timer belongs to. */
81 TMCLOCK enmClock;
82 /** Callback to call when the timer expires. */
83 PFNTMTIMERDEV pfnCallbackDev;
84 /** Opaque user data to pass to the callback. */
85 void *pvUser;
86 /** Flags. */
87 uint32_t fFlags;
88 /** @todo: */
89} TMTIMER;
90
91/**
92 * Internal VMM structure of VMCPU
93 */
94typedef struct VMMCPU
95{
96 /** Pointer to the callback table. */
97 PCTSTDEVVMMCALLBACKS pVmmCallbacks;
98 /** @todo: */
99} VMMCPU;
100AssertCompile(sizeof(VMMCPU) <= 704);
101
102/**
103 * Internal VMM structure of VM
104 */
105typedef struct VMM
106{
107 /** Pointer to the callback table. */
108 PCTSTDEVVMMCALLBACKS pVmmCallbacks;
109 /** @todo: */
110} VMM;
111AssertCompile(sizeof(VMM) <= 1600);
112
113/**
114 * Internal VM structure of VM
115 */
116typedef struct VMINT
117{
118 /** Pointer to the callback table. */
119 PCTSTDEVVMMCALLBACKS pVmmCallbacks;
120 /** @todo: */
121} VMINT;
122AssertCompile(sizeof(VMINT) <= 24);
123
124/**
125 * Internal per vCPU user VM structure.
126 */
127typedef struct VMINTUSERPERVMCPU
128{
129 /** Pointer to the callback table. */
130 PCTSTDEVVMMCALLBACKS pVmmCallbacks;
131 /** @todo: */
132} VMINTUSERPERVMCPU;
133AssertCompile(sizeof(VMINTUSERPERVMCPU) <= 512);
134
135/**
136 * Internal user VM structure.
137 */
138typedef struct VMINTUSERPERVM
139{
140 /** Pointer to the callback table. */
141 PCTSTDEVVMMCALLBACKS pVmmCallbacks;
142 /** @todo: */
143} VMINTUSERPERVM;
144AssertCompile(sizeof(VMINTUSERPERVM) <= 512);
145
146/**
147 * Internal PDM critical section structure.
148 */
149typedef struct PDMCRITSECTINT
150{
151 /** Pointer to the callback table. */
152 PCTSTDEVVMMCALLBACKS pVmmCallbacks;
153 /** The actual critical section used for emulation. */
154 RTCRITSECT CritSect;
155} PDMCRITSECTINT;
156AssertCompile(sizeof(PDMCRITSECTINT) <= (HC_ARCH_BITS == 32 ? 0x80 : 0xc0));
157
158/**
159 * Internal PDM thread instance data.
160 */
161typedef struct PDMTHREADINT
162{
163 /** Pointer to the callback table. */
164 PCTSTDEVVMMCALLBACKS pVmmCallbacks;
165 /** @todo: */
166} PDMTHREADINT;
167AssertCompile(sizeof(PDMTHREADINT) <= 64);
168
169#if 0
170/**
171 * Internal PDM netshaper filter instance data.
172 */
173typedef struct PDMNSFILTER
174{
175 /** Pointer to the callback table. */
176 PCTSTDEVVMMCALLBACKS pVmmCallbacks;
177 /** @todo: */
178} PDMNSFILTER;
179#endif
180
181#define PDMCRITSECTINT_DECLARED
182#define PDMTHREADINT_DECLARED
183#define PDMDEVINSINT_DECLARED
184#define ___VMInternal_h
185#define ___VMMInternal_h
186RT_C_DECLS_END
187#include <VBox/vmm/pdmcritsect.h>
188#include <VBox/vmm/vm.h>
189#include <VBox/vmm/uvm.h>
190#include <VBox/vmm/cfgm.h>
191#include <VBox/vmm/tm.h>
192#include <VBox/vmm/pdmblkcache.h>
193#include <VBox/vmm/pdmdev.h>
194#include <VBox/vmm/pdmqueue.h>
195#include <VBox/vmm/pdmthread.h>
196#include <VBox/vmm/cfgm.h>
197#include <VBox/vmm/mm.h>
198#include <VBox/vmm/pdmasynccompletion.h>
199#include <VBox/vmm/pdmnetshaper.h>
200#include <VBox/vmm/pgm.h>
201RT_C_DECLS_BEGIN
202
203
204/**
205 * Callback table from the VMM shim library to the PDM test framework.
206 */
207typedef struct TSTDEVVMMCALLBACKS
208{
209 DECLR3CALLBACKMEMBER(bool, pfnCFGMR3AreValuesValid, (PCFGMNODE pNode, const char *pszzValid));
210 DECLR3CALLBACKMEMBER(void, pfnCFGMR3Dump, (PCFGMNODE pRoot));
211 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMR3GetChild, (PCFGMNODE pNode, const char *pszPath));
212 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMR3GetChildFV, (PCFGMNODE pNode, const char *pszPathFormat, va_list Args));
213 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMR3GetFirstChild, (PCFGMNODE pNode));
214 DECLR3CALLBACKMEMBER(int, pfnCFGMR3GetName, (PCFGMNODE pCur, char *pszName, size_t cchName));
215 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMR3GetNextChild, (PCFGMNODE pCur));
216 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMR3GetParent, (PCFGMNODE pNode));
217 DECLR3CALLBACKMEMBER(PCFGMNODE, pfnCFGMR3GetRoot, (PVM pVM));
218 DECLR3CALLBACKMEMBER(int, pfnCFGMR3InsertNode, (PCFGMNODE pNode, const char *pszName, PCFGMNODE *ppChild));
219 DECLR3CALLBACKMEMBER(int, pfnCFGMR3InsertNodeFV, (PCFGMNODE pNode, PCFGMNODE *ppChild,
220 const char *pszNameFormat, va_list Args));
221 DECLR3CALLBACKMEMBER(int, pfnCFGMR3InsertString, (PCFGMNODE pNode, const char *pszName, const char *pszString));
222 DECLR3CALLBACKMEMBER(int, pfnCFGMR3QueryBytes, (PCFGMNODE pNode, const char *pszName, void *pvData, size_t cbData));
223 DECLR3CALLBACKMEMBER(int, pfnCFGMR3QueryInteger, (PCFGMNODE pNode, const char *pszName, uint64_t *pu64));
224 DECLR3CALLBACKMEMBER(int, pfnCFGMR3QuerySize, (PCFGMNODE pNode, const char *pszName, size_t *pcb));
225 DECLR3CALLBACKMEMBER(int, pfnCFGMR3QueryString, (PCFGMNODE pNode, const char *pszName, char *pszString, size_t cchString));
226 DECLR3CALLBACKMEMBER(int, pfnCFGMR3QueryStringAlloc, (PCFGMNODE pNode, const char *pszName, char **ppszString));
227 DECLR3CALLBACKMEMBER(int, pfnCFGMR3QueryStringAllocDef, (PCFGMNODE pNode, const char *pszName, char **ppszString, const char *pszDef));
228 DECLR3CALLBACKMEMBER(void, pfnCFGMR3RemoveNode, (PCFGMNODE pNode));
229 DECLR3CALLBACKMEMBER(int, pfnCFGMR3ValidateConfig, (PCFGMNODE pNode, const char *pszNode,
230 const char *pszValidValues, const char *pszValidNodes,
231 const char *pszWho, uint32_t uInstance));
232
233 DECLR3CALLBACKMEMBER(int, pfnIOMIOPortWrite, (PVM pVM, PVMCPU pVCpu, RTIOPORT Port, uint32_t u32Value, size_t cbValue));
234 DECLR3CALLBACKMEMBER(int, pfnIOMMMIOMapMMIO2Page, (PVM pVM, RTGCPHYS GCPhys, RTGCPHYS GCPhysRemapped, uint64_t fPageFlags));
235 DECLR3CALLBACKMEMBER(int, pfnIOMMMIOResetRegion, (PVM pVM, RTGCPHYS GCPhys));
236 DECLR3CALLBACKMEMBER(int, pfnMMHyperAlloc, (PVM pVM, size_t cb, uint32_t uAlignment, MMTAG enmTag, void **ppv));
237 DECLR3CALLBACKMEMBER(int, pfnMMHyperFree, (PVM pVM, void *pv));
238 DECLR3CALLBACKMEMBER(RTR0PTR, pfnMMHyperR3ToR0, (PVM pVM, RTR3PTR R3Ptr));
239 DECLR3CALLBACKMEMBER(RTRCPTR, pfnMMHyperR3ToRC, (PVM pVM, RTR3PTR R3Ptr));
240 DECLR3CALLBACKMEMBER(void, pfnMMR3HeapFree, (void *pv));
241 DECLR3CALLBACKMEMBER(int, pfnMMR3HyperAllocOnceNoRel, (PVM pVM, size_t cb, uint32_t uAlignment, MMTAG enmTag, void **ppv));
242 DECLR3CALLBACKMEMBER(uint64_t, pfnMMR3PhysGetRamSize, (PVM pVM));
243 DECLR3CALLBACKMEMBER(uint64_t, pfnMMR3PhysGetRamSizeAbove4GB, (PVM pVM));
244 DECLR3CALLBACKMEMBER(uint32_t, pfnMMR3PhysGetRamSizeBelow4GB, (PVM pVM));
245 DECLR3CALLBACKMEMBER(int, pfnPDMCritSectEnterDebug, (PPDMCRITSECT pCritSect, int rcBusy, RTHCUINTPTR uId, RT_SRC_POS_DECL));
246 DECLR3CALLBACKMEMBER(bool, pfnPDMCritSectIsInitialized, (PCPDMCRITSECT pCritSect));
247 DECLR3CALLBACKMEMBER(bool, pfnPDMCritSectIsOwner, (PCPDMCRITSECT pCritSect));
248 DECLR3CALLBACKMEMBER(int, pfnPDMCritSectLeave, (PPDMCRITSECT pCritSect));
249 DECLR3CALLBACKMEMBER(int, pfnPDMCritSectTryEnterDebug, (PPDMCRITSECT pCritSect, RTHCUINTPTR uId, RT_SRC_POS_DECL));
250 DECLR3CALLBACKMEMBER(int, pfnPDMHCCritSectScheduleExitEvent, (PPDMCRITSECT pCritSect, SUPSEMEVENT hEventToSignal));
251 DECLR3CALLBACKMEMBER(bool, pfnPDMNsAllocateBandwidth, (PPDMNSFILTER pFilter, size_t cbTransfer));
252 DECLR3CALLBACKMEMBER(PPDMQUEUEITEMCORE, pfnPDMQueueAlloc, (PPDMQUEUE pQueue));
253 DECLR3CALLBACKMEMBER(bool, pfnPDMQueueFlushIfNecessary, (PPDMQUEUE pQueue));
254 DECLR3CALLBACKMEMBER(void, pfnPDMQueueInsert, (PPDMQUEUE pQueue, PPDMQUEUEITEMCORE pItem));
255 DECLR3CALLBACKMEMBER(R0PTRTYPE(PPDMQUEUE), pfnPDMQueueR0Ptr, (PPDMQUEUE pQueue));
256 DECLR3CALLBACKMEMBER(RCPTRTYPE(PPDMQUEUE), pfnPDMQueueRCPtr, (PPDMQUEUE pQueue));
257 DECLR3CALLBACKMEMBER(int, pfnPDMR3AsyncCompletionEpClose, (PPDMASYNCCOMPLETIONENDPOINT pEndpoint));
258 DECLR3CALLBACKMEMBER(int, pfnPDMR3AsyncCompletionEpCreateForFile, (PPPDMASYNCCOMPLETIONENDPOINT ppEndpoint,
259 const char *pszFilename, uint32_t fFlags,
260 PPDMASYNCCOMPLETIONTEMPLATE pTemplate));
261 DECLR3CALLBACKMEMBER(int, pfnPDMR3AsyncCompletionEpFlush, (PPDMASYNCCOMPLETIONENDPOINT pEndpoint, void *pvUser,
262 PPPDMASYNCCOMPLETIONTASK ppTask));
263 DECLR3CALLBACKMEMBER(int, pfnPDMR3AsyncCompletionEpGetSize, (PPDMASYNCCOMPLETIONENDPOINT pEndpoint, uint64_t *pcbSize));
264 DECLR3CALLBACKMEMBER(int, pfnPDMR3AsyncCompletionEpRead, (PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
265 PCRTSGSEG paSegments, unsigned cSegments,
266 size_t cbRead, void *pvUser,
267 PPPDMASYNCCOMPLETIONTASK ppTask));
268 DECLR3CALLBACKMEMBER(int, pfnPDMR3AsyncCompletionEpSetBwMgr, (PPDMASYNCCOMPLETIONENDPOINT pEndpoint, const char *pszBwMgr));
269 DECLR3CALLBACKMEMBER(int, pfnPDMR3AsyncCompletionEpSetSize, (PPDMASYNCCOMPLETIONENDPOINT pEndpoint, uint64_t cbSize));
270 DECLR3CALLBACKMEMBER(int, pfnPDMR3AsyncCompletionEpWrite, (PPDMASYNCCOMPLETIONENDPOINT pEndpoint, RTFOFF off,
271 PCRTSGSEG paSegments, unsigned cSegments,
272 size_t cbWrite, void *pvUser,
273 PPPDMASYNCCOMPLETIONTASK ppTask));
274 DECLR3CALLBACKMEMBER(int, pfnPDMR3AsyncCompletionTemplateDestroy, (PPDMASYNCCOMPLETIONTEMPLATE pTemplate));
275 DECLR3CALLBACKMEMBER(int, pfnPDMR3BlkCacheClear, (PPDMBLKCACHE pBlkCache));
276 DECLR3CALLBACKMEMBER(int, pfnPDMR3BlkCacheDiscard, (PPDMBLKCACHE pBlkCache, PCRTRANGE paRanges,
277 unsigned cRanges, void *pvUser));
278 DECLR3CALLBACKMEMBER(int, pfnPDMR3BlkCacheFlush, (PPDMBLKCACHE pBlkCache, void *pvUser));
279 DECLR3CALLBACKMEMBER(int, pfnPDMR3BlkCacheIoXferComplete, (PPDMBLKCACHE pBlkCache, PPDMBLKCACHEIOXFER hIoXfer, int rcIoXfer));
280 DECLR3CALLBACKMEMBER(int, pfnPDMR3BlkCacheRead, (PPDMBLKCACHE pBlkCache, uint64_t off, PCRTSGBUF pSgBuf, size_t cbRead, void *pvUser));
281 DECLR3CALLBACKMEMBER(int, pfnPDMR3BlkCacheRelease, (PPDMBLKCACHE pBlkCache));
282 DECLR3CALLBACKMEMBER(int, pfnPDMR3BlkCacheResume, (PPDMBLKCACHE pBlkCache));
283 DECLR3CALLBACKMEMBER(int, pfnPDMR3BlkCacheSuspend, (PPDMBLKCACHE pBlkCache));
284 DECLR3CALLBACKMEMBER(int, pfnPDMR3BlkCacheWrite, (PPDMBLKCACHE pBlkCache, uint64_t off, PCRTSGBUF pSgBuf, size_t cbWrite, void *pvUser));
285 DECLR3CALLBACKMEMBER(int, pfnPDMR3CritSectDelete, (PPDMCRITSECT pCritSect));
286 DECLR3CALLBACKMEMBER(int, pfnPDMR3QueryLun, (PUVM pUVM, const char *pszDevice, unsigned iInstance, unsigned iLun, PPPDMIBASE ppBase));
287 DECLR3CALLBACKMEMBER(int, pfnPDMR3ThreadDestroy, (PPDMTHREAD pThread, int *pRcThread));
288 DECLR3CALLBACKMEMBER(int, pfnPDMR3ThreadResume, (PPDMTHREAD pThread));
289 DECLR3CALLBACKMEMBER(int, pfnPDMR3ThreadSleep, (PPDMTHREAD pThread, RTMSINTERVAL cMillies));
290 DECLR3CALLBACKMEMBER(int, pfnPDMR3ThreadSuspend, (PPDMTHREAD pThread));
291 DECLR3CALLBACKMEMBER(uint64_t, pfnTMCpuTicksPerSecond, (PVM pVM));
292 DECLR3CALLBACKMEMBER(int, pfnTMR3TimerDestroy, (PTMTIMER pTimer));
293 DECLR3CALLBACKMEMBER(int, pfnTMR3TimerLoad, (PTMTIMERR3 pTimer, PSSMHANDLE pSSM));
294 DECLR3CALLBACKMEMBER(int, pfnTMR3TimerSave, (PTMTIMERR3 pTimer, PSSMHANDLE pSSM));
295 DECLR3CALLBACKMEMBER(int, pfnTMR3TimerSetCritSect, (PTMTIMERR3 pTimer, PPDMCRITSECT pCritSect));
296 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimerFromMilli, (PTMTIMER pTimer, uint64_t cMilliSecs));
297 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimerFromNano, (PTMTIMER pTimer, uint64_t cNanoSecs));
298 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimerGet, (PTMTIMER pTimer));
299 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimerGetFreq, (PTMTIMER pTimer));
300 DECLR3CALLBACKMEMBER(uint64_t, pfnTMTimerGetNano, (PTMTIMER pTimer));
301 DECLR3CALLBACKMEMBER(bool, pfnTMTimerIsActive, (PTMTIMER pTimer));
302 DECLR3CALLBACKMEMBER(bool, pfnTMTimerIsLockOwner, (PTMTIMER pTimer));
303 DECLR3CALLBACKMEMBER(int, pfnTMTimerLock, (PTMTIMER pTimer, int rcBusy));
304 DECLR3CALLBACKMEMBER(PTMTIMERR0, pfnTMTimerR0Ptr, (PTMTIMER pTimer));
305 DECLR3CALLBACKMEMBER(PTMTIMERRC, pfnTMTimerRCPtr, (PTMTIMER pTimer));
306 DECLR3CALLBACKMEMBER(int, pfnTMTimerSet, (PTMTIMER pTimer, uint64_t u64Expire));
307 DECLR3CALLBACKMEMBER(int, pfnTMTimerSetFrequencyHint, (PTMTIMER pTimer, uint32_t uHz));
308 DECLR3CALLBACKMEMBER(int, pfnTMTimerSetMicro, (PTMTIMER pTimer, uint64_t cMicrosToNext));
309 DECLR3CALLBACKMEMBER(int, pfnTMTimerSetMillies, (PTMTIMER pTimer, uint32_t cMilliesToNext));
310 DECLR3CALLBACKMEMBER(int, pfnTMTimerSetNano, (PTMTIMER pTimer, uint64_t cNanosToNext));
311 DECLR3CALLBACKMEMBER(int, pfnTMTimerStop, (PTMTIMER pTimer));
312 DECLR3CALLBACKMEMBER(void, pfnTMTimerUnlock, (PTMTIMER pTimer));
313 DECLR3CALLBACKMEMBER(PVMCPU, pfnVMMGetCpu, (PVM pVM));
314 DECLR3CALLBACKMEMBER(VMCPUID, pfnVMMGetCpuId, (PVM pVM));
315 DECLR3CALLBACKMEMBER(int, pfnVMMR3DeregisterPatchMemory, (PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem));
316 DECLR3CALLBACKMEMBER(int, pfnVMMR3RegisterPatchMemory, (PVM pVM, RTGCPTR pPatchMem, unsigned cbPatchMem));
317 DECLR3CALLBACKMEMBER(RTNATIVETHREAD, pfnVMR3GetVMCPUNativeThread, (PVM pVM));
318 DECLR3CALLBACKMEMBER(int, pfnVMR3NotifyCpuDeviceReady, (PVM pVM, VMCPUID idCpu));
319 DECLR3CALLBACKMEMBER(int, pfnVMR3ReqCallNoWait, (PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...));
320 DECLR3CALLBACKMEMBER(int, pfnVMR3ReqCallVoidNoWait, (PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...));
321 DECLR3CALLBACKMEMBER(int, pfnVMR3ReqPriorityCallWait, (PVM pVM, VMCPUID idDstCpu, PFNRT pfnFunction, unsigned cArgs, ...));
322 DECLR3CALLBACKMEMBER(int, pfnVMR3WaitForDeviceReady, (PVM pVM, VMCPUID idCpu));
323} TSTDEVVMMCALLBACKS;
324
325
326extern const PDMDEVHLPR3 g_tstDevPdmDevHlpR3;
327extern const TSTDEVVMMCALLBACKS g_tstDevVmmCallbacks;
328
329RT_C_DECLS_END
330
331#endif
332
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