VirtualBox

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

Last change on this file since 18645 was 18645, checked in by vboxsync, 15 years ago

VMSetRuntimeError[V] refactoring: fFatal -> fFlags, may return informational status codes.

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