VirtualBox

source: vbox/trunk/src/VBox/VMM/include/IOMInline.h@ 76397

Last change on this file since 76397 was 76397, checked in by vboxsync, 6 years ago

VBox/vmm/hm_svm.h,hm_vmx.h: Try avoid including VBox/err.h in widely used headers, so split out the inline stuff from hm_vmx.h into hmvmxinline.h. bugref:9344

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.4 KB
Line 
1/* $Id: IOMInline.h 76397 2018-12-23 14:32:01Z vboxsync $ */
2/** @file
3 * IOM - Inlined functions.
4 */
5
6/*
7 * Copyright (C) 2006-2017 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 ___IOMInline_h
19#define ___IOMInline_h
20
21#include <iprt/errcore.h>
22
23/** @addtogroup grp_iom_int Internals
24 * @internal
25 * @{
26 */
27
28/**
29 * Gets the I/O port range for the specified I/O port in the current context.
30 *
31 * @returns Pointer to I/O port range.
32 * @returns NULL if no port registered.
33 *
34 * @param pVM The cross context VM structure.
35 * @param Port The I/O port lookup.
36 */
37DECLINLINE(CTX_SUFF(PIOMIOPORTRANGE)) iomIOPortGetRange(PVM pVM, RTIOPORT Port)
38{
39 Assert(IOM_IS_SHARED_LOCK_OWNER(pVM));
40 return (CTX_SUFF(PIOMIOPORTRANGE))RTAvlroIOPortRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->CTX_SUFF(IOPortTree), Port);
41}
42
43
44/**
45 * Gets the I/O port range for the specified I/O port in the HC.
46 *
47 * @returns Pointer to I/O port range.
48 * @returns NULL if no port registered.
49 *
50 * @param pVM The cross context VM structure.
51 * @param Port The I/O port to lookup.
52 */
53DECLINLINE(PIOMIOPORTRANGER3) iomIOPortGetRangeR3(PVM pVM, RTIOPORT Port)
54{
55 Assert(IOM_IS_SHARED_LOCK_OWNER(pVM));
56 return (PIOMIOPORTRANGER3)RTAvlroIOPortRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->IOPortTreeR3, Port);
57}
58
59
60/**
61 * Gets the MMIO range for the specified physical address in the current context.
62 *
63 * @returns Pointer to MMIO range.
64 * @returns NULL if address not in a MMIO range.
65 *
66 * @param pVM The cross context VM structure.
67 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
68 * @param GCPhys Physical address to lookup.
69 */
70DECLINLINE(PIOMMMIORANGE) iomMmioGetRange(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys)
71{
72 Assert(IOM_IS_SHARED_LOCK_OWNER(pVM));
73 PIOMMMIORANGE pRange = pVCpu->iom.s.CTX_SUFF(pMMIORangeLast);
74 if ( !pRange
75 || GCPhys - pRange->GCPhys >= pRange->cb)
76 pVCpu->iom.s.CTX_SUFF(pMMIORangeLast) = pRange
77 = (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->MMIOTree, GCPhys);
78 return pRange;
79}
80
81/**
82 * Retain a MMIO range.
83 *
84 * @param pRange The range to release.
85 */
86DECLINLINE(void) iomMmioRetainRange(PIOMMMIORANGE pRange)
87{
88 uint32_t cRefs = ASMAtomicIncU32(&pRange->cRefs);
89 Assert(cRefs > 1);
90 Assert(cRefs < _1M);
91 NOREF(cRefs);
92}
93
94
95/**
96 * Gets the referenced MMIO range for the specified physical address in the
97 * current context.
98 *
99 * @returns Pointer to MMIO range.
100 * @returns NULL if address not in a MMIO range.
101 *
102 * @param pVM The cross context VM structure.
103 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
104 * @param GCPhys Physical address to lookup.
105 */
106DECLINLINE(PIOMMMIORANGE) iomMmioGetRangeWithRef(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys)
107{
108 int rc = IOM_LOCK_SHARED_EX(pVM, VINF_SUCCESS);
109 AssertRCReturn(rc, NULL);
110
111 PIOMMMIORANGE pRange = pVCpu->iom.s.CTX_SUFF(pMMIORangeLast);
112 if ( !pRange
113 || GCPhys - pRange->GCPhys >= pRange->cb)
114 pVCpu->iom.s.CTX_SUFF(pMMIORangeLast) = pRange
115 = (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->MMIOTree, GCPhys);
116 if (pRange)
117 iomMmioRetainRange(pRange);
118
119 IOM_UNLOCK_SHARED(pVM);
120 return pRange;
121}
122
123
124/**
125 * Releases a MMIO range.
126 *
127 * @param pVM The cross context VM structure.
128 * @param pRange The range to release.
129 */
130DECLINLINE(void) iomMmioReleaseRange(PVM pVM, PIOMMMIORANGE pRange)
131{
132 uint32_t cRefs = ASMAtomicDecU32(&pRange->cRefs);
133 if (!cRefs)
134 iomMmioFreeRange(pVM, pRange);
135}
136
137
138#ifdef VBOX_STRICT
139/**
140 * Gets the MMIO range for the specified physical address in the current context.
141 *
142 * @returns Pointer to MMIO range.
143 * @returns NULL if address not in a MMIO range.
144 *
145 * @param pVM The cross context VM structure.
146 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
147 * @param GCPhys Physical address to lookup.
148 */
149DECLINLINE(PIOMMMIORANGE) iomMMIOGetRangeUnsafe(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys)
150{
151 PIOMMMIORANGE pRange = pVCpu->iom.s.CTX_SUFF(pMMIORangeLast);
152 if ( !pRange
153 || GCPhys - pRange->GCPhys >= pRange->cb)
154 pVCpu->iom.s.CTX_SUFF(pMMIORangeLast) = pRange
155 = (PIOMMMIORANGE)RTAvlroGCPhysRangeGet(&pVM->iom.s.CTX_SUFF(pTrees)->MMIOTree, GCPhys);
156 return pRange;
157}
158#endif /* VBOX_STRICT */
159
160
161#ifdef VBOX_WITH_STATISTICS
162/**
163 * Gets the MMIO statistics record.
164 *
165 * In ring-3 this will lazily create missing records, while in GC/R0 the caller has to
166 * return the appropriate status to defer the operation to ring-3.
167 *
168 * @returns Pointer to MMIO stats.
169 * @returns NULL if not found (R0/GC), or out of memory (R3).
170 *
171 * @param pVM The cross context VM structure.
172 * @param pVCpu The cross context virtual CPU structure of the calling EMT.
173 * @param GCPhys Physical address to lookup.
174 * @param pRange The MMIO range.
175 *
176 * @remarks The caller holds the IOM critical section with shared access prior
177 * to calling this method. Upon return, the lock has been released!
178 * This is ugly, but it's a necessary evil since we cannot upgrade read
179 * locks to write locks and the whole purpose here is calling
180 * iomR3MMIOStatsCreate.
181 */
182DECLINLINE(PIOMMMIOSTATS) iomMmioGetStats(PVM pVM, PVMCPU pVCpu, RTGCPHYS GCPhys, PIOMMMIORANGE pRange)
183{
184 Assert(IOM_IS_SHARED_LOCK_OWNER(pVM));
185
186 /* For large ranges, we'll put everything on the first byte. */
187 if (pRange->cb > PAGE_SIZE)
188 GCPhys = pRange->GCPhys;
189
190 PIOMMMIOSTATS pStats = pVCpu->iom.s.CTX_SUFF(pMMIOStatsLast);
191 if ( !pStats
192 || pStats->Core.Key != GCPhys)
193 {
194 pStats = (PIOMMMIOSTATS)RTAvloGCPhysGet(&pVM->iom.s.CTX_SUFF(pTrees)->MmioStatTree, GCPhys);
195# ifdef IN_RING3
196 if (!pStats)
197 {
198 IOM_UNLOCK_SHARED(pVM);
199 return iomR3MMIOStatsCreate(pVM, GCPhys, pRange->pszDesc);
200 }
201# endif
202 }
203
204 IOM_UNLOCK_SHARED(pVM);
205 return pStats;
206}
207#endif /* VBOX_WITH_STATISTICS */
208
209
210/** @} */
211
212#endif
213
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