1 /* $Id: HGSMIBase.cpp $ */
3 * VirtualBox Video driver, common code - HGSMI initialisation and helper
8 * Copyright (C) 2006-2016 Oracle Corporation
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
19 #include <VBox/VBoxVideoGuest.h>
20 #include <VBox/VBoxVideo.h>
21 #include <VBox/VBoxGuest.h>
22 #include <VBox/Hardware/VBoxVideoVBE.h>
23 #include <VBox/VMMDev.h>
27 #include <iprt/string.h>
29 /** Send completion notification to the host for the command located at offset
30 * @a offt into the host command buffer. */
31 static void HGSMINotifyHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx
, HGSMIOFFSET offt
)
33 VBoxVideoCmnPortWriteUlong(pCtx
->port
, offt
);
38 * Inform the host that a command has been handled.
40 * @param pCtx the context containing the heap to be used
41 * @param pvMem pointer into the heap as mapped in @a pCtx to the command to
44 DECLHIDDEN(void) VBoxHGSMIHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx
,
47 HGSMIBUFFERHEADER
*pHdr
= HGSMIBufferHeaderFromData(pvMem
);
48 HGSMIOFFSET offMem
= HGSMIPointerToOffset(&pCtx
->areaCtx
, pHdr
);
49 Assert(offMem
!= HGSMIOFFSET_VOID
);
50 if(offMem
!= HGSMIOFFSET_VOID
)
52 HGSMINotifyHostCmdComplete(pCtx
, offMem
);
57 /** Submit an incoming host command to the appropriate handler. */
58 static void hgsmiHostCmdProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx
,
59 HGSMIOFFSET offBuffer
)
61 int rc
= HGSMIBufferProcess(&pCtx
->areaCtx
, &pCtx
->channels
, offBuffer
);
62 Assert(!RT_FAILURE(rc
));
65 /* failure means the command was not submitted to the handler for some reason
66 * it's our responsibility to notify its completion in this case */
67 HGSMINotifyHostCmdComplete(pCtx
, offBuffer
);
69 /* if the cmd succeeded it's responsibility of the callback to complete it */
72 /** Get the next command from the host. */
73 static HGSMIOFFSET
hgsmiGetHostBuffer(PHGSMIHOSTCOMMANDCONTEXT pCtx
)
75 return VBoxVideoCmnPortReadUlong(pCtx
->port
);
79 /** Get and handle the next command from the host. */
80 static void hgsmiHostCommandQueryProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx
)
82 HGSMIOFFSET offset
= hgsmiGetHostBuffer(pCtx
);
83 AssertReturnVoid(offset
!= HGSMIOFFSET_VOID
);
84 hgsmiHostCmdProcess(pCtx
, offset
);
88 /** Drain the host command queue. */
89 DECLHIDDEN(void) VBoxHGSMIProcessHostQueue(PHGSMIHOSTCOMMANDCONTEXT pCtx
)
91 while (pCtx
->pfHostFlags
->u32HostFlags
& HGSMIHOSTFLAGS_COMMANDS_PENDING
)
93 if (!ASMAtomicCmpXchgBool(&pCtx
->fHostCmdProcessing
, true, false))
95 hgsmiHostCommandQueryProcess(pCtx
);
96 ASMAtomicWriteBool(&pCtx
->fHostCmdProcessing
, false);
101 /** Detect whether HGSMI is supported by the host. */
102 DECLHIDDEN(bool) VBoxHGSMIIsSupported(void)
106 VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX
, VBE_DISPI_INDEX_ID
);
107 VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA
, VBE_DISPI_ID_HGSMI
);
109 DispiId
= VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA
);
111 return (DispiId
== VBE_DISPI_ID_HGSMI
);
116 * Allocate and initialise a command descriptor in the guest heap for a
117 * guest-to-host command.
119 * @returns pointer to the descriptor's command data buffer
120 * @param pCtx the context containing the heap to be used
121 * @param cbData the size of the command data to go into the descriptor
122 * @param u8Ch the HGSMI channel to be used, set to the descriptor
123 * @param u16Op the HGSMI command to be sent, set to the descriptor
125 DECLHIDDEN(void *) VBoxHGSMIBufferAlloc(PHGSMIGUESTCOMMANDCONTEXT pCtx
,
130 #ifdef VBOX_WDDM_MINIPORT
131 return VBoxSHGSMIHeapAlloc (&pCtx
->heapCtx
, cbData
, u8Ch
, u16Op
);
133 return HGSMIHeapAlloc (&pCtx
->heapCtx
, cbData
, u8Ch
, u16Op
);
139 * Free a descriptor allocated by @a VBoxHGSMIBufferAlloc.
141 * @param pCtx the context containing the heap used
142 * @param pvBuffer the pointer returned by @a VBoxHGSMIBufferAlloc
144 DECLHIDDEN(void) VBoxHGSMIBufferFree(PHGSMIGUESTCOMMANDCONTEXT pCtx
,
147 #ifdef VBOX_WDDM_MINIPORT
148 VBoxSHGSMIHeapFree (&pCtx
->heapCtx
, pvBuffer
);
150 HGSMIHeapFree (&pCtx
->heapCtx
, pvBuffer
);
156 * Submit a command descriptor allocated by @a VBoxHGSMIBufferAlloc.
158 * @param pCtx the context containing the heap used
159 * @param pvBuffer the pointer returned by @a VBoxHGSMIBufferAlloc
161 DECLHIDDEN(int) VBoxHGSMIBufferSubmit(PHGSMIGUESTCOMMANDCONTEXT pCtx
,
164 /* Initialize the buffer and get the offset for port IO. */
165 HGSMIOFFSET offBuffer
= HGSMIHeapBufferOffset (HGSMIGUESTCMDHEAP_GET(&pCtx
->heapCtx
), pvBuffer
);
167 Assert(offBuffer
!= HGSMIOFFSET_VOID
);
168 if (offBuffer
!= HGSMIOFFSET_VOID
)
170 /* Submit the buffer to the host. */
171 VBoxVideoCmnPortWriteUlong(pCtx
->port
, offBuffer
);
172 /* Make the compiler aware that the host has changed memory. */
173 ASMCompilerBarrier();
177 return VERR_INVALID_PARAMETER
;
181 /** Inform the host of the location of the host flags in VRAM via an HGSMI
183 static int vboxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx
,
184 HGSMIOFFSET offLocation
)
186 HGSMIBUFFERLOCATION
*p
;
187 int rc
= VINF_SUCCESS
;
189 /* Allocate the IO buffer. */
190 p
= (HGSMIBUFFERLOCATION
*)VBoxHGSMIBufferAlloc(pCtx
,
191 sizeof(HGSMIBUFFERLOCATION
),
193 HGSMI_CC_HOST_FLAGS_LOCATION
);
196 /* Prepare data to be sent to the host. */
197 p
->offLocation
= offLocation
;
198 p
->cbLocation
= sizeof(HGSMIHOSTFLAGS
);
199 rc
= VBoxHGSMIBufferSubmit(pCtx
, p
);
200 /* Free the IO buffer. */
201 VBoxHGSMIBufferFree(pCtx
, p
);
210 * Inform the host of the location of the host flags in VRAM via an HGSMI
212 * @returns IPRT status value.
213 * @returns VERR_NOT_IMPLEMENTED if the host does not support the command.
214 * @returns VERR_NO_MEMORY if a heap allocation fails.
215 * @param pCtx the context of the guest heap to use.
216 * @param offLocation the offset chosen for the flags withing guest
219 DECLHIDDEN(int) VBoxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx
,
220 HGSMIOFFSET offLocation
)
222 return vboxHGSMIReportFlagsLocation(pCtx
, offLocation
);
226 /** Notify the host of HGSMI-related guest capabilities via an HGSMI command.
228 static int vboxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx
,
232 int rc
= VINF_SUCCESS
;
234 /* Allocate the IO buffer. */
235 pCaps
= (VBVACAPS
*)VBoxHGSMIBufferAlloc(pCtx
,
236 sizeof(VBVACAPS
), HGSMI_CH_VBVA
,
241 /* Prepare data to be sent to the host. */
242 pCaps
->rc
= VERR_NOT_IMPLEMENTED
;
243 pCaps
->fCaps
= fCaps
;
244 rc
= VBoxHGSMIBufferSubmit(pCtx
, pCaps
);
250 /* Free the IO buffer. */
251 VBoxHGSMIBufferFree(pCtx
, pCaps
);
260 * Notify the host of HGSMI-related guest capabilities via an HGSMI command.
261 * @returns IPRT status value.
262 * @returns VERR_NOT_IMPLEMENTED if the host does not support the command.
263 * @returns VERR_NO_MEMORY if a heap allocation fails.
264 * @param pCtx the context of the guest heap to use.
265 * @param fCaps the capabilities to report, see VBVACAPS.
267 DECLHIDDEN(int) VBoxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx
,
270 return vboxHGSMISendCapsInfo(pCtx
, fCaps
);
274 /** Tell the host about the location of the area of VRAM set aside for the host
276 static int vboxHGSMIReportHostArea(PHGSMIGUESTCOMMANDCONTEXT pCtx
,
277 uint32_t u32AreaOffset
, uint32_t u32AreaSize
)
280 int rc
= VINF_SUCCESS
;
282 /* Allocate the IO buffer. */
283 p
= (VBVAINFOHEAP
*)VBoxHGSMIBufferAlloc(pCtx
,
284 sizeof (VBVAINFOHEAP
), HGSMI_CH_VBVA
,
288 /* Prepare data to be sent to the host. */
289 p
->u32HeapOffset
= u32AreaOffset
;
290 p
->u32HeapSize
= u32AreaSize
;
291 rc
= VBoxHGSMIBufferSubmit(pCtx
, p
);
292 /* Free the IO buffer. */
293 VBoxHGSMIBufferFree(pCtx
, p
);
302 * Get the information needed to map the basic communication structures in
303 * device memory into our address space. All pointer parameters are optional.
305 * @param cbVRAM how much video RAM is allocated to the device
306 * @param poffVRAMBaseMapping where to save the offset from the start of the
307 * device VRAM of the whole area to map
308 * @param pcbMapping where to save the mapping size
309 * @param poffGuestHeapMemory where to save the offset into the mapped area
310 * of the guest heap backing memory
311 * @param pcbGuestHeapMemory where to save the size of the guest heap
313 * @param poffHostFlags where to save the offset into the mapped area
316 DECLHIDDEN(void) VBoxHGSMIGetBaseMappingInfo(uint32_t cbVRAM
,
317 uint32_t *poffVRAMBaseMapping
,
318 uint32_t *pcbMapping
,
319 uint32_t *poffGuestHeapMemory
,
320 uint32_t *pcbGuestHeapMemory
,
321 uint32_t *poffHostFlags
)
323 AssertPtrNullReturnVoid(poffVRAMBaseMapping
);
324 AssertPtrNullReturnVoid(pcbMapping
);
325 AssertPtrNullReturnVoid(poffGuestHeapMemory
);
326 AssertPtrNullReturnVoid(pcbGuestHeapMemory
);
327 AssertPtrNullReturnVoid(poffHostFlags
);
328 if (poffVRAMBaseMapping
)
329 *poffVRAMBaseMapping
= cbVRAM
- VBVA_ADAPTER_INFORMATION_SIZE
;
331 *pcbMapping
= VBVA_ADAPTER_INFORMATION_SIZE
;
332 if (poffGuestHeapMemory
)
333 *poffGuestHeapMemory
= 0;
334 if (pcbGuestHeapMemory
)
335 *pcbGuestHeapMemory
= VBVA_ADAPTER_INFORMATION_SIZE
336 - sizeof(HGSMIHOSTFLAGS
);
338 *poffHostFlags
= VBVA_ADAPTER_INFORMATION_SIZE
339 - sizeof(HGSMIHOSTFLAGS
);
344 * Set up the HGSMI guest-to-host command context.
345 * @returns iprt status value
346 * @param pCtx the context to set up
347 * @param pvGuestHeapMemory a pointer to the mapped backing memory for
349 * @param cbGuestHeapMemory the size of the backing memory area
350 * @param offVRAMGuestHeapMemory the offset of the memory pointed to by
351 * @a pvGuestHeapMemory within the video RAM
353 DECLHIDDEN(int) VBoxHGSMISetupGuestContext(PHGSMIGUESTCOMMANDCONTEXT pCtx
,
354 void *pvGuestHeapMemory
,
355 uint32_t cbGuestHeapMemory
,
356 uint32_t offVRAMGuestHeapMemory
,
357 const HGSMIENV
*pEnv
)
359 /** @todo should we be using a fixed ISA port value here? */
360 pCtx
->port
= (RTIOPORT
)VGA_PORT_HGSMI_GUEST
;
361 #ifdef VBOX_WDDM_MINIPORT
362 return VBoxSHGSMIInit(&pCtx
->heapCtx
, pvGuestHeapMemory
,
363 cbGuestHeapMemory
, offVRAMGuestHeapMemory
, pEnv
);
365 return HGSMIHeapSetup(&pCtx
->heapCtx
, pvGuestHeapMemory
,
366 cbGuestHeapMemory
, offVRAMGuestHeapMemory
, pEnv
);
372 * Get the information needed to map the area used by the host to send back
375 * @param pCtx the context containing the heap to use
376 * @param cbVRAM how much video RAM is allocated to the device
377 * @param offVRAMBaseMapping the offset of the basic communication structures
378 * into the guest's VRAM
379 * @param poffVRAMHostArea where to store the offset into VRAM of the host
381 * @param pcbHostArea where to store the size of the host heap area
383 DECLHIDDEN(void) VBoxHGSMIGetHostAreaMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx
,
385 uint32_t offVRAMBaseMapping
,
386 uint32_t *poffVRAMHostArea
,
387 uint32_t *pcbHostArea
)
389 uint32_t offVRAMHostArea
= offVRAMBaseMapping
, cbHostArea
= 0;
391 AssertPtrReturnVoid(poffVRAMHostArea
);
392 AssertPtrReturnVoid(pcbHostArea
);
393 VBoxQueryConfHGSMI(pCtx
, VBOX_VBVA_CONF32_HOST_HEAP_SIZE
, &cbHostArea
);
396 uint32_t cbHostAreaMaxSize
= cbVRAM
/ 4;
397 /** @todo what is the idea of this? */
398 if (cbHostAreaMaxSize
>= VBVA_ADAPTER_INFORMATION_SIZE
)
400 cbHostAreaMaxSize
-= VBVA_ADAPTER_INFORMATION_SIZE
;
402 if (cbHostArea
> cbHostAreaMaxSize
)
404 cbHostArea
= cbHostAreaMaxSize
;
406 /* Round up to 4096 bytes. */
407 cbHostArea
= (cbHostArea
+ 0xFFF) & ~0xFFF;
408 offVRAMHostArea
= offVRAMBaseMapping
- cbHostArea
;
411 *pcbHostArea
= cbHostArea
;
412 *poffVRAMHostArea
= offVRAMHostArea
;
413 LogFunc(("offVRAMHostArea = 0x%08X, cbHostArea = 0x%08X\n",
414 offVRAMHostArea
, cbHostArea
));
419 * Initialise the host context structure.
421 * @param pCtx the context structure to initialise
422 * @param pvBaseMapping where the basic HGSMI structures are mapped at
423 * @param offHostFlags the offset of the host flags into the basic HGSMI
425 * @param pvHostAreaMapping where the area for the host heap is mapped at
426 * @param offVRAMHostArea offset of the host heap area into VRAM
427 * @param cbHostArea size in bytes of the host heap area
429 DECLHIDDEN(void) VBoxHGSMISetupHostContext(PHGSMIHOSTCOMMANDCONTEXT pCtx
,
431 uint32_t offHostFlags
,
432 void *pvHostAreaMapping
,
433 uint32_t offVRAMHostArea
,
436 uint8_t *pu8HostFlags
= ((uint8_t *)pvBaseMapping
) + offHostFlags
;
437 pCtx
->pfHostFlags
= (HGSMIHOSTFLAGS
*)pu8HostFlags
;
438 /** @todo should we really be using a fixed ISA port value here? */
439 pCtx
->port
= (RTIOPORT
)VGA_PORT_HGSMI_HOST
;
440 HGSMIAreaInitialize(&pCtx
->areaCtx
, pvHostAreaMapping
, cbHostArea
,
446 * Tell the host about the ways it can use to communicate back to us via an
449 * @returns iprt status value
450 * @param pCtx the context containing the heap to use
451 * @param offVRAMFlagsLocation where we wish the host to place its flags
452 * relative to the start of the VRAM
453 * @param fCaps additions HGSMI capabilities the guest
455 * @param offVRAMHostArea offset into VRAM of the host heap area
456 * @param cbHostArea size in bytes of the host heap area
458 DECLHIDDEN(int) VBoxHGSMISendHostCtxInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx
,
459 HGSMIOFFSET offVRAMFlagsLocation
,
461 uint32_t offVRAMHostArea
,
464 Log(("VBoxVideo::vboxSetupAdapterInfo\n"));
466 /* setup the flags first to ensure they are initialized by the time the
467 * host heap is ready */
468 int rc
= vboxHGSMIReportFlagsLocation(pCtx
, offVRAMFlagsLocation
);
470 if (RT_SUCCESS(rc
) && fCaps
)
472 /* Inform about caps */
473 rc
= vboxHGSMISendCapsInfo(pCtx
, fCaps
);
478 /* Report the host heap location. */
479 rc
= vboxHGSMIReportHostArea(pCtx
, offVRAMHostArea
, cbHostArea
);
482 Log(("VBoxVideo::vboxSetupAdapterInfo finished rc = %d\n", rc
));
487 /** Sanity test on first call. We do not worry about concurrency issues. */
488 static int testQueryConf(PHGSMIGUESTCOMMANDCONTEXT pCtx
)
490 static bool cOnce
= false;
491 uint32_t ulValue
= 0;
497 rc
= VBoxQueryConfHGSMI(pCtx
, UINT32_MAX
, &ulValue
);
498 if (RT_SUCCESS(rc
) && ulValue
== UINT32_MAX
)
503 return VERR_INTERNAL_ERROR
;
508 * Query the host for an HGSMI configuration parameter via an HGSMI command.
509 * @returns iprt status value
510 * @param pCtx the context containing the heap used
511 * @param u32Index the index of the parameter to query,
512 * @see VBVACONF32::u32Index
513 * @param u32DefValue defaut value
514 * @param pulValue where to store the value of the parameter on success
516 DECLHIDDEN(int) VBoxQueryConfHGSMIDef(PHGSMIGUESTCOMMANDCONTEXT pCtx
,
517 uint32_t u32Index
, uint32_t u32DefValue
, uint32_t *pulValue
)
519 int rc
= VINF_SUCCESS
;
521 LogFunc(("u32Index = %d\n", u32Index
));
523 rc
= testQueryConf(pCtx
);
526 /* Allocate the IO buffer. */
527 p
= (VBVACONF32
*)VBoxHGSMIBufferAlloc(pCtx
,
528 sizeof(VBVACONF32
), HGSMI_CH_VBVA
,
532 /* Prepare data to be sent to the host. */
533 p
->u32Index
= u32Index
;
534 p
->u32Value
= u32DefValue
;
535 rc
= VBoxHGSMIBufferSubmit(pCtx
, p
);
538 *pulValue
= p
->u32Value
;
539 LogFunc(("u32Value = %d\n", p
->u32Value
));
541 /* Free the IO buffer. */
542 VBoxHGSMIBufferFree(pCtx
, p
);
546 LogFunc(("rc = %d\n", rc
));
550 DECLHIDDEN(int) VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx
,
551 uint32_t u32Index
, uint32_t *pulValue
)
553 return VBoxQueryConfHGSMIDef(pCtx
, u32Index
, UINT32_MAX
, pulValue
);
557 * Pass the host a new mouse pointer shape via an HGSMI command.
559 * @returns success or failure
560 * @param fFlags cursor flags, @see VMMDevReqMousePointer::fFlags
561 * @param cHotX horizontal position of the hot spot
562 * @param cHotY vertical position of the hot spot
563 * @param cWidth width in pixels of the cursor
564 * @param cHeight height in pixels of the cursor
565 * @param pPixels pixel data, @see VMMDevReqMousePointer for the format
566 * @param cbLength size in bytes of the pixel data
568 DECLHIDDEN(int) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx
,
577 VBVAMOUSEPOINTERSHAPE
*p
;
579 int rc
= VINF_SUCCESS
;
581 if (fFlags
& VBOX_MOUSE_POINTER_SHAPE
)
583 /* Size of the pointer data: sizeof (AND mask) + sizeof (XOR_MASK) */
584 cbData
= ((((cWidth
+ 7) / 8) * cHeight
+ 3) & ~3)
585 + cWidth
* 4 * cHeight
;
586 /* If shape is supplied, then always create the pointer visible.
587 * See comments in 'vboxUpdatePointerShape'
589 fFlags
|= VBOX_MOUSE_POINTER_VISIBLE
;
591 LogFlowFunc(("cbData %d, %dx%d\n", cbData
, cWidth
, cHeight
));
592 if (cbData
> cbLength
)
594 LogFunc(("calculated pointer data size is too big (%d bytes, limit %d)\n",
596 return VERR_INVALID_PARAMETER
;
598 /* Allocate the IO buffer. */
599 p
= (VBVAMOUSEPOINTERSHAPE
*)VBoxHGSMIBufferAlloc(pCtx
,
600 sizeof(VBVAMOUSEPOINTERSHAPE
)
603 VBVA_MOUSE_POINTER_SHAPE
);
606 /* Prepare data to be sent to the host. */
607 /* Will be updated by the host. */
608 p
->i32Result
= VINF_SUCCESS
;
609 /* We have our custom flags in the field */
610 p
->fu32Flags
= fFlags
;
613 p
->u32Width
= cWidth
;
614 p
->u32Height
= cHeight
;
615 if (p
->fu32Flags
& VBOX_MOUSE_POINTER_SHAPE
)
616 /* Copy the actual pointer data. */
617 memcpy (p
->au8Data
, pPixels
, cbData
);
618 rc
= VBoxHGSMIBufferSubmit(pCtx
, p
);
621 /* Free the IO buffer. */
622 VBoxHGSMIBufferFree(pCtx
, p
);
626 LogFlowFunc(("rc %d\n", rc
));
632 * Report the guest cursor position. The host may wish to use this information
633 * to re-position its own cursor (though this is currently unlikely). The
634 * current host cursor position is returned.
635 * @param pCtx The context containing the heap used.
636 * @param fReportPosition Are we reporting a position?
637 * @param x Guest cursor X position.
638 * @param y Guest cursor Y position.
639 * @param pxHost Host cursor X position is stored here. Optional.
640 * @param pyHost Host cursor Y position is stored here. Optional.
641 * @returns iprt status code.
642 * @returns VERR_NO_MEMORY HGSMI heap allocation failed.
644 DECLHIDDEN(int) VBoxHGSMICursorPosition(PHGSMIGUESTCOMMANDCONTEXT pCtx
, bool fReportPosition
, uint32_t x
, uint32_t y
,
645 uint32_t *pxHost
, uint32_t *pyHost
)
647 int rc
= VINF_SUCCESS
;
648 VBVACURSORPOSITION
*p
;
649 Log(("%s: x=%u, y=%u\n", __PRETTY_FUNCTION__
, (unsigned)x
, (unsigned)y
));
651 /* Allocate the IO buffer. */
652 p
= (VBVACURSORPOSITION
*)VBoxHGSMIBufferAlloc(pCtx
, sizeof(VBVACURSORPOSITION
), HGSMI_CH_VBVA
, VBVA_CURSOR_POSITION
);
655 /* Prepare data to be sent to the host. */
656 p
->fReportPosition
= fReportPosition
? 1 : 0;
659 rc
= VBoxHGSMIBufferSubmit(pCtx
, p
);
666 Log(("%s: return: x=%u, y=%u\n", __PRETTY_FUNCTION__
, (unsigned)p
->x
, (unsigned)p
->y
));
668 /* Free the IO buffer. */
669 VBoxHGSMIBufferFree(pCtx
, p
);
673 LogFunc(("rc = %d\n", rc
));
678 /** @todo Mouse pointer position to be read from VMMDev memory, address of the memory region
679 * can be queried from VMMDev via an IOCTL. This VMMDev memory region will contain
680 * host information which is needed by the guest.
682 * Reading will not cause a switch to the host.
684 * Have to take into account:
685 * * synchronization: host must write to the memory only from EMT,
686 * large structures must be read under flag, which tells the host
687 * that the guest is currently reading the memory (OWNER flag?).
688 * * guest writes: may be allocate a page for the host info and make
689 * the page readonly for the guest.
690 * * the information should be available only for additions drivers.
691 * * VMMDev additions driver will inform the host which version of the info it expects,
692 * host must support all versions.