VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMAll/IEMAllMemRWTmpl.cpp.h@ 100829

Last change on this file since 100829 was 100826, checked in by vboxsync, 19 months ago

VMM/IEM: Started refactoring IEM_MC_MEM_MAP into type and access specific variant so we can more efficiently apply inlined code using the TLB. Converted a bunch of 8-bit accesses in the one-byte opcode map. bugref:10369

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.3 KB
Line 
1/* $Id: IEMAllMemRWTmpl.cpp.h 100826 2023-08-09 01:57:40Z vboxsync $ */
2/** @file
3 * IEM - Interpreted Execution Manager - R/W Memory Functions Template.
4 */
5
6/*
7 * Copyright (C) 2011-2023 Oracle and/or its affiliates.
8 *
9 * This file is part of VirtualBox base platform packages, as
10 * available from https://www.virtualbox.org.
11 *
12 * This program is free software; you can redistribute it and/or
13 * modify it under the terms of the GNU General Public License
14 * as published by the Free Software Foundation, in version 3 of the
15 * License.
16 *
17 * This program is distributed in the hope that it will be useful, but
18 * WITHOUT ANY WARRANTY; without even the implied warranty of
19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 * General Public License for more details.
21 *
22 * You should have received a copy of the GNU General Public License
23 * along with this program; if not, see <https://www.gnu.org/licenses>.
24 *
25 * SPDX-License-Identifier: GPL-3.0-only
26 */
27
28
29/* Check template parameters. */
30#ifndef TMPL_MEM_TYPE
31# error "TMPL_MEM_TYPE is undefined"
32#endif
33#ifndef TMPL_MEM_TYPE_ALIGN
34# define TMPL_MEM_TYPE_ALIGN (sizeof(TMPL_MEM_TYPE) - 1)
35#endif
36#ifndef TMPL_MEM_FN_SUFF
37# error "TMPL_MEM_FN_SUFF is undefined"
38#endif
39#ifndef TMPL_MEM_FMT_TYPE
40# error "TMPL_MEM_FMT_TYPE is undefined"
41#endif
42#ifndef TMPL_MEM_FMT_DESC
43# error "TMPL_MEM_FMT_DESC is undefined"
44#endif
45
46
47/**
48 * Standard fetch function.
49 *
50 * This is used by CImpl code, so it needs to be kept even when IEM_WITH_SETJMP
51 * is defined.
52 */
53VBOXSTRICTRC RT_CONCAT(iemMemFetchData,TMPL_MEM_FN_SUFF)(PVMCPUCC pVCpu, TMPL_MEM_TYPE *puDst,
54 uint8_t iSegReg, RTGCPTR GCPtrMem) RT_NOEXCEPT
55{
56 /* The lazy approach for now... */
57 TMPL_MEM_TYPE const *puSrc;
58 VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&puSrc, sizeof(*puSrc), iSegReg, GCPtrMem,
59 IEM_ACCESS_DATA_R, TMPL_MEM_TYPE_ALIGN);
60 if (rc == VINF_SUCCESS)
61 {
62 *puDst = *puSrc;
63 rc = iemMemCommitAndUnmap(pVCpu, (void *)puSrc, IEM_ACCESS_DATA_R);
64 Log9(("IEM RD " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, *puDst));
65 }
66 return rc;
67}
68
69
70#ifdef IEM_WITH_SETJMP
71/**
72 * Safe/fallback fetch function that longjmps on error.
73 */
74TMPL_MEM_TYPE
75RT_CONCAT3(iemMemFetchData,TMPL_MEM_FN_SUFF,SafeJmp)(PVMCPUCC pVCpu, uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
76{
77# if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
78 pVCpu->iem.s.DataTlb.cTlbSafeReadPath++;
79# endif
80 TMPL_MEM_TYPE const *puSrc = (TMPL_MEM_TYPE const *)iemMemMapJmp(pVCpu, sizeof(*puSrc), iSegReg, GCPtrMem,
81 IEM_ACCESS_DATA_R, TMPL_MEM_TYPE_ALIGN);
82 TMPL_MEM_TYPE const uRet = *puSrc;
83 iemMemCommitAndUnmapJmp(pVCpu, (void *)puSrc, IEM_ACCESS_DATA_R);
84 Log9(("IEM RD " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, uRet));
85 return uRet;
86}
87#endif /* IEM_WITH_SETJMP */
88
89
90
91/**
92 * Standard fetch function.
93 *
94 * This is used by CImpl code, so it needs to be kept even when IEM_WITH_SETJMP
95 * is defined.
96 */
97VBOXSTRICTRC RT_CONCAT(iemMemStoreData,TMPL_MEM_FN_SUFF)(PVMCPUCC pVCpu, uint8_t iSegReg, RTGCPTR GCPtrMem,
98 TMPL_MEM_TYPE uValue) RT_NOEXCEPT
99{
100 /* The lazy approach for now... */
101 TMPL_MEM_TYPE *puDst;
102 VBOXSTRICTRC rc = iemMemMap(pVCpu, (void **)&puDst, sizeof(*puDst), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W, TMPL_MEM_TYPE_ALIGN);
103 if (rc == VINF_SUCCESS)
104 {
105 *puDst = uValue;
106 rc = iemMemCommitAndUnmap(pVCpu, puDst, IEM_ACCESS_DATA_W);
107 Log8(("IEM WR " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, uValue));
108 }
109 return rc;
110}
111
112
113#ifdef IEM_WITH_SETJMP
114/**
115 * Stores a data byte, longjmp on error.
116 *
117 * @param pVCpu The cross context virtual CPU structure of the calling thread.
118 * @param iSegReg The index of the segment register to use for
119 * this access. The base and limits are checked.
120 * @param GCPtrMem The address of the guest memory.
121 * @param u8Value The value to store.
122 */
123void RT_CONCAT3(iemMemStoreData,TMPL_MEM_FN_SUFF,SafeJmp)(PVMCPUCC pVCpu, uint8_t iSegReg, RTGCPTR GCPtrMem,
124 TMPL_MEM_TYPE uValue) IEM_NOEXCEPT_MAY_LONGJMP
125{
126# if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
127 pVCpu->iem.s.DataTlb.cTlbSafeWritePath++;
128# endif
129 Log8(("IEM WR " TMPL_MEM_FMT_DESC " %d|%RGv: " TMPL_MEM_FMT_TYPE "\n", iSegReg, GCPtrMem, uValue));
130 TMPL_MEM_TYPE *puDst = (TMPL_MEM_TYPE *)iemMemMapJmp(pVCpu, sizeof(*puDst), iSegReg, GCPtrMem,
131 IEM_ACCESS_DATA_W, TMPL_MEM_TYPE_ALIGN);
132 *puDst = uValue;
133 iemMemCommitAndUnmapJmp(pVCpu, puDst, IEM_ACCESS_DATA_W);
134}
135#endif /* IEM_WITH_SETJMP */
136
137
138#ifdef IEM_WITH_SETJMP
139
140/**
141 * Maps a data buffer for read+write direct access (or via a bounce buffer),
142 * longjmp on error.
143 *
144 * @param pVCpu The cross context virtual CPU structure of the calling thread.
145 * @param pbUnmapInfo Pointer to unmap info variable.
146 * @param iSegReg The index of the segment register to use for
147 * this access. The base and limits are checked.
148 * @param GCPtrMem The address of the guest memory.
149 */
150TMPL_MEM_TYPE *
151RT_CONCAT3(iemMemMapData,TMPL_MEM_FN_SUFF,RwSafeJmp)(PVMCPUCC pVCpu, uint8_t *pbUnmapInfo,
152 uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
153{
154# if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
155 pVCpu->iem.s.DataTlb.cTlbSafeWritePath++;
156# endif
157 Log8(("IEM RW/map " TMPL_MEM_FMT_DESC " %d|%RGv\n", iSegReg, GCPtrMem));
158 *pbUnmapInfo = 1 | ((IEM_ACCESS_TYPE_READ | IEM_ACCESS_TYPE_WRITE) << 4); /* zero is for the TLB hit */
159 return (TMPL_MEM_TYPE *)iemMemMapJmp(pVCpu, sizeof(TMPL_MEM_TYPE), iSegReg, GCPtrMem, IEM_ACCESS_DATA_RW, TMPL_MEM_TYPE_ALIGN);
160}
161
162
163/**
164 * Maps a data buffer for writeonly direct access (or via a bounce buffer),
165 * longjmp on error.
166 *
167 * @param pVCpu The cross context virtual CPU structure of the calling thread.
168 * @param pbUnmapInfo Pointer to unmap info variable.
169 * @param iSegReg The index of the segment register to use for
170 * this access. The base and limits are checked.
171 * @param GCPtrMem The address of the guest memory.
172 */
173TMPL_MEM_TYPE *
174RT_CONCAT3(iemMemMapData,TMPL_MEM_FN_SUFF,WoSafeJmp)(PVMCPUCC pVCpu, uint8_t *pbUnmapInfo,
175 uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
176{
177# if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
178 pVCpu->iem.s.DataTlb.cTlbSafeWritePath++;
179# endif
180 Log8(("IEM WO/map " TMPL_MEM_FMT_DESC " %d|%RGv\n", iSegReg, GCPtrMem));
181 *pbUnmapInfo = 1 | (IEM_ACCESS_TYPE_WRITE << 4); /* zero is for the TLB hit */
182 return (TMPL_MEM_TYPE *)iemMemMapJmp(pVCpu, sizeof(TMPL_MEM_TYPE), iSegReg, GCPtrMem, IEM_ACCESS_DATA_W, TMPL_MEM_TYPE_ALIGN);
183}
184
185
186/**
187 * Maps a data buffer for readonly direct access (or via a bounce buffer),
188 * longjmp on error.
189 *
190 * @param pVCpu The cross context virtual CPU structure of the calling thread.
191 * @param pbUnmapInfo Pointer to unmap info variable.
192 * @param iSegReg The index of the segment register to use for
193 * this access. The base and limits are checked.
194 * @param GCPtrMem The address of the guest memory.
195 */
196TMPL_MEM_TYPE const *
197RT_CONCAT3(iemMemMapData,TMPL_MEM_FN_SUFF,RoSafeJmp)(PVMCPUCC pVCpu, uint8_t *pbUnmapInfo,
198 uint8_t iSegReg, RTGCPTR GCPtrMem) IEM_NOEXCEPT_MAY_LONGJMP
199{
200# if defined(IEM_WITH_DATA_TLB) && defined(IN_RING3)
201 pVCpu->iem.s.DataTlb.cTlbSafeWritePath++;
202# endif
203 Log8(("IEM WO/map " TMPL_MEM_FMT_DESC " %d|%RGv\n", iSegReg, GCPtrMem));
204 *pbUnmapInfo = 1 | (IEM_ACCESS_TYPE_READ << 4); /* zero is for the TLB hit */
205 return (TMPL_MEM_TYPE *)iemMemMapJmp(pVCpu, sizeof(TMPL_MEM_TYPE), iSegReg, GCPtrMem, IEM_ACCESS_DATA_R, TMPL_MEM_TYPE_ALIGN);
206}
207
208#endif /* IEM_WITH_SETJMP */
209
210
211/* clean up */
212#undef TMPL_MEM_TYPE
213#undef TMPL_MEM_TYPE_ALIGN
214#undef TMPL_MEM_FN_SUFF
215#undef TMPL_MEM_FMT_TYPE
216#undef TMPL_MEM_FMT_DESC
217
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