VirtualBox

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

Last change on this file since 64596 was 64596, checked in by vboxsync, 8 years ago

VMM/APIC, PDM: Clean up PDM APIC helper interface, call VMM directly instead.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 18.7 KB
Line 
1/* $Id: PDMDevMiscHlp.cpp 64596 2016-11-08 15:03:18Z vboxsync $ */
2/** @file
3 * PDM - Pluggable Device and Driver Manager, Misc. Device Helpers.
4 */
5
6/*
7 * Copyright (C) 2006-2016 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 PVMCPU pVCpu = &pVM->aCpus[0]; /* for PIC we always deliver to CPU 0, MP use APIC */
55
56 if (pVM->pdm.s.Apic.pfnLocalInterruptR3)
57 {
58 LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: Setting local interrupt on LAPIC\n",
59 pDevIns->pReg->szName, pDevIns->iInstance));
60
61 /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
62 /** @todo 'rcRZ' propagation to pfnLocalInterrupt from caller. */
63 pVM->pdm.s.Apic.pfnLocalInterruptR3(pVM->pdm.s.Apic.pDevInsR3, pVCpu, 0 /* u8Pin */, 1 /* u8Level */,
64 VINF_SUCCESS /* rcRZ */);
65 return;
66 }
67
68 LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_PIC %d -> 1\n",
69 pDevIns->pReg->szName, pDevIns->iInstance, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
70
71 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
72#ifdef VBOX_WITH_REM
73 REMR3NotifyInterruptSet(pVM, pVCpu);
74#endif
75 VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
76}
77
78
79/** @interface_method_impl{PDMPICHLPR3,pfnClearInterruptFF} */
80static DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
81{
82 PDMDEV_ASSERT_DEVINS(pDevIns);
83 PVM pVM = pDevIns->Internal.s.pVMR3;
84 PVMCPU pVCpu = &pVM->aCpus[0]; /* for PIC we always deliver to CPU 0, MP use APIC */
85
86 if (pVM->pdm.s.Apic.pfnLocalInterruptR3)
87 {
88 /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
89 LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
90 pDevIns->pReg->szName, pDevIns->iInstance));
91
92 /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
93 /** @todo 'rcRZ' propagation to pfnLocalInterrupt from caller. */
94 pVM->pdm.s.Apic.pfnLocalInterruptR3(pVM->pdm.s.Apic.pDevInsR3, pVCpu, 0 /* u8Pin */, 0 /* u8Level */,
95 VINF_SUCCESS /* rcRZ */);
96 return;
97 }
98
99 LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
100 pDevIns->pReg->szName, pDevIns->iInstance, VMCPU_FF_IS_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
101
102 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
103#ifdef VBOX_WITH_REM
104 REMR3NotifyInterruptClear(pVM, pVCpu);
105#endif
106}
107
108
109/** @interface_method_impl{PDMPICHLPR3,pfnLock} */
110static DECLCALLBACK(int) pdmR3PicHlp_Lock(PPDMDEVINS pDevIns, int rc)
111{
112 PDMDEV_ASSERT_DEVINS(pDevIns);
113 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
114}
115
116
117/** @interface_method_impl{PDMPICHLPR3,pfnUnlock} */
118static DECLCALLBACK(void) pdmR3PicHlp_Unlock(PPDMDEVINS pDevIns)
119{
120 PDMDEV_ASSERT_DEVINS(pDevIns);
121 pdmUnlock(pDevIns->Internal.s.pVMR3);
122}
123
124
125/** @interface_method_impl{PDMPICHLPR3,pfnGetRCHelpers} */
126static DECLCALLBACK(PCPDMPICHLPRC) pdmR3PicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
127{
128 PDMDEV_ASSERT_DEVINS(pDevIns);
129 PVM pVM = pDevIns->Internal.s.pVMR3;
130 VM_ASSERT_EMT(pVM);
131
132 RTRCPTR pRCHelpers = NIL_RTRCPTR;
133 if (!HMIsEnabled(pVM))
134 {
135 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCPicHlp", &pRCHelpers);
136 AssertReleaseRC(rc);
137 AssertRelease(pRCHelpers);
138 }
139
140 LogFlow(("pdmR3PicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
141 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
142 return pRCHelpers;
143}
144
145
146/** @interface_method_impl{PDMPICHLPR3,pfnGetR0Helpers} */
147static DECLCALLBACK(PCPDMPICHLPR0) pdmR3PicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
148{
149 PDMDEV_ASSERT_DEVINS(pDevIns);
150 PVM pVM = pDevIns->Internal.s.pVMR3;
151 VM_ASSERT_EMT(pVM);
152 PCPDMPICHLPR0 pR0Helpers = 0;
153 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0PicHlp", &pR0Helpers);
154 AssertReleaseRC(rc);
155 AssertRelease(pR0Helpers);
156 LogFlow(("pdmR3PicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
157 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
158 return pR0Helpers;
159}
160
161
162/**
163 * PIC Device Helpers.
164 */
165const PDMPICHLPR3 g_pdmR3DevPicHlp =
166{
167 PDM_PICHLPR3_VERSION,
168 pdmR3PicHlp_SetInterruptFF,
169 pdmR3PicHlp_ClearInterruptFF,
170 pdmR3PicHlp_Lock,
171 pdmR3PicHlp_Unlock,
172 pdmR3PicHlp_GetRCHelpers,
173 pdmR3PicHlp_GetR0Helpers,
174 PDM_PICHLPR3_VERSION /* the end */
175};
176
177/** @} */
178
179
180/** @name Ring-3 I/O APIC Helpers
181 * @{
182 */
183
184/** @interface_method_impl{PDMIOAPICHLPR3,pfnApicBusDeliver} */
185static DECLCALLBACK(int) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
186 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc)
187{
188 PDMDEV_ASSERT_DEVINS(pDevIns);
189 PVM pVM = pDevIns->Internal.s.pVMR3;
190 LogFlow(("pdmR3IoApicHlp_ApicBusDeliver: caller='%s'/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
191 pDevIns->pReg->szName, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc));
192 if (pVM->pdm.s.Apic.pfnBusDeliverR3)
193 return pVM->pdm.s.Apic.pfnBusDeliverR3(pVM->pdm.s.Apic.pDevInsR3, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc);
194 return VINF_SUCCESS;
195}
196
197
198/** @interface_method_impl{PDMIOAPICHLPR3,pfnLock} */
199static DECLCALLBACK(int) pdmR3IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
200{
201 PDMDEV_ASSERT_DEVINS(pDevIns);
202 LogFlow(("pdmR3IoApicHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
203 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
204}
205
206
207/** @interface_method_impl{PDMIOAPICHLPR3,pfnUnlock} */
208static DECLCALLBACK(void) pdmR3IoApicHlp_Unlock(PPDMDEVINS pDevIns)
209{
210 PDMDEV_ASSERT_DEVINS(pDevIns);
211 LogFlow(("pdmR3IoApicHlp_Unlock: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
212 pdmUnlock(pDevIns->Internal.s.pVMR3);
213}
214
215
216/** @interface_method_impl{PDMIOAPICHLPR3,pfnGetRCHelpers} */
217static DECLCALLBACK(PCPDMIOAPICHLPRC) pdmR3IoApicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
218{
219 PDMDEV_ASSERT_DEVINS(pDevIns);
220 PVM pVM = pDevIns->Internal.s.pVMR3;
221 VM_ASSERT_EMT(pVM);
222
223 RTRCPTR pRCHelpers = NIL_RTRCPTR;
224 if (!HMIsEnabled(pVM))
225 {
226 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCIoApicHlp", &pRCHelpers);
227 AssertReleaseRC(rc);
228 AssertRelease(pRCHelpers);
229 }
230
231 LogFlow(("pdmR3IoApicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
232 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
233 return pRCHelpers;
234}
235
236
237/** @interface_method_impl{PDMIOAPICHLPR3,pfnGetR0Helpers} */
238static DECLCALLBACK(PCPDMIOAPICHLPR0) pdmR3IoApicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
239{
240 PDMDEV_ASSERT_DEVINS(pDevIns);
241 PVM pVM = pDevIns->Internal.s.pVMR3;
242 VM_ASSERT_EMT(pVM);
243 PCPDMIOAPICHLPR0 pR0Helpers = 0;
244 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0IoApicHlp", &pR0Helpers);
245 AssertReleaseRC(rc);
246 AssertRelease(pR0Helpers);
247 LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
248 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
249 return pR0Helpers;
250}
251
252
253/**
254 * I/O APIC Device Helpers.
255 */
256const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp =
257{
258 PDM_IOAPICHLPR3_VERSION,
259 pdmR3IoApicHlp_ApicBusDeliver,
260 pdmR3IoApicHlp_Lock,
261 pdmR3IoApicHlp_Unlock,
262 pdmR3IoApicHlp_GetRCHelpers,
263 pdmR3IoApicHlp_GetR0Helpers,
264 PDM_IOAPICHLPR3_VERSION /* the end */
265};
266
267/** @} */
268
269
270
271
272/** @name Ring-3 PCI Bus Helpers
273 * @{
274 */
275
276/** @interface_method_impl{PDMPCIHLPR3,pfnIsaSetIrq} */
277static DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
278{
279 PDMDEV_ASSERT_DEVINS(pDevIns);
280 Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
281 PDMIsaSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel, uTagSrc);
282}
283
284/** @interface_method_impl{PDMPCIHLPR3,pfnIoApicSetIrq} */
285static DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
286{
287 PDMDEV_ASSERT_DEVINS(pDevIns);
288 Log4(("pdmR3PciHlp_IoApicSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
289 PDMIoApicSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel, uTagSrc);
290}
291
292/** @interface_method_impl{PDMPCIHLPR3,pfnIoApicSendMsi} */
293static DECLCALLBACK(void) pdmR3PciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, uint32_t uValue, uint32_t uTagSrc)
294{
295 PDMDEV_ASSERT_DEVINS(pDevIns);
296 Log4(("pdmR3PciHlp_IoApicSendMsi: address=%p value=%x uTagSrc=%#x\n", GCPhys, uValue, uTagSrc));
297 PDMIoApicSendMsi(pDevIns->Internal.s.pVMR3, GCPhys, uValue, uTagSrc);
298}
299
300/** @interface_method_impl{PDMPCIHLPR3,pfnIsMMIOExBase} */
301static DECLCALLBACK(bool) pdmR3PciHlp_IsMMIO2Base(PPDMDEVINS pDevIns, PPDMDEVINS pOwner, RTGCPHYS GCPhys)
302{
303 PDMDEV_ASSERT_DEVINS(pDevIns);
304 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
305 bool fRc = PGMR3PhysMMIOExIsBase(pDevIns->Internal.s.pVMR3, pOwner, GCPhys);
306 Log4(("pdmR3PciHlp_IsMMIOExBase: pOwner=%p GCPhys=%RGp -> %RTbool\n", pOwner, GCPhys, fRc));
307 return fRc;
308}
309
310
311/** @interface_method_impl{PDMPCIHLPR3,pfnLock} */
312static DECLCALLBACK(int) pdmR3PciHlp_Lock(PPDMDEVINS pDevIns, int rc)
313{
314 PDMDEV_ASSERT_DEVINS(pDevIns);
315 LogFlow(("pdmR3PciHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
316 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
317}
318
319
320/** @interface_method_impl{PDMPCIHLPR3,pfnUnlock} */
321static DECLCALLBACK(void) pdmR3PciHlp_Unlock(PPDMDEVINS pDevIns)
322{
323 PDMDEV_ASSERT_DEVINS(pDevIns);
324 LogFlow(("pdmR3PciHlp_Unlock: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
325 pdmUnlock(pDevIns->Internal.s.pVMR3);
326}
327
328
329/** @interface_method_impl{PDMPCIHLPR3,pfnGetRCHelpers} */
330static DECLCALLBACK(PCPDMPCIHLPRC) pdmR3PciHlp_GetRCHelpers(PPDMDEVINS pDevIns)
331{
332 PDMDEV_ASSERT_DEVINS(pDevIns);
333 PVM pVM = pDevIns->Internal.s.pVMR3;
334 VM_ASSERT_EMT(pVM);
335
336 RTRCPTR pRCHelpers = NIL_RTRCPTR;
337 if (!HMIsEnabled(pVM))
338 {
339 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCPciHlp", &pRCHelpers);
340 AssertReleaseRC(rc);
341 AssertRelease(pRCHelpers);
342 }
343
344 LogFlow(("pdmR3PciHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
345 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
346 return pRCHelpers;
347}
348
349
350/** @interface_method_impl{PDMPCIHLPR3,pfnGetR0Helpers} */
351static DECLCALLBACK(PCPDMPCIHLPR0) pdmR3PciHlp_GetR0Helpers(PPDMDEVINS pDevIns)
352{
353 PDMDEV_ASSERT_DEVINS(pDevIns);
354 PVM pVM = pDevIns->Internal.s.pVMR3;
355 VM_ASSERT_EMT(pVM);
356 PCPDMPCIHLPR0 pR0Helpers = 0;
357 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0PciHlp", &pR0Helpers);
358 AssertReleaseRC(rc);
359 AssertRelease(pR0Helpers);
360 LogFlow(("pdmR3PciHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
361 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
362 return pR0Helpers;
363}
364
365
366/**
367 * PCI Bus Device Helpers.
368 */
369const PDMPCIHLPR3 g_pdmR3DevPciHlp =
370{
371 PDM_PCIHLPR3_VERSION,
372 pdmR3PciHlp_IsaSetIrq,
373 pdmR3PciHlp_IoApicSetIrq,
374 pdmR3PciHlp_IoApicSendMsi,
375 pdmR3PciHlp_IsMMIO2Base,
376 pdmR3PciHlp_GetRCHelpers,
377 pdmR3PciHlp_GetR0Helpers,
378 pdmR3PciHlp_Lock,
379 pdmR3PciHlp_Unlock,
380 PDM_PCIHLPR3_VERSION, /* the end */
381};
382
383/** @} */
384
385
386
387
388/** @name Ring-3 HPET Helpers
389 * {@
390 */
391
392/** @interface_method_impl{PDMHPETHLPR3,pfnSetLegacyMode} */
393static DECLCALLBACK(int) pdmR3HpetHlp_SetLegacyMode(PPDMDEVINS pDevIns, bool fActivated)
394{
395 PDMDEV_ASSERT_DEVINS(pDevIns);
396 LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: fActivated=%RTbool\n", pDevIns->pReg->szName, pDevIns->iInstance, fActivated));
397
398 size_t i;
399 int rc = VINF_SUCCESS;
400 static const char * const s_apszDevsToNotify[] =
401 {
402 "i8254",
403 "mc146818"
404 };
405 for (i = 0; i < RT_ELEMENTS(s_apszDevsToNotify); i++)
406 {
407 PPDMIBASE pBase;
408 rc = PDMR3QueryDevice(pDevIns->Internal.s.pVMR3->pUVM, "i8254", 0, &pBase);
409 if (RT_SUCCESS(rc))
410 {
411 PPDMIHPETLEGACYNOTIFY pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIHPETLEGACYNOTIFY);
412 AssertLogRelMsgBreakStmt(pPort, ("%s\n", s_apszDevsToNotify[i]), rc = VERR_PDM_HPET_LEGACY_NOTIFY_MISSING);
413 pPort->pfnModeChanged(pPort, fActivated);
414 }
415 else if ( rc == VERR_PDM_DEVICE_NOT_FOUND
416 || rc == VERR_PDM_DEVICE_INSTANCE_NOT_FOUND)
417 rc = VINF_SUCCESS; /* the device isn't configured, ignore. */
418 else
419 AssertLogRelMsgFailedBreak(("%s -> %Rrc\n", s_apszDevsToNotify[i], rc));
420 }
421
422 /* Don't bother cleaning up, any failure here will cause a guru meditation. */
423
424 LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
425 return rc;
426}
427
428
429/** @interface_method_impl{PDMHPETHLPR3,pfnSetIrq} */
430static DECLCALLBACK(int) pdmR3HpetHlp_SetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
431{
432 PDMDEV_ASSERT_DEVINS(pDevIns);
433 LogFlow(("pdmR3HpetHlp_SetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, iIrq, iLevel));
434 PVM pVM = pDevIns->Internal.s.pVMR3;
435
436 pdmLock(pVM);
437 uint32_t uTagSrc;
438 if (iLevel & PDM_IRQ_LEVEL_HIGH)
439 {
440 pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
441 if (iLevel == PDM_IRQ_LEVEL_HIGH)
442 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
443 else
444 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
445 }
446 else
447 uTagSrc = pDevIns->Internal.s.uLastIrqTag;
448
449 PDMIsaSetIrq(pVM, iIrq, iLevel, uTagSrc); /* (The API takes the lock recursively.) */
450
451 if (iLevel == PDM_IRQ_LEVEL_LOW)
452 VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
453 pdmUnlock(pVM);
454 return 0;
455}
456
457
458/** @interface_method_impl{PDMHPETHLPR3,pfnGetRCHelpers} */
459static DECLCALLBACK(PCPDMHPETHLPRC) pdmR3HpetHlp_GetRCHelpers(PPDMDEVINS pDevIns)
460{
461 PDMDEV_ASSERT_DEVINS(pDevIns);
462 PVM pVM = pDevIns->Internal.s.pVMR3;
463 VM_ASSERT_EMT(pVM);
464
465 RTRCPTR pRCHelpers = NIL_RTRCPTR;
466 if (!HMIsEnabled(pVM))
467 {
468 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCHpetHlp", &pRCHelpers);
469 AssertReleaseRC(rc);
470 AssertRelease(pRCHelpers);
471 }
472
473 LogFlow(("pdmR3HpetHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
474 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
475 return pRCHelpers;
476}
477
478
479/** @interface_method_impl{PDMHPETHLPR3,pfnGetR0Helpers} */
480static DECLCALLBACK(PCPDMHPETHLPR0) pdmR3HpetHlp_GetR0Helpers(PPDMDEVINS pDevIns)
481{
482 PDMDEV_ASSERT_DEVINS(pDevIns);
483 PVM pVM = pDevIns->Internal.s.pVMR3;
484 VM_ASSERT_EMT(pVM);
485 PCPDMHPETHLPR0 pR0Helpers = 0;
486 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0HpetHlp", &pR0Helpers);
487 AssertReleaseRC(rc);
488 AssertRelease(pR0Helpers);
489 LogFlow(("pdmR3HpetHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
490 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
491 return pR0Helpers;
492}
493
494
495/**
496 * HPET Device Helpers.
497 */
498const PDMHPETHLPR3 g_pdmR3DevHpetHlp =
499{
500 PDM_HPETHLPR3_VERSION,
501 pdmR3HpetHlp_GetRCHelpers,
502 pdmR3HpetHlp_GetR0Helpers,
503 pdmR3HpetHlp_SetLegacyMode,
504 pdmR3HpetHlp_SetIrq,
505 PDM_HPETHLPR3_VERSION, /* the end */
506};
507
508/** @} */
509
510
511/** @name Ring-3 Raw PCI Device Helpers
512 * {@
513 */
514
515/** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetRCHelpers} */
516static DECLCALLBACK(PCPDMPCIRAWHLPRC) pdmR3PciRawHlp_GetRCHelpers(PPDMDEVINS pDevIns)
517{
518 PDMDEV_ASSERT_DEVINS(pDevIns);
519 PVM pVM = pDevIns->Internal.s.pVMR3;
520 VM_ASSERT_EMT(pVM);
521
522 RTRCPTR pRCHelpers = NIL_RTRCPTR;
523 if (!HMIsEnabled(pVM))
524 {
525 int rc = PDMR3LdrGetSymbolRC(pVM, NULL, "g_pdmRCPciRawHlp", &pRCHelpers);
526 AssertReleaseRC(rc);
527 AssertRelease(pRCHelpers);
528 }
529
530 LogFlow(("pdmR3PciRawHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
531 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
532 return pRCHelpers;
533}
534
535
536/** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetR0Helpers} */
537static DECLCALLBACK(PCPDMPCIRAWHLPR0) pdmR3PciRawHlp_GetR0Helpers(PPDMDEVINS pDevIns)
538{
539 PDMDEV_ASSERT_DEVINS(pDevIns);
540 PVM pVM = pDevIns->Internal.s.pVMR3;
541 VM_ASSERT_EMT(pVM);
542 PCPDMHPETHLPR0 pR0Helpers = NIL_RTR0PTR;
543 int rc = PDMR3LdrGetSymbolR0(pVM, NULL, "g_pdmR0PciRawHlp", &pR0Helpers);
544 AssertReleaseRC(rc);
545 AssertRelease(pR0Helpers);
546 LogFlow(("pdmR3PciRawHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
547 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
548 return pR0Helpers;
549}
550
551
552/**
553 * Raw PCI Device Helpers.
554 */
555const PDMPCIRAWHLPR3 g_pdmR3DevPciRawHlp =
556{
557 PDM_PCIRAWHLPR3_VERSION,
558 pdmR3PciRawHlp_GetRCHelpers,
559 pdmR3PciRawHlp_GetR0Helpers,
560 PDM_PCIRAWHLPR3_VERSION, /* the end */
561};
562
563/** @} */
564
565
566/* none yet */
567
568/**
569 * Firmware Device Helpers.
570 */
571const PDMFWHLPR3 g_pdmR3DevFirmwareHlp =
572{
573 PDM_FWHLPR3_VERSION,
574 PDM_FWHLPR3_VERSION
575};
576
577/**
578 * DMAC Device Helpers.
579 */
580const PDMDMACHLP g_pdmR3DevDmacHlp =
581{
582 PDM_DMACHLP_VERSION
583};
584
585
586
587
588/* none yet */
589
590/**
591 * RTC Device Helpers.
592 */
593const PDMRTCHLP g_pdmR3DevRtcHlp =
594{
595 PDM_RTCHLP_VERSION
596};
597
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