VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMGC/PDMGCDevice.cpp@ 2981

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

InnoTek -> innotek: all the headers and comments.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 18.9 KB
Line 
1/* $Id: PDMGCDevice.cpp 2981 2007-06-01 16:01:28Z vboxsync $ */
2/** @file
3 * PDM - Pluggable Device and Driver Manager, GC 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 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->pvInstanceDataGC == (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 PDMDEVHLPGC) g_pdmGCDevHlp;
62extern DECLEXPORT(const PDMPICHLPGC) g_pdmGCPicHlp;
63extern DECLEXPORT(const PDMAPICHLPGC) g_pdmGCApicHlp;
64extern DECLEXPORT(const PDMIOAPICHLPGC) g_pdmGCIoApicHlp;
65extern DECLEXPORT(const PDMPCIHLPGC) g_pdmGCPciHlp;
66__END_DECLS
67
68
69/*******************************************************************************
70* Internal Functions *
71*******************************************************************************/
72/** @name GC Device Helpers
73 * @{
74 */
75static DECLCALLBACK(void) pdmGCDevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
76static DECLCALLBACK(void) pdmGCDevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
77static DECLCALLBACK(void) pdmGCDevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);
78static DECLCALLBACK(void) pdmGCDevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
79static DECLCALLBACK(bool) pdmGCDevHlp_A20IsEnabled(PPDMDEVINS pDevIns);
80static DECLCALLBACK(int) pdmGCDevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
81static DECLCALLBACK(int) pdmGCDevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va);
82static DECLCALLBACK(int) pdmGCDevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData);
83/** @} */
84
85
86/** @name PIC GC Helpers
87 * @{
88 */
89static DECLCALLBACK(void) pdmGCPicHlp_SetInterruptFF(PPDMDEVINS pDevIns);
90static DECLCALLBACK(void) pdmGCPicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);
91#ifdef VBOX_WITH_PDM_LOCK
92static DECLCALLBACK(int) pdmGCPicHlp_Lock(PPDMDEVINS pDevIns, int rc);
93static DECLCALLBACK(void) pdmGCPicHlp_Unlock(PPDMDEVINS pDevIns);
94#endif
95/** @} */
96
97
98/** @name APIC GC Helpers
99 * @{
100 */
101static DECLCALLBACK(void) pdmGCApicHlp_SetInterruptFF(PPDMDEVINS pDevIns);
102static DECLCALLBACK(void) pdmGCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);
103static DECLCALLBACK(void) pdmGCApicHlp_ChangeFeature(PPDMDEVINS pDevIns, bool fEnabled);
104#ifdef VBOX_WITH_PDM_LOCK
105static DECLCALLBACK(int) pdmGCApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
106static DECLCALLBACK(void) pdmGCApicHlp_Unlock(PPDMDEVINS pDevIns);
107#endif
108/** @} */
109
110
111/** @name I/O APIC GC Helpers
112 * @{
113 */
114static DECLCALLBACK(void) pdmGCIoApicHlp_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) pdmGCIoApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
118static DECLCALLBACK(void) pdmGCIoApicHlp_Unlock(PPDMDEVINS pDevIns);
119#endif
120/** @} */
121
122
123/** @name PCI Bus GC Helpers
124 * @{
125 */
126static DECLCALLBACK(void) pdmGCPciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
127static DECLCALLBACK(void) pdmGCPciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
128#ifdef VBOX_WITH_PDM_LOCK
129static DECLCALLBACK(int) pdmGCPciHlp_Lock(PPDMDEVINS pDevIns, int rc);
130static DECLCALLBACK(void) pdmGCPciHlp_Unlock(PPDMDEVINS pDevIns);
131#endif
132/** @} */
133
134
135static void pdmGCIsaSetIrq(PVM pVM, int iIrq, int iLevel);
136static void pdmGCIoApicSetIrq(PVM pVM, int iIrq, int iLevel);
137
138
139
140/**
141 * The Guest Context Device Helper Callbacks.
142 */
143extern DECLEXPORT(const PDMDEVHLPGC) g_pdmGCDevHlp =
144{
145 PDM_DEVHLPGC_VERSION,
146 pdmGCDevHlp_PCISetIrq,
147 pdmGCDevHlp_ISASetIrq,
148 pdmGCDevHlp_PhysRead,
149 pdmGCDevHlp_PhysWrite,
150 pdmGCDevHlp_A20IsEnabled,
151 pdmGCDevHlp_VMSetError,
152 pdmGCDevHlp_VMSetErrorV,
153 pdmGCDevHlp_PATMSetMMIOPatchInfo,
154 PDM_DEVHLPGC_VERSION
155};
156
157/**
158 * The Guest Context PIC Helper Callbacks.
159 */
160extern DECLEXPORT(const PDMPICHLPGC) g_pdmGCPicHlp =
161{
162 PDM_PICHLPGC_VERSION,
163 pdmGCPicHlp_SetInterruptFF,
164 pdmGCPicHlp_ClearInterruptFF,
165#ifdef VBOX_WITH_PDM_LOCK
166 pdmGCPicHlp_Lock,
167 pdmGCPicHlp_Unlock,
168#endif
169 PDM_PICHLPGC_VERSION
170};
171
172
173/**
174 * The Guest Context APIC Helper Callbacks.
175 */
176extern DECLEXPORT(const PDMAPICHLPGC) g_pdmGCApicHlp =
177{
178 PDM_APICHLPGC_VERSION,
179 pdmGCApicHlp_SetInterruptFF,
180 pdmGCApicHlp_ClearInterruptFF,
181 pdmGCApicHlp_ChangeFeature,
182#ifdef VBOX_WITH_PDM_LOCK
183 pdmGCApicHlp_Lock,
184 pdmGCApicHlp_Unlock,
185#endif
186 PDM_APICHLPGC_VERSION
187};
188
189
190/**
191 * The Guest Context I/O APIC Helper Callbacks.
192 */
193extern DECLEXPORT(const PDMIOAPICHLPGC) g_pdmGCIoApicHlp =
194{
195 PDM_IOAPICHLPGC_VERSION,
196 pdmGCIoApicHlp_ApicBusDeliver,
197#ifdef VBOX_WITH_PDM_LOCK
198 pdmGCIoApicHlp_Lock,
199 pdmGCIoApicHlp_Unlock,
200#endif
201 PDM_IOAPICHLPGC_VERSION
202};
203
204
205/**
206 * The Guest Context PCI Bus Helper Callbacks.
207 */
208extern DECLEXPORT(const PDMPCIHLPGC) g_pdmGCPciHlp =
209{
210 PDM_PCIHLPGC_VERSION,
211 pdmGCPciHlp_IsaSetIrq,
212 pdmGCPciHlp_IoApicSetIrq,
213#ifdef VBOX_WITH_PDM_LOCK
214 pdmGCPciHlp_Lock,
215 pdmGCPciHlp_Unlock,
216#endif
217 PDM_PCIHLPGC_VERSION, /* the end */
218};
219
220
221
222
223/** @copydoc PDMDEVHLPGC::pfnPCISetIrq */
224static DECLCALLBACK(void) pdmGCDevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
225{
226 PDMDEV_ASSERT_DEVINS(pDevIns);
227 LogFlow(("pdmGCDevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
228
229 PVM pVM = pDevIns->Internal.s.pVMGC;
230 PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceGC;
231 PPDMPCIBUS pPciBus = pDevIns->Internal.s.pPciBusGC;
232 if ( pPciDev
233 && pPciBus
234 && pPciBus->pDevInsGC)
235 {
236 pdmLock(pVM);
237 pPciBus->pfnSetIrqGC(pPciBus->pDevInsGC, pPciDev, iIrq, iLevel);
238 pdmUnlock(pVM);
239 }
240 else
241 {
242 /* queue for ring-3 execution. */
243 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueGC);
244 if (pTask)
245 {
246 pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
247 pTask->pDevInsHC = MMHyperGC2HC(pVM, pDevIns);
248 pTask->u.SetIRQ.iIrq = iIrq;
249 pTask->u.SetIRQ.iLevel = iLevel;
250
251 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueGC, &pTask->Core, 0);
252 }
253 else
254 AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
255 }
256
257 LogFlow(("pdmGCDevHlp_PCISetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
258}
259
260
261/** @copydoc PDMDEVHLPGC::pfnPCISetIrq */
262static DECLCALLBACK(void) pdmGCDevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
263{
264 PDMDEV_ASSERT_DEVINS(pDevIns);
265 LogFlow(("pdmGCDevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
266
267 pdmGCIsaSetIrq(pDevIns->Internal.s.pVMGC, iIrq, iLevel);
268
269 LogFlow(("pdmGCDevHlp_ISASetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
270}
271
272
273/** @copydoc PDMDEVHLPGC::pfnPhysRead */
274static DECLCALLBACK(void) pdmGCDevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
275{
276 PDMDEV_ASSERT_DEVINS(pDevIns);
277 LogFlow(("pdmGCDevHlp_PhysRead: caller=%p/%d: GCPhys=%VGp pvBuf=%p cbRead=%#x\n",
278 pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
279
280 PGMPhysRead(pDevIns->Internal.s.pVMGC, GCPhys, pvBuf, cbRead);
281
282 Log(("pdmGCDevHlp_PhysRead: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
283}
284
285
286/** @copydoc PDMDEVHLPGC::pfnPhysWrite */
287static DECLCALLBACK(void) pdmGCDevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
288{
289 PDMDEV_ASSERT_DEVINS(pDevIns);
290 LogFlow(("pdmGCDevHlp_PhysWrite: caller=%p/%d: GCPhys=%VGp pvBuf=%p cbWrite=%#x\n",
291 pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
292
293 PGMPhysWrite(pDevIns->Internal.s.pVMGC, GCPhys, pvBuf, cbWrite);
294
295 Log(("pdmGCDevHlp_PhysWrite: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
296}
297
298
299/** @copydoc PDMDEVHLPGC::pfnA20IsEnabled */
300static DECLCALLBACK(bool) pdmGCDevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
301{
302 PDMDEV_ASSERT_DEVINS(pDevIns);
303 LogFlow(("pdmGCDevHlp_A20IsEnabled: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
304
305 bool fEnabled = PGMPhysIsA20Enabled(pDevIns->Internal.s.pVMGC);
306
307 Log(("pdmGCDevHlp_A20IsEnabled: caller=%p/%d: returns %RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
308 return fEnabled;
309}
310
311
312/** @copydoc PDMDEVHLPGC::pfnVMSetError */
313static DECLCALLBACK(int) pdmGCDevHlp_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.pVMGC, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
319 va_end(args);
320 return rc;
321}
322
323
324/** @copydoc PDMDEVHLPGC::pfnVMSetErrorV */
325static DECLCALLBACK(int) pdmGCDevHlp_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.pVMGC, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
329 return rc;
330}
331
332
333/** @copydoc PDMDEVHLPGC::pdmGCDevHlp_PATMSetMMIOPatchInfo */
334static DECLCALLBACK(int) pdmGCDevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData)
335{
336 PDMDEV_ASSERT_DEVINS(pDevIns);
337 LogFlow(("pdmGCDevHlp_PATMSetMMIOPatchInfo: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
338
339 return PATMSetMMIOPatchInfo(pDevIns->Internal.s.pVMGC, GCPhys, pCachedData);
340}
341
342
343
344
345/** @copydoc PDMPICHLPGC::pfnSetInterruptFF */
346static DECLCALLBACK(void) pdmGCPicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
347{
348 PDMDEV_ASSERT_DEVINS(pDevIns);
349 LogFlow(("pdmGCPicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT_PIC %d -> 1\n",
350 pDevIns, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMGC, VM_FF_INTERRUPT_PIC)));
351 VM_FF_SET(pDevIns->Internal.s.pVMGC, VM_FF_INTERRUPT_PIC);
352}
353
354
355/** @copydoc PDMPICHLPGC::pfnClearInterruptFF */
356static DECLCALLBACK(void) pdmGCPicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
357{
358 PDMDEV_ASSERT_DEVINS(pDevIns);
359 LogFlow(("pdmGCPicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT_PIC %d -> 0\n",
360 pDevIns, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMGC, VM_FF_INTERRUPT_PIC)));
361 VM_FF_CLEAR(pDevIns->Internal.s.pVMGC, VM_FF_INTERRUPT_PIC);
362}
363
364
365#ifdef VBOX_WITH_PDM_LOCK
366/** @copydoc PDMPICHLPGC::pfnLock */
367static DECLCALLBACK(int) pdmGCPicHlp_Lock(PPDMDEVINS pDevIns, int rc)
368{
369 PDMDEV_ASSERT_DEVINS(pDevIns);
370 return pdmLockEx(pDevIns->Internal.s.pVMGC, rc);
371}
372
373
374/** @copydoc PDMPICHLPGC::pfnUnlock */
375static DECLCALLBACK(void) pdmGCPicHlp_Unlock(PPDMDEVINS pDevIns)
376{
377 PDMDEV_ASSERT_DEVINS(pDevIns);
378 pdmUnlock(pDevIns->Internal.s.pVMGC);
379}
380#endif /* VBOX_WITH_PDM_LOCK */
381
382
383
384
385/** @copydoc PDMAPICHLPGC::pfnSetInterruptFF */
386static DECLCALLBACK(void) pdmGCApicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
387{
388 PDMDEV_ASSERT_DEVINS(pDevIns);
389 LogFlow(("pdmGCApicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 1\n",
390 pDevIns, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMGC, VM_FF_INTERRUPT_APIC)));
391 VM_FF_SET(pDevIns->Internal.s.pVMGC, VM_FF_INTERRUPT_APIC);
392}
393
394
395/** @copydoc PDMAPICHLPGC::pfnClearInterruptFF */
396static DECLCALLBACK(void) pdmGCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
397{
398 PDMDEV_ASSERT_DEVINS(pDevIns);
399 LogFlow(("pdmGCApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
400 pDevIns, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMGC, VM_FF_INTERRUPT_APIC)));
401 VM_FF_CLEAR(pDevIns->Internal.s.pVMGC, VM_FF_INTERRUPT_APIC);
402}
403
404
405/** @copydoc PDMAPICHLPGC::pfnChangeFeature */
406static DECLCALLBACK(void) pdmGCApicHlp_ChangeFeature(PPDMDEVINS pDevIns, bool fEnabled)
407{
408 PDMDEV_ASSERT_DEVINS(pDevIns);
409 LogFlow(("pdmGCApicHlp_ChangeFeature: caller=%p/%d: fEnabled=%RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
410 if (fEnabled)
411 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMGC, CPUMCPUIDFEATURE_APIC);
412 else
413 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMGC, CPUMCPUIDFEATURE_APIC);
414}
415
416
417#ifdef VBOX_WITH_PDM_LOCK
418/** @copydoc PDMAPICHLPGC::pfnLock */
419static DECLCALLBACK(int) pdmGCApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
420{
421 PDMDEV_ASSERT_DEVINS(pDevIns);
422 return pdmLockEx(pDevIns->Internal.s.pVMGC, rc);
423}
424
425
426/** @copydoc PDMAPICHLPGC::pfnUnlock */
427static DECLCALLBACK(void) pdmGCApicHlp_Unlock(PPDMDEVINS pDevIns)
428{
429 PDMDEV_ASSERT_DEVINS(pDevIns);
430 pdmUnlock(pDevIns->Internal.s.pVMGC);
431}
432#endif /* VBOX_WITH_PDM_LOCK */
433
434
435
436
437/** @copydoc PDMIOAPICHLPGC::pfnApicBusDeliver */
438static DECLCALLBACK(void) pdmGCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
439 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
440{
441 PDMDEV_ASSERT_DEVINS(pDevIns);
442 PVM pVM = pDevIns->Internal.s.pVMGC;
443 LogFlow(("pdmGCIoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
444 pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
445 if (pVM->pdm.s.Apic.pfnBusDeliverGC)
446 pVM->pdm.s.Apic.pfnBusDeliverGC(pVM->pdm.s.Apic.pDevInsGC, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
447}
448
449
450#ifdef VBOX_WITH_PDM_LOCK
451/** @copydoc PDMIOAPICHLPGC::pfnLock */
452static DECLCALLBACK(int) pdmGCIoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
453{
454 PDMDEV_ASSERT_DEVINS(pDevIns);
455 return pdmLockEx(pDevIns->Internal.s.pVMGC, rc);
456}
457
458
459/** @copydoc PDMIOAPICHLPGC::pfnUnlock */
460static DECLCALLBACK(void) pdmGCIoApicHlp_Unlock(PPDMDEVINS pDevIns)
461{
462 PDMDEV_ASSERT_DEVINS(pDevIns);
463 pdmUnlock(pDevIns->Internal.s.pVMGC);
464}
465#endif /* VBOX_WITH_PDM_LOCK */
466
467
468
469
470/** @copydoc PDMPCIHLPGC::pfnIsaSetIrq */
471static DECLCALLBACK(void) pdmGCPciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
472{
473 PDMDEV_ASSERT_DEVINS(pDevIns);
474 Log4(("pdmGCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
475 pdmGCIsaSetIrq(pDevIns->Internal.s.pVMGC, iIrq, iLevel);
476}
477
478
479/** @copydoc PDMPCIHLPGC::pfnIoApicSetIrq */
480static DECLCALLBACK(void) pdmGCPciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
481{
482 PDMDEV_ASSERT_DEVINS(pDevIns);
483 Log4(("pdmGCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
484 pdmGCIoApicSetIrq(pDevIns->Internal.s.pVMGC, iIrq, iLevel);
485}
486
487
488#ifdef VBOX_WITH_PDM_LOCK
489/** @copydoc PDMPCIHLPGC::pfnLock */
490static DECLCALLBACK(int) pdmGCPciHlp_Lock(PPDMDEVINS pDevIns, int rc)
491{
492 PDMDEV_ASSERT_DEVINS(pDevIns);
493 return pdmLockEx(pDevIns->Internal.s.pVMGC, rc);
494}
495
496
497/** @copydoc PDMPCIHLPGC::pfnUnlock */
498static DECLCALLBACK(void) pdmGCPciHlp_Unlock(PPDMDEVINS pDevIns)
499{
500 PDMDEV_ASSERT_DEVINS(pDevIns);
501 pdmUnlock(pDevIns->Internal.s.pVMGC);
502}
503#endif /* VBOX_WITH_PDM_LOCK */
504
505
506
507
508/**
509 * Sets an irq on the I/O APIC.
510 *
511 * @param pVM The VM handle.
512 * @param iIrq The irq.
513 * @param iLevel The new level.
514 */
515static void pdmGCIsaSetIrq(PVM pVM, int iIrq, int iLevel)
516{
517 if ( ( pVM->pdm.s.IoApic.pDevInsGC
518 || !pVM->pdm.s.IoApic.pDevInsR3)
519 && ( pVM->pdm.s.Pic.pDevInsGC
520 || !pVM->pdm.s.Pic.pDevInsR3))
521 {
522 pdmLock(pVM);
523 if (pVM->pdm.s.Pic.pDevInsGC)
524 pVM->pdm.s.Pic.pfnSetIrqGC(pVM->pdm.s.Pic.pDevInsGC, iIrq, iLevel);
525 if (pVM->pdm.s.IoApic.pDevInsGC)
526 pVM->pdm.s.IoApic.pfnSetIrqGC(pVM->pdm.s.IoApic.pDevInsGC, iIrq, iLevel);
527 pdmUnlock(pVM);
528 }
529 else
530 {
531 /* queue for ring-3 execution. */
532 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueGC);
533 if (pTask)
534 {
535 pTask->enmOp = PDMDEVHLPTASKOP_ISA_SET_IRQ;
536 pTask->pDevInsHC = 0; /* not required */
537 pTask->u.SetIRQ.iIrq = iIrq;
538 pTask->u.SetIRQ.iLevel = iLevel;
539
540 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueGC, &pTask->Core, 0);
541 }
542 else
543 AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
544 }
545}
546
547
548/**
549 * Sets an irq on the I/O APIC.
550 *
551 * @param pVM The VM handle.
552 * @param iIrq The irq.
553 * @param iLevel The new level.
554 */
555static void pdmGCIoApicSetIrq(PVM pVM, int iIrq, int iLevel)
556{
557 if (pVM->pdm.s.IoApic.pDevInsGC)
558 {
559 pdmLock(pVM);
560 pVM->pdm.s.IoApic.pfnSetIrqGC(pVM->pdm.s.IoApic.pDevInsGC, iIrq, iLevel);
561 pdmUnlock(pVM);
562 }
563 else if (pVM->pdm.s.IoApic.pDevInsR3)
564 {
565 /* queue for ring-3 execution. */
566 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueGC);
567 if (pTask)
568 {
569 pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_IRQ;
570 pTask->pDevInsHC = 0; /* not required */
571 pTask->u.SetIRQ.iIrq = iIrq;
572 pTask->u.SetIRQ.iLevel = iLevel;
573
574 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueGC, &pTask->Core, 0);
575 }
576 else
577 AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
578 }
579}
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