VirtualBox

source: vbox/trunk/src/VBox/VMM/IOMInternal.h@ 10196

Last change on this file since 10196 was 9776, checked in by vboxsync, 16 years ago

Stat updates

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 18.8 KB
Line 
1/* $Id: IOMInternal.h 9776 2008-06-17 14:58:11Z vboxsync $ */
2/** @file
3 * IOM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22#ifndef ___IOMInternal_h
23#define ___IOMInternal_h
24
25#include <VBox/cdefs.h>
26#include <VBox/types.h>
27#include <VBox/iom.h>
28#include <VBox/stam.h>
29#include <VBox/pgm.h>
30#include <VBox/param.h>
31#include <iprt/avl.h>
32
33#if !defined(IN_IOM_R3) && !defined(IN_IOM_R0) && !defined(IN_IOM_GC)
34# error "Not in IOM! This is an internal header!"
35#endif
36
37
38/** @defgroup grp_iom_int Internals
39 * @ingroup grp_iom
40 * @internal
41 * @{
42 */
43
44/**
45 * MMIO range descriptor.
46 */
47typedef struct IOMMMIORANGE
48{
49 /** Avl node core with GCPhys as Key and GCPhys + cbSize - 1 as KeyLast. */
50 AVLROGCPHYSNODECORE Core;
51 /** Start physical address. */
52 RTGCPHYS GCPhys;
53 /** Size of the range. */
54 uint32_t cb;
55 uint32_t u32Alignment; /**< Alignment padding. */
56
57 /** Pointer to user argument. */
58 RTR3PTR pvUserR3;
59 /** Pointer to device instance. */
60 PPDMDEVINSR3 pDevInsR3;
61 /** Pointer to write callback function. */
62 R3PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackR3;
63 /** Pointer to read callback function. */
64 R3PTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackR3;
65 /** Pointer to fill (memset) callback function. */
66 R3PTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackR3;
67
68 /** Pointer to user argument. */
69 RTR0PTR pvUserR0;
70 /** Pointer to device instance. */
71 PPDMDEVINSR0 pDevInsR0;
72 /** Pointer to write callback function. */
73 R0PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackR0;
74 /** Pointer to read callback function. */
75 R0PTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackR0;
76 /** Pointer to fill (memset) callback function. */
77 R0PTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackR0;
78
79 /** Pointer to user argument. */
80 RCPTRTYPE(void *) pvUserGC;
81 /** Pointer to device instance. */
82 PPDMDEVINSGC pDevInsGC;
83 /** Pointer to write callback function. */
84 RCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackGC;
85 /** Pointer to read callback function. */
86 RCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackGC;
87 /** Pointer to fill (memset) callback function. */
88 RCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackGC;
89 /** Alignment padding. */
90 RTRCPTR GCPtrAlignment;
91
92 /** Description / Name. For easing debugging. */
93 R3PTRTYPE(const char *) pszDesc;
94} IOMMMIORANGE;
95/** Pointer to a MMIO range descriptor, R3 version. */
96typedef struct IOMMMIORANGE *PIOMMMIORANGE;
97
98
99/**
100 * MMIO address statistics. (one address)
101 *
102 * This is a simple way of making on demand statistics, however it's a
103 * bit free with the hypervisor heap memory..
104 */
105typedef struct IOMMMIOSTATS
106{
107 /** Avl node core with the address as Key. */
108 AVLOGCPHYSNODECORE Core;
109 /** Number of reads to this address from R3. */
110 STAMCOUNTER ReadR3;
111 /** Number of writes to this address from R3. */
112 STAMCOUNTER WriteR3;
113 /** Number of reads to this address from R0. */
114 STAMCOUNTER ReadR0;
115 /** Number of writes to this address from R0. */
116 STAMCOUNTER WriteR0;
117 /** Number of reads to this address from GC. */
118 STAMCOUNTER ReadGC;
119 /** Number of writes to this address from GC. */
120 STAMCOUNTER WriteGC;
121 /** Profiling read handler overhead in R3. */
122 STAMPROFILEADV ProfReadR3;
123 /** Profiling write handler overhead in R3. */
124 STAMPROFILEADV ProfWriteR3;
125 /** Profiling read handler overhead in R0. */
126 STAMPROFILEADV ProfReadR0;
127 /** Profiling write handler overhead in R0. */
128 STAMPROFILEADV ProfWriteR0;
129 /** Profiling read handler overhead in GC. */
130 STAMPROFILEADV ProfReadGC;
131 /** Profiling write handler overhead in GC. */
132 STAMPROFILEADV ProfWriteGC;
133 /** Number of reads to this address from R0 which was serviced in R3. */
134 STAMCOUNTER ReadR0ToR3;
135 /** Number of writes to this address from R0 which was serviced in R3. */
136 STAMCOUNTER WriteR0ToR3;
137 /** Number of reads to this address from GC which was serviced in R3. */
138 STAMCOUNTER ReadGCToR3;
139 /** Number of writes to this address from GC which was serviced in R3. */
140 STAMCOUNTER WriteGCToR3;
141} IOMMMIOSTATS;
142/** Pointer to I/O port statistics. */
143typedef IOMMMIOSTATS *PIOMMMIOSTATS;
144
145
146/**
147 * I/O port range descriptor, R3 version.
148 */
149typedef struct IOMIOPORTRANGER3
150{
151 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
152 AVLROIOPORTNODECORE Core;
153#if HC_ARCH_BITS == 64 && !defined(RT_OS_WINDOWS)
154 uint32_t u32Alignment; /**< The sizeof(Core) differs. */
155#endif
156 /** Start I/O port address. */
157 RTIOPORT Port;
158 /** Size of the range. */
159 uint16_t cPorts;
160 /** Pointer to user argument. */
161 RTR3PTR pvUser;
162 /** Pointer to the associated device instance. */
163 R3PTRTYPE(PPDMDEVINS) pDevIns;
164 /** Pointer to OUT callback function. */
165 R3PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
166 /** Pointer to IN callback function. */
167 R3PTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
168 /** Pointer to string OUT callback function. */
169 R3PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
170 /** Pointer to string IN callback function. */
171 R3PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
172 /** Description / Name. For easing debugging. */
173 R3PTRTYPE(const char *) pszDesc;
174} IOMIOPORTRANGER3;
175/** Pointer to I/O port range descriptor, R3 version. */
176typedef IOMIOPORTRANGER3 *PIOMIOPORTRANGER3;
177
178/**
179 * I/O port range descriptor, R0 version.
180 */
181typedef struct IOMIOPORTRANGER0
182{
183 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
184 AVLROIOPORTNODECORE Core;
185#if HC_ARCH_BITS == 64 && !defined(RT_OS_WINDOWS)
186 uint32_t u32Alignment; /**< The sizeof(Core) differs. */
187#endif
188 /** Start I/O port address. */
189 RTIOPORT Port;
190 /** Size of the range. */
191 uint16_t cPorts;
192 /** Pointer to user argument. */
193 RTR0PTR pvUser;
194 /** Pointer to the associated device instance. */
195 R0PTRTYPE(PPDMDEVINS) pDevIns;
196 /** Pointer to OUT callback function. */
197 R0PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
198 /** Pointer to IN callback function. */
199 R0PTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
200 /** Pointer to string OUT callback function. */
201 R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
202 /** Pointer to string IN callback function. */
203 R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
204 /** Description / Name. For easing debugging. */
205 R3PTRTYPE(const char *) pszDesc;
206} IOMIOPORTRANGER0;
207/** Pointer to I/O port range descriptor, R0 version. */
208typedef IOMIOPORTRANGER0 *PIOMIOPORTRANGER0;
209
210/**
211 * I/O port range descriptor.
212 */
213typedef struct IOMIOPORTRANGEGC
214{
215 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
216 AVLROIOPORTNODECORE Core;
217 /** Start I/O port address. */
218 RTIOPORT Port;
219 /** Size of the range. */
220 uint16_t cPorts;
221 /** Pointer to user argument. */
222 RCPTRTYPE(void *) pvUser;
223 /** Pointer to the associated device instance. */
224 RCPTRTYPE(PPDMDEVINS) pDevIns;
225 /** Pointer to OUT callback function. */
226 RCPTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
227 /** Pointer to IN callback function. */
228 RCPTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
229 /** Pointer to string OUT callback function. */
230 RCPTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
231 /** Pointer to string IN callback function. */
232 RCPTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
233#if HC_ARCH_BITS == 64
234 RTRCPTR GCPtrAlignment; /**< pszDesc is 8 byte aligned. */
235#endif
236 /** Description / Name. For easing debugging. */
237 R3PTRTYPE(const char *) pszDesc;
238} IOMIOPORTRANGEGC;
239/** Pointer to I/O port range descriptor, GC version. */
240typedef IOMIOPORTRANGEGC *PIOMIOPORTRANGEGC;
241
242
243/**
244 * I/O port statistics. (one I/O port)
245 *
246 * This is a simple way of making on demand statistics, however it's a
247 * bit free with the hypervisor heap memory..
248 */
249typedef struct IOMIOPORTSTATS
250{
251 /** Avl node core with the port as Key. */
252 AVLOIOPORTNODECORE Core;
253#if HC_ARCH_BITS == 64 && !defined(RT_OS_WINDOWS)
254 uint32_t u32Alignment; /**< The sizeof(Core) differs. */
255#endif
256 /** Number of INs to this port from R3. */
257 STAMCOUNTER InR3;
258 /** Number of OUTs to this port from R3. */
259 STAMCOUNTER OutR3;
260 /** Number of INs to this port from R0. */
261 STAMCOUNTER InR0;
262 /** Number of OUTs to this port from R0. */
263 STAMCOUNTER OutR0;
264 /** Number of INs to this port from GC. */
265 STAMCOUNTER InGC;
266 /** Number of OUTs to this port from GC. */
267 STAMCOUNTER OutGC;
268 /** Profiling IN handler overhead in R3. */
269 STAMPROFILEADV ProfInR3;
270 /** Profiling OUT handler overhead in R3. */
271 STAMPROFILEADV ProfOutR3;
272 /** Profiling IN handler overhead in R0. */
273 STAMPROFILEADV ProfInR0;
274 /** Profiling OUT handler overhead in R0. */
275 STAMPROFILEADV ProfOutR0;
276 /** Profiling IN handler overhead in GC. */
277 STAMPROFILEADV ProfInGC;
278 /** Profiling OUT handler overhead in GC. */
279 STAMPROFILEADV ProfOutGC;
280 /** Number of INs to this port from R0 which was serviced in R3. */
281 STAMCOUNTER InR0ToR3;
282 /** Number of OUTs to this port from R0 which was serviced in R3. */
283 STAMCOUNTER OutR0ToR3;
284 /** Number of INs to this port from GC which was serviced in R3. */
285 STAMCOUNTER InGCToR3;
286 /** Number of OUTs to this port from GC which was serviced in R3. */
287 STAMCOUNTER OutGCToR3;
288} IOMIOPORTSTATS;
289/** Pointer to I/O port statistics. */
290typedef IOMIOPORTSTATS *PIOMIOPORTSTATS;
291
292
293/**
294 * The IOM trees.
295 * These are offset based the nodes and root must be in the same
296 * memory block in HC. The locations of IOM structure and the hypervisor heap
297 * are quite different in HC and GC.
298 */
299typedef struct IOMTREES
300{
301 /** Tree containing I/O port range descriptors registered for HC (IOMIOPORTRANGEHC). */
302 AVLROIOPORTTREE IOPortTreeR3;
303 /** Tree containing I/O port range descriptors registered for R0 (IOMIOPORTRANGER0). */
304 AVLROIOPORTTREE IOPortTreeR0;
305 /** Tree containing I/O port range descriptors registered for GC (IOMIOPORTRANGEGC). */
306 AVLROIOPORTTREE IOPortTreeGC;
307
308 /** Tree containing the MMIO range descriptors (IOMMMIORANGE). */
309 AVLROGCPHYSTREE MMIOTree;
310
311 /** Tree containing I/O port statistics (IOMIOPORTSTATS). */
312 AVLOIOPORTTREE IOPortStatTree;
313 /** Tree containing MMIO statistics (IOMMMIOSTATS). */
314 AVLOGCPHYSTREE MMIOStatTree;
315} IOMTREES;
316/** Pointer to the IOM trees. */
317typedef IOMTREES *PIOMTREES;
318
319
320/**
321 * Converts an IOM pointer into a VM pointer.
322 * @returns Pointer to the VM structure the PGM is part of.
323 * @param pIOM Pointer to IOM instance data.
324 */
325#define IOM2VM(pIOM) ( (PVM)((char*)pIOM - pIOM->offVM) )
326
327/**
328 * IOM Data (part of VM)
329 */
330typedef struct IOM
331{
332 /** Offset to the VM structure. */
333 RTINT offVM;
334
335 /** Pointer to the trees - GC ptr. */
336 RCPTRTYPE(PIOMTREES) pTreesGC;
337 /** Pointer to the trees - HC ptr. */
338 R3R0PTRTYPE(PIOMTREES) pTreesHC;
339
340 /** The ring-0 address of IOMMMIOHandler. */
341 R0PTRTYPE(PFNPGMR0PHYSHANDLER) pfnMMIOHandlerR0;
342 /** The GC address of IOMMMIOHandler. */
343 RCPTRTYPE(PFNPGMGCPHYSHANDLER) pfnMMIOHandlerGC;
344#if GC_ARCH_BITS == 64
345 RTRCPTR padding;
346#endif
347 RTGCPTR Alignment;
348
349 /** @name Caching of I/O Port and MMIO ranges and statistics.
350 * (Saves quite some time in rep outs/ins instruction emulation.)
351 * @{ */
352 R3PTRTYPE(PIOMIOPORTRANGER3) pRangeLastReadR3;
353 R3PTRTYPE(PIOMIOPORTRANGER3) pRangeLastWriteR3;
354 R3PTRTYPE(PIOMIOPORTSTATS) pStatsLastReadR3;
355 R3PTRTYPE(PIOMIOPORTSTATS) pStatsLastWriteR3;
356 R3PTRTYPE(PIOMMMIORANGE) pMMIORangeLastR3;
357 R3PTRTYPE(PIOMMMIOSTATS) pMMIOStatsLastR3;
358
359 R0PTRTYPE(PIOMIOPORTRANGER0) pRangeLastReadR0;
360 R0PTRTYPE(PIOMIOPORTRANGER0) pRangeLastWriteR0;
361 R0PTRTYPE(PIOMIOPORTSTATS) pStatsLastReadR0;
362 R0PTRTYPE(PIOMIOPORTSTATS) pStatsLastWriteR0;
363 R0PTRTYPE(PIOMMMIORANGE) pMMIORangeLastR0;
364 R0PTRTYPE(PIOMMMIOSTATS) pMMIOStatsLastR0;
365
366 RCPTRTYPE(PIOMIOPORTRANGEGC) pRangeLastReadGC;
367 RCPTRTYPE(PIOMIOPORTRANGEGC) pRangeLastWriteGC;
368 RCPTRTYPE(PIOMIOPORTSTATS) pStatsLastReadGC;
369 RCPTRTYPE(PIOMIOPORTSTATS) pStatsLastWriteGC;
370 RCPTRTYPE(PIOMMMIORANGE) pMMIORangeLastGC;
371 RCPTRTYPE(PIOMMMIOSTATS) pMMIOStatsLastGC;
372 /** @} */
373
374 /** @name I/O Port statistics.
375 * @{ */
376 STAMPROFILE StatGCIOPortHandler;
377
378 STAMCOUNTER StatGCInstIn;
379 STAMCOUNTER StatGCInstOut;
380 STAMCOUNTER StatGCInstIns;
381 STAMCOUNTER StatGCInstOuts;
382 /** @} */
383
384 /** @name MMIO statistics.
385 * @{ */
386 STAMPROFILE StatGCMMIOHandler;
387 STAMCOUNTER StatGCMMIOFailures;
388
389 STAMPROFILE StatGCInstMov;
390 STAMPROFILE StatGCInstCmp;
391 STAMPROFILE StatGCInstAnd;
392 STAMPROFILE StatGCInstTest;
393 STAMPROFILE StatGCInstXchg;
394 STAMPROFILE StatGCInstStos;
395 STAMPROFILE StatGCInstLods;
396 STAMPROFILE StatGCInstMovs;
397 STAMPROFILE StatGCInstMovsToMMIO;
398 STAMPROFILE StatGCInstMovsFromMMIO;
399 STAMPROFILE StatGCInstMovsMMIO;
400 STAMCOUNTER StatGCInstOther;
401
402 STAMCOUNTER StatGCMMIO1Byte;
403 STAMCOUNTER StatGCMMIO2Bytes;
404 STAMCOUNTER StatGCMMIO4Bytes;
405 STAMCOUNTER StatGCMMIO8Bytes;
406
407 RTUINT cMovsMaxBytes;
408 RTUINT cStosMaxBytes;
409 /** @} */
410
411} IOM;
412/** Pointer to IOM instance data. */
413typedef IOM *PIOM;
414
415
416__BEGIN_DECLS
417
418#ifdef IN_IOM_R3
419PIOMIOPORTSTATS iomr3IOPortStatsCreate(PVM pVM, RTIOPORT Port, const char *pszDesc);
420PIOMMMIOSTATS iomR3MMIOStatsCreate(PVM pVM, RTGCPHYS GCPhys, const char *pszDesc);
421#endif /* IN_IOM_R3 */
422
423/**
424 * \#PF Handler callback for MMIO ranges.
425 *
426 * @returns VBox status code (appropriate for GC return).
427 *
428 * @param pVM VM Handle.
429 * @param uErrorCode CPU Error code.
430 * @param pRegFrame Trap register frame.
431 * @param pvFault The fault address (cr2).
432 * @param GCPhysFault The GC physical address corresponding to pvFault.
433 * @param pvUser Pointer to the MMIO range entry.
434 */
435IOMDECL(int) IOMMMIOHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault, RTGCPHYS GCPhysFault, void *pvUser);
436
437/**
438 * Gets the I/O port range for the specified I/O port in the current context.
439 *
440 * @returns Pointer to I/O port range.
441 * @returns NULL if no port registered.
442 *
443 * @param pIOM IOM instance data.
444 * @param Port Port to lookup.
445 */
446DECLINLINE(CTXALLSUFF(PIOMIOPORTRANGE)) iomIOPortGetRange(PIOM pIOM, RTIOPORT Port)
447{
448 CTXALLSUFF(PIOMIOPORTRANGE) pRange = (CTXALLSUFF(PIOMIOPORTRANGE))RTAvlroIOPortRangeGet(&pIOM->CTXSUFF(pTrees)->CTXALLSUFF(IOPortTree), Port);
449 return pRange;
450}
451
452/**
453 * Gets the I/O port range for the specified I/O port in the HC.
454 *
455 * @returns Pointer to I/O port range.
456 * @returns NULL if no port registered.
457 *
458 * @param pIOM IOM instance data.
459 * @param Port Port to lookup.
460 */
461DECLINLINE(PIOMIOPORTRANGER3) iomIOPortGetRangeHC(PIOM pIOM, RTIOPORT Port)
462{
463 PIOMIOPORTRANGER3 pRange = (PIOMIOPORTRANGER3)RTAvlroIOPortRangeGet(&pIOM->CTXSUFF(pTrees)->IOPortTreeR3, Port);
464 return pRange;
465}
466
467
468/**
469 * Gets the MMIO range for the specified physical address in the current context.
470 *
471 * @returns Pointer to MMIO range.
472 * @returns NULL if address not in a MMIO range.
473 *
474 * @param pIOM IOM instance data.
475 * @param GCPhys Physical address to lookup.
476 */
477DECLINLINE(PIOMMMIORANGE) iomMMIOGetRange(PIOM pIOM, RTGCPHYS GCPhys)
478{
479 PIOMMMIORANGE pRange = CTXALLSUFF(pIOM->pMMIORangeLast);
480 if ( !pRange
481 || GCPhys - pRange->GCPhys >= pRange->cb)
482 CTXALLSUFF(pIOM->pMMIORangeLast) = pRange = (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pIOM->CTXSUFF(pTrees)->MMIOTree, GCPhys);
483 return pRange;
484}
485
486
487#ifdef VBOX_WITH_STATISTICS
488/**
489 * Gets the MMIO statistics record.
490 *
491 * In ring-3 this will lazily create missing records, while in GC/R0 the caller has to
492 * return the appropriate status to defer the operation to ring-3.
493 *
494 * @returns Pointer to MMIO stats.
495 * @returns NULL if not found (R0/GC), or out of memory (R3).
496 *
497 * @param pIOM IOM instance data.
498 * @param GCPhys Physical address to lookup.
499 * @param pRange The MMIO range.
500 */
501DECLINLINE(PIOMMMIOSTATS) iomMMIOGetStats(PIOM pIOM, RTGCPHYS GCPhys, PIOMMMIORANGE pRange)
502{
503 /* For large ranges, we'll put everything on the first byte. */
504 if (pRange->cb > PAGE_SIZE)
505 GCPhys = pRange->GCPhys;
506
507 PIOMMMIOSTATS pStats = CTXALLSUFF(pIOM->pMMIOStatsLast);
508 if ( !pStats
509 || pStats->Core.Key != GCPhys)
510 {
511 pStats = (PIOMMMIOSTATS)RTAvloGCPhysGet(&pIOM->CTXSUFF(pTrees)->MMIOStatTree, GCPhys);
512# ifdef IN_RING3
513 if (!pStats)
514 pStats = iomR3MMIOStatsCreate(IOM2VM(pIOM), GCPhys, pRange->pszDesc);
515# endif
516 }
517 return pStats;
518}
519#endif
520
521/* Disassembly helpers used in IOMAll.cpp & IOMAllMMIO.cpp */
522bool iomGetRegImmData(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, uint64_t *pu64Data, unsigned *pcbSize);
523bool iomSaveDataToReg(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, uint64_t u32Data);
524
525__END_DECLS
526
527
528#ifdef IN_RING3
529
530#endif
531
532/** @} */
533
534#endif /* ___IOMInternal_h */
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