VirtualBox

Ignore:
Timestamp:
Nov 27, 2010 2:07:28 AM (14 years ago)
Author:
vboxsync
Message:

Additions/WINNT/Graphics and Additions/common/VBoxVideo: file forgotten from r68201

Location:
trunk/src/VBox/Additions/common/VBoxVideo
Files:
1 added
1 copied

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxVideo/HGSMIBase.cpp

    r34390 r34430  
    11/* $Id$ */
    22/** @file
    3  * VirtualBox Video miniport driver for NT/2k/XP - HGSMI related functions.
     3 * VirtualBox Video driver, common code - HGSMI initialisation and helper
     4 * functions.
    45 */
    56
    67/*
    7  * Copyright (C) 2006-2009 Oracle Corporation
     8 * Copyright (C) 2006-2010 Oracle Corporation
    89 *
    910 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1617 */
    1718
    18 #include <string.h>
    19 
    20 #include "VBoxVideo.h"
    21 #include "Helper.h"
     19#include <VBox/VBoxVideoGuest.h>
     20#include <VBox/VBoxVideo.h>
     21#include <VBox/VBoxGuest.h>
     22#include <VBox/Hardware/VBoxVideoVBE.h>
     23#include <VBox/VMMDev.h>
    2224
    2325#include <iprt/asm.h>
    2426#include <iprt/log.h>
    25 #include <iprt/thread.h>
    26 #include <VBox/VMMDev.h>
    27 #include <VBox/VBoxGuest.h>
    28 #include <VBox/VBoxVideo.h>
    29 
    30 // #include <VBoxDisplay.h>
    31 
    32 // #include "vboxioctl.h"
     27
     28#include <string.h>
    3329
    3430/** Send completion notification to the host for the command located at offset
    3531 * @a offt into the host command buffer. */
    36 void HGSMINotifyHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx, HGSMIOFFSET offt)
     32static void HGSMINotifyHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx, HGSMIOFFSET offt)
    3733{
    3834    VBoxVideoCmnPortWriteUlong(pCtx->port, offt);
    3935}
    4036
    41 /** Acknowlege an IRQ. */
    42 void HGSMIClearIrq(PHGSMIHOSTCOMMANDCONTEXT pCtx)
    43 {
    44     VBoxVideoCmnPortWriteUlong(pCtx->port, HGSMIOFFSET_VOID);
    45 }
    46 
    47 /** Inform the host that a command has been handled. */
    48 static void HGSMIHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx, void * pvMem)
     37
     38/**
     39 * Inform the host that a command has been handled.
     40 *
     41 * @param  pCtx   the context containing the heap to be used
     42 * @param  pvMem  pointer into the heap as mapped in @a pCtx to the command to
     43 *                be completed
     44 */
     45RTDECL(void) VBoxHGSMIHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx,
     46                                      void *pvMem)
    4947{
    5048    HGSMIBUFFERHEADER *pHdr = HGSMIBufferHeaderFromData(pvMem);
     
    5755}
    5856
     57
    5958/** Submit an incoming host command to the appropriate handler. */
    6059static void hgsmiHostCmdProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx,
     
    7877}
    7978
     79
    8080/** Get and handle the next command from the host. */
    8181static void hgsmiHostCommandQueryProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx)
     
    8686}
    8787
     88
    8889/** Drain the host command queue. */
    89 void hgsmiProcessHostCommandQueue(PHGSMIHOSTCOMMANDCONTEXT pCtx)
     90RTDECL(void) VBoxHGSMIProcessHostQueue(PHGSMIHOSTCOMMANDCONTEXT pCtx)
    9091{
    9192    while (pCtx->pfHostFlags->u32HostFlags & HGSMIHOSTFLAGS_COMMANDS_PENDING)
     
    9899}
    99100
     101
    100102/** Detect whether HGSMI is supported by the host. */
    101 bool VBoxHGSMIIsSupported (void)
     103RTDECL(bool) VBoxHGSMIIsSupported(void)
    102104{
    103105    uint16_t DispiId;
     
    112114
    113115
    114 void* vboxHGSMIBufferAlloc(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    115                          HGSMISIZE cbData,
    116                          uint8_t u8Ch,
    117                          uint16_t u16Op)
     116/**
     117 * Allocate and initialise a command descriptor in the guest heap for a
     118 * guest-to-host command.
     119 *
     120 * @returns  pointer to the descriptor's command data buffer
     121 * @param  pCtx     the context containing the heap to be used
     122 * @param  cbData   the size of the command data to go into the descriptor
     123 * @param  u8Ch     the HGSMI channel to be used, set to the descriptor
     124 * @param  u16Op    the HGSMI command to be sent, set to the descriptor
     125 */
     126RTDECL(void *) VBoxHGSMIBufferAlloc(PHGSMIGUESTCOMMANDCONTEXT pCtx,
     127                                    HGSMISIZE cbData,
     128                                    uint8_t u8Ch,
     129                                    uint16_t u16Op)
    118130{
    119131#ifdef VBOX_WITH_WDDM
     
    123135}
    124136
    125 void vboxHGSMIBufferFree(PHGSMIGUESTCOMMANDCONTEXT pCtx, void *pvBuffer)
     137
     138/**
     139 * Free a descriptor allocated by @a VBoxHGSMIBufferAlloc.
     140 *
     141 * @param  pCtx      the context containing the heap used
     142 * @param  pvBuffer  the pointer returned by @a VBoxHGSMIBufferAlloc
     143 */
     144RTDECL(void) VBoxHGSMIBufferFree(PHGSMIGUESTCOMMANDCONTEXT pCtx,
     145                                 void *pvBuffer)
    126146{
    127147#ifdef VBOX_WITH_WDDM
     
    131151}
    132152
    133 int vboxHGSMIBufferSubmit(PHGSMIGUESTCOMMANDCONTEXT pCtx, void *pvBuffer)
     153
     154/**
     155 * Submit a command descriptor allocated by @a VBoxHGSMIBufferAlloc.
     156 *
     157 * @param  pCtx      the context containing the heap used
     158 * @param  pvBuffer  the pointer returned by @a VBoxHGSMIBufferAlloc
     159 */
     160RTDECL(int) VBoxHGSMIBufferSubmit(PHGSMIGUESTCOMMANDCONTEXT pCtx,
     161                                  void *pvBuffer)
    134162{
    135163    /* Initialize the buffer and get the offset for port IO. */
     
    148176
    149177
     178/** Query the host for an HGSMI configuration parameter via an HGSMI command.
     179 */
    150180static int vboxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t u32Index,
    151181                              uint32_t *pulValue)
     
    164194        p->u32Index = u32Index;
    165195        p->u32Value = 0;
    166         rc = vboxHGSMIBufferSubmit(pCtx, p);
     196        rc = VBoxHGSMIBufferSubmit(pCtx, p);
    167197        if (RT_SUCCESS(rc))
    168198        {
     
    180210
    181211
    182 static int vboxHGSMIBufferLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    183                                    HGSMIOFFSET offLocation)
     212/** Inform the host of the location of the host flags in VRAM via an HGSMI
     213 * command. */
     214static int vboxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx,
     215                                        HGSMIOFFSET offLocation)
    184216{
    185217    HGSMIBUFFERLOCATION *p;
     
    196228        p->offLocation = offLocation;
    197229        p->cbLocation  = sizeof(HGSMIHOSTFLAGS);
    198         rc = vboxHGSMIBufferSubmit(pCtx, p);
     230        rc = VBoxHGSMIBufferSubmit(pCtx, p);
    199231        /* Free the IO buffer. */
    200232        HGSMIHeapFree (&pCtx->heapCtx, p);
     
    206238
    207239
     240/** Notify the host of HGSMI-related guest capabilities via an HGSMI command.
     241 */
    208242static int vboxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    209243                                 uint32_t fCaps)
     
    222256        pCaps->rc    = VERR_NOT_IMPLEMENTED;
    223257        pCaps->fCaps = fCaps;
    224         rc = vboxHGSMIBufferSubmit(pCtx, pCaps);
     258        rc = VBoxHGSMIBufferSubmit(pCtx, pCaps);
    225259        if (RT_SUCCESS(rc))
    226260        {
     
    237271
    238272
    239 static int vboxVBVAInitInfoHeap(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    240                                 uint32_t u32HeapOffset, uint32_t u32HeapSize)
     273/** Tell the host about the location of the area of VRAM set aside for the host
     274 * heap. */
     275static int vboxHGSMIReportHostArea(PHGSMIGUESTCOMMANDCONTEXT pCtx,
     276                                   uint32_t u32AreaOffset, uint32_t u32AreaSize)
    241277{
    242278    VBVAINFOHEAP *p;
     
    250286    {
    251287        /* Prepare data to be sent to the host. */
    252         p->u32HeapOffset = u32HeapOffset;
    253         p->u32HeapSize   = u32HeapSize;
    254         rc = vboxHGSMIBufferSubmit(pCtx, p);
     288        p->u32HeapOffset = u32AreaOffset;
     289        p->u32HeapSize   = u32AreaSize;
     290        rc = VBoxHGSMIBufferSubmit(pCtx, p);
    255291        /* Free the IO buffer. */
    256292        HGSMIHeapFree(&pCtx->heapCtx, p);
     
    262298
    263299
    264 int VBoxHGSMISendViewInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t u32Count,
    265                           PFNHGSMIFILLVIEWINFO pfnFill, void *pvData)
     300/**
     301 * Tell the host about how VRAM is divided up between each screen via an HGSMI
     302 * command.  It is acceptable to specifiy identical data for each screen if
     303 * they share a single framebuffer.
     304 * @todo confirm that that really is acceptable
     305 *
     306 * @returns iprt status code, either VERR_NO_MEMORY or the status returned by
     307 *          @a pfnFill
     308 * @param  pCtx      the context containing the heap to use
     309 * @param  u32Count  the number of screens we are activating
     310 * @param  pfnFill   a callback which initialises the VBVAINFOVIEW structures
     311 *                   for all screens
     312 * @param  pvData    context data for @a pfnFill
     313 */
     314RTDECL(int) VBoxHGSMISendViewInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
     315                                  uint32_t u32Count,
     316                                  PFNHGSMIFILLVIEWINFO pfnFill,
     317                                  void *pvData)
    266318{
    267319    int rc;
    268320    /* Issue the screen info command. */
    269     void *p = vboxHGSMIBufferAlloc(pCtx, sizeof(VBVAINFOVIEW) * u32Count,
     321    void *p = VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVAINFOVIEW) * u32Count,
    270322                                   HGSMI_CH_VBVA, VBVA_INFO_VIEW);
    271323    if (p)
     
    274326        rc = pfnFill(pvData, pInfo);
    275327        if (RT_SUCCESS(rc))
    276             vboxHGSMIBufferSubmit (pCtx, p);
    277         vboxHGSMIBufferFree(pCtx, p);
     328            VBoxHGSMIBufferSubmit (pCtx, p);
     329        VBoxHGSMIBufferFree(pCtx, p);
    278330    }
    279331    else
     
    298350 *                              of the host flags
    299351 */
    300 void vboxHGSMIGetBaseMappingInfo(uint32_t cbVRAM,
    301                                  uint32_t *poffVRAMBaseMapping,
    302                                  uint32_t *pcbMapping,
    303                                  uint32_t *poffGuestHeapMemory,
    304                                  uint32_t *pcbGuestHeapMemory,
    305                                  uint32_t *poffHostFlags)
     352RTDECL(void) VBoxHGSMIGetBaseMappingInfo(uint32_t cbVRAM,
     353                                         uint32_t *poffVRAMBaseMapping,
     354                                         uint32_t *pcbMapping,
     355                                         uint32_t *poffGuestHeapMemory,
     356                                         uint32_t *pcbGuestHeapMemory,
     357                                         uint32_t *poffHostFlags)
    306358{
    307359    AssertPtrReturnVoid(poffVRAMBaseMapping);
     
    328380 *                                 @a pvGuestHeapMemory within the video RAM
    329381 */
    330 int vboxHGSMISetupGuestContext(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    331                                void *pvGuestHeapMemory,
    332                                uint32_t cbGuestHeapMemory,
    333                                uint32_t offVRAMGuestHeapMemory)
     382RTDECL(int) VBoxHGSMISetupGuestContext(PHGSMIGUESTCOMMANDCONTEXT pCtx,
     383                                       void *pvGuestHeapMemory,
     384                                       uint32_t cbGuestHeapMemory,
     385                                       uint32_t offVRAMGuestHeapMemory)
    334386{
    335387    /** @todo should we be using a fixed ISA port value here? */
     
    345397 * requests.
    346398 *
    347  * @param  pCtx                the guest context used to query the host
     399 * @param  pCtx                the context containing the heap to use
    348400 * @param  cbVRAM              how much video RAM is allocated to the device
    349401 * @param  offVRAMBaseMapping  the offset of the basic communication structures
    350402 *                             into the guest's VRAM
    351  * @param  poffVRAMHostArea    where to store the offset of the host area into
    352  *                             the guest's VRAM
    353  * @param  pcbHostArea         where to store the size of the host area
    354  */
    355 void vboxHGSMIGetHostAreaMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    356                                  uint32_t cbVRAM, uint32_t offVRAMBaseMapping,
    357                                  uint32_t *poffVRAMHostArea,
    358                                  uint32_t *pcbHostArea)
     403 * @param  poffVRAMHostArea    where to store the offset into VRAM of the host
     404 *                             heap area
     405 * @param  pcbHostArea         where to store the size of the host heap area
     406 */
     407RTDECL(void) VBoxHGSMIGetHostAreaMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx,
     408                                         uint32_t cbVRAM,
     409                                         uint32_t offVRAMBaseMapping,
     410                                         uint32_t *poffVRAMHostArea,
     411                                         uint32_t *pcbHostArea)
    359412{
    360413    uint32_t offVRAMHostArea = offVRAMBaseMapping, cbHostArea = 0;
     
    387440
    388441
    389 /** Initialise the host context structure. */
    390 void vboxHGSMISetupHostContext(PHGSMIHOSTCOMMANDCONTEXT pCtx,
    391                                void *pvBaseMapping, uint32_t offHostFlags,
    392                                void *pvHostAreaMapping,
    393                                uint32_t offVRAMHostArea, uint32_t cbHostArea)
     442/**
     443 * Initialise the host context structure.
     444 *
     445 * @param  pCtx               the context structure to initialise
     446 * @param  pvBaseMapping      where the basic HGSMI structures are mapped at
     447 * @param  offHostFlags       the offset of the host flags into the basic HGSMI
     448 *                            structures
     449 * @param  pvHostAreaMapping  where the area for the host heap is mapped at
     450 * @param  offVRAMHostArea    offset of the host heap area into VRAM
     451 * @param  cbHostArea         size in bytes of the host heap area
     452 */
     453RTDECL(void) VBoxHGSMISetupHostContext(PHGSMIHOSTCOMMANDCONTEXT pCtx,
     454                                       void *pvBaseMapping,
     455                                       uint32_t offHostFlags,
     456                                       void *pvHostAreaMapping,
     457                                       uint32_t offVRAMHostArea,
     458                                       uint32_t cbHostArea)
    394459{
    395460    uint8_t *pu8HostFlags = ((uint8_t *)pvBaseMapping) + offHostFlags;
     
    403468
    404469/**
    405  * Mirror the information in the host context structure to the host.
    406  */
    407 static int vboxHGSMISendHostCtxInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    408                                     HGSMIOFFSET offBufferLocation,
    409                                     uint32_t fCaps, uint32_t u32HeapOffset,
    410                                     uint32_t u32HeapSize)
     470 * Tell the host about the ways it can use to communicate back to us via an
     471 * HGSMI command
     472 *
     473 * @returns  iprt status value
     474 * @param  pCtx                  the context containing the heap to use
     475 * @param  offVRAMFlagsLocation  where we wish the host to place its flags
     476 *                               relative to the start of the VRAM
     477 * @param  fCaps                 additions HGSMI capabilities the guest
     478 *                               supports
     479 * @param  offVRAMHostArea       offset into VRAM of the host heap area
     480 * @param  cbHostArea            size in bytes of the host heap area
     481 */
     482RTDECL(int) VBoxHGSMISendHostCtxInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
     483                                     HGSMIOFFSET offVRAMFlagsLocation,
     484                                     uint32_t fCaps,
     485                                     uint32_t offVRAMHostArea,
     486                                     uint32_t cbHostArea)
    411487{
    412488    Log(("VBoxVideo::vboxSetupAdapterInfo\n"));
     
    414490    /* setup the flags first to ensure they are initialized by the time the
    415491     * host heap is ready */
    416     int rc = vboxHGSMIBufferLocation(pCtx, offBufferLocation);
     492    int rc = vboxHGSMIReportFlagsLocation(pCtx, offVRAMFlagsLocation);
    417493    AssertRC(rc);
    418494    if (RT_SUCCESS(rc) && fCaps)
     
    425501    {
    426502        /* Report the host heap location. */
    427         rc = vboxVBVAInitInfoHeap(pCtx, u32HeapOffset, u32HeapSize);
     503        rc = vboxHGSMIReportHostArea(pCtx, offVRAMHostArea, cbHostArea);
    428504        AssertRC(rc);
    429505    }
     
    434510
    435511/**
    436  * Returns the count of virtual monitors attached to the guest.  Returns
    437  * 1 on failure.
    438  */
    439 unsigned vboxHGSMIGetMonitorCount(PHGSMIGUESTCOMMANDCONTEXT pCtx)
     512 * Gets the count of virtual monitors attached to the guest via an HGSMI
     513 * command
     514 *
     515 * @returns the right count on success or 1 on failure.
     516 * @param  pCtx  the context containing the heap to use
     517 */
     518RTDECL(uint32_t) VBoxHGSMIGetMonitorCount(PHGSMIGUESTCOMMANDCONTEXT pCtx)
    440519{
    441520    /* Query the configured number of displays. */
     
    451530
    452531/**
    453  * Helper function to register secondary displays (DualView). Note that this will not
    454  * be available on pre-XP versions, and some editions on XP will fail because they are
    455  * intentionally crippled.
    456  *
    457  * HGSMI variant is a bit different because it uses only HGSMI interface (VBVA channel)
    458  * to talk to the host.
    459  */
    460 void VBoxSetupDisplaysHGSMI(PVBOXVIDEO_COMMON pCommon,
    461                             uint32_t AdapterMemorySize, uint32_t fCaps)
    462 {
    463     /** @todo I simply converted this from Windows error codes.  That is wrong,
    464      * but we currently freely mix and match those (failure == rc > 0) and iprt
    465      * ones (failure == rc < 0) anyway.  This needs to be fully reviewed and
    466      * fixed. */
    467     int rc = VINF_SUCCESS;
    468     uint32_t offVRAMBaseMapping, cbMapping, offGuestHeapMemory, cbGuestHeapMemory,
    469              offHostFlags, offVRAMHostArea, cbHostArea;
    470     Log(("VBoxVideo::VBoxSetupDisplays: pCommon = %p\n", pCommon));
    471 
    472     memset(pCommon, 0, sizeof(*pCommon));
    473     pCommon->cbVRAM    = AdapterMemorySize;
    474     pCommon->cDisplays = 1;
    475     pCommon->bHGSMI    = VBoxHGSMIIsSupported ();
    476     /* Why does this use VBoxVideoCmnMemZero?  The MSDN docs say that it should
    477      * only be used on mapped display adapter memory.  Done with memset above. */
    478     // VBoxVideoCmnMemZero(&pCommon->areaHostHeap, sizeof(HGSMIAREA));
    479     if (pCommon->bHGSMI)
    480     {
    481         vboxHGSMIGetBaseMappingInfo(pCommon->cbVRAM, &offVRAMBaseMapping,
    482                                     &cbMapping, &offGuestHeapMemory,
    483                                     &cbGuestHeapMemory, &offHostFlags);
    484 
    485         /* Map the adapter information. It will be needed for HGSMI IO. */
    486         /** @todo all callers of VBoxMapAdapterMemory expect it to use iprt
    487          * error codes, but it doesn't. */
    488         rc = VBoxMapAdapterMemory (pCommon, &pCommon->pvAdapterInformation,
    489                                    offVRAMBaseMapping, cbMapping);
    490         if (RT_FAILURE(rc))
    491         {
    492             Log(("VBoxVideo::VBoxSetupDisplays: VBoxMapAdapterMemory pvAdapterInfoirrmation failed rc = %d\n",
    493                      rc));
    494 
    495             pCommon->bHGSMI = false;
    496         }
    497         else
    498         {
    499             /* Setup an HGSMI heap within the adapter information area. */
    500             rc = vboxHGSMISetupGuestContext(&pCommon->guestCtx,
    501                                             pCommon->pvAdapterInformation,
    502                                             cbGuestHeapMemory,
    503                                               offVRAMBaseMapping
    504                                             + offGuestHeapMemory);
    505 
    506             if (RT_FAILURE(rc))
    507             {
    508                 Log(("VBoxVideo::VBoxSetupDisplays: HGSMIHeapSetup failed rc = %d\n",
    509                          rc));
    510 
    511                 pCommon->bHGSMI = false;
    512             }
    513         }
    514     }
    515 
    516     /* Setup the host heap and the adapter memory. */
    517     if (pCommon->bHGSMI)
    518     {
    519         vboxHGSMIGetHostAreaMapping(&pCommon->guestCtx, pCommon->cbVRAM,
    520                                     offVRAMBaseMapping, &offVRAMHostArea,
    521                                     &cbHostArea);
    522         if (cbHostArea)
    523         {
    524 
    525             /* Map the heap region.
    526              *
    527              * Note: the heap will be used for the host buffers submitted to the guest.
    528              *       The miniport driver is responsible for reading FIFO and notifying
    529              *       display drivers.
    530              */
    531             pCommon->cbMiniportHeap = cbHostArea;
    532             rc = VBoxMapAdapterMemory (pCommon, &pCommon->pvMiniportHeap,
    533                                        offVRAMHostArea, cbHostArea);
    534             if (RT_FAILURE(rc))
    535             {
    536                 pCommon->pvMiniportHeap = NULL;
    537                 pCommon->cbMiniportHeap = 0;
    538                 pCommon->bHGSMI = false;
    539             }
    540             else
    541                 vboxHGSMISetupHostContext(&pCommon->hostCtx,
    542                                           pCommon->pvAdapterInformation,
    543                                           offHostFlags,
    544                                           pCommon->pvMiniportHeap,
    545                                           offVRAMHostArea, cbHostArea);
    546         }
    547         else
    548         {
    549             /* Host has not requested a heap. */
    550             pCommon->pvMiniportHeap = NULL;
    551             pCommon->cbMiniportHeap = 0;
    552         }
    553     }
    554 
    555     if (pCommon->bHGSMI)
    556     {
    557         /* Setup the information for the host. */
    558         rc = vboxHGSMISendHostCtxInfo(&pCommon->guestCtx,
    559                                       offVRAMBaseMapping + offHostFlags,
    560                                       fCaps, offVRAMHostArea,
    561                                       pCommon->cbMiniportHeap);
    562 
    563         if (RT_FAILURE(rc))
    564         {
    565             pCommon->bHGSMI = false;
    566         }
    567     }
    568 
    569     /* Check whether the guest supports multimonitors. */
    570     if (pCommon->bHGSMI)
    571         /* Query the configured number of displays. */
    572         pCommon->cDisplays = vboxHGSMIGetMonitorCount(&pCommon->guestCtx);
    573 
    574     if (!pCommon->bHGSMI)
    575         VBoxFreeDisplaysHGSMI(pCommon);
    576 
    577     Log(("VBoxVideo::VBoxSetupDisplays: finished\n"));
    578 }
    579 
    580 static bool VBoxUnmapAdpInfoCallback(void *pvCommon)
    581 {
    582     PVBOXVIDEO_COMMON pCommon = (PVBOXVIDEO_COMMON)pvCommon;
    583 
    584     pCommon->hostCtx.pfHostFlags = NULL;
    585     return true;
    586 }
    587 
    588 void VBoxFreeDisplaysHGSMI(PVBOXVIDEO_COMMON pCommon)
    589 {
    590     VBoxUnmapAdapterMemory(pCommon, &pCommon->pvMiniportHeap);
    591     HGSMIHeapDestroy(&pCommon->guestCtx.heapCtx);
    592 
    593     /* Unmap the adapter information needed for HGSMI IO. */
    594     VBoxSyncToVideoIRQ(pCommon, VBoxUnmapAdpInfoCallback, pCommon);
    595     VBoxUnmapAdapterMemory(pCommon, &pCommon->pvAdapterInformation);
    596 }
    597 
    598 
    599 bool vboxUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    600                             uint32_t fFlags,
    601                             uint32_t cHotX,
    602                             uint32_t cHotY,
    603                             uint32_t cWidth,
    604                             uint32_t cHeight,
    605                             uint8_t *pPixels,
    606                             uint32_t cbLength)
     532 * Pass the host a new mouse pointer shape via an HGSMI command.
     533 *
     534 * @returns  success or failure
     535 * @todo  why not return an iprt status code?
     536 * @param  fFlags    cursor flags, @see VMMDevReqMousePointer::fFlags
     537 * @param  cHotX     horizontal position of the hot spot
     538 * @param  cHotY     vertical position of the hot spot
     539 * @param  cWidth    width in pixels of the cursor
     540 * @param  cHeight   height in pixels of the cursor
     541 * @param  pPixels   pixel data, @see VMMDevReqMousePointer for the format
     542 * @param  cbLength  size in bytes of the pixel data
     543 */
     544RTDECL(bool) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
     545                                         uint32_t fFlags,
     546                                         uint32_t cHotX,
     547                                         uint32_t cHotY,
     548                                         uint32_t cWidth,
     549                                         uint32_t cHeight,
     550                                         uint8_t *pPixels,
     551                                         uint32_t cbLength)
    607552{
    608553    VBVAMOUSEPOINTERSHAPE *p;
     
    649594            /* Copy the actual pointer data. */
    650595            memcpy (p->au8Data, pPixels, cbData);
    651         rc = vboxHGSMIBufferSubmit(pCtx, p);
     596        rc = VBoxHGSMIBufferSubmit(pCtx, p);
    652597        if (RT_SUCCESS(rc))
    653598            rc = p->i32Result;
     
    663608}
    664609
    665 #ifndef VBOX_WITH_WDDM
    666 typedef struct _VBVAMINIPORT_CHANNELCONTEXT
    667 {
    668     PFNHGSMICHANNELHANDLER pfnChannelHandler;
    669     void *pvChannelHandler;
    670 }VBVAMINIPORT_CHANNELCONTEXT;
    671 
    672 typedef struct _VBVADISP_CHANNELCONTEXT
    673 {
    674     /** The generic command handler builds up a list of commands - in reverse
    675      * order! - here */
    676     VBVAHOSTCMD *pCmd;
    677     bool bValid;
    678 }VBVADISP_CHANNELCONTEXT;
    679 
    680 typedef struct _VBVA_CHANNELCONTEXTS
    681 {
    682     PVBOXVIDEO_COMMON pCommon;
    683     uint32_t cUsed;
    684     uint32_t cContexts;
    685     VBVAMINIPORT_CHANNELCONTEXT mpContext;
    686     VBVADISP_CHANNELCONTEXT aContexts[1];
    687 }VBVA_CHANNELCONTEXTS;
    688 
    689 static int vboxVBVADeleteChannelContexts(PVBOXVIDEO_COMMON pCommon,
    690                                          VBVA_CHANNELCONTEXTS * pContext)
    691 {
    692     VBoxVideoCmnMemFreeDriver(pCommon, pContext);
    693     return VINF_SUCCESS;
    694 }
    695 
    696 static int vboxVBVACreateChannelContexts(PVBOXVIDEO_COMMON pCommon, VBVA_CHANNELCONTEXTS ** ppContext)
    697 {
    698     uint32_t cDisplays = (uint32_t)pCommon->cDisplays;
    699     const size_t size = RT_OFFSETOF(VBVA_CHANNELCONTEXTS, aContexts[cDisplays]);
    700     VBVA_CHANNELCONTEXTS * pContext = (VBVA_CHANNELCONTEXTS*)VBoxVideoCmnMemAllocDriver(pCommon, size);
    701     if(pContext)
    702     {
    703         memset(pContext, 0, size);
    704         pContext->cContexts = cDisplays;
    705         pContext->pCommon = pCommon;
    706         *ppContext = pContext;
    707         return VINF_SUCCESS;
    708     }
    709     return VERR_GENERAL_FAILURE;
    710 }
    711 
    712 static VBVADISP_CHANNELCONTEXT* vboxVBVAFindHandlerInfo(VBVA_CHANNELCONTEXTS *pCallbacks, int iId)
    713 {
    714     if(iId < 0)
    715     {
    716         return NULL;
    717     }
    718     else if(pCallbacks->cContexts > (uint32_t)iId)
    719     {
    720         return &pCallbacks->aContexts[iId];
    721     }
    722     return NULL;
    723 }
    724 
    725 DECLCALLBACK(void) hgsmiHostCmdComplete (HVBOXVIDEOHGSMI hHGSMI, struct _VBVAHOSTCMD * pCmd)
    726 {
    727     PHGSMIHOSTCOMMANDCONTEXT pCtx = &((PVBOXVIDEO_COMMON)hHGSMI)->hostCtx;
    728     HGSMIHostCmdComplete(pCtx, pCmd);
    729 }
    730 
    731 /** Reverses a NULL-terminated linked list of VBVAHOSTCMD structures. */
    732 static VBVAHOSTCMD *vboxVBVAReverseList(VBVAHOSTCMD *pList)
    733 {
    734     VBVAHOSTCMD *pFirst = NULL;
    735     while (pList)
    736     {
    737         VBVAHOSTCMD *pNext = pList;
    738         pList = pList->u.pNext;
    739         pNext->u.pNext = pFirst;
    740         pFirst = pNext;
    741     }
    742     return pFirst;
    743 }
    744 
    745 DECLCALLBACK(int) hgsmiHostCmdRequest (HVBOXVIDEOHGSMI hHGSMI, uint8_t u8Channel, uint32_t iDevice, struct _VBVAHOSTCMD ** ppCmd)
    746 {
    747 //    if(display < 0)
    748 //        return VERR_INVALID_PARAMETER;
    749     if(!ppCmd)
    750         return VERR_INVALID_PARAMETER;
    751 
    752     PHGSMIHOSTCOMMANDCONTEXT pCtx = &((PVBOXVIDEO_COMMON)hHGSMI)->hostCtx;
    753 
    754     /* pick up the host commands */
    755     hgsmiProcessHostCommandQueue(pCtx);
    756 
    757     HGSMICHANNEL *pChannel = HGSMIChannelFindById (&pCtx->channels, u8Channel);
    758     if(pChannel)
    759     {
    760         VBVA_CHANNELCONTEXTS * pContexts = (VBVA_CHANNELCONTEXTS *)pChannel->handler.pvHandler;
    761         VBVADISP_CHANNELCONTEXT *pDispContext = vboxVBVAFindHandlerInfo(pContexts, iDevice);
    762         Assert(pDispContext);
    763         if(pDispContext)
    764         {
    765             VBVAHOSTCMD *pCmd;
    766             do
    767                 pCmd = ASMAtomicReadPtrT(&pDispContext->pCmd, VBVAHOSTCMD *);
    768             while (!ASMAtomicCmpXchgPtr(&pDispContext->pCmd, NULL, pCmd));
    769             *ppCmd = vboxVBVAReverseList(pCmd);
    770 
    771             return VINF_SUCCESS;
    772         }
    773     }
    774 
    775     return VERR_INVALID_PARAMETER;
    776 }
    777 
    778 
    779 static DECLCALLBACK(int) vboxVBVAChannelGenericHandler(void *pvHandler, uint16_t u16ChannelInfo, void *pvBuffer, HGSMISIZE cbBuffer)
    780 {
    781     VBVA_CHANNELCONTEXTS *pCallbacks = (VBVA_CHANNELCONTEXTS*)pvHandler;
    782 //    Assert(0);
    783     Assert(cbBuffer > VBVAHOSTCMD_HDRSIZE);
    784     if(cbBuffer > VBVAHOSTCMD_HDRSIZE)
    785     {
    786         VBVAHOSTCMD *pHdr = (VBVAHOSTCMD*)pvBuffer;
    787         Assert(pHdr->iDstID >= 0);
    788         if(pHdr->iDstID >= 0)
    789         {
    790             VBVADISP_CHANNELCONTEXT* pHandler = vboxVBVAFindHandlerInfo(pCallbacks, pHdr->iDstID);
    791             Assert(pHandler && pHandler->bValid);
    792             if(pHandler && pHandler->bValid)
    793             {
    794                 VBVAHOSTCMD *pFirst = NULL, *pLast = NULL;
    795                 for(VBVAHOSTCMD *pCur = pHdr; pCur; )
    796                 {
    797                     Assert(!pCur->u.Data);
    798                     Assert(!pFirst);
    799                     Assert(!pLast);
    800 
    801                     switch(u16ChannelInfo)
    802                     {
    803                         case VBVAHG_DISPLAY_CUSTOM:
    804                         {
    805 #if 0  /* Never taken */
    806                             if(pLast)
    807                             {
    808                                 pLast->u.pNext = pCur;
    809                                 pLast = pCur;
    810                             }
    811                             else
    812 #endif
    813                             {
    814                                 pFirst = pCur;
    815                                 pLast = pCur;
    816                             }
    817                             Assert(!pCur->u.Data);
    818 #if 0  /* Who is supposed to set pNext? */
    819                             //TODO: use offset here
    820                             pCur = pCur->u.pNext;
    821                             Assert(!pCur);
    822 #else
    823                             Assert(!pCur->u.pNext);
    824                             pCur = NULL;
    825 #endif
    826                             Assert(pFirst);
    827                             Assert(pFirst == pLast);
    828                             break;
    829                         }
    830                         case VBVAHG_EVENT:
    831                         {
    832                             VBVAHOSTCMDEVENT *pEventCmd = VBVAHOSTCMD_BODY(pCur, VBVAHOSTCMDEVENT);
    833                             VBoxVideoCmnSignalEvent(pCallbacks->pCommon, pEventCmd->pEvent);
    834                         }
    835                         default:
    836                         {
    837                             Assert(u16ChannelInfo==VBVAHG_EVENT);
    838                             Assert(!pCur->u.Data);
    839 #if 0  /* pLast has been asserted to be NULL, and who should set pNext? */
    840                             //TODO: use offset here
    841                             if(pLast)
    842                                 pLast->u.pNext = pCur->u.pNext;
    843                             VBVAHOSTCMD * pNext = pCur->u.pNext;
    844                             pCur->u.pNext = NULL;
    845 #else
    846                             Assert(!pCur->u.pNext);
    847 #endif
    848                             HGSMIHostCmdComplete(&pCallbacks->pCommon->hostCtx, pCur);
    849 #if 0  /* pNext is NULL, and the other things have already been asserted */
    850                             pCur = pNext;
    851                             Assert(!pCur);
    852                             Assert(!pFirst);
    853                             Assert(pFirst == pLast);
    854 #else
    855                             pCur = NULL;
    856 #endif
    857                             break;
    858                         }
    859                     }
    860                 }
    861 
    862                 /* we do not support lists currently */
    863                 Assert(pFirst == pLast);
    864                 if(pLast)
    865                 {
    866                     Assert(pLast->u.pNext == NULL);
    867                 }
    868 
    869                 if(pFirst)
    870                 {
    871                     Assert(pLast);
    872                     VBVAHOSTCMD *pCmd;
    873                     do
    874                     {
    875                         pCmd = ASMAtomicReadPtrT(&pHandler->pCmd, VBVAHOSTCMD *);
    876                         pFirst->u.pNext = pCmd;
    877                     }
    878                     while (!ASMAtomicCmpXchgPtr(&pHandler->pCmd, pFirst, pCmd));
    879                 }
    880                 else
    881                 {
    882                     Assert(!pLast);
    883                 }
    884                 return VINF_SUCCESS;
    885             }
    886         }
    887         else
    888         {
    889             //TODO: impl
    890 //          HGSMIMINIPORT_CHANNELCONTEXT *pHandler = vboxVideoHGSMIFindHandler;
    891 //           if(pHandler && pHandler->pfnChannelHandler)
    892 //           {
    893 //               pHandler->pfnChannelHandler(pHandler->pvChannelHandler, u16ChannelInfo, pHdr, cbBuffer);
    894 //
    895 //               return VINF_SUCCESS;
    896 //           }
    897         }
    898     }
    899     /* no handlers were found, need to complete the command here */
    900     HGSMIHostCmdComplete(&pCallbacks->pCommon->hostCtx, pvBuffer);
    901     return VINF_SUCCESS;
    902 }
    903 
    904 static HGSMICHANNELHANDLER g_OldHandler;
    905 
    906 int vboxVBVAChannelDisplayEnable(PVBOXVIDEO_COMMON pCommon,
    907         int iDisplay, /* negative would mean this is a miniport handler */
    908         uint8_t u8Channel)
    909 {
    910     VBVA_CHANNELCONTEXTS * pContexts;
    911     HGSMICHANNEL * pChannel = HGSMIChannelFindById (&pCommon->hostCtx.channels, u8Channel);
    912     if(!pChannel)
    913     {
    914         int rc = vboxVBVACreateChannelContexts(pCommon, &pContexts);
    915         if(RT_FAILURE(rc))
    916         {
    917             return rc;
    918         }
    919     }
    920     else
    921     {
    922         pContexts = (VBVA_CHANNELCONTEXTS *)pChannel->handler.pvHandler;
    923     }
    924 
    925     VBVADISP_CHANNELCONTEXT *pDispContext = vboxVBVAFindHandlerInfo(pContexts, iDisplay);
    926     Assert(pDispContext);
    927     if(pDispContext)
    928     {
    929 #ifdef DEBUGVHWASTRICT
    930         Assert(!pDispContext->bValid);
    931 #endif
    932         Assert(!pDispContext->pCmd);
    933         if(!pDispContext->bValid)
    934         {
    935             pDispContext->bValid = true;
    936             pDispContext->pCmd = NULL;
    937 
    938             int rc = VINF_SUCCESS;
    939             if(!pChannel)
    940             {
    941                 rc = HGSMIChannelRegister (&pCommon->hostCtx.channels,
    942                                            u8Channel,
    943                                            "VGA Miniport HGSMI channel",
    944                                            vboxVBVAChannelGenericHandler,
    945                                            pContexts,
    946                                            &g_OldHandler);
    947             }
    948 
    949             if(RT_SUCCESS(rc))
    950             {
    951                 pContexts->cUsed++;
    952                 return VINF_SUCCESS;
    953             }
    954         }
    955     }
    956 
    957     if(!pChannel)
    958     {
    959         vboxVBVADeleteChannelContexts(pCommon, pContexts);
    960     }
    961 
    962     return VERR_GENERAL_FAILURE;
    963 }
    964 #endif /* !VBOX_WITH_WDDM */
    965610
    966611/** @todo Mouse pointer position to be read from VMMDev memory, address of the memory region
     
    981626 *
    982627 */
    983 
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette