VirtualBox

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

Last change on this file since 38152 was 37467, checked in by vboxsync, 13 years ago

IOM: Clean up locking now that all devices has its own CS.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 16.0 KB
Line 
1/* $Id: IOMInternal.h 37467 2011-06-15 13:08:45Z vboxsync $ */
2/** @file
3 * IOM - Internal header file.
4 */
5
6/*
7 * Copyright (C) 2006-2007 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
18#ifndef ___IOMInternal_h
19#define ___IOMInternal_h
20
21#include <VBox/cdefs.h>
22#include <VBox/types.h>
23#include <VBox/vmm/iom.h>
24#include <VBox/vmm/stam.h>
25#include <VBox/vmm/pgm.h>
26#include <VBox/vmm/pdmcritsect.h>
27#include <VBox/param.h>
28#include <iprt/assert.h>
29#include <iprt/avl.h>
30
31
32
33/** @defgroup grp_iom_int Internals
34 * @ingroup grp_iom
35 * @internal
36 * @{
37 */
38
39/**
40 * MMIO range descriptor.
41 */
42typedef struct IOMMMIORANGE
43{
44 /** Avl node core with GCPhys as Key and GCPhys + cbSize - 1 as KeyLast. */
45 AVLROGCPHYSNODECORE Core;
46 /** Start physical address. */
47 RTGCPHYS GCPhys;
48 /** Size of the range. */
49 uint32_t cb;
50 /** The reference counter. */
51 uint32_t volatile cRefs;
52
53 /** Pointer to user argument - R3. */
54 RTR3PTR pvUserR3;
55 /** Pointer to device instance - R3. */
56 PPDMDEVINSR3 pDevInsR3;
57 /** Pointer to write callback function - R3. */
58 R3PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackR3;
59 /** Pointer to read callback function - R3. */
60 R3PTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackR3;
61 /** Pointer to fill (memset) callback function - R3. */
62 R3PTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackR3;
63
64 /** Pointer to user argument - R0. */
65 RTR0PTR pvUserR0;
66 /** Pointer to device instance - R0. */
67 PPDMDEVINSR0 pDevInsR0;
68 /** Pointer to write callback function - R0. */
69 R0PTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackR0;
70 /** Pointer to read callback function - R0. */
71 R0PTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackR0;
72 /** Pointer to fill (memset) callback function - R0. */
73 R0PTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackR0;
74
75 /** Pointer to user argument - RC. */
76 RTRCPTR pvUserRC;
77 /** Pointer to device instance - RC. */
78 PPDMDEVINSRC pDevInsRC;
79 /** Pointer to write callback function - RC. */
80 RCPTRTYPE(PFNIOMMMIOWRITE) pfnWriteCallbackRC;
81 /** Pointer to read callback function - RC. */
82 RCPTRTYPE(PFNIOMMMIOREAD) pfnReadCallbackRC;
83 /** Pointer to fill (memset) callback function - RC. */
84 RCPTRTYPE(PFNIOMMMIOFILL) pfnFillCallbackRC;
85 /** Alignment padding. */
86 RTRCPTR RCPtrAlignment;
87
88 /** Description / Name. For easing debugging. */
89 R3PTRTYPE(const char *) pszDesc;
90} IOMMMIORANGE;
91/** Pointer to a MMIO range descriptor, R3 version. */
92typedef struct IOMMMIORANGE *PIOMMMIORANGE;
93
94
95/**
96 * MMIO address statistics. (one address)
97 *
98 * This is a simple way of making on demand statistics, however it's a
99 * bit free with the hypervisor heap memory.
100 */
101typedef struct IOMMMIOSTATS
102{
103 /** Avl node core with the address as Key. */
104 AVLOGCPHYSNODECORE Core;
105
106 /** Number of accesses (subtract ReadRZToR3 and WriteRZToR3 to get the right
107 * number). */
108 STAMCOUNTER Accesses;
109
110 /** Profiling read handler overhead in R3. */
111 STAMPROFILE ProfReadR3;
112 /** Profiling write handler overhead in R3. */
113 STAMPROFILE ProfWriteR3;
114 /** Counting and profiling reads in R0/RC. */
115 STAMPROFILE ProfReadRZ;
116 /** Counting and profiling writes in R0/RC. */
117 STAMPROFILE ProfWriteRZ;
118
119 /** Number of reads to this address from R0/RC which was serviced in R3. */
120 STAMCOUNTER ReadRZToR3;
121 /** Number of writes to this address from R0/RC which was serviced in R3. */
122 STAMCOUNTER WriteRZToR3;
123} IOMMMIOSTATS;
124AssertCompileMemberAlignment(IOMMMIOSTATS, Accesses, 8);
125/** Pointer to I/O port statistics. */
126typedef IOMMMIOSTATS *PIOMMMIOSTATS;
127
128
129/**
130 * I/O port range descriptor, R3 version.
131 */
132typedef struct IOMIOPORTRANGER3
133{
134 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
135 AVLROIOPORTNODECORE Core;
136#if HC_ARCH_BITS == 64 && !defined(RT_OS_WINDOWS)
137 uint32_t u32Alignment; /**< The sizeof(Core) differs. */
138#endif
139 /** Start I/O port address. */
140 RTIOPORT Port;
141 /** Size of the range. */
142 uint16_t cPorts;
143 /** Pointer to user argument. */
144 RTR3PTR pvUser;
145 /** Pointer to the associated device instance. */
146 R3PTRTYPE(PPDMDEVINS) pDevIns;
147 /** Pointer to OUT callback function. */
148 R3PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
149 /** Pointer to IN callback function. */
150 R3PTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
151 /** Pointer to string OUT callback function. */
152 R3PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
153 /** Pointer to string IN callback function. */
154 R3PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
155 /** Description / Name. For easing debugging. */
156 R3PTRTYPE(const char *) pszDesc;
157} IOMIOPORTRANGER3;
158/** Pointer to I/O port range descriptor, R3 version. */
159typedef IOMIOPORTRANGER3 *PIOMIOPORTRANGER3;
160
161/**
162 * I/O port range descriptor, R0 version.
163 */
164typedef struct IOMIOPORTRANGER0
165{
166 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
167 AVLROIOPORTNODECORE Core;
168#if HC_ARCH_BITS == 64 && !defined(RT_OS_WINDOWS)
169 uint32_t u32Alignment; /**< The sizeof(Core) differs. */
170#endif
171 /** Start I/O port address. */
172 RTIOPORT Port;
173 /** Size of the range. */
174 uint16_t cPorts;
175 /** Pointer to user argument. */
176 RTR0PTR pvUser;
177 /** Pointer to the associated device instance. */
178 R0PTRTYPE(PPDMDEVINS) pDevIns;
179 /** Pointer to OUT callback function. */
180 R0PTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
181 /** Pointer to IN callback function. */
182 R0PTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
183 /** Pointer to string OUT callback function. */
184 R0PTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
185 /** Pointer to string IN callback function. */
186 R0PTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
187 /** Description / Name. For easing debugging. */
188 R3PTRTYPE(const char *) pszDesc;
189} IOMIOPORTRANGER0;
190/** Pointer to I/O port range descriptor, R0 version. */
191typedef IOMIOPORTRANGER0 *PIOMIOPORTRANGER0;
192
193/**
194 * I/O port range descriptor, RC version.
195 */
196typedef struct IOMIOPORTRANGERC
197{
198 /** Avl node core with Port as Key and Port + cPorts - 1 as KeyLast. */
199 AVLROIOPORTNODECORE Core;
200 /** Start I/O port address. */
201 RTIOPORT Port;
202 /** Size of the range. */
203 uint16_t cPorts;
204 /** Pointer to user argument. */
205 RTRCPTR pvUser;
206 /** Pointer to the associated device instance. */
207 RCPTRTYPE(PPDMDEVINS) pDevIns;
208 /** Pointer to OUT callback function. */
209 RCPTRTYPE(PFNIOMIOPORTOUT) pfnOutCallback;
210 /** Pointer to IN callback function. */
211 RCPTRTYPE(PFNIOMIOPORTIN) pfnInCallback;
212 /** Pointer to string OUT callback function. */
213 RCPTRTYPE(PFNIOMIOPORTOUTSTRING) pfnOutStrCallback;
214 /** Pointer to string IN callback function. */
215 RCPTRTYPE(PFNIOMIOPORTINSTRING) pfnInStrCallback;
216#if HC_ARCH_BITS == 64
217 RTRCPTR RCPtrAlignment; /**< pszDesc is 8 byte aligned. */
218#endif
219 /** Description / Name. For easing debugging. */
220 R3PTRTYPE(const char *) pszDesc;
221} IOMIOPORTRANGERC;
222/** Pointer to I/O port range descriptor, RC version. */
223typedef IOMIOPORTRANGERC *PIOMIOPORTRANGERC;
224
225
226/**
227 * I/O port statistics. (one I/O port)
228 *
229 * This is a simple way of making on demand statistics, however it's a
230 * bit free with the hypervisor heap memory.
231 */
232typedef struct IOMIOPORTSTATS
233{
234 /** Avl node core with the port as Key. */
235 AVLOIOPORTNODECORE Core;
236#if HC_ARCH_BITS != 64 || !defined(RT_OS_WINDOWS)
237 uint32_t u32Alignment; /**< The sizeof(Core) differs. */
238#endif
239 /** Number of INs to this port from R3. */
240 STAMCOUNTER InR3;
241 /** Profiling IN handler overhead in R3. */
242 STAMPROFILE ProfInR3;
243 /** Number of OUTs to this port from R3. */
244 STAMCOUNTER OutR3;
245 /** Profiling OUT handler overhead in R3. */
246 STAMPROFILE ProfOutR3;
247
248 /** Number of INs to this port from R0/RC. */
249 STAMCOUNTER InRZ;
250 /** Profiling IN handler overhead in R0/RC. */
251 STAMPROFILE ProfInRZ;
252 /** Number of INs to this port from R0/RC which was serviced in R3. */
253 STAMCOUNTER InRZToR3;
254
255 /** Number of OUTs to this port from R0/RC. */
256 STAMCOUNTER OutRZ;
257 /** Profiling OUT handler overhead in R0/RC. */
258 STAMPROFILE ProfOutRZ;
259 /** Number of OUTs to this port from R0/RC which was serviced in R3. */
260 STAMCOUNTER OutRZToR3;
261} IOMIOPORTSTATS;
262AssertCompileMemberAlignment(IOMIOPORTSTATS, InR3, 8);
263/** Pointer to I/O port statistics. */
264typedef IOMIOPORTSTATS *PIOMIOPORTSTATS;
265
266
267/**
268 * The IOM trees.
269 * These are offset based the nodes and root must be in the same
270 * memory block in HC. The locations of IOM structure and the hypervisor heap
271 * are quite different in R3, R0 and RC.
272 */
273typedef struct IOMTREES
274{
275 /** Tree containing I/O port range descriptors registered for HC (IOMIOPORTRANGEHC). */
276 AVLROIOPORTTREE IOPortTreeR3;
277 /** Tree containing I/O port range descriptors registered for R0 (IOMIOPORTRANGER0). */
278 AVLROIOPORTTREE IOPortTreeR0;
279 /** Tree containing I/O port range descriptors registered for RC (IOMIOPORTRANGERC). */
280 AVLROIOPORTTREE IOPortTreeRC;
281
282 /** Tree containing the MMIO range descriptors (IOMMMIORANGE). */
283 AVLROGCPHYSTREE MMIOTree;
284
285 /** Tree containing I/O port statistics (IOMIOPORTSTATS). */
286 AVLOIOPORTTREE IOPortStatTree;
287 /** Tree containing MMIO statistics (IOMMMIOSTATS). */
288 AVLOGCPHYSTREE MmioStatTree;
289} IOMTREES;
290/** Pointer to the IOM trees. */
291typedef IOMTREES *PIOMTREES;
292
293
294/**
295 * Converts an IOM pointer into a VM pointer.
296 * @returns Pointer to the VM structure the PGM is part of.
297 * @param pIOM Pointer to IOM instance data.
298 */
299#define IOM2VM(pIOM) ( (PVM)((char*)pIOM - pIOM->offVM) )
300
301/**
302 * IOM Data (part of VM)
303 */
304typedef struct IOM
305{
306 /** Offset to the VM structure. */
307 RTINT offVM;
308
309 /** Pointer to the trees - RC ptr. */
310 RCPTRTYPE(PIOMTREES) pTreesRC;
311 /** Pointer to the trees - R3 ptr. */
312 R3PTRTYPE(PIOMTREES) pTreesR3;
313 /** Pointer to the trees - R0 ptr. */
314 R0PTRTYPE(PIOMTREES) pTreesR0;
315
316 /** The ring-0 address of IOMMMIOHandler. */
317 R0PTRTYPE(PFNPGMR0PHYSHANDLER) pfnMMIOHandlerR0;
318 /** The RC address of IOMMMIOHandler. */
319 RCPTRTYPE(PFNPGMRCPHYSHANDLER) pfnMMIOHandlerRC;
320#if HC_ARCH_BITS == 64
321 RTRCPTR padding;
322#endif
323
324 /** Lock serializing EMT access to IOM. */
325 PDMCRITSECT CritSect;
326
327 /** @name Caching of I/O Port and MMIO ranges and statistics.
328 * (Saves quite some time in rep outs/ins instruction emulation.)
329 * @{ */
330 R3PTRTYPE(PIOMIOPORTRANGER3) pRangeLastReadR3;
331 R3PTRTYPE(PIOMIOPORTRANGER3) pRangeLastWriteR3;
332 R3PTRTYPE(PIOMIOPORTSTATS) pStatsLastReadR3;
333 R3PTRTYPE(PIOMIOPORTSTATS) pStatsLastWriteR3;
334 R3PTRTYPE(PIOMMMIORANGE) pMMIORangeLastR3;
335 R3PTRTYPE(PIOMMMIOSTATS) pMMIOStatsLastR3;
336
337 R0PTRTYPE(PIOMIOPORTRANGER0) pRangeLastReadR0;
338 R0PTRTYPE(PIOMIOPORTRANGER0) pRangeLastWriteR0;
339 R0PTRTYPE(PIOMIOPORTSTATS) pStatsLastReadR0;
340 R0PTRTYPE(PIOMIOPORTSTATS) pStatsLastWriteR0;
341 R0PTRTYPE(PIOMMMIORANGE) pMMIORangeLastR0;
342 R0PTRTYPE(PIOMMMIOSTATS) pMMIOStatsLastR0;
343
344 RCPTRTYPE(PIOMIOPORTRANGERC) pRangeLastReadRC;
345 RCPTRTYPE(PIOMIOPORTRANGERC) pRangeLastWriteRC;
346 RCPTRTYPE(PIOMIOPORTSTATS) pStatsLastReadRC;
347 RCPTRTYPE(PIOMIOPORTSTATS) pStatsLastWriteRC;
348 RCPTRTYPE(PIOMMMIORANGE) pMMIORangeLastRC;
349 RCPTRTYPE(PIOMMMIOSTATS) pMMIOStatsLastRC;
350 /** @} */
351
352 /** @name I/O Port statistics.
353 * @{ */
354 STAMCOUNTER StatInstIn;
355 STAMCOUNTER StatInstOut;
356 STAMCOUNTER StatInstIns;
357 STAMCOUNTER StatInstOuts;
358 /** @} */
359
360 /** @name MMIO statistics.
361 * @{ */
362 STAMPROFILE StatRZMMIOHandler;
363 STAMCOUNTER StatRZMMIOFailures;
364
365 STAMPROFILE StatRZInstMov;
366 STAMPROFILE StatRZInstCmp;
367 STAMPROFILE StatRZInstAnd;
368 STAMPROFILE StatRZInstOr;
369 STAMPROFILE StatRZInstXor;
370 STAMPROFILE StatRZInstBt;
371 STAMPROFILE StatRZInstTest;
372 STAMPROFILE StatRZInstXchg;
373 STAMPROFILE StatRZInstStos;
374 STAMPROFILE StatRZInstLods;
375#ifdef IOM_WITH_MOVS_SUPPORT
376 STAMPROFILEADV StatRZInstMovs;
377 STAMPROFILE StatRZInstMovsToMMIO;
378 STAMPROFILE StatRZInstMovsFromMMIO;
379 STAMPROFILE StatRZInstMovsMMIO;
380#endif
381 STAMCOUNTER StatRZInstOther;
382
383 STAMCOUNTER StatRZMMIO1Byte;
384 STAMCOUNTER StatRZMMIO2Bytes;
385 STAMCOUNTER StatRZMMIO4Bytes;
386 STAMCOUNTER StatRZMMIO8Bytes;
387
388 STAMCOUNTER StatR3MMIOHandler;
389
390 RTUINT cMovsMaxBytes;
391 RTUINT cStosMaxBytes;
392 /** @} */
393} IOM;
394/** Pointer to IOM instance data. */
395typedef IOM *PIOM;
396
397
398/**
399 * IOM per virtual CPU instance data.
400 */
401typedef struct IOMCPU
402{
403 /** For saving stack space, the disassembler state is allocated here instead of
404 * on the stack.
405 * @note The DISCPUSTATE structure is not R3/R0/RZ clean! */
406 union
407 {
408 /** The disassembler scratch space. */
409 DISCPUSTATE DisState;
410 /** Padding. */
411 uint8_t abDisStatePadding[DISCPUSTATE_PADDING_SIZE];
412 };
413 uint8_t Dummy[16];
414} IOMCPU;
415/** Pointer to IOM per virtual CPU instance data. */
416typedef IOMCPU *PIOMCPU;
417
418
419RT_C_DECLS_BEGIN
420
421void iomMmioFreeRange(PVM pVM, PIOMMMIORANGE pRange);
422#ifdef IN_RING3
423PIOMIOPORTSTATS iomR3IOPortStatsCreate(PVM pVM, RTIOPORT Port, const char *pszDesc);
424PIOMMMIOSTATS iomR3MMIOStatsCreate(PVM pVM, RTGCPHYS GCPhys, const char *pszDesc);
425#endif /* IN_RING3 */
426
427VMMDECL(int) IOMMMIOHandler(PVM pVM, RTGCUINT uErrorCode, PCPUMCTXCORE pRegFrame, RTGCPTR pvFault,
428 RTGCPHYS GCPhysFault, void *pvUser);
429#ifdef IN_RING3
430DECLCALLBACK(int) IOMR3MMIOHandler(PVM pVM, RTGCPHYS GCPhys, void *pvPhys, void *pvBuf, size_t cbBuf,
431 PGMACCESSTYPE enmAccessType, void *pvUser);
432#endif
433
434/* IOM locking helpers. */
435#define IOM_LOCK(a_pVM) PDMCritSectEnter(&(a_pVM)->iom.s.CritSect, VERR_SEM_BUSY)
436#define IOM_UNLOCK(a_pVM) do { PDMCritSectLeave(&(a_pVM)->iom.s.CritSect); } while (0)
437
438
439/* Disassembly helpers used in IOMAll.cpp & IOMAllMMIO.cpp */
440bool iomGetRegImmData(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, uint64_t *pu64Data, unsigned *pcbSize);
441bool iomSaveDataToReg(PDISCPUSTATE pCpu, PCOP_PARAMETER pParam, PCPUMCTXCORE pRegFrame, uint64_t u32Data);
442
443RT_C_DECLS_END
444
445
446#ifdef IN_RING3
447
448#endif
449
450/** @} */
451
452#endif /* !___IOMInternal_h */
453
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