VirtualBox

Ignore:
Timestamp:
Nov 25, 2010 11:53:56 PM (14 years ago)
Author:
vboxsync
Message:

Additions/WINNT/Graphics: more refactoring

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/WINNT/Graphics/Miniport/VBoxVideoHGSMI.cpp

    r34349 r34388  
    283283
    284284
    285 static int vboxSetupAdapterInfoHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    286                                      HGSMIOFFSET offBufferLocation,
    287                                      uint32_t fCaps, uint32_t u32HeapOffset,
    288                                      uint32_t u32HeapSize)
     285/**
     286 * Get the information needed to map the basic communication structures in
     287 * device memory into our address space.
     288 *
     289 * @param  cbVRAM               how much video RAM is allocated to the device
     290 * @param  poffVRAMBaseMapping  where to save the offset from the start of the
     291 *                              device VRAM of the whole area to map
     292 * @param  pcbMapping           where to save the mapping size
     293 * @param  poffGuestHeapMemory  where to save the offset into the mapped area
     294 *                              of the guest heap backing memory
     295 * @param  pcbGuestHeapMemory   where to save the size of the guest heap
     296 *                              backing memory
     297 * @param  poffHostFlags        where to save the offset into the mapped area
     298 *                              of the host flags
     299 */
     300void vboxHGSMIGetBaseMappingInfo(uint32_t cbVRAM,
     301                                 uint32_t *poffVRAMBaseMapping,
     302                                 uint32_t *pcbMapping,
     303                                 uint32_t *poffGuestHeapMemory,
     304                                 uint32_t *pcbGuestHeapMemory,
     305                                 uint32_t *poffHostFlags)
     306{
     307    AssertPtrReturnVoid(poffVRAMBaseMapping);
     308    AssertPtrReturnVoid(pcbMapping);
     309    AssertPtrReturnVoid(poffGuestHeapMemory);
     310    AssertPtrReturnVoid(pcbGuestHeapMemory);
     311    AssertPtrReturnVoid(poffHostFlags);
     312    *poffVRAMBaseMapping = cbVRAM - VBVA_ADAPTER_INFORMATION_SIZE;
     313    *pcbMapping = VBVA_ADAPTER_INFORMATION_SIZE;
     314    *poffGuestHeapMemory = 0;
     315    *pcbGuestHeapMemory = VBVA_ADAPTER_INFORMATION_SIZE - sizeof(HGSMIHOSTFLAGS);
     316    *poffHostFlags = VBVA_ADAPTER_INFORMATION_SIZE - sizeof(HGSMIHOSTFLAGS);
     317}
     318
     319
     320/**
     321 * Set up the HGSMI guest-to-host command context.
     322 * @returns iprt status value
     323 * @param  pCtx                    the context to set up
     324 * @param  pvGuestHeapMemory       a pointer to the mapped backing memory for
     325 *                                 the guest heap
     326 * @param  cbGuestHeapMemory       the size of the backing memory area
     327 * @param  offVRAMGuestHeapMemory  the offset of the memory pointed to by
     328 *                                 @a pvGuestHeapMemory within the video RAM
     329 */
     330int vboxHGSMISetupGuestContext(PHGSMIGUESTCOMMANDCONTEXT pCtx,
     331                               void *pvGuestHeapMemory,
     332                               uint32_t cbGuestHeapMemory,
     333                               uint32_t offVRAMGuestHeapMemory)
     334{
     335    /** @todo should we be using a fixed ISA port value here? */
     336    pCtx->port = (RTIOPORT)VGA_PORT_HGSMI_GUEST;
     337    return HGSMIHeapSetup(&pCtx->heapCtx, pvGuestHeapMemory,
     338                          cbGuestHeapMemory, offVRAMGuestHeapMemory,
     339                          false /*fOffsetBased*/);
     340}
     341
     342
     343/**
     344 * Get the information needed to map the area used by the host to send back
     345 * requests.
     346 *
     347 * @param  pCtx                the guest context used to query the host
     348 * @param  cbVRAM              how much video RAM is allocated to the device
     349 * @param  offVRAMBaseMapping  the offset of the basic communication structures
     350 *                             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 */
     355void vboxHGSMIGetHostAreaMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx,
     356                                 uint32_t cbVRAM, uint32_t offVRAMBaseMapping,
     357                                 uint32_t *poffVRAMHostArea,
     358                                 uint32_t *pcbHostArea)
     359{
     360    uint32_t offVRAMHostArea = offVRAMBaseMapping, cbHostArea = 0;
     361
     362    AssertPtrReturnVoid(poffVRAMHostArea);
     363    AssertPtrReturnVoid(pcbHostArea);
     364    vboxQueryConfHGSMI(pCtx, VBOX_VBVA_CONF32_HOST_HEAP_SIZE, &cbHostArea);
     365    if (cbHostArea != 0)
     366    {
     367        uint32_t cbHostAreaMaxSize = cbVRAM / 4;
     368        /** @todo what is the idea of this? */
     369        if (cbHostAreaMaxSize >= VBVA_ADAPTER_INFORMATION_SIZE)
     370        {
     371            cbHostAreaMaxSize -= VBVA_ADAPTER_INFORMATION_SIZE;
     372        }
     373        if (cbHostArea > cbHostAreaMaxSize)
     374        {
     375            cbHostArea = cbHostAreaMaxSize;
     376        }
     377        /* Round up to 4096 bytes. */
     378        cbHostArea = (cbHostArea + 0xFFF) & ~0xFFF;
     379        offVRAMHostArea = offVRAMBaseMapping - cbHostArea;
     380    }
     381
     382    *pcbHostArea = cbHostArea;
     383    *poffVRAMHostArea = offVRAMHostArea;
     384    LogFunc(("offVRAMHostArea = 0x%08X, cbHostArea = 0x%08X\n",
     385             offVRAMHostArea, cbHostArea));
     386}
     387
     388
     389/** Initialise the host context structure. */
     390void vboxHGSMISetupHostContext(PHGSMIHOSTCOMMANDCONTEXT pCtx,
     391                               void *pvBaseMapping, uint32_t offHostFlags,
     392                               void *pvHostAreaMapping,
     393                               uint32_t offVRAMHostArea, uint32_t cbHostArea)
     394{
     395    uint8_t *pu8HostFlags = ((uint8_t *)pvBaseMapping) + offHostFlags;
     396    pCtx->pfHostFlags = (HGSMIHOSTFLAGS *)pu8HostFlags;
     397    /** @todo should we really be using a fixed ISA port value here? */
     398    pCtx->port        = (RTIOPORT)VGA_PORT_HGSMI_HOST;
     399    HGSMIAreaInitialize(&pCtx->areaCtx, pvHostAreaMapping, cbHostArea,
     400                         offVRAMHostArea);
     401}
     402
     403
     404/**
     405 * Mirror the information in the host context structure to the host.
     406 */
     407static int vboxHGSMISendHostCtxInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
     408                                    HGSMIOFFSET offBufferLocation,
     409                                    uint32_t fCaps, uint32_t u32HeapOffset,
     410                                    uint32_t u32HeapSize)
    289411{
    290412    Log(("VBoxVideo::vboxSetupAdapterInfo\n"));
    291413
    292     /* setup the flags first to ensure they are initialized by the time the host heap is ready */
     414    /* setup the flags first to ensure they are initialized by the time the
     415     * host heap is ready */
    293416    int rc = vboxHGSMIBufferLocation(pCtx, offBufferLocation);
    294417    AssertRC(rc);
     
    307430    Log(("VBoxVideo::vboxSetupAdapterInfo finished rc = %d\n", rc));
    308431    return rc;
     432}
     433
     434
     435/**
     436 * Returns the count of virtual monitors attached to the guest.  Returns
     437 * 1 on failure.
     438 */
     439unsigned vboxHGSMIGetMonitorCount(PHGSMIGUESTCOMMANDCONTEXT pCtx)
     440{
     441    /* Query the configured number of displays. */
     442    uint32_t cDisplays = 0;
     443    vboxQueryConfHGSMI(pCtx, VBOX_VBVA_CONF32_MONITOR_COUNT, &cDisplays);
     444    LogFunc(("cDisplays = %d\n", cDisplays));
     445    if (cDisplays == 0 || cDisplays > VBOX_VIDEO_MAX_SCREENS)
     446        /* Host reported some bad value. Continue in the 1 screen mode. */
     447        cDisplays = 1;
     448    return cDisplays;
    309449}
    310450
     
    326466     * fixed. */
    327467    int rc = VINF_SUCCESS;
    328 
     468    uint32_t offVRAMBaseMapping, cbMapping, offGuestHeapMemory, cbGuestHeapMemory,
     469             offHostFlags, offVRAMHostArea, cbHostArea;
    329470    Log(("VBoxVideo::VBoxSetupDisplays: pCommon = %p\n", pCommon));
    330471
     
    338479    if (pCommon->bHGSMI)
    339480    {
    340         /** @note (michael) moved this here as it is done unconditionally in both
    341          * driver branches.  Feel free to fix if that is ever changed. */
    342         pCommon->hostCtx.port = (RTIOPORT)VGA_PORT_HGSMI_HOST;
    343         pCommon->guestCtx.port = (RTIOPORT)VGA_PORT_HGSMI_GUEST;
     481        vboxHGSMIGetBaseMappingInfo(pCommon->cbVRAM, &offVRAMBaseMapping,
     482                                    &cbMapping, &offGuestHeapMemory,
     483                                    &cbGuestHeapMemory, &offHostFlags);
    344484
    345485        /* Map the adapter information. It will be needed for HGSMI IO. */
     
    347487         * error codes, but it doesn't. */
    348488        rc = VBoxMapAdapterMemory (pCommon, &pCommon->pvAdapterInformation,
    349                                    AdapterMemorySize - VBVA_ADAPTER_INFORMATION_SIZE,
    350                                    VBVA_ADAPTER_INFORMATION_SIZE
    351                                   );
     489                                   offVRAMBaseMapping, cbMapping);
    352490        if (RT_FAILURE(rc))
    353491        {
     
    359497        else
    360498        {
    361             /* Setup a HGSMI heap within the adapter information area. */
    362             rc = HGSMIHeapSetup (&pCommon->guestCtx.heapCtx,
    363                                  pCommon->pvAdapterInformation,
    364                                  VBVA_ADAPTER_INFORMATION_SIZE - sizeof(HGSMIHOSTFLAGS),
    365                                  pCommon->cbVRAM - VBVA_ADAPTER_INFORMATION_SIZE,
    366                                  false /*fOffsetBased*/);
     499            /* Setup an HGSMI heap within the adapter information area. */
     500            rc = vboxHGSMISetupGuestContext(&pCommon->guestCtx,
     501                                            pCommon->pvAdapterInformation,
     502                                            cbGuestHeapMemory,
     503                                              offVRAMBaseMapping
     504                                            + offGuestHeapMemory);
    367505
    368506            if (RT_FAILURE(rc))
     
    373511                pCommon->bHGSMI = false;
    374512            }
    375             else
    376             {
    377                 pCommon->hostCtx.pfHostFlags = (HGSMIHOSTFLAGS*)(((uint8_t*)pCommon->pvAdapterInformation)
    378                                                             + VBVA_ADAPTER_INFORMATION_SIZE - sizeof(HGSMIHOSTFLAGS));
    379             }
    380513        }
    381514    }
     
    384517    if (pCommon->bHGSMI)
    385518    {
    386         /* The miniport heap is used for the host buffers. */
    387         uint32_t cbMiniportHeap = 0;
    388         vboxQueryConfHGSMI(&pCommon->guestCtx, VBOX_VBVA_CONF32_HOST_HEAP_SIZE,
    389                            &cbMiniportHeap);
    390 
    391         if (cbMiniportHeap != 0)
    392         {
    393             /* Do not allow too big heap. No more than 25% of VRAM is allowed. */
    394             uint32_t cbMiniportHeapMaxSize = AdapterMemorySize / 4;
    395 
    396             if (cbMiniportHeapMaxSize >= VBVA_ADAPTER_INFORMATION_SIZE)
    397             {
    398                 cbMiniportHeapMaxSize -= VBVA_ADAPTER_INFORMATION_SIZE;
    399             }
    400 
    401             if (cbMiniportHeap > cbMiniportHeapMaxSize)
    402             {
    403                 cbMiniportHeap = cbMiniportHeapMaxSize;
    404             }
    405 
    406             /* Round up to 4096 bytes. */
    407             pCommon->cbMiniportHeap = (cbMiniportHeap + 0xFFF) & ~0xFFF;
    408 
    409             Log(("VBoxVideo::VBoxSetupDisplays: cbMiniportHeap = 0x%08X, pCommon->cbMiniportHeap = 0x%08X, cbMiniportHeapMaxSize = 0x%08X\n",
    410                      cbMiniportHeap, pCommon->cbMiniportHeap, cbMiniportHeapMaxSize));
     519        vboxHGSMIGetHostAreaMapping(&pCommon->guestCtx, pCommon->cbVRAM,
     520                                    offVRAMBaseMapping, &offVRAMHostArea,
     521                                    &cbHostArea);
     522        if (cbHostArea)
     523        {
    411524
    412525            /* Map the heap region.
     
    416529             *       display drivers.
    417530             */
     531            pCommon->cbMiniportHeap = cbHostArea;
    418532            rc = VBoxMapAdapterMemory (pCommon, &pCommon->pvMiniportHeap,
    419                                        pCommon->cbVRAM
    420                                        - VBVA_ADAPTER_INFORMATION_SIZE
    421                                        - pCommon->cbMiniportHeap,
    422                                        pCommon->cbMiniportHeap
    423                                       );
     533                                       offVRAMHostArea, cbHostArea);
    424534            if (RT_FAILURE(rc))
    425535            {
     
    429539            }
    430540            else
    431             {
    432                 HGSMIOFFSET offBase = pCommon->cbVRAM
    433                                       - VBVA_ADAPTER_INFORMATION_SIZE
    434                                       - pCommon->cbMiniportHeap;
    435 
    436                 /* Init the host hap area. Buffers from the host will be placed there. */
    437                 HGSMIAreaInitialize (&pCommon->hostCtx.areaCtx,
    438                                      pCommon->pvMiniportHeap,
    439                                      pCommon->cbMiniportHeap,
    440                                      offBase);
    441             }
     541                vboxHGSMISetupHostContext(&pCommon->hostCtx,
     542                                          pCommon->pvAdapterInformation,
     543                                          offHostFlags,
     544                                          pCommon->pvMiniportHeap,
     545                                          offVRAMHostArea, cbHostArea);
    442546        }
    443547        else
     
    449553    }
    450554
     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
    451569    /* Check whether the guest supports multimonitors. */
    452570    if (pCommon->bHGSMI)
    453     {
    454571        /* Query the configured number of displays. */
    455         uint32_t cDisplays = 0;
    456         vboxQueryConfHGSMI(&pCommon->guestCtx, VBOX_VBVA_CONF32_MONITOR_COUNT,
    457                            &cDisplays);
    458 
    459         Log(("VBoxVideo::VBoxSetupDisplays: cDisplays = %d\n",
    460                  cDisplays));
    461 
    462         if (cDisplays == 0 || cDisplays > VBOX_VIDEO_MAX_SCREENS)
    463         {
    464             /* Host reported some bad value. Continue in the 1 screen mode. */
    465             cDisplays = 1;
    466         }
    467         pCommon->cDisplays = cDisplays;
    468     }
    469 
    470     if (pCommon->bHGSMI)
    471     {
    472         /* Setup the information for the host. */
    473         rc = vboxSetupAdapterInfoHGSMI(&pCommon->guestCtx,
    474                                        pCommon->cbVRAM - sizeof(HGSMIHOSTFLAGS),
    475                                        fCaps,
    476                                          pCommon->cbVRAM
    477                                        - pCommon->cbMiniportHeap
    478                                        - VBVA_ADAPTER_INFORMATION_SIZE,
    479                                        pCommon->cbMiniportHeap);
    480 
    481         if (RT_FAILURE(rc))
    482         {
    483             pCommon->bHGSMI = false;
    484         }
    485     }
     572        pCommon->cDisplays = vboxHGSMIGetMonitorCount(&pCommon->guestCtx);
    486573
    487574    if (!pCommon->bHGSMI)
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