VirtualBox

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

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

Big step to separate VMM data structures for guest SMP. (pgm, em)

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