VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp

Last change on this file was 98103, checked in by vboxsync, 16 months ago

Copyright year updates by scm.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.6 KB
Line 
1/* $Id: HGSMIBase.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
2/** @file
3 * VirtualBox Video driver, common code - HGSMI guest-to-host communication.
4 */
5
6/*
7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31#include <HGSMIBase.h>
32#include <VBoxVideoIPRT.h>
33#include <VBoxVideoGuest.h>
34#include <VBoxVideoVBE.h>
35#include <HGSMIChannels.h>
36#include <HGSMIChSetup.h>
37
38/** Detect whether HGSMI is supported by the host. */
39DECLHIDDEN(bool) VBoxHGSMIIsSupported(void)
40{
41 uint16_t DispiId;
42
43 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
44 VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_HGSMI);
45
46 DispiId = VBVO_PORT_READ_U16(VBE_DISPI_IOPORT_DATA);
47
48 return (DispiId == VBE_DISPI_ID_HGSMI);
49}
50
51
52/**
53 * Inform the host of the location of the host flags in VRAM via an HGSMI command.
54 * @returns IPRT status value.
55 * @returns VERR_NOT_IMPLEMENTED if the host does not support the command.
56 * @returns VERR_NO_MEMORY if a heap allocation fails.
57 * @param pCtx the context of the guest heap to use.
58 * @param offLocation the offset chosen for the flags withing guest VRAM.
59 */
60DECLHIDDEN(int) VBoxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx, HGSMIOFFSET offLocation)
61{
62
63 /* Allocate the IO buffer. */
64 HGSMIBUFFERLOCATION RT_UNTRUSTED_VOLATILE_HOST *p =
65 (HGSMIBUFFERLOCATION RT_UNTRUSTED_VOLATILE_HOST *)VBoxHGSMIBufferAlloc(pCtx, sizeof(*p), HGSMI_CH_HGSMI,
66 HGSMI_CC_HOST_FLAGS_LOCATION);
67 if (!p)
68 return VERR_NO_MEMORY;
69
70 /* Prepare data to be sent to the host. */
71 p->offLocation = offLocation;
72 p->cbLocation = sizeof(HGSMIHOSTFLAGS);
73 /* No need to check that the buffer is valid as we have just allocated it. */
74 VBoxHGSMIBufferSubmit(pCtx, p);
75 /* Free the IO buffer. */
76 VBoxHGSMIBufferFree(pCtx, p);
77
78 return VINF_SUCCESS;
79}
80
81
82/**
83 * Notify the host of HGSMI-related guest capabilities via an HGSMI command.
84 * @returns IPRT status value.
85 * @returns VERR_NOT_IMPLEMENTED if the host does not support the command.
86 * @returns VERR_NO_MEMORY if a heap allocation fails.
87 * @param pCtx the context of the guest heap to use.
88 * @param fCaps the capabilities to report, see VBVACAPS.
89 */
90DECLHIDDEN(int) VBoxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t fCaps)
91{
92
93 /* Allocate the IO buffer. */
94 VBVACAPS RT_UNTRUSTED_VOLATILE_HOST *p =
95 (VBVACAPS RT_UNTRUSTED_VOLATILE_HOST *)VBoxHGSMIBufferAlloc(pCtx, sizeof(*p), HGSMI_CH_VBVA, VBVA_INFO_CAPS);
96
97 if (!p)
98 return VERR_NO_MEMORY;
99
100 /* Prepare data to be sent to the host. */
101 p->rc = VERR_NOT_IMPLEMENTED;
102 p->fCaps = fCaps;
103 /* No need to check that the buffer is valid as we have just allocated it. */
104 VBoxHGSMIBufferSubmit(pCtx, p);
105
106 AssertRC(p->rc);
107 /* Free the IO buffer. */
108 VBoxHGSMIBufferFree(pCtx, p);
109 return p->rc;
110}
111
112
113/**
114 * Get the information needed to map the basic communication structures in
115 * device memory into our address space. All pointer parameters are optional.
116 *
117 * @param cbVRAM how much video RAM is allocated to the device
118 * @param poffVRAMBaseMapping where to save the offset from the start of the
119 * device VRAM of the whole area to map
120 * @param pcbMapping where to save the mapping size
121 * @param poffGuestHeapMemory where to save the offset into the mapped area
122 * of the guest heap backing memory
123 * @param pcbGuestHeapMemory where to save the size of the guest heap
124 * backing memory
125 * @param poffHostFlags where to save the offset into the mapped area
126 * of the host flags
127 */
128DECLHIDDEN(void) VBoxHGSMIGetBaseMappingInfo(uint32_t cbVRAM,
129 uint32_t *poffVRAMBaseMapping,
130 uint32_t *pcbMapping,
131 uint32_t *poffGuestHeapMemory,
132 uint32_t *pcbGuestHeapMemory,
133 uint32_t *poffHostFlags)
134{
135 AssertPtrNullReturnVoid(poffVRAMBaseMapping);
136 AssertPtrNullReturnVoid(pcbMapping);
137 AssertPtrNullReturnVoid(poffGuestHeapMemory);
138 AssertPtrNullReturnVoid(pcbGuestHeapMemory);
139 AssertPtrNullReturnVoid(poffHostFlags);
140 if (poffVRAMBaseMapping)
141 *poffVRAMBaseMapping = cbVRAM - VBVA_ADAPTER_INFORMATION_SIZE;
142 if (pcbMapping)
143 *pcbMapping = VBVA_ADAPTER_INFORMATION_SIZE;
144 if (poffGuestHeapMemory)
145 *poffGuestHeapMemory = 0;
146 if (pcbGuestHeapMemory)
147 *pcbGuestHeapMemory = VBVA_ADAPTER_INFORMATION_SIZE
148 - sizeof(HGSMIHOSTFLAGS);
149 if (poffHostFlags)
150 *poffHostFlags = VBVA_ADAPTER_INFORMATION_SIZE
151 - sizeof(HGSMIHOSTFLAGS);
152}
153
154/**
155 * Query the host for an HGSMI configuration parameter via an HGSMI command.
156 * @returns iprt status value
157 * @param pCtx the context containing the heap used
158 * @param u32Index the index of the parameter to query,
159 * @see VBVACONF32::u32Index
160 * @param pulValue where to store the value of the parameter on success
161 */
162DECLHIDDEN(int) VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t u32Index, uint32_t *pulValue)
163{
164 VBVACONF32 *p;
165
166 /* Allocate the IO buffer. */
167 p = (VBVACONF32 *)VBoxHGSMIBufferAlloc(pCtx, sizeof(*p), HGSMI_CH_VBVA, VBVA_QUERY_CONF32);
168 if (!p)
169 return VERR_NO_MEMORY;
170
171 /* Prepare data to be sent to the host. */
172 p->u32Index = u32Index;
173 p->u32Value = UINT32_MAX;
174 /* No need to check that the buffer is valid as we have just allocated it. */
175 VBoxHGSMIBufferSubmit(pCtx, p);
176 *pulValue = p->u32Value;
177 /* Free the IO buffer. */
178 VBoxHGSMIBufferFree(pCtx, p);
179 return VINF_SUCCESS;
180}
181
182/**
183 * Pass the host a new mouse pointer shape via an HGSMI command.
184 *
185 * @returns success or failure
186 * @param pCtx the context containing the heap to be used
187 * @param fFlags cursor flags, @see VMMDevReqMousePointer::fFlags
188 * @param cHotX horizontal position of the hot spot
189 * @param cHotY vertical position of the hot spot
190 * @param cWidth width in pixels of the cursor
191 * @param cHeight height in pixels of the cursor
192 * @param pPixels pixel data, @see VMMDevReqMousePointer for the format
193 * @param cbLength size in bytes of the pixel data
194 */
195DECLHIDDEN(int) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t fFlags,
196 uint32_t cHotX, uint32_t cHotY, uint32_t cWidth, uint32_t cHeight,
197 uint8_t *pPixels, uint32_t cbLength)
198{
199 VBVAMOUSEPOINTERSHAPE *p;
200 uint32_t cbPixels = 0;
201 int rc;
202
203 if (fFlags & VBOX_MOUSE_POINTER_SHAPE)
204 {
205 /*
206 * Size of the pointer data:
207 * sizeof (AND mask) + sizeof (XOR_MASK)
208 */
209 cbPixels = ((((cWidth + 7) / 8) * cHeight + 3) & ~3)
210 + cWidth * 4 * cHeight;
211 if (cbPixels > cbLength)
212 return VERR_INVALID_PARAMETER;
213 /*
214 * If shape is supplied, then always create the pointer visible.
215 * See comments in 'vboxUpdatePointerShape'
216 */
217 fFlags |= VBOX_MOUSE_POINTER_VISIBLE;
218 }
219 /* Allocate the IO buffer. */
220 p = (VBVAMOUSEPOINTERSHAPE *)VBoxHGSMIBufferAlloc(pCtx, sizeof(*p) + cbPixels, HGSMI_CH_VBVA,
221 VBVA_MOUSE_POINTER_SHAPE);
222 if (!p)
223 return VERR_NO_MEMORY;
224 /* Prepare data to be sent to the host. */
225 /* Will be updated by the host. */
226 p->i32Result = VINF_SUCCESS;
227 /* We have our custom flags in the field */
228 p->fu32Flags = fFlags;
229 p->u32HotX = cHotX;
230 p->u32HotY = cHotY;
231 p->u32Width = cWidth;
232 p->u32Height = cHeight;
233 if (cbPixels)
234 /* Copy the actual pointer data. */
235 memcpy (p->au8Data, pPixels, cbPixels);
236 /* No need to check that the buffer is valid as we have just allocated it. */
237 VBoxHGSMIBufferSubmit(pCtx, p);
238 rc = p->i32Result;
239 /* Free the IO buffer. */
240 VBoxHGSMIBufferFree(pCtx, p);
241 return rc;
242}
243
244
245/**
246 * Report the guest cursor position. The host may wish to use this information
247 * to re-position its own cursor (though this is currently unlikely). The
248 * current host cursor position is returned.
249 * @param pCtx The context containing the heap used.
250 * @param fReportPosition Are we reporting a position?
251 * @param x Guest cursor X position.
252 * @param y Guest cursor Y position.
253 * @param pxHost Host cursor X position is stored here. Optional.
254 * @param pyHost Host cursor Y position is stored here. Optional.
255 * @returns iprt status code.
256 * @returns VERR_NO_MEMORY HGSMI heap allocation failed.
257 */
258DECLHIDDEN(int) VBoxHGSMICursorPosition(PHGSMIGUESTCOMMANDCONTEXT pCtx, bool fReportPosition,
259 uint32_t x, uint32_t y, uint32_t *pxHost, uint32_t *pyHost)
260{
261 VBVACURSORPOSITION *p;
262
263 /* Allocate the IO buffer. */
264 p = (VBVACURSORPOSITION *)VBoxHGSMIBufferAlloc(pCtx, sizeof(*p), HGSMI_CH_VBVA,
265 VBVA_CURSOR_POSITION);
266 if (!p)
267 return VERR_NO_MEMORY;
268 /* Prepare data to be sent to the host. */
269 p->fReportPosition = fReportPosition;
270 p->x = x;
271 p->y = y;
272 /* No need to check that the buffer is valid as we have just allocated it. */
273 VBoxHGSMIBufferSubmit(pCtx, p);
274 if (pxHost)
275 *pxHost = p->x;
276 if (pyHost)
277 *pyHost = p->y;
278 /* Free the IO buffer. */
279 VBoxHGSMIBufferFree(pCtx, p);
280 return VINF_SUCCESS;
281}
282
283
284/**
285 * @todo Mouse pointer position to be read from VMMDev memory, address of the
286 * memory region can be queried from VMMDev via an IOCTL. This VMMDev memory
287 * region will contain host information which is needed by the guest.
288 *
289 * Reading will not cause a switch to the host.
290 *
291 * Have to take into account:
292 * * synchronization: host must write to the memory only from EMT,
293 * large structures must be read under flag, which tells the host
294 * that the guest is currently reading the memory (OWNER flag?).
295 * * guest writes: may be allocate a page for the host info and make
296 * the page readonly for the guest.
297 * * the information should be available only for additions drivers.
298 * * VMMDev additions driver will inform the host which version of the info
299 * it expects, host must support all versions.
300 */
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use