VirtualBox

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

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

Automated rebranding to Oracle copyright/license strings via filemuncher

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