VirtualBox

source: vbox/trunk/src/VBox/Devices/GIMDev/GIMDev.cpp@ 58143

Last change on this file since 58143 was 57989, checked in by vboxsync, 9 years ago

Added support for GIM Hyper-V hypercalls and guest debugging.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.3 KB
Line 
1/* $Id: GIMDev.cpp 57989 2015-10-01 16:44:12Z vboxsync $ */
2/** @file
3 * Guest Interface Manager Device.
4 */
5
6/*
7 * Copyright (C) 2014-2015 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_DEV_GIM
23#include <VBox/vmm/pdmdev.h>
24#include <VBox/vmm/gim.h>
25#include <VBox/vmm/vm.h>
26
27#include "VBoxDD.h"
28#include <iprt/uuid.h>
29
30#define GIMDEV_DEBUG_LUN 998
31
32/**
33 * GIM device.
34 */
35typedef struct GIMDEV
36{
37 /** Pointer to the device instance - R3 Ptr. */
38 PPDMDEVINSR3 pDevInsR3;
39 /** Pointer to the device instance - R0 Ptr. */
40 PPDMDEVINSR0 pDevInsR0;
41 /** Pointer to the device instance - RC Ptr. */
42 PPDMDEVINSRC pDevInsRC;
43 /** Alignment. */
44 RTRCPTR Alignment0;
45
46 /** LUN\#998: The debug interface. */
47 PDMIBASE IDbgBase;
48 /** LUN\#998: The stream port interface. */
49 PDMISTREAM IDbgStreamPort;
50 /** Pointer to the attached base debug driver. */
51 R3PTRTYPE(PPDMIBASE) pDbgDrvBase;
52 /** Pointer to the attached debug stream driver. */
53 R3PTRTYPE(PPDMISTREAM) pDbgDrvStream;
54} GIMDEV;
55/** Pointer to the GIM device state. */
56typedef GIMDEV *PGIMDEV;
57AssertCompileMemberAlignment(GIMDEV, IDbgBase, 8);
58
59#ifndef VBOX_DEVICE_STRUCT_TESTCASE
60
61#ifdef IN_RING3
62
63
64/* -=-=-=-=-=-=-=-=- PDMIBASE on LUN#GIMDEV_DEBUG_LUN -=-=-=-=-=-=-=-=- */
65
66/**
67 * @interface_method_impl{PDMIBASE, pfnQueryInterface}
68 */
69static DECLCALLBACK(void *) gimdevR3QueryInterface(PPDMIBASE pInterface, const char *pszIID)
70{
71 PGIMDEV pThis = RT_FROM_MEMBER(pInterface, GIMDEV, IDbgBase);
72 PDMIBASE_RETURN_INTERFACE(pszIID, PDMIBASE, &pThis->IDbgBase);
73 PDMIBASE_RETURN_INTERFACE(pszIID, PDMISTREAM, &pThis->IDbgStreamPort);
74 return NULL;
75}
76
77
78/**
79 * @interface_method_impl{PDMDEVREG,pfnConstruct}
80 */
81static DECLCALLBACK(int) gimdevR3Construct(PPDMDEVINS pDevIns, int iInstance, PCFGMNODE pCfg)
82{
83 Assert(iInstance == 0);
84 PGIMDEV pThis = PDMINS_2_DATA(pDevIns, PGIMDEV);
85 PDMDEV_CHECK_VERSIONS_RETURN(pDevIns);
86
87 /*
88 * Initialize relevant state bits.
89 */
90 pThis->pDevInsR3 = pDevIns;
91 pThis->pDevInsR0 = PDMDEVINS_2_R0PTR(pDevIns);
92 pThis->pDevInsRC = PDMDEVINS_2_RCPTR(pDevIns);
93
94 /*
95 * Attach the stream driver for the debug connection.
96 */
97 pThis->IDbgBase.pfnQueryInterface = gimdevR3QueryInterface;
98 int rc = PDMDevHlpDriverAttach(pDevIns, GIMDEV_DEBUG_LUN, &pThis->IDbgBase, &pThis->pDbgDrvBase, "GIM Debug Port");
99 if (RT_SUCCESS(rc))
100 {
101 pThis->pDbgDrvStream = PDMIBASE_QUERY_INTERFACE(pThis->pDbgDrvBase, PDMISTREAM);
102 if (pThis->pDbgDrvStream)
103 LogRel(("GIMDev: LUN#%u: Debug port configured\n", GIMDEV_DEBUG_LUN));
104 else
105 LogRel(("GIMDev: LUN#%u: No unit\n", GIMDEV_DEBUG_LUN));
106 }
107 else if (rc == VERR_PDM_NO_ATTACHED_DRIVER)
108 {
109 pThis->pDbgDrvBase = NULL;
110 pThis->pDbgDrvStream = NULL;
111 LogRel(("GIMDev: LUN#%u: No debug port configured\n", GIMDEV_DEBUG_LUN));
112 }
113 else
114 {
115 AssertLogRelMsgFailed(("GIMDev: LUN#%u: Failed to attach to driver on debug port. rc=%Rrc\n", GIMDEV_DEBUG_LUN, rc));
116 /* Don't call VMSetError here as we assume that the driver already set an appropriate error */
117 return rc;
118 }
119
120 /*
121 * Register ourselves with the GIM VMM component.
122 */
123 PVM pVM = PDMDevHlpGetVM(pDevIns);
124 GIMR3GimDeviceRegister(pVM, pDevIns, pThis->pDbgDrvStream);
125
126 /*
127 * Get the MMIO2 regions from the GIM provider.
128 */
129 uint32_t cRegions = 0;
130 PGIMMMIO2REGION pRegionsR3 = GIMR3GetMmio2Regions(pVM, &cRegions);
131 if ( cRegions
132 && pRegionsR3)
133 {
134 /*
135 * Register the MMIO2 regions.
136 */
137 PGIMMMIO2REGION pCur = pRegionsR3;
138 for (uint32_t i = 0; i < cRegions; i++, pCur++)
139 {
140 Assert(!pCur->fRegistered);
141 rc = PDMDevHlpMMIO2Register(pDevIns, pCur->iRegion, pCur->cbRegion, 0 /* fFlags */, &pCur->pvPageR3,
142 pCur->szDescription);
143 if (RT_FAILURE(rc))
144 return rc;
145
146 pCur->fRegistered = true;
147
148#if defined(VBOX_WITH_2X_4GB_ADDR_SPACE)
149 RTR0PTR pR0Mapping = 0;
150 rc = PDMDevHlpMMIO2MapKernel(pDevIns, pCur->iRegion, 0 /* off */, pCur->cbRegion, pCur->szDescription,
151 &pR0Mapping);
152 AssertLogRelMsgRCReturn(rc, ("PDMDevHlpMapMMIO2IntoR0(%#x,) -> %Rrc\n", pCur->cbRegion, rc), rc);
153 pCur->pvPageR0 = pR0Mapping;
154#else
155 pCur->pvPageR0 = (RTR0PTR)pCur->pvPageR3;
156#endif
157
158 /*
159 * Map into RC if required.
160 */
161 if (pCur->fRCMapping)
162 {
163 RTRCPTR pRCMapping = 0;
164 rc = PDMDevHlpMMHyperMapMMIO2(pDevIns, pCur->iRegion, 0 /* off */, pCur->cbRegion, pCur->szDescription,
165 &pRCMapping);
166 AssertLogRelMsgRCReturn(rc, ("PDMDevHlpMMHyperMapMMIO2(%#x,) -> %Rrc\n", pCur->cbRegion, rc), rc);
167 pCur->pvPageRC = pRCMapping;
168 }
169 else
170 pCur->pvPageRC = NIL_RTRCPTR;
171
172 LogRel(("GIMDev: Registered %s\n", pCur->szDescription));
173 }
174 }
175
176 /** @todo Register SSM: PDMDevHlpSSMRegister(). */
177 /** @todo Register statistics: STAM_REG(). */
178 /** @todo Register DBGFInfo: PDMDevHlpDBGFInfoRegister(). */
179
180 return VINF_SUCCESS;
181}
182
183
184/**
185 * @interface_method_impl{PDMDEVREG,pfnDestruct}
186 */
187static DECLCALLBACK(int) gimdevR3Destruct(PPDMDEVINS pDevIns)
188{
189 PGIMDEV pThis = PDMINS_2_DATA(pDevIns, PGIMDEV);
190 PVM pVM = PDMDevHlpGetVM(pDevIns);
191 uint32_t cRegions = 0;
192
193 PGIMMMIO2REGION pCur = GIMR3GetMmio2Regions(pVM, &cRegions);
194 for (uint32_t i = 0; i < cRegions; i++, pCur++)
195 {
196 int rc = PDMDevHlpMMIO2Deregister(pDevIns, pCur->iRegion);
197 if (RT_FAILURE(rc))
198 return rc;
199 }
200
201 return VINF_SUCCESS;
202}
203
204
205/**
206 * @interface_method_impl{PDMDEVREG,pfnRelocate}
207 */
208static DECLCALLBACK(void) gimdevR3Relocate(PPDMDEVINS pDevIns, RTGCINTPTR offDelta)
209{
210 NOREF(pDevIns);
211 NOREF(offDelta);
212}
213
214
215/**
216 * @interface_method_impl{PDMDEVREG,pfnReset}
217 */
218static DECLCALLBACK(void) gimdevR3Reset(PPDMDEVINS pDevIns)
219{
220 NOREF(pDevIns);
221 /* We do not deregister any MMIO2 regions as the regions are expected to be static. */
222}
223
224
225/**
226 * The device registration structure.
227 */
228const PDMDEVREG g_DeviceGIMDev =
229{
230 /* u32Version */
231 PDM_DEVREG_VERSION,
232 /* szName */
233 "GIMDev",
234 /* szRCMod */
235 "VBoxDDRC.rc",
236 /* szR0Mod */
237 "VBoxDDR0.r0",
238 /* pszDescription */
239 "VirtualBox GIM Device",
240 /* fFlags */
241 PDM_DEVREG_FLAGS_DEFAULT_BITS | PDM_DEVREG_FLAGS_R0 | PDM_DEVREG_FLAGS_RC,
242 /* fClass */
243 PDM_DEVREG_CLASS_MISC,
244 /* cMaxInstances */
245 1,
246 /* cbInstance */
247 sizeof(GIMDEV),
248 /* pfnConstruct */
249 gimdevR3Construct,
250 /* pfnDestruct */
251 gimdevR3Destruct,
252 /* pfnRelocate */
253 gimdevR3Relocate,
254 /* pfnMemSetup */
255 NULL,
256 /* pfnPowerOn */
257 NULL,
258 /* pfnReset */
259 gimdevR3Reset,
260 /* pfnSuspend */
261 NULL,
262 /* pfnResume */
263 NULL,
264 /* pfnAttach */
265 NULL,
266 /* pfnDetach */
267 NULL,
268 /* pfnQueryInterface. */
269 NULL,
270 /* pfnInitComplete */
271 NULL,
272 /* pfnPowerOff */
273 NULL,
274 /* pfnSoftReset */
275 NULL,
276 /* u32VersionEnd */
277 PDM_DEVREG_VERSION
278};
279#endif /* IN_RING3 */
280
281#endif /* VBOX_DEVICE_STRUCT_TESTCASE */
282
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