VirtualBox

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

Last change on this file since 1223 was 706, checked in by vboxsync, 18 years ago

IOM handler profiling.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 16.4 KB
Line 
1/* $Id: IOMInternal.h 706 2007-02-06 14:05:06Z vboxsync $ */
2/** @file
3 * IOM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006 InnoTek Systemberatung GmbH
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 as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
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 <iprt/avl.h>
30
31#if !defined(IN_IOM_R3) && !defined(IN_IOM_R0) && !defined(IN_IOM_GC)
32# error "Not in IOM! This is an internal header!"
33#endif
34
35
36/** @defgroup grp_iom_int Internals
37 * @ingroup grp_iom
38 * @internal
39 * @{
40 */
41
42/**
43 * MMIO range descriptor, R3 version.
44 */
45typedef struct IOMMMIORANGER3
46{
47 /** Avl node core with GCPhys as Key and GCPhys + cbSize - 1 as KeyLast. */
48 AVLROGCPHYSNODECORE Core;
49 /** Start physical address. */
50 RTGCPHYS GCPhys;
51 /** Size of the range. */
52 RTUINT cbSize;
53 /** Pointer to user argument. */
54 RTHCPTR pvUser;
55 /** Pointer to device instance. */
56 HCPTRTYPE(PPDMDEVINS) pDevIns;
57 /** Pointer to write callback function. */
58 HCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback;
59 /** Pointer to read callback function. */
60 HCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallback;
61 /** Pointer to fill (memset) callback function. */
62 HCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallback;
63 /** Description / Name. For easing debugging. */
64 HCPTRTYPE(const char *) pszDesc;
65} IOMMMIORANGER3;
66/** Pointer to a MMIO range descriptor, R3 version. */
67typedef struct IOMMMIORANGER3 *PIOMMMIORANGER3;
68
69/** MMIO range descriptor, R0 version. */
70typedef IOMMMIORANGER3 IOMMMIORANGER0;
71/** Pointer to a MMIO range descriptor, R0 version. */
72typedef PIOMMMIORANGER3 PIOMMMIORANGER0;
73
74/**
75 * MMIO range descriptor, GC version.
76 */
77typedef struct IOMMMIORANGEGC
78{
79 /** Avl node core with GCPhys as Key and GCPhys + cbSize - 1 as KeyLast. */
80 AVLROGCPHYSNODECORE Core;
81 /** Start physical address. */
82 RTGCPHYS GCPhys;
83 /** Size of the range. */
84 RTUINT cbSize;
85 /** Pointer to user argument. */
86 RTGCPTR pvUser;
87 /** Pointer to device instance. */
88 GCPTRTYPE(PPDMDEVINS) pDevIns;
89 /** Pointer to write callback function. */
90 GCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallback;
91 /** Pointer to read callback function. */
92 GCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallback;
93 /** Pointer to fill (memset) callback function. */
94 GCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallback;
95 /** Description / Name. For easing debugging. */
96 HCPTRTYPE(const char *) pszDesc;
97} IOMMMIORANGEGC;
98/** Pointer to a MMIO range descriptor, GC version. */
99typedef struct IOMMMIORANGEGC *PIOMMMIORANGEGC;
100
101
102/**
103 * MMIO address statistics. (one address)
104 *
105 * This is a simple way of making on demand statistics, however it's a
106 * bit free with the hypervisor heap memory..
107 */
108typedef struct IOMMMIOSTATS
109{
110 /** Avl node core with the address as Key. */
111 AVLOGCPHYSNODECORE Core;
112 /** Number of reads to this address from R3. */
113 STAMCOUNTER ReadR3;
114 /** Number of writes to this address from R3. */
115 STAMCOUNTER WriteR3;
116 /** Number of reads to this address from R0. */
117 STAMCOUNTER ReadR0;
118 /** Number of writes to this address from R0. */
119 STAMCOUNTER WriteR0;
120 /** Number of reads to this address from GC. */
121 STAMCOUNTER ReadGC;
122 /** Number of writes to this address from GC. */
123 STAMCOUNTER WriteGC;
124 /** Profiling read handler overhead in R3. */
125 STAMPROFILEADV ProfReadR3;
126 /** Profiling write handler overhead in R3. */
127 STAMPROFILEADV ProfWriteR3;
128 /** Profiling read handler overhead in R0. */
129 STAMPROFILEADV ProfReadR0;
130 /** Profiling write handler overhead in R0. */
131 STAMPROFILEADV ProfWriteR0;
132 /** Profiling read handler overhead in GC. */
133 STAMPROFILEADV ProfReadGC;
134 /** Profiling write handler overhead in GC. */
135 STAMPROFILEADV ProfWriteGC;
136 /** Number of reads to this address from R0 which was serviced in R3. */
137 STAMCOUNTER ReadR0ToR3;
138 /** Number of writes to this address from R0 which was serviced in R3. */
139 STAMCOUNTER WriteR0ToR3;
140 /** Number of reads to this address from GC which was serviced in R3. */
141 STAMCOUNTER ReadGCToR3;
142 /** Number of writes to this address from GC which was serviced in R3. */
143 STAMCOUNTER WriteGCToR3;
144} IOMMMIOSTATS;
145/** Pointer to I/O port statistics. */
146typedef IOMMMIOSTATS *PIOMMMIOSTATS;
147
148
149/**
150 * I/O port range descriptor, R3 version.
151 */
152typedef struct IOMIOPORTRANGER3
153{
154 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
155 AVLROIOPORTNODECORE Core;
156 /** Start I/O port address. */
157 RTIOPORT Port;
158 /** Size of the range. */
159 uint16_t cPorts;
160 /** Pointer to user argument. */
161 RTHCPTR pvUser;
162 /** Pointer to the associated device instance. */
163 HCPTRTYPE(PPDMDEVINS) pDevIns;
164 /** Pointer to OUT callback function. */
165 HCPTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
166 /** Pointer to IN callback function. */
167 HCPTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
168 /** Pointer to string OUT callback function. */
169 HCPTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
170 /** Pointer to string IN callback function. */
171 HCPTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
172 /** Description / Name. For easing debugging. */
173 HCPTRTYPE(const char *) pszDesc;
174} IOMIOPORTRANGER3;
175/** Pointer to I/O port range descriptor, R3 version. */
176typedef IOMIOPORTRANGER3 *PIOMIOPORTRANGER3;
177
178/** I/O port range descriptor, R0 version. */
179typedef IOMIOPORTRANGER3 IOMIOPORTRANGER0;
180/** Pointer to I/O port range descriptor, R0 version. */
181typedef PIOMIOPORTRANGER3 PIOMIOPORTRANGER0;
182
183/**
184 * I/O port range descriptor.
185 */
186typedef struct IOMIOPORTRANGEGC
187{
188 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
189 AVLROIOPORTNODECORE Core;
190 /** Start I/O port address. */
191 RTIOPORT Port;
192 /** Size of the range. */
193 uint16_t cPorts;
194 /** Pointer to user argument. */
195 RTGCPTR pvUser;
196 /** Pointer to the associated device instance. */
197 GCPTRTYPE(PPDMDEVINS) pDevIns;
198 /** Pointer to OUT callback function. */
199 GCPTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
200 /** Pointer to IN callback function. */
201 GCPTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
202 /** Pointer to string OUT callback function. */
203 GCPTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
204 /** Pointer to string IN callback function. */
205 GCPTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
206 /** Description / Name. For easing debugging. */
207 HCPTRTYPE(const char *) pszDesc;
208} IOMIOPORTRANGEGC;
209/** Pointer to I/O port range descriptor, GC version. */
210typedef IOMIOPORTRANGEGC *PIOMIOPORTRANGEGC;
211
212
213/**
214 * I/O port statistics. (one I/O port)
215 *
216 * This is a simple way of making on demand statistics, however it's a
217 * bit free with the hypervisor heap memory..
218 */
219typedef struct IOMIOPORTSTATS
220{
221 /** Avl node core with the port as Key. */
222 AVLOIOPORTNODECORE Core;
223 /** Number of INs to this port from R3. */
224 STAMCOUNTER InR3;
225 /** Number of OUTs to this port from R3. */
226 STAMCOUNTER OutR3;
227 /** Number of INs to this port from R0. */
228 STAMCOUNTER InR0;
229 /** Number of OUTs to this port from R0. */
230 STAMCOUNTER OutR0;
231 /** Number of INs to this port from GC. */
232 STAMCOUNTER InGC;
233 /** Number of OUTs to this port from GC. */
234 STAMCOUNTER OutGC;
235 /** Profiling IN handler overhead in R3. */
236 STAMPROFILEADV ProfInR3;
237 /** Profiling OUT handler overhead in R3. */
238 STAMPROFILEADV ProfOutR3;
239 /** Profiling IN handler overhead in R0. */
240 STAMPROFILEADV ProfInR0;
241 /** Profiling OUT handler overhead in R0. */
242 STAMPROFILEADV ProfOutR0;
243 /** Profiling IN handler overhead in GC. */
244 STAMPROFILEADV ProfInGC;
245 /** Profiling OUT handler overhead in GC. */
246 STAMPROFILEADV ProfOutGC;
247 /** Number of INs to this port from R0 which was serviced in R3. */
248 STAMCOUNTER InR0ToR3;
249 /** Number of OUTs to this port from R0 which was serviced in R3. */
250 STAMCOUNTER OutR0ToR3;
251 /** Number of INs to this port from GC which was serviced in R3. */
252 STAMCOUNTER InGCToR3;
253 /** Number of OUTs to this port from GC which was serviced in R3. */
254 STAMCOUNTER OutGCToR3;
255} IOMIOPORTSTATS;
256/** Pointer to I/O port statistics. */
257typedef IOMIOPORTSTATS *PIOMIOPORTSTATS;
258
259
260/**
261 * The IOM trees.
262 * These are offset based the nodes and root must be in the same
263 * memory block in HC. The locations of IOM structure and the hypervisor heap
264 * are quite different in HC and GC.
265 */
266typedef struct IOMTREES
267{
268 /** Tree containing I/O port range descriptors registered for HC (IOMIOPORTRANGEHC). */
269 AVLROIOPORTTREE IOPortTreeR3;
270 /** Tree containing I/O port range descriptors registered for R0 (IOMIOPORTRANGER0). */
271 AVLROIOPORTTREE IOPortTreeR0;
272 /** Tree containing I/O port range descriptors registered for GC (IOMIOPORTRANGEGC). */
273 AVLROIOPORTTREE IOPortTreeGC;
274
275 /** Tree containing MMIO range descriptors registered for HC (IOMMMIORANGEHC). */
276 AVLROGCPHYSTREE MMIOTreeR3;
277 /** Tree containing MMIO range descriptors registered for R0 (IOMMMIORANGER0). */
278 AVLROGCPHYSTREE MMIOTreeR0;
279 /** Tree containing MMIO range descriptors registered for GC (IOMMMIORANGEGC). */
280 AVLROGCPHYSTREE MMIOTreeGC;
281
282 /** Tree containing I/O port statistics (IOMIOPORTSTATS). */
283 AVLOIOPORTTREE IOPortStatTree;
284 /** Tree containing MMIO statistics (IOMMMIOSTATS). */
285 AVLOGCPHYSTREE MMIOStatTree;
286} IOMTREES;
287/** Pointer to the IOM trees. */
288typedef IOMTREES *PIOMTREES;
289
290
291/**
292 * Converts an IOM pointer into a VM pointer.
293 * @returns Pointer to the VM structure the PGM is part of.
294 * @param pIOM Pointer to IOM instance data.
295 */
296#define IOM2VM(pIOM) ( (PVM)((char*)pIOM - pIOM->offVM) )
297
298/**
299 * IOM Data (part of VM)
300 */
301typedef struct IOM
302{
303 /** Offset to the VM structure. */
304 RTINT offVM;
305
306 /** Pointer to the trees - GC ptr. */
307 GCPTRTYPE(PIOMTREES) pTreesGC;
308 /** Pointer to the trees - HC ptr. */
309 HCPTRTYPE(PIOMTREES) pTreesHC;
310
311
312 /** @name Caching of I/O Port ranges and statistics.
313 * (Saves quite some time in rep outs/ins instruction emulation.)
314 * @{ */
315 HCPTRTYPE(PIOMIOPORTRANGER3) pRangeLastReadR3;
316 HCPTRTYPE(PIOMIOPORTRANGER3) pRangeLastWriteR3;
317 HCPTRTYPE(PIOMIOPORTSTATS) pStatsLastReadR3;
318 HCPTRTYPE(PIOMIOPORTSTATS) pStatsLastWriteR3;
319
320 HCPTRTYPE(PIOMIOPORTRANGER0) pRangeLastReadR0;
321 HCPTRTYPE(PIOMIOPORTRANGER0) pRangeLastWriteR0;
322 HCPTRTYPE(PIOMIOPORTSTATS) pStatsLastReadR0;
323 HCPTRTYPE(PIOMIOPORTSTATS) pStatsLastWriteR0;
324
325 GCPTRTYPE(PIOMIOPORTRANGEGC) pRangeLastReadGC;
326 GCPTRTYPE(PIOMIOPORTRANGEGC) pRangeLastWriteGC;
327 GCPTRTYPE(PIOMIOPORTSTATS) pStatsLastReadGC;
328 GCPTRTYPE(PIOMIOPORTSTATS) pStatsLastWriteGC;
329 /** @} */
330
331 /** @name I/O Port statistics.
332 * @{ */
333 STAMPROFILE StatGCIOPortHandler;
334
335 STAMCOUNTER StatGCInstIn;
336 STAMCOUNTER StatGCInstOut;
337 STAMCOUNTER StatGCInstIns;
338 STAMCOUNTER StatGCInstOuts;
339 /** @} */
340
341 /** @name MMIO statistics.
342 * @{ */
343 STAMPROFILE StatGCMMIOHandler;
344 STAMCOUNTER StatGCMMIOFailures;
345
346 STAMPROFILE StatGCInstMov;
347 STAMPROFILE StatGCInstCmp;
348 STAMPROFILE StatGCInstAnd;
349 STAMPROFILE StatGCInstTest;
350 STAMPROFILE StatGCInstXchg;
351 STAMPROFILE StatGCInstStos;
352 STAMPROFILE StatGCInstLods;
353 STAMPROFILE StatGCInstMovs;
354 STAMPROFILE StatGCInstMovsToMMIO;
355 STAMPROFILE StatGCInstMovsFromMMIO;
356 STAMPROFILE StatGCInstMovsMMIO;
357 STAMCOUNTER StatGCInstOther;
358
359 STAMCOUNTER StatGCMMIO1Byte;
360 STAMCOUNTER StatGCMMIO2Bytes;
361 STAMCOUNTER StatGCMMIO4Bytes;
362
363 RTUINT cMovsMaxBytes;
364 RTUINT cStosMaxBytes;
365 /** @} */
366
367} IOM;
368/** Pointer to IOM instance data. */
369typedef IOM *PIOM;
370
371
372__BEGIN_DECLS
373
374#ifdef IN_IOM_R3
375PIOMIOPORTSTATS iomr3IOPortStatsCreate(PVM pVM, RTIOPORT Port, const char *pszDesc);
376PIOMMMIOSTATS iomR3MMIOStatsCreate(PVM pVM, RTGCPHYS GCPhys, const char *pszDesc);
377#endif /* IN_IOM_R3 */
378
379/**
380 * \#PF Handler callback for MMIO ranges.
381 *
382 * @returns VBox status code (appropriate for GC return).
383 *
384 * @param pVM VM Handle.
385 * @param uErrorCode CPU Error code.
386 * @param pRegFrame Trap register frame.
387 * @param pvFault The fault address (cr2).
388 * @param GCPhysFault The GC physical address corresponding to pvFault.
389 * @param pvUser Pointer to the MMIO range entry.
390 */
391IOMDECL(int) IOMMMIOHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, void *pvFault, RTGCPHYS GCPhysFault, void *pvUser);
392
393/**
394 * Gets the I/O port range for the specified I/O port in the current context.
395 *
396 * @returns Pointer to I/O port range.
397 * @returns NULL if no port registered.
398 *
399 * @param pIOM IOM instance data.
400 * @param Port Port to lookup.
401 */
402inline CTXALLSUFF(PIOMIOPORTRANGE) iomIOPortGetRange(PIOM pIOM, RTIOPORT Port)
403{
404 CTXALLSUFF(PIOMIOPORTRANGE) pRange = (CTXALLSUFF(PIOMIOPORTRANGE))RTAvlroIOPortRangeGet(&pIOM->CTXSUFF(pTrees)->CTXALLSUFF(IOPortTree), Port);
405 return pRange;
406}
407
408/**
409 * Gets the I/O port range for the specified I/O port in the HC.
410 *
411 * @returns Pointer to I/O port range.
412 * @returns NULL if no port registered.
413 *
414 * @param pIOM IOM instance data.
415 * @param Port Port to lookup.
416 */
417inline PIOMIOPORTRANGER3 iomIOPortGetRangeHC(PIOM pIOM, RTIOPORT Port)
418{
419 PIOMIOPORTRANGER3 pRange = (PIOMIOPORTRANGER3)RTAvlroIOPortRangeGet(&pIOM->CTXSUFF(pTrees)->IOPortTreeR3, Port);
420 return pRange;
421}
422
423
424/**
425 * Gets the MMIO range for the specified physical address in the current context.
426 *
427 * @returns Pointer to MMIO range.
428 * @returns NULL if address not in a MMIO range.
429 *
430 * @param pIOM IOM instance data.
431 * @param GCPhys Physical address to lookup.
432 */
433inline CTXALLSUFF(PIOMMMIORANGE) iomMMIOGetRange(PIOM pIOM, RTGCPHYS GCPhys)
434{
435 CTXALLSUFF(PIOMMMIORANGE) pRange = (CTXALLSUFF(PIOMMMIORANGE))RTAvlroGCPhysRangeGet(&pIOM->CTXSUFF(pTrees)->CTXALLSUFF(MMIOTree), GCPhys);
436 return pRange;
437}
438
439
440/**
441 * Gets the MMIO range for the specified physical address in the current context.
442 *
443 * @returns Pointer to MMIO range.
444 * @returns NULL if address not in a MMIO range.
445 *
446 * @param pIOM IOM instance data.
447 * @param GCPhys Physical address to lookup.
448 */
449inline PIOMMMIORANGER3 iomMMIOGetRangeHC(PIOM pIOM, RTGCPHYS GCPhys)
450{
451 PIOMMMIORANGER3 pRange = (PIOMMMIORANGER3)RTAvlroGCPhysRangeGet(&pIOM->CTXSUFF(pTrees)->MMIOTreeR3, GCPhys);
452 return pRange;
453}
454
455#ifdef VBOX_WITH_STATISTICS
456/**
457 * Gets the MMIO statistics record.
458 * @returns Pointer to MMIO stats.
459 * @returns NULL if not found.
460 *
461 * @param pIOM IOM instance data.
462 * @param GCPhys Physical address to lookup.
463 */
464inline PIOMMMIOSTATS iomMMIOGetStats(PIOM pIOM, RTGCPHYS GCPhys)
465{
466 PIOMMMIOSTATS pStats = (PIOMMMIOSTATS)RTAvloGCPhysGet(&pIOM->CTXSUFF(pTrees)->MMIOStatTree, GCPhys);
467 return pStats;
468}
469#endif
470
471__END_DECLS
472
473#ifdef IN_RING3
474
475#endif
476
477/** @} */
478
479#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