VirtualBox

source: vbox/trunk/src/VBox/Additions/WINNT/VBoxGuest/Helper.cpp@ 13384

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

Don't overwrite the relevant mmio range with any others found!

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 8.7 KB
Line 
1/** @file
2 *
3 * VBoxGuest -- VirtualBox Win32 guest support driver
4 *
5 * Copyright (C) 2006-2007 Sun Microsystems, Inc.
6 *
7 * This file is part of VirtualBox Open Source Edition (OSE), as
8 * available from http://www.virtualbox.org. This file is free software;
9 * you can redistribute it and/or modify it under the terms of the GNU
10 * General Public License (GPL) as published by the Free Software
11 * Foundation, in version 2 as it comes in the "COPYING" file of the
12 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
13 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
14 *
15 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
16 * Clara, CA 95054 USA or visit http://www.sun.com if you need
17 * additional information or have any questions.
18 */
19
20//#define LOG_ENABLED
21
22#include "VBoxGuest_Internal.h"
23#include "Helper.h"
24#include <VBox/err.h>
25#include <VBox/VBoxGuestLib.h>
26
27#ifdef ALLOC_PRAGMA
28#pragma alloc_text (PAGE, VBoxScanPCIResourceList)
29#endif
30
31/* CM_RESOURCE_MEMORY_* flags which were used on XP or earlier. */
32#define VBOX_CM_PRE_VISTA_MASK (0x3f)
33
34/**
35 * Helper to scan the PCI resource list and remember stuff.
36 *
37 * @param pResList Resource list
38 * @param pDevExt Device extension
39 */
40NTSTATUS VBoxScanPCIResourceList(PCM_RESOURCE_LIST pResList, PVBOXGUESTDEVEXT pDevExt)
41{
42 NTSTATUS rc = STATUS_SUCCESS;
43 PCM_PARTIAL_RESOURCE_DESCRIPTOR partialData;
44
45 // enumerate the resource list
46 dprintf(("found %d resources\n", pResList->List->PartialResourceList.Count));
47 ULONG rangeCount = 0;
48 ULONG cMMIORange = 0;
49 PBASE_ADDRESS baseAddress = pDevExt->baseAddress;
50 for (ULONG i = 0; i < pResList->List->PartialResourceList.Count; i++)
51 {
52 partialData = &pResList->List->PartialResourceList.PartialDescriptors[i];
53 switch (partialData->Type)
54 {
55 case CmResourceTypePort:
56 {
57 // overflow protection
58 if (rangeCount < PCI_TYPE0_ADDRESSES)
59 {
60 dprintf(("I/O range: Base = %08x : %08x Length = %08x \n",
61 partialData->u.Port.Start.HighPart,
62 partialData->u.Port.Start.LowPart,
63 partialData->u.Port.Length));
64 //@todo not so gut
65 dprintf(("I got all I want, my dear port, oh!\n"));
66 pDevExt->startPortAddress = (ULONG)partialData->u.Port.Start.LowPart;
67 // save resource information
68 baseAddress->RangeStart = partialData->u.Port.Start;
69 baseAddress->RangeLength = partialData->u.Port.Length;
70 baseAddress->RangeInMemory = FALSE;
71 baseAddress->ResourceMapped = FALSE;
72 // next item
73 rangeCount++; baseAddress++;
74 }
75 break;
76 }
77
78 case CmResourceTypeInterrupt:
79 {
80 dprintf(("Interrupt: Level = %x Vector = %x Mode = %x \n",
81 partialData->u.Interrupt.Level,
82 partialData->u.Interrupt.Vector,
83 partialData->Flags));
84 // save information
85 pDevExt->interruptLevel = partialData->u.Interrupt.Level;
86 pDevExt->interruptVector = partialData->u.Interrupt.Vector;
87 pDevExt->interruptAffinity = partialData->u.Interrupt.Affinity;
88 // check interrupt mode
89 if (partialData->Flags & CM_RESOURCE_INTERRUPT_LATCHED)
90 {
91 pDevExt->interruptMode = Latched;
92 }
93 else
94 {
95 pDevExt->interruptMode = LevelSensitive;
96 }
97 break;
98 }
99
100 case CmResourceTypeMemory:
101 {
102 // overflow protection
103 if (rangeCount < PCI_TYPE0_ADDRESSES)
104 {
105 dprintf(("Memory range: Base = %08x : %08x Length = %08x \n",
106 partialData->u.Memory.Start.HighPart,
107 partialData->u.Memory.Start.LowPart,
108 partialData->u.Memory.Length));
109 // we only care about read/write memory
110 /** @todo reconsider memory type */
111 if ( cMMIORange == 0 /* only care about the first mmio range (!!!) */
112 && (partialData->Flags & VBOX_CM_PRE_VISTA_MASK) == CM_RESOURCE_MEMORY_READ_WRITE)
113 {
114 pDevExt->memoryAddress = partialData->u.Memory.Start;
115 pDevExt->memoryLength = (ULONG)partialData->u.Memory.Length;
116 // save resource information
117 baseAddress->RangeStart = partialData->u.Memory.Start;
118 baseAddress->RangeLength = partialData->u.Memory.Length;
119 baseAddress->RangeInMemory = TRUE;
120 baseAddress->ResourceMapped = FALSE;
121 // next item
122 rangeCount++; baseAddress++;cMMIORange++;
123 } else
124 {
125 dprintf(("Ignoring memory: flags = %08x \n", partialData->Flags));
126 }
127 }
128 break;
129 }
130
131 case CmResourceTypeDma:
132 {
133 dprintf(("DMA resource found. Hmm...\n"));
134 break;
135 }
136
137 default:
138 {
139 dprintf(("Unexpected resource found %d. Hmm...\n", partialData->Type));
140 break;
141 }
142 }
143 }
144 // memorize the number of resources found
145 pDevExt->addressCount = rangeCount;
146
147 return rc;
148}
149
150
151NTSTATUS hlpVBoxMapVMMDevMemory (PVBOXGUESTDEVEXT pDevExt)
152{
153 NTSTATUS rc = STATUS_SUCCESS;
154
155 if (pDevExt->memoryLength != 0)
156 {
157 pDevExt->pVMMDevMemory = (VMMDevMemory *)MmMapIoSpace (pDevExt->memoryAddress, pDevExt->memoryLength, MmNonCached);
158 dprintf(("VBoxGuest::VBoxGuestPnp: VMMDevMemory: ptr = 0x%x\n", pDevExt->pVMMDevMemory));
159 if (pDevExt->pVMMDevMemory)
160 {
161 dprintf(("VBoxGuest::VBoxGuestPnp: VMMDevMemory: version = 0x%x, size = %d\n", pDevExt->pVMMDevMemory->u32Version, pDevExt->pVMMDevMemory->u32Size));
162
163 /* Check version of the structure */
164 if (pDevExt->pVMMDevMemory->u32Version != VMMDEV_MEMORY_VERSION)
165 {
166 /* Not our version, refuse operation and unmap the memory */
167 hlpVBoxUnmapVMMDevMemory (pDevExt);
168
169 rc = STATUS_UNSUCCESSFUL;
170 }
171 }
172 else
173 {
174 rc = STATUS_UNSUCCESSFUL;
175 }
176 }
177
178 return rc;
179}
180
181void hlpVBoxUnmapVMMDevMemory (PVBOXGUESTDEVEXT pDevExt)
182{
183 if (pDevExt->pVMMDevMemory)
184 {
185 MmUnmapIoSpace (pDevExt->pVMMDevMemory, pDevExt->memoryLength);
186 pDevExt->pVMMDevMemory = NULL;
187 }
188
189 pDevExt->memoryAddress.QuadPart = 0;
190 pDevExt->memoryLength = 0;
191}
192
193NTSTATUS hlpVBoxReportGuestInfo (PVBOXGUESTDEVEXT pDevExt)
194{
195 VMMDevReportGuestInfo *req = NULL;
196
197 int rc = VbglGRAlloc ((VMMDevRequestHeader **)&req, sizeof (VMMDevReportGuestInfo), VMMDevReq_ReportGuestInfo);
198
199 dprintf(("hlpVBoxReportGuestInfo: VbglGRAlloc rc = %d\n", rc));
200
201 if (VBOX_SUCCESS(rc))
202 {
203 req->guestInfo.additionsVersion = VMMDEV_VERSION;
204
205 /* we've already determined the Windows product before */
206 switch (winVersion)
207 {
208 case WINNT4:
209 req->guestInfo.osType = VBOXOSTYPE_WinNT4;
210 break;
211 case WIN2K:
212 req->guestInfo.osType = VBOXOSTYPE_Win2k;
213 break;
214 case WINXP:
215 req->guestInfo.osType = VBOXOSTYPE_WinXP;
216 break;
217 case WIN2K3:
218 req->guestInfo.osType = VBOXOSTYPE_Win2k3;
219 break;
220 case WINVISTA:
221 req->guestInfo.osType = VBOXOSTYPE_WinVista;
222 break;
223 default:
224 /* we don't know, therefore NT family */
225 req->guestInfo.osType = VBOXOSTYPE_WinNT;
226 break;
227 }
228
229 /** @todo registry lookup for additional information */
230
231
232 rc = VbglGRPerform (&req->header);
233
234 if (VBOX_FAILURE(rc) || VBOX_FAILURE(req->header.rc))
235 {
236 dprintf(("VBoxGuest::hlpVBoxReportGuestInfo: error reporting guest info to VMMDev."
237 "rc = %d, VMMDev rc = %Vrc\n", rc, req->header.rc));
238 }
239
240 rc = VBOX_SUCCESS(rc) ? req->header.rc : rc;
241
242 VbglGRFree (&req->header);
243 }
244
245 return VBOX_FAILURE(rc) ? STATUS_UNSUCCESSFUL : STATUS_SUCCESS;
246}
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