VirtualBox

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

Last change on this file since 41391 was 39111, checked in by vboxsync, 13 years ago

IOM,PDM: Working on moving unaligned and non-dword MMIO access splitting and buffering up into IOM (from the device emulation).

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