VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp@ 58591

Last change on this file since 58591 was 58116, checked in by vboxsync, 9 years ago

VMM: Doxygen fixes.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 26.2 KB
Line 
1/* $Id: PDMDevMiscHlp.cpp 58116 2015-10-08 14:51:53Z vboxsync $ */
2/** @file
3 * PDM - Pluggable Device and Driver Manager, Misc. Device Helpers.
4 */
5
6/*
7 * Copyright (C) 2006-2015 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#include "PDMInternal.h"
24#include <VBox/vmm/pdm.h>
25#include <VBox/vmm/pgm.h>
26#include <VBox/vmm/hm.h>
27#ifdef VBOX_WITH_REM
28# include <VBox/vmm/rem.h>
29#endif
30#include <VBox/vmm/vm.h>
31#include <VBox/vmm/vmm.h>
32
33#include <VBox/log.h>
34#include <VBox/err.h>
35#include <iprt/asm.h>
36#include <iprt/assert.h>
37#include <iprt/thread.h>
38
39
40#include "PDMInline.h"
41#include "dtrace/VBoxVMM.h"
42
43
44
45/** @name Ring-3 PIC Helpers
46 * @{
47 */
48
49/** @interface_method_impl{PDMPICHLPR3,pfnSetInterruptFF} */
50static DECLCALLBACK(void) pdmR3PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
51{
52 PDMDEV_ASSERT_DEVINS(pDevIns);
53 PVM pVM = pDevIns->Internal.s.pVMR3;
54
55 if (pVM->pdm.s.Apic.pfnLocalInterruptR3)
56 {
57 LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: Setting local interrupt on LAPIC\n",
58 pDevIns->pReg->szName, pDevIns->iInstance));
59 /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
60 pVM->pdm.s.Apic.pfnLocalInterruptR3(pVM->pdm.s.Apic.pDevInsR3, 0, 1);
61 return;
62 }
63
64 PVMCPU pVCpu = &pVM->aCpus[0]; /* for PIC we always deliver to CPU 0, MP use APIC */
65
66 LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_PIC %d -> 1\n",
67 pDevIns->pReg->szName, pDevIns->iInstance, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
68
69 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
70#ifdef VBOX_WITH_REM
71 REMR3NotifyInterruptSet(pVM, pVCpu);
72#endif
73 VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
74}
75
76
77/** @interface_method_impl{PDMPICHLPR3,pfnClearInterruptFF} */
78static DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
79{
80 PDMDEV_ASSERT_DEVINS(pDevIns);
81 PVM pVM = pDevIns->Internal.s.pVMR3;
82 PVMCPU pVCpu = &pVM->aCpus[0]; /* for PIC we always deliver to CPU 0, MP use APIC */
83
84 if (pVM->pdm.s.Apic.pfnLocalInterruptR3)
85 {
86 /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
87 LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
88 pDevIns->pReg->szName, pDevIns->iInstance));
89 /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
90 pVM->pdm.s.Apic.pfnLocalInterruptR3(pVM->pdm.s.Apic.pDevInsR3, 0, 0);
91 return;
92 }
93
94 LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
95 pDevIns->pReg->szName, pDevIns->iInstance, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
96
97 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
98#ifdef VBOX_WITH_REM
99 REMR3NotifyInterruptClear(pVM, pVCpu);
100#endif
101}
102
103
104/** @interface_method_impl{PDMPICHLPR3,pfnLock} */
105static DECLCALLBACK(int) pdmR3PicHlp_Lock(PPDMDEVINS pDevIns, int rc)
106{
107 PDMDEV_ASSERT_DEVINS(pDevIns);
108 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
109}
110
111
112/** @interface_method_impl{PDMPICHLPR3,pfnUnlock} */
113static DECLCALLBACK(void) pdmR3PicHlp_Unlock(PPDMDEVINS pDevIns)
114{
115 PDMDEV_ASSERT_DEVINS(pDevIns);
116 pdmUnlock(pDevIns->Internal.s.pVMR3);
117}
118
119
120/** @interface_method_impl{PDMPICHLPR3,pfnGetRCHelpers} */
121static DECLCALLBACK(PCPDMPICHLPRC) pdmR3PicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
122{
123 PDMDEV_ASSERT_DEVINS(pDevIns);
124 PVM pVM = pDevIns->Internal.s.pVMR3;
125 VM_ASSERT_EMT(pVM);
126
127 RTRCPTR pRCHelpers = NIL_RTRCPTR;
128 if (!HMIsEnabled(pVM))
129 {
130 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCPicHlp", &pRCHelpers);
131 AssertReleaseRC(rc);
132 AssertRelease(pRCHelpers);
133 }
134
135 LogFlow(("pdmR3PicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
136 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
137 return pRCHelpers;
138}
139
140
141/** @interface_method_impl{PDMPICHLPR3,pfnGetR0Helpers} */
142static DECLCALLBACK(PCPDMPICHLPR0) pdmR3PicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
143{
144 PDMDEV_ASSERT_DEVINS(pDevIns);
145 PVM pVM = pDevIns->Internal.s.pVMR3;
146 VM_ASSERT_EMT(pVM);
147 PCPDMPICHLPR0 pR0Helpers = 0;
148 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0PicHlp", &pR0Helpers);
149 AssertReleaseRC(rc);
150 AssertRelease(pR0Helpers);
151 LogFlow(("pdmR3PicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
152 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
153 return pR0Helpers;
154}
155
156
157/**
158 * PIC Device Helpers.
159 */
160const PDMPICHLPR3 g_pdmR3DevPicHlp =
161{
162 PDM_PICHLPR3_VERSION,
163 pdmR3PicHlp_SetInterruptFF,
164 pdmR3PicHlp_ClearInterruptFF,
165 pdmR3PicHlp_Lock,
166 pdmR3PicHlp_Unlock,
167 pdmR3PicHlp_GetRCHelpers,
168 pdmR3PicHlp_GetR0Helpers,
169 PDM_PICHLPR3_VERSION /* the end */
170};
171
172/** @} */
173
174
175
176
177/** @name R3 APIC Helpers
178 * @{
179 */
180
181/** @interface_method_impl{PDMAPICHLPR3,pfnSetInterruptFF} */
182static DECLCALLBACK(void) pdmR3ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
183{
184 PDMDEV_ASSERT_DEVINS(pDevIns);
185 PVM pVM = pDevIns->Internal.s.pVMR3;
186 PVMCPU pVCpu = &pVM->aCpus[idCpu];
187
188 AssertReturnVoid(idCpu < pVM->cCpus);
189
190 LogFlow(("pdmR3ApicHlp_SetInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_APIC(%d) %d -> 1\n",
191 pDevIns->pReg->szName, pDevIns->iInstance, idCpu, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
192
193 switch (enmType)
194 {
195 case PDMAPICIRQ_HARDWARE:
196 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
197 break;
198 case PDMAPICIRQ_NMI:
199 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);
200 break;
201 case PDMAPICIRQ_SMI:
202 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
203 break;
204 case PDMAPICIRQ_EXTINT:
205 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
206 break;
207 default:
208 AssertMsgFailed(("enmType=%d\n", enmType));
209 break;
210 }
211#ifdef VBOX_WITH_REM
212 REMR3NotifyInterruptSet(pVM, pVCpu);
213#endif
214 VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
215}
216
217
218/** @interface_method_impl{PDMAPICHLPR3,pfnClearInterruptFF} */
219static DECLCALLBACK(void) pdmR3ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
220{
221 PDMDEV_ASSERT_DEVINS(pDevIns);
222 PVM pVM = pDevIns->Internal.s.pVMR3;
223 PVMCPU pVCpu = &pVM->aCpus[idCpu];
224
225 AssertReturnVoid(idCpu < pVM->cCpus);
226
227 LogFlow(("pdmR3ApicHlp_ClearInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_APIC(%d) %d -> 0\n",
228 pDevIns->pReg->szName, pDevIns->iInstance, idCpu, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
229
230 /* Note: NMI/SMI can't be cleared. */
231 switch (enmType)
232 {
233 case PDMAPICIRQ_HARDWARE:
234 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
235 break;
236 case PDMAPICIRQ_EXTINT:
237 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
238 break;
239 default:
240 AssertMsgFailed(("enmType=%d\n", enmType));
241 break;
242 }
243#ifdef VBOX_WITH_REM
244 REMR3NotifyInterruptClear(pVM, pVCpu);
245#endif
246}
247
248
249/** @interface_method_impl{PDMAPICHLPR3,pfnCalcIrqTag} */
250static DECLCALLBACK(uint32_t) pdmR3ApicHlp_CalcIrqTag(PPDMDEVINS pDevIns, uint8_t u8Level)
251{
252 PDMDEV_ASSERT_DEVINS(pDevIns);
253 PVM pVM = pDevIns->Internal.s.pVMR3;
254 Assert(u8Level == PDM_IRQ_LEVEL_HIGH || u8Level == PDM_IRQ_LEVEL_FLIP_FLOP);
255
256 pdmLock(pVM);
257
258 uint32_t uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
259 if (u8Level == PDM_IRQ_LEVEL_HIGH)
260 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
261 else
262 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
263
264
265 pdmUnlock(pVM);
266 LogFlow(("pdmR3ApicHlp_CalcIrqTag: caller='%s'/%d: returns %#x (u8Level=%d)\n",
267 pDevIns->pReg->szName, pDevIns->iInstance, uTagSrc, u8Level));
268 return uTagSrc;
269}
270
271
272/** @interface_method_impl{PDMAPICHLPR3,pfnChangeFeature} */
273static DECLCALLBACK(void) pdmR3ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion)
274{
275 PDMDEV_ASSERT_DEVINS(pDevIns);
276 LogFlow(("pdmR3ApicHlp_ChangeFeature: caller='%s'/%d: version=%d\n",
277 pDevIns->pReg->szName, pDevIns->iInstance, (int)enmVersion));
278 switch (enmVersion)
279 {
280 case PDMAPICVERSION_NONE:
281 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC);
282 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC);
283 break;
284 case PDMAPICVERSION_APIC:
285 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC);
286 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC);
287 break;
288 case PDMAPICVERSION_X2APIC:
289 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC);
290 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC);
291 break;
292 default:
293 AssertMsgFailed(("Unknown APIC version: %d\n", (int)enmVersion));
294 }
295}
296
297/** @interface_method_impl{PDMAPICHLPR3,pfnGetCpuId} */
298static DECLCALLBACK(VMCPUID) pdmR3ApicHlp_GetCpuId(PPDMDEVINS pDevIns)
299{
300 PDMDEV_ASSERT_DEVINS(pDevIns);
301 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
302 return VMMGetCpuId(pDevIns->Internal.s.pVMR3);
303}
304
305
306/** @interface_method_impl{PDMAPICHLPR3,pfnSendSipi} */
307static DECLCALLBACK(void) pdmR3ApicHlp_SendSipi(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t uVector)
308{
309 PDMDEV_ASSERT_DEVINS(pDevIns);
310 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
311 VMMR3SendSipi(pDevIns->Internal.s.pVMR3, idCpu, uVector);
312}
313
314
315/** @interface_method_impl{PDMAPICHLPR3,pfnSendInitIpi} */
316static DECLCALLBACK(void) pdmR3ApicHlp_SendInitIpi(PPDMDEVINS pDevIns, VMCPUID idCpu)
317{
318 PDMDEV_ASSERT_DEVINS(pDevIns);
319 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
320 VMMR3SendInitIpi(pDevIns->Internal.s.pVMR3, idCpu);
321}
322
323
324/** @interface_method_impl{PDMAPICHLPR3,pfnGetRCHelpers} */
325static DECLCALLBACK(PCPDMAPICHLPRC) pdmR3ApicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
326{
327 PDMDEV_ASSERT_DEVINS(pDevIns);
328 PVM pVM = pDevIns->Internal.s.pVMR3;
329 VM_ASSERT_EMT(pVM);
330
331 RTRCPTR pRCHelpers = NIL_RTRCPTR;
332 if (!HMIsEnabled(pVM))
333 {
334 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCApicHlp", &pRCHelpers);
335 AssertReleaseRC(rc);
336 AssertRelease(pRCHelpers);
337 }
338
339 LogFlow(("pdmR3ApicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
340 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
341 return pRCHelpers;
342}
343
344
345/** @interface_method_impl{PDMAPICHLPR3,pfnGetR0Helpers} */
346static DECLCALLBACK(PCPDMAPICHLPR0) pdmR3ApicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
347{
348 PDMDEV_ASSERT_DEVINS(pDevIns);
349 PVM pVM = pDevIns->Internal.s.pVMR3;
350 VM_ASSERT_EMT(pVM);
351 PCPDMAPICHLPR0 pR0Helpers = 0;
352 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0ApicHlp", &pR0Helpers);
353 AssertReleaseRC(rc);
354 AssertRelease(pR0Helpers);
355 LogFlow(("pdmR3ApicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
356 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
357 return pR0Helpers;
358}
359
360
361/** @interface_method_impl{PDMAPICHLPR3,pfnGetR3CritSect} */
362static DECLCALLBACK(R3PTRTYPE(PPDMCRITSECT)) pdmR3ApicHlp_GetR3CritSect(PPDMDEVINS pDevIns)
363{
364 PDMDEV_ASSERT_DEVINS(pDevIns);
365 LogFlow(("pdmR3ApicHlp_Lock: caller='%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
366 return &pDevIns->Internal.s.pVMR3->pdm.s.CritSect;
367}
368
369
370/** @interface_method_impl{PDMAPICHLPR3,pfnGetRCCritSect} */
371static DECLCALLBACK(RCPTRTYPE(PPDMCRITSECT)) pdmR3ApicHlp_GetRCCritSect(PPDMDEVINS pDevIns)
372{
373 PDMDEV_ASSERT_DEVINS(pDevIns);
374 PVM pVM = pDevIns->Internal.s.pVMR3;
375 RTRCPTR RCPtr = MMHyperCCToRC(pVM, &pVM->pdm.s.CritSect);
376 LogFlow(("pdmR3ApicHlp_GetR0CritSect: caller='%s'/%d: return %RRv\n", pDevIns->pReg->szName, pDevIns->iInstance, RCPtr));
377 return RCPtr;
378}
379
380
381/** @interface_method_impl{PDMAPICHLPR3,pfnGetR3CritSect} */
382static DECLCALLBACK(R0PTRTYPE(PPDMCRITSECT)) pdmR3ApicHlp_GetR0CritSect(PPDMDEVINS pDevIns)
383{
384 PDMDEV_ASSERT_DEVINS(pDevIns);
385 PVM pVM = pDevIns->Internal.s.pVMR3;
386 RTR0PTR R0Ptr = MMHyperCCToR0(pVM, &pVM->pdm.s.CritSect);
387 LogFlow(("pdmR3ApicHlp_GetR0CritSect: caller='%s'/%d: return %RHv\n", pDevIns->pReg->szName, pDevIns->iInstance, R0Ptr));
388 return R0Ptr;
389}
390
391
392
393/**
394 * APIC Device Helpers.
395 */
396const PDMAPICHLPR3 g_pdmR3DevApicHlp =
397{
398 PDM_APICHLPR3_VERSION,
399 pdmR3ApicHlp_SetInterruptFF,
400 pdmR3ApicHlp_ClearInterruptFF,
401 pdmR3ApicHlp_CalcIrqTag,
402 pdmR3ApicHlp_ChangeFeature,
403 pdmR3ApicHlp_GetCpuId,
404 pdmR3ApicHlp_SendSipi,
405 pdmR3ApicHlp_SendInitIpi,
406 pdmR3ApicHlp_GetRCHelpers,
407 pdmR3ApicHlp_GetR0Helpers,
408 pdmR3ApicHlp_GetR3CritSect,
409 pdmR3ApicHlp_GetRCCritSect,
410 pdmR3ApicHlp_GetR0CritSect,
411 PDM_APICHLPR3_VERSION /* the end */
412};
413
414/** @} */
415
416
417
418
419/** @name Ring-3 I/O APIC Helpers
420 * @{
421 */
422
423/** @interface_method_impl{PDMIOAPICHLPR3,pfnApicBusDeliver} */
424static DECLCALLBACK(int) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
425 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc)
426{
427 PDMDEV_ASSERT_DEVINS(pDevIns);
428 PVM pVM = pDevIns->Internal.s.pVMR3;
429 LogFlow(("pdmR3IoApicHlp_ApicBusDeliver: caller='%s'/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
430 pDevIns->pReg->szName, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc));
431 if (pVM->pdm.s.Apic.pfnBusDeliverR3)
432 return pVM->pdm.s.Apic.pfnBusDeliverR3(pVM->pdm.s.Apic.pDevInsR3, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc);
433 return VINF_SUCCESS;
434}
435
436
437/** @interface_method_impl{PDMIOAPICHLPR3,pfnLock} */
438static DECLCALLBACK(int) pdmR3IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
439{
440 PDMDEV_ASSERT_DEVINS(pDevIns);
441 LogFlow(("pdmR3IoApicHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
442 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
443}
444
445
446/** @interface_method_impl{PDMIOAPICHLPR3,pfnUnlock} */
447static DECLCALLBACK(void) pdmR3IoApicHlp_Unlock(PPDMDEVINS pDevIns)
448{
449 PDMDEV_ASSERT_DEVINS(pDevIns);
450 LogFlow(("pdmR3IoApicHlp_Unlock: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
451 pdmUnlock(pDevIns->Internal.s.pVMR3);
452}
453
454
455/** @interface_method_impl{PDMIOAPICHLPR3,pfnGetRCHelpers} */
456static DECLCALLBACK(PCPDMIOAPICHLPRC) pdmR3IoApicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
457{
458 PDMDEV_ASSERT_DEVINS(pDevIns);
459 PVM pVM = pDevIns->Internal.s.pVMR3;
460 VM_ASSERT_EMT(pVM);
461
462 RTRCPTR pRCHelpers = NIL_RTRCPTR;
463 if (!HMIsEnabled(pVM))
464 {
465 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCIoApicHlp", &pRCHelpers);
466 AssertReleaseRC(rc);
467 AssertRelease(pRCHelpers);
468 }
469
470 LogFlow(("pdmR3IoApicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
471 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
472 return pRCHelpers;
473}
474
475
476/** @interface_method_impl{PDMIOAPICHLPR3,pfnGetR0Helpers} */
477static DECLCALLBACK(PCPDMIOAPICHLPR0) pdmR3IoApicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
478{
479 PDMDEV_ASSERT_DEVINS(pDevIns);
480 PVM pVM = pDevIns->Internal.s.pVMR3;
481 VM_ASSERT_EMT(pVM);
482 PCPDMIOAPICHLPR0 pR0Helpers = 0;
483 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0IoApicHlp", &pR0Helpers);
484 AssertReleaseRC(rc);
485 AssertRelease(pR0Helpers);
486 LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
487 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
488 return pR0Helpers;
489}
490
491
492/**
493 * I/O APIC Device Helpers.
494 */
495const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp =
496{
497 PDM_IOAPICHLPR3_VERSION,
498 pdmR3IoApicHlp_ApicBusDeliver,
499 pdmR3IoApicHlp_Lock,
500 pdmR3IoApicHlp_Unlock,
501 pdmR3IoApicHlp_GetRCHelpers,
502 pdmR3IoApicHlp_GetR0Helpers,
503 PDM_IOAPICHLPR3_VERSION /* the end */
504};
505
506/** @} */
507
508
509
510
511/** @name Ring-3 PCI Bus Helpers
512 * @{
513 */
514
515/** @interface_method_impl{PDMPCIHLPR3,pfnIsaSetIrq} */
516static DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
517{
518 PDMDEV_ASSERT_DEVINS(pDevIns);
519 Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
520 PVM pVM = pDevIns->Internal.s.pVMR3;
521 PDMIsaSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel, uTagSrc);
522}
523
524/** @interface_method_impl{PDMPCIHLPR3,pfnIoApicSetIrq} */
525static DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
526{
527 PDMDEV_ASSERT_DEVINS(pDevIns);
528 Log4(("pdmR3PciHlp_IoApicSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
529 PDMIoApicSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel, uTagSrc);
530}
531
532/** @interface_method_impl{PDMPCIHLPR3,pfnIoApicSendMsi} */
533static DECLCALLBACK(void) pdmR3PciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc)
534{
535 PDMDEV_ASSERT_DEVINS(pDevIns);
536 Log4(("pdmR3PciHlp_IoApicSendMsi: address=%p value=%x uTagSrc=%#x\n", GCPhys, uValue, uTagSrc));
537 PDMIoApicSendMsi(pDevIns->Internal.s.pVMR3, GCPhys, uValue, uTagSrc);
538}
539
540/** @interface_method_impl{PDMPCIHLPR3,pfnIsMMIO2Base} */
541static DECLCALLBACK(bool) pdmR3PciHlp_IsMMIO2Base(PPDMDEVINS pDevIns, PPDMDEVINS pOwner, RTGCPHYS GCPhys)
542{
543 PDMDEV_ASSERT_DEVINS(pDevIns);
544 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
545 bool fRc = PGMR3PhysMMIO2IsBase(pDevIns->Internal.s.pVMR3, pOwner, GCPhys);
546 Log4(("pdmR3PciHlp_IsMMIO2Base: pOwner=%p GCPhys=%RGp -> %RTbool\n", pOwner, GCPhys, fRc));
547 return fRc;
548}
549
550
551/** @interface_method_impl{PDMPCIHLPR3,pfnLock} */
552static DECLCALLBACK(int) pdmR3PciHlp_Lock(PPDMDEVINS pDevIns, int rc)
553{
554 PDMDEV_ASSERT_DEVINS(pDevIns);
555 LogFlow(("pdmR3PciHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
556 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
557}
558
559
560/** @interface_method_impl{PDMPCIHLPR3,pfnUnlock} */
561static DECLCALLBACK(void) pdmR3PciHlp_Unlock(PPDMDEVINS pDevIns)
562{
563 PDMDEV_ASSERT_DEVINS(pDevIns);
564 LogFlow(("pdmR3PciHlp_Unlock: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
565 pdmUnlock(pDevIns->Internal.s.pVMR3);
566}
567
568
569/** @interface_method_impl{PDMPCIHLPR3,pfnGetRCHelpers} */
570static DECLCALLBACK(PCPDMPCIHLPRC) pdmR3PciHlp_GetRCHelpers(PPDMDEVINS pDevIns)
571{
572 PDMDEV_ASSERT_DEVINS(pDevIns);
573 PVM pVM = pDevIns->Internal.s.pVMR3;
574 VM_ASSERT_EMT(pVM);
575
576 RTRCPTR pRCHelpers = NIL_RTRCPTR;
577 if (!HMIsEnabled(pVM))
578 {
579 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCPciHlp", &pRCHelpers);
580 AssertReleaseRC(rc);
581 AssertRelease(pRCHelpers);
582 }
583
584 LogFlow(("pdmR3IoApicHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
585 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
586 return pRCHelpers;
587}
588
589
590/** @interface_method_impl{PDMPCIHLPR3,pfnGetR0Helpers} */
591static DECLCALLBACK(PCPDMPCIHLPR0) pdmR3PciHlp_GetR0Helpers(PPDMDEVINS pDevIns)
592{
593 PDMDEV_ASSERT_DEVINS(pDevIns);
594 PVM pVM = pDevIns->Internal.s.pVMR3;
595 VM_ASSERT_EMT(pVM);
596 PCPDMPCIHLPR0 pR0Helpers = 0;
597 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0PciHlp", &pR0Helpers);
598 AssertReleaseRC(rc);
599 AssertRelease(pR0Helpers);
600 LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
601 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
602 return pR0Helpers;
603}
604
605
606/**
607 * PCI Bus Device Helpers.
608 */
609const PDMPCIHLPR3 g_pdmR3DevPciHlp =
610{
611 PDM_PCIHLPR3_VERSION,
612 pdmR3PciHlp_IsaSetIrq,
613 pdmR3PciHlp_IoApicSetIrq,
614 pdmR3PciHlp_IoApicSendMsi,
615 pdmR3PciHlp_IsMMIO2Base,
616 pdmR3PciHlp_GetRCHelpers,
617 pdmR3PciHlp_GetR0Helpers,
618 pdmR3PciHlp_Lock,
619 pdmR3PciHlp_Unlock,
620 PDM_PCIHLPR3_VERSION, /* the end */
621};
622
623/** @} */
624
625
626
627
628/** @name Ring-3 HPET Helpers
629 * {@
630 */
631
632/** @interface_method_impl{PDMHPETHLPR3,pfnSetLegacyMode} */
633static DECLCALLBACK(int) pdmR3HpetHlp_SetLegacyMode(PPDMDEVINS pDevIns, bool fActivated)
634{
635 PDMDEV_ASSERT_DEVINS(pDevIns);
636 LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: fActivated=%RTbool\n", pDevIns->pReg->szName, pDevIns->iInstance, fActivated));
637
638 size_t i;
639 int rc = VINF_SUCCESS;
640 static const char * const s_apszDevsToNotify[] =
641 {
642 "i8254",
643 "mc146818"
644 };
645 for (i = 0; i < RT_ELEMENTS(s_apszDevsToNotify); i++)
646 {
647 PPDMIBASE pBase;
648 rc = PDMR3QueryDevice(pDevIns->Internal.s.pVMR3->pUVM, "i8254", 0, &pBase);
649 if (RT_SUCCESS(rc))
650 {
651 PPDMIHPETLEGACYNOTIFY pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIHPETLEGACYNOTIFY);
652 AssertLogRelMsgBreakStmt(pPort, ("%s\n", s_apszDevsToNotify[i]), rc = VERR_PDM_HPET_LEGACY_NOTIFY_MISSING);
653 pPort->pfnModeChanged(pPort, fActivated);
654 }
655 else if ( rc == VERR_PDM_DEVICE_NOT_FOUND
656 || rc == VERR_PDM_DEVICE_INSTANCE_NOT_FOUND)
657 rc = VINF_SUCCESS; /* the device isn't configured, ignore. */
658 else
659 AssertLogRelMsgFailedBreak(("%s -> %Rrc\n", s_apszDevsToNotify[i], rc));
660 }
661
662 /* Don't bother cleaning up, any failure here will cause a guru meditation. */
663
664 LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
665 return rc;
666}
667
668
669/** @interface_method_impl{PDMHPETHLPR3,pfnSetIrq} */
670static DECLCALLBACK(int) pdmR3HpetHlp_SetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
671{
672 PDMDEV_ASSERT_DEVINS(pDevIns);
673 LogFlow(("pdmR3HpetHlp_SetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, iIrq, iLevel));
674 PVM pVM = pDevIns->Internal.s.pVMR3;
675
676 pdmLock(pVM);
677 uint32_t uTagSrc;
678 if (iLevel & PDM_IRQ_LEVEL_HIGH)
679 {
680 pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
681 if (iLevel == PDM_IRQ_LEVEL_HIGH)
682 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
683 else
684 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
685 }
686 else
687 uTagSrc = pDevIns->Internal.s.uLastIrqTag;
688
689 PDMIsaSetIrq(pVM, iIrq, iLevel, uTagSrc); /* (The API takes the lock recursively.) */
690
691 if (iLevel == PDM_IRQ_LEVEL_LOW)
692 VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
693 pdmUnlock(pVM);
694 return 0;
695}
696
697
698/** @interface_method_impl{PDMHPETHLPR3,pfnGetRCHelpers} */
699static DECLCALLBACK(PCPDMHPETHLPRC) pdmR3HpetHlp_GetRCHelpers(PPDMDEVINS pDevIns)
700{
701 PDMDEV_ASSERT_DEVINS(pDevIns);
702 PVM pVM = pDevIns->Internal.s.pVMR3;
703 VM_ASSERT_EMT(pVM);
704
705 RTRCPTR pRCHelpers = NIL_RTRCPTR;
706 if (!HMIsEnabled(pVM))
707 {
708 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCHpetHlp", &pRCHelpers);
709 AssertReleaseRC(rc);
710 AssertRelease(pRCHelpers);
711 }
712
713 LogFlow(("pdmR3HpetHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
714 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
715 return pRCHelpers;
716}
717
718
719/** @interface_method_impl{PDMHPETHLPR3,pfnGetR0Helpers} */
720static DECLCALLBACK(PCPDMHPETHLPR0) pdmR3HpetHlp_GetR0Helpers(PPDMDEVINS pDevIns)
721{
722 PDMDEV_ASSERT_DEVINS(pDevIns);
723 PVM pVM = pDevIns->Internal.s.pVMR3;
724 VM_ASSERT_EMT(pVM);
725 PCPDMHPETHLPR0 pR0Helpers = 0;
726 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0HpetHlp", &pR0Helpers);
727 AssertReleaseRC(rc);
728 AssertRelease(pR0Helpers);
729 LogFlow(("pdmR3HpetHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
730 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
731 return pR0Helpers;
732}
733
734
735/**
736 * HPET Device Helpers.
737 */
738const PDMHPETHLPR3 g_pdmR3DevHpetHlp =
739{
740 PDM_HPETHLPR3_VERSION,
741 pdmR3HpetHlp_GetRCHelpers,
742 pdmR3HpetHlp_GetR0Helpers,
743 pdmR3HpetHlp_SetLegacyMode,
744 pdmR3HpetHlp_SetIrq,
745 PDM_HPETHLPR3_VERSION, /* the end */
746};
747
748/** @} */
749
750
751/** @name Ring-3 Raw PCI Device Helpers
752 * {@
753 */
754
755/** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetRCHelpers} */
756static DECLCALLBACK(PCPDMPCIRAWHLPRC) pdmR3PciRawHlp_GetRCHelpers(PPDMDEVINS pDevIns)
757{
758 PDMDEV_ASSERT_DEVINS(pDevIns);
759 PVM pVM = pDevIns->Internal.s.pVMR3;
760 VM_ASSERT_EMT(pVM);
761
762 RTRCPTR pRCHelpers = NIL_RTRCPTR;
763 if (!HMIsEnabled(pVM))
764 {
765 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCPciRawHlp", &pRCHelpers);
766 AssertReleaseRC(rc);
767 AssertRelease(pRCHelpers);
768 }
769
770 LogFlow(("pdmR3PciRawHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
771 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
772 return pRCHelpers;
773}
774
775
776/** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetR0Helpers} */
777static DECLCALLBACK(PCPDMPCIRAWHLPR0) pdmR3PciRawHlp_GetR0Helpers(PPDMDEVINS pDevIns)
778{
779 PDMDEV_ASSERT_DEVINS(pDevIns);
780 PVM pVM = pDevIns->Internal.s.pVMR3;
781 VM_ASSERT_EMT(pVM);
782 PCPDMHPETHLPR0 pR0Helpers = NIL_RTR0PTR;
783 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0PciRawHlp", &pR0Helpers);
784 AssertReleaseRC(rc);
785 AssertRelease(pR0Helpers);
786 LogFlow(("pdmR3PciRawHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
787 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
788 return pR0Helpers;
789}
790
791
792/**
793 * Raw PCI Device Helpers.
794 */
795const PDMPCIRAWHLPR3 g_pdmR3DevPciRawHlp =
796{
797 PDM_PCIRAWHLPR3_VERSION,
798 pdmR3PciRawHlp_GetRCHelpers,
799 pdmR3PciRawHlp_GetR0Helpers,
800 PDM_PCIRAWHLPR3_VERSION, /* the end */
801};
802
803/** @} */
804
805
806/* none yet */
807
808/**
809 * DMAC Device Helpers.
810 */
811const PDMDMACHLP g_pdmR3DevDmacHlp =
812{
813 PDM_DMACHLP_VERSION
814};
815
816
817
818
819/* none yet */
820
821/**
822 * RTC Device Helpers.
823 */
824const PDMRTCHLP g_pdmR3DevRtcHlp =
825{
826 PDM_RTCHLP_VERSION
827};
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