VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR0/PDMR0DevHlpTracing.cpp@ 86070

Last change on this file since 86070 was 86070, checked in by vboxsync, 4 years ago

AMD IOMMU: bugref:9654 Fix accidentally not copying/initialize MSIMSG values. Fix using the translated memory address on
successful translations from the IOMMU. Fix not remapping any interrupt when IOMMU code is compiled but an IOMMU is not present.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 20.2 KB
Line 
1/* $Id: PDMR0DevHlpTracing.cpp 86070 2020-09-09 09:50:01Z vboxsync $ */
2/** @file
3 * PDM - Pluggable Device and Driver Manager, Device Helper variants when tracing is enabled.
4 */
5
6/*
7 * Copyright (C) 2020 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 Ring-0 Device Helpers
53 * @{
54 */
55
56
57static DECLCALLBACK(VBOXSTRICTRC) pdmR0DevHlpTracing_IoPortNewIn(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t *pu32, unsigned cb)
58{
59 PCPDMDEVINSDBGFTRACK pTrack = (PCPDMDEVINSDBGFTRACK)pvUser;
60
61 Assert(!pTrack->fMmio);
62 PGVM pGVM = pDevIns->Internal.s.pGVM;
63 VBOXSTRICTRC rcStrict = pTrack->u.IoPort.pfnIn(pDevIns, pTrack->pvUser, offPort, pu32, cb);
64 if (RT_SUCCESS(rcStrict))
65 DBGFTracerEvtIoPortRead(pGVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, pTrack->u.IoPort.hIoPorts, offPort, pu32, cb);
66
67 return rcStrict;
68}
69
70
71static DECLCALLBACK(VBOXSTRICTRC) pdmR0DevHlpTracing_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 PGVM pGVM = pDevIns->Internal.s.pGVM;
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(pGVM, 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) pdmR0DevHlpTracing_IoPortNewOut(PPDMDEVINS pDevIns, void *pvUser, RTIOPORT offPort, uint32_t u32, unsigned cb)
89{
90 PCPDMDEVINSDBGFTRACK pTrack = (PCPDMDEVINSDBGFTRACK)pvUser;
91
92 Assert(!pTrack->fMmio);
93 PGVM pGVM = pDevIns->Internal.s.pGVM;
94 VBOXSTRICTRC rcStrict = pTrack->u.IoPort.pfnOut(pDevIns, pTrack->pvUser, offPort, u32, cb);
95 if (RT_SUCCESS(rcStrict))
96 DBGFTracerEvtIoPortWrite(pGVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, pTrack->u.IoPort.hIoPorts, offPort, &u32, cb);
97
98 return rcStrict;
99}
100
101
102static DECLCALLBACK(VBOXSTRICTRC) pdmR0DevHlpTracing_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 PGVM pGVM = pDevIns->Internal.s.pGVM;
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(pGVM, 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) pdmR0DevHlpTracing_MmioRead(PPDMDEVINS pDevIns, void *pvUser, RTGCPHYS off, void *pv, uint32_t cb)
120{
121 PCPDMDEVINSDBGFTRACK pTrack = (PCPDMDEVINSDBGFTRACK)pvUser;
122
123 Assert(pTrack->fMmio);
124 PGVM pGVM = pDevIns->Internal.s.pGVM;
125 VBOXSTRICTRC rcStrict = pTrack->u.Mmio.pfnRead(pDevIns, pTrack->pvUser, off, pv, cb);
126 if (RT_SUCCESS(rcStrict))
127 DBGFTracerEvtMmioRead(pGVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, pTrack->u.Mmio.hMmioRegion, off, pv, cb);
128
129 return rcStrict;
130}
131
132
133static DECLCALLBACK(VBOXSTRICTRC) pdmR0DevHlpTracing_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 PGVM pGVM = pDevIns->Internal.s.pGVM;
139 VBOXSTRICTRC rcStrict = pTrack->u.Mmio.pfnWrite(pDevIns, pTrack->pvUser, off, pv, cb);
140 if (RT_SUCCESS(rcStrict))
141 DBGFTracerEvtMmioWrite(pGVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, pTrack->u.Mmio.hMmioRegion, off, pv, cb);
142
143 return rcStrict;
144}
145
146
147static DECLCALLBACK(VBOXSTRICTRC) pdmR0DevHlpTracing_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 PGVM pGVM = pDevIns->Internal.s.pGVM;
154 VBOXSTRICTRC rcStrict = pTrack->u.Mmio.pfnFill(pDevIns, pTrack->pvUser, off, u32Item, cbItem, cItems);
155 if (RT_SUCCESS(rcStrict))
156 DBGFTracerEvtMmioFill(pGVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, pTrack->u.Mmio.hMmioRegion, off,
157 u32Item, cbItem, cItems);
158
159 return rcStrict;
160}
161
162
163/** @interface_method_impl{PDMDEVHLPR0,pfnIoPortSetUpContextEx} */
164DECL_HIDDEN_CALLBACK(int)
165pdmR0DevHlpTracing_IoPortSetUpContextEx(PPDMDEVINS pDevIns, IOMIOPORTHANDLE hIoPorts,
166 PFNIOMIOPORTNEWOUT pfnOut, PFNIOMIOPORTNEWIN pfnIn,
167 PFNIOMIOPORTNEWOUTSTRING pfnOutStr, PFNIOMIOPORTNEWINSTRING pfnInStr, void *pvUser)
168{
169 PDMDEV_ASSERT_DEVINS(pDevIns);
170 LogFlow(("pdmR0DevHlp_IoPortSetUpContextEx: caller='%s'/%d: hIoPorts=%#x pfnOut=%p pfnIn=%p pfnOutStr=%p pfnInStr=%p pvUser=%p\n",
171 pDevIns->pReg->szName, pDevIns->iInstance, hIoPorts, pfnOut, pfnIn, pfnOutStr, pfnInStr, pvUser));
172 PGVM pGVM = pDevIns->Internal.s.pGVM;
173 VM_ASSERT_EMT0_RETURN(pGVM, VERR_VM_THREAD_NOT_EMT);
174 VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE);
175
176 int rc = VINF_SUCCESS;
177 if (pDevIns->Internal.s.idxDbgfTraceTrackNext < pDevIns->Internal.s.cDbgfTraceTrackMax)
178 {
179 PPDMDEVINSDBGFTRACK pTrack = &pDevIns->Internal.s.paDbgfTraceTrack[pDevIns->Internal.s.idxDbgfTraceTrackNext];
180 rc = IOMR0IoPortSetUpContext(pGVM, pDevIns, hIoPorts,
181 pfnOut ? pdmR0DevHlpTracing_IoPortNewOut : NULL,
182 pfnIn ? pdmR0DevHlpTracing_IoPortNewIn : NULL,
183 pfnOutStr ? pdmR0DevHlpTracing_IoPortNewOutStr : NULL,
184 pfnInStr ? pdmR0DevHlpTracing_IoPortNewInStr : NULL,
185 pTrack);
186 if (RT_SUCCESS(rc))
187 {
188 pTrack->fMmio = false;
189 pTrack->pvUser = pvUser;
190 pTrack->u.IoPort.hIoPorts = hIoPorts;
191 pTrack->u.IoPort.pfnOut = pfnOut;
192 pTrack->u.IoPort.pfnIn = pfnIn;
193 pTrack->u.IoPort.pfnOutStr = pfnOutStr;
194 pTrack->u.IoPort.pfnInStr = pfnInStr;
195 pDevIns->Internal.s.idxDbgfTraceTrackNext++;
196 }
197 }
198 else
199 rc = VERR_OUT_OF_RESOURCES;
200
201 LogFlow(("pdmR0DevHlp_IoPortSetUpContextEx: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
202 return rc;
203}
204
205
206/** @interface_method_impl{PDMDEVHLPR0,pfnMmioSetUpContextEx} */
207DECL_HIDDEN_CALLBACK(int)
208pdmR0DevHlpTracing_MmioSetUpContextEx(PPDMDEVINS pDevIns, IOMMMIOHANDLE hRegion, PFNIOMMMIONEWWRITE pfnWrite,
209 PFNIOMMMIONEWREAD pfnRead, PFNIOMMMIONEWFILL pfnFill, void *pvUser)
210{
211 PDMDEV_ASSERT_DEVINS(pDevIns);
212 LogFlow(("pdmR0DevHlp_MmioSetUpContextEx: caller='%s'/%d: hRegion=%#x pfnWrite=%p pfnRead=%p pfnFill=%p pvUser=%p\n",
213 pDevIns->pReg->szName, pDevIns->iInstance, hRegion, pfnWrite, pfnRead, pfnFill, pvUser));
214 PGVM pGVM = pDevIns->Internal.s.pGVM;
215 VM_ASSERT_EMT0_RETURN(pGVM, VERR_VM_THREAD_NOT_EMT);
216 VM_ASSERT_STATE_RETURN(pGVM, VMSTATE_CREATING, VERR_VM_INVALID_VM_STATE);
217
218 int rc = VINF_SUCCESS;
219 if (pDevIns->Internal.s.idxDbgfTraceTrackNext < pDevIns->Internal.s.cDbgfTraceTrackMax)
220 {
221 PPDMDEVINSDBGFTRACK pTrack = &pDevIns->Internal.s.paDbgfTraceTrack[pDevIns->Internal.s.idxDbgfTraceTrackNext];
222
223 rc = IOMR0MmioSetUpContext(pGVM, pDevIns, hRegion,
224 pfnWrite ? pdmR0DevHlpTracing_MmioWrite : NULL,
225 pfnRead ? pdmR0DevHlpTracing_MmioRead : NULL,
226 pfnFill ? pdmR0DevHlpTracing_MmioFill : NULL,
227 pTrack);
228 if (RT_SUCCESS(rc))
229 {
230 pTrack->fMmio = true;
231 pTrack->pvUser = pvUser;
232 pTrack->u.Mmio.hMmioRegion = hRegion;
233 pTrack->u.Mmio.pfnWrite = pfnWrite;
234 pTrack->u.Mmio.pfnRead = pfnRead;
235 pTrack->u.Mmio.pfnFill = pfnFill;
236 pDevIns->Internal.s.idxDbgfTraceTrackNext++;
237 }
238 }
239 else
240 rc = VERR_OUT_OF_RESOURCES;
241
242 LogFlow(("pdmR0DevHlp_MmioSetUpContextEx: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
243 return rc;
244}
245
246
247/** @interface_method_impl{PDMDEVHLPR0,pfnPhysRead} */
248DECL_HIDDEN_CALLBACK(int)
249pdmR0DevHlpTracing_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead, uint32_t fFlags)
250{
251 RT_NOREF(fFlags);
252
253 PDMDEV_ASSERT_DEVINS(pDevIns);
254 LogFlow(("pdmR0DevHlp_PhysRead: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbRead=%#x\n",
255 pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
256
257 VBOXSTRICTRC rcStrict = PGMPhysRead(pDevIns->Internal.s.pGVM, GCPhys, pvBuf, cbRead, PGMACCESSORIGIN_DEVICE);
258 AssertMsg(rcStrict == VINF_SUCCESS, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); /** @todo track down the users for this bugger. */
259
260 if (!(fFlags & PDM_DEVHLP_PHYS_RW_F_DATA_USER))
261 DBGFTracerEvtGCPhysRead(pDevIns->Internal.s.pGVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, GCPhys, pvBuf, cbRead);
262
263 Log(("pdmR0DevHlp_PhysRead: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, VBOXSTRICTRC_VAL(rcStrict) ));
264 return VBOXSTRICTRC_VAL(rcStrict);
265}
266
267
268/** @interface_method_impl{PDMDEVHLPR0,pfnPhysWrite} */
269DECL_HIDDEN_CALLBACK(int)
270pdmR0DevHlpTracing_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, uint32_t fFlags)
271{
272 RT_NOREF(fFlags);
273
274 PDMDEV_ASSERT_DEVINS(pDevIns);
275 LogFlow(("pdmR0DevHlp_PhysWrite: caller=%p/%d: GCPhys=%RGp pvBuf=%p cbWrite=%#x\n",
276 pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
277
278 VBOXSTRICTRC rcStrict = PGMPhysWrite(pDevIns->Internal.s.pGVM, GCPhys, pvBuf, cbWrite, PGMACCESSORIGIN_DEVICE);
279 AssertMsg(rcStrict == VINF_SUCCESS, ("%Rrc\n", VBOXSTRICTRC_VAL(rcStrict))); /** @todo track down the users for this bugger. */
280
281 if (!(fFlags & PDM_DEVHLP_PHYS_RW_F_DATA_USER))
282 DBGFTracerEvtGCPhysWrite(pDevIns->Internal.s.pGVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, GCPhys, pvBuf, cbWrite);
283
284 Log(("pdmR0DevHlp_PhysWrite: caller=%p/%d: returns %Rrc\n", pDevIns, pDevIns->iInstance, VBOXSTRICTRC_VAL(rcStrict) ));
285 return VBOXSTRICTRC_VAL(rcStrict);
286}
287
288
289/** @interface_method_impl{PDMDEVHLPR0,pfnPCIPhysRead} */
290DECL_HIDDEN_CALLBACK(int)
291pdmR0DevHlpTracing_PCIPhysRead(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead, uint32_t fFlags)
292{
293 PDMDEV_ASSERT_DEVINS(pDevIns);
294 if (!pPciDev) /* NULL is an alias for the default PCI device. */
295 pPciDev = pDevIns->apPciDevs[0];
296 AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
297 PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
298
299#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
300 /*
301 * Just check the busmaster setting here and forward the request to the generic read helper.
302 */
303 if (PCIDevIsBusmaster(pPciDev))
304 { /* likely */ }
305 else
306 {
307 Log(("pdmRCDevHlp_PCIPhysRead: caller=%p/%d: returns %Rrc - Not bus master! GCPhys=%RGp cbRead=%#zx\n",
308 pDevIns, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, GCPhys, cbRead));
309 memset(pvBuf, 0xff, cbRead);
310 return VERR_PDM_NOT_PCI_BUS_MASTER;
311 }
312#endif
313
314#ifdef VBOX_WITH_IOMMU_AMD
315 /** @todo IOMMU: Optimize/re-organize things here later. */
316 PGVM pGVM = pDevIns->Internal.s.pGVM;
317 PPDMIOMMUR0 pIommu = &pGVM->pdmr0.s.aIommus[0];
318 PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
319 if ( pDevInsIommu
320 && pDevInsIommu != pDevIns)
321 {
322 size_t const idxBus = pPciDev->Int.s.idxPdmBus;
323 Assert(idxBus < RT_ELEMENTS(pGVM->pdmr0.s.aPciBuses));
324 PPDMPCIBUSR0 pBus = &pGVM->pdmr0.s.aPciBuses[idxBus];
325
326 RTGCPHYS GCPhysOut;
327 uint16_t const uDeviceId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
328 int rc = pIommu->pfnMemRead(pDevInsIommu, uDeviceId, GCPhys, cbRead, &GCPhysOut);
329 if (RT_SUCCESS(rc))
330 GCPhys = GCPhysOut;
331 else
332 {
333 Log(("pdmR0DevHlp_PCIPhysRead: IOMMU translation failed. uDeviceId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDeviceId,
334 GCPhys, cbRead, rc));
335 return rc;
336 }
337 }
338#endif
339
340 return pDevIns->pHlpR0->pfnPhysRead(pDevIns, GCPhys, pvBuf, cbRead, fFlags);
341}
342
343
344/** @interface_method_impl{PDMDEVHLPR0,pfnPCIPhysWrite} */
345DECL_HIDDEN_CALLBACK(int)
346pdmR0DevHlpTracing_PCIPhysWrite(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite, uint32_t fFlags)
347{
348 PDMDEV_ASSERT_DEVINS(pDevIns);
349 if (!pPciDev) /* NULL is an alias for the default PCI device. */
350 pPciDev = pDevIns->apPciDevs[0];
351 AssertReturn(pPciDev, VERR_PDM_NOT_PCI_DEVICE);
352 PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
353
354#ifndef PDM_DO_NOT_RESPECT_PCI_BM_BIT
355 /*
356 * Just check the busmaster setting here and forward the request to the generic read helper.
357 */
358 if (PCIDevIsBusmaster(pPciDev))
359 { /* likely */ }
360 else
361 {
362 Log(("pdmRCDevHlp_PCIPhysWrite: caller=%p/%d: returns %Rrc - Not bus master! GCPhys=%RGp cbWrite=%#zx\n",
363 pDevIns, pDevIns->iInstance, VERR_PDM_NOT_PCI_BUS_MASTER, GCPhys, cbWrite));
364 return VERR_PDM_NOT_PCI_BUS_MASTER;
365 }
366#endif
367
368#ifdef VBOX_WITH_IOMMU_AMD
369 /** @todo IOMMU: Optimize/re-organize things here later. */
370 PGVM pGVM = pDevIns->Internal.s.pGVM;
371 PPDMIOMMUR0 pIommu = &pGVM->pdmr0.s.aIommus[0];
372 PPDMDEVINS pDevInsIommu = pIommu->CTX_SUFF(pDevIns);
373 if ( pDevInsIommu
374 && pDevInsIommu != pDevIns)
375 {
376 size_t const idxBus = pPciDev->Int.s.idxPdmBus;
377 Assert(idxBus < RT_ELEMENTS(pGVM->pdmr0.s.aPciBuses));
378 PPDMPCIBUSR0 pBus = &pGVM->pdmr0.s.aPciBuses[idxBus];
379
380 RTGCPHYS GCPhysOut;
381 uint16_t const uDeviceId = PCIBDF_MAKE(pBus->iBus, pPciDev->uDevFn);
382 int rc = pIommu->pfnMemWrite(pDevInsIommu, uDeviceId, GCPhys, cbWrite, &GCPhysOut);
383 if (RT_SUCCESS(rc))
384 GCPhys = GCPhysOut;
385 else
386 {
387 Log(("pdmR0DevHlp_PCIPhysWrite: IOMMU translation failed. uDeviceId=%#x GCPhys=%#RGp cb=%u rc=%Rrc\n", uDeviceId,
388 GCPhys, cbWrite, rc));
389 return rc;
390 }
391 }
392#endif
393
394 return pDevIns->pHlpR0->pfnPhysWrite(pDevIns, GCPhys, pvBuf, cbWrite, fFlags);
395}
396
397
398/** @interface_method_impl{PDMDEVHLPR0,pfnPCISetIrq} */
399DECL_HIDDEN_CALLBACK(void) pdmR0DevHlpTracing_PCISetIrq(PPDMDEVINS pDevIns, PPDMPCIDEV pPciDev, int iIrq, int iLevel)
400{
401 PDMDEV_ASSERT_DEVINS(pDevIns);
402 if (!pPciDev) /* NULL is an alias for the default PCI device. */
403 pPciDev = pDevIns->apPciDevs[0];
404 AssertReturnVoid(pPciDev);
405 LogFlow(("pdmR0DevHlpTracing_PCISetIrq: caller=%p/%d: pPciDev=%p:{%#x} iIrq=%d iLevel=%d\n",
406 pDevIns, pDevIns->iInstance, pPciDev, pPciDev->uDevFn, iIrq, iLevel));
407 PDMPCIDEV_ASSERT_VALID_AND_REGISTERED(pDevIns, pPciDev);
408
409 PGVM pGVM = pDevIns->Internal.s.pGVM;
410 size_t const idxBus = pPciDev->Int.s.idxPdmBus;
411 AssertReturnVoid(idxBus < RT_ELEMENTS(pGVM->pdmr0.s.aPciBuses));
412 PPDMPCIBUSR0 pPciBusR0 = &pGVM->pdmr0.s.aPciBuses[idxBus];
413
414 DBGFTracerEvtIrq(pGVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, iIrq, iLevel);
415
416 pdmLock(pGVM);
417
418 uint32_t uTagSrc;
419 if (iLevel & PDM_IRQ_LEVEL_HIGH)
420 {
421 pDevIns->Internal.s.pIntR3R0->uLastIrqTag = uTagSrc = pdmCalcIrqTag(pGVM, pDevIns->Internal.s.pInsR3R0->idTracing);
422 if (iLevel == PDM_IRQ_LEVEL_HIGH)
423 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pGVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
424 else
425 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pGVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
426 }
427 else
428 uTagSrc = pDevIns->Internal.s.pIntR3R0->uLastIrqTag;
429
430 if (pPciBusR0->pDevInsR0)
431 {
432 pPciBusR0->pfnSetIrqR0(pPciBusR0->pDevInsR0, pPciDev, iIrq, iLevel, uTagSrc);
433
434 pdmUnlock(pGVM);
435
436 if (iLevel == PDM_IRQ_LEVEL_LOW)
437 VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pGVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
438 }
439 else
440 {
441 pdmUnlock(pGVM);
442
443 /* queue for ring-3 execution. */
444 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pGVM->pdm.s.pDevHlpQueueR0);
445 AssertReturnVoid(pTask);
446
447 pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
448 pTask->pDevInsR3 = PDMDEVINS_2_R3PTR(pDevIns);
449 pTask->u.PciSetIRQ.iIrq = iIrq;
450 pTask->u.PciSetIRQ.iLevel = iLevel;
451 pTask->u.PciSetIRQ.uTagSrc = uTagSrc;
452 pTask->u.PciSetIRQ.pPciDevR3 = MMHyperR0ToR3(pGVM, pPciDev);
453
454 PDMQueueInsertEx(pGVM->pdm.s.pDevHlpQueueR0, &pTask->Core, 0);
455 }
456
457 LogFlow(("pdmR0DevHlpTracing_PCISetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc));
458}
459
460
461/** @interface_method_impl{PDMDEVHLPR0,pfnISASetIrq} */
462DECL_HIDDEN_CALLBACK(void) pdmR0DevHlpTracing_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
463{
464 PDMDEV_ASSERT_DEVINS(pDevIns);
465 LogFlow(("pdmR0DevHlpTracing_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
466 PGVM pGVM = pDevIns->Internal.s.pGVM;
467
468 DBGFTracerEvtIrq(pGVM, pDevIns->Internal.s.hDbgfTraceEvtSrc, iIrq, iLevel);
469
470 pdmLock(pGVM);
471 uint32_t uTagSrc;
472 if (iLevel & PDM_IRQ_LEVEL_HIGH)
473 {
474 pDevIns->Internal.s.pIntR3R0->uLastIrqTag = uTagSrc = pdmCalcIrqTag(pGVM, pDevIns->Internal.s.pInsR3R0->idTracing);
475 if (iLevel == PDM_IRQ_LEVEL_HIGH)
476 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pGVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
477 else
478 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pGVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
479 }
480 else
481 uTagSrc = pDevIns->Internal.s.pIntR3R0->uLastIrqTag;
482
483 bool fRc = pdmR0IsaSetIrq(pGVM, iIrq, iLevel, uTagSrc);
484
485 if (iLevel == PDM_IRQ_LEVEL_LOW && fRc)
486 VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pGVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
487 pdmUnlock(pGVM);
488 LogFlow(("pdmR0DevHlpTracing_ISASetIrq: caller=%p/%d: returns void; uTagSrc=%#x\n", pDevIns, pDevIns->iInstance, uTagSrc));
489}
490
491
492/** @} */
493
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