VirtualBox

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

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

#1865: PDMQueue.

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