HGSMIBase.cpp revision c87c6e10b608762972b76bfc734daaec9070b50b
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * VirtualBox Video driver, common code - HGSMI initialisation and helper
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * functions.
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * Copyright (C) 2006-2012 Oracle Corporation
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * available from http://www.virtualbox.org. This file is free software;
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * you can redistribute it and/or modify it under the terms of the GNU
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * General Public License (GPL) as published by the Free Software
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync/** Send completion notification to the host for the command located at offset
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @a offt into the host command buffer. */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncstatic void HGSMINotifyHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx, HGSMIOFFSET offt)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * Inform the host that a command has been handled.
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @param pCtx the context containing the heap to be used
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @param pvMem pointer into the heap as mapped in @a pCtx to the command to
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * be completed
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncRTDECL(void) VBoxHGSMIHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx,
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync HGSMIBUFFERHEADER *pHdr = HGSMIBufferHeaderFromData(pvMem);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync HGSMIOFFSET offMem = HGSMIPointerToOffset(&pCtx->areaCtx, pHdr);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync/** Submit an incoming host command to the appropriate handler. */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncstatic void hgsmiHostCmdProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx,
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync int rc = HGSMIBufferProcess(&pCtx->areaCtx, &pCtx->channels, offBuffer);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* failure means the command was not submitted to the handler for some reason
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * it's our responsibility to notify its completion in this case */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* if the cmd succeeded it's responsibility of the callback to complete it */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync/** Get the next command from the host. */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncstatic HGSMIOFFSET hgsmiGetHostBuffer(PHGSMIHOSTCOMMANDCONTEXT pCtx)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync/** Get and handle the next command from the host. */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncstatic void hgsmiHostCommandQueryProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync/** Drain the host command queue. */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncRTDECL(void) VBoxHGSMIProcessHostQueue(PHGSMIHOSTCOMMANDCONTEXT pCtx)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync while (pCtx->pfHostFlags->u32HostFlags & HGSMIHOSTFLAGS_COMMANDS_PENDING)
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync if (!ASMAtomicCmpXchgBool(&pCtx->fHostCmdProcessing, true, false))
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync ASMAtomicWriteBool(&pCtx->fHostCmdProcessing, false);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync/** Detect whether HGSMI is supported by the host. */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_HGSMI);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync DispiId = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * Allocate and initialise a command descriptor in the guest heap for a
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * guest-to-host command.
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @returns pointer to the descriptor's command data buffer
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @param pCtx the context containing the heap to be used
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @param cbData the size of the command data to go into the descriptor
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @param u8Ch the HGSMI channel to be used, set to the descriptor
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @param u16Op the HGSMI command to be sent, set to the descriptor
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncRTDECL(void *) VBoxHGSMIBufferAlloc(PHGSMIGUESTCOMMANDCONTEXT pCtx,
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync return VBoxSHGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync return HGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * Free a descriptor allocated by @a VBoxHGSMIBufferAlloc.
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @param pCtx the context containing the heap used
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @param pvBuffer the pointer returned by @a VBoxHGSMIBufferAlloc
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncRTDECL(void) VBoxHGSMIBufferFree(PHGSMIGUESTCOMMANDCONTEXT pCtx,
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * Submit a command descriptor allocated by @a VBoxHGSMIBufferAlloc.
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @param pCtx the context containing the heap used
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @param pvBuffer the pointer returned by @a VBoxHGSMIBufferAlloc
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncRTDECL(int) VBoxHGSMIBufferSubmit(PHGSMIGUESTCOMMANDCONTEXT pCtx,
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* Initialize the buffer and get the offset for port IO. */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (HGSMIGUESTCMDHEAP_GET(&pCtx->heapCtx), pvBuffer);
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* Submit the buffer to the host. */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync/** Inform the host of the location of the host flags in VRAM via an HGSMI
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * command. */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncstatic int vboxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx,
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* Allocate the IO buffer. */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync p = (HGSMIBUFFERLOCATION *)VBoxHGSMIBufferAlloc(pCtx,
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* Prepare data to be sent to the host. */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* Free the IO buffer. */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync/** Notify the host of HGSMI-related guest capabilities via an HGSMI command.
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncstatic int vboxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* Allocate the IO buffer. */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* Prepare data to be sent to the host. */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync /* Free the IO buffer. */
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * Notify the host of HGSMI-related guest capabilities via an HGSMI command.
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @returns IPRT status value.
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @returns VERR_NOT_IMPLEMENTED if the host does not support the command.
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @returns VERR_NO_MEMORY if a heap allocation fails.
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @param pCtx the context of the guest heap to use.
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync * @param fCaps the capabilities to report, see VBVACAPS.
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncRTDECL(int) VBoxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsync/** Tell the host about the location of the area of VRAM set aside for the host
61cb83a8ccd1dd7f671f31fa93c9d8b7be09b4ccvboxsyncstatic int vboxHGSMIReportHostArea(PHGSMIGUESTCOMMANDCONTEXT pCtx,
VBVAINFOHEAP *p;
return rc;
if (poffVRAMBaseMapping)
if (pcbMapping)
if (poffGuestHeapMemory)
*poffGuestHeapMemory = 0;
if (pcbGuestHeapMemory)
- sizeof(HGSMIHOSTFLAGS);
if (poffHostFlags)
- sizeof(HGSMIHOSTFLAGS);
void *pvGuestHeapMemory,
#ifdef VBOX_WDDM_MINIPORT
if (cbHostArea != 0)
void *pvBaseMapping,
void *pvHostAreaMapping,
return rc;
VBVACONF32 *p;
p->u32Value = 0;
return rc;
return VERR_INVALID_PARAMETER;
sizeof(VBVAMOUSEPOINTERSHAPE)
+ cbData,
return rc;
RTDECL(int) VBoxHGSMICursorPosition(PHGSMIGUESTCOMMANDCONTEXT pCtx, bool fReportPosition, uint32_t x, uint32_t y,
p = (VBVACURSORPOSITION *)VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVACURSORPOSITION), HGSMI_CH_VBVA, VBVA_CURSOR_POSITION);
if (pxHost)
*pxHost = p->x;
if (pyHost)
*pyHost = p->y;
return rc;