VirtualBox

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

Last change on this file since 2776 was 2270, checked in by vboxsync, 18 years ago

Stricter pointer typechecking. (R0 vs R3)

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