VirtualBox

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

Last change on this file since 25414 was 24125, checked in by vboxsync, 15 years ago

DevAPIC/PDM: Properly route PIC interrupts through local APIC (fixes double time interrupt delivery in some Linux kernels).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 18.5 KB
Line 
1/* $Id: PDMDevMiscHlp.cpp 24125 2009-10-28 09:58:41Z vboxsync $ */
2/** @file
3 * PDM - Pluggable Device and Driver Manager, Misc. Device Helpers.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
20 */
21
22
23/*******************************************************************************
24* Header Files *
25*******************************************************************************/
26#define LOG_GROUP LOG_GROUP_PDM_DEVICE
27#include "PDMInternal.h"
28#include <VBox/pdm.h>
29#include <VBox/rem.h>
30#include <VBox/vm.h>
31#include <VBox/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
41/** @name HC PIC Helpers
42 * @{
43 */
44
45/** @copydoc PDMPICHLPR3::pfnSetInterruptFF */
46static DECLCALLBACK(void) pdmR3PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
47{
48 PDMDEV_ASSERT_DEVINS(pDevIns);
49 PVM pVM = pDevIns->Internal.s.pVMR3;
50
51 if (pVM->pdm.s.Apic.pfnLocalInterruptR3)
52 {
53 LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: Setting local interrupt on LAPIC\n",
54 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
55 /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
56 pVM->pdm.s.Apic.pfnLocalInterruptR3(pVM->pdm.s.Apic.pDevInsR3, 0, 1);
57 return;
58 }
59
60 PVMCPU pVCpu = &pVM->aCpus[0]; /* for PIC we always deliver to CPU 0, MP use APIC */
61
62 LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 1\n",
63 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
64
65 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
66 REMR3NotifyInterruptSet(pVM, pVCpu);
67 VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
68}
69
70
71/** @copydoc PDMPICHLPR3::pfnClearInterruptFF */
72static DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
73{
74 PDMDEV_ASSERT_DEVINS(pDevIns);
75 PVM pVM = pDevIns->Internal.s.pVMR3;
76 PVMCPU pVCpu = &pVM->aCpus[0]; /* for PIC we always deliver to CPU 0, MP use APIC */
77
78 if (pVM->pdm.s.Apic.pfnLocalInterruptR3)
79 {
80 /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
81 LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
82 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
83 /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
84 pVM->pdm.s.Apic.pfnLocalInterruptR3(pVM->pdm.s.Apic.pDevInsR3, 0, 0);
85 return;
86 }
87
88 LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT_PIC %d -> 0\n",
89 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
90
91 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
92 REMR3NotifyInterruptClear(pVM, pVCpu);
93}
94
95
96/** @copydoc PDMPICHLPR3::pfnLock */
97static DECLCALLBACK(int) pdmR3PicHlp_Lock(PPDMDEVINS pDevIns, int rc)
98{
99 PDMDEV_ASSERT_DEVINS(pDevIns);
100 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
101}
102
103
104/** @copydoc PDMPICHLPR3::pfnUnlock */
105static DECLCALLBACK(void) pdmR3PicHlp_Unlock(PPDMDEVINS pDevIns)
106{
107 PDMDEV_ASSERT_DEVINS(pDevIns);
108 pdmUnlock(pDevIns->Internal.s.pVMR3);
109}
110
111
112/** @copydoc PDMPICHLPR3::pfnGetRCHelpers */
113static DECLCALLBACK(PCPDMPICHLPRC) pdmR3PicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
114{
115 PDMDEV_ASSERT_DEVINS(pDevIns);
116 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
117 RTRCPTR pRCHelpers = 0;
118 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCPicHlp", &pRCHelpers);
119 AssertReleaseRC(rc);
120 AssertRelease(pRCHelpers);
121 LogFlow(("pdmR3PicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
122 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers));
123 return pRCHelpers;
124}
125
126
127/** @copydoc PDMPICHLPR3::pfnGetR0Helpers */
128static DECLCALLBACK(PCPDMPICHLPR0) pdmR3PicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
129{
130 PDMDEV_ASSERT_DEVINS(pDevIns);
131 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
132 PCPDMPICHLPR0 pR0Helpers = 0;
133 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0PicHlp", &pR0Helpers);
134 AssertReleaseRC(rc);
135 AssertRelease(pR0Helpers);
136 LogFlow(("pdmR3PicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
137 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers));
138 return pR0Helpers;
139}
140
141
142/**
143 * PIC Device Helpers.
144 */
145const PDMPICHLPR3 g_pdmR3DevPicHlp =
146{
147 PDM_PICHLPR3_VERSION,
148 pdmR3PicHlp_SetInterruptFF,
149 pdmR3PicHlp_ClearInterruptFF,
150 pdmR3PicHlp_Lock,
151 pdmR3PicHlp_Unlock,
152 pdmR3PicHlp_GetRCHelpers,
153 pdmR3PicHlp_GetR0Helpers,
154 PDM_PICHLPR3_VERSION /* the end */
155};
156
157/** @} */
158
159
160
161
162/** @name R3 APIC Helpers
163 * @{
164 */
165
166/** @copydoc PDMAPICHLPR3::pfnSetInterruptFF */
167static DECLCALLBACK(void) pdmR3ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
168{
169 PDMDEV_ASSERT_DEVINS(pDevIns);
170 PVM pVM = pDevIns->Internal.s.pVMR3;
171 PVMCPU pVCpu = &pVM->aCpus[idCpu];
172
173 AssertReturnVoid(idCpu < pVM->cCpus);
174
175 LogFlow(("pdmR3ApicHlp_SetInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT(%d) %d -> 1\n",
176 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, idCpu, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
177
178 switch (enmType)
179 {
180 case PDMAPICIRQ_HARDWARE:
181 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
182 break;
183 case PDMAPICIRQ_NMI:
184 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);
185 break;
186 case PDMAPICIRQ_SMI:
187 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
188 break;
189 case PDMAPICIRQ_EXTINT:
190 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
191 break;
192 default:
193 AssertMsgFailed(("enmType=%d\n", enmType));
194 break;
195 }
196 REMR3NotifyInterruptSet(pVM, pVCpu);
197 VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
198}
199
200
201/** @copydoc PDMAPICHLPR3::pfnClearInterruptFF */
202static DECLCALLBACK(void) pdmR3ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
203{
204 PDMDEV_ASSERT_DEVINS(pDevIns);
205 PVM pVM = pDevIns->Internal.s.pVMR3;
206 PVMCPU pVCpu = &pVM->aCpus[idCpu];
207
208 AssertReturnVoid(idCpu < pVM->cCpus);
209
210 LogFlow(("pdmR3ApicHlp_ClearInterruptFF: caller='%s'/%d: VM_FF_INTERRUPT(%d) %d -> 0\n",
211 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, idCpu, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
212
213 /* Note: NMI/SMI can't be cleared. */
214 switch (enmType)
215 {
216 case PDMAPICIRQ_HARDWARE:
217 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
218 break;
219 case PDMAPICIRQ_EXTINT:
220 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
221 break;
222 default:
223 AssertMsgFailed(("enmType=%d\n", enmType));
224 break;
225 }
226 REMR3NotifyInterruptClear(pVM, pVCpu);
227}
228
229
230/** @copydoc PDMAPICHLPR3::pfnChangeFeature */
231static DECLCALLBACK(void) pdmR3ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion)
232{
233 PDMDEV_ASSERT_DEVINS(pDevIns);
234 LogFlow(("pdmR3ApicHlp_ChangeFeature: caller='%s'/%d: version=%d\n",
235 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, (int)enmVersion));
236 switch (enmVersion)
237 {
238 case PDMAPICVERSION_NONE:
239 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC);
240 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC);
241 break;
242 case PDMAPICVERSION_APIC:
243 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC);
244 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC);
245 break;
246 case PDMAPICVERSION_X2APIC:
247 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC);
248 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC);
249 break;
250 default:
251 AssertMsgFailed(("Unknown APIC version: %d\n", (int)enmVersion));
252 }
253}
254
255/** @copydoc PDMAPICHLPR3::pfnGetCpuId */
256static DECLCALLBACK(VMCPUID) pdmR3ApicHlp_GetCpuId(PPDMDEVINS pDevIns)
257{
258 PDMDEV_ASSERT_DEVINS(pDevIns);
259 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
260 return VMMGetCpuId(pDevIns->Internal.s.pVMR3);
261}
262
263
264/** @copydoc PDMAPICHLPR3::pfnSendSipi */
265static DECLCALLBACK(void) pdmR3ApicHlp_SendSipi(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t uVector)
266{
267 PDMDEV_ASSERT_DEVINS(pDevIns);
268 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
269 VMMR3SendSipi(pDevIns->Internal.s.pVMR3, idCpu, uVector);
270}
271
272/** @copydoc PDMAPICHLPR3::pfnSendInitIpi */
273static DECLCALLBACK(void) pdmR3ApicHlp_SendInitIpi(PPDMDEVINS pDevIns, VMCPUID idCpu)
274{
275 PDMDEV_ASSERT_DEVINS(pDevIns);
276 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
277 VMMR3SendInitIpi(pDevIns->Internal.s.pVMR3, idCpu);
278}
279
280/** @copydoc PDMAPICHLPR3::pfnGetRCHelpers */
281static DECLCALLBACK(PCPDMAPICHLPRC) pdmR3ApicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
282{
283 PDMDEV_ASSERT_DEVINS(pDevIns);
284 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
285 RTRCPTR pRCHelpers = 0;
286 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCApicHlp", &pRCHelpers);
287 AssertReleaseRC(rc);
288 AssertRelease(pRCHelpers);
289 LogFlow(("pdmR3ApicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
290 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers));
291 return pRCHelpers;
292}
293
294
295/** @copydoc PDMAPICHLPR3::pfnGetR0Helpers */
296static DECLCALLBACK(PCPDMAPICHLPR0) pdmR3ApicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
297{
298 PDMDEV_ASSERT_DEVINS(pDevIns);
299 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
300 PCPDMAPICHLPR0 pR0Helpers = 0;
301 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0ApicHlp", &pR0Helpers);
302 AssertReleaseRC(rc);
303 AssertRelease(pR0Helpers);
304 LogFlow(("pdmR3ApicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
305 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers));
306 return pR0Helpers;
307}
308
309
310/** @copydoc PDMAPICHLPR3::pfnGetR3CritSect */
311static DECLCALLBACK(R3PTRTYPE(PPDMCRITSECT)) pdmR3ApicHlp_GetR3CritSect(PPDMDEVINS pDevIns)
312{
313 PDMDEV_ASSERT_DEVINS(pDevIns);
314 LogFlow(("pdmR3ApicHlp_Lock: caller='%s'/%d\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
315 return &pDevIns->Internal.s.pVMR3->pdm.s.CritSect;
316}
317
318
319/** @copydoc PDMAPICHLPR3::pfnGetRCCritSect */
320static DECLCALLBACK(RCPTRTYPE(PPDMCRITSECT)) pdmR3ApicHlp_GetRCCritSect(PPDMDEVINS pDevIns)
321{
322 PDMDEV_ASSERT_DEVINS(pDevIns);
323 PVM pVM = pDevIns->Internal.s.pVMR3;
324 RTRCPTR RCPtr = MMHyperCCToRC(pVM, &pVM->pdm.s.CritSect);
325 LogFlow(("pdmR3ApicHlp_GetR0CritSect: caller='%s'/%d: return %RRv\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, RCPtr));
326 return RCPtr;
327}
328
329
330/** @copydoc PDMAPICHLPR3::pfnGetR3CritSect */
331static DECLCALLBACK(R0PTRTYPE(PPDMCRITSECT)) pdmR3ApicHlp_GetR0CritSect(PPDMDEVINS pDevIns)
332{
333 PDMDEV_ASSERT_DEVINS(pDevIns);
334 PVM pVM = pDevIns->Internal.s.pVMR3;
335 RTR0PTR R0Ptr = MMHyperCCToR0(pVM, &pVM->pdm.s.CritSect);
336 LogFlow(("pdmR3ApicHlp_GetR0CritSect: caller='%s'/%d: return %RHv\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, R0Ptr));
337 return R0Ptr;
338}
339
340
341
342/**
343 * APIC Device Helpers.
344 */
345const PDMAPICHLPR3 g_pdmR3DevApicHlp =
346{
347 PDM_APICHLPR3_VERSION,
348 pdmR3ApicHlp_SetInterruptFF,
349 pdmR3ApicHlp_ClearInterruptFF,
350 pdmR3ApicHlp_ChangeFeature,
351 pdmR3ApicHlp_GetCpuId,
352 pdmR3ApicHlp_SendSipi,
353 pdmR3ApicHlp_SendInitIpi,
354 pdmR3ApicHlp_GetRCHelpers,
355 pdmR3ApicHlp_GetR0Helpers,
356 pdmR3ApicHlp_GetR3CritSect,
357 pdmR3ApicHlp_GetRCCritSect,
358 pdmR3ApicHlp_GetR0CritSect,
359 PDM_APICHLPR3_VERSION /* the end */
360};
361
362/** @} */
363
364
365
366
367/** @name HC I/O APIC Helpers
368 * @{
369 */
370
371/** @copydoc PDMIOAPICHLPR3::pfnApicBusDeliver */
372static DECLCALLBACK(int) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
373 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
374{
375 PDMDEV_ASSERT_DEVINS(pDevIns);
376 PVM pVM = pDevIns->Internal.s.pVMR3;
377 LogFlow(("pdmR3IoApicHlp_ApicBusDeliver: caller='%s'/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
378 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
379 if (pVM->pdm.s.Apic.pfnBusDeliverR3)
380 return pVM->pdm.s.Apic.pfnBusDeliverR3(pVM->pdm.s.Apic.pDevInsR3, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
381 return VINF_SUCCESS;
382}
383
384
385/** @copydoc PDMIOAPICHLPR3::pfnLock */
386static DECLCALLBACK(int) pdmR3IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
387{
388 PDMDEV_ASSERT_DEVINS(pDevIns);
389 LogFlow(("pdmR3IoApicHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
390 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
391}
392
393
394/** @copydoc PDMIOAPICHLPR3::pfnUnlock */
395static DECLCALLBACK(void) pdmR3IoApicHlp_Unlock(PPDMDEVINS pDevIns)
396{
397 PDMDEV_ASSERT_DEVINS(pDevIns);
398 LogFlow(("pdmR3IoApicHlp_Unlock: caller='%s'/%d:\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
399 pdmUnlock(pDevIns->Internal.s.pVMR3);
400}
401
402
403/** @copydoc PDMIOAPICHLPR3::pfnGetRCHelpers */
404static DECLCALLBACK(PCPDMIOAPICHLPRC) pdmR3IoApicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
405{
406 PDMDEV_ASSERT_DEVINS(pDevIns);
407 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
408 RTRCPTR pRCHelpers = 0;
409 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCIoApicHlp", &pRCHelpers);
410 AssertReleaseRC(rc);
411 AssertRelease(pRCHelpers);
412 LogFlow(("pdmR3IoApicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
413 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers));
414 return pRCHelpers;
415}
416
417
418/** @copydoc PDMIOAPICHLPR3::pfnGetR0Helpers */
419static DECLCALLBACK(PCPDMIOAPICHLPR0) pdmR3IoApicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
420{
421 PDMDEV_ASSERT_DEVINS(pDevIns);
422 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
423 PCPDMIOAPICHLPR0 pR0Helpers = 0;
424 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0IoApicHlp", &pR0Helpers);
425 AssertReleaseRC(rc);
426 AssertRelease(pR0Helpers);
427 LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
428 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers));
429 return pR0Helpers;
430}
431
432
433/**
434 * I/O APIC Device Helpers.
435 */
436const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp =
437{
438 PDM_IOAPICHLPR3_VERSION,
439 pdmR3IoApicHlp_ApicBusDeliver,
440 pdmR3IoApicHlp_Lock,
441 pdmR3IoApicHlp_Unlock,
442 pdmR3IoApicHlp_GetRCHelpers,
443 pdmR3IoApicHlp_GetR0Helpers,
444 PDM_IOAPICHLPR3_VERSION /* the end */
445};
446
447/** @} */
448
449
450
451
452/** @name HC PCI Bus Helpers
453 * @{
454 */
455
456/** @copydoc PDMPCIHLPR3::pfnIsaSetIrq */
457static DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
458{
459 PDMDEV_ASSERT_DEVINS(pDevIns);
460 Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
461 PDMIsaSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel);
462}
463
464
465/** @copydoc PDMPCIHLPR3::pfnIoApicSetIrq */
466static DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
467{
468 PDMDEV_ASSERT_DEVINS(pDevIns);
469 Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
470 PDMIoApicSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel);
471}
472
473
474/** @copydoc PDMPCIHLPR3::pfnIsMMIO2Base */
475static DECLCALLBACK(bool) pdmR3PciHlp_IsMMIO2Base(PPDMDEVINS pDevIns, PPDMDEVINS pOwner, RTGCPHYS GCPhys)
476{
477 PDMDEV_ASSERT_DEVINS(pDevIns);
478 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
479 bool fRc = PGMR3PhysMMIO2IsBase(pDevIns->Internal.s.pVMR3, pOwner, GCPhys);
480 Log4(("pdmR3PciHlp_IsMMIO2Base: pOwner=%p GCPhys=%RGp -> %RTbool\n", pOwner, GCPhys, fRc));
481 return fRc;
482}
483
484
485/** @copydoc PDMPCIHLPR3::pfnLock */
486static DECLCALLBACK(int) pdmR3PciHlp_Lock(PPDMDEVINS pDevIns, int rc)
487{
488 PDMDEV_ASSERT_DEVINS(pDevIns);
489 LogFlow(("pdmR3PciHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, rc));
490 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
491}
492
493
494/** @copydoc PDMPCIHLPR3::pfnUnlock */
495static DECLCALLBACK(void) pdmR3PciHlp_Unlock(PPDMDEVINS pDevIns)
496{
497 PDMDEV_ASSERT_DEVINS(pDevIns);
498 LogFlow(("pdmR3PciHlp_Unlock: caller='%s'/%d:\n", pDevIns->pDevReg->szDeviceName, pDevIns->iInstance));
499 pdmUnlock(pDevIns->Internal.s.pVMR3);
500}
501
502
503/** @copydoc PDMPCIHLPR3::pfnGetRCHelpers */
504static DECLCALLBACK(PCPDMPCIHLPRC) pdmR3PciHlp_GetRCHelpers(PPDMDEVINS pDevIns)
505{
506 PDMDEV_ASSERT_DEVINS(pDevIns);
507 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
508 RTRCPTR pRCHelpers = 0;
509 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCPciHlp", &pRCHelpers);
510 AssertReleaseRC(rc);
511 AssertRelease(pRCHelpers);
512 LogFlow(("pdmR3IoApicHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
513 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pRCHelpers));
514 return pRCHelpers;
515}
516
517
518/** @copydoc PDMPCIHLPR3::pfnGetR0Helpers */
519static DECLCALLBACK(PCPDMPCIHLPR0) pdmR3PciHlp_GetR0Helpers(PPDMDEVINS pDevIns)
520{
521 PDMDEV_ASSERT_DEVINS(pDevIns);
522 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
523 PCPDMPCIHLPR0 pR0Helpers = 0;
524 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0PciHlp", &pR0Helpers);
525 AssertReleaseRC(rc);
526 AssertRelease(pR0Helpers);
527 LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
528 pDevIns->pDevReg->szDeviceName, pDevIns->iInstance, pR0Helpers));
529 return pR0Helpers;
530}
531
532
533/**
534 * PCI Bus Device Helpers.
535 */
536const PDMPCIHLPR3 g_pdmR3DevPciHlp =
537{
538 PDM_PCIHLPR3_VERSION,
539 pdmR3PciHlp_IsaSetIrq,
540 pdmR3PciHlp_IoApicSetIrq,
541 pdmR3PciHlp_IsMMIO2Base,
542 pdmR3PciHlp_GetRCHelpers,
543 pdmR3PciHlp_GetR0Helpers,
544 pdmR3PciHlp_Lock,
545 pdmR3PciHlp_Unlock,
546 PDM_PCIHLPR3_VERSION, /* the end */
547};
548
549/** @} */
550
551
552
553/* none yet */
554
555/**
556 * DMAC Device Helpers.
557 */
558const PDMDMACHLP g_pdmR3DevDmacHlp =
559{
560 PDM_DMACHLP_VERSION
561};
562
563
564
565
566/* none yet */
567
568/**
569 * RTC Device Helpers.
570 */
571const PDMRTCHLP g_pdmR3DevRtcHlp =
572{
573 PDM_RTCHLP_VERSION
574};
575
576
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use