VBoxVideoVdma.cpp revision 649f47eb2c9c03f3dc7fb88991f8fd36de9f4b44
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync * Copyright (C) 2010 Sun Microsystems, Inc.
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync * available from http://www.virtualbox.org. This file is free software;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync * you can redistribute it and/or modify it under the terms of the GNU
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync * General Public License (GPL) as published by the Free Software
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync * additional information or have any questions.
d46ee884c41b808b239563b1978468aae12e33a2vboxsync#include "../Helper.h"
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * This is currently used by VDMA. It is invisible for Vdma API clients since
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * Vdma transport may change if we choose to use another (e.g. more light-weight)
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync * transport for DMA commands submission
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsyncstatic int vboxVdmaInformHost (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo, VBOXVDMA_CTL_TYPE enmCtl)
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync PVBOXVDMA_CTL pCmd = (PVBOXVDMA_CTL)VBoxSHGSMICommandAlloc (&pDevExt->u.primary.hgsmiAdapterHeap, sizeof (VBOXVDMA_CTL), HGSMI_CH_VBVA, VBVA_VDMA_CTL);
d46ee884c41b808b239563b1978468aae12e33a2vboxsync VBoxSHGSMICommandSubmitSynch (&pDevExt->u.primary.hgsmiAdapterHeap, pCmd);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync VBoxSHGSMICommandFree (&pDevExt->u.primary.hgsmiAdapterHeap, pCmd);
2a229554eb081e98411c81dcdef146c35a000f80vboxsync drprintf((__FUNCTION__": HGSMIHeapAlloc failed\n"));
635fe52d5adf7b894207be82370e49e1fae64af0vboxsync/* create a DMACommand buffer */
635fe52d5adf7b894207be82370e49e1fae64af0vboxsyncint vboxVdmaCreate (PDEVICE_EXTENSION pDevExt, VBOXVDMAINFO *pInfo, ULONG offBuffer, ULONG cbBuffer)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync drprintf((__FUNCTION__": invalid parameters: offBuffer(0x%x), cbBuffer(0x%x)", offBuffer, cbBuffer));
d8523ff7d948462e328eec88b602effe2e7f7080vboxsync /* Setup a HGSMI heap within the adapter information area. */
d8523ff7d948462e328eec88b602effe2e7f7080vboxsync false /*fOffsetBased*/);
d8523ff7d948462e328eec88b602effe2e7f7080vboxsync drprintf((__FUNCTION__": HGSMIHeapSetup failed rc = 0x%x\n", rc));
d8523ff7d948462e328eec88b602effe2e7f7080vboxsync VBoxUnmapAdapterMemory(pDevExt, &pvBuffer, cbBuffer);
d8523ff7d948462e328eec88b602effe2e7f7080vboxsync drprintf((__FUNCTION__": VBoxMapAdapterMemory failed rc = 0x%x\n", rc));
d8523ff7d948462e328eec88b602effe2e7f7080vboxsyncint vboxVdmaDisable (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync /* ensure nothing else is submitted */
d8523ff7d948462e328eec88b602effe2e7f7080vboxsync int rc = vboxVdmaInformHost (pDevExt, pInfo, VBOXVDMA_CTL_TYPE_DISABLE);
d8523ff7d948462e328eec88b602effe2e7f7080vboxsyncint vboxVdmaEnable (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo)
6063286f0f0d78e627c9ef48073f5753da93ba10vboxsync int rc = vboxVdmaInformHost (pDevExt, pInfo, VBOXVDMA_CTL_TYPE_ENABLE);
64836f6a22eea42b83b0ec64abcb3aa7ccc27f25vboxsyncint vboxVdmaFlush (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo)
d8523ff7d948462e328eec88b602effe2e7f7080vboxsync int rc = vboxVdmaInformHost (pDevExt, pInfo, VBOXVDMA_CTL_TYPE_FLUSH);
d8523ff7d948462e328eec88b602effe2e7f7080vboxsyncint vboxVdmaDestroy (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo)
d8523ff7d948462e328eec88b602effe2e7f7080vboxsync VBoxUnmapAdapterMemory (pDevExt, (void**)&pInfo->CmdHeap.area.pu8Base, pInfo->CmdHeap.area.cbArea);
d8523ff7d948462e328eec88b602effe2e7f7080vboxsyncvoid vboxVdmaCBufDrFree (PVBOXVDMAINFO pInfo, PVBOXVDMACBUF_DR pDr)
e4e800c40799670522fcc976b0e07345cf459297vboxsyncPVBOXVDMACBUF_DR vboxVdmaCBufDrCreate (PVBOXVDMAINFO pInfo, uint32_t cbTrailingData)
e4e800c40799670522fcc976b0e07345cf459297vboxsync uint32_t cbDr = sizeof (VBOXVDMACBUF_DR) + cbTrailingData;
e4e800c40799670522fcc976b0e07345cf459297vboxsync PVBOXVDMACBUF_DR pDr = (PVBOXVDMACBUF_DR)VBoxSHGSMICommandAlloc (&pInfo->CmdHeap, cbDr, HGSMI_CH_VBVA, VBVA_VDMA_CMD);
e4e800c40799670522fcc976b0e07345cf459297vboxsync drprintf((__FUNCTION__": VBoxSHGSMICommandAlloc returned NULL\n"));
e4e800c40799670522fcc976b0e07345cf459297vboxsyncstatic DECLCALLBACK(void) vboxVdmaCBufDrCompletion(struct _HGSMIHEAP * pHeap, void *pvCmd, void *pvContext)
e4e800c40799670522fcc976b0e07345cf459297vboxsync PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pvContext;
e4e800c40799670522fcc976b0e07345cf459297vboxsync vboxVdmaCBufDrFree (pInfo, (PVBOXVDMACBUF_DR)pvCmd);
e4e800c40799670522fcc976b0e07345cf459297vboxsyncstatic DECLCALLBACK(void) vboxVdmaCBufDrCompletionIrq(struct _HGSMIHEAP * pHeap, void *pvCmd, void *pvContext,
e4e800c40799670522fcc976b0e07345cf459297vboxsync PFNVBOXSHGSMICMDCOMPLETION *ppfnCompletion, void **ppvCompletion)
e4e800c40799670522fcc976b0e07345cf459297vboxsync PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pvContext;
689351c3b85a73743a522136a28262299e30b7fdvboxsync memset(¬ify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
689351c3b85a73743a522136a28262299e30b7fdvboxsync PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pDr->u64GuestContext;
689351c3b85a73743a522136a28262299e30b7fdvboxsync notify.InterruptType = DXGK_INTERRUPT_DMA_COMPLETED;
689351c3b85a73743a522136a28262299e30b7fdvboxsync notify.DmaCompleted.SubmissionFenceId = pDr->u32FenceId;
689351c3b85a73743a522136a28262299e30b7fdvboxsync notify.DmaCompleted.NodeOrdinal = pContext->NodeOrdinal;
689351c3b85a73743a522136a28262299e30b7fdvboxsync pContext->uLastCompletedCmdFenceId = pDr->u32FenceId;
689351c3b85a73743a522136a28262299e30b7fdvboxsync pVdma->uLastCompletedPagingBufferCmdFenceId = pDr->u32FenceId;
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync notify.InterruptType = DXGK_INTERRUPT_DMA_PREEMPTED;
e33247bff4fddfdba92538374bcc9e2753044a38vboxsync notify.DmaPreempted.PreemptionFenceId = pDr->u32FenceId;
e33247bff4fddfdba92538374bcc9e2753044a38vboxsync notify.DmaPreempted.LastCompletedFenceId = pContext->uLastCompletedCmdFenceId;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync notify.DmaPreempted.NodeOrdinal = pContext->NodeOrdinal;
1d9143584d5616e94efe0ff5ce57e04708529775vboxsync notify.DmaPreempted.LastCompletedFenceId = pVdma->uLastCompletedPagingBufferCmdFenceId;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync notify.DmaFaulted.FaultedFenceId = pDr->u32FenceId;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync notify.DmaFaulted.Status = STATUS_UNSUCCESSFUL; /* @todo: better status ? */
e33247bff4fddfdba92538374bcc9e2753044a38vboxsync notify.DmaFaulted.NodeOrdinal = pContext->NodeOrdinal;
d8523ff7d948462e328eec88b602effe2e7f7080vboxsync pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, ¬ify);
c09430453634ebc72695a69d12366a8fb57132e3vboxsync /* inform SHGSMI we want to be called at DPC later */
d46ee884c41b808b239563b1978468aae12e33a2vboxsyncvoid vboxVdmaCBufDrSubmit (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo, PVBOXVDMACBUF_DR pDr)