VirtualBox

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

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

HPET: correct interrupts delivery

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