VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR0/PDMR0Device.cpp@ 6862

Last change on this file since 6862 was 5999, checked in by vboxsync, 17 years ago

The Giant CDDL Dual-License Header Change.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 19.9 KB
Line 
1/* $Id: PDMR0Device.cpp 5999 2007-12-07 15:05:06Z vboxsync $ */
2/** @file
3 * PDM - Pluggable Device and Driver Manager, R0 Device parts.
4 */
5
6/*
7 * Copyright (C) 2006-2007 innotek GmbH
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/pdm.h>
25#include <VBox/pgm.h>
26#include <VBox/mm.h>
27#include <VBox/vm.h>
28#include <VBox/patm.h>
29
30#include <VBox/log.h>
31#include <VBox/err.h>
32#include <iprt/asm.h>
33#include <iprt/assert.h>
34#include <iprt/string.h>
35
36
37/*******************************************************************************
38* Defined Constants And Macros *
39*******************************************************************************/
40/** @def PDMDEV_ASSERT_DEVINS
41 * Asserts the validity of the driver instance.
42 */
43#ifdef VBOX_STRICT
44# define PDMDEV_ASSERT_DEVINS(pDevIns) do { Assert(VALID_PTR(pDevIns)); \
45 Assert(pDevIns->u32Version == PDM_DEVINS_VERSION); \
46 Assert(pDevIns->pvInstanceDataR0 == (void *)&pDevIns->achInstanceData[0]); \
47 } while (0)
48#else
49# define PDMDEV_ASSERT_DEVINS(pDevIns) do { } while (0)
50#endif
51
52
53/*******************************************************************************
54* Global Variables *
55*******************************************************************************/
56__BEGIN_DECLS
57extern DECLEXPORT(const PDMDEVHLPR0) g_pdmR0DevHlp;
58extern DECLEXPORT(const PDMPICHLPR0) g_pdmR0PicHlp;
59extern DECLEXPORT(const PDMAPICHLPR0) g_pdmR0ApicHlp;
60extern DECLEXPORT(const PDMIOAPICHLPR0) g_pdmR0IoApicHlp;
61extern DECLEXPORT(const PDMPCIHLPR0) g_pdmR0PciHlp;
62__END_DECLS
63
64
65/*******************************************************************************
66* Internal Functions *
67*******************************************************************************/
68/** @name GC Device Helpers
69 * @{
70 */
71static DECLCALLBACK(void) pdmR0DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
72static DECLCALLBACK(void) pdmR0DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
73static DECLCALLBACK(void) pdmR0DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);
74static DECLCALLBACK(void) pdmR0DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
75static DECLCALLBACK(bool) pdmR0DevHlp_A20IsEnabled(PPDMDEVINS pDevIns);
76static DECLCALLBACK(int) pdmR0DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
77static DECLCALLBACK(int) pdmR0DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va);
78static DECLCALLBACK(int) pdmR0DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...);
79static DECLCALLBACK(int) pdmR0DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va);
80static DECLCALLBACK(int) pdmR0DevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData);
81/** @} */
82
83
84/** @name PIC GC Helpers
85 * @{
86 */
87static DECLCALLBACK(void) pdmR0PicHlp_SetInterruptFF(PPDMDEVINS pDevIns);
88static DECLCALLBACK(void) pdmR0PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);
89#ifdef VBOX_WITH_PDM_LOCK
90static DECLCALLBACK(int) pdmR0PicHlp_Lock(PPDMDEVINS pDevIns, int rc);
91static DECLCALLBACK(void) pdmR0PicHlp_Unlock(PPDMDEVINS pDevIns);
92#endif
93/** @} */
94
95
96/** @name APIC GC Helpers
97 * @{
98 */
99static DECLCALLBACK(void) pdmR0ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns);
100static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);
101static DECLCALLBACK(void) pdmR0ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, bool fEnabled);
102#ifdef VBOX_WITH_PDM_LOCK
103static DECLCALLBACK(int) pdmR0ApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
104static DECLCALLBACK(void) pdmR0ApicHlp_Unlock(PPDMDEVINS pDevIns);
105#endif
106/** @} */
107
108
109/** @name I/O APIC GC Helpers
110 * @{
111 */
112static DECLCALLBACK(void) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
113 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode);
114#ifdef VBOX_WITH_PDM_LOCK
115static DECLCALLBACK(int) pdmR0IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
116static DECLCALLBACK(void) pdmR0IoApicHlp_Unlock(PPDMDEVINS pDevIns);
117#endif
118/** @} */
119
120
121/** @name PCI Bus GC Helpers
122 * @{
123 */
124static DECLCALLBACK(void) pdmR0PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
125static DECLCALLBACK(void) pdmR0PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
126#ifdef VBOX_WITH_PDM_LOCK
127static DECLCALLBACK(int) pdmR0PciHlp_Lock(PPDMDEVINS pDevIns, int rc);
128static DECLCALLBACK(void) pdmR0PciHlp_Unlock(PPDMDEVINS pDevIns);
129#endif
130/** @} */
131
132
133static void pdmR0IsaSetIrq(PVM pVM, int iIrq, int iLevel);
134static void pdmR0IoApicSetIrq(PVM pVM, int iIrq, int iLevel);
135
136
137
138/**
139 * The Guest Context Device Helper Callbacks.
140 */
141extern DECLEXPORT(const PDMDEVHLPR0) g_pdmR0DevHlp =
142{
143 PDM_DEVHLPR0_VERSION,
144 pdmR0DevHlp_PCISetIrq,
145 pdmR0DevHlp_ISASetIrq,
146 pdmR0DevHlp_PhysRead,
147 pdmR0DevHlp_PhysWrite,
148 pdmR0DevHlp_A20IsEnabled,
149 pdmR0DevHlp_VMSetError,
150 pdmR0DevHlp_VMSetErrorV,
151 pdmR0DevHlp_VMSetRuntimeError,
152 pdmR0DevHlp_VMSetRuntimeErrorV,
153 pdmR0DevHlp_PATMSetMMIOPatchInfo,
154 PDM_DEVHLPR0_VERSION
155};
156
157/**
158 * The Guest Context PIC Helper Callbacks.
159 */
160extern DECLEXPORT(const PDMPICHLPR0) g_pdmR0PicHlp =
161{
162 PDM_PICHLPR0_VERSION,
163 pdmR0PicHlp_SetInterruptFF,
164 pdmR0PicHlp_ClearInterruptFF,
165#ifdef VBOX_WITH_PDM_LOCK
166 pdmR0PicHlp_Lock,
167 pdmR0PicHlp_Unlock,
168#endif
169 PDM_PICHLPR0_VERSION
170};
171
172
173/**
174 * The Guest Context APIC Helper Callbacks.
175 */
176extern DECLEXPORT(const PDMAPICHLPR0) g_pdmR0ApicHlp =
177{
178 PDM_APICHLPR0_VERSION,
179 pdmR0ApicHlp_SetInterruptFF,
180 pdmR0ApicHlp_ClearInterruptFF,
181 pdmR0ApicHlp_ChangeFeature,
182#ifdef VBOX_WITH_PDM_LOCK
183 pdmR0ApicHlp_Lock,
184 pdmR0ApicHlp_Unlock,
185#endif
186 PDM_APICHLPR0_VERSION
187};
188
189
190/**
191 * The Guest Context I/O APIC Helper Callbacks.
192 */
193extern DECLEXPORT(const PDMIOAPICHLPR0) g_pdmR0IoApicHlp =
194{
195 PDM_IOAPICHLPR0_VERSION,
196 pdmR0IoApicHlp_ApicBusDeliver,
197#ifdef VBOX_WITH_PDM_LOCK
198 pdmR0IoApicHlp_Lock,
199 pdmR0IoApicHlp_Unlock,
200#endif
201 PDM_IOAPICHLPR0_VERSION
202};
203
204
205/**
206 * The Guest Context PCI Bus Helper Callbacks.
207 */
208extern DECLEXPORT(const PDMPCIHLPR0) g_pdmR0PciHlp =
209{
210 PDM_PCIHLPR0_VERSION,
211 pdmR0PciHlp_IsaSetIrq,
212 pdmR0PciHlp_IoApicSetIrq,
213#ifdef VBOX_WITH_PDM_LOCK
214 pdmR0PciHlp_Lock,
215 pdmR0PciHlp_Unlock,
216#endif
217 PDM_PCIHLPR0_VERSION, /* the end */
218};
219
220
221
222
223/** @copydoc PDMDEVHLPR0::pfnPCISetIrq */
224static DECLCALLBACK(void) pdmR0DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
225{
226 PDMDEV_ASSERT_DEVINS(pDevIns);
227 LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
228
229 PVM pVM = pDevIns->Internal.s.pVMHC;
230 PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceHC;
231 PPDMPCIBUS pPciBus = pDevIns->Internal.s.pPciBusHC;
232 if ( pPciDev
233 && pPciBus
234 && pPciBus->pDevInsR0)
235 {
236 pdmLock(pVM);
237 pPciBus->pfnSetIrqR0(pPciBus->pDevInsR0, pPciDev, iIrq, iLevel);
238 pdmUnlock(pVM);
239 }
240 else
241 {
242 /* queue for ring-3 execution. */
243 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueHC);
244 if (pTask)
245 {
246 pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
247 pTask->pDevInsHC = pDevIns;
248 pTask->u.SetIRQ.iIrq = iIrq;
249 pTask->u.SetIRQ.iLevel = iLevel;
250
251 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueHC, &pTask->Core, 0);
252 }
253 else
254 AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
255 }
256
257 LogFlow(("pdmR0DevHlp_PCISetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
258}
259
260
261/** @copydoc PDMDEVHLPR0::pfnPCISetIrq */
262static DECLCALLBACK(void) pdmR0DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
263{
264 PDMDEV_ASSERT_DEVINS(pDevIns);
265 LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
266
267 pdmR0IsaSetIrq(pDevIns->Internal.s.pVMHC, iIrq, iLevel);
268
269 LogFlow(("pdmR0DevHlp_ISASetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
270}
271
272
273/** @copydoc PDMDEVHLPR0::pfnPhysRead */
274static DECLCALLBACK(void) pdmR0DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
275{
276 PDMDEV_ASSERT_DEVINS(pDevIns);
277 LogFlow(("pdmR0DevHlp_PhysRead: caller=%p/%d: GCPhys=%VGp pvBuf=%p cbRead=%#x\n",
278 pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
279
280 PGMPhysRead(pDevIns->Internal.s.pVMHC, GCPhys, pvBuf, cbRead);
281
282 Log(("pdmR0DevHlp_PhysRead: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
283}
284
285
286/** @copydoc PDMDEVHLPR0::pfnPhysWrite */
287static DECLCALLBACK(void) pdmR0DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
288{
289 PDMDEV_ASSERT_DEVINS(pDevIns);
290 LogFlow(("pdmR0DevHlp_PhysWrite: caller=%p/%d: GCPhys=%VGp pvBuf=%p cbWrite=%#x\n",
291 pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
292
293 PGMPhysWrite(pDevIns->Internal.s.pVMHC, GCPhys, pvBuf, cbWrite);
294
295 Log(("pdmR0DevHlp_PhysWrite: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
296}
297
298
299/** @copydoc PDMDEVHLPR0::pfnA20IsEnabled */
300static DECLCALLBACK(bool) pdmR0DevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
301{
302 PDMDEV_ASSERT_DEVINS(pDevIns);
303 LogFlow(("pdmR0DevHlp_A20IsEnabled: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
304
305 bool fEnabled = PGMPhysIsA20Enabled(pDevIns->Internal.s.pVMHC);
306
307 Log(("pdmR0DevHlp_A20IsEnabled: caller=%p/%d: returns %RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
308 return fEnabled;
309}
310
311
312/** @copydoc PDMDEVHLPR0::pfnVMSetError */
313static DECLCALLBACK(int) pdmR0DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
314{
315 PDMDEV_ASSERT_DEVINS(pDevIns);
316 va_list args;
317 va_start(args, pszFormat);
318 int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMHC, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
319 va_end(args);
320 return rc;
321}
322
323
324/** @copydoc PDMDEVHLPR0::pfnVMSetErrorV */
325static DECLCALLBACK(int) pdmR0DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
326{
327 PDMDEV_ASSERT_DEVINS(pDevIns);
328 int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMHC, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
329 return rc;
330}
331
332
333/** @copydoc PDMDEVHLPR0::pfnVMSetRuntimeError */
334static DECLCALLBACK(int) pdmR0DevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...)
335{
336 PDMDEV_ASSERT_DEVINS(pDevIns);
337 va_list args;
338 va_start(args, pszFormat);
339 int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMHC, fFatal, pszErrorID, pszFormat, args);
340 va_end(args);
341 return rc;
342}
343
344
345/** @copydoc PDMDEVHLPR0::pfnVMSetRuntimeErrorV */
346static DECLCALLBACK(int) pdmR0DevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va)
347{
348 PDMDEV_ASSERT_DEVINS(pDevIns);
349 int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMHC, fFatal, pszErrorID, pszFormat, va);
350 return rc;
351}
352
353
354/** @copydoc PDMDEVHLPR0::pdmR0DevHlp_PATMSetMMIOPatchInfo*/
355static DECLCALLBACK(int) pdmR0DevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData)
356{
357 PDMDEV_ASSERT_DEVINS(pDevIns);
358 LogFlow(("pdmR0DevHlp_PATMSetMMIOPatchInfo: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
359
360 AssertFailed();
361
362/* return PATMSetMMIOPatchInfo(pDevIns->Internal.s.pVMHC, GCPhys, pCachedData); */
363 return VINF_SUCCESS;
364}
365
366
367
368
369
370/** @copydoc PDMPICHLPGC::pfnSetInterruptFF */
371static DECLCALLBACK(void) pdmR0PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
372{
373 PDMDEV_ASSERT_DEVINS(pDevIns);
374 LogFlow(("pdmR0PicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT_PIC %d -> 1\n",
375 pDevIns, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_PIC)));
376 VM_FF_SET(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_PIC);
377}
378
379
380/** @copydoc PDMPICHLPGC::pfnClearInterruptFF */
381static DECLCALLBACK(void) pdmR0PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
382{
383 PDMDEV_ASSERT_DEVINS(pDevIns);
384 LogFlow(("pdmR0PicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT_PIC %d -> 0\n",
385 pDevIns, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_PIC)));
386 VM_FF_CLEAR(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_PIC);
387}
388
389
390#ifdef VBOX_WITH_PDM_LOCK
391/** @copydoc PDMPICHLPR0::pfnLock */
392static DECLCALLBACK(int) pdmR0PicHlp_Lock(PPDMDEVINS pDevIns, int rc)
393{
394 PDMDEV_ASSERT_DEVINS(pDevIns);
395 return pdmLockEx(pDevIns->Internal.s.pVMHC, rc);
396}
397
398
399/** @copydoc PDMPICHLPR0::pfnUnlock */
400static DECLCALLBACK(void) pdmR0PicHlp_Unlock(PPDMDEVINS pDevIns)
401{
402 PDMDEV_ASSERT_DEVINS(pDevIns);
403 pdmUnlock(pDevIns->Internal.s.pVMHC);
404}
405#endif /* VBOX_WITH_PDM_LOCK */
406
407
408
409
410/** @copydoc PDMAPICHLPGC::pfnSetInterruptFF */
411static DECLCALLBACK(void) pdmR0ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
412{
413 PDMDEV_ASSERT_DEVINS(pDevIns);
414 LogFlow(("pdmR0ApicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 1\n",
415 pDevIns, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_APIC)));
416 VM_FF_SET(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_APIC);
417}
418
419
420/** @copydoc PDMAPICHLPGC::pfnClearInterruptFF */
421static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
422{
423 PDMDEV_ASSERT_DEVINS(pDevIns);
424 LogFlow(("pdmR0ApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
425 pDevIns, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_APIC)));
426 VM_FF_CLEAR(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_APIC);
427}
428
429
430/** @copydoc PDMAPICHLPGC::pfnChangeFeature */
431static DECLCALLBACK(void) pdmR0ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, bool fEnabled)
432{
433 PDMDEV_ASSERT_DEVINS(pDevIns);
434 LogFlow(("pdmR0ApicHlp_ChangeFeature: caller=%p/%d: fEnabled=%RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
435 if (fEnabled)
436 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMHC, CPUMCPUIDFEATURE_APIC);
437 else
438 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMHC, CPUMCPUIDFEATURE_APIC);
439}
440
441
442#ifdef VBOX_WITH_PDM_LOCK
443/** @copydoc PDMAPICHLPR0::pfnLock */
444static DECLCALLBACK(int) pdmR0ApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
445{
446 PDMDEV_ASSERT_DEVINS(pDevIns);
447 return pdmLockEx(pDevIns->Internal.s.pVMHC, rc);
448}
449
450
451/** @copydoc PDMAPICHLPR0::pfnUnlock */
452static DECLCALLBACK(void) pdmR0ApicHlp_Unlock(PPDMDEVINS pDevIns)
453{
454 PDMDEV_ASSERT_DEVINS(pDevIns);
455 pdmUnlock(pDevIns->Internal.s.pVMHC);
456}
457#endif /* VBOX_WITH_PDM_LOCK */
458
459
460
461
462/** @copydoc PDMIOAPICHLPR0::pfnApicBusDeliver */
463static DECLCALLBACK(void) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
464 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
465{
466 PDMDEV_ASSERT_DEVINS(pDevIns);
467 PVM pVM = pDevIns->Internal.s.pVMHC;
468 LogFlow(("pdmR0IoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
469 pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
470 Assert(pVM->pdm.s.Apic.pDevInsR0);
471 if (pVM->pdm.s.Apic.pfnBusDeliverR0)
472 pVM->pdm.s.Apic.pfnBusDeliverR0(pVM->pdm.s.Apic.pDevInsR0, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
473}
474
475
476#ifdef VBOX_WITH_PDM_LOCK
477/** @copydoc PDMIOAPICHLPR0::pfnLock */
478static DECLCALLBACK(int) pdmR0IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
479{
480 PDMDEV_ASSERT_DEVINS(pDevIns);
481 return pdmLockEx(pDevIns->Internal.s.pVMHC, rc);
482}
483
484
485/** @copydoc PDMIOAPICHLPR0::pfnUnlock */
486static DECLCALLBACK(void) pdmR0IoApicHlp_Unlock(PPDMDEVINS pDevIns)
487{
488 PDMDEV_ASSERT_DEVINS(pDevIns);
489 pdmUnlock(pDevIns->Internal.s.pVMHC);
490}
491#endif /* VBOX_WITH_PDM_LOCK */
492
493
494
495
496
497/** @copydoc PDMPCIHLPR0::pfnIsaSetIrq */
498static DECLCALLBACK(void) pdmR0PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
499{
500 PDMDEV_ASSERT_DEVINS(pDevIns);
501 Log4(("pdmR0PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
502 pdmR0IsaSetIrq(pDevIns->Internal.s.pVMHC, iIrq, iLevel);
503}
504
505
506/** @copydoc PDMPCIHLPR0::pfnIoApicSetIrq */
507static DECLCALLBACK(void) pdmR0PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
508{
509 PDMDEV_ASSERT_DEVINS(pDevIns);
510 Log4(("pdmR0PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
511 pdmR0IoApicSetIrq(pDevIns->Internal.s.pVMHC, iIrq, iLevel);
512}
513
514
515#ifdef VBOX_WITH_PDM_LOCK
516/** @copydoc PDMPCIHLPR0::pfnLock */
517static DECLCALLBACK(int) pdmR0PciHlp_Lock(PPDMDEVINS pDevIns, int rc)
518{
519 PDMDEV_ASSERT_DEVINS(pDevIns);
520 return pdmLockEx(pDevIns->Internal.s.pVMHC, rc);
521}
522
523
524/** @copydoc PDMPCIHLPR0::pfnUnlock */
525static DECLCALLBACK(void) pdmR0PciHlp_Unlock(PPDMDEVINS pDevIns)
526{
527 PDMDEV_ASSERT_DEVINS(pDevIns);
528 pdmUnlock(pDevIns->Internal.s.pVMHC);
529}
530#endif /* VBOX_WITH_PDM_LOCK */
531
532
533
534
535/**
536 * Sets an irq on the I/O APIC.
537 *
538 * @param pVM The VM handle.
539 * @param iIrq The irq.
540 * @param iLevel The new level.
541 */
542static void pdmR0IsaSetIrq(PVM pVM, int iIrq, int iLevel)
543{
544 if ( ( pVM->pdm.s.IoApic.pDevInsR0
545 || !pVM->pdm.s.IoApic.pDevInsR3)
546 && ( pVM->pdm.s.Pic.pDevInsR0
547 || !pVM->pdm.s.Pic.pDevInsR3))
548 {
549 pdmLock(pVM);
550 if (pVM->pdm.s.Pic.pDevInsR0)
551 pVM->pdm.s.Pic.pfnSetIrqR0(pVM->pdm.s.Pic.pDevInsR0, iIrq, iLevel);
552 if (pVM->pdm.s.IoApic.pDevInsR0)
553 pVM->pdm.s.IoApic.pfnSetIrqR0(pVM->pdm.s.IoApic.pDevInsR0, iIrq, iLevel);
554 pdmUnlock(pVM);
555 }
556 else
557 {
558 /* queue for ring-3 execution. */
559 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueHC);
560 if (pTask)
561 {
562 pTask->enmOp = PDMDEVHLPTASKOP_ISA_SET_IRQ;
563 pTask->pDevInsHC = 0; /* not required */
564 pTask->u.SetIRQ.iIrq = iIrq;
565 pTask->u.SetIRQ.iLevel = iLevel;
566
567 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueHC, &pTask->Core, 0);
568 }
569 else
570 AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
571 }
572}
573
574
575/**
576 * Sets an irq on the I/O APIC.
577 *
578 * @param pVM The VM handle.
579 * @param iIrq The irq.
580 * @param iLevel The new level.
581 */
582static void pdmR0IoApicSetIrq(PVM pVM, int iIrq, int iLevel)
583{
584 if (pVM->pdm.s.IoApic.pDevInsR0)
585 {
586 pdmLock(pVM);
587 pVM->pdm.s.IoApic.pfnSetIrqR0(pVM->pdm.s.IoApic.pDevInsR0, iIrq, iLevel);
588 pdmUnlock(pVM);
589 }
590 else if (pVM->pdm.s.IoApic.pDevInsR3)
591 {
592 /* queue for ring-3 execution. */
593 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueHC);
594 if (pTask)
595 {
596 pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_IRQ;
597 pTask->pDevInsHC = 0; /* not required */
598 pTask->u.SetIRQ.iIrq = iIrq;
599 pTask->u.SetIRQ.iLevel = iLevel;
600
601 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueHC, &pTask->Core, 0);
602 }
603 else
604 AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
605 }
606}
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