VBoxMPHGSMI.cpp revision 32b1164f35483be483177be7b5235002a4a5afbe
2N/A/* $Id$ */
2N/A
2N/A/** @file
2N/A * VBox Miniport HGSMI related functions
2N/A */
2N/A
2N/A/*
2N/A * Copyright (C) 2011-2012 Oracle Corporation
2N/A *
2N/A * This file is part of VirtualBox Open Source Edition (OSE), as
2N/A * available from http://www.virtualbox.org. This file is free software;
2N/A * you can redistribute it and/or modify it under the terms of the GNU
2N/A * General Public License (GPL) as published by the Free Software
2N/A * Foundation, in version 2 as it comes in the "COPYING" file of the
2N/A * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
2N/A * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
2N/A */
2N/A
2N/A#include "VBoxMPHGSMI.h"
2N/A#include "VBoxMPCommon.h"
2N/A#include <VBox/VMMDev.h>
2N/A#include <iprt/alloc.h>
2N/A
2N/Astatic DECLCALLBACK(void *) hgsmiEnvAlloc(void *pvEnv, HGSMISIZE cb)
2N/A{
2N/A NOREF(pvEnv);
2N/A return RTMemAlloc(cb);
2N/A}
2N/A
2N/Astatic DECLCALLBACK(void) hgsmiEnvFree(void *pvEnv, void *pv)
2N/A{
2N/A NOREF(pvEnv);
2N/A RTMemFree(pv);
2N/A}
2N/A
2N/Astatic HGSMIENV g_hgsmiEnvMP =
2N/A{
2N/A NULL,
2N/A hgsmiEnvAlloc,
2N/A hgsmiEnvFree
2N/A};
2N/A
2N/A/**
2N/A * Helper function to register secondary displays (DualView). Note that this will not
2N/A * be available on pre-XP versions, and some editions on XP will fail because they are
2N/A * intentionally crippled.
2N/A *
2N/A * HGSMI variant is a bit different because it uses only HGSMI interface (VBVA channel)
2N/A * to talk to the host.
2N/A */
2N/Avoid VBoxSetupDisplaysHGSMI(PVBOXMP_COMMON pCommon, PHYSICAL_ADDRESS phVRAM, uint32_t ulApertureSize,
2N/A uint32_t cbVRAM, uint32_t fCaps)
2N/A{
2N/A /** @todo I simply converted this from Windows error codes. That is wrong,
2N/A * but we currently freely mix and match those (failure == rc > 0) and iprt
2N/A * ones (failure == rc < 0) anyway. This needs to be fully reviewed and
2N/A * fixed. */
2N/A int rc = VINF_SUCCESS;
2N/A uint32_t offVRAMBaseMapping, cbMapping, offGuestHeapMemory, cbGuestHeapMemory,
2N/A offHostFlags, offVRAMHostArea, cbHostArea;
2N/A LOGF_ENTER();
2N/A
2N/A memset(pCommon, 0, sizeof(*pCommon));
2N/A pCommon->phVRAM = phVRAM;
2N/A pCommon->ulApertureSize = ulApertureSize;
2N/A pCommon->cbVRAM = cbVRAM;
2N/A pCommon->cDisplays = 1;
2N/A pCommon->bHGSMI = VBoxHGSMIIsSupported();
2N/A
2N/A if (pCommon->bHGSMI)
2N/A {
2N/A VBoxHGSMIGetBaseMappingInfo(pCommon->cbVRAM, &offVRAMBaseMapping,
2N/A &cbMapping, &offGuestHeapMemory,
2N/A &cbGuestHeapMemory, &offHostFlags);
2N/A
2N/A /* Map the adapter information. It will be needed for HGSMI IO. */
2N/A rc = VBoxMPCmnMapAdapterMemory(pCommon, &pCommon->pvAdapterInformation, offVRAMBaseMapping, cbMapping);
2N/A if (RT_FAILURE(rc))
2N/A {
2N/A LOG(("VBoxMPCmnMapAdapterMemory failed rc = %d", rc));
2N/A pCommon->bHGSMI = false;
2N/A }
2N/A else
2N/A {
2N/A /* Setup an HGSMI heap within the adapter information area. */
2N/A rc = VBoxHGSMISetupGuestContext(&pCommon->guestCtx,
2N/A pCommon->pvAdapterInformation,
2N/A cbGuestHeapMemory,
2N/A offVRAMBaseMapping
2N/A + offGuestHeapMemory,
2N/A &g_hgsmiEnvMP);
2N/A
2N/A if (RT_FAILURE(rc))
2N/A {
2N/A LOG(("HGSMIHeapSetup failed rc = %d", rc));
2N/A pCommon->bHGSMI = false;
2N/A }
2N/A }
2N/A }
2N/A
2N/A /* Setup the host heap and the adapter memory. */
2N/A if (pCommon->bHGSMI)
2N/A {
2N/A VBoxHGSMIGetHostAreaMapping(&pCommon->guestCtx, pCommon->cbVRAM,
2N/A offVRAMBaseMapping, &offVRAMHostArea,
2N/A &cbHostArea);
2N/A if (cbHostArea)
2N/A {
2N/A
2N/A /* Map the heap region.
2N/A *
2N/A * Note: the heap will be used for the host buffers submitted to the guest.
2N/A * The miniport driver is responsible for reading FIFO and notifying
2N/A * display drivers.
2N/A */
2N/A pCommon->cbMiniportHeap = cbHostArea;
2N/A rc = VBoxMPCmnMapAdapterMemory (pCommon, &pCommon->pvMiniportHeap,
2N/A offVRAMHostArea, cbHostArea);
2N/A if (RT_FAILURE(rc))
2N/A {
2N/A pCommon->pvMiniportHeap = NULL;
2N/A pCommon->cbMiniportHeap = 0;
2N/A pCommon->bHGSMI = false;
2N/A }
2N/A else
2N/A VBoxHGSMISetupHostContext(&pCommon->hostCtx,
2N/A pCommon->pvAdapterInformation,
2N/A offHostFlags,
2N/A pCommon->pvMiniportHeap,
2N/A offVRAMHostArea, cbHostArea);
2N/A }
2N/A else
2N/A {
2N/A /* Host has not requested a heap. */
2N/A pCommon->pvMiniportHeap = NULL;
2N/A pCommon->cbMiniportHeap = 0;
2N/A }
2N/A }
2N/A
2N/A if (pCommon->bHGSMI)
2N/A {
2N/A /* Setup the information for the host. */
2N/A rc = VBoxHGSMISendHostCtxInfo(&pCommon->guestCtx,
2N/A offVRAMBaseMapping + offHostFlags,
2N/A fCaps, offVRAMHostArea,
2N/A pCommon->cbMiniportHeap);
2N/A
2N/A if (RT_FAILURE(rc))
2N/A {
2N/A pCommon->bHGSMI = false;
2N/A }
2N/A }
2N/A
2N/A /* Check whether the guest supports multimonitors. */
2N/A if (pCommon->bHGSMI)
2N/A {
2N/A /* Query the configured number of displays. */
2N/A pCommon->cDisplays = VBoxHGSMIGetMonitorCount(&pCommon->guestCtx);
2N/A }
2N/A else
2N/A {
2N/A VBoxFreeDisplaysHGSMI(pCommon);
2N/A }
2N/A
2N/A LOGF_LEAVE();
2N/A}
2N/A
2N/Astatic bool VBoxUnmapAdpInfoCallback(void *pvCommon)
2N/A{
2N/A PVBOXMP_COMMON pCommon = (PVBOXMP_COMMON)pvCommon;
2N/A
2N/A pCommon->hostCtx.pfHostFlags = NULL;
2N/A return true;
2N/A}
2N/A
2N/Avoid VBoxFreeDisplaysHGSMI(PVBOXMP_COMMON pCommon)
2N/A{
2N/A VBoxMPCmnUnmapAdapterMemory(pCommon, &pCommon->pvMiniportHeap);
2N/A#ifdef VBOX_WDDM_MINIPORT
2N/A VBoxSHGSMITerm(&pCommon->guestCtx.heapCtx);
2N/A#else
2N/A HGSMIHeapDestroy(&pCommon->guestCtx.heapCtx);
2N/A#endif
2N/A
2N/A /* Unmap the adapter information needed for HGSMI IO. */
2N/A VBoxMPCmnSyncToVideoIRQ(pCommon, VBoxUnmapAdpInfoCallback, pCommon);
2N/A VBoxMPCmnUnmapAdapterMemory(pCommon, &pCommon->pvAdapterInformation);
2N/A}
2N/A