VirtualBox

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

Last change on this file since 1272 was 23, checked in by vboxsync, 18 years ago

string.h & stdio.h + header cleanups.

  • Property svn:keywords set to Id
File size: 19.5 KB
Line 
1/* $Id: PDMR0Device.cpp 23 2007-01-15 14:08:28Z vboxsync $ */
2/** @file
3 * PDM - Pluggable Device and Driver Manager, R0 Device parts.
4 */
5
6/*
7 * Copyright (C) 2006 InnoTek Systemberatung 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 as published by the Free Software Foundation,
13 * in version 2 as it comes in the "COPYING" file of the VirtualBox OSE
14 * distribution. VirtualBox OSE is distributed in the hope that it will
15 * be useful, but WITHOUT ANY WARRANTY of any kind.
16 *
17 * If you received this file as part of a commercial VirtualBox
18 * distribution, then only the terms of your commercial VirtualBox
19 * license agreement apply instead of the previous paragraph.
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/pgm.h>
30#include <VBox/mm.h>
31#include <VBox/vm.h>
32#include <VBox/patm.h>
33
34#include <VBox/log.h>
35#include <VBox/err.h>
36#include <iprt/asm.h>
37#include <iprt/assert.h>
38#include <iprt/string.h>
39
40
41/*******************************************************************************
42* Defined Constants And Macros *
43*******************************************************************************/
44/** @def PDMDEV_ASSERT_DEVINS
45 * Asserts the validity of the driver instance.
46 */
47#ifdef VBOX_STRICT
48# define PDMDEV_ASSERT_DEVINS(pDevIns) do { Assert(VALID_PTR(pDevIns)); \
49 Assert(pDevIns->u32Version == PDM_DEVINS_VERSION); \
50 Assert(pDevIns->pvInstanceDataHC == (void *)&pDevIns->achInstanceData[0]); \
51 } while (0)
52#else
53# define PDMDEV_ASSERT_DEVINS(pDevIns) do { } while (0)
54#endif
55
56
57/*******************************************************************************
58* Global Variables *
59*******************************************************************************/
60__BEGIN_DECLS
61extern DECLEXPORT(const PDMDEVHLPR0) g_pdmR0DevHlp;
62extern DECLEXPORT(const PDMPICHLPR0) g_pdmR0PicHlp;
63extern DECLEXPORT(const PDMAPICHLPR0) g_pdmR0ApicHlp;
64extern DECLEXPORT(const PDMIOAPICHLPR0) g_pdmR0IoApicHlp;
65extern DECLEXPORT(const PDMPCIHLPR0) g_pdmR0PciHlp;
66__END_DECLS
67
68
69/*******************************************************************************
70* Internal Functions *
71*******************************************************************************/
72/** @name GC Device Helpers
73 * @{
74 */
75static DECLCALLBACK(void) pdmR0DevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
76static DECLCALLBACK(void) pdmR0DevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
77static DECLCALLBACK(void) pdmR0DevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);
78static DECLCALLBACK(void) pdmR0DevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
79static DECLCALLBACK(bool) pdmR0DevHlp_A20IsEnabled(PPDMDEVINS pDevIns);
80static DECLCALLBACK(int) pdmR0DevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
81static DECLCALLBACK(int) pdmR0DevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va);
82static DECLCALLBACK(int) pdmR0DevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData);
83/** @} */
84
85
86/** @name PIC GC Helpers
87 * @{
88 */
89static DECLCALLBACK(void) pdmR0PicHlp_SetInterruptFF(PPDMDEVINS pDevIns);
90static DECLCALLBACK(void) pdmR0PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);
91#ifdef VBOX_WITH_PDM_LOCK
92static DECLCALLBACK(int) pdmR0PicHlp_Lock(PPDMDEVINS pDevIns, int rc);
93static DECLCALLBACK(void) pdmR0PicHlp_Unlock(PPDMDEVINS pDevIns);
94#endif
95/** @} */
96
97
98/** @name APIC GC Helpers
99 * @{
100 */
101static DECLCALLBACK(void) pdmR0ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns);
102static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);
103static DECLCALLBACK(void) pdmR0ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, bool fEnabled);
104#ifdef VBOX_WITH_PDM_LOCK
105static DECLCALLBACK(int) pdmR0ApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
106static DECLCALLBACK(void) pdmR0ApicHlp_Unlock(PPDMDEVINS pDevIns);
107#endif
108/** @} */
109
110
111/** @name I/O APIC GC Helpers
112 * @{
113 */
114static DECLCALLBACK(void) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
115 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode);
116#ifdef VBOX_WITH_PDM_LOCK
117static DECLCALLBACK(int) pdmR0IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
118static DECLCALLBACK(void) pdmR0IoApicHlp_Unlock(PPDMDEVINS pDevIns);
119#endif
120/** @} */
121
122
123/** @name PCI Bus GC Helpers
124 * @{
125 */
126static DECLCALLBACK(void) pdmR0PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
127static DECLCALLBACK(void) pdmR0PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
128#ifdef VBOX_WITH_PDM_LOCK
129static DECLCALLBACK(int) pdmR0PciHlp_Lock(PPDMDEVINS pDevIns, int rc);
130static DECLCALLBACK(void) pdmR0PciHlp_Unlock(PPDMDEVINS pDevIns);
131#endif
132/** @} */
133
134
135static void pdmR0IsaSetIrq(PVM pVM, int iIrq, int iLevel);
136static void pdmR0IoApicSetIrq(PVM pVM, int iIrq, int iLevel);
137
138
139
140/**
141 * The Guest Context Device Helper Callbacks.
142 */
143extern DECLEXPORT(const PDMDEVHLPR0) g_pdmR0DevHlp =
144{
145 PDM_DEVHLPR0_VERSION,
146 pdmR0DevHlp_PCISetIrq,
147 pdmR0DevHlp_ISASetIrq,
148 pdmR0DevHlp_PhysRead,
149 pdmR0DevHlp_PhysWrite,
150 pdmR0DevHlp_A20IsEnabled,
151 pdmR0DevHlp_VMSetError,
152 pdmR0DevHlp_VMSetErrorV,
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::pdmR0DevHlp_PATMSetMMIOPatchInfo*/
334static DECLCALLBACK(int) pdmR0DevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData)
335{
336 PDMDEV_ASSERT_DEVINS(pDevIns);
337 LogFlow(("pdmR0DevHlp_PATMSetMMIOPatchInfo: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
338
339 return PATMSetMMIOPatchInfo(pDevIns->Internal.s.pVMHC, GCPhys, pCachedData);
340}
341
342
343
344
345
346/** @copydoc PDMPICHLPGC::pfnSetInterruptFF */
347static DECLCALLBACK(void) pdmR0PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
348{
349 PDMDEV_ASSERT_DEVINS(pDevIns);
350 LogFlow(("pdmR0PicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT_PIC %d -> 1\n",
351 pDevIns, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_PIC)));
352 VM_FF_SET(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_PIC);
353}
354
355
356/** @copydoc PDMPICHLPGC::pfnClearInterruptFF */
357static DECLCALLBACK(void) pdmR0PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
358{
359 PDMDEV_ASSERT_DEVINS(pDevIns);
360 LogFlow(("pdmR0PicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT_PIC %d -> 0\n",
361 pDevIns, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_PIC)));
362 VM_FF_CLEAR(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_PIC);
363}
364
365
366#ifdef VBOX_WITH_PDM_LOCK
367/** @copydoc PDMPICHLPR0::pfnLock */
368static DECLCALLBACK(int) pdmR0PicHlp_Lock(PPDMDEVINS pDevIns, int rc)
369{
370 PDMDEV_ASSERT_DEVINS(pDevIns);
371 return pdmLockEx(pDevIns->Internal.s.pVMHC, rc);
372}
373
374
375/** @copydoc PDMPICHLPR0::pfnUnlock */
376static DECLCALLBACK(void) pdmR0PicHlp_Unlock(PPDMDEVINS pDevIns)
377{
378 PDMDEV_ASSERT_DEVINS(pDevIns);
379 pdmUnlock(pDevIns->Internal.s.pVMHC);
380}
381#endif /* VBOX_WITH_PDM_LOCK */
382
383
384
385
386/** @copydoc PDMAPICHLPGC::pfnSetInterruptFF */
387static DECLCALLBACK(void) pdmR0ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
388{
389 PDMDEV_ASSERT_DEVINS(pDevIns);
390 LogFlow(("pdmR0ApicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 1\n",
391 pDevIns, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_APIC)));
392 VM_FF_SET(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_APIC);
393}
394
395
396/** @copydoc PDMAPICHLPGC::pfnClearInterruptFF */
397static DECLCALLBACK(void) pdmR0ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
398{
399 PDMDEV_ASSERT_DEVINS(pDevIns);
400 LogFlow(("pdmR0ApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
401 pDevIns, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_APIC)));
402 VM_FF_CLEAR(pDevIns->Internal.s.pVMHC, VM_FF_INTERRUPT_APIC);
403}
404
405
406/** @copydoc PDMAPICHLPGC::pfnChangeFeature */
407static DECLCALLBACK(void) pdmR0ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, bool fEnabled)
408{
409 PDMDEV_ASSERT_DEVINS(pDevIns);
410 LogFlow(("pdmR0ApicHlp_ChangeFeature: caller=%p/%d: fEnabled=%RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
411 if (fEnabled)
412 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMHC, CPUMCPUIDFEATURE_APIC);
413 else
414 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMHC, CPUMCPUIDFEATURE_APIC);
415}
416
417
418#ifdef VBOX_WITH_PDM_LOCK
419/** @copydoc PDMAPICHLPR0::pfnLock */
420static DECLCALLBACK(int) pdmR0ApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
421{
422 PDMDEV_ASSERT_DEVINS(pDevIns);
423 return pdmLockEx(pDevIns->Internal.s.pVMHC, rc);
424}
425
426
427/** @copydoc PDMAPICHLPR0::pfnUnlock */
428static DECLCALLBACK(void) pdmR0ApicHlp_Unlock(PPDMDEVINS pDevIns)
429{
430 PDMDEV_ASSERT_DEVINS(pDevIns);
431 pdmUnlock(pDevIns->Internal.s.pVMHC);
432}
433#endif /* VBOX_WITH_PDM_LOCK */
434
435
436
437
438/** @copydoc PDMIOAPICHLPR0::pfnApicBusDeliver */
439static DECLCALLBACK(void) pdmR0IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
440 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
441{
442 PDMDEV_ASSERT_DEVINS(pDevIns);
443 PVM pVM = pDevIns->Internal.s.pVMHC;
444 LogFlow(("pdmR0IoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
445 pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
446 Assert(pVM->pdm.s.Apic.pDevInsR0);
447 if (pVM->pdm.s.Apic.pfnBusDeliverR0)
448 pVM->pdm.s.Apic.pfnBusDeliverR0(pVM->pdm.s.Apic.pDevInsR0, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
449}
450
451
452#ifdef VBOX_WITH_PDM_LOCK
453/** @copydoc PDMIOAPICHLPR0::pfnLock */
454static DECLCALLBACK(int) pdmR0IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
455{
456 PDMDEV_ASSERT_DEVINS(pDevIns);
457 return pdmLockEx(pDevIns->Internal.s.pVMHC, rc);
458}
459
460
461/** @copydoc PDMIOAPICHLPR0::pfnUnlock */
462static DECLCALLBACK(void) pdmR0IoApicHlp_Unlock(PPDMDEVINS pDevIns)
463{
464 PDMDEV_ASSERT_DEVINS(pDevIns);
465 pdmUnlock(pDevIns->Internal.s.pVMHC);
466}
467#endif /* VBOX_WITH_PDM_LOCK */
468
469
470
471
472
473/** @copydoc PDMPCIHLPR0::pfnIsaSetIrq */
474static DECLCALLBACK(void) pdmR0PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
475{
476 PDMDEV_ASSERT_DEVINS(pDevIns);
477 Log4(("pdmR0PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
478 pdmR0IsaSetIrq(pDevIns->Internal.s.pVMHC, iIrq, iLevel);
479}
480
481
482/** @copydoc PDMPCIHLPR0::pfnIoApicSetIrq */
483static DECLCALLBACK(void) pdmR0PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
484{
485 PDMDEV_ASSERT_DEVINS(pDevIns);
486 Log4(("pdmR0PciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
487 pdmR0IoApicSetIrq(pDevIns->Internal.s.pVMHC, iIrq, iLevel);
488}
489
490
491#ifdef VBOX_WITH_PDM_LOCK
492/** @copydoc PDMPCIHLPR0::pfnLock */
493static DECLCALLBACK(int) pdmR0PciHlp_Lock(PPDMDEVINS pDevIns, int rc)
494{
495 PDMDEV_ASSERT_DEVINS(pDevIns);
496 return pdmLockEx(pDevIns->Internal.s.pVMHC, rc);
497}
498
499
500/** @copydoc PDMPCIHLPR0::pfnUnlock */
501static DECLCALLBACK(void) pdmR0PciHlp_Unlock(PPDMDEVINS pDevIns)
502{
503 PDMDEV_ASSERT_DEVINS(pDevIns);
504 pdmUnlock(pDevIns->Internal.s.pVMHC);
505}
506#endif /* VBOX_WITH_PDM_LOCK */
507
508
509
510
511/**
512 * Sets an irq on the I/O APIC.
513 *
514 * @param pVM The VM handle.
515 * @param iIrq The irq.
516 * @param iLevel The new level.
517 */
518static void pdmR0IsaSetIrq(PVM pVM, int iIrq, int iLevel)
519{
520 if ( ( pVM->pdm.s.IoApic.pDevInsR0
521 || !pVM->pdm.s.IoApic.pDevInsR3)
522 && ( pVM->pdm.s.Pic.pDevInsR0
523 || !pVM->pdm.s.Pic.pDevInsR3))
524 {
525 pdmLock(pVM);
526 if (pVM->pdm.s.Pic.pDevInsR0)
527 pVM->pdm.s.Pic.pfnSetIrqR0(pVM->pdm.s.Pic.pDevInsR0, iIrq, iLevel);
528 if (pVM->pdm.s.IoApic.pDevInsR0)
529 pVM->pdm.s.IoApic.pfnSetIrqR0(pVM->pdm.s.IoApic.pDevInsR0, iIrq, iLevel);
530 pdmUnlock(pVM);
531 }
532 else
533 {
534 /* queue for ring-3 execution. */
535 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueHC);
536 if (pTask)
537 {
538 pTask->enmOp = PDMDEVHLPTASKOP_ISA_SET_IRQ;
539 pTask->pDevInsHC = 0; /* not required */
540 pTask->u.SetIRQ.iIrq = iIrq;
541 pTask->u.SetIRQ.iLevel = iLevel;
542
543 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueHC, &pTask->Core, 0);
544 }
545 else
546 AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
547 }
548}
549
550
551/**
552 * Sets an irq on the I/O APIC.
553 *
554 * @param pVM The VM handle.
555 * @param iIrq The irq.
556 * @param iLevel The new level.
557 */
558static void pdmR0IoApicSetIrq(PVM pVM, int iIrq, int iLevel)
559{
560 if (pVM->pdm.s.IoApic.pDevInsR0)
561 {
562 pdmLock(pVM);
563 pVM->pdm.s.IoApic.pfnSetIrqR0(pVM->pdm.s.IoApic.pDevInsR0, iIrq, iLevel);
564 pdmUnlock(pVM);
565 }
566 else if (pVM->pdm.s.IoApic.pDevInsR3)
567 {
568 /* queue for ring-3 execution. */
569 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueHC);
570 if (pTask)
571 {
572 pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_IRQ;
573 pTask->pDevInsHC = 0; /* not required */
574 pTask->u.SetIRQ.iIrq = iIrq;
575 pTask->u.SetIRQ.iLevel = iLevel;
576
577 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueHC, &pTask->Core, 0);
578 }
579 else
580 AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
581 }
582}
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