VirtualBox

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

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

Biggest check-in ever. New source code headers for all (C) innotek files.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 19.8 KB
Line 
1/* $Id: PDMGCDevice.cpp 4071 2007-08-07 17:07:59Z 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
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->pvInstanceDataGC == (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 PDMDEVHLPGC) g_pdmGCDevHlp;
58extern DECLEXPORT(const PDMPICHLPGC) g_pdmGCPicHlp;
59extern DECLEXPORT(const PDMAPICHLPGC) g_pdmGCApicHlp;
60extern DECLEXPORT(const PDMIOAPICHLPGC) g_pdmGCIoApicHlp;
61extern DECLEXPORT(const PDMPCIHLPGC) g_pdmGCPciHlp;
62__END_DECLS
63
64
65/*******************************************************************************
66* Internal Functions *
67*******************************************************************************/
68/** @name GC Device Helpers
69 * @{
70 */
71static DECLCALLBACK(void) pdmGCDevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
72static DECLCALLBACK(void) pdmGCDevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
73static DECLCALLBACK(void) pdmGCDevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead);
74static DECLCALLBACK(void) pdmGCDevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite);
75static DECLCALLBACK(bool) pdmGCDevHlp_A20IsEnabled(PPDMDEVINS pDevIns);
76static DECLCALLBACK(int) pdmGCDevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...);
77static DECLCALLBACK(int) pdmGCDevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va);
78static DECLCALLBACK(int) pdmGCDevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...);
79static DECLCALLBACK(int) pdmGCDevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va);
80static DECLCALLBACK(int) pdmGCDevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData);
81/** @} */
82
83
84/** @name PIC GC Helpers
85 * @{
86 */
87static DECLCALLBACK(void) pdmGCPicHlp_SetInterruptFF(PPDMDEVINS pDevIns);
88static DECLCALLBACK(void) pdmGCPicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);
89#ifdef VBOX_WITH_PDM_LOCK
90static DECLCALLBACK(int) pdmGCPicHlp_Lock(PPDMDEVINS pDevIns, int rc);
91static DECLCALLBACK(void) pdmGCPicHlp_Unlock(PPDMDEVINS pDevIns);
92#endif
93/** @} */
94
95
96/** @name APIC GC Helpers
97 * @{
98 */
99static DECLCALLBACK(void) pdmGCApicHlp_SetInterruptFF(PPDMDEVINS pDevIns);
100static DECLCALLBACK(void) pdmGCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);
101static DECLCALLBACK(void) pdmGCApicHlp_ChangeFeature(PPDMDEVINS pDevIns, bool fEnabled);
102#ifdef VBOX_WITH_PDM_LOCK
103static DECLCALLBACK(int) pdmGCApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
104static DECLCALLBACK(void) pdmGCApicHlp_Unlock(PPDMDEVINS pDevIns);
105#endif
106/** @} */
107
108
109/** @name I/O APIC GC Helpers
110 * @{
111 */
112static DECLCALLBACK(void) pdmGCIoApicHlp_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) pdmGCIoApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
116static DECLCALLBACK(void) pdmGCIoApicHlp_Unlock(PPDMDEVINS pDevIns);
117#endif
118/** @} */
119
120
121/** @name PCI Bus GC Helpers
122 * @{
123 */
124static DECLCALLBACK(void) pdmGCPciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
125static DECLCALLBACK(void) pdmGCPciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
126#ifdef VBOX_WITH_PDM_LOCK
127static DECLCALLBACK(int) pdmGCPciHlp_Lock(PPDMDEVINS pDevIns, int rc);
128static DECLCALLBACK(void) pdmGCPciHlp_Unlock(PPDMDEVINS pDevIns);
129#endif
130/** @} */
131
132
133static void pdmGCIsaSetIrq(PVM pVM, int iIrq, int iLevel);
134static void pdmGCIoApicSetIrq(PVM pVM, int iIrq, int iLevel);
135
136
137
138/**
139 * The Guest Context Device Helper Callbacks.
140 */
141extern DECLEXPORT(const PDMDEVHLPGC) g_pdmGCDevHlp =
142{
143 PDM_DEVHLPGC_VERSION,
144 pdmGCDevHlp_PCISetIrq,
145 pdmGCDevHlp_ISASetIrq,
146 pdmGCDevHlp_PhysRead,
147 pdmGCDevHlp_PhysWrite,
148 pdmGCDevHlp_A20IsEnabled,
149 pdmGCDevHlp_VMSetError,
150 pdmGCDevHlp_VMSetErrorV,
151 pdmGCDevHlp_VMSetRuntimeError,
152 pdmGCDevHlp_VMSetRuntimeErrorV,
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::pfnVMSetRuntimeError */
334static DECLCALLBACK(int) pdmGCDevHlp_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.pVMGC, fFatal, pszErrorID, pszFormat, args);
340 va_end(args);
341 return rc;
342}
343
344
345/** @copydoc PDMDEVHLPGC::pfnVMSetErrorV */
346static DECLCALLBACK(int) pdmGCDevHlp_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.pVMGC, fFatal, pszErrorID, pszFormat, va);
350 return rc;
351}
352
353
354/** @copydoc PDMDEVHLPGC::pdmGCDevHlp_PATMSetMMIOPatchInfo */
355static DECLCALLBACK(int) pdmGCDevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData)
356{
357 PDMDEV_ASSERT_DEVINS(pDevIns);
358 LogFlow(("pdmGCDevHlp_PATMSetMMIOPatchInfo: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
359
360 return PATMSetMMIOPatchInfo(pDevIns->Internal.s.pVMGC, GCPhys, pCachedData);
361}
362
363
364
365
366/** @copydoc PDMPICHLPGC::pfnSetInterruptFF */
367static DECLCALLBACK(void) pdmGCPicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
368{
369 PDMDEV_ASSERT_DEVINS(pDevIns);
370 LogFlow(("pdmGCPicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT_PIC %d -> 1\n",
371 pDevIns, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMGC, VM_FF_INTERRUPT_PIC)));
372 VM_FF_SET(pDevIns->Internal.s.pVMGC, VM_FF_INTERRUPT_PIC);
373}
374
375
376/** @copydoc PDMPICHLPGC::pfnClearInterruptFF */
377static DECLCALLBACK(void) pdmGCPicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
378{
379 PDMDEV_ASSERT_DEVINS(pDevIns);
380 LogFlow(("pdmGCPicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT_PIC %d -> 0\n",
381 pDevIns, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMGC, VM_FF_INTERRUPT_PIC)));
382 VM_FF_CLEAR(pDevIns->Internal.s.pVMGC, VM_FF_INTERRUPT_PIC);
383}
384
385
386#ifdef VBOX_WITH_PDM_LOCK
387/** @copydoc PDMPICHLPGC::pfnLock */
388static DECLCALLBACK(int) pdmGCPicHlp_Lock(PPDMDEVINS pDevIns, int rc)
389{
390 PDMDEV_ASSERT_DEVINS(pDevIns);
391 return pdmLockEx(pDevIns->Internal.s.pVMGC, rc);
392}
393
394
395/** @copydoc PDMPICHLPGC::pfnUnlock */
396static DECLCALLBACK(void) pdmGCPicHlp_Unlock(PPDMDEVINS pDevIns)
397{
398 PDMDEV_ASSERT_DEVINS(pDevIns);
399 pdmUnlock(pDevIns->Internal.s.pVMGC);
400}
401#endif /* VBOX_WITH_PDM_LOCK */
402
403
404
405
406/** @copydoc PDMAPICHLPGC::pfnSetInterruptFF */
407static DECLCALLBACK(void) pdmGCApicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
408{
409 PDMDEV_ASSERT_DEVINS(pDevIns);
410 LogFlow(("pdmGCApicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 1\n",
411 pDevIns, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMGC, VM_FF_INTERRUPT_APIC)));
412 VM_FF_SET(pDevIns->Internal.s.pVMGC, VM_FF_INTERRUPT_APIC);
413}
414
415
416/** @copydoc PDMAPICHLPGC::pfnClearInterruptFF */
417static DECLCALLBACK(void) pdmGCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
418{
419 PDMDEV_ASSERT_DEVINS(pDevIns);
420 LogFlow(("pdmGCApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
421 pDevIns, pDevIns->iInstance, VM_FF_ISSET(pDevIns->Internal.s.pVMGC, VM_FF_INTERRUPT_APIC)));
422 VM_FF_CLEAR(pDevIns->Internal.s.pVMGC, VM_FF_INTERRUPT_APIC);
423}
424
425
426/** @copydoc PDMAPICHLPGC::pfnChangeFeature */
427static DECLCALLBACK(void) pdmGCApicHlp_ChangeFeature(PPDMDEVINS pDevIns, bool fEnabled)
428{
429 PDMDEV_ASSERT_DEVINS(pDevIns);
430 LogFlow(("pdmGCApicHlp_ChangeFeature: caller=%p/%d: fEnabled=%RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
431 if (fEnabled)
432 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMGC, CPUMCPUIDFEATURE_APIC);
433 else
434 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMGC, CPUMCPUIDFEATURE_APIC);
435}
436
437
438#ifdef VBOX_WITH_PDM_LOCK
439/** @copydoc PDMAPICHLPGC::pfnLock */
440static DECLCALLBACK(int) pdmGCApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
441{
442 PDMDEV_ASSERT_DEVINS(pDevIns);
443 return pdmLockEx(pDevIns->Internal.s.pVMGC, rc);
444}
445
446
447/** @copydoc PDMAPICHLPGC::pfnUnlock */
448static DECLCALLBACK(void) pdmGCApicHlp_Unlock(PPDMDEVINS pDevIns)
449{
450 PDMDEV_ASSERT_DEVINS(pDevIns);
451 pdmUnlock(pDevIns->Internal.s.pVMGC);
452}
453#endif /* VBOX_WITH_PDM_LOCK */
454
455
456
457
458/** @copydoc PDMIOAPICHLPGC::pfnApicBusDeliver */
459static DECLCALLBACK(void) pdmGCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
460 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
461{
462 PDMDEV_ASSERT_DEVINS(pDevIns);
463 PVM pVM = pDevIns->Internal.s.pVMGC;
464 LogFlow(("pdmGCIoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
465 pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
466 if (pVM->pdm.s.Apic.pfnBusDeliverGC)
467 pVM->pdm.s.Apic.pfnBusDeliverGC(pVM->pdm.s.Apic.pDevInsGC, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
468}
469
470
471#ifdef VBOX_WITH_PDM_LOCK
472/** @copydoc PDMIOAPICHLPGC::pfnLock */
473static DECLCALLBACK(int) pdmGCIoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
474{
475 PDMDEV_ASSERT_DEVINS(pDevIns);
476 return pdmLockEx(pDevIns->Internal.s.pVMGC, rc);
477}
478
479
480/** @copydoc PDMIOAPICHLPGC::pfnUnlock */
481static DECLCALLBACK(void) pdmGCIoApicHlp_Unlock(PPDMDEVINS pDevIns)
482{
483 PDMDEV_ASSERT_DEVINS(pDevIns);
484 pdmUnlock(pDevIns->Internal.s.pVMGC);
485}
486#endif /* VBOX_WITH_PDM_LOCK */
487
488
489
490
491/** @copydoc PDMPCIHLPGC::pfnIsaSetIrq */
492static DECLCALLBACK(void) pdmGCPciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
493{
494 PDMDEV_ASSERT_DEVINS(pDevIns);
495 Log4(("pdmGCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
496 pdmGCIsaSetIrq(pDevIns->Internal.s.pVMGC, iIrq, iLevel);
497}
498
499
500/** @copydoc PDMPCIHLPGC::pfnIoApicSetIrq */
501static DECLCALLBACK(void) pdmGCPciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
502{
503 PDMDEV_ASSERT_DEVINS(pDevIns);
504 Log4(("pdmGCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
505 pdmGCIoApicSetIrq(pDevIns->Internal.s.pVMGC, iIrq, iLevel);
506}
507
508
509#ifdef VBOX_WITH_PDM_LOCK
510/** @copydoc PDMPCIHLPGC::pfnLock */
511static DECLCALLBACK(int) pdmGCPciHlp_Lock(PPDMDEVINS pDevIns, int rc)
512{
513 PDMDEV_ASSERT_DEVINS(pDevIns);
514 return pdmLockEx(pDevIns->Internal.s.pVMGC, rc);
515}
516
517
518/** @copydoc PDMPCIHLPGC::pfnUnlock */
519static DECLCALLBACK(void) pdmGCPciHlp_Unlock(PPDMDEVINS pDevIns)
520{
521 PDMDEV_ASSERT_DEVINS(pDevIns);
522 pdmUnlock(pDevIns->Internal.s.pVMGC);
523}
524#endif /* VBOX_WITH_PDM_LOCK */
525
526
527
528
529/**
530 * Sets an irq on the I/O APIC.
531 *
532 * @param pVM The VM handle.
533 * @param iIrq The irq.
534 * @param iLevel The new level.
535 */
536static void pdmGCIsaSetIrq(PVM pVM, int iIrq, int iLevel)
537{
538 if ( ( pVM->pdm.s.IoApic.pDevInsGC
539 || !pVM->pdm.s.IoApic.pDevInsR3)
540 && ( pVM->pdm.s.Pic.pDevInsGC
541 || !pVM->pdm.s.Pic.pDevInsR3))
542 {
543 pdmLock(pVM);
544 if (pVM->pdm.s.Pic.pDevInsGC)
545 pVM->pdm.s.Pic.pfnSetIrqGC(pVM->pdm.s.Pic.pDevInsGC, iIrq, iLevel);
546 if (pVM->pdm.s.IoApic.pDevInsGC)
547 pVM->pdm.s.IoApic.pfnSetIrqGC(pVM->pdm.s.IoApic.pDevInsGC, iIrq, iLevel);
548 pdmUnlock(pVM);
549 }
550 else
551 {
552 /* queue for ring-3 execution. */
553 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueGC);
554 if (pTask)
555 {
556 pTask->enmOp = PDMDEVHLPTASKOP_ISA_SET_IRQ;
557 pTask->pDevInsHC = 0; /* not required */
558 pTask->u.SetIRQ.iIrq = iIrq;
559 pTask->u.SetIRQ.iLevel = iLevel;
560
561 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueGC, &pTask->Core, 0);
562 }
563 else
564 AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
565 }
566}
567
568
569/**
570 * Sets an irq on the I/O APIC.
571 *
572 * @param pVM The VM handle.
573 * @param iIrq The irq.
574 * @param iLevel The new level.
575 */
576static void pdmGCIoApicSetIrq(PVM pVM, int iIrq, int iLevel)
577{
578 if (pVM->pdm.s.IoApic.pDevInsGC)
579 {
580 pdmLock(pVM);
581 pVM->pdm.s.IoApic.pfnSetIrqGC(pVM->pdm.s.IoApic.pDevInsGC, iIrq, iLevel);
582 pdmUnlock(pVM);
583 }
584 else if (pVM->pdm.s.IoApic.pDevInsR3)
585 {
586 /* queue for ring-3 execution. */
587 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueGC);
588 if (pTask)
589 {
590 pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_IRQ;
591 pTask->pDevInsHC = 0; /* not required */
592 pTask->u.SetIRQ.iIrq = iIrq;
593 pTask->u.SetIRQ.iLevel = iLevel;
594
595 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueGC, &pTask->Core, 0);
596 }
597 else
598 AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
599 }
600}
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