DevVGA_VDMA.cpp revision 0809b223e0b2bac24335a319696ab6ebccb99415
1f5867c6a115bbb281bcdc0b2c90eefe1de81134vboxsync * Video DMA (VDMA) support.
1f5867c6a115bbb281bcdc0b2c90eefe1de81134vboxsync * Copyright (C) 2006-2012 Oracle Corporation
1f5867c6a115bbb281bcdc0b2c90eefe1de81134vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
1f5867c6a115bbb281bcdc0b2c90eefe1de81134vboxsync * available from http://www.virtualbox.org. This file is free software;
1f5867c6a115bbb281bcdc0b2c90eefe1de81134vboxsync * you can redistribute it and/or modify it under the terms of the GNU
1f5867c6a115bbb281bcdc0b2c90eefe1de81134vboxsync * General Public License (GPL) as published by the Free Software
1f5867c6a115bbb281bcdc0b2c90eefe1de81134vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
1f5867c6a115bbb281bcdc0b2c90eefe1de81134vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
1f5867c6a115bbb281bcdc0b2c90eefe1de81134vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
1f5867c6a115bbb281bcdc0b2c90eefe1de81134vboxsync#define WARN_BP() do { } while (0)
1f5867c6a115bbb281bcdc0b2c90eefe1de81134vboxsync } while (0)
1f5867c6a115bbb281bcdc0b2c90eefe1de81134vboxsynctypedef DECLCALLBACKPTR(void, PFNVBOXVDMATHREAD_CHANGED)(struct VBOXVDMATHREAD *pThread, int rc, void *pvThreadContext, void *pvChangeContext);
1f5867c6a115bbb281bcdc0b2c90eefe1de81134vboxsync/* state transformations:
1f5867c6a115bbb281bcdc0b2c90eefe1de81134vboxsync * submitter | processor
1f5867c6a115bbb281bcdc0b2c90eefe1de81134vboxsync * LISTENING ---> PROCESSING
#define VBVAEXHOSTCONTEXT_STATE_LISTENING 0
#define VBVAEXHOSTCONTEXT_ESTATE_PAUSED 0
typedef struct VBVAEXHOSTCONTEXT
#ifndef VBOXVDBG_MEMCACHE_DISABLE
struct VBVAEXHOSTCTL;
typedef DECLCALLBACKPTR(void, PFNVBVAEXHOSTCTL_COMPLETE)(VBVAEXHOSTCONTEXT *pVbva, struct VBVAEXHOSTCTL *pCtl, int rc, void *pvComplete);
typedef struct VBVAEXHOSTCTL
} cmd;
} state;
void *pvComplete;
* but can be called with other VBoxVBVAExS** (submitter) functions except Init/Start/Term aparently.
* Can only be called be the processor, i.e. the entity that acquired the processor state by direct or indirect call to the VBoxVBVAExHSCheckCommands
static VBVAEXHOST_DATA_TYPE VBoxVBVAExHPDataGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd);
static void VBoxVBVAExHPDataCompleteCtl(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL *pCtl, int rc);
* can be called concurrently with istelf as well as with other VBoxVBVAEx** functions except Init/Start/Term aparently */
static int VBoxVBVAExHSSaveState(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM);
static int VBoxVBVAExHSLoadState(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM, uint32_t u32Version);
#ifndef VBOXVDBG_MEMCACHE_DISABLE
#ifndef VBOXVDBG_MEMCACHE_DISABLE
if (!pCtl)
return NULL;
return pCtl;
if (ASMAtomicCmpXchgS32(&pCmdVbva->i32State, VBVAEXHOSTCONTEXT_STATE_PROCESSING, VBVAEXHOSTCONTEXT_STATE_LISTENING))
return VINF_SUCCESS;
return VERR_SEM_BUSY;
static VBVAEXHOSTCTL* vboxVBVAExHPCheckCtl(struct VBVAEXHOSTCONTEXT *pCmdVbva, bool *pfHostCtl, bool fHostOnlyMode)
return NULL;
if (pCtl)
*pfHostCtl = true;
else if (!fHostOnlyMode)
*pfHostCtl = false;
if (pCtl)
return pCtl;
return NULL;
bool fHostCtl = false;
return pCtl;
return VERR_INVALID_STATE;
return VINF_SUCCESS;
return VERR_INVALID_STATE;
return VINF_SUCCESS;
static bool vboxVBVAExHPCheckProcessCtlInternal(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL* pCtl)
static int vboxVBVAExHPCmdGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd)
return VINF_EOF;
return VINF_TRY_AGAIN;
if (!cbRecord)
return VINF_TRY_AGAIN;
return VINF_SUCCESS;
return VERR_INVALID_STATE;
static void VBoxVBVAExHPDataCompleteCtl(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL *pCtl, int rc)
static VBVAEXHOST_DATA_TYPE vboxVBVAExHPDataGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd)
bool fHostClt;
if (pCtl)
if (fHostClt)
return VBVAEXHOST_DATA_TYPE_HOSTCTL;
return VBVAEXHOST_DATA_TYPE_GUESTCTL;
return VBVAEXHOST_DATA_TYPE_NO_DATA;
switch (rc)
case VINF_SUCCESS:
return VBVAEXHOST_DATA_TYPE_CMD;
case VINF_EOF:
return VBVAEXHOST_DATA_TYPE_NO_DATA;
case VINF_TRY_AGAIN:
/* this is something really unexpected, i.e. most likely guest has written something incorrect to the VBVA buffer */
return VBVAEXHOST_DATA_TYPE_NO_DATA;
return VBVAEXHOST_DATA_TYPE_NO_DATA;
static VBVAEXHOST_DATA_TYPE VBoxVBVAExHPDataGet(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t **ppCmd, uint32_t *pcbCmd)
/* we need to prevent racing between us clearing the flag and command check/submission thread, i.e.
* 5. ->here we need to re-check the queue state to ensure we do not leak the notification of the above command
return VBVAEXHOST_DATA_TYPE_NO_DATA;
return enmType;
if (pVBVA)
* VINF_SUCCESS - there are commands are in a queue, and the given thread is now the processor (i.e. typically it would delegate processing to a worker thread)
return VINF_SUCCESS;
return VINF_EOF;
return VINF_ALREADY_INITIALIZED;
return VERR_INVALID_STATE;
#ifndef VBOXVDBG_MEMCACHE_DISABLE
return VINF_SUCCESS;
#ifndef VBOXVDBG_MEMCACHE_DISABLE
return rc;
return VERR_INVALID_STATE;
return VINF_SUCCESS;
return VINF_SUCCESS;
return VINF_SUCCESS;
#ifndef VBOXVDBG_MEMCACHE_DISABLE
static int vboxVBVAExHSSaveGuestCtl(struct VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL* pCtl, uint8_t* pu8VramBase, PSSMHANDLE pSSM)
return VINF_SUCCESS;
static int vboxVBVAExHSSaveStateLocked(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM)
return VERR_INVALID_STATE;
int rc;
return VINF_SUCCESS;
static int VBoxVBVAExHSSaveState(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM)
return rc;
return rc;
static int vboxVBVAExHSLoadGuestCtl(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM, uint32_t u32Version)
if (!u32)
return VINF_EOF;
if (!pHCtl)
return VERR_NO_MEMORY;
return VINF_SUCCESS;
static int vboxVBVAExHSLoadStateLocked(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM, uint32_t u32Version)
return VERR_INVALID_STATE;
int rc;
return VINF_SUCCESS;
static int VBoxVBVAExHSLoadState(struct VBVAEXHOSTCONTEXT *pCmdVbva, uint8_t* pu8VramBase, PSSMHANDLE pSSM, uint32_t u32Version)
return rc;
return rc;
static int VBoxVBVAExHCtlSubmit(VBVAEXHOSTCONTEXT *pCmdVbva, VBVAEXHOSTCTL* pCtl, VBVAEXHOSTCTL_SOURCE enmSource, PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
return VERR_INVALID_STATE;
return VERR_INVALID_STATE;
return rc;
#ifdef VBOX_WITH_CRHGSMI
typedef struct VBOXVDMA_SOURCE
typedef struct VBOXVDMAHOST
#ifdef VBOX_WITH_CRHGSMI
#ifdef VBOX_VDMA_WITH_WATCHDOG
#ifdef VBOX_WITH_CRHGSMI
if (pfnChanged)
if (pfnChanged)
switch (u32State)
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
return VERR_INVALID_STATE;
int VBoxVDMAThreadCreate(PVBOXVDMATHREAD pThread, PFNRTTHREAD pfnThread, void *pvThread, PFNVBOXVDMATHREAD_CHANGED pfnCreated, void*pvCreated)
return rc;
rc = RTThreadCreate(&pThread->hWorkerThread, pfnThread, pvThread, 0, RTTHREADTYPE_IO, RTTHREADFLAGS_WAITABLE, "VDMA");
return VINF_SUCCESS;
return rc;
return rc;
return rc;
int VBoxVDMAThreadTerm(PVBOXVDMATHREAD pThread, PFNVBOXVDMATHREAD_CHANGED pfnTerminated, void*pvTerminated, bool fNotify)
int rc;
switch (u32State)
if (fNotify)
return VINF_SUCCESS;
return VERR_INVALID_STATE;
return VERR_INVALID_STATE;
return VERR_INTERNAL_ERROR;
static int vdmaVBVACtlSubmitSync(PVBOXVDMAHOST pVdma, VBVAEXHOSTCTL* pCtl, VBVAEXHOSTCTL_SOURCE enmSource);
typedef DECLCALLBACK(void) FNVBOXVDMACRCTL_CALLBACK(PVGASTATE pVGAState, PVBOXVDMACMD_CHROMIUM_CTL pCmd, void* pvContext);
typedef struct VBOXVDMACMD_CHROMIUM_CTL_PRIVATE
void *pvCompletion;
#define VBOXVDMACMD_CHROMIUM_CTL_PRIVATE_FROM_CTL(_p) ((PVBOXVDMACMD_CHROMIUM_CTL_PRIVATE)(((uint8_t*)(_p)) - RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CTL_PRIVATE, Cmd)))
static PVBOXVDMACMD_CHROMIUM_CTL vboxVDMACrCtlCreate(VBOXVDMACMD_CHROMIUM_CTL_TYPE enmCmd, uint32_t cbCmd)
PVBOXVDMACMD_CHROMIUM_CTL_PRIVATE pHdr = (PVBOXVDMACMD_CHROMIUM_CTL_PRIVATE)RTMemAllocZ(cbCmd + RT_OFFSETOF(VBOXVDMACMD_CHROMIUM_CTL_PRIVATE, Cmd));
if (pHdr)
return NULL;
if(!cRefs)
static DECLCALLBACK(void) vboxVDMACrCtlCbSetEvent(PVGASTATE pVGAState, PVBOXVDMACMD_CHROMIUM_CTL pCmd, void* pvContext)
static DECLCALLBACK(void) vboxVDMACrCtlCbReleaseCmd(PVGASTATE pVGAState, PVBOXVDMACMD_CHROMIUM_CTL pCmd, void* pvContext)
static int vboxVDMACrCtlPostAsync (PVGASTATE pVGAState, PVBOXVDMACMD_CHROMIUM_CTL pCmd, uint32_t cbCmd, PFNVBOXVDMACRCTL_CALLBACK pfnCompletion, void *pvCompletion)
return VINF_SUCCESS;
#ifdef DEBUG_misha
Assert(0);
return VERR_NOT_SUPPORTED;
#ifdef DEBUG_misha
return rc;
typedef struct VDMA_VBVA_CTL_CYNC_COMPLETION
int rc;
static DECLCALLBACK(void) vboxVDMACrHgcmSubmitSyncCompletion(struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd, int rc, void *pvCompletion)
return rc;
rc = pVGAState->pDrv->pfnCrHgcmCtlSubmit(pVGAState->pDrv, pCtl, cbCtl, vboxVDMACrHgcmSubmitSyncCompletion, &Data);
return rc;
return rc;
return VINF_SUCCESS;
static DECLCALLBACK(uint8_t*) vboxVDMACrHgcmHandleEnableRemainingHostCommand(HVBOXCRCMDCTL_REMAINING_HOST_COMMAND hClient, uint32_t *pcbCtl, int prevCmdRc)
*pcbCtl = 0;
return NULL;
static DECLCALLBACK(void) vboxVDMACrHgcmNotifyTerminatingDoneCb(HVBOXCRCMDCTL_NOTIFY_TERMINATING hClient)
static DECLCALLBACK(int) vboxVDMACrHgcmNotifyTerminatingCb(HVBOXCRCMDCTL_NOTIFY_TERMINATING hClient, VBOXCRCMDCTL_HGCMENABLE_DATA *pHgcmEnableData)
return rc;
return VINF_SUCCESS;
return rc;
return VERR_INVALID_STATE;
if (!pVBVA)
return VERR_INVALID_PARAMETER;
#ifdef DEBUG_misha
return VERR_NOT_SUPPORTED;
return VINF_SUCCESS;
return rc;
return VINF_SUCCESS;
if (fDoHgcmEnable)
return VINF_SUCCESS;
return rc;
static int vboxVDMACrHostCtlProcess(struct VBOXVDMAHOST *pVdma, VBVAEXHOSTCTL *pCmd, bool *pfContinue)
*pfContinue = true;
return VERR_INVALID_STATE;
return rc;
return rc;
return rc;
*pfContinue = false;
return VINF_SUCCESS;
return rc;
int rc = VBoxVBVAExHSLoadState(&pVdma->CmdVbva, pu8VramBase, pCmd->u.state.pSSM, pCmd->u.state.u32Version);
return rc;
rc = pVdma->CrSrvInfo.pfnLoadState(pVdma->CrSrvInfo.hSvr, pCmd->u.state.pSSM, pCmd->u.state.u32Version);
return rc;
return VINF_SUCCESS;
return rc;
return rc;
return VINF_SUCCESS;
return VERR_INVALID_PARAMETER;
static int vboxVDMACrGuestCtlResizeEntryProcess(struct VBOXVDMAHOST *pVdma, VBOXCMDVBVA_RESIZE_ENTRY *pEntry)
bool fDisable = false;
fDisable = true;
return VERR_INVALID_PARAMETER;
else if (!fDisable)
return VERR_INVALID_PARAMETER;
View.u32MaxScreenSize = View.u32ViewSize + Screen.u32Width + 1; /* <- make VBVAInfoScreen logic (offEnd < pView->u32MaxScreenSize) happy */
return rc;
return rc;
switch (enmType)
return VERR_INVALID_STATE;
return VERR_INVALID_STATE;
return VERR_INVALID_PARAMETER;
if (!cElements)
return VERR_INVALID_PARAMETER;
return rc;
return rc;
return rc;
return VINF_SUCCESS;
return rc;
return VERR_INVALID_PARAMETER;
static int vboxVDMACrCmdVbvaProcessPagingEl(PPDMDEVINS pDevIns, VBOXCMDVBVAPAGEIDX iPage, uint8_t *pu8Vram, bool fIn)
int rc;
if (fIn)
const void * pvPage;
return rc;
void * pvPage;
return rc;
return VINF_SUCCESS;
static int vboxVDMACrCmdVbvaProcessPagingEls(PPDMDEVINS pDevIns, const VBOXCMDVBVAPAGEIDX *piPages, uint32_t cPages, uint8_t *pu8Vram, bool fIn)
return rc;
return VINF_SUCCESS;
static int8_t vboxVDMACrCmdVbvaPagingDataInit(PVGASTATE pVGAState, const VBOXCMDVBVA_HDR *pHdr, const VBOXCMDVBVA_PAGING_TRANSFER_DATA *pData, uint32_t cbCmd,
static int8_t vboxVDMACrCmdVbvaProcessCmdData(struct VBOXVDMAHOST *pVdma, const VBOXCMDVBVA_HDR *pCmd, uint32_t cbCmd)
bool fIn;
int8_t i8Result = vboxVDMACrCmdVbvaPagingDataInit(pVGAState, pCmd, &((VBOXCMDVBVA_PAGING_TRANSFER*)pCmd)->Data, cbCmd,
if (i8Result < 0)
return i8Result;
typedef struct VBOXCMDVBVA_PAGING_TRANSFER
static int8_t vboxVDMACrCmdVbvaProcess(struct VBOXVDMAHOST *pVdma, const VBOXCMDVBVA_HDR *pCmd, uint32_t cbCmd)
const void * pvCmd;
return i8Result;
const void *pvCurCmdTail;
bool fIn;
i8Result = vboxVDMACrCmdVbvaPagingDataInit(pVGAState, pRealCmdHdr, (const VBOXCMDVBVA_PAGING_TRANSFER_DATA*)pvCurCmdTail, cbRealCmd,
if (i8Result < 0)
if (!cPages)
return i8Result;
++pCmd;
if (i8Result < 0)
return i8Result;
if (!ASMAtomicCmpXchgU8(&pCmd->u8State, VBOXCMDVBVA_STATE_IN_PROGRESS, VBOXCMDVBVA_STATE_SUBMITTED))
if (pCmd)
return rc;
static int vboxVDMACmdExecBpbTransfer(PVBOXVDMAHOST pVdma, const PVBOXVDMACMD_DMA_BPB_TRANSFER pTransfer, uint32_t cbBuffer);
static int vboxVDMACmdCheckCrCmd(struct VBOXVDMAHOST *pVdma, PVBOXVDMACBUF_DR pCmdDr, uint32_t cbCmdDr)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
if (pDmaCmd)
return VERR_INVALID_PARAMETER;
Assert(0);
return VERR_INVALID_PARAMETER;
return rc;
int vboxVDMACrHgsmiCommandCompleteAsync(PPDMIDISPLAYVBVACALLBACKS pInterface, PVBOXVDMACMD_CHROMIUM_CMD pCmd, int rc)
return rc;
int vboxVDMACrHgsmiControlCompleteAsync(PPDMIDISPLAYVBVACALLBACKS pInterface, PVBOXVDMACMD_CHROMIUM_CTL pCmd, int rc)
return VINF_SUCCESS;
return VERR_INVALID_FUNCTION;
uint32_t offDstLineEnd = ((pDstRectl->left * pDstDesc->bpp + 7) >> 3) + ((pDstDesc->bpp * pDstRectl->width + 7) >> 3);
uint32_t offSrcLineEnd = ((pSrcRectl->left * pSrcDesc->bpp + 7) >> 3) + ((pSrcDesc->bpp * pSrcRectl->width + 7) >> 3);
for (uint32_t i = 0; ; ++i)
return VINF_SUCCESS;
static int vboxVDMACmdExecBlt(PVBOXVDMAHOST pVdma, const PVBOXVDMACMD_DMA_PRESENT_BLT pBlt, uint32_t cbBuffer)
const uint32_t cbBlt = VBOXVDMACMD_BODY_FIELD_OFFSET(uint32_t, VBOXVDMACMD_DMA_PRESENT_BLT, aDstSubRects[pBlt->cDstSubRects]);
return VERR_INVALID_FUNCTION;
return VERR_INVALID_FUNCTION;
return VERR_INVALID_FUNCTION;
return rc;
return rc;
return cbBlt;
static int vboxVDMACmdExecBpbTransfer(PVBOXVDMAHOST pVdma, const PVBOXVDMACMD_DMA_BPB_TRANSFER pTransfer, uint32_t cbBuffer)
return VERR_INVALID_PARAMETER;
const void * pvSrc;
void * pvDst;
bool bSrcLocked = false;
bool bDstLocked = false;
bSrcLocked = true;
bDstLocked = true;
if (bSrcLocked)
if (bDstLocked)
} while (cbTransfer);
return sizeof (*pTransfer);
return rc;
if (!pvBuffer)
return VERR_INVALID_PARAMETER;
return VERR_INVALID_PARAMETER;
#ifdef VBOXWDDM_TEST_UHGSMI
static int count = 0;
if (count==0)
++count;
return VINF_SUCCESS;
if (cbBlt >= 0)
return VINF_SUCCESS;
const PVBOXVDMACMD_DMA_BPB_TRANSFER pTransfer = VBOXVDMACMD_BODY(pCmd, VBOXVDMACMD_DMA_BPB_TRANSFER);
if (cbTransfer >= 0)
return VINF_SUCCESS;
case VBOXVDMACMD_TYPE_DMA_NOP:
return VINF_SUCCESS;
return VINF_SUCCESS;
return VERR_INVALID_FUNCTION;
return VERR_INVALID_STATE;
int rc;
switch (enmType)
case VBVAEXHOST_DATA_TYPE_CMD:
bool fContinue = true;
if (fContinue)
return VINF_SUCCESS;
int rc;
bool bReleaseLocked = false;
const void * pvPageBuf;
bReleaseLocked = true;
if (bReleaseLocked)
#ifdef VBOX_VDMA_WITH_WATCHDOG
if (cMillis)
return VINF_SUCCESS;
int rc;
if (pVdma)
#ifdef VBOX_VDMA_WITH_WATCHDOG
#ifdef VBOX_WITH_CRHGSMI
int rcIgnored = vboxVDMACrCtlHgsmiSetup(pVdma); NOREF(rcIgnored); /** @todo is this ignoring intentional? */
return VINF_SUCCESS;
return VINF_SUCCESS;
return rc;
#ifdef VBOX_WITH_CRHGSMI
return VINF_SUCCESS;
if (!pVdma)
return VINF_SUCCESS;
#ifdef VBOX_WITH_CRHGSMI
return VINF_SUCCESS;
case VBOXVDMA_CTL_TYPE_ENABLE:
case VBOXVDMA_CTL_TYPE_FLUSH:
#ifdef VBOX_VDMA_WITH_WATCHDOG
#ifdef VBOX_WITH_CRHGSMI
/* chromium commands are processed by crhomium hgcm thread independently from our internal cmd processing pipeline
#ifdef VBOX_WITH_CRHGSMI
static DECLCALLBACK(void) vdmaVBVACtlSubmitSyncCompletion(VBVAEXHOSTCONTEXT *pVbva, struct VBVAEXHOSTCTL *pCtl, int rc, void *pvContext);
static int vdmaVBVACtlSubmit(PVBOXVDMAHOST pVdma, VBVAEXHOSTCTL* pCtl, VBVAEXHOSTCTL_SOURCE enmSource, PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
return rc;
static DECLCALLBACK(void) vboxCmdVBVACmdCtlGuestCompletion(VBVAEXHOSTCONTEXT *pVbva, struct VBVAEXHOSTCTL *pCtl, int rc, void *pvContext)
static int vdmaVBVACtlGenericSubmit(PVBOXVDMAHOST pVdma, VBVAEXHOSTCTL_SOURCE enmSource, VBVAEXHOSTCTL_TYPE enmType, uint8_t* pu8Cmd, uint32_t cbCmd, PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
if (!pHCtl)
return VERR_NO_MEMORY;
return rc;;
return VINF_SUCCESS;
static int vdmaVBVACtlGenericGuestSubmit(PVBOXVDMAHOST pVdma, VBVAEXHOSTCTL_TYPE enmType, VBOXCMDVBVA_CTL *pCtl, uint32_t cbCtl)
int rc = vdmaVBVACtlGenericSubmit(pVdma, VBVAEXHOSTCTL_SOURCE_GUEST, enmType, (uint8_t*)(pCtl+1), cbCtl - sizeof (VBOXCMDVBVA_CTL), vboxCmdVBVACmdCtlGuestCompletion, pVdma);
return VINF_SUCCESS;
return VINF_SUCCESS;
static DECLCALLBACK(void) vboxCmdVBVACmdCtlHostCompletion(VBVAEXHOSTCONTEXT *pVbva, struct VBVAEXHOSTCTL *pCtl, int rc, void *pvCompletion)
static int vdmaVBVACtlOpaqueHostSubmit(PVBOXVDMAHOST pVdma, struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd,
void *pvCompletion)
int rc = vdmaVBVACtlGenericSubmit(pVdma, VBVAEXHOSTCTL_SOURCE_HOST, VBVAEXHOSTCTL_TYPE_GHH_BE_OPAQUE, (uint8_t*)pCmd, cbCmd, vboxCmdVBVACmdCtlHostCompletion, pvCompletion);
rc = pVGAState->pDrv->pfnCrHgcmCtlSubmit(pVGAState->pDrv, pCmd, cbCmd, pfnCompletion, pvCompletion);
return rc;
return rc;
return VINF_SUCCESS;
for (uint32_t j = 0; j < i; j++)
return rc;
return VINF_SUCCESS;
return VINF_SUCCESS;
static DECLCALLBACK(void) vdmaVBVACtlThreadCreatedEnable(struct VBOXVDMATHREAD *pThread, int rc, void *pvThreadContext, void *pvContext)
static int vdmaVBVACtlEnableSubmitInternal(PVBOXVDMAHOST pVdma, VBVAENABLE *pEnable, bool fPaused, PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
int rc;
VBVAEXHOSTCTL* pHCtl = VBoxVBVAExHCtlCreate(&pVdma->CmdVbva, fPaused ? VBVAEXHOSTCTL_TYPE_GHH_ENABLE_PAUSED : VBVAEXHOSTCTL_TYPE_GHH_ENABLE);
if (pHCtl)
rc = VBoxVDMAThreadCreate(&pVdma->Thread, vboxVDMAWorkerThread, pVdma, vdmaVBVACtlThreadCreatedEnable, pHCtl);
return VINF_SUCCESS;
return rc;
return rc;
rc = vdmaVBVACtlEnableSubmitInternal(pVdma, &Enable, fPaused, vdmaVBVACtlSubmitSyncCompletion, &Data);
return rc;
static int vdmaVBVACtlDisableSubmitInternal(PVBOXVDMAHOST pVdma, VBVAENABLE *pEnable, PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
int rc;
return VINF_SUCCESS;
if (!pHCtl)
return VERR_NO_MEMORY;
return VINF_SUCCESS;
return rc;
static int vdmaVBVACtlEnableDisableSubmitInternal(PVBOXVDMAHOST pVdma, VBVAENABLE *pEnable, PFNVBVAEXHOSTCTL_COMPLETE pfnComplete, void *pvComplete)
if (fEnable)
int rc = vdmaVBVACtlEnableDisableSubmitInternal(pVdma, &pEnable->Enable, vboxCmdVBVACmdCtlGuestCompletion, pVdma);
return VINF_SUCCESS;
return VINF_SUCCESS;
static DECLCALLBACK(void) vdmaVBVACtlSubmitSyncCompletion(VBVAEXHOSTCONTEXT *pVbva, struct VBVAEXHOSTCTL *pCtl, int rc, void *pvContext)
static int vdmaVBVACtlSubmitSync(PVBOXVDMAHOST pVdma, VBVAEXHOSTCTL* pCtl, VBVAEXHOSTCTL_SOURCE enmSource)
return rc;
return rc;
switch (rc)
case VINF_SUCCESS:
case VINF_ALREADY_INITIALIZED:
case VINF_EOF:
case VERR_INVALID_STATE:
return VINF_SUCCESS;
void *pvCompletion)
typedef struct VBOXCMDVBVA_CMDHOSTCTL_SYNC
int rc;
static DECLCALLBACK(void) vboxCmdVBVACmdHostCtlSyncCb(struct VBOXCRCMDCTL* pCmd, uint32_t cbCmd, int rc, void *pvCompletion)
return rc;
Assert(c >= 0);
return rc;
return VINF_SUCCESS;
return VERR_INVALID_STATE;
return VERR_INVALID_STATE;
#ifdef VBOX_WITH_CRHGSMI
return VINF_SUCCESS;
return rc;
#ifdef DEBUG_misha
if (pCmd)
return rc;
return VERR_NO_MEMORY;
return VINF_SUCCESS;
#ifdef VBOX_WITH_CRHGSMI
return VINF_SUCCESS;
return rc;
#ifdef DEBUG_misha
if (pCmd)
return rc;
return VERR_NO_MEMORY;
return VINF_SUCCESS;
int rc;
#ifdef VBOX_WITH_CRHGSMI
return VINF_SUCCESS;
#ifdef VBOX_WITH_CRHGSMI
#ifdef VBOX_WITH_CRHGSMI
return VINF_SUCCESS;
return VERR_VERSION_MISMATCH;
return VINF_SUCCESS;
#ifdef VBOX_WITH_CRHGSMI
return VINF_SUCCESS;
/** @todo r=bird: BTW. would be great if you put in a couple of comments here and there explaining what
if (!pHCtl)
return VERR_NO_MEMORY;
return rc;
return VINF_SUCCESS;