VirtualBox

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

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

*: scm --fix-header-guard-endif

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