VirtualBox

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

Last change on this file since 40937 was 40937, checked in by vboxsync, 13 years ago

Tag the APIC timer IRQs.

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