74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/* $Id$ */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/** @file
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * VirtualBox Video driver, common code - HGSMI initialisation and helper
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * functions.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/*
c58f1213e628a545081c70e26c6b67a841cff880vboxsync * Copyright (C) 2006-2012 Oracle Corporation
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync *
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * available from http://www.virtualbox.org. This file is free software;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * you can redistribute it and/or modify it under the terms of the GNU
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * General Public License (GPL) as published by the Free Software
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync#include <VBox/VBoxVideoGuest.h>
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync#include <VBox/VBoxVideo.h>
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync#include <VBox/VBoxGuest.h>
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync#include <VBox/Hardware/VBoxVideoVBE.h>
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync#include <VBox/VMMDev.h>
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync#include <iprt/asm.h>
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync#include <iprt/log.h>
0fc8a97f9a19a44f1ad4670454edf26d80c42281vboxsync#include <iprt/string.h>
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/** Send completion notification to the host for the command located at offset
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @a offt into the host command buffer. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncstatic void HGSMINotifyHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx, HGSMIOFFSET offt)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync VBoxVideoCmnPortWriteUlong(pCtx->port, offt);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/**
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * Inform the host that a command has been handled.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync *
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pCtx the context containing the heap to be used
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pvMem pointer into the heap as mapped in @a pCtx to the command to
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * be completed
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncRTDECL(void) VBoxHGSMIHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync void *pvMem)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync HGSMIBUFFERHEADER *pHdr = HGSMIBufferHeaderFromData(pvMem);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync HGSMIOFFSET offMem = HGSMIPointerToOffset(&pCtx->areaCtx, pHdr);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync Assert(offMem != HGSMIOFFSET_VOID);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if(offMem != HGSMIOFFSET_VOID)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync {
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync HGSMINotifyHostCmdComplete(pCtx, offMem);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync }
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/** Submit an incoming host command to the appropriate handler. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncstatic void hgsmiHostCmdProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync HGSMIOFFSET offBuffer)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync int rc = HGSMIBufferProcess(&pCtx->areaCtx, &pCtx->channels, offBuffer);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync Assert(!RT_FAILURE(rc));
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if(RT_FAILURE(rc))
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync {
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* failure means the command was not submitted to the handler for some reason
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * it's our responsibility to notify its completion in this case */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync HGSMINotifyHostCmdComplete(pCtx, offBuffer);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync }
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* if the cmd succeeded it's responsibility of the callback to complete it */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/** Get the next command from the host. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncstatic HGSMIOFFSET hgsmiGetHostBuffer(PHGSMIHOSTCOMMANDCONTEXT pCtx)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync return VBoxVideoCmnPortReadUlong(pCtx->port);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/** Get and handle the next command from the host. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncstatic void hgsmiHostCommandQueryProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync HGSMIOFFSET offset = hgsmiGetHostBuffer(pCtx);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync AssertReturnVoid(offset != HGSMIOFFSET_VOID);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync hgsmiHostCmdProcess(pCtx, offset);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/** Drain the host command queue. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncRTDECL(void) VBoxHGSMIProcessHostQueue(PHGSMIHOSTCOMMANDCONTEXT pCtx)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync while (pCtx->pfHostFlags->u32HostFlags & HGSMIHOSTFLAGS_COMMANDS_PENDING)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync {
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if (!ASMAtomicCmpXchgBool(&pCtx->fHostCmdProcessing, true, false))
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync return;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync hgsmiHostCommandQueryProcess(pCtx);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync ASMAtomicWriteBool(&pCtx->fHostCmdProcessing, false);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync }
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/** Detect whether HGSMI is supported by the host. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncRTDECL(bool) VBoxHGSMIIsSupported(void)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint16_t DispiId;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync VBoxVideoCmnPortWriteUshort(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_HGSMI);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync DispiId = VBoxVideoCmnPortReadUshort(VBE_DISPI_IOPORT_DATA);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync return (DispiId == VBE_DISPI_ID_HGSMI);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/**
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * Allocate and initialise a command descriptor in the guest heap for a
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * guest-to-host command.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync *
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @returns pointer to the descriptor's command data buffer
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pCtx the context containing the heap to be used
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param cbData the size of the command data to go into the descriptor
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param u8Ch the HGSMI channel to be used, set to the descriptor
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param u16Op the HGSMI command to be sent, set to the descriptor
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncRTDECL(void *) VBoxHGSMIBufferAlloc(PHGSMIGUESTCOMMANDCONTEXT pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync HGSMISIZE cbData,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint8_t u8Ch,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint16_t u16Op)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync#ifdef VBOX_WDDM_MINIPORT
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync return VBoxSHGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync#else
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync return HGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync#endif
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/**
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * Free a descriptor allocated by @a VBoxHGSMIBufferAlloc.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync *
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pCtx the context containing the heap used
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pvBuffer the pointer returned by @a VBoxHGSMIBufferAlloc
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncRTDECL(void) VBoxHGSMIBufferFree(PHGSMIGUESTCOMMANDCONTEXT pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync void *pvBuffer)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync#ifdef VBOX_WDDM_MINIPORT
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync VBoxSHGSMIHeapFree (&pCtx->heapCtx, pvBuffer);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync#else
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync HGSMIHeapFree (&pCtx->heapCtx, pvBuffer);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync#endif
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/**
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * Submit a command descriptor allocated by @a VBoxHGSMIBufferAlloc.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync *
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pCtx the context containing the heap used
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pvBuffer the pointer returned by @a VBoxHGSMIBufferAlloc
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncRTDECL(int) VBoxHGSMIBufferSubmit(PHGSMIGUESTCOMMANDCONTEXT pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync void *pvBuffer)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Initialize the buffer and get the offset for port IO. */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (HGSMIGUESTCMDHEAP_GET(&pCtx->heapCtx), pvBuffer);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync Assert(offBuffer != HGSMIOFFSET_VOID);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if (offBuffer != HGSMIOFFSET_VOID)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync {
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Submit the buffer to the host. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync VBoxVideoCmnPortWriteUlong(pCtx->port, offBuffer);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync return VINF_SUCCESS;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync }
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync return VERR_INVALID_PARAMETER;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/** Inform the host of the location of the host flags in VRAM via an HGSMI
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * command. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncstatic int vboxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync HGSMIOFFSET offLocation)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync HGSMIBUFFERLOCATION *p;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync int rc = VINF_SUCCESS;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Allocate the IO buffer. */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync p = (HGSMIBUFFERLOCATION *)VBoxHGSMIBufferAlloc(pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync sizeof(HGSMIBUFFERLOCATION),
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync HGSMI_CH_HGSMI,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync HGSMI_CC_HOST_FLAGS_LOCATION);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if (p)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync {
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Prepare data to be sent to the host. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync p->offLocation = offLocation;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync p->cbLocation = sizeof(HGSMIHOSTFLAGS);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync rc = VBoxHGSMIBufferSubmit(pCtx, p);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Free the IO buffer. */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync VBoxHGSMIBufferFree(pCtx, p);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync }
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync else
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync rc = VERR_NO_MEMORY;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync return rc;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/** Notify the host of HGSMI-related guest capabilities via an HGSMI command.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncstatic int vboxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t fCaps)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync VBVACAPS *pCaps;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync int rc = VINF_SUCCESS;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Allocate the IO buffer. */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync pCaps = (VBVACAPS *)VBoxHGSMIBufferAlloc(pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync sizeof(VBVACAPS), HGSMI_CH_VBVA,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync VBVA_INFO_CAPS);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if (pCaps)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync {
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Prepare data to be sent to the host. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync pCaps->rc = VERR_NOT_IMPLEMENTED;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync pCaps->fCaps = fCaps;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync rc = VBoxHGSMIBufferSubmit(pCtx, pCaps);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if (RT_SUCCESS(rc))
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync {
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync AssertRC(pCaps->rc);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync rc = pCaps->rc;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync }
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Free the IO buffer. */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync VBoxHGSMIBufferFree(pCtx, pCaps);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync }
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync else
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync rc = VERR_NO_MEMORY;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync return rc;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
97803398b9554900b4dd45f88b2eb2056e2c606bvboxsync/**
97803398b9554900b4dd45f88b2eb2056e2c606bvboxsync * Notify the host of HGSMI-related guest capabilities via an HGSMI command.
97803398b9554900b4dd45f88b2eb2056e2c606bvboxsync * @returns IPRT status value.
97803398b9554900b4dd45f88b2eb2056e2c606bvboxsync * @returns VERR_NOT_IMPLEMENTED if the host does not support the command.
97803398b9554900b4dd45f88b2eb2056e2c606bvboxsync * @returns VERR_NO_MEMORY if a heap allocation fails.
97803398b9554900b4dd45f88b2eb2056e2c606bvboxsync * @param pCtx the context of the guest heap to use.
97803398b9554900b4dd45f88b2eb2056e2c606bvboxsync * @param fCaps the capabilities to report, see VBVACAPS.
97803398b9554900b4dd45f88b2eb2056e2c606bvboxsync */
97803398b9554900b4dd45f88b2eb2056e2c606bvboxsyncRTDECL(int) VBoxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
97803398b9554900b4dd45f88b2eb2056e2c606bvboxsync uint32_t fCaps)
97803398b9554900b4dd45f88b2eb2056e2c606bvboxsync{
97803398b9554900b4dd45f88b2eb2056e2c606bvboxsync return vboxHGSMISendCapsInfo(pCtx, fCaps);
97803398b9554900b4dd45f88b2eb2056e2c606bvboxsync}
97803398b9554900b4dd45f88b2eb2056e2c606bvboxsync
97803398b9554900b4dd45f88b2eb2056e2c606bvboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/** Tell the host about the location of the area of VRAM set aside for the host
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * heap. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncstatic int vboxHGSMIReportHostArea(PHGSMIGUESTCOMMANDCONTEXT pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t u32AreaOffset, uint32_t u32AreaSize)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync VBVAINFOHEAP *p;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync int rc = VINF_SUCCESS;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Allocate the IO buffer. */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync p = (VBVAINFOHEAP *)VBoxHGSMIBufferAlloc(pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync sizeof (VBVAINFOHEAP), HGSMI_CH_VBVA,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync VBVA_INFO_HEAP);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if (p)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync {
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Prepare data to be sent to the host. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync p->u32HeapOffset = u32AreaOffset;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync p->u32HeapSize = u32AreaSize;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync rc = VBoxHGSMIBufferSubmit(pCtx, p);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Free the IO buffer. */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync VBoxHGSMIBufferFree(pCtx, p);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync }
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync else
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync rc = VERR_NO_MEMORY;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync return rc;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/**
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * Get the information needed to map the basic communication structures in
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync * device memory into our address space. All pointer parameters are optional.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync *
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param cbVRAM how much video RAM is allocated to the device
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param poffVRAMBaseMapping where to save the offset from the start of the
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync * device VRAM of the whole area to map
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pcbMapping where to save the mapping size
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param poffGuestHeapMemory where to save the offset into the mapped area
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * of the guest heap backing memory
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pcbGuestHeapMemory where to save the size of the guest heap
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * backing memory
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param poffHostFlags where to save the offset into the mapped area
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * of the host flags
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncRTDECL(void) VBoxHGSMIGetBaseMappingInfo(uint32_t cbVRAM,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t *poffVRAMBaseMapping,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t *pcbMapping,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t *poffGuestHeapMemory,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t *pcbGuestHeapMemory,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t *poffHostFlags)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync AssertPtrNullReturnVoid(poffVRAMBaseMapping);
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync AssertPtrNullReturnVoid(pcbMapping);
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync AssertPtrNullReturnVoid(poffGuestHeapMemory);
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync AssertPtrNullReturnVoid(pcbGuestHeapMemory);
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync AssertPtrNullReturnVoid(poffHostFlags);
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync if (poffVRAMBaseMapping)
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync *poffVRAMBaseMapping = cbVRAM - VBVA_ADAPTER_INFORMATION_SIZE;
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync if (pcbMapping)
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync *pcbMapping = VBVA_ADAPTER_INFORMATION_SIZE;
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync if (poffGuestHeapMemory)
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync *poffGuestHeapMemory = 0;
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync if (pcbGuestHeapMemory)
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync *pcbGuestHeapMemory = VBVA_ADAPTER_INFORMATION_SIZE
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync - sizeof(HGSMIHOSTFLAGS);
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync if (poffHostFlags)
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync *poffHostFlags = VBVA_ADAPTER_INFORMATION_SIZE
25be0b1daccd180b98ac7bd0a81e2acb75db6146vboxsync - sizeof(HGSMIHOSTFLAGS);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/**
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * Set up the HGSMI guest-to-host command context.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @returns iprt status value
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pCtx the context to set up
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pvGuestHeapMemory a pointer to the mapped backing memory for
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * the guest heap
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param cbGuestHeapMemory the size of the backing memory area
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param offVRAMGuestHeapMemory the offset of the memory pointed to by
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @a pvGuestHeapMemory within the video RAM
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncRTDECL(int) VBoxHGSMISetupGuestContext(PHGSMIGUESTCOMMANDCONTEXT pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync void *pvGuestHeapMemory,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t cbGuestHeapMemory,
32b1164f35483be483177be7b5235002a4a5afbevboxsync uint32_t offVRAMGuestHeapMemory,
32b1164f35483be483177be7b5235002a4a5afbevboxsync const HGSMIENV *pEnv)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /** @todo should we be using a fixed ISA port value here? */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync pCtx->port = (RTIOPORT)VGA_PORT_HGSMI_GUEST;
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync#ifdef VBOX_WDDM_MINIPORT
6c28ed70192c3f2d1edf978697ff0ee0276bf0eevboxsync return VBoxSHGSMIInit(&pCtx->heapCtx, HGSMI_HEAP_TYPE_MA, pvGuestHeapMemory,
32b1164f35483be483177be7b5235002a4a5afbevboxsync cbGuestHeapMemory, offVRAMGuestHeapMemory, pEnv);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync#else
6c28ed70192c3f2d1edf978697ff0ee0276bf0eevboxsync return HGSMIHeapSetup(&pCtx->heapCtx, HGSMI_HEAP_TYPE_MA, pvGuestHeapMemory,
32b1164f35483be483177be7b5235002a4a5afbevboxsync cbGuestHeapMemory, offVRAMGuestHeapMemory, pEnv);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync#endif
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/**
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * Get the information needed to map the area used by the host to send back
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * requests.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync *
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pCtx the context containing the heap to use
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param cbVRAM how much video RAM is allocated to the device
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param offVRAMBaseMapping the offset of the basic communication structures
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * into the guest's VRAM
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param poffVRAMHostArea where to store the offset into VRAM of the host
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * heap area
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pcbHostArea where to store the size of the host heap area
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncRTDECL(void) VBoxHGSMIGetHostAreaMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t cbVRAM,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t offVRAMBaseMapping,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t *poffVRAMHostArea,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t *pcbHostArea)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t offVRAMHostArea = offVRAMBaseMapping, cbHostArea = 0;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync AssertPtrReturnVoid(poffVRAMHostArea);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync AssertPtrReturnVoid(pcbHostArea);
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync VBoxQueryConfHGSMI(pCtx, VBOX_VBVA_CONF32_HOST_HEAP_SIZE, &cbHostArea);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if (cbHostArea != 0)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync {
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t cbHostAreaMaxSize = cbVRAM / 4;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /** @todo what is the idea of this? */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if (cbHostAreaMaxSize >= VBVA_ADAPTER_INFORMATION_SIZE)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync {
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync cbHostAreaMaxSize -= VBVA_ADAPTER_INFORMATION_SIZE;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync }
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if (cbHostArea > cbHostAreaMaxSize)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync {
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync cbHostArea = cbHostAreaMaxSize;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync }
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Round up to 4096 bytes. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync cbHostArea = (cbHostArea + 0xFFF) & ~0xFFF;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync offVRAMHostArea = offVRAMBaseMapping - cbHostArea;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync }
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync *pcbHostArea = cbHostArea;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync *poffVRAMHostArea = offVRAMHostArea;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync LogFunc(("offVRAMHostArea = 0x%08X, cbHostArea = 0x%08X\n",
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync offVRAMHostArea, cbHostArea));
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/**
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * Initialise the host context structure.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync *
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pCtx the context structure to initialise
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pvBaseMapping where the basic HGSMI structures are mapped at
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param offHostFlags the offset of the host flags into the basic HGSMI
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * structures
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pvHostAreaMapping where the area for the host heap is mapped at
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param offVRAMHostArea offset of the host heap area into VRAM
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param cbHostArea size in bytes of the host heap area
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncRTDECL(void) VBoxHGSMISetupHostContext(PHGSMIHOSTCOMMANDCONTEXT pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync void *pvBaseMapping,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t offHostFlags,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync void *pvHostAreaMapping,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t offVRAMHostArea,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t cbHostArea)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint8_t *pu8HostFlags = ((uint8_t *)pvBaseMapping) + offHostFlags;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync pCtx->pfHostFlags = (HGSMIHOSTFLAGS *)pu8HostFlags;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /** @todo should we really be using a fixed ISA port value here? */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync pCtx->port = (RTIOPORT)VGA_PORT_HGSMI_HOST;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync HGSMIAreaInitialize(&pCtx->areaCtx, pvHostAreaMapping, cbHostArea,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync offVRAMHostArea);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/**
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * Tell the host about the ways it can use to communicate back to us via an
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * HGSMI command
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync *
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @returns iprt status value
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pCtx the context containing the heap to use
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param offVRAMFlagsLocation where we wish the host to place its flags
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * relative to the start of the VRAM
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param fCaps additions HGSMI capabilities the guest
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * supports
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param offVRAMHostArea offset into VRAM of the host heap area
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param cbHostArea size in bytes of the host heap area
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsyncRTDECL(int) VBoxHGSMISendHostCtxInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync HGSMIOFFSET offVRAMFlagsLocation,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t fCaps,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t offVRAMHostArea,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t cbHostArea)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync Log(("VBoxVideo::vboxSetupAdapterInfo\n"));
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* setup the flags first to ensure they are initialized by the time the
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * host heap is ready */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync int rc = vboxHGSMIReportFlagsLocation(pCtx, offVRAMFlagsLocation);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync AssertRC(rc);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if (RT_SUCCESS(rc) && fCaps)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync {
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Inform about caps */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync rc = vboxHGSMISendCapsInfo(pCtx, fCaps);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync AssertRC(rc);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync }
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if (RT_SUCCESS (rc))
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync {
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Report the host heap location. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync rc = vboxHGSMIReportHostArea(pCtx, offVRAMHostArea, cbHostArea);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync AssertRC(rc);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync }
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync Log(("VBoxVideo::vboxSetupAdapterInfo finished rc = %d\n", rc));
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync return rc;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
2dded9efd167d5273281f734d76f49115b47fd89vboxsync/** Sanity test on first call. We do not worry about concurrency issues. */
2dded9efd167d5273281f734d76f49115b47fd89vboxsyncstatic int testQueryConf(PHGSMIGUESTCOMMANDCONTEXT pCtx)
2dded9efd167d5273281f734d76f49115b47fd89vboxsync{
2dded9efd167d5273281f734d76f49115b47fd89vboxsync static bool cOnce = false;
2dded9efd167d5273281f734d76f49115b47fd89vboxsync uint32_t ulValue = 0;
2dded9efd167d5273281f734d76f49115b47fd89vboxsync int rc;
2dded9efd167d5273281f734d76f49115b47fd89vboxsync
2dded9efd167d5273281f734d76f49115b47fd89vboxsync if (cOnce)
2dded9efd167d5273281f734d76f49115b47fd89vboxsync return VINF_SUCCESS;
2dded9efd167d5273281f734d76f49115b47fd89vboxsync cOnce = true;
2dded9efd167d5273281f734d76f49115b47fd89vboxsync rc = VBoxQueryConfHGSMI(pCtx, UINT32_MAX, &ulValue);
2dded9efd167d5273281f734d76f49115b47fd89vboxsync if (RT_SUCCESS(rc) && ulValue == UINT32_MAX)
2dded9efd167d5273281f734d76f49115b47fd89vboxsync return VINF_SUCCESS;
2dded9efd167d5273281f734d76f49115b47fd89vboxsync cOnce = false;
2dded9efd167d5273281f734d76f49115b47fd89vboxsync if (RT_FAILURE(rc))
2dded9efd167d5273281f734d76f49115b47fd89vboxsync return rc;
2dded9efd167d5273281f734d76f49115b47fd89vboxsync return VERR_INTERNAL_ERROR;
2dded9efd167d5273281f734d76f49115b47fd89vboxsync}
2dded9efd167d5273281f734d76f49115b47fd89vboxsync
2dded9efd167d5273281f734d76f49115b47fd89vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/**
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync * Query the host for an HGSMI configuration parameter via an HGSMI command.
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync * @returns iprt status value
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync * @param pCtx the context containing the heap used
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync * @param u32Index the index of the parameter to query,
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync * @see VBVACONF32::u32Index
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync * @param pulValue where to store the value of the parameter on success
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync */
54d13d84f69d613c39bf7672d4095c8d863176efvboxsyncRTDECL(int) VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx,
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync uint32_t u32Index, uint32_t *pulValue)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync int rc = VINF_SUCCESS;
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync VBVACONF32 *p;
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync LogFunc(("u32Index = %d\n", u32Index));
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync
2dded9efd167d5273281f734d76f49115b47fd89vboxsync rc = testQueryConf(pCtx);
2dded9efd167d5273281f734d76f49115b47fd89vboxsync if (RT_FAILURE(rc))
2dded9efd167d5273281f734d76f49115b47fd89vboxsync return rc;
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync /* Allocate the IO buffer. */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync p = (VBVACONF32 *)VBoxHGSMIBufferAlloc(pCtx,
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync sizeof(VBVACONF32), HGSMI_CH_VBVA,
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync VBVA_QUERY_CONF32);
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync if (p)
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync {
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync /* Prepare data to be sent to the host. */
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync p->u32Index = u32Index;
2dded9efd167d5273281f734d76f49115b47fd89vboxsync p->u32Value = UINT32_MAX;
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync rc = VBoxHGSMIBufferSubmit(pCtx, p);
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync if (RT_SUCCESS(rc))
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync {
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync *pulValue = p->u32Value;
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync LogFunc(("u32Value = %d\n", p->u32Value));
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync }
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync /* Free the IO buffer. */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync VBoxHGSMIBufferFree(pCtx, p);
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync }
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync else
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync rc = VERR_NO_MEMORY;
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync LogFunc(("rc = %d\n", rc));
54d13d84f69d613c39bf7672d4095c8d863176efvboxsync return rc;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/**
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * Pass the host a new mouse pointer shape via an HGSMI command.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync *
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @returns success or failure
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param fFlags cursor flags, @see VMMDevReqMousePointer::fFlags
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param cHotX horizontal position of the hot spot
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param cHotY vertical position of the hot spot
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param cWidth width in pixels of the cursor
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param cHeight height in pixels of the cursor
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param pPixels pixel data, @see VMMDevReqMousePointer for the format
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * @param cbLength size in bytes of the pixel data
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync */
d90a4d0b255342cd5bb146b0ec1f47e66bddb77fvboxsyncRTDECL(int) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t fFlags,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t cHotX,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t cHotY,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t cWidth,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t cHeight,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint8_t *pPixels,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t cbLength)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync{
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync VBVAMOUSEPOINTERSHAPE *p;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync uint32_t cbData = 0;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync int rc = VINF_SUCCESS;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if (fFlags & VBOX_MOUSE_POINTER_SHAPE)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync {
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Size of the pointer data: sizeof (AND mask) + sizeof (XOR_MASK) */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync cbData = ((((cWidth + 7) / 8) * cHeight + 3) & ~3)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync + cWidth * 4 * cHeight;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* If shape is supplied, then always create the pointer visible.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * See comments in 'vboxUpdatePointerShape'
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync fFlags |= VBOX_MOUSE_POINTER_VISIBLE;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync }
923f68c9a8ed0a0cb8067fa0196553c3130e2d14vboxsync LogFlowFunc(("cbData %d, %dx%d\n", cbData, cWidth, cHeight));
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if (cbData > cbLength)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync {
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync LogFunc(("calculated pointer data size is too big (%d bytes, limit %d)\n",
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync cbData, cbLength));
d90a4d0b255342cd5bb146b0ec1f47e66bddb77fvboxsync return VERR_INVALID_PARAMETER;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync }
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Allocate the IO buffer. */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync p = (VBVAMOUSEPOINTERSHAPE *)VBoxHGSMIBufferAlloc(pCtx,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync sizeof(VBVAMOUSEPOINTERSHAPE)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync + cbData,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync HGSMI_CH_VBVA,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync VBVA_MOUSE_POINTER_SHAPE);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if (p)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync {
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Prepare data to be sent to the host. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Will be updated by the host. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync p->i32Result = VINF_SUCCESS;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* We have our custom flags in the field */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync p->fu32Flags = fFlags;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync p->u32HotX = cHotX;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync p->u32HotY = cHotY;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync p->u32Width = cWidth;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync p->u32Height = cHeight;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if (p->fu32Flags & VBOX_MOUSE_POINTER_SHAPE)
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Copy the actual pointer data. */
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync memcpy (p->au8Data, pPixels, cbData);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync rc = VBoxHGSMIBufferSubmit(pCtx, p);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync if (RT_SUCCESS(rc))
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync rc = p->i32Result;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync /* Free the IO buffer. */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync VBoxHGSMIBufferFree(pCtx, p);
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync }
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync else
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync rc = VERR_NO_MEMORY;
923f68c9a8ed0a0cb8067fa0196553c3130e2d14vboxsync LogFlowFunc(("rc %d\n", rc));
d90a4d0b255342cd5bb146b0ec1f47e66bddb77fvboxsync return rc;
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync}
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync/**
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync * Report the guest cursor position. The host may wish to use this information
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync * to re-position its own cursor (though this is currently unlikely). The
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync * current host cursor position is returned.
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync * @param pCtx The context containing the heap used.
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync * @param fReportPosition Are we reporting a position?
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync * @param x Guest cursor X position.
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync * @param y Guest cursor Y position.
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync * @param pxHost Host cursor X position is stored here. Optional.
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync * @param pyHost Host cursor Y position is stored here. Optional.
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync * @returns iprt status code.
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync * @returns VERR_NO_MEMORY HGSMI heap allocation failed.
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync */
c87c6e10b608762972b76bfc734daaec9070b50bvboxsyncRTDECL(int) VBoxHGSMICursorPosition(PHGSMIGUESTCOMMANDCONTEXT pCtx, bool fReportPosition, uint32_t x, uint32_t y,
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync uint32_t *pxHost, uint32_t *pyHost)
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync{
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync int rc = VINF_SUCCESS;
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync VBVACURSORPOSITION *p;
3b3317877ad46112ff4f551328888d300034f4dbvboxsync Log(("%s: x=%u, y=%u\n", __PRETTY_FUNCTION__, (unsigned)x, (unsigned)y));
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync /* Allocate the IO buffer. */
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync p = (VBVACURSORPOSITION *)VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVACURSORPOSITION), HGSMI_CH_VBVA, VBVA_CURSOR_POSITION);
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync if (p)
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync {
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync /* Prepare data to be sent to the host. */
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync p->fReportPosition = fReportPosition ? 1 : 0;
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync p->x = x;
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync p->y = y;
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync rc = VBoxHGSMIBufferSubmit(pCtx, p);
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync if (RT_SUCCESS(rc))
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync {
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync if (pxHost)
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync *pxHost = p->x;
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync if (pyHost)
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync *pyHost = p->y;
3b3317877ad46112ff4f551328888d300034f4dbvboxsync Log(("%s: return: x=%u, y=%u\n", __PRETTY_FUNCTION__, (unsigned)x, (unsigned)y));
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync }
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync /* Free the IO buffer. */
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync VBoxHGSMIBufferFree(pCtx, p);
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync }
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync else
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync rc = VERR_NO_MEMORY;
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync LogFunc(("rc = %d\n", rc));
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync return rc;
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync}
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync
c87c6e10b608762972b76bfc734daaec9070b50bvboxsync
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync/** @todo Mouse pointer position to be read from VMMDev memory, address of the memory region
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * can be queried from VMMDev via an IOCTL. This VMMDev memory region will contain
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * host information which is needed by the guest.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync *
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * Reading will not cause a switch to the host.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync *
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * Have to take into account:
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * * synchronization: host must write to the memory only from EMT,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * large structures must be read under flag, which tells the host
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * that the guest is currently reading the memory (OWNER flag?).
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * * guest writes: may be allocate a page for the host info and make
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * the page readonly for the guest.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * * the information should be available only for additions drivers.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * * VMMDev additions driver will inform the host which version of the info it expects,
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync * host must support all versions.
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync *
74fdb8a41a8fdc04e44a1ecaeefb70ed9a7a1e47vboxsync */