VirtualBox

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

Last change on this file since 8170 was 8155, checked in by vboxsync, 17 years ago

The Big Sun Rebranding Header Change

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