VirtualBox

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

Last change on this file since 50653 was 46420, checked in by vboxsync, 11 years ago

VMM, recompiler: Purge deprecated macros.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 26.0 KB
Line 
1/* $Id: PDMDevMiscHlp.cpp 46420 2013-06-06 16:27:25Z vboxsync $ */
2/** @file
3 * PDM - Pluggable Device and Driver Manager, Misc. Device Helpers.
4 */
5
6/*
7 * Copyright (C) 2006-2013 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/** @interface_method_impl{PDMAPICHLPR3,pfnSendInitIpi} */
315static DECLCALLBACK(void) pdmR3ApicHlp_SendInitIpi(PPDMDEVINS pDevIns, VMCPUID idCpu)
316{
317 PDMDEV_ASSERT_DEVINS(pDevIns);
318 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
319 VMMR3SendInitIpi(pDevIns->Internal.s.pVMR3, idCpu);
320}
321
322/** @interface_method_impl{PDMAPICHLPR3,pfnGetRCHelpers} */
323static DECLCALLBACK(PCPDMAPICHLPRC) pdmR3ApicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
324{
325 PDMDEV_ASSERT_DEVINS(pDevIns);
326 PVM pVM = pDevIns->Internal.s.pVMR3;
327 VM_ASSERT_EMT(pVM);
328
329 RTRCPTR pRCHelpers = NIL_RTRCPTR;
330 if (!HMIsEnabled(pVM))
331 {
332 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCApicHlp", &pRCHelpers);
333 AssertReleaseRC(rc);
334 AssertRelease(pRCHelpers);
335 }
336
337 LogFlow(("pdmR3ApicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
338 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
339 return pRCHelpers;
340}
341
342
343/** @interface_method_impl{PDMAPICHLPR3,pfnGetR0Helpers} */
344static DECLCALLBACK(PCPDMAPICHLPR0) pdmR3ApicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
345{
346 PDMDEV_ASSERT_DEVINS(pDevIns);
347 PVM pVM = pDevIns->Internal.s.pVMR3;
348 VM_ASSERT_EMT(pVM);
349 PCPDMAPICHLPR0 pR0Helpers = 0;
350 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0ApicHlp", &pR0Helpers);
351 AssertReleaseRC(rc);
352 AssertRelease(pR0Helpers);
353 LogFlow(("pdmR3ApicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
354 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
355 return pR0Helpers;
356}
357
358
359/** @interface_method_impl{PDMAPICHLPR3,pfnGetR3CritSect} */
360static DECLCALLBACK(R3PTRTYPE(PPDMCRITSECT)) pdmR3ApicHlp_GetR3CritSect(PPDMDEVINS pDevIns)
361{
362 PDMDEV_ASSERT_DEVINS(pDevIns);
363 LogFlow(("pdmR3ApicHlp_Lock: caller='%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
364 return &pDevIns->Internal.s.pVMR3->pdm.s.CritSect;
365}
366
367
368/** @interface_method_impl{PDMAPICHLPR3,pfnGetRCCritSect} */
369static DECLCALLBACK(RCPTRTYPE(PPDMCRITSECT)) pdmR3ApicHlp_GetRCCritSect(PPDMDEVINS pDevIns)
370{
371 PDMDEV_ASSERT_DEVINS(pDevIns);
372 PVM pVM = pDevIns->Internal.s.pVMR3;
373 RTRCPTR RCPtr = MMHyperCCToRC(pVM, &pVM->pdm.s.CritSect);
374 LogFlow(("pdmR3ApicHlp_GetR0CritSect: caller='%s'/%d: return %RRv\n", pDevIns->pReg->szName, pDevIns->iInstance, RCPtr));
375 return RCPtr;
376}
377
378
379/** @interface_method_impl{PDMAPICHLPR3,pfnGetR3CritSect} */
380static DECLCALLBACK(R0PTRTYPE(PPDMCRITSECT)) pdmR3ApicHlp_GetR0CritSect(PPDMDEVINS pDevIns)
381{
382 PDMDEV_ASSERT_DEVINS(pDevIns);
383 PVM pVM = pDevIns->Internal.s.pVMR3;
384 RTR0PTR R0Ptr = MMHyperCCToR0(pVM, &pVM->pdm.s.CritSect);
385 LogFlow(("pdmR3ApicHlp_GetR0CritSect: caller='%s'/%d: return %RHv\n", pDevIns->pReg->szName, pDevIns->iInstance, R0Ptr));
386 return R0Ptr;
387}
388
389
390
391/**
392 * APIC Device Helpers.
393 */
394const PDMAPICHLPR3 g_pdmR3DevApicHlp =
395{
396 PDM_APICHLPR3_VERSION,
397 pdmR3ApicHlp_SetInterruptFF,
398 pdmR3ApicHlp_ClearInterruptFF,
399 pdmR3ApicHlp_CalcIrqTag,
400 pdmR3ApicHlp_ChangeFeature,
401 pdmR3ApicHlp_GetCpuId,
402 pdmR3ApicHlp_SendSipi,
403 pdmR3ApicHlp_SendInitIpi,
404 pdmR3ApicHlp_GetRCHelpers,
405 pdmR3ApicHlp_GetR0Helpers,
406 pdmR3ApicHlp_GetR3CritSect,
407 pdmR3ApicHlp_GetRCCritSect,
408 pdmR3ApicHlp_GetR0CritSect,
409 PDM_APICHLPR3_VERSION /* the end */
410};
411
412/** @} */
413
414
415
416
417/** @name Ring-3 I/O APIC Helpers
418 * @{
419 */
420
421/** @interface_method_impl{PDMIOAPICHLPR3,pfnApicBusDeliver} */
422static DECLCALLBACK(int) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
423 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc)
424{
425 PDMDEV_ASSERT_DEVINS(pDevIns);
426 PVM pVM = pDevIns->Internal.s.pVMR3;
427 LogFlow(("pdmR3IoApicHlp_ApicBusDeliver: caller='%s'/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
428 pDevIns->pReg->szName, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc));
429 if (pVM->pdm.s.Apic.pfnBusDeliverR3)
430 return pVM->pdm.s.Apic.pfnBusDeliverR3(pVM->pdm.s.Apic.pDevInsR3, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc);
431 return VINF_SUCCESS;
432}
433
434
435/** @interface_method_impl{PDMIOAPICHLPR3,pfnLock} */
436static DECLCALLBACK(int) pdmR3IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
437{
438 PDMDEV_ASSERT_DEVINS(pDevIns);
439 LogFlow(("pdmR3IoApicHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
440 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
441}
442
443
444/** @interface_method_impl{PDMIOAPICHLPR3,pfnUnlock} */
445static DECLCALLBACK(void) pdmR3IoApicHlp_Unlock(PPDMDEVINS pDevIns)
446{
447 PDMDEV_ASSERT_DEVINS(pDevIns);
448 LogFlow(("pdmR3IoApicHlp_Unlock: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
449 pdmUnlock(pDevIns->Internal.s.pVMR3);
450}
451
452
453/** @interface_method_impl{PDMIOAPICHLPR3,pfnGetRCHelpers} */
454static DECLCALLBACK(PCPDMIOAPICHLPRC) pdmR3IoApicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
455{
456 PDMDEV_ASSERT_DEVINS(pDevIns);
457 PVM pVM = pDevIns->Internal.s.pVMR3;
458 VM_ASSERT_EMT(pVM);
459
460 RTRCPTR pRCHelpers = NIL_RTRCPTR;
461 if (!HMIsEnabled(pVM))
462 {
463 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCIoApicHlp", &pRCHelpers);
464 AssertReleaseRC(rc);
465 AssertRelease(pRCHelpers);
466 }
467
468 LogFlow(("pdmR3IoApicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
469 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
470 return pRCHelpers;
471}
472
473
474/** @interface_method_impl{PDMIOAPICHLPR3,pfnGetR0Helpers} */
475static DECLCALLBACK(PCPDMIOAPICHLPR0) pdmR3IoApicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
476{
477 PDMDEV_ASSERT_DEVINS(pDevIns);
478 PVM pVM = pDevIns->Internal.s.pVMR3;
479 VM_ASSERT_EMT(pVM);
480 PCPDMIOAPICHLPR0 pR0Helpers = 0;
481 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0IoApicHlp", &pR0Helpers);
482 AssertReleaseRC(rc);
483 AssertRelease(pR0Helpers);
484 LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
485 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
486 return pR0Helpers;
487}
488
489
490/**
491 * I/O APIC Device Helpers.
492 */
493const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp =
494{
495 PDM_IOAPICHLPR3_VERSION,
496 pdmR3IoApicHlp_ApicBusDeliver,
497 pdmR3IoApicHlp_Lock,
498 pdmR3IoApicHlp_Unlock,
499 pdmR3IoApicHlp_GetRCHelpers,
500 pdmR3IoApicHlp_GetR0Helpers,
501 PDM_IOAPICHLPR3_VERSION /* the end */
502};
503
504/** @} */
505
506
507
508
509/** @name Ring-3 PCI Bus Helpers
510 * @{
511 */
512
513/** @interface_method_impl{PDMPCIHLPR3,pfnIsaSetIrq} */
514static DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
515{
516 PDMDEV_ASSERT_DEVINS(pDevIns);
517 Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
518 PVM pVM = pDevIns->Internal.s.pVMR3;
519 PDMIsaSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel, uTagSrc);
520}
521
522/** @interface_method_impl{PDMPCIHLPR3,pfnIoApicSetIrq} */
523static DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
524{
525 PDMDEV_ASSERT_DEVINS(pDevIns);
526 Log4(("pdmR3PciHlp_IoApicSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
527 PDMIoApicSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel, uTagSrc);
528}
529
530/** @interface_method_impl{PDMPCIHLPR3,pfnIoApicSendMsi} */
531static DECLCALLBACK(void) pdmR3PciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc)
532{
533 PDMDEV_ASSERT_DEVINS(pDevIns);
534 Log4(("pdmR3PciHlp_IoApicSendMsi: address=%p value=%x uTagSrc=%#x\n", GCAddr, uValue, uTagSrc));
535 PDMIoApicSendMsi(pDevIns->Internal.s.pVMR3, GCAddr, uValue, uTagSrc);
536}
537
538/** @interface_method_impl{PDMPCIHLPR3,pfnIsMMIO2Base} */
539static DECLCALLBACK(bool) pdmR3PciHlp_IsMMIO2Base(PPDMDEVINS pDevIns, PPDMDEVINS pOwner, RTGCPHYS GCPhys)
540{
541 PDMDEV_ASSERT_DEVINS(pDevIns);
542 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
543 bool fRc = PGMR3PhysMMIO2IsBase(pDevIns->Internal.s.pVMR3, pOwner, GCPhys);
544 Log4(("pdmR3PciHlp_IsMMIO2Base: pOwner=%p GCPhys=%RGp -> %RTbool\n", pOwner, GCPhys, fRc));
545 return fRc;
546}
547
548
549/** @interface_method_impl{PDMPCIHLPR3,pfnLock} */
550static DECLCALLBACK(int) pdmR3PciHlp_Lock(PPDMDEVINS pDevIns, int rc)
551{
552 PDMDEV_ASSERT_DEVINS(pDevIns);
553 LogFlow(("pdmR3PciHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
554 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
555}
556
557
558/** @interface_method_impl{PDMPCIHLPR3,pfnUnlock} */
559static DECLCALLBACK(void) pdmR3PciHlp_Unlock(PPDMDEVINS pDevIns)
560{
561 PDMDEV_ASSERT_DEVINS(pDevIns);
562 LogFlow(("pdmR3PciHlp_Unlock: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
563 pdmUnlock(pDevIns->Internal.s.pVMR3);
564}
565
566
567/** @interface_method_impl{PDMPCIHLPR3,pfnGetRCHelpers} */
568static DECLCALLBACK(PCPDMPCIHLPRC) pdmR3PciHlp_GetRCHelpers(PPDMDEVINS pDevIns)
569{
570 PDMDEV_ASSERT_DEVINS(pDevIns);
571 PVM pVM = pDevIns->Internal.s.pVMR3;
572 VM_ASSERT_EMT(pVM);
573
574 RTRCPTR pRCHelpers = NIL_RTRCPTR;
575 if (!HMIsEnabled(pVM))
576 {
577 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCPciHlp", &pRCHelpers);
578 AssertReleaseRC(rc);
579 AssertRelease(pRCHelpers);
580 }
581
582 LogFlow(("pdmR3IoApicHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
583 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
584 return pRCHelpers;
585}
586
587
588/** @interface_method_impl{PDMPCIHLPR3,pfnGetR0Helpers} */
589static DECLCALLBACK(PCPDMPCIHLPR0) pdmR3PciHlp_GetR0Helpers(PPDMDEVINS pDevIns)
590{
591 PDMDEV_ASSERT_DEVINS(pDevIns);
592 PVM pVM = pDevIns->Internal.s.pVMR3;
593 VM_ASSERT_EMT(pVM);
594 PCPDMPCIHLPR0 pR0Helpers = 0;
595 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0PciHlp", &pR0Helpers);
596 AssertReleaseRC(rc);
597 AssertRelease(pR0Helpers);
598 LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
599 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
600 return pR0Helpers;
601}
602
603
604/**
605 * PCI Bus Device Helpers.
606 */
607const PDMPCIHLPR3 g_pdmR3DevPciHlp =
608{
609 PDM_PCIHLPR3_VERSION,
610 pdmR3PciHlp_IsaSetIrq,
611 pdmR3PciHlp_IoApicSetIrq,
612 pdmR3PciHlp_IoApicSendMsi,
613 pdmR3PciHlp_IsMMIO2Base,
614 pdmR3PciHlp_GetRCHelpers,
615 pdmR3PciHlp_GetR0Helpers,
616 pdmR3PciHlp_Lock,
617 pdmR3PciHlp_Unlock,
618 PDM_PCIHLPR3_VERSION, /* the end */
619};
620
621/** @} */
622
623
624
625
626/** @name Ring-3 HPET Helpers
627 * {@
628 */
629
630/** @interface_method_impl{PDMHPETHLPR3,pfnSetLegacyMode} */
631static DECLCALLBACK(int) pdmR3HpetHlp_SetLegacyMode(PPDMDEVINS pDevIns, bool fActivated)
632{
633 PDMDEV_ASSERT_DEVINS(pDevIns);
634 LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: fActivated=%RTbool\n", pDevIns->pReg->szName, pDevIns->iInstance, fActivated));
635
636 size_t i;
637 int rc = VINF_SUCCESS;
638 static const char * const s_apszDevsToNotify[] =
639 {
640 "i8254",
641 "mc146818"
642 };
643 for (i = 0; i < RT_ELEMENTS(s_apszDevsToNotify); i++)
644 {
645 PPDMIBASE pBase;
646 rc = PDMR3QueryDevice(pDevIns->Internal.s.pVMR3->pUVM, "i8254", 0, &pBase);
647 if (RT_SUCCESS(rc))
648 {
649 PPDMIHPETLEGACYNOTIFY pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIHPETLEGACYNOTIFY);
650 AssertLogRelMsgBreakStmt(pPort, ("%s\n", s_apszDevsToNotify[i]), rc = VERR_PDM_HPET_LEGACY_NOTIFY_MISSING);
651 pPort->pfnModeChanged(pPort, fActivated);
652 }
653 else if ( rc == VERR_PDM_DEVICE_NOT_FOUND
654 || rc == VERR_PDM_DEVICE_INSTANCE_NOT_FOUND)
655 rc = VINF_SUCCESS; /* the device isn't configured, ignore. */
656 else
657 AssertLogRelMsgFailedBreak(("%s -> %Rrc\n", s_apszDevsToNotify[i], rc));
658 }
659
660 /* Don't bother cleaning up, any failure here will cause a guru meditation. */
661
662 LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
663 return rc;
664}
665
666
667/** @interface_method_impl{PDMHPETHLPR3,pfnSetIrq} */
668static DECLCALLBACK(int) pdmR3HpetHlp_SetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
669{
670 PDMDEV_ASSERT_DEVINS(pDevIns);
671 LogFlow(("pdmR3HpetHlp_SetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, iIrq, iLevel));
672 PVM pVM = pDevIns->Internal.s.pVMR3;
673
674 pdmLock(pVM);
675 uint32_t uTagSrc;
676 if (iLevel & PDM_IRQ_LEVEL_HIGH)
677 {
678 pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
679 if (iLevel == PDM_IRQ_LEVEL_HIGH)
680 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
681 else
682 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
683 }
684 else
685 uTagSrc = pDevIns->Internal.s.uLastIrqTag;
686
687 PDMIsaSetIrq(pVM, iIrq, iLevel, uTagSrc); /* (The API takes the lock recursively.) */
688
689 if (iLevel == PDM_IRQ_LEVEL_LOW)
690 VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
691 pdmUnlock(pVM);
692 return 0;
693}
694
695
696/** @interface_method_impl{PDMHPETHLPR3,pfnGetRCHelpers} */
697static DECLCALLBACK(PCPDMHPETHLPRC) pdmR3HpetHlp_GetRCHelpers(PPDMDEVINS pDevIns)
698{
699 PDMDEV_ASSERT_DEVINS(pDevIns);
700 PVM pVM = pDevIns->Internal.s.pVMR3;
701 VM_ASSERT_EMT(pVM);
702
703 RTRCPTR pRCHelpers = NIL_RTRCPTR;
704 if (!HMIsEnabled(pVM))
705 {
706 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCHpetHlp", &pRCHelpers);
707 AssertReleaseRC(rc);
708 AssertRelease(pRCHelpers);
709 }
710
711 LogFlow(("pdmR3HpetHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
712 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
713 return pRCHelpers;
714}
715
716
717/** @interface_method_impl{PDMHPETHLPR3,pfnGetR0Helpers} */
718static DECLCALLBACK(PCPDMHPETHLPR0) pdmR3HpetHlp_GetR0Helpers(PPDMDEVINS pDevIns)
719{
720 PDMDEV_ASSERT_DEVINS(pDevIns);
721 PVM pVM = pDevIns->Internal.s.pVMR3;
722 VM_ASSERT_EMT(pVM);
723 PCPDMHPETHLPR0 pR0Helpers = 0;
724 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0HpetHlp", &pR0Helpers);
725 AssertReleaseRC(rc);
726 AssertRelease(pR0Helpers);
727 LogFlow(("pdmR3HpetHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
728 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
729 return pR0Helpers;
730}
731
732
733/**
734 * HPET Device Helpers.
735 */
736const PDMHPETHLPR3 g_pdmR3DevHpetHlp =
737{
738 PDM_HPETHLPR3_VERSION,
739 pdmR3HpetHlp_GetRCHelpers,
740 pdmR3HpetHlp_GetR0Helpers,
741 pdmR3HpetHlp_SetLegacyMode,
742 pdmR3HpetHlp_SetIrq,
743 PDM_HPETHLPR3_VERSION, /* the end */
744};
745
746/** @} */
747
748
749/** @name Ring-3 Raw PCI Device Helpers
750 * {@
751 */
752
753/** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetRCHelpers} */
754static DECLCALLBACK(PCPDMPCIRAWHLPRC) pdmR3PciRawHlp_GetRCHelpers(PPDMDEVINS pDevIns)
755{
756 PDMDEV_ASSERT_DEVINS(pDevIns);
757 PVM pVM = pDevIns->Internal.s.pVMR3;
758 VM_ASSERT_EMT(pVM);
759
760 RTRCPTR pRCHelpers = NIL_RTRCPTR;
761 if (!HMIsEnabled(pVM))
762 {
763 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCPciRawHlp", &pRCHelpers);
764 AssertReleaseRC(rc);
765 AssertRelease(pRCHelpers);
766 }
767
768 LogFlow(("pdmR3PciRawHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
769 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
770 return pRCHelpers;
771}
772
773
774/** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetR0Helpers} */
775static DECLCALLBACK(PCPDMPCIRAWHLPR0) pdmR3PciRawHlp_GetR0Helpers(PPDMDEVINS pDevIns)
776{
777 PDMDEV_ASSERT_DEVINS(pDevIns);
778 PVM pVM = pDevIns->Internal.s.pVMR3;
779 VM_ASSERT_EMT(pVM);
780 PCPDMHPETHLPR0 pR0Helpers = NIL_RTR0PTR;
781 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0PciRawHlp", &pR0Helpers);
782 AssertReleaseRC(rc);
783 AssertRelease(pR0Helpers);
784 LogFlow(("pdmR3PciRawHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
785 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
786 return pR0Helpers;
787}
788
789
790/**
791 * Raw PCI Device Helpers.
792 */
793const PDMPCIRAWHLPR3 g_pdmR3DevPciRawHlp =
794{
795 PDM_PCIRAWHLPR3_VERSION,
796 pdmR3PciRawHlp_GetRCHelpers,
797 pdmR3PciRawHlp_GetR0Helpers,
798 PDM_PCIRAWHLPR3_VERSION, /* the end */
799};
800
801/** @} */
802
803
804/* none yet */
805
806/**
807 * DMAC Device Helpers.
808 */
809const PDMDMACHLP g_pdmR3DevDmacHlp =
810{
811 PDM_DMACHLP_VERSION
812};
813
814
815
816
817/* none yet */
818
819/**
820 * RTC Device Helpers.
821 */
822const PDMRTCHLP g_pdmR3DevRtcHlp =
823{
824 PDM_RTCHLP_VERSION
825};
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use