VBoxMPShgsmi.cpp revision 32b1164f35483be483177be7b5235002a4a5afbe
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VBox WDDM Miniport driver
c7814cf6e1240a519cbec0441e033d0e2470ed00vboxsync * Copyright (C) 2011-2012 Oracle Corporation
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * available from http://www.virtualbox.org. This file is free software;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * General Public License (GPL) as published by the Free Software
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* SHGSMI */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsyncDECLINLINE(void) vboxSHGSMICommandRetain (PVBOXSHGSMIHEADER pCmd)
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid vboxSHGSMICommandFree (PVBOXSHGSMI pHeap, PVBOXSHGSMIHEADER pCmd)
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncDECLINLINE(void) vboxSHGSMICommandRelease (PVBOXSHGSMI pHeap, PVBOXSHGSMIHEADER pCmd)
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncDECLCALLBACK(void) vboxSHGSMICompletionSetEvent(PVBOXSHGSMI pHeap, void *pvCmd, void *pvContext)
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncDECLCALLBACK(void) vboxSHGSMICompletionCommandRelease(PVBOXSHGSMI pHeap, void *pvCmd, void *pvContext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxSHGSMICommandRelease (pHeap, VBoxSHGSMIBufferHeader(pvCmd));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync/* do not wait for completion */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncDECLINLINE(const VBOXSHGSMIHEADER*) vboxSHGSMICommandPrepAsynch (PVBOXSHGSMI pHeap, PVBOXSHGSMIHEADER pHeader)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* ensure the command is not removed until we're processing it */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncDECLINLINE(void) vboxSHGSMICommandDoneAsynch (PVBOXSHGSMI pHeap, const VBOXSHGSMIHEADER* pHeader)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if(!(ASMAtomicReadU32((volatile uint32_t *)&pHeader->fFlags) & VBOXSHGSMI_FLAG_HG_ASYNCH))
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PFNVBOXSHGSMICMDCOMPLETION pfnCompletion = (PFNVBOXSHGSMICMDCOMPLETION)pHeader->u64Info1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pfnCompletion(pHeap, VBoxSHGSMIBufferData (pHeader), (PVOID)pHeader->u64Info2);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxSHGSMICommandRelease(pHeap, (PVBOXSHGSMIHEADER)pHeader);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncconst VBOXSHGSMIHEADER* VBoxSHGSMICommandPrepAsynchEvent (PVBOXSHGSMI pHeap, PVOID pvBuff, RTSEMEVENT hEventSem)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXSHGSMIHEADER pHeader = VBoxSHGSMIBufferHeader (pvBuff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pHeader->u64Info1 = (uint64_t)vboxSHGSMICompletionSetEvent;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return vboxSHGSMICommandPrepAsynch (pHeap, pHeader);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncconst VBOXSHGSMIHEADER* VBoxSHGSMICommandPrepSynch (PVBOXSHGSMI pHeap, PVOID pCmd)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return VBoxSHGSMICommandPrepAsynchEvent (pHeap, pCmd, hEventSem);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid VBoxSHGSMICommandDoneAsynch (PVBOXSHGSMI pHeap, const VBOXSHGSMIHEADER * pHeader)
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncint VBoxSHGSMICommandDoneSynch (PVBOXSHGSMI pHeap, const VBOXSHGSMIHEADER* pHeader)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTSEMEVENT hEventSem = (RTSEMEVENT)pHeader->u64Info2;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync int rc = RTSemEventWait(hEventSem, RT_INDEFINITE_WAIT);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid VBoxSHGSMICommandCancelAsynch (PVBOXSHGSMI pHeap, const VBOXSHGSMIHEADER* pHeader)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync vboxSHGSMICommandRelease(pHeap, (PVBOXSHGSMIHEADER)pHeader);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid VBoxSHGSMICommandCancelSynch (PVBOXSHGSMI pHeap, const VBOXSHGSMIHEADER* pHeader)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync RTSEMEVENT hEventSem = (RTSEMEVENT)pHeader->u64Info2;
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncconst VBOXSHGSMIHEADER* VBoxSHGSMICommandPrepAsynch (PVBOXSHGSMI pHeap, PVOID pvBuff, PFNVBOXSHGSMICMDCOMPLETION pfnCompletion, PVOID pvCompletion, uint32_t fFlags)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXSHGSMIHEADER pHeader = VBoxSHGSMIBufferHeader (pvBuff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return vboxSHGSMICommandPrepAsynch (pHeap, pHeader);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncconst VBOXSHGSMIHEADER* VBoxSHGSMICommandPrepAsynchIrq (PVBOXSHGSMI pHeap, PVOID pvBuff, PFNVBOXSHGSMICMDCOMPLETION_IRQ pfnCompletion, PVOID pvCompletion, uint32_t fFlags)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync fFlags |= VBOXSHGSMI_FLAG_GH_ASYNCH_CALLBACK_IRQ | VBOXSHGSMI_FLAG_GH_ASYNCH_IRQ;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXSHGSMIHEADER pHeader = VBoxSHGSMIBufferHeader (pvBuff);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* we must assign rather than or because flags field does not get zeroed on command creation */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync return vboxSHGSMICommandPrepAsynch (pHeap, pHeader);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid* VBoxSHGSMIHeapAlloc(PVBOXSHGSMI pHeap, HGSMISIZE cbData, uint8_t u8Channel, uint16_t u16ChannelInfo)
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync pvData = HGSMIHeapAlloc(&pHeap->Heap, cbData, u8Channel, u16ChannelInfo);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid VBoxSHGSMIHeapFree(PVBOXSHGSMI pHeap, void *pvBuffer)
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsyncvoid* VBoxSHGSMIHeapBufferAlloc(PVBOXSHGSMI pHeap, HGSMISIZE cbData)
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsync pvData = HGSMIHeapBufferAlloc(&pHeap->Heap, cbData);
d0a71f63bd810b54e0359223fe53b07730154dc5vboxsyncvoid VBoxSHGSMIHeapBufferFree(PVBOXSHGSMI pHeap, void *pvBuffer)
32b1164f35483be483177be7b5235002a4a5afbevboxsyncint VBoxSHGSMIInit(PVBOXSHGSMI pHeap, uint32_t u32HeapType, void *pvBase, HGSMISIZE cbArea, HGSMIOFFSET offBase,
32b1164f35483be483177be7b5235002a4a5afbevboxsync return HGSMIHeapSetup(&pHeap->Heap, u32HeapType, pvBase, cbArea, offBase, pEnv);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid* VBoxSHGSMICommandAlloc(PVBOXSHGSMI pHeap, HGSMISIZE cbData, uint8_t u8Channel, uint16_t u16ChannelInfo)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* Issue the flush command. */
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsync PVBOXSHGSMIHEADER pHeader = (PVBOXSHGSMIHEADER)VBoxSHGSMIHeapAlloc(pHeap, cbData + sizeof (VBOXSHGSMIHEADER), u8Channel, u16ChannelInfo);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncvoid VBoxSHGSMICommandFree(PVBOXSHGSMI pHeap, void *pvBuffer)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXSHGSMIHEADER pHeader = VBoxSHGSMIBufferHeader(pvBuffer);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync#define VBOXSHGSMI_CMD2LISTENTRY(_pCmd) ((PVBOXVTLIST_ENTRY)&(_pCmd)->pvNext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync#define VBOXSHGSMI_LISTENTRY2CMD(_pEntry) ( (PVBOXSHGSMIHEADER)((uint8_t *)(_pEntry) - RT_OFFSETOF(VBOXSHGSMIHEADER, pvNext)) )
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncint VBoxSHGSMICommandProcessCompletion (PVBOXSHGSMI pHeap, VBOXSHGSMIHEADER* pCur, bool bIrq, PVBOXVTLIST pPostProcessList)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync if (pCur->fFlags & VBOXSHGSMI_FLAG_GH_ASYNCH_CALLBACK_IRQ)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PFNVBOXSHGSMICMDCOMPLETION_IRQ pfnCallback = (PFNVBOXSHGSMICMDCOMPLETION_IRQ)pCur->u64Info1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pfnCallback(pHeap, VBoxSHGSMIBufferData(pCur), pvCallback, &pfnCompletion, &pvCompletion);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pCur->fFlags &= ~VBOXSHGSMI_FLAG_GH_ASYNCH_CALLBACK_IRQ;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* nothing to do with this command */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PFNVBOXSHGSMICMDCOMPLETION pfnCallback = (PFNVBOXSHGSMICMDCOMPLETION)pCur->u64Info1;
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync pfnCallback(pHeap, VBoxSHGSMIBufferData(pCur), pvCallback);
e6ad2e18e663b076aeabfec994947514566a7accvboxsync vboxVtListPut(pPostProcessList, VBOXSHGSMI_CMD2LISTENTRY(pCur), VBOXSHGSMI_CMD2LISTENTRY(pCur));
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync } while (0);
dc959f60f6d3e0cba86f7da4d39aa475913a7e10vboxsyncint VBoxSHGSMICommandPostprocessCompletion (PVBOXSHGSMI pHeap, PVBOXVTLIST pPostProcessList)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync for (pCur = pPostProcessList->pFirst; pCur; pCur = pNext)
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync /* need to save next since the command may be released in a pfnCallback and thus its data might be invalid */
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PVBOXSHGSMIHEADER pCmd = VBOXSHGSMI_LISTENTRY2CMD(pCur);
9055f61bb57d2a625c6434d55beac7565c3b3c0dvboxsync PFNVBOXSHGSMICMDCOMPLETION pfnCallback = (PFNVBOXSHGSMICMDCOMPLETION)pCmd->u64Info1;