VirtualBox

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

Last change on this file since 12970 was 12970, checked in by vboxsync, 16 years ago

#1865: PDMINS.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id
File size: 20.1 KB
Line 
1/* $Id: PDMGCDevice.cpp 12970 2008-10-03 07:04:11Z vboxsync $ */
2/** @file
3 * PDM - Pluggable Device and Driver Manager, GC Device parts.
4 */
5
6/*
7 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
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 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
18 * Clara, CA 95054 USA or visit http://www.sun.com if you need
19 * additional information or have any questions.
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->pvInstanceDataRC == (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 PDMDEVHLPRC) g_pdmRCDevHlp;
62extern DECLEXPORT(const PDMPICHLPRC) g_pdmRCPicHlp;
63extern DECLEXPORT(const PDMAPICHLPRC) g_pdmRCApicHlp;
64extern DECLEXPORT(const PDMIOAPICHLPRC) g_pdmRCIoApicHlp;
65extern DECLEXPORT(const PDMPCIHLPRC) g_pdmRCPciHlp;
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_VMSetRuntimeError(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...);
83static DECLCALLBACK(int) pdmGCDevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va);
84static DECLCALLBACK(int) pdmGCDevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData);
85/** @} */
86
87
88/** @name PIC GC Helpers
89 * @{
90 */
91static DECLCALLBACK(void) pdmRCPicHlp_SetInterruptFF(PPDMDEVINS pDevIns);
92static DECLCALLBACK(void) pdmRCPicHlp_ClearInterruptFF(PPDMDEVINS pDevIns);
93static DECLCALLBACK(int) pdmRCPicHlp_Lock(PPDMDEVINS pDevIns, int rc);
94static DECLCALLBACK(void) pdmRCPicHlp_Unlock(PPDMDEVINS pDevIns);
95/** @} */
96
97
98/** @name APIC RC Helpers
99 * @{
100 */
101static DECLCALLBACK(void) pdmRCApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu);
102static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu);
103static DECLCALLBACK(void) pdmRCApicHlp_ChangeFeature(PPDMDEVINS pDevIns, bool fEnabled);
104static DECLCALLBACK(int) pdmRCApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
105static DECLCALLBACK(void) pdmRCApicHlp_Unlock(PPDMDEVINS pDevIns);
106static DECLCALLBACK(VMCPUID) pdmRCApicHlp_GetCpuId(PPDMDEVINS pDevIns);
107/** @} */
108
109
110/** @name I/O APIC RC Helpers
111 * @{
112 */
113static DECLCALLBACK(void) pdmRCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
114 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode);
115static DECLCALLBACK(int) pdmRCIoApicHlp_Lock(PPDMDEVINS pDevIns, int rc);
116static DECLCALLBACK(void) pdmRCIoApicHlp_Unlock(PPDMDEVINS pDevIns);
117/** @} */
118
119
120/** @name PCI Bus RC Helpers
121 * @{
122 */
123static DECLCALLBACK(void) pdmRCPciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
124static DECLCALLBACK(void) pdmRCPciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel);
125static DECLCALLBACK(int) pdmRCPciHlp_Lock(PPDMDEVINS pDevIns, int rc);
126static DECLCALLBACK(void) pdmRCPciHlp_Unlock(PPDMDEVINS pDevIns);
127/** @} */
128
129
130static void pdmGCIsaSetIrq(PVM pVM, int iIrq, int iLevel);
131static void pdmGCIoApicSetIrq(PVM pVM, int iIrq, int iLevel);
132
133
134
135/**
136 * The Guest Context Device Helper Callbacks.
137 */
138extern DECLEXPORT(const PDMDEVHLPRC) g_pdmRCDevHlp =
139{
140 PDM_DEVHLPRC_VERSION,
141 pdmGCDevHlp_PCISetIrq,
142 pdmGCDevHlp_ISASetIrq,
143 pdmGCDevHlp_PhysRead,
144 pdmGCDevHlp_PhysWrite,
145 pdmGCDevHlp_A20IsEnabled,
146 pdmGCDevHlp_VMSetError,
147 pdmGCDevHlp_VMSetErrorV,
148 pdmGCDevHlp_VMSetRuntimeError,
149 pdmGCDevHlp_VMSetRuntimeErrorV,
150 pdmGCDevHlp_PATMSetMMIOPatchInfo,
151 PDM_DEVHLPRC_VERSION
152};
153
154/**
155 * The Raw-Mode Context PIC Helper Callbacks.
156 */
157extern DECLEXPORT(const PDMPICHLPRC) g_pdmRCPicHlp =
158{
159 PDM_PICHLPRC_VERSION,
160 pdmRCPicHlp_SetInterruptFF,
161 pdmRCPicHlp_ClearInterruptFF,
162 pdmRCPicHlp_Lock,
163 pdmRCPicHlp_Unlock,
164 PDM_PICHLPRC_VERSION
165};
166
167
168/**
169 * The Raw-Mode Context APIC Helper Callbacks.
170 */
171extern DECLEXPORT(const PDMAPICHLPRC) g_pdmRCApicHlp =
172{
173 PDM_APICHLPRC_VERSION,
174 pdmRCApicHlp_SetInterruptFF,
175 pdmRCApicHlp_ClearInterruptFF,
176 pdmRCApicHlp_ChangeFeature,
177 pdmRCApicHlp_Lock,
178 pdmRCApicHlp_Unlock,
179 pdmRCApicHlp_GetCpuId,
180 PDM_APICHLPRC_VERSION
181};
182
183
184/**
185 * The Raw-Mode Context I/O APIC Helper Callbacks.
186 */
187extern DECLEXPORT(const PDMIOAPICHLPRC) g_pdmRCIoApicHlp =
188{
189 PDM_IOAPICHLPRC_VERSION,
190 pdmRCIoApicHlp_ApicBusDeliver,
191 pdmRCIoApicHlp_Lock,
192 pdmRCIoApicHlp_Unlock,
193 PDM_IOAPICHLPRC_VERSION
194};
195
196
197/**
198 * The Raw-Mode Context PCI Bus Helper Callbacks.
199 */
200extern DECLEXPORT(const PDMPCIHLPRC) g_pdmRCPciHlp =
201{
202 PDM_PCIHLPRC_VERSION,
203 pdmRCPciHlp_IsaSetIrq,
204 pdmRCPciHlp_IoApicSetIrq,
205 pdmRCPciHlp_Lock,
206 pdmRCPciHlp_Unlock,
207 PDM_PCIHLPRC_VERSION, /* the end */
208};
209
210
211
212
213/** @copydoc PDMDEVHLPRC::pfnPCISetIrq */
214static DECLCALLBACK(void) pdmGCDevHlp_PCISetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
215{
216 PDMDEV_ASSERT_DEVINS(pDevIns);
217 LogFlow(("pdmGCDevHlp_PCISetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
218
219 PVM pVM = pDevIns->Internal.s.pVMRC;
220 PPCIDEVICE pPciDev = pDevIns->Internal.s.pPciDeviceRC;
221 PPDMPCIBUS pPciBus = pDevIns->Internal.s.pPciBusRC;
222 if ( pPciDev
223 && pPciBus
224 && pPciBus->pDevInsRC)
225 {
226 pdmLock(pVM);
227 pPciBus->pfnSetIrqRC(pPciBus->pDevInsRC, pPciDev, iIrq, iLevel);
228 pdmUnlock(pVM);
229 }
230 else
231 {
232 /* queue for ring-3 execution. */
233 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueGC);
234 if (pTask)
235 {
236 pTask->enmOp = PDMDEVHLPTASKOP_PCI_SET_IRQ;
237 pTask->pDevInsHC = MMHyperGC2HC(pVM, pDevIns);
238 pTask->u.SetIRQ.iIrq = iIrq;
239 pTask->u.SetIRQ.iLevel = iLevel;
240
241 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueGC, &pTask->Core, 0);
242 }
243 else
244 AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
245 }
246
247 LogFlow(("pdmGCDevHlp_PCISetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
248}
249
250
251/** @copydoc PDMDEVHLPRC::pfnPCISetIrq */
252static DECLCALLBACK(void) pdmGCDevHlp_ISASetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
253{
254 PDMDEV_ASSERT_DEVINS(pDevIns);
255 LogFlow(("pdmGCDevHlp_ISASetIrq: caller=%p/%d: iIrq=%d iLevel=%d\n", pDevIns, pDevIns->iInstance, iIrq, iLevel));
256
257 pdmGCIsaSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
258
259 LogFlow(("pdmGCDevHlp_ISASetIrq: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
260}
261
262
263/** @copydoc PDMDEVHLPRC::pfnPhysRead */
264static DECLCALLBACK(void) pdmGCDevHlp_PhysRead(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, void *pvBuf, size_t cbRead)
265{
266 PDMDEV_ASSERT_DEVINS(pDevIns);
267 LogFlow(("pdmGCDevHlp_PhysRead: caller=%p/%d: GCPhys=%VGp pvBuf=%p cbRead=%#x\n",
268 pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbRead));
269
270 PGMPhysRead(pDevIns->Internal.s.pVMRC, GCPhys, pvBuf, cbRead);
271
272 Log(("pdmGCDevHlp_PhysRead: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
273}
274
275
276/** @copydoc PDMDEVHLPRC::pfnPhysWrite */
277static DECLCALLBACK(void) pdmGCDevHlp_PhysWrite(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, const void *pvBuf, size_t cbWrite)
278{
279 PDMDEV_ASSERT_DEVINS(pDevIns);
280 LogFlow(("pdmGCDevHlp_PhysWrite: caller=%p/%d: GCPhys=%VGp pvBuf=%p cbWrite=%#x\n",
281 pDevIns, pDevIns->iInstance, GCPhys, pvBuf, cbWrite));
282
283 PGMPhysWrite(pDevIns->Internal.s.pVMRC, GCPhys, pvBuf, cbWrite);
284
285 Log(("pdmGCDevHlp_PhysWrite: caller=%p/%d: returns void\n", pDevIns, pDevIns->iInstance));
286}
287
288
289/** @copydoc PDMDEVHLPRC::pfnA20IsEnabled */
290static DECLCALLBACK(bool) pdmGCDevHlp_A20IsEnabled(PPDMDEVINS pDevIns)
291{
292 PDMDEV_ASSERT_DEVINS(pDevIns);
293 LogFlow(("pdmGCDevHlp_A20IsEnabled: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
294
295 bool fEnabled = PGMPhysIsA20Enabled(pDevIns->Internal.s.pVMRC);
296
297 Log(("pdmGCDevHlp_A20IsEnabled: caller=%p/%d: returns %RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
298 return fEnabled;
299}
300
301
302/** @copydoc PDMDEVHLPRC::pfnVMSetError */
303static DECLCALLBACK(int) pdmGCDevHlp_VMSetError(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, ...)
304{
305 PDMDEV_ASSERT_DEVINS(pDevIns);
306 va_list args;
307 va_start(args, pszFormat);
308 int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMRC, rc, RT_SRC_POS_ARGS, pszFormat, args); Assert(rc2 == rc); NOREF(rc2);
309 va_end(args);
310 return rc;
311}
312
313
314/** @copydoc PDMDEVHLPRC::pfnVMSetErrorV */
315static DECLCALLBACK(int) pdmGCDevHlp_VMSetErrorV(PPDMDEVINS pDevIns, int rc, RT_SRC_POS_DECL, const char *pszFormat, va_list va)
316{
317 PDMDEV_ASSERT_DEVINS(pDevIns);
318 int rc2 = VMSetErrorV(pDevIns->Internal.s.pVMRC, rc, RT_SRC_POS_ARGS, pszFormat, va); Assert(rc2 == rc); NOREF(rc2);
319 return rc;
320}
321
322
323/** @copydoc PDMDEVHLPRC::pfnVMSetRuntimeError */
324static DECLCALLBACK(int) pdmGCDevHlp_VMSetRuntimeError(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, ...)
325{
326 PDMDEV_ASSERT_DEVINS(pDevIns);
327 va_list args;
328 va_start(args, pszFormat);
329 int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMRC, fFatal, pszErrorID, pszFormat, args);
330 va_end(args);
331 return rc;
332}
333
334
335/** @copydoc PDMDEVHLPRC::pfnVMSetErrorV */
336static DECLCALLBACK(int) pdmGCDevHlp_VMSetRuntimeErrorV(PPDMDEVINS pDevIns, bool fFatal, const char *pszErrorID, const char *pszFormat, va_list va)
337{
338 PDMDEV_ASSERT_DEVINS(pDevIns);
339 int rc = VMSetRuntimeErrorV(pDevIns->Internal.s.pVMRC, fFatal, pszErrorID, pszFormat, va);
340 return rc;
341}
342
343
344/** @copydoc PDMDEVHLPRC::pfnPATMSetMMIOPatchInfo */
345static DECLCALLBACK(int) pdmGCDevHlp_PATMSetMMIOPatchInfo(PPDMDEVINS pDevIns, RTGCPHYS GCPhys, RTGCPTR pCachedData)
346{
347 PDMDEV_ASSERT_DEVINS(pDevIns);
348 LogFlow(("pdmGCDevHlp_PATMSetMMIOPatchInfo: caller=%p/%d:\n", pDevIns, pDevIns->iInstance));
349
350 return PATMSetMMIOPatchInfo(pDevIns->Internal.s.pVMRC, GCPhys, (RTRCPTR)pCachedData);
351}
352
353
354
355
356/** @copydoc PDMPICHLPGC::pfnSetInterruptFF */
357static DECLCALLBACK(void) pdmRCPicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
358{
359 PDMDEV_ASSERT_DEVINS(pDevIns);
360 LogFlow(("pdmRCPicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT_PIC %d -> 1\n",
361 pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMRC, 0, VM_FF_INTERRUPT_PIC)));
362 /* for PIC we always deliver to CPU 0, MP use APIC */
363 VMCPU_FF_SET(pDevIns->Internal.s.pVMRC, 0, VM_FF_INTERRUPT_PIC);
364}
365
366
367/** @copydoc PDMPICHLPGC::pfnClearInterruptFF */
368static DECLCALLBACK(void) pdmRCPicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
369{
370 PDMDEV_ASSERT_DEVINS(pDevIns);
371 LogFlow(("pdmRCPicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT_PIC %d -> 0\n",
372 pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMRC, 0, VM_FF_INTERRUPT_PIC)));
373 /* for PIC we always deliver to CPU 0, MP use APIC */
374 VMCPU_FF_CLEAR(pDevIns->Internal.s.pVMRC, 0, VM_FF_INTERRUPT_PIC);
375}
376
377
378/** @copydoc PDMPICHLPGC::pfnLock */
379static DECLCALLBACK(int) pdmRCPicHlp_Lock(PPDMDEVINS pDevIns, int rc)
380{
381 PDMDEV_ASSERT_DEVINS(pDevIns);
382 return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
383}
384
385
386/** @copydoc PDMPICHLPGC::pfnUnlock */
387static DECLCALLBACK(void) pdmRCPicHlp_Unlock(PPDMDEVINS pDevIns)
388{
389 PDMDEV_ASSERT_DEVINS(pDevIns);
390 pdmUnlock(pDevIns->Internal.s.pVMRC);
391}
392
393
394
395
396/** @copydoc PDMAPICHLPRC::pfnSetInterruptFF */
397static DECLCALLBACK(void) pdmRCApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu)
398{
399 PDMDEV_ASSERT_DEVINS(pDevIns);
400 LogFlow(("pdmRCApicHlp_SetInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 1\n",
401 pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMRC, idCpu, VM_FF_INTERRUPT_APIC)));
402 VMCPU_FF_SET(pDevIns->Internal.s.pVMRC, idCpu, VM_FF_INTERRUPT_APIC);
403}
404
405
406/** @copydoc PDMAPICHLPRC::pfnClearInterruptFF */
407static DECLCALLBACK(void) pdmRCApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, VMCPUID idCpu)
408{
409 PDMDEV_ASSERT_DEVINS(pDevIns);
410 LogFlow(("pdmRCApicHlp_ClearInterruptFF: caller=%p/%d: VM_FF_INTERRUPT %d -> 0\n",
411 pDevIns, pDevIns->iInstance, VMCPU_FF_ISSET(pDevIns->Internal.s.pVMRC, idCpu, VM_FF_INTERRUPT_APIC)));
412 VMCPU_FF_CLEAR(pDevIns->Internal.s.pVMRC, idCpu, VM_FF_INTERRUPT_APIC);
413}
414
415
416/** @copydoc PDMAPICHLPRC::pfnChangeFeature */
417static DECLCALLBACK(void) pdmRCApicHlp_ChangeFeature(PPDMDEVINS pDevIns, bool fEnabled)
418{
419 PDMDEV_ASSERT_DEVINS(pDevIns);
420 LogFlow(("pdmRCApicHlp_ChangeFeature: caller=%p/%d: fEnabled=%RTbool\n", pDevIns, pDevIns->iInstance, fEnabled));
421 if (fEnabled)
422 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_APIC);
423 else
424 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMRC, CPUMCPUIDFEATURE_APIC);
425}
426
427
428/** @copydoc PDMAPICHLPRC::pfnLock */
429static DECLCALLBACK(int) pdmRCApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
430{
431 PDMDEV_ASSERT_DEVINS(pDevIns);
432 return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
433}
434
435
436/** @copydoc PDMAPICHLPRC::pfnUnlock */
437static DECLCALLBACK(void) pdmRCApicHlp_Unlock(PPDMDEVINS pDevIns)
438{
439 PDMDEV_ASSERT_DEVINS(pDevIns);
440 pdmUnlock(pDevIns->Internal.s.pVMRC);
441}
442
443
444/** @copydoc PDMAPICHLPRC::pfnGetCpuId */
445static DECLCALLBACK(VMCPUID) pdmRCApicHlp_GetCpuId(PPDMDEVINS pDevIns)
446{
447 PDMDEV_ASSERT_DEVINS(pDevIns);
448 return VMMGetCpuId(pDevIns->Internal.s.pVMRC);
449}
450
451/** @copydoc PDMIOAPICHLPRC::pfnApicBusDeliver */
452static DECLCALLBACK(void) pdmRCIoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
453 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode)
454{
455 PDMDEV_ASSERT_DEVINS(pDevIns);
456 PVM pVM = pDevIns->Internal.s.pVMRC;
457 LogFlow(("pdmRCIoApicHlp_ApicBusDeliver: caller=%p/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8\n",
458 pDevIns, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode));
459 if (pVM->pdm.s.Apic.pfnBusDeliverRC)
460 pVM->pdm.s.Apic.pfnBusDeliverRC(pVM->pdm.s.Apic.pDevInsRC, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode);
461}
462
463
464/** @copydoc PDMIOAPICHLPRC::pfnLock */
465static DECLCALLBACK(int) pdmRCIoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
466{
467 PDMDEV_ASSERT_DEVINS(pDevIns);
468 return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
469}
470
471
472/** @copydoc PDMIOAPICHLPRC::pfnUnlock */
473static DECLCALLBACK(void) pdmRCIoApicHlp_Unlock(PPDMDEVINS pDevIns)
474{
475 PDMDEV_ASSERT_DEVINS(pDevIns);
476 pdmUnlock(pDevIns->Internal.s.pVMRC);
477}
478
479
480
481
482/** @copydoc PDMPCIHLPRC::pfnIsaSetIrq */
483static DECLCALLBACK(void) pdmRCPciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
484{
485 PDMDEV_ASSERT_DEVINS(pDevIns);
486 Log4(("pdmRCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
487 pdmGCIsaSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
488}
489
490
491/** @copydoc PDMPCIHLPRC::pfnIoApicSetIrq */
492static DECLCALLBACK(void) pdmRCPciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
493{
494 PDMDEV_ASSERT_DEVINS(pDevIns);
495 Log4(("pdmRCPciHlp_IsaSetIrq: iIrq=%d iLevel=%d\n", iIrq, iLevel));
496 pdmGCIoApicSetIrq(pDevIns->Internal.s.pVMRC, iIrq, iLevel);
497}
498
499
500/** @copydoc PDMPCIHLPRC::pfnLock */
501static DECLCALLBACK(int) pdmRCPciHlp_Lock(PPDMDEVINS pDevIns, int rc)
502{
503 PDMDEV_ASSERT_DEVINS(pDevIns);
504 return pdmLockEx(pDevIns->Internal.s.pVMRC, rc);
505}
506
507
508/** @copydoc PDMPCIHLPRC::pfnUnlock */
509static DECLCALLBACK(void) pdmRCPciHlp_Unlock(PPDMDEVINS pDevIns)
510{
511 PDMDEV_ASSERT_DEVINS(pDevIns);
512 pdmUnlock(pDevIns->Internal.s.pVMRC);
513}
514
515
516
517
518/**
519 * Sets an irq on the I/O APIC.
520 *
521 * @param pVM The VM handle.
522 * @param iIrq The irq.
523 * @param iLevel The new level.
524 */
525static void pdmGCIsaSetIrq(PVM pVM, int iIrq, int iLevel)
526{
527 if ( ( pVM->pdm.s.IoApic.pDevInsRC
528 || !pVM->pdm.s.IoApic.pDevInsR3)
529 && ( pVM->pdm.s.Pic.pDevInsRC
530 || !pVM->pdm.s.Pic.pDevInsR3))
531 {
532 pdmLock(pVM);
533 if (pVM->pdm.s.Pic.pDevInsRC)
534 pVM->pdm.s.Pic.pfnSetIrqRC(pVM->pdm.s.Pic.pDevInsRC, iIrq, iLevel);
535 if (pVM->pdm.s.IoApic.pDevInsRC)
536 pVM->pdm.s.IoApic.pfnSetIrqRC(pVM->pdm.s.IoApic.pDevInsRC, iIrq, iLevel);
537 pdmUnlock(pVM);
538 }
539 else
540 {
541 /* queue for ring-3 execution. */
542 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueGC);
543 if (pTask)
544 {
545 pTask->enmOp = PDMDEVHLPTASKOP_ISA_SET_IRQ;
546 pTask->pDevInsHC = 0; /* not required */
547 pTask->u.SetIRQ.iIrq = iIrq;
548 pTask->u.SetIRQ.iLevel = iLevel;
549
550 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueGC, &pTask->Core, 0);
551 }
552 else
553 AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
554 }
555}
556
557
558/**
559 * Sets an irq on the I/O APIC.
560 *
561 * @param pVM The VM handle.
562 * @param iIrq The irq.
563 * @param iLevel The new level.
564 */
565static void pdmGCIoApicSetIrq(PVM pVM, int iIrq, int iLevel)
566{
567 if (pVM->pdm.s.IoApic.pDevInsRC)
568 {
569 pdmLock(pVM);
570 pVM->pdm.s.IoApic.pfnSetIrqRC(pVM->pdm.s.IoApic.pDevInsRC, iIrq, iLevel);
571 pdmUnlock(pVM);
572 }
573 else if (pVM->pdm.s.IoApic.pDevInsR3)
574 {
575 /* queue for ring-3 execution. */
576 PPDMDEVHLPTASK pTask = (PPDMDEVHLPTASK)PDMQueueAlloc(pVM->pdm.s.pDevHlpQueueGC);
577 if (pTask)
578 {
579 pTask->enmOp = PDMDEVHLPTASKOP_IOAPIC_SET_IRQ;
580 pTask->pDevInsHC = 0; /* not required */
581 pTask->u.SetIRQ.iIrq = iIrq;
582 pTask->u.SetIRQ.iLevel = iLevel;
583
584 PDMQueueInsertEx(pVM->pdm.s.pDevHlpQueueGC, &pTask->Core, 0);
585 }
586 else
587 AssertMsgFailed(("We're out of devhlp queue items!!!\n"));
588 }
589}
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