VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR3/PDMDevHlpTracing.cpp@ 93554

Last change on this file since 93554 was 93554, checked in by vboxsync, 3 years ago

VMM: Changed PAGE_SIZE -> GUEST_PAGE_SIZE / HOST_PAGE_SIZE, PAGE_SHIFT -> GUEST_PAGE_SHIFT / HOST_PAGE_SHIFT, and PAGE_OFFSET_MASK -> GUEST_PAGE_OFFSET_MASK / HOST_PAGE_OFFSET_MASK. Also removed most usage of ASMMemIsZeroPage and ASMMemZeroPage since the host and guest page size doesn't need to be the same any more. Some work left to do in the page pool code. bugref:9898

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 23.9 KB
Line 
1/* $Id: PDMDevHlpTracing.cpp 93554 2022-02-02 22:57:02Z vboxsync $ */
2/** @file
3 * PDM - Pluggable Device and Driver Manager, Device Helper variants when tracing is enabled.
4 */
5
6/*
7 * Copyright (C) 2020-2022 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
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_PDM_DEVICE
23#define PDMPCIDEV_INCLUDE_PRIVATE /* Hack to get pdmpcidevint.h included at the right point. */
24#include "PDMInternal.h"
25#include <VBox/vmm/pdm.h>
26#include <VBox/vmm/mm.h>
27#include <VBox/vmm/hm.h>
28#include <VBox/vmm/pgm.h>
29#include <VBox/vmm/iom.h>
30#include <VBox/vmm/dbgf.h>
31#include <VBox/vmm/ssm.h>
32#include <VBox/vmm/vmapi.h>
33#include <VBox/vmm/vmm.h>
34#include <VBox/vmm/vmcc.h>
35
36#include <VBox/version.h>
37#include <VBox/log.h>
38#include <VBox/err.h>
39#include <iprt/asm.h>
40#include <iprt/assert.h>
41#include <iprt/ctype.h>
42#include <iprt/string.h>
43#include <iprt/thread.h>
44
45#include "dtrace/VBoxVMM.h"
46#include "PDMInline.h"
47
48
49/*********************************************************************************************************************************
50* Defined Constants And Macros *
51*********************************************************************************************************************************/
52/** @name R3 DevHlp
53 * @{
54 */
55
56
57static DECLCALLBACK(VBOXSTRICTRC) pdmR3DevHlpTracing_IoPortNewIn(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t *pu32, unsigned cb)
58{
59 PCPDMDEVINSDBGFTRACK pTrack = (PCPDMDEVINSDBGFTRACK)pvUser;
60
61 Assert(!pTrack->fMmio);
62 PVM pVM = pDevIns->Internal.s.pVMR3;
63 VBOXSTRICTRC rcStrict = pTrack->u.IoPort.pfnIn(pDevIns, pTrack->pvUser, offPort, pu32, cb);
64 if (RT_SUCCESS(rcStrict))
65 DBGFTracerEvtIoPortRead(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, pTrack->u.IoPort.hIoPorts, offPort, pu32, cb);
66
67 return rcStrict;
68}
69
70
71static DECLCALLBACK(VBOXSTRICTRC) pdmR3DevHlpTracing_IoPortNewInStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint8_t *pbDst,
72 uint32_t *pcTransfers, unsigned cb)
73{
74 PCPDMDEVINSDBGFTRACK pTrack = (PCPDMDEVINSDBGFTRACK)pvUser;
75
76 Assert(!pTrack->fMmio);
77 PVM pVM = pDevIns->Internal.s.pVMR3;
78 uint32_t cTransfersReq = *pcTransfers;
79 VBOXSTRICTRC rcStrict = pTrack->u.IoPort.pfnInStr(pDevIns, pTrack->pvUser, offPort, pbDst, pcTransfers, cb);
80 if (RT_SUCCESS(rcStrict))
81 DBGFTracerEvtIoPortReadStr(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, pTrack->u.IoPort.hIoPorts, offPort, pbDst, cb,
82 cTransfersReq, cTransfersReq - *pcTransfers);
83
84 return rcStrict;
85}
86
87
88static DECLCALLBACK(VBOXSTRICTRC) pdmR3DevHlpTracing_IoPortNewOut(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t u32, unsigned cb)
89{
90 PCPDMDEVINSDBGFTRACK pTrack = (PCPDMDEVINSDBGFTRACK)pvUser;
91
92 Assert(!pTrack->fMmio);
93 PVM pVM = pDevIns->Internal.s.pVMR3;
94 VBOXSTRICTRC rcStrict = pTrack->u.IoPort.pfnOut(pDevIns, pTrack->pvUser, offPort, u32, cb);
95 if (RT_SUCCESS(rcStrict))
96 DBGFTracerEvtIoPortWrite(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, pTrack->u.IoPort.hIoPorts, offPort, &u32, cb);
97
98 return rcStrict;
99}
100
101
102static DECLCALLBACK(VBOXSTRICTRC) pdmR3DevHlpTracing_IoPortNewOutStr(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, const uint8_t *pbSrc,
103 uint32_t *pcTransfers, unsigned cb)
104{
105 PCPDMDEVINSDBGFTRACK pTrack = (PCPDMDEVINSDBGFTRACK)pvUser;
106
107 Assert(!pTrack->fMmio);
108 PVM pVM = pDevIns->Internal.s.pVMR3;
109 uint32_t cTransfersReq = *pcTransfers;
110 VBOXSTRICTRC rcStrict = pTrack->u.IoPort.pfnOutStr(pDevIns, pTrack->pvUser, offPort, pbSrc, pcTransfers, cb);
111 if (RT_SUCCESS(rcStrict))
112 DBGFTracerEvtIoPortWriteStr(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, pTrack->u.IoPort.hIoPorts, offPort, pbSrc, cb,
113 cTransfersReq, cTransfersReq - *pcTransfers);
114
115 return rcStrict;
116}
117
118
119static DECLCALLBACK(VBOXSTRICTRC) pdmR3DevHlpTracing_MmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, uint32_t cb)
120{
121 PCPDMDEVINSDBGFTRACK pTrack = (PCPDMDEVINSDBGFTRACK)pvUser;
122
123 Assert(pTrack->fMmio);
124 PVM pVM = pDevIns->Internal.s.pVMR3;
125 VBOXSTRICTRC rcStrict = pTrack->u.Mmio.pfnRead(pDevIns, pTrack->pvUser, off, pv, cb);
126 if (RT_SUCCESS(rcStrict))
127 DBGFTracerEvtMmioRead(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, pTrack->u.Mmio.hMmioRegion, off, pv, cb);
128
129 return rcStrict;
130}
131
132
133static DECLCALLBACK(VBOXSTRICTRC) pdmR3DevHlpTracing_MmioWrite(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void const *pv, uint32_t cb)
134{
135 PCPDMDEVINSDBGFTRACK pTrack = (PCPDMDEVINSDBGFTRACK)pvUser;
136
137 Assert(pTrack->fMmio);
138 PVM pVM = pDevIns->Internal.s.pVMR3;
139 VBOXSTRICTRC rcStrict = pTrack->u.Mmio.pfnWrite(pDevIns, pTrack->pvUser, off, pv, cb);
140 if (RT_SUCCESS(rcStrict))
141 DBGFTracerEvtMmioWrite(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, pTrack->u.Mmio.hMmioRegion, off, pv, cb);
142
143 return rcStrict;
144}
145
146
147static DECLCALLBACK(VBOXSTRICTRC) pdmR3DevHlpTracing_MmioFill(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off,
148 uint32_t u32Item, uint32_t cbItem, uint32_t cItems)
149{
150 PCPDMDEVINSDBGFTRACK pTrack = (PCPDMDEVINSDBGFTRACK)pvUser;
151
152 Assert(pTrack->fMmio);
153 PVM pVM = pDevIns->Internal.s.pVMR3;
154 VBOXSTRICTRC rcStrict = pTrack->u.Mmio.pfnFill(pDevIns, pTrack->pvUser, off, u32Item, cbItem, cItems);
155 if (RT_SUCCESS(rcStrict))
156 DBGFTracerEvtMmioFill(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, pTrack->u.Mmio.hMmioRegion, off,
157 u32Item, cbItem, cItems);
158
159 return rcStrict;
160}
161
162
163/** @interface_method_impl{PDMDEVHLPR3,pfnIoPortCreateEx} */
164DECL_HIDDEN_CALLBACK(int)
165pdmR3DevHlpTracing_IoPortCreateEx(PPDMDEVINS pDevIns, RTIOPORT cPorts, uint32_t fFlags, PPDMPCIDEV pPciDev,
166 uint32_t iPciRegion, PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
167 PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr, RTR3PTR pvUser,
168 const char *pszDesc, PCIOMIOPORTDESC paExtDescs, PIOMIOPORTHANDLE phIoPorts)
169{
170 PDMDEV_ASSERT_DEVINS(pDevIns);
171 LogFlow(("pdmR3DevHlpTracing_IoPortCreateEx: caller='%s'/%d: cPorts=%#x fFlags=%#x pPciDev=%p iPciRegion=%#x pfnOut=%p pfnIn=%p pfnOutStr=%p pfnInStr=%p pvUser=%p pszDesc=%p:{%s} paExtDescs=%p phIoPorts=%p\n",
172 pDevIns->pReg->szName, pDevIns->iInstance, cPorts, fFlags, pPciDev, iPciRegion, pfnOut, pfnIn, pfnOutStr, pfnInStr,
173 pvUser, pszDesc, pszDesc, paExtDescs, phIoPorts));
174 PVM pVM = pDevIns->Internal.s.pVMR3;
175 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
176 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE);
177
178 int rc = VINF_SUCCESS;
179 if (pDevIns->Internal.s.idxDbgfTraceTrackNext < pDevIns->Internal.s.cDbgfTraceTrackMax)
180 {
181 PPDMDEVINSDBGFTRACK pTrack = &pDevIns->Internal.s.paDbgfTraceTrack[pDevIns->Internal.s.idxDbgfTraceTrackNext];
182
183 rc = IOMR3IoPortCreate(pVM, pDevIns, cPorts, fFlags, pPciDev, iPciRegion,
184 pfnOut ? pdmR3DevHlpTracing_IoPortNewOut : NULL,
185 pfnIn ? pdmR3DevHlpTracing_IoPortNewIn : NULL,
186 pfnOutStr ? pdmR3DevHlpTracing_IoPortNewOutStr : NULL,
187 pfnInStr ? pdmR3DevHlpTracing_IoPortNewInStr : NULL,
188 pTrack, pszDesc, paExtDescs, phIoPorts);
189 if (RT_SUCCESS(rc))
190 {
191 pTrack->fMmio = false;
192 pTrack->pvUser = pvUser;
193 pTrack->u.IoPort.hIoPorts = *phIoPorts;
194 pTrack->u.IoPort.pfnOut = pfnOut;
195 pTrack->u.IoPort.pfnIn = pfnIn;
196 pTrack->u.IoPort.pfnOutStr = pfnOutStr;
197 pTrack->u.IoPort.pfnInStr = pfnInStr;
198 pDevIns->Internal.s.idxDbgfTraceTrackNext++;
199 DBGFR3TracerEvtIoPortCreate(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, *phIoPorts, cPorts, fFlags, iPciRegion);
200 }
201 }
202 else
203 rc = VERR_OUT_OF_RESOURCES;
204
205 LogFlow(("pdmR3DevHlpTracing_IoPortCreateEx: caller='%s'/%d: returns %Rrc (*phIoPorts=%#x)\n",
206 pDevIns->pReg->szName, pDevIns->iInstance, rc, *phIoPorts));
207 return rc;
208}
209
210
211/** @interface_method_impl{PDMDEVHLPR3,pfnIoPortMap} */
212DECL_HIDDEN_CALLBACK(int) pdmR3DevHlpTracing_IoPortMap(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts, RTIOPORT Port)
213{
214 PDMDEV_ASSERT_DEVINS(pDevIns);
215 LogFlow(("pdmR3DevHlp_IoPortMap: caller='%s'/%d: hIoPorts=%#x Port=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance, hIoPorts, Port));
216 PVM pVM = pDevIns->Internal.s.pVMR3;
217 VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
218
219 int rc = IOMR3IoPortMap(pVM, pDevIns, hIoPorts, Port);
220 DBGFTracerEvtIoPortMap(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, hIoPorts, Port);
221
222 LogFlow(("pdmR3DevHlp_IoPortMap: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
223 return rc;
224}
225
226
227/** @interface_method_impl{PDMDEVHLPR3,pfnIoPortUnmap} */
228DECL_HIDDEN_CALLBACK(int) pdmR3DevHlpTracing_IoPortUnmap(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts)
229{
230 PDMDEV_ASSERT_DEVINS(pDevIns);
231 LogFlow(("pdmR3DevHlp_IoPortMap: caller='%s'/%d: hIoPorts=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance, hIoPorts));
232 PVM pVM = pDevIns->Internal.s.pVMR3;
233 VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
234
235 int rc = IOMR3IoPortUnmap(pVM, pDevIns, hIoPorts);
236 DBGFTracerEvtIoPortUnmap(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, hIoPorts);
237
238 LogFlow(("pdmR3DevHlp_IoPortMap: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
239 return rc;
240}
241
242
243/** @interface_method_impl{PDMDEVHLPR3,pfnMmioCreateEx} */
244DECL_HIDDEN_CALLBACK(int)
245pdmR3DevHlpTracing_MmioCreateEx(PPDMDEVINS pDevIns, RTGCPHYS cbRegion,
246 uint32_t fFlags, PPDMPCIDEV pPciDev, uint32_t iPciRegion,
247 PFNIOMMMIONEWWRITE pfnWrite, PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill,
248 void *pvUser, const char *pszDesc, PIOMMMIOHANDLE phRegion)
249{
250 PDMDEV_ASSERT_DEVINS(pDevIns);
251 LogFlow(("pdmR3DevHlp_MmioCreateEx: caller='%s'/%d: cbRegion=%#RGp fFlags=%#x pPciDev=%p iPciRegion=%#x pfnWrite=%p pfnRead=%p pfnFill=%p pvUser=%p pszDesc=%p:{%s} phRegion=%p\n",
252 pDevIns->pReg->szName, pDevIns->iInstance, cbRegion, fFlags, pPciDev, iPciRegion, pfnWrite, pfnRead, pfnFill, pvUser, pszDesc, pszDesc, phRegion));
253 PVM pVM = pDevIns->Internal.s.pVMR3;
254 VM_ASSERT_EMT0_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
255 VM_ASSERT_STATE_RETURN(pVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE);
256
257 /* HACK ALERT! Round the size up to page size. The PCI bus should do something similar before mapping it. */
258 /** @todo It's possible we need to do dummy MMIO fill-in of the PCI bus or
259 * guest adds more alignment to an region. */
260 cbRegion = RT_ALIGN_T(cbRegion, GUEST_PAGE_SIZE, RTGCPHYS);
261
262 int rc = VINF_SUCCESS;
263 if (pDevIns->Internal.s.idxDbgfTraceTrackNext < pDevIns->Internal.s.cDbgfTraceTrackMax)
264 {
265 PPDMDEVINSDBGFTRACK pTrack = &pDevIns->Internal.s.paDbgfTraceTrack[pDevIns->Internal.s.idxDbgfTraceTrackNext];
266
267 rc = IOMR3MmioCreate(pVM, pDevIns, cbRegion, fFlags, pPciDev, iPciRegion,
268 pfnWrite ? pdmR3DevHlpTracing_MmioWrite : NULL,
269 pfnRead ? pdmR3DevHlpTracing_MmioRead : NULL,
270 pfnFill ? pdmR3DevHlpTracing_MmioFill : NULL,
271 pTrack, pszDesc, phRegion);
272 if (RT_SUCCESS(rc))
273 {
274 pTrack->fMmio = true;
275 pTrack->pvUser = pvUser;
276 pTrack->u.Mmio.hMmioRegion = *phRegion;
277 pTrack->u.Mmio.pfnWrite = pfnWrite;
278 pTrack->u.Mmio.pfnRead = pfnRead;
279 pTrack->u.Mmio.pfnFill = pfnFill;
280 pDevIns->Internal.s.idxDbgfTraceTrackNext++;
281 DBGFR3TracerEvtMmioCreate(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, *phRegion, cbRegion, fFlags, iPciRegion);
282 }
283 }
284 else
285 rc = VERR_OUT_OF_RESOURCES;
286
287 LogFlow(("pdmR3DevHlp_MmioCreateEx: caller='%s'/%d: returns %Rrc (*phRegion=%#x)\n",
288 pDevIns->pReg->szName, pDevIns->iInstance, rc, *phRegion));
289 return rc;
290}
291
292
293/** @interface_method_impl{PDMDEVHLPR3,pfnMmioMap} */
294DECL_HIDDEN_CALLBACK(int) pdmR3DevHlpTracing_MmioMap(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, RTGCPHYS GCPhys)
295{
296 PDMDEV_ASSERT_DEVINS(pDevIns);
297 LogFlow(("pdmR3DevHlp_MmioMap: caller='%s'/%d: hRegion=%#x GCPhys=%#RGp\n", pDevIns->pReg->szName, pDevIns->iInstance, hRegion, GCPhys));
298 PVM pVM = pDevIns->Internal.s.pVMR3;
299 VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
300
301 int rc = IOMR3MmioMap(pVM, pDevIns, hRegion, GCPhys);
302 DBGFTracerEvtMmioMap(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, hRegion, GCPhys);
303
304 LogFlow(("pdmR3DevHlp_MmioMap: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
305 return rc;
306}
307
308
309/** @interface_method_impl{PDMDEVHLPR3,pfnMmioUnmap} */
310DECL_HIDDEN_CALLBACK(int) pdmR3DevHlpTracing_MmioUnmap(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion)
311{
312 PDMDEV_ASSERT_DEVINS(pDevIns);
313 LogFlow(("pdmR3DevHlp_MmioUnmap: caller='%s'/%d: hRegion=%#x\n", pDevIns->pReg->szName, pDevIns->iInstance, hRegion));
314 PVM pVM = pDevIns->Internal.s.pVMR3;
315 VM_ASSERT_EMT_RETURN(pVM, VERR_VM_THREAD_NOT_EMT);
316
317 int rc = IOMR3MmioUnmap(pVM, pDevIns, hRegion);
318 DBGFTracerEvtMmioUnmap(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, hRegion);
319
320 LogFlow(("pdmR3DevHlp_MmioUnmap: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
321 return rc;
322}
323
324
325/** @interface_method_impl{PDMDEVHLPR3,pfnPhysRead} */
326DECL_HIDDEN_CALLBACK(int)
327pdmR3DevHlpTracing_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead, uint32_t fFlags)
328{
329 RT_NOREF(fFlags);
330
331 PDMDEV_ASSERT_DEVINS(pDevIns);
332 PVM pVM = pDevIns->Internal.s.pVMR3;
333 LogFlow(("pdmR3DevHlp_PhysRead: caller='%s'/%d: GCPhys=%RGp pvBuf=%p cbRead=%#x\n",
334 pDevIns->pReg->szName, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
335
336#if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
337 if (!VM_IS_EMT(pVM))
338 {
339 char szNames[128];
340 uint32_t cLocks = PDMR3CritSectCountOwned(pVM, szNames, sizeof(szNames));
341 AssertMsg(cLocks == 0, ("cLocks=%u %s\n", cLocks, szNames));
342 }
343#endif
344
345 VBOXSTRICTRC rcStrict;
346 if (VM_IS_EMT(pVM))
347 rcStrict = PGMPhysRead(pVM, GCPhys, pvBuf, cbRead, PGMACCESSORIGIN_DEVICE);
348 else
349 rcStrict = PGMR3PhysReadExternal(pVM, GCPhys, pvBuf, cbRead, PGMACCESSORIGIN_DEVICE);
350 AssertMsg(rcStrict == VINF_SUCCESS, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); /** @todo track down the users for this bugger. */
351
352 if (!(fFlags & PDM_DEVHLP_PHYS_RW_F_DATA_USER))
353 DBGFTracerEvtGCPhysRead(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, GCPhys, pvBuf, cbRead);
354
355 Log(("pdmR3DevHlp_PhysRead: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VBOXSTRICTRC_VAL(rcStrict) ));
356 return VBOXSTRICTRC_VAL(rcStrict);
357}
358
359
360/** @interface_method_impl{PDMDEVHLPR3,pfnPhysWrite} */
361DECL_HIDDEN_CALLBACK(int)
362pdmR3DevHlpTracing_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, uint32_t fFlags)
363{
364 RT_NOREF(fFlags);
365
366 PDMDEV_ASSERT_DEVINS(pDevIns);
367 PVM pVM = pDevIns->Internal.s.pVMR3;
368 LogFlow(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: GCPhys=%RGp pvBuf=%p cbWrite=%#x\n",
369 pDevIns->pReg->szName, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
370
371#if defined(VBOX_STRICT) && defined(PDM_DEVHLP_DEADLOCK_DETECTION)
372 if (!VM_IS_EMT(pVM))
373 {
374 char szNames[128];
375 uint32_t cLocks = PDMR3CritSectCountOwned(pVM, szNames, sizeof(szNames));
376 AssertMsg(cLocks == 0, ("cLocks=%u %s\n", cLocks, szNames));
377 }
378#endif
379
380 VBOXSTRICTRC rcStrict;
381 if (VM_IS_EMT(pVM))
382 rcStrict = PGMPhysWrite(pVM, GCPhys, pvBuf, cbWrite, PGMACCESSORIGIN_DEVICE);
383 else
384 rcStrict = PGMR3PhysWriteExternal(pVM, GCPhys, pvBuf, cbWrite, PGMACCESSORIGIN_DEVICE);
385 AssertMsg(rcStrict == VINF_SUCCESS, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); /** @todo track down the users for this bugger. */
386
387 if (!(fFlags & PDM_DEVHLP_PHYS_RW_F_DATA_USER))
388 DBGFTracerEvtGCPhysWrite(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, GCPhys, pvBuf, cbWrite);
389
390 Log(("pdmR3DevHlp_PhysWrite: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, VBOXSTRICTRC_VAL(rcStrict) ));
391 return VBOXSTRICTRC_VAL(rcStrict);
392}
393
394
395/** @interface_method_impl{PDMDEVHLPR3,pfnPCIPhysRead} */
396DECL_HIDDEN_CALLBACK(int)
397pdmR3DevHlpTracing_PCIPhysRead(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead, uint32_t fFlags)
398{
399 PDMDEV_ASSERT_DEVINS(pDevIns);
400 if (!pPciDev) /* NULL is an alias for the default PCI device. */
401 pPciDev = pDevIns->apPciDevs[0];
402 AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
403 PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
404
405#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
406 /*
407 * Just check the busmaster setting here and forward the request to the generic read helper.
408 */
409 if (PCIDevIsBusmaster(pPciDev))
410 { /* likely */ }
411 else
412 {
413 LogFunc(("caller='%s'/%d: returns %Rrc - Not bus master! GCPhys=%RGp cbRead=%#zx\n", pDevIns->pReg->szName,
414 pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, GCPhys, cbRead));
415 memset(pvBuf, 0xff, cbRead);
416 return VERR_PDM_NOT_PCI_BUS_MASTER;
417 }
418#endif
419
420#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
421 int rc = pdmIommuMemAccessRead(pDevIns, pPciDev, GCPhys, pvBuf, cbRead, fFlags);
422 if ( rc == VERR_IOMMU_NOT_PRESENT
423 || rc == VERR_IOMMU_CANNOT_CALL_SELF)
424 { /* likely - ASSUMING most VMs won't be configured with an IOMMU. */ }
425 else
426 return rc;
427#endif
428
429 return pDevIns->pHlpR3->pfnPhysRead(pDevIns, GCPhys, pvBuf, cbRead, fFlags);
430}
431
432
433/** @interface_method_impl{PDMDEVHLPR3,pfnPCIPhysWrite} */
434DECL_HIDDEN_CALLBACK(int)
435pdmR3DevHlpTracing_PCIPhysWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, uint32_t fFlags)
436{
437 PDMDEV_ASSERT_DEVINS(pDevIns);
438 if (!pPciDev) /* NULL is an alias for the default PCI device. */
439 pPciDev = pDevIns->apPciDevs[0];
440 AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
441 PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
442
443#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
444 /*
445 * Just check the busmaster setting here and forward the request to the generic read helper.
446 */
447 if (PCIDevIsBusmaster(pPciDev))
448 { /* likely */ }
449 else
450 {
451 Log(("pdmR3DevHlp_PCIPhysWrite: caller='%s'/%d: returns %Rrc - Not bus master! GCPhys=%RGp cbWrite=%#zx\n",
452 pDevIns->pReg->szName, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, GCPhys, cbWrite));
453 return VERR_PDM_NOT_PCI_BUS_MASTER;
454 }
455#endif
456
457#if defined(VBOX_WITH_IOMMU_AMD) || defined(VBOX_WITH_IOMMU_INTEL)
458 int rc = pdmIommuMemAccessWrite(pDevIns, pPciDev, GCPhys, pvBuf, cbWrite, fFlags);
459 if ( rc == VERR_IOMMU_NOT_PRESENT
460 || rc == VERR_IOMMU_CANNOT_CALL_SELF)
461 { /* likely - ASSUMING most VMs won't be configured with an IOMMU. */ }
462 else
463 return rc;
464#endif
465
466 return pDevIns->pHlpR3->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite, fFlags);
467}
468
469
470/** @interface_method_impl{PDMDEVHLPR3,pfnPCISetIrq} */
471DECL_HIDDEN_CALLBACK(void) pdmR3DevHlpTracing_PCISetIrq(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel)
472{
473 PDMDEV_ASSERT_DEVINS(pDevIns);
474 if (!pPciDev) /* NULL is an alias for the default PCI device. */
475 pPciDev = pDevIns->apPciDevs[0];
476 AssertReturnVoid(pPciDev);
477 LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: pPciDev=%p:{%#x} iIrq=%d iLevel=%d\n",
478 pDevIns->pReg->szName, pDevIns->iInstance, pPciDev, pPciDev->uDevFn, iIrq, iLevel));
479 PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
480
481 /*
482 * Validate input.
483 */
484 Assert(iIrq == 0);
485 Assert((uint32_t)iLevel <= PDM_IRQ_LEVEL_FLIP_FLOP);
486
487 /*
488 * Must have a PCI device registered!
489 */
490 PVM pVM = pDevIns->Internal.s.pVMR3;
491 size_t const idxBus = pPciDev->Int.s.idxPdmBus;
492 AssertReturnVoid(idxBus < RT_ELEMENTS(pVM->pdm.s.aPciBuses));
493 PPDMPCIBUS pBus = &pVM->pdm.s.aPciBuses[idxBus];
494
495 DBGFTracerEvtIrq(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, iIrq, iLevel);
496
497 pdmLock(pVM);
498 uint32_t uTagSrc;
499 if (iLevel & PDM_IRQ_LEVEL_HIGH)
500 {
501 pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
502 if (iLevel == PDM_IRQ_LEVEL_HIGH)
503 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
504 else
505 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
506 }
507 else
508 uTagSrc = pDevIns->Internal.s.uLastIrqTag;
509
510 pBus->pfnSetIrqR3(pBus->pDevInsR3, pPciDev, iIrq, iLevel, uTagSrc);
511
512 if (iLevel == PDM_IRQ_LEVEL_LOW)
513 VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
514 pdmUnlock(pVM);
515
516 LogFlow(("pdmR3DevHlp_PCISetIrq: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
517}
518
519
520/** @interface_method_impl{PDMDEVHLPR3,pfnPCISetIrqNoWait} */
521DECL_HIDDEN_CALLBACK(void) pdmR3DevHlpTracing_PCISetIrqNoWait(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel)
522{
523 pdmR3DevHlpTracing_PCISetIrq(pDevIns, pPciDev, iIrq, iLevel);
524}
525
526
527/** @interface_method_impl{PDMDEVHLPR3,pfnISASetIrq} */
528DECL_HIDDEN_CALLBACK(void) pdmR3DevHlpTracing_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
529{
530 PDMDEV_ASSERT_DEVINS(pDevIns);
531 LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, iIrq, iLevel));
532
533 /*
534 * Validate input.
535 */
536 Assert(iIrq < 16);
537 Assert((uint32_t)iLevel <= PDM_IRQ_LEVEL_FLIP_FLOP);
538
539 PVM pVM = pDevIns->Internal.s.pVMR3;
540
541 DBGFTracerEvtIrq(pVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, iIrq, iLevel);
542
543 /*
544 * Do the job.
545 */
546 pdmLock(pVM);
547 uint32_t uTagSrc;
548 if (iLevel & PDM_IRQ_LEVEL_HIGH)
549 {
550 pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
551 if (iLevel == PDM_IRQ_LEVEL_HIGH)
552 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
553 else
554 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
555 }
556 else
557 uTagSrc = pDevIns->Internal.s.uLastIrqTag;
558
559 PDMIsaSetIrq(pVM, iIrq, iLevel, uTagSrc); /* (The API takes the lock recursively.) */
560
561 if (iLevel == PDM_IRQ_LEVEL_LOW)
562 VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
563 pdmUnlock(pVM);
564
565 LogFlow(("pdmR3DevHlp_ISASetIrq: caller='%s'/%d: returns void\n", pDevIns->pReg->szName, pDevIns->iInstance));
566}
567
568
569/** @interface_method_impl{PDMDEVHLPR3,pfnISASetIrqNoWait} */
570DECL_HIDDEN_CALLBACK(void) pdmR3DevHlpTracing_ISASetIrqNoWait(PPDMDEVINS pDevIns, int iIrq, int iLevel)
571{
572 pdmR3DevHlpTracing_ISASetIrq(pDevIns, iIrq, iLevel);
573}
574
575
576/** @} */
577
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