VBoxVideoVdma.cpp revision 04f964d82c1af6d3b6cb05e6abccc20a1e051966
d46ee884c41b808b239563b1978468aae12e33a2vboxsync/*
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync * Copyright (C) 2010 Oracle Corporation
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync *
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 */
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync#include "../VBoxVideo.h"
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync#include "../Helper.h"
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync#include <VBox/VBoxGuestLib.h>
d46ee884c41b808b239563b1978468aae12e33a2vboxsync#include <VBox/VBoxVideo.h>
d46ee884c41b808b239563b1978468aae12e33a2vboxsync#include "VBoxVideoVdma.h"
d46ee884c41b808b239563b1978468aae12e33a2vboxsync#include "../VBoxVideo.h"
e2760cdc84c692bc46cfaf5018d313db2f122acavboxsync
d46ee884c41b808b239563b1978468aae12e33a2vboxsync
d46ee884c41b808b239563b1978468aae12e33a2vboxsyncNTSTATUS vboxVdmaPipeConstruct(PVBOXVDMAPIPE pPipe)
d46ee884c41b808b239563b1978468aae12e33a2vboxsync{
d46ee884c41b808b239563b1978468aae12e33a2vboxsync KeInitializeSpinLock(&pPipe->SinchLock);
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync KeInitializeEvent(&pPipe->Event, SynchronizationEvent, FALSE);
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync InitializeListHead(&pPipe->CmdListHead);
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync pPipe->enmState = VBOXVDMAPIPE_STATE_CREATED;
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync pPipe->bNeedNotify = true;
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync return STATUS_SUCCESS;
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync}
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsyncNTSTATUS vboxVdmaPipeSvrOpen(PVBOXVDMAPIPE pPipe)
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync{
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync NTSTATUS Status = STATUS_SUCCESS;
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync KIRQL OldIrql;
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync KeAcquireSpinLock(&pPipe->SinchLock, &OldIrql);
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_CREATED);
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync switch (pPipe->enmState)
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync {
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync case VBOXVDMAPIPE_STATE_CREATED:
1c94c0a63ba68be1a7b2c640e70d7a06464e4fcavboxsync pPipe->enmState = VBOXVDMAPIPE_STATE_OPENNED;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync pPipe->bNeedNotify = false;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync break;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync case VBOXVDMAPIPE_STATE_OPENNED:
d46ee884c41b808b239563b1978468aae12e33a2vboxsync pPipe->bNeedNotify = false;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync break;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync default:
3b70c9ab3cea93ab1a771d2db319311282041382vboxsync AssertBreakpoint();
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Status = STATUS_INVALID_PIPE_STATE;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync break;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
d46ee884c41b808b239563b1978468aae12e33a2vboxsync KeReleaseSpinLock(&pPipe->SinchLock, OldIrql);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync return Status;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
2a229554eb081e98411c81dcdef146c35a000f80vboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsyncNTSTATUS vboxVdmaPipeSvrClose(PVBOXVDMAPIPE pPipe)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync{
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync NTSTATUS Status = STATUS_SUCCESS;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync KIRQL OldIrql;
e33247bff4fddfdba92538374bcc9e2753044a38vboxsync KeAcquireSpinLock(&pPipe->SinchLock, &OldIrql);
d46ee884c41b808b239563b1978468aae12e33a2vboxsync Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSED
d46ee884c41b808b239563b1978468aae12e33a2vboxsync || pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSING);
d46ee884c41b808b239563b1978468aae12e33a2vboxsync switch (pPipe->enmState)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
e33247bff4fddfdba92538374bcc9e2753044a38vboxsync case VBOXVDMAPIPE_STATE_CLOSING:
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pPipe->enmState = VBOXVDMAPIPE_STATE_CLOSED;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync break;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync case VBOXVDMAPIPE_STATE_CLOSED:
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync break;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync default:
e33247bff4fddfdba92538374bcc9e2753044a38vboxsync AssertBreakpoint();
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Status = STATUS_INVALID_PIPE_STATE;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync break;
71e8510a26b72d539cf6d7d7157bd87a53de8cf4vboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
e33247bff4fddfdba92538374bcc9e2753044a38vboxsync KeReleaseSpinLock(&pPipe->SinchLock, OldIrql);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync return Status;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsyncNTSTATUS vboxVdmaPipeCltClose(PVBOXVDMAPIPE pPipe)
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync{
e33247bff4fddfdba92538374bcc9e2753044a38vboxsync NTSTATUS Status = STATUS_SUCCESS;
e33247bff4fddfdba92538374bcc9e2753044a38vboxsync KIRQL OldIrql;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync KeAcquireSpinLock(&pPipe->SinchLock, &OldIrql);
e33247bff4fddfdba92538374bcc9e2753044a38vboxsync bool bNeedNotify = false;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_OPENNED
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync || pPipe->enmState == VBOXVDMAPIPE_STATE_CREATED
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync || pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSED);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync switch (pPipe->enmState)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
e33247bff4fddfdba92538374bcc9e2753044a38vboxsync case VBOXVDMAPIPE_STATE_OPENNED:
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pPipe->enmState = VBOXVDMAPIPE_STATE_CLOSING;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync bNeedNotify = pPipe->bNeedNotify;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pPipe->bNeedNotify = false;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync break;
e33247bff4fddfdba92538374bcc9e2753044a38vboxsync case VBOXVDMAPIPE_STATE_CREATED:
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pPipe->enmState = VBOXVDMAPIPE_STATE_CLOSED;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pPipe->bNeedNotify = false;
e33247bff4fddfdba92538374bcc9e2753044a38vboxsync break;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync case VBOXVDMAPIPE_STATE_CLOSED:
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync break;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync default:
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync AssertBreakpoint();
e33247bff4fddfdba92538374bcc9e2753044a38vboxsync Status = STATUS_INVALID_PIPE_STATE;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync break;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync KeReleaseSpinLock(&pPipe->SinchLock, OldIrql);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (bNeedNotify)
d46ee884c41b808b239563b1978468aae12e33a2vboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync KeSetEvent(&pPipe->Event, 0, FALSE);
d46ee884c41b808b239563b1978468aae12e33a2vboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync return Status;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
d46ee884c41b808b239563b1978468aae12e33a2vboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsyncNTSTATUS vboxVdmaPipeDestruct(PVBOXVDMAPIPE pPipe)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync{
d46ee884c41b808b239563b1978468aae12e33a2vboxsync Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSED
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync || pPipe->enmState == VBOXVDMAPIPE_STATE_CREATED);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync /* ensure the pipe is closed */
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync NTSTATUS Status = vboxVdmaPipeCltClose(pPipe);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(Status == STATUS_SUCCESS);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
d46ee884c41b808b239563b1978468aae12e33a2vboxsync Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSED);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync return Status;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync}
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsyncNTSTATUS vboxVdmaPipeSvrCmdGetList(PVBOXVDMAPIPE pPipe, PLIST_ENTRY pDetachHead)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync{
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync PLIST_ENTRY pEntry = NULL;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync KIRQL OldIrql;
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync NTSTATUS Status = STATUS_SUCCESS;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync VBOXVDMAPIPE_STATE enmState = VBOXVDMAPIPE_STATE_CLOSED;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync do
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync KeAcquireSpinLock(&pPipe->SinchLock, &OldIrql);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_OPENNED
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync || pPipe->enmState == VBOXVDMAPIPE_STATE_CLOSING);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(pPipe->enmState >= VBOXVDMAPIPE_STATE_OPENNED);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync enmState = pPipe->enmState;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync if (enmState >= VBOXVDMAPIPE_STATE_OPENNED)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync vboxVideoLeDetach(&pPipe->CmdListHead, pDetachHead);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pPipe->bNeedNotify = false;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync else
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Status = STATUS_INVALID_PIPE_STATE;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync break;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync KeReleaseSpinLock(&pPipe->SinchLock, OldIrql);
fd0cf98cb3eafc5c96b7e95d934b01c5df4785fbvboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (!IsListEmpty(pDetachHead))
d46ee884c41b808b239563b1978468aae12e33a2vboxsync {
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert(Status == STATUS_SUCCESS);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync break;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync }
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync if (enmState == VBOXVDMAPIPE_STATE_OPENNED)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync {
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync KeAcquireSpinLock(&pPipe->SinchLock, &OldIrql);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pPipe->bNeedNotify = true;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync KeReleaseSpinLock(&pPipe->SinchLock, OldIrql);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
d46ee884c41b808b239563b1978468aae12e33a2vboxsync Status = KeWaitForSingleObject(&pPipe->Event, Executive, KernelMode, FALSE, NULL /* PLARGE_INTEGER Timeout */);
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync Assert(Status == STATUS_SUCCESS);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (Status != STATUS_SUCCESS)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync break;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(enmState > VBOXVDMAPIPE_STATE_OPENNED);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Status = STATUS_PIPE_CLOSING;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync } while (1);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync return Status;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fd0cf98cb3eafc5c96b7e95d934b01c5df4785fbvboxsyncNTSTATUS vboxVdmaPipeCltCmdPut(PVBOXVDMAPIPE pPipe, PVBOXVDMAPIPE_CMD_HDR pCmd)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync{
d46ee884c41b808b239563b1978468aae12e33a2vboxsync NTSTATUS Status = STATUS_SUCCESS;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync KIRQL OldIrql;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync bool bNeedNotify = false;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync KeAcquireSpinLock(&pPipe->SinchLock, &OldIrql);
d46ee884c41b808b239563b1978468aae12e33a2vboxsync
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync Assert(pPipe->enmState == VBOXVDMAPIPE_STATE_OPENNED);
d46ee884c41b808b239563b1978468aae12e33a2vboxsync if (pPipe->enmState == VBOXVDMAPIPE_STATE_OPENNED)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync bNeedNotify = pPipe->bNeedNotify;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync InsertHeadList(&pPipe->CmdListHead, &pCmd->ListEntry);
d46ee884c41b808b239563b1978468aae12e33a2vboxsync pPipe->bNeedNotify = false;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync else
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Status = STATUS_INVALID_PIPE_STATE;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync KeReleaseSpinLock(&pPipe->SinchLock, OldIrql);
d46ee884c41b808b239563b1978468aae12e33a2vboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (bNeedNotify)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
d46ee884c41b808b239563b1978468aae12e33a2vboxsync KeSetEvent(&pPipe->Event, 0, FALSE);
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync return Status;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsyncPVBOXVDMAPIPE_CMD_DR vboxVdmaGgCmdCreate(PVBOXVDMAGG pVdma, uint32_t cbCmd)
d46ee884c41b808b239563b1978468aae12e33a2vboxsync{
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync return (PVBOXVDMAPIPE_CMD_DR)vboxWddmMemAllocZero(cbCmd);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsyncvoid vboxVdmaGgCmdDestroy(PVBOXVDMAPIPE_CMD_DR pDr)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync{
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync vboxWddmMemFree(pDr);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync/**
d46ee884c41b808b239563b1978468aae12e33a2vboxsync * helper function used for system thread creation
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync */
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsyncstatic NTSTATUS vboxVdmaGgThreadCreate(PKTHREAD * ppThread, PKSTART_ROUTINE pStartRoutine, PVOID pStartContext)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync{
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync NTSTATUS fStatus;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync HANDLE hThread;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync OBJECT_ATTRIBUTES fObjectAttributes;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(KeGetCurrentIrql() == PASSIVE_LEVEL);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync InitializeObjectAttributes(&fObjectAttributes, NULL, OBJ_KERNEL_HANDLE,
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync NULL, NULL);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync fStatus = PsCreateSystemThread(&hThread, THREAD_ALL_ACCESS,
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync &fObjectAttributes, NULL, NULL,
6c2e2f2be39d679eb8e2e371afd146099f8dc5e7vboxsync (PKSTART_ROUTINE) pStartRoutine, pStartContext);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (!NT_SUCCESS(fStatus))
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync return fStatus;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync ObReferenceObjectByHandle(hThread, THREAD_ALL_ACCESS, NULL,
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync KernelMode, (PVOID*) ppThread, NULL);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync ZwClose(hThread);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync return STATUS_SUCCESS;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsyncDECLINLINE(void) vboxVdmaDirtyRectsCalcIntersection(const RECT *pArea, const PVBOXWDDM_RECTS_INFO pRects, PVBOXWDDM_RECTS_INFO pResult)
5ff3fa0492332325f57e80636321619e2224027evboxsync{
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pResult->cRects = 0;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync for (uint32_t i = 0; i < pRects->cRects; ++i)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (vboxWddmRectIntersection(pArea, &pRects->aRects[i], &pResult->aRects[pResult->cRects]))
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
5ff3fa0492332325f57e80636321619e2224027evboxsync ++pResult->cRects;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync }
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync }
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync}
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync/**
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync * @param pDevExt
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync */
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsyncNTSTATUS vboxVdmaGgDirtyRectsProcess(VBOXVDMAPIPE_CMD_RECTSINFO *pRectsInfo)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync{
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync PVBOXWDDM_CONTEXT pContext = pRectsInfo->pContext;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync PDEVICE_EXTENSION pDevExt = pContext->pDevice->pAdapter;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync RECT * pContextRect = &pRectsInfo->ContextRect;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync PVBOXWDDM_RECTS_INFO pRects = &pRectsInfo->UpdateRects;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync NTSTATUS Status = STATUS_SUCCESS;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync PVBOXVIDEOCM_CMD_RECTS pCmd = NULL;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync uint32_t cbCmd = VBOXVIDEOCM_CMD_RECTS_SIZE4CRECTS(pRects->cRects);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert(KeGetCurrentIrql() < DISPATCH_LEVEL);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync ExAcquireFastMutex(&pDevExt->ContextMutex);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync for (PLIST_ENTRY pCur = pDevExt->ContextList3D.Flink; pCur != &pDevExt->ContextList3D; pCur = pCur->Flink)
aa0632eb844172ced4bef7b3afdbb216c8462fb2vboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (pCur != &pContext->ListEntry)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fd0cf98cb3eafc5c96b7e95d934b01c5df4785fbvboxsync PVBOXWDDM_CONTEXT pCurContext = VBOXWDDMENTRY_2_CONTEXT(pCur);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (!pCmd)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pCmd = (PVBOXVIDEOCM_CMD_RECTS)vboxVideoCmCmdCreate(&pCurContext->CmContext, cbCmd);
5ff3fa0492332325f57e80636321619e2224027evboxsync Assert(pCmd);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync if (!pCmd)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync {
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Status = STATUS_NO_MEMORY;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync break;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync }
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync else
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pCmd = (PVBOXVIDEOCM_CMD_RECTS)vboxVideoCmCmdReinitForContext(pCmd, &pCurContext->CmContext);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
a12929133f77ffa755a13a7d5d2ff3d87c41c9c5vboxsync vboxVdmaDirtyRectsCalcIntersection(&pContext->ViewRect, pRects, &pCmd->RectsInfo);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (pCmd->RectsInfo.cRects)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(pCmd->fFlags.Value == 0);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pCmd->fFlags.bAddHiddenRects = 1;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync vboxVideoCmCmdSubmit(pCmd, VBOXVIDEOCM_CMD_RECTS_SIZE4CRECTS(pCmd->RectsInfo.cRects));
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pCmd = NULL;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync }
52262a1f2eed7acaf08d8a169159e8201c9da661vboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync else
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync bool bRectShanged = (pContext->ViewRect.left != pContextRect->left
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync || pContext->ViewRect.top != pContextRect->top
fd0cf98cb3eafc5c96b7e95d934b01c5df4785fbvboxsync || pContext->ViewRect.right != pContextRect->right
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync || pContext->ViewRect.bottom != pContextRect->bottom);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync PVBOXVIDEOCM_CMD_RECTS pDrCmd;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
10153a147e7cb38821b5e7404bd2ef6b9af5be4avboxsync if (bRectShanged)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
5ff3fa0492332325f57e80636321619e2224027evboxsync uint32_t cbDrCmd = VBOXVIDEOCM_CMD_RECTS_SIZE4CRECTS(pRects->cRects + 1);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync pDrCmd = (PVBOXVIDEOCM_CMD_RECTS)vboxVideoCmCmdCreate(&pContext->CmContext, cbDrCmd);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert(pDrCmd);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync if (!pDrCmd)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync {
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Status = STATUS_NO_MEMORY;
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync break;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pDrCmd->RectsInfo.cRects = pRects->cRects + 1;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync else
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (pCmd)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync {
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync pDrCmd = (PVBOXVIDEOCM_CMD_RECTS)vboxVideoCmCmdReinitForContext(pCmd, &pContext->CmContext);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pCmd = NULL;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync else
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
5ff3fa0492332325f57e80636321619e2224027evboxsync pDrCmd = (PVBOXVIDEOCM_CMD_RECTS)vboxVideoCmCmdCreate(&pContext->CmContext, cbCmd);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert(pDrCmd);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync if (!pDrCmd)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync {
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Status = STATUS_NO_MEMORY;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync break;
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pDrCmd->RectsInfo.cRects = pRects->cRects;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(pDrCmd->fFlags.Value == 0);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync RECT *pDirtyRect;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (bRectShanged)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pDrCmd->fFlags.bPositionRect = 1;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pDrCmd->RectsInfo.aRects[0] = *pContextRect;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pDirtyRect = &pDrCmd->RectsInfo.aRects[1];
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync }
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync else
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pDirtyRect = &pDrCmd->RectsInfo.aRects[0];
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pDrCmd->fFlags.bAddVisibleRects = 1;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync memcpy (pDirtyRect, pRects->aRects, sizeof (RECT) * pRects->cRects);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync vboxVideoCmCmdSubmit(pDrCmd, VBOXVIDEOCM_SUBMITSIZE_DEFAULT);
fd0cf98cb3eafc5c96b7e95d934b01c5df4785fbvboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync InsertHeadList(&pDevExt->ContextList3D, &pContext->ListEntry);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync ExReleaseFastMutex(&pDevExt->ContextMutex);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (pCmd)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync vboxVideoCmCmdRelease(pCmd);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync return Status;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync}
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsyncstatic VOID vboxVdmaGgWorkerThread(PVOID pvUser)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync{
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync PVBOXVDMAGG pVdma = (PVBOXVDMAGG)pvUser;
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync
d46ee884c41b808b239563b1978468aae12e33a2vboxsync NTSTATUS Status = vboxVdmaPipeSvrOpen(&pVdma->CmdPipe);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(Status == STATUS_SUCCESS);
d3bef44ac7674167abeada174f0d6cf0572249c5vboxsync if (Status == STATUS_SUCCESS)
d3bef44ac7674167abeada174f0d6cf0572249c5vboxsync {
d3bef44ac7674167abeada174f0d6cf0572249c5vboxsync do
d3bef44ac7674167abeada174f0d6cf0572249c5vboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync LIST_ENTRY CmdList;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Status = vboxVdmaPipeSvrCmdGetList(&pVdma->CmdPipe, &CmdList);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(Status == STATUS_SUCCESS || Status == STATUS_PIPE_CLOSING);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (Status == STATUS_SUCCESS)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync {
d3bef44ac7674167abeada174f0d6cf0572249c5vboxsync for (PLIST_ENTRY pCur = CmdList.Blink; pCur != &CmdList; pCur = CmdList.Blink)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync PVBOXVDMAPIPE_CMD_DR pDr = VBOXVDMAPIPE_CMD_DR_FROM_ENTRY(pCur);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync switch (pDr->enmType)
fd0cf98cb3eafc5c96b7e95d934b01c5df4785fbvboxsync {
fd0cf98cb3eafc5c96b7e95d934b01c5df4785fbvboxsync case VBOXVDMAPIPE_CMD_TYPE_RECTSINFO:
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync PVBOXVDMAPIPE_CMD_RECTSINFO pRects = (PVBOXVDMAPIPE_CMD_RECTSINFO)pDr;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Status = vboxVdmaGgDirtyRectsProcess(pRects);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(Status == STATUS_SUCCESS);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync break;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync }
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync case VBOXVDMAPIPE_CMD_TYPE_DMACMD:
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync default:
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync AssertBreakpoint();
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync }
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync RemoveEntryList(pCur);
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync vboxVdmaGgCmdDestroy(pDr);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
04ee5d908f45a7883257fa7e40fb42bbdbaf24b9vboxsync else
04ee5d908f45a7883257fa7e40fb42bbdbaf24b9vboxsync break;
04ee5d908f45a7883257fa7e40fb42bbdbaf24b9vboxsync } while (1);
04ee5d908f45a7883257fa7e40fb42bbdbaf24b9vboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync /* always try to close the pipe to make sure the client side is notified */
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Status = vboxVdmaPipeSvrClose(&pVdma->CmdPipe);
04ee5d908f45a7883257fa7e40fb42bbdbaf24b9vboxsync Assert(Status == STATUS_SUCCESS);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsyncNTSTATUS vboxVdmaGgConstruct(PVBOXVDMAGG pVdma)
fd0cf98cb3eafc5c96b7e95d934b01c5df4785fbvboxsync{
fd0cf98cb3eafc5c96b7e95d934b01c5df4785fbvboxsync NTSTATUS Status = vboxVdmaPipeConstruct(&pVdma->CmdPipe);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(Status == STATUS_SUCCESS);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (Status == STATUS_SUCCESS)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
d46ee884c41b808b239563b1978468aae12e33a2vboxsync Status = vboxVdmaGgThreadCreate(&pVdma->pThread, vboxVdmaGgWorkerThread, pVdma);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert(Status == STATUS_SUCCESS);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync if (Status == STATUS_SUCCESS)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync return STATUS_SUCCESS;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync NTSTATUS tmpStatus = vboxVdmaPipeDestruct(&pVdma->CmdPipe);
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync Assert(tmpStatus == STATUS_SUCCESS);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync /* we're here ONLY in case of an error */
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(Status != STATUS_SUCCESS);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync return Status;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsyncNTSTATUS vboxVdmaGgDestruct(PVBOXVDMAGG pVdma)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync{
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync /* this informs the server thread that it should complete all current commands and exit */
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync NTSTATUS Status = vboxVdmaPipeCltClose(&pVdma->CmdPipe);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert(Status == STATUS_SUCCESS);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync if (Status == STATUS_SUCCESS)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync {
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Status = KeWaitForSingleObject(pVdma->pThread, Executive, KernelMode, FALSE, NULL /* PLARGE_INTEGER Timeout */);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert(Status == STATUS_SUCCESS);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (Status == STATUS_SUCCESS)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Status = vboxVdmaPipeDestruct(&pVdma->CmdPipe);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(Status == STATUS_SUCCESS);
d46ee884c41b808b239563b1978468aae12e33a2vboxsync }
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync }
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync return Status;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync}
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsyncNTSTATUS vboxVdmaGgCmdPost(PVBOXVDMAGG pVdma, PVBOXVDMAPIPE_CMD_DR pCmd)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync{
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync return vboxVdmaPipeCltCmdPut(&pVdma->CmdPipe, &pCmd->PipeHdr);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
d46ee884c41b808b239563b1978468aae12e33a2vboxsync/* end */
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync/*
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync * This is currently used by VDMA. It is invisible for Vdma API clients since
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync * Vdma transport may change if we choose to use another (e.g. more light-weight)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync * transport for DMA commands submission
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync */
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
d46ee884c41b808b239563b1978468aae12e33a2vboxsync#ifdef VBOXVDMA_WITH_VBVA
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsyncstatic int vboxWddmVdmaSubmitVbva(struct _DEVICE_EXTENSION* pDevExt, PVBOXVDMAINFO pInfo, HGSMIOFFSET offDr)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync{
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync int rc;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync if (vboxVbvaBufferBeginUpdate (pDevExt, &pDevExt->u.primary.Vbva))
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync {
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync rc = vboxVbvaReportCmdOffset(pDevExt, &pDevExt->u.primary.Vbva, offDr);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync vboxVbvaBufferEndUpdate (pDevExt, &pDevExt->u.primary.Vbva);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync else
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync AssertBreakpoint();
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync rc = VERR_INVALID_STATE;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync return rc;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
fd0cf98cb3eafc5c96b7e95d934b01c5df4785fbvboxsync#define vboxWddmVdmaSubmit vboxWddmVdmaSubmitVbva
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync#else
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsyncstatic int vboxWddmVdmaSubmitHgsmi(struct _DEVICE_EXTENSION* pDevExt, PVBOXVDMAINFO pInfo, HGSMIOFFSET offDr)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync{
d46ee884c41b808b239563b1978468aae12e33a2vboxsync VBoxHGSMIGuestWrite(pDevExt, offDr);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync return VINF_SUCCESS;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync}
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync#define vboxWddmVdmaSubmit vboxWddmVdmaSubmitHgsmi
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync#endif
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsyncstatic int vboxVdmaInformHost (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo, VBOXVDMA_CTL_TYPE enmCtl)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync{
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync int rc = VINF_SUCCESS;
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync PVBOXVDMA_CTL pCmd = (PVBOXVDMA_CTL)VBoxSHGSMICommandAlloc(&pDevExt->u.primary.hgsmiAdapterHeap, sizeof (VBOXVDMA_CTL), HGSMI_CH_VBVA, VBVA_VDMA_CTL);
1ea22ca610c19eb455275a4398575b6291c27629vboxsync if (pCmd)
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync {
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync pCmd->enmCtl = enmCtl;
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync pCmd->u32Offset = pInfo->CmdHeap.area.offBase;
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync pCmd->i32Result = VERR_NOT_SUPPORTED;
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync const VBOXSHGSMIHEADER* pHdr = VBoxSHGSMICommandPrepSynch(&pDevExt->u.primary.hgsmiAdapterHeap, pCmd);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert(pHdr);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync if (pHdr)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync {
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync do
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync {
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync HGSMIOFFSET offCmd = VBoxSHGSMICommandOffset(&pDevExt->u.primary.hgsmiAdapterHeap, pHdr);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert(offCmd != HGSMIOFFSET_VOID);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync if (offCmd != HGSMIOFFSET_VOID)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync {
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync rc = vboxWddmVdmaSubmit(pDevExt, pInfo, offCmd);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync AssertRC(rc);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync if (RT_SUCCESS(rc))
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync {
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync rc = VBoxSHGSMICommandDoneSynch(&pDevExt->u.primary.hgsmiAdapterHeap, pHdr);
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync AssertRC(rc);
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync if (RT_SUCCESS(rc))
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync {
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync rc = pCmd->i32Result;
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync AssertRC(rc);
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync }
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync break;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync }
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync }
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync else
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync rc = VERR_INVALID_PARAMETER;
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync /* fail to submit, cancel it */
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync VBoxSHGSMICommandCancelSynch(&pDevExt->u.primary.hgsmiAdapterHeap, pHdr);
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync } while (0);
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync }
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync VBoxSHGSMICommandFree (&pDevExt->u.primary.hgsmiAdapterHeap, pCmd);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync }
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync else
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync {
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync drprintf((__FUNCTION__": HGSMIHeapAlloc failed\n"));
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync rc = VERR_OUT_OF_RESOURCES;
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync }
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync return rc;
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync}
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync/* create a DMACommand buffer */
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsyncint vboxVdmaCreate (PDEVICE_EXTENSION pDevExt, VBOXVDMAINFO *pInfo, ULONG offBuffer, ULONG cbBuffer)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync{
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert((offBuffer & 0xfff) == 0);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert((cbBuffer & 0xfff) == 0);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert(offBuffer);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert(cbBuffer);
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if((offBuffer & 0xfff)
606bf1f8cb2c02eb19f231f75e56417f0439951fvboxsync || (cbBuffer & 0xfff)
d46ee884c41b808b239563b1978468aae12e33a2vboxsync || !offBuffer
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync || !cbBuffer)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync drprintf((__FUNCTION__": invalid parameters: offBuffer(0x%x), cbBuffer(0x%x)", offBuffer, cbBuffer));
ad9e5a61fea617d40d07390ff1737277d6aef869vboxsync return VERR_INVALID_PARAMETER;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
2c744347b35ec425c206a25ca4095d30a12474d9vboxsync pInfo->fEnabled = FALSE;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync PVOID pvBuffer;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
7119861e2c17e0a4e0638b06a544cc571cf6804avboxsync int rc = VBoxMapAdapterMemory (pDevExt,
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync &pvBuffer,
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync offBuffer,
7a5aa60c341d7f14da337f31a3ed1afcee98bc8avboxsync cbBuffer);
7a5aa60c341d7f14da337f31a3ed1afcee98bc8avboxsync Assert(RT_SUCCESS(rc));
7a5aa60c341d7f14da337f31a3ed1afcee98bc8avboxsync if (RT_SUCCESS(rc))
7a5aa60c341d7f14da337f31a3ed1afcee98bc8avboxsync {
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync /* Setup a HGSMI heap within the adapter information area. */
d46ee884c41b808b239563b1978468aae12e33a2vboxsync rc = HGSMIHeapSetup (&pInfo->CmdHeap,
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pvBuffer,
d46ee884c41b808b239563b1978468aae12e33a2vboxsync cbBuffer,
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync offBuffer,
d46ee884c41b808b239563b1978468aae12e33a2vboxsync false /*fOffsetBased*/);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(RT_SUCCESS(rc));
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if(RT_SUCCESS(rc))
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync NTSTATUS Status = vboxVdmaGgConstruct(&pInfo->DmaGg);
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync Assert(Status == STATUS_SUCCESS);
7a5aa60c341d7f14da337f31a3ed1afcee98bc8avboxsync if (Status == STATUS_SUCCESS)
c606fa3531314e32f0ae90495618aeae47418477vboxsync return VINF_SUCCESS;
c606fa3531314e32f0ae90495618aeae47418477vboxsync rc = VERR_GENERAL_FAILURE;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync else
d46ee884c41b808b239563b1978468aae12e33a2vboxsync drprintf((__FUNCTION__": HGSMIHeapSetup failed rc = 0x%x\n", rc));
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync VBoxUnmapAdapterMemory(pDevExt, &pvBuffer, cbBuffer);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync else
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync drprintf((__FUNCTION__": VBoxMapAdapterMemory failed rc = 0x%x\n", rc));
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
d46ee884c41b808b239563b1978468aae12e33a2vboxsync return rc;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsyncint vboxVdmaDisable (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync{
d46ee884c41b808b239563b1978468aae12e33a2vboxsync dfprintf((__FUNCTION__"\n"));
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(pInfo->fEnabled);
d46ee884c41b808b239563b1978468aae12e33a2vboxsync if (!pInfo->fEnabled)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync return VINF_ALREADY_INITIALIZED;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync /* ensure nothing else is submitted */
d46ee884c41b808b239563b1978468aae12e33a2vboxsync pInfo->fEnabled = FALSE;
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync int rc = vboxVdmaInformHost (pDevExt, pInfo, VBOXVDMA_CTL_TYPE_DISABLE);
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync AssertRC(rc);
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync return rc;
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync}
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsyncint vboxVdmaEnable (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync{
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync dfprintf((__FUNCTION__"\n"));
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync Assert(!pInfo->fEnabled);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (pInfo->fEnabled)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync return VINF_ALREADY_INITIALIZED;
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync int rc = vboxVdmaInformHost (pDevExt, pInfo, VBOXVDMA_CTL_TYPE_ENABLE);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(RT_SUCCESS(rc));
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (RT_SUCCESS(rc))
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pInfo->fEnabled = TRUE;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync return rc;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync}
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsyncint vboxVdmaFlush (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo)
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync{
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync dfprintf((__FUNCTION__"\n"));
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync
10153a147e7cb38821b5e7404bd2ef6b9af5be4avboxsync Assert(pInfo->fEnabled);
10153a147e7cb38821b5e7404bd2ef6b9af5be4avboxsync if (!pInfo->fEnabled)
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync return VINF_ALREADY_INITIALIZED;
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync int rc = vboxVdmaInformHost (pDevExt, pInfo, VBOXVDMA_CTL_TYPE_FLUSH);
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync Assert(RT_SUCCESS(rc));
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync return rc;
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync}
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsyncint vboxVdmaDestroy (PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync{
d46ee884c41b808b239563b1978468aae12e33a2vboxsync int rc = VINF_SUCCESS;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync NTSTATUS Status = vboxVdmaGgDestruct(&pInfo->DmaGg);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert(Status == STATUS_SUCCESS);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync if (Status == STATUS_SUCCESS)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync {
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert(!pInfo->fEnabled);
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync if (pInfo->fEnabled)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync rc = vboxVdmaDisable (pDevExt, pInfo);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync VBoxUnmapAdapterMemory (pDevExt, (void**)&pInfo->CmdHeap.area.pu8Base, pInfo->CmdHeap.area.cbArea);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync else
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync rc = VERR_GENERAL_FAILURE;
c8faf7a704e698dec3679d7df43ae55b1bab3eadvboxsync return rc;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsyncvoid vboxVdmaCBufDrFree (PVBOXVDMAINFO pInfo, PVBOXVDMACBUF_DR pDr)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync{
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync VBoxSHGSMICommandFree (&pInfo->CmdHeap, pDr);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsyncPVBOXVDMACBUF_DR vboxVdmaCBufDrCreate (PVBOXVDMAINFO pInfo, uint32_t cbTrailingData)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync{
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync uint32_t cbDr = VBOXVDMACBUF_DR_SIZE(cbTrailingData);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync PVBOXVDMACBUF_DR pDr = (PVBOXVDMACBUF_DR)VBoxSHGSMICommandAlloc (&pInfo->CmdHeap, cbDr, HGSMI_CH_VBVA, VBVA_VDMA_CMD);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync Assert(pDr);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync if (pDr)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync memset (pDr, 0, cbDr);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync else
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync drprintf((__FUNCTION__": VBoxSHGSMICommandAlloc returned NULL\n"));
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync return pDr;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync}
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsyncstatic DECLCALLBACK(void) vboxVdmaCBufDrCompletion(struct _HGSMIHEAP * pHeap, void *pvCmd, void *pvContext)
d46ee884c41b808b239563b1978468aae12e33a2vboxsync{
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pvContext;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync PVBOXVDMAINFO pInfo = &pDevExt->u.primary.Vdma;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync vboxVdmaCBufDrFree (pInfo, (PVBOXVDMACBUF_DR)pvCmd);
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync}
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsyncstatic DECLCALLBACK(void) vboxVdmaCBufDrCompletionIrq(struct _HGSMIHEAP * pHeap, void *pvCmd, void *pvContext,
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync PFNVBOXSHGSMICMDCOMPLETION *ppfnCompletion, void **ppvCompletion)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync{
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pvContext;
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync PVBOXVDMAINFO pVdma = &pDevExt->u.primary.Vdma;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync DXGKARGCB_NOTIFY_INTERRUPT_DATA notify;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync PVBOXVDMACBUF_DR pDr = (PVBOXVDMACBUF_DR)pvCmd;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync memset(&notify, 0, sizeof(DXGKARGCB_NOTIFY_INTERRUPT_DATA));
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
d46ee884c41b808b239563b1978468aae12e33a2vboxsync PVBOXWDDM_CONTEXT pContext = (PVBOXWDDM_CONTEXT)pDr->u64GuestContext;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (RT_SUCCESS(pDr->rc))
d46ee884c41b808b239563b1978468aae12e33a2vboxsync {
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync notify.InterruptType = DXGK_INTERRUPT_DMA_COMPLETED;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync notify.DmaCompleted.SubmissionFenceId = pDr->u32FenceId;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync if (pContext)
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync {
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync notify.DmaCompleted.NodeOrdinal = pContext->NodeOrdinal;
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync notify.DmaCompleted.EngineOrdinal = 0;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pContext->uLastCompletedCmdFenceId = pDr->u32FenceId;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync }
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync else
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pVdma->uLastCompletedPagingBufferCmdFenceId = pDr->u32FenceId;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pDevExt->bSetNotifyDxDpc = TRUE;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync else if (pDr->rc == VERR_INTERRUPTED)
d46ee884c41b808b239563b1978468aae12e33a2vboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync notify.InterruptType = DXGK_INTERRUPT_DMA_PREEMPTED;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync notify.DmaPreempted.PreemptionFenceId = pDr->u32FenceId;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (pContext)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
d46ee884c41b808b239563b1978468aae12e33a2vboxsync notify.DmaPreempted.LastCompletedFenceId = pContext->uLastCompletedCmdFenceId;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync notify.DmaPreempted.NodeOrdinal = pContext->NodeOrdinal;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync notify.DmaPreempted.EngineOrdinal = 0;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync }
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync else
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync notify.DmaPreempted.LastCompletedFenceId = pVdma->uLastCompletedPagingBufferCmdFenceId;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync pDevExt->bSetNotifyDxDpc = TRUE;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync }
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync else
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync {
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync AssertBreakpoint();
358a99c385080f7f31166943f3ac3a2aea6b5263vboxsync notify.InterruptType = DXGK_INTERRUPT_DMA_FAULTED;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync notify.DmaFaulted.FaultedFenceId = pDr->u32FenceId;
d46ee884c41b808b239563b1978468aae12e33a2vboxsync notify.DmaFaulted.Status = STATUS_UNSUCCESSFUL; /* @todo: better status ? */
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (pContext)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync notify.DmaFaulted.NodeOrdinal = pContext->NodeOrdinal;
8cd393943ea52545c4d063f5a94436639f0f80b6vboxsync notify.DmaFaulted.EngineOrdinal = 0;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
34aaaf212fe61ccafbae15eb832d6062ba548799vboxsync pDevExt->bSetNotifyDxDpc = TRUE;
6e12ccc60ac657fb87e27b7a2b26e0a63bebe024vboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync pDevExt->u.primary.DxgkInterface.DxgkCbNotifyInterrupt(pDevExt->u.primary.DxgkInterface.DeviceHandle, &notify);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync
f83c571186f95b28f63a1acb516edaf6ee372419vboxsync /* inform SHGSMI we want to be called at DPC later */
f83c571186f95b28f63a1acb516edaf6ee372419vboxsync *ppfnCompletion = vboxVdmaCBufDrCompletion;
f83c571186f95b28f63a1acb516edaf6ee372419vboxsync *ppvCompletion = pvContext;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsyncint vboxVdmaCBufDrSubmit(PDEVICE_EXTENSION pDevExt, PVBOXVDMAINFO pInfo, PVBOXVDMACBUF_DR pDr)
8ef9698f7d5a2304d43584fb942a7b69c7424f51vboxsync{
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync const VBOXSHGSMIHEADER* pHdr = VBoxSHGSMICommandPrepAsynchIrq (&pInfo->CmdHeap, pDr, vboxVdmaCBufDrCompletionIrq, pDevExt, VBOXSHGSMI_FLAG_GH_ASYNCH_FORCE);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(pHdr);
fc148a6b23d25a87561beaffe0ba06c3ba93bf5avboxsync int rc = VERR_GENERAL_FAILURE;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (pHdr)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
14b903b792c76bd7d1a240370d64a146d90e28f4vboxsync do
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync HGSMIOFFSET offCmd = VBoxSHGSMICommandOffset(&pInfo->CmdHeap, pHdr);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync Assert(offCmd != HGSMIOFFSET_VOID);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (offCmd != HGSMIOFFSET_VOID)
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync rc = vboxWddmVdmaSubmit(pDevExt, pInfo, offCmd);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync AssertRC(rc);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync if (RT_SUCCESS(rc))
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync {
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync VBoxSHGSMICommandDoneAsynch(&pInfo->CmdHeap, pHdr);
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync AssertRC(rc);
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync break;
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync }
9e4ea89b1085fdaa5861e45a729d9c978db1a8f1vboxsync }
e2760cdc84c692bc46cfaf5018d313db2f122acavboxsync else
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync rc = VERR_INVALID_PARAMETER;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync /* fail to submit, cancel it */
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync VBoxSHGSMICommandCancelAsynch(&pInfo->CmdHeap, pHdr);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync } while (0);
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync }
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync else
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync rc = VERR_INVALID_PARAMETER;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync return rc;
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync}
fe06619ae576367ff3568e6abd99fb8ad28cc73avboxsync