VirtualBox

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

Last change on this file since 84459 was 84459, checked in by vboxsync, 5 years ago

VMM/PDM: DBGF even tracing integration, bugref:9210

Integrates the new DBGF event tracing framework into PDM
devices. The new CFGM key "TracingEnabled" for a device
instance enables tracing using DBGF. A special tracing variant
of the PDM device helper is provided.

Disabled by default for now, enable with VBOX_WITH_DBGF_TRACING

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