VirtualBox

source: vbox/trunk/src/VBox/VMM/VMMR3/PDMDevMiscHlp.cpp@ 43858

Last change on this file since 43858 was 41965, checked in by vboxsync, 12 years ago

VMM: ran scm. Mostly svn:keywords changes (adding Revision).

  • Property svn:eol-style set to native
  • Property svn:keywords set to Id Revision
File size: 25.7 KB
Line 
1/* $Id: PDMDevMiscHlp.cpp 41965 2012-06-29 02:52:49Z vboxsync $ */
2/** @file
3 * PDM - Pluggable Device and Driver Manager, Misc. Device Helpers.
4 */
5
6/*
7 * Copyright (C) 2006-2012 Oracle Corporation
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
18
19/*******************************************************************************
20* Header Files *
21*******************************************************************************/
22#define LOG_GROUP LOG_GROUP_PDM_DEVICE
23#include "PDMInternal.h"
24#include <VBox/vmm/pdm.h>
25#include <VBox/vmm/pgm.h>
26#ifdef VBOX_WITH_REM
27# include <VBox/vmm/rem.h>
28#endif
29#include <VBox/vmm/vm.h>
30#include <VBox/vmm/vmm.h>
31
32#include <VBox/log.h>
33#include <VBox/err.h>
34#include <iprt/asm.h>
35#include <iprt/assert.h>
36#include <iprt/thread.h>
37
38
39#include "PDMInline.h"
40#include "dtrace/VBoxVMM.h"
41
42
43
44/** @name Ring-3 PIC Helpers
45 * @{
46 */
47
48/** @interface_method_impl{PDMPICHLPR3,pfnSetInterruptFF} */
49static DECLCALLBACK(void) pdmR3PicHlp_SetInterruptFF(PPDMDEVINS pDevIns)
50{
51 PDMDEV_ASSERT_DEVINS(pDevIns);
52 PVM pVM = pDevIns->Internal.s.pVMR3;
53
54 if (pVM->pdm.s.Apic.pfnLocalInterruptR3)
55 {
56 LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: Setting local interrupt on LAPIC\n",
57 pDevIns->pReg->szName, pDevIns->iInstance));
58 /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
59 pVM->pdm.s.Apic.pfnLocalInterruptR3(pVM->pdm.s.Apic.pDevInsR3, 0, 1);
60 return;
61 }
62
63 PVMCPU pVCpu = &pVM->aCpus[0]; /* for PIC we always deliver to CPU 0, MP use APIC */
64
65 LogFlow(("pdmR3PicHlp_SetInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_PIC %d -> 1\n",
66 pDevIns->pReg->szName, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
67
68 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
69#ifdef VBOX_WITH_REM
70 REMR3NotifyInterruptSet(pVM, pVCpu);
71#endif
72 VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
73}
74
75
76/** @interface_method_impl{PDMPICHLPR3,pfnClearInterruptFF} */
77static DECLCALLBACK(void) pdmR3PicHlp_ClearInterruptFF(PPDMDEVINS pDevIns)
78{
79 PDMDEV_ASSERT_DEVINS(pDevIns);
80 PVM pVM = pDevIns->Internal.s.pVMR3;
81 PVMCPU pVCpu = &pVM->aCpus[0]; /* for PIC we always deliver to CPU 0, MP use APIC */
82
83 if (pVM->pdm.s.Apic.pfnLocalInterruptR3)
84 {
85 /* Raise the LAPIC's LINT0 line instead of signaling the CPU directly. */
86 LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: Clearing local interrupt on LAPIC\n",
87 pDevIns->pReg->szName, pDevIns->iInstance));
88 /* Lower the LAPIC's LINT0 line instead of signaling the CPU directly. */
89 pVM->pdm.s.Apic.pfnLocalInterruptR3(pVM->pdm.s.Apic.pDevInsR3, 0, 0);
90 return;
91 }
92
93 LogFlow(("pdmR3PicHlp_ClearInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_PIC %d -> 0\n",
94 pDevIns->pReg->szName, pDevIns->iInstance, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_PIC)));
95
96 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
97#ifdef VBOX_WITH_REM
98 REMR3NotifyInterruptClear(pVM, pVCpu);
99#endif
100}
101
102
103/** @interface_method_impl{PDMPICHLPR3,pfnLock} */
104static DECLCALLBACK(int) pdmR3PicHlp_Lock(PPDMDEVINS pDevIns, int rc)
105{
106 PDMDEV_ASSERT_DEVINS(pDevIns);
107 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
108}
109
110
111/** @interface_method_impl{PDMPICHLPR3,pfnUnlock} */
112static DECLCALLBACK(void) pdmR3PicHlp_Unlock(PPDMDEVINS pDevIns)
113{
114 PDMDEV_ASSERT_DEVINS(pDevIns);
115 pdmUnlock(pDevIns->Internal.s.pVMR3);
116}
117
118
119/** @interface_method_impl{PDMPICHLPR3,pfnGetRCHelpers} */
120static DECLCALLBACK(PCPDMPICHLPRC) pdmR3PicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
121{
122 PDMDEV_ASSERT_DEVINS(pDevIns);
123 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
124 RTRCPTR pRCHelpers = 0;
125 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCPicHlp", &pRCHelpers);
126 AssertReleaseRC(rc);
127 AssertRelease(pRCHelpers);
128 LogFlow(("pdmR3PicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
129 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
130 return pRCHelpers;
131}
132
133
134/** @interface_method_impl{PDMPICHLPR3,pfnGetR0Helpers} */
135static DECLCALLBACK(PCPDMPICHLPR0) pdmR3PicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
136{
137 PDMDEV_ASSERT_DEVINS(pDevIns);
138 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
139 PCPDMPICHLPR0 pR0Helpers = 0;
140 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0PicHlp", &pR0Helpers);
141 AssertReleaseRC(rc);
142 AssertRelease(pR0Helpers);
143 LogFlow(("pdmR3PicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
144 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
145 return pR0Helpers;
146}
147
148
149/**
150 * PIC Device Helpers.
151 */
152const PDMPICHLPR3 g_pdmR3DevPicHlp =
153{
154 PDM_PICHLPR3_VERSION,
155 pdmR3PicHlp_SetInterruptFF,
156 pdmR3PicHlp_ClearInterruptFF,
157 pdmR3PicHlp_Lock,
158 pdmR3PicHlp_Unlock,
159 pdmR3PicHlp_GetRCHelpers,
160 pdmR3PicHlp_GetR0Helpers,
161 PDM_PICHLPR3_VERSION /* the end */
162};
163
164/** @} */
165
166
167
168
169/** @name R3 APIC Helpers
170 * @{
171 */
172
173/** @interface_method_impl{PDMAPICHLPR3,pfnSetInterruptFF} */
174static DECLCALLBACK(void) pdmR3ApicHlp_SetInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
175{
176 PDMDEV_ASSERT_DEVINS(pDevIns);
177 PVM pVM = pDevIns->Internal.s.pVMR3;
178 PVMCPU pVCpu = &pVM->aCpus[idCpu];
179
180 AssertReturnVoid(idCpu < pVM->cCpus);
181
182 LogFlow(("pdmR3ApicHlp_SetInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_APIC(%d) %d -> 1\n",
183 pDevIns->pReg->szName, pDevIns->iInstance, idCpu, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
184
185 switch (enmType)
186 {
187 case PDMAPICIRQ_HARDWARE:
188 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_APIC);
189 break;
190 case PDMAPICIRQ_NMI:
191 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_NMI);
192 break;
193 case PDMAPICIRQ_SMI:
194 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_SMI);
195 break;
196 case PDMAPICIRQ_EXTINT:
197 VMCPU_FF_SET(pVCpu, VMCPU_FF_INTERRUPT_PIC);
198 break;
199 default:
200 AssertMsgFailed(("enmType=%d\n", enmType));
201 break;
202 }
203#ifdef VBOX_WITH_REM
204 REMR3NotifyInterruptSet(pVM, pVCpu);
205#endif
206 VMR3NotifyCpuFFU(pVCpu->pUVCpu, VMNOTIFYFF_FLAGS_DONE_REM | VMNOTIFYFF_FLAGS_POKE);
207}
208
209
210/** @interface_method_impl{PDMAPICHLPR3,pfnClearInterruptFF} */
211static DECLCALLBACK(void) pdmR3ApicHlp_ClearInterruptFF(PPDMDEVINS pDevIns, PDMAPICIRQ enmType, VMCPUID idCpu)
212{
213 PDMDEV_ASSERT_DEVINS(pDevIns);
214 PVM pVM = pDevIns->Internal.s.pVMR3;
215 PVMCPU pVCpu = &pVM->aCpus[idCpu];
216
217 AssertReturnVoid(idCpu < pVM->cCpus);
218
219 LogFlow(("pdmR3ApicHlp_ClearInterruptFF: caller='%s'/%d: VMCPU_FF_INTERRUPT_APIC(%d) %d -> 0\n",
220 pDevIns->pReg->szName, pDevIns->iInstance, idCpu, VMCPU_FF_ISSET(pVCpu, VMCPU_FF_INTERRUPT_APIC)));
221
222 /* Note: NMI/SMI can't be cleared. */
223 switch (enmType)
224 {
225 case PDMAPICIRQ_HARDWARE:
226 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_APIC);
227 break;
228 case PDMAPICIRQ_EXTINT:
229 VMCPU_FF_CLEAR(pVCpu, VMCPU_FF_INTERRUPT_PIC);
230 break;
231 default:
232 AssertMsgFailed(("enmType=%d\n", enmType));
233 break;
234 }
235#ifdef VBOX_WITH_REM
236 REMR3NotifyInterruptClear(pVM, pVCpu);
237#endif
238}
239
240
241/** @interface_method_impl{PDMAPICHLPR3,pfnCalcIrqTag} */
242static DECLCALLBACK(uint32_t) pdmR3ApicHlp_CalcIrqTag(PPDMDEVINS pDevIns, uint8_t u8Level)
243{
244 PDMDEV_ASSERT_DEVINS(pDevIns);
245 PVM pVM = pDevIns->Internal.s.pVMR3;
246 Assert(u8Level == PDM_IRQ_LEVEL_HIGH || u8Level == PDM_IRQ_LEVEL_FLIP_FLOP);
247
248 pdmLock(pVM);
249
250 uint32_t uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
251 if (u8Level == PDM_IRQ_LEVEL_HIGH)
252 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
253 else
254 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
255
256
257 pdmUnlock(pVM);
258 LogFlow(("pdmR3ApicHlp_CalcIrqTag: caller='%s'/%d: returns %#x (u8Level=%d)\n",
259 pDevIns->pReg->szName, pDevIns->iInstance, uTagSrc, u8Level));
260 return uTagSrc;
261}
262
263
264/** @interface_method_impl{PDMAPICHLPR3,pfnChangeFeature} */
265static DECLCALLBACK(void) pdmR3ApicHlp_ChangeFeature(PPDMDEVINS pDevIns, PDMAPICVERSION enmVersion)
266{
267 PDMDEV_ASSERT_DEVINS(pDevIns);
268 LogFlow(("pdmR3ApicHlp_ChangeFeature: caller='%s'/%d: version=%d\n",
269 pDevIns->pReg->szName, pDevIns->iInstance, (int)enmVersion));
270 switch (enmVersion)
271 {
272 case PDMAPICVERSION_NONE:
273 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC);
274 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC);
275 break;
276 case PDMAPICVERSION_APIC:
277 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC);
278 CPUMClearGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC);
279 break;
280 case PDMAPICVERSION_X2APIC:
281 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_X2APIC);
282 CPUMSetGuestCpuIdFeature(pDevIns->Internal.s.pVMR3, CPUMCPUIDFEATURE_APIC);
283 break;
284 default:
285 AssertMsgFailed(("Unknown APIC version: %d\n", (int)enmVersion));
286 }
287}
288
289/** @interface_method_impl{PDMAPICHLPR3,pfnGetCpuId} */
290static DECLCALLBACK(VMCPUID) pdmR3ApicHlp_GetCpuId(PPDMDEVINS pDevIns)
291{
292 PDMDEV_ASSERT_DEVINS(pDevIns);
293 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
294 return VMMGetCpuId(pDevIns->Internal.s.pVMR3);
295}
296
297
298/** @interface_method_impl{PDMAPICHLPR3,pfnSendSipi} */
299static DECLCALLBACK(void) pdmR3ApicHlp_SendSipi(PPDMDEVINS pDevIns, VMCPUID idCpu, uint32_t uVector)
300{
301 PDMDEV_ASSERT_DEVINS(pDevIns);
302 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
303 VMMR3SendSipi(pDevIns->Internal.s.pVMR3, idCpu, uVector);
304}
305
306/** @interface_method_impl{PDMAPICHLPR3,pfnSendInitIpi} */
307static DECLCALLBACK(void) pdmR3ApicHlp_SendInitIpi(PPDMDEVINS pDevIns, VMCPUID idCpu)
308{
309 PDMDEV_ASSERT_DEVINS(pDevIns);
310 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
311 VMMR3SendInitIpi(pDevIns->Internal.s.pVMR3, idCpu);
312}
313
314/** @interface_method_impl{PDMAPICHLPR3,pfnGetRCHelpers} */
315static DECLCALLBACK(PCPDMAPICHLPRC) pdmR3ApicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
316{
317 PDMDEV_ASSERT_DEVINS(pDevIns);
318 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
319 RTRCPTR pRCHelpers = 0;
320 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCApicHlp", &pRCHelpers);
321 AssertReleaseRC(rc);
322 AssertRelease(pRCHelpers);
323 LogFlow(("pdmR3ApicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
324 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
325 return pRCHelpers;
326}
327
328
329/** @interface_method_impl{PDMAPICHLPR3,pfnGetR0Helpers} */
330static DECLCALLBACK(PCPDMAPICHLPR0) pdmR3ApicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
331{
332 PDMDEV_ASSERT_DEVINS(pDevIns);
333 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
334 PCPDMAPICHLPR0 pR0Helpers = 0;
335 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0ApicHlp", &pR0Helpers);
336 AssertReleaseRC(rc);
337 AssertRelease(pR0Helpers);
338 LogFlow(("pdmR3ApicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
339 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
340 return pR0Helpers;
341}
342
343
344/** @interface_method_impl{PDMAPICHLPR3,pfnGetR3CritSect} */
345static DECLCALLBACK(R3PTRTYPE(PPDMCRITSECT)) pdmR3ApicHlp_GetR3CritSect(PPDMDEVINS pDevIns)
346{
347 PDMDEV_ASSERT_DEVINS(pDevIns);
348 LogFlow(("pdmR3ApicHlp_Lock: caller='%s'/%d\n", pDevIns->pReg->szName, pDevIns->iInstance));
349 return &pDevIns->Internal.s.pVMR3->pdm.s.CritSect;
350}
351
352
353/** @interface_method_impl{PDMAPICHLPR3,pfnGetRCCritSect} */
354static DECLCALLBACK(RCPTRTYPE(PPDMCRITSECT)) pdmR3ApicHlp_GetRCCritSect(PPDMDEVINS pDevIns)
355{
356 PDMDEV_ASSERT_DEVINS(pDevIns);
357 PVM pVM = pDevIns->Internal.s.pVMR3;
358 RTRCPTR RCPtr = MMHyperCCToRC(pVM, &pVM->pdm.s.CritSect);
359 LogFlow(("pdmR3ApicHlp_GetR0CritSect: caller='%s'/%d: return %RRv\n", pDevIns->pReg->szName, pDevIns->iInstance, RCPtr));
360 return RCPtr;
361}
362
363
364/** @interface_method_impl{PDMAPICHLPR3,pfnGetR3CritSect} */
365static DECLCALLBACK(R0PTRTYPE(PPDMCRITSECT)) pdmR3ApicHlp_GetR0CritSect(PPDMDEVINS pDevIns)
366{
367 PDMDEV_ASSERT_DEVINS(pDevIns);
368 PVM pVM = pDevIns->Internal.s.pVMR3;
369 RTR0PTR R0Ptr = MMHyperCCToR0(pVM, &pVM->pdm.s.CritSect);
370 LogFlow(("pdmR3ApicHlp_GetR0CritSect: caller='%s'/%d: return %RHv\n", pDevIns->pReg->szName, pDevIns->iInstance, R0Ptr));
371 return R0Ptr;
372}
373
374
375
376/**
377 * APIC Device Helpers.
378 */
379const PDMAPICHLPR3 g_pdmR3DevApicHlp =
380{
381 PDM_APICHLPR3_VERSION,
382 pdmR3ApicHlp_SetInterruptFF,
383 pdmR3ApicHlp_ClearInterruptFF,
384 pdmR3ApicHlp_CalcIrqTag,
385 pdmR3ApicHlp_ChangeFeature,
386 pdmR3ApicHlp_GetCpuId,
387 pdmR3ApicHlp_SendSipi,
388 pdmR3ApicHlp_SendInitIpi,
389 pdmR3ApicHlp_GetRCHelpers,
390 pdmR3ApicHlp_GetR0Helpers,
391 pdmR3ApicHlp_GetR3CritSect,
392 pdmR3ApicHlp_GetRCCritSect,
393 pdmR3ApicHlp_GetR0CritSect,
394 PDM_APICHLPR3_VERSION /* the end */
395};
396
397/** @} */
398
399
400
401
402/** @name Ring-3 I/O APIC Helpers
403 * @{
404 */
405
406/** @interface_method_impl{PDMIOAPICHLPR3,pfnApicBusDeliver} */
407static DECLCALLBACK(int) pdmR3IoApicHlp_ApicBusDeliver(PPDMDEVINS pDevIns, uint8_t u8Dest, uint8_t u8DestMode, uint8_t u8DeliveryMode,
408 uint8_t iVector, uint8_t u8Polarity, uint8_t u8TriggerMode, uint32_t uTagSrc)
409{
410 PDMDEV_ASSERT_DEVINS(pDevIns);
411 PVM pVM = pDevIns->Internal.s.pVMR3;
412 LogFlow(("pdmR3IoApicHlp_ApicBusDeliver: caller='%s'/%d: u8Dest=%RX8 u8DestMode=%RX8 u8DeliveryMode=%RX8 iVector=%RX8 u8Polarity=%RX8 u8TriggerMode=%RX8 uTagSrc=%#x\n",
413 pDevIns->pReg->szName, pDevIns->iInstance, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc));
414 if (pVM->pdm.s.Apic.pfnBusDeliverR3)
415 return pVM->pdm.s.Apic.pfnBusDeliverR3(pVM->pdm.s.Apic.pDevInsR3, u8Dest, u8DestMode, u8DeliveryMode, iVector, u8Polarity, u8TriggerMode, uTagSrc);
416 return VINF_SUCCESS;
417}
418
419
420/** @interface_method_impl{PDMIOAPICHLPR3,pfnLock} */
421static DECLCALLBACK(int) pdmR3IoApicHlp_Lock(PPDMDEVINS pDevIns, int rc)
422{
423 PDMDEV_ASSERT_DEVINS(pDevIns);
424 LogFlow(("pdmR3IoApicHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
425 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
426}
427
428
429/** @interface_method_impl{PDMIOAPICHLPR3,pfnUnlock} */
430static DECLCALLBACK(void) pdmR3IoApicHlp_Unlock(PPDMDEVINS pDevIns)
431{
432 PDMDEV_ASSERT_DEVINS(pDevIns);
433 LogFlow(("pdmR3IoApicHlp_Unlock: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
434 pdmUnlock(pDevIns->Internal.s.pVMR3);
435}
436
437
438/** @interface_method_impl{PDMIOAPICHLPR3,pfnGetRCHelpers} */
439static DECLCALLBACK(PCPDMIOAPICHLPRC) pdmR3IoApicHlp_GetRCHelpers(PPDMDEVINS pDevIns)
440{
441 PDMDEV_ASSERT_DEVINS(pDevIns);
442 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
443 RTRCPTR pRCHelpers = 0;
444 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCIoApicHlp", &pRCHelpers);
445 AssertReleaseRC(rc);
446 AssertRelease(pRCHelpers);
447 LogFlow(("pdmR3IoApicHlp_GetRCHelpers: caller='%s'/%d: returns %RRv\n",
448 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
449 return pRCHelpers;
450}
451
452
453/** @interface_method_impl{PDMIOAPICHLPR3,pfnGetR0Helpers} */
454static DECLCALLBACK(PCPDMIOAPICHLPR0) pdmR3IoApicHlp_GetR0Helpers(PPDMDEVINS pDevIns)
455{
456 PDMDEV_ASSERT_DEVINS(pDevIns);
457 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
458 PCPDMIOAPICHLPR0 pR0Helpers = 0;
459 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0IoApicHlp", &pR0Helpers);
460 AssertReleaseRC(rc);
461 AssertRelease(pR0Helpers);
462 LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
463 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
464 return pR0Helpers;
465}
466
467
468/**
469 * I/O APIC Device Helpers.
470 */
471const PDMIOAPICHLPR3 g_pdmR3DevIoApicHlp =
472{
473 PDM_IOAPICHLPR3_VERSION,
474 pdmR3IoApicHlp_ApicBusDeliver,
475 pdmR3IoApicHlp_Lock,
476 pdmR3IoApicHlp_Unlock,
477 pdmR3IoApicHlp_GetRCHelpers,
478 pdmR3IoApicHlp_GetR0Helpers,
479 PDM_IOAPICHLPR3_VERSION /* the end */
480};
481
482/** @} */
483
484
485
486
487/** @name Ring-3 PCI Bus Helpers
488 * @{
489 */
490
491/** @interface_method_impl{PDMPCIHLPR3,pfnIsaSetIrq} */
492static DECLCALLBACK(void) pdmR3PciHlp_IsaSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
493{
494 PDMDEV_ASSERT_DEVINS(pDevIns);
495 Log4(("pdmR3PciHlp_IsaSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
496 PVM pVM = pDevIns->Internal.s.pVMR3;
497 PDMIsaSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel, uTagSrc);
498}
499
500/** @interface_method_impl{PDMPCIHLPR3,pfnIoApicSetIrq} */
501static DECLCALLBACK(void) pdmR3PciHlp_IoApicSetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel, uint32_t uTagSrc)
502{
503 PDMDEV_ASSERT_DEVINS(pDevIns);
504 Log4(("pdmR3PciHlp_IoApicSetIrq: iIrq=%d iLevel=%d uTagSrc=%#x\n", iIrq, iLevel, uTagSrc));
505 PDMIoApicSetIrq(pDevIns->Internal.s.pVMR3, iIrq, iLevel, uTagSrc);
506}
507
508/** @interface_method_impl{PDMPCIHLPR3,pfnIoApicSendMsi} */
509static DECLCALLBACK(void) pdmR3PciHlp_IoApicSendMsi(PPDMDEVINS pDevIns, RTGCPHYS GCAddr, uint32_t uValue, uint32_t uTagSrc)
510{
511 PDMDEV_ASSERT_DEVINS(pDevIns);
512 Log4(("pdmR3PciHlp_IoApicSendMsi: address=%p value=%x uTagSrc=%#x\n", GCAddr, uValue, uTagSrc));
513 PDMIoApicSendMsi(pDevIns->Internal.s.pVMR3, GCAddr, uValue, uTagSrc);
514}
515
516/** @interface_method_impl{PDMPCIHLPR3,pfnIsMMIO2Base} */
517static DECLCALLBACK(bool) pdmR3PciHlp_IsMMIO2Base(PPDMDEVINS pDevIns, PPDMDEVINS pOwner, RTGCPHYS GCPhys)
518{
519 PDMDEV_ASSERT_DEVINS(pDevIns);
520 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
521 bool fRc = PGMR3PhysMMIO2IsBase(pDevIns->Internal.s.pVMR3, pOwner, GCPhys);
522 Log4(("pdmR3PciHlp_IsMMIO2Base: pOwner=%p GCPhys=%RGp -> %RTbool\n", pOwner, GCPhys, fRc));
523 return fRc;
524}
525
526
527/** @interface_method_impl{PDMPCIHLPR3,pfnLock} */
528static DECLCALLBACK(int) pdmR3PciHlp_Lock(PPDMDEVINS pDevIns, int rc)
529{
530 PDMDEV_ASSERT_DEVINS(pDevIns);
531 LogFlow(("pdmR3PciHlp_Lock: caller='%s'/%d: rc=%Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
532 return pdmLockEx(pDevIns->Internal.s.pVMR3, rc);
533}
534
535
536/** @interface_method_impl{PDMPCIHLPR3,pfnUnlock} */
537static DECLCALLBACK(void) pdmR3PciHlp_Unlock(PPDMDEVINS pDevIns)
538{
539 PDMDEV_ASSERT_DEVINS(pDevIns);
540 LogFlow(("pdmR3PciHlp_Unlock: caller='%s'/%d:\n", pDevIns->pReg->szName, pDevIns->iInstance));
541 pdmUnlock(pDevIns->Internal.s.pVMR3);
542}
543
544
545/** @interface_method_impl{PDMPCIHLPR3,pfnGetRCHelpers} */
546static DECLCALLBACK(PCPDMPCIHLPRC) pdmR3PciHlp_GetRCHelpers(PPDMDEVINS pDevIns)
547{
548 PDMDEV_ASSERT_DEVINS(pDevIns);
549 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
550 RTRCPTR pRCHelpers = 0;
551 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCPciHlp", &pRCHelpers);
552 AssertReleaseRC(rc);
553 AssertRelease(pRCHelpers);
554 LogFlow(("pdmR3IoApicHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
555 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
556 return pRCHelpers;
557}
558
559
560/** @interface_method_impl{PDMPCIHLPR3,pfnGetR0Helpers} */
561static DECLCALLBACK(PCPDMPCIHLPR0) pdmR3PciHlp_GetR0Helpers(PPDMDEVINS pDevIns)
562{
563 PDMDEV_ASSERT_DEVINS(pDevIns);
564 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
565 PCPDMPCIHLPR0 pR0Helpers = 0;
566 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0PciHlp", &pR0Helpers);
567 AssertReleaseRC(rc);
568 AssertRelease(pR0Helpers);
569 LogFlow(("pdmR3IoApicHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
570 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
571 return pR0Helpers;
572}
573
574
575/**
576 * PCI Bus Device Helpers.
577 */
578const PDMPCIHLPR3 g_pdmR3DevPciHlp =
579{
580 PDM_PCIHLPR3_VERSION,
581 pdmR3PciHlp_IsaSetIrq,
582 pdmR3PciHlp_IoApicSetIrq,
583 pdmR3PciHlp_IoApicSendMsi,
584 pdmR3PciHlp_IsMMIO2Base,
585 pdmR3PciHlp_GetRCHelpers,
586 pdmR3PciHlp_GetR0Helpers,
587 pdmR3PciHlp_Lock,
588 pdmR3PciHlp_Unlock,
589 PDM_PCIHLPR3_VERSION, /* the end */
590};
591
592/** @} */
593
594
595
596
597/** @name Ring-3 HPET Helpers
598 * {@
599 */
600
601/** @interface_method_impl{PDMHPETHLPR3,pfnSetLegacyMode} */
602static DECLCALLBACK(int) pdmR3HpetHlp_SetLegacyMode(PPDMDEVINS pDevIns, bool fActivated)
603{
604 PDMDEV_ASSERT_DEVINS(pDevIns);
605 LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: fActivated=%RTbool\n", pDevIns->pReg->szName, pDevIns->iInstance, fActivated));
606
607 size_t i;
608 int rc = VINF_SUCCESS;
609 static const char * const s_apszDevsToNotify[] =
610 {
611 "i8254",
612 "mc146818"
613 };
614 for (i = 0; i < RT_ELEMENTS(s_apszDevsToNotify); i++)
615 {
616 PPDMIBASE pBase;
617 rc = PDMR3QueryDevice(pDevIns->Internal.s.pVMR3, "i8254", 0, &pBase);
618 if (RT_SUCCESS(rc))
619 {
620 PPDMIHPETLEGACYNOTIFY pPort = PDMIBASE_QUERY_INTERFACE(pBase, PDMIHPETLEGACYNOTIFY);
621 AssertLogRelMsgBreakStmt(pPort, ("%s\n", s_apszDevsToNotify[i]), rc = VERR_PDM_HPET_LEGACY_NOTIFY_MISSING);
622 pPort->pfnModeChanged(pPort, fActivated);
623 }
624 else if ( rc == VERR_PDM_DEVICE_NOT_FOUND
625 || rc == VERR_PDM_DEVICE_INSTANCE_NOT_FOUND)
626 rc = VINF_SUCCESS; /* the device isn't configured, ignore. */
627 else
628 AssertLogRelMsgFailedBreak(("%s -> %Rrc\n", s_apszDevsToNotify[i], rc));
629 }
630
631 /* Don't bother cleaning up, any failure here will cause a guru meditation. */
632
633 LogFlow(("pdmR3HpetHlp_SetLegacyMode: caller='%s'/%d: returns %Rrc\n", pDevIns->pReg->szName, pDevIns->iInstance, rc));
634 return rc;
635}
636
637
638/** @interface_method_impl{PDMHPETHLPR3,pfnSetIrq} */
639static DECLCALLBACK(int) pdmR3HpetHlp_SetIrq(PPDMDEVINS pDevIns, int iIrq, int iLevel)
640{
641 PDMDEV_ASSERT_DEVINS(pDevIns);
642 LogFlow(("pdmR3HpetHlp_SetIrq: caller='%s'/%d: iIrq=%d iLevel=%d\n", pDevIns->pReg->szName, pDevIns->iInstance, iIrq, iLevel));
643 PVM pVM = pDevIns->Internal.s.pVMR3;
644
645 pdmLock(pVM);
646 uint32_t uTagSrc;
647 if (iLevel & PDM_IRQ_LEVEL_HIGH)
648 {
649 pDevIns->Internal.s.uLastIrqTag = uTagSrc = pdmCalcIrqTag(pVM, pDevIns->idTracing);
650 if (iLevel == PDM_IRQ_LEVEL_HIGH)
651 VBOXVMM_PDM_IRQ_HIGH(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
652 else
653 VBOXVMM_PDM_IRQ_HILO(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
654 }
655 else
656 uTagSrc = pDevIns->Internal.s.uLastIrqTag;
657
658 PDMIsaSetIrq(pVM, iIrq, iLevel, uTagSrc); /* (The API takes the lock recursively.) */
659
660 if (iLevel == PDM_IRQ_LEVEL_LOW)
661 VBOXVMM_PDM_IRQ_LOW(VMMGetCpu(pVM), RT_LOWORD(uTagSrc), RT_HIWORD(uTagSrc));
662 pdmUnlock(pVM);
663 return 0;
664}
665
666
667/** @interface_method_impl{PDMHPETHLPR3,pfnGetRCHelpers} */
668static DECLCALLBACK(PCPDMHPETHLPRC) pdmR3HpetHlp_GetRCHelpers(PPDMDEVINS pDevIns)
669{
670 PDMDEV_ASSERT_DEVINS(pDevIns);
671 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
672 RTRCPTR pRCHelpers = 0;
673 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCHpetHlp", &pRCHelpers);
674 AssertReleaseRC(rc);
675 AssertRelease(pRCHelpers);
676 LogFlow(("pdmR3HpetHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
677 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
678 return pRCHelpers;
679}
680
681
682/** @interface_method_impl{PDMHPETHLPR3,pfnGetR0Helpers} */
683static DECLCALLBACK(PCPDMHPETHLPR0) pdmR3HpetHlp_GetR0Helpers(PPDMDEVINS pDevIns)
684{
685 PDMDEV_ASSERT_DEVINS(pDevIns);
686 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
687 PCPDMHPETHLPR0 pR0Helpers = 0;
688 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0HpetHlp", &pR0Helpers);
689 AssertReleaseRC(rc);
690 AssertRelease(pR0Helpers);
691 LogFlow(("pdmR3HpetHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
692 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
693 return pR0Helpers;
694}
695
696
697/**
698 * HPET Device Helpers.
699 */
700const PDMHPETHLPR3 g_pdmR3DevHpetHlp =
701{
702 PDM_HPETHLPR3_VERSION,
703 pdmR3HpetHlp_GetRCHelpers,
704 pdmR3HpetHlp_GetR0Helpers,
705 pdmR3HpetHlp_SetLegacyMode,
706 pdmR3HpetHlp_SetIrq,
707 PDM_HPETHLPR3_VERSION, /* the end */
708};
709
710/** @} */
711
712
713/** @name Ring-3 Raw PCI Device Helpers
714 * {@
715 */
716
717/** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetRCHelpers} */
718static DECLCALLBACK(PCPDMPCIRAWHLPRC) pdmR3PciRawHlp_GetRCHelpers(PPDMDEVINS pDevIns)
719{
720 PDMDEV_ASSERT_DEVINS(pDevIns);
721 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
722 RTRCPTR pRCHelpers = NIL_RTRCPTR;
723 int rc = PDMR3LdrGetSymbolRC(pDevIns->Internal.s.pVMR3, NULL, "g_pdmRCPciRawHlp", &pRCHelpers);
724 AssertReleaseRC(rc);
725 AssertRelease(pRCHelpers);
726 LogFlow(("pdmR3PciRawHlp_GetGCHelpers: caller='%s'/%d: returns %RRv\n",
727 pDevIns->pReg->szName, pDevIns->iInstance, pRCHelpers));
728 return pRCHelpers;
729}
730
731
732/** @interface_method_impl{PDMPCIRAWHLPR3,pfnGetR0Helpers} */
733static DECLCALLBACK(PCPDMPCIRAWHLPR0) pdmR3PciRawHlp_GetR0Helpers(PPDMDEVINS pDevIns)
734{
735 PDMDEV_ASSERT_DEVINS(pDevIns);
736 VM_ASSERT_EMT(pDevIns->Internal.s.pVMR3);
737 PCPDMHPETHLPR0 pR0Helpers = NIL_RTR0PTR;
738 int rc = PDMR3LdrGetSymbolR0(pDevIns->Internal.s.pVMR3, NULL, "g_pdmR0PciRawHlp", &pR0Helpers);
739 AssertReleaseRC(rc);
740 AssertRelease(pR0Helpers);
741 LogFlow(("pdmR3PciRawHlp_GetR0Helpers: caller='%s'/%d: returns %RHv\n",
742 pDevIns->pReg->szName, pDevIns->iInstance, pR0Helpers));
743 return pR0Helpers;
744}
745
746
747/**
748 * Raw PCI Device Helpers.
749 */
750const PDMPCIRAWHLPR3 g_pdmR3DevPciRawHlp =
751{
752 PDM_PCIRAWHLPR3_VERSION,
753 pdmR3PciRawHlp_GetRCHelpers,
754 pdmR3PciRawHlp_GetR0Helpers,
755 PDM_PCIRAWHLPR3_VERSION, /* the end */
756};
757
758/** @} */
759
760
761/* none yet */
762
763/**
764 * DMAC Device Helpers.
765 */
766const PDMDMACHLP g_pdmR3DevDmacHlp =
767{
768 PDM_DMACHLP_VERSION
769};
770
771
772
773
774/* none yet */
775
776/**
777 * RTC Device Helpers.
778 */
779const PDMRTCHLP g_pdmR3DevRtcHlp =
780{
781 PDM_RTCHLP_VERSION
782};
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