VirtualBox

Changeset 66694 in vbox for trunk/src/VBox/Additions/common


Ignore:
Timestamp:
Apr 27, 2017 2:59:05 PM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
115087
Message:

bugref:8524: Additions/linux: play nicely with distribution-installed Additions
Split up HGSMIBase.cpp into two files: HGSMIGuest.cpp which contains code needed for guest-to-host communication and HGSMIHost.cpp which contains code for host-to-guest communication. Currently only the Windows Additions use the second.

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

Legend:

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

    r66693 r66694  
    11/* $Id$ */
    22/** @file
    3  * VirtualBox Video driver, common code - HGSMI initialisation and helper
    4  * functions.
     3 * VirtualBox Video driver, common code - HGSMI guest-to-host communication.
    54 */
    65
     
    3029#include <VBoxVideoVBE.h>
    3130#include <VBoxVideoIPRT.h>
    32 
    33 /**
    34  * Initialise the host context structure.
    35  *
    36  * @param  pCtx               the context structure to initialise
    37  * @param  pvBaseMapping      where the basic HGSMI structures are mapped at
    38  * @param  offHostFlags       the offset of the host flags into the basic HGSMI
    39  *                            structures
    40  * @param  pvHostAreaMapping  where the area for the host heap is mapped at
    41  * @param  offVRAMHostArea    offset of the host heap area into VRAM
    42  * @param  cbHostArea         size in bytes of the host heap area
    43  */
    44 DECLHIDDEN(void) VBoxHGSMISetupHostContext(PHGSMIHOSTCOMMANDCONTEXT pCtx,
    45                                            void *pvBaseMapping,
    46                                            uint32_t offHostFlags,
    47                                            void *pvHostAreaMapping,
    48                                            uint32_t offVRAMHostArea,
    49                                            uint32_t cbHostArea)
    50 {
    51     uint8_t *pu8HostFlags = ((uint8_t *)pvBaseMapping) + offHostFlags;
    52     pCtx->pfHostFlags = (HGSMIHOSTFLAGS *)pu8HostFlags;
    53     /** @todo should we really be using a fixed ISA port value here? */
    54     pCtx->port        = (RTIOPORT)VGA_PORT_HGSMI_HOST;
    55     HGSMIAreaInitialize(&pCtx->areaCtx, pvHostAreaMapping, cbHostArea,
    56                          offVRAMHostArea);
    57 }
    58 
    59 
    60 /** Send completion notification to the host for the command located at offset
    61  * @a offt into the host command buffer. */
    62 static void HGSMINotifyHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx, HGSMIOFFSET offt)
    63 {
    64     VBVO_PORT_WRITE_U32(pCtx->port, offt);
    65 }
    66 
    67 
    68 /**
    69  * Inform the host that a command has been handled.
    70  *
    71  * @param  pCtx   the context containing the heap to be used
    72  * @param  pvMem  pointer into the heap as mapped in @a pCtx to the command to
    73  *                be completed
    74  */
    75 DECLHIDDEN(void) VBoxHGSMIHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx,
    76                                           void *pvMem)
    77 {
    78     HGSMIBUFFERHEADER *pHdr = HGSMIBufferHeaderFromData(pvMem);
    79     HGSMIOFFSET offMem = HGSMIPointerToOffset(&pCtx->areaCtx, pHdr);
    80     Assert(offMem != HGSMIOFFSET_VOID);
    81     if(offMem != HGSMIOFFSET_VOID)
    82     {
    83         HGSMINotifyHostCmdComplete(pCtx, offMem);
    84     }
    85 }
    86 
    87 
    88 /** Submit an incoming host command to the appropriate handler. */
    89 static void hgsmiHostCmdProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx,
    90                                 HGSMIOFFSET offBuffer)
    91 {
    92     int rc = HGSMIBufferProcess(&pCtx->areaCtx, &pCtx->channels, offBuffer);
    93     Assert(!RT_FAILURE(rc));
    94     if(RT_FAILURE(rc))
    95     {
    96         /* failure means the command was not submitted to the handler for some reason
    97          * it's our responsibility to notify its completion in this case */
    98         HGSMINotifyHostCmdComplete(pCtx, offBuffer);
    99     }
    100     /* if the cmd succeeded it's responsibility of the callback to complete it */
    101 }
    102 
    103 /** Get the next command from the host. */
    104 static HGSMIOFFSET hgsmiGetHostBuffer(PHGSMIHOSTCOMMANDCONTEXT pCtx)
    105 {
    106     return VBVO_PORT_READ_U32(pCtx->port);
    107 }
    108 
    109 
    110 /** Get and handle the next command from the host. */
    111 static void hgsmiHostCommandQueryProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx)
    112 {
    113     HGSMIOFFSET offset = hgsmiGetHostBuffer(pCtx);
    114     AssertReturnVoid(offset != HGSMIOFFSET_VOID);
    115     hgsmiHostCmdProcess(pCtx, offset);
    116 }
    117 
    118 
    119 /** Drain the host command queue. */
    120 DECLHIDDEN(void) VBoxHGSMIProcessHostQueue(PHGSMIHOSTCOMMANDCONTEXT pCtx)
    121 {
    122     while (pCtx->pfHostFlags->u32HostFlags & HGSMIHOSTFLAGS_COMMANDS_PENDING)
    123     {
    124         if (!ASMAtomicCmpXchgBool(&pCtx->fHostCmdProcessing, true, false))
    125             return;
    126         hgsmiHostCommandQueryProcess(pCtx);
    127         ASMAtomicWriteBool(&pCtx->fHostCmdProcessing, false);
    128     }
    129 }
    130 
    13131
    13232/**
     
    239139
    240140
    241 /** Inform the host of the location of the host flags in VRAM via an HGSMI
    242  * command. */
    243 static int vboxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    244                                         HGSMIOFFSET offLocation)
    245 {
    246     HGSMIBUFFERLOCATION *p;
    247     int rc = VINF_SUCCESS;
    248 
    249     /* Allocate the IO buffer. */
    250     p = (HGSMIBUFFERLOCATION *)VBoxHGSMIBufferAlloc(pCtx,
    251                                               sizeof(HGSMIBUFFERLOCATION),
    252                                               HGSMI_CH_HGSMI,
    253                                               HGSMI_CC_HOST_FLAGS_LOCATION);
    254     if (p)
    255     {
    256         /* Prepare data to be sent to the host. */
    257         p->offLocation = offLocation;
    258         p->cbLocation  = sizeof(HGSMIHOSTFLAGS);
    259         rc = VBoxHGSMIBufferSubmit(pCtx, p);
    260         /* Free the IO buffer. */
    261         VBoxHGSMIBufferFree(pCtx, p);
    262     }
    263     else
    264         rc = VERR_NO_MEMORY;
    265     return rc;
    266 }
    267 
    268 
    269141/**
    270142 * Inform the host of the location of the host flags in VRAM via an HGSMI
     
    280152                                             HGSMIOFFSET offLocation)
    281153{
    282     return vboxHGSMIReportFlagsLocation(pCtx, offLocation);
    283 }
    284 
    285 
    286 /** Notify the host of HGSMI-related guest capabilities via an HGSMI command.
    287  */
    288 static int vboxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    289                                  uint32_t fCaps)
     154    HGSMIBUFFERLOCATION *p;
     155    int rc = VINF_SUCCESS;
     156
     157    /* Allocate the IO buffer. */
     158    p = (HGSMIBUFFERLOCATION *)VBoxHGSMIBufferAlloc(pCtx,
     159                                              sizeof(HGSMIBUFFERLOCATION),
     160                                              HGSMI_CH_HGSMI,
     161                                              HGSMI_CC_HOST_FLAGS_LOCATION);
     162    if (p)
     163    {
     164        /* Prepare data to be sent to the host. */
     165        p->offLocation = offLocation;
     166        p->cbLocation  = sizeof(HGSMIHOSTFLAGS);
     167        rc = VBoxHGSMIBufferSubmit(pCtx, p);
     168        /* Free the IO buffer. */
     169        VBoxHGSMIBufferFree(pCtx, p);
     170    }
     171    else
     172        rc = VERR_NO_MEMORY;
     173    return rc;
     174}
     175
     176
     177/**
     178 * Notify the host of HGSMI-related guest capabilities via an HGSMI command.
     179 * @returns  IPRT status value.
     180 * @returns  VERR_NOT_IMPLEMENTED  if the host does not support the command.
     181 * @returns  VERR_NO_MEMORY        if a heap allocation fails.
     182 * @param    pCtx                  the context of the guest heap to use.
     183 * @param    fCaps                 the capabilities to report, see VBVACAPS.
     184 */
     185DECLHIDDEN(int) VBoxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
     186                                      uint32_t fCaps)
    290187{
    291188    VBVACAPS *pCaps;
     
    310207        /* Free the IO buffer. */
    311208        VBoxHGSMIBufferFree(pCtx, pCaps);
    312     }
    313     else
    314         rc = VERR_NO_MEMORY;
    315     return rc;
    316 }
    317 
    318 
    319 /**
    320  * Notify the host of HGSMI-related guest capabilities via an HGSMI command.
    321  * @returns  IPRT status value.
    322  * @returns  VERR_NOT_IMPLEMENTED  if the host does not support the command.
    323  * @returns  VERR_NO_MEMORY        if a heap allocation fails.
    324  * @param    pCtx                  the context of the guest heap to use.
    325  * @param    fCaps                 the capabilities to report, see VBVACAPS.
    326  */
    327 DECLHIDDEN(int) VBoxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    328                                       uint32_t fCaps)
    329 {
    330     return vboxHGSMISendCapsInfo(pCtx, fCaps);
    331 }
    332 
    333 
    334 /** Tell the host about the location of the area of VRAM set aside for the host
    335  * heap. */
    336 static int vboxHGSMIReportHostArea(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    337                                    uint32_t u32AreaOffset, uint32_t u32AreaSize)
    338 {
    339     VBVAINFOHEAP *p;
    340     int rc = VINF_SUCCESS;
    341 
    342     /* Allocate the IO buffer. */
    343     p = (VBVAINFOHEAP *)VBoxHGSMIBufferAlloc(pCtx,
    344                                        sizeof (VBVAINFOHEAP), HGSMI_CH_VBVA,
    345                                        VBVA_INFO_HEAP);
    346     if (p)
    347     {
    348         /* Prepare data to be sent to the host. */
    349         p->u32HeapOffset = u32AreaOffset;
    350         p->u32HeapSize   = u32AreaSize;
    351         rc = VBoxHGSMIBufferSubmit(pCtx, p);
    352         /* Free the IO buffer. */
    353         VBoxHGSMIBufferFree(pCtx, p);
    354209    }
    355210    else
     
    401256
    402257
    403 /**
    404  * Get the information needed to map the area used by the host to send back
    405  * requests.
    406  *
    407  * @param  pCtx                the context containing the heap to use
    408  * @param  cbVRAM              how much video RAM is allocated to the device
    409  * @param  offVRAMBaseMapping  the offset of the basic communication structures
    410  *                             into the guest's VRAM
    411  * @param  poffVRAMHostArea    where to store the offset into VRAM of the host
    412  *                             heap area
    413  * @param  pcbHostArea         where to store the size of the host heap area
    414  */
    415 DECLHIDDEN(void) VBoxHGSMIGetHostAreaMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    416                                              uint32_t cbVRAM,
    417                                              uint32_t offVRAMBaseMapping,
    418                                              uint32_t *poffVRAMHostArea,
    419                                              uint32_t *pcbHostArea)
    420 {
    421     uint32_t offVRAMHostArea = offVRAMBaseMapping, cbHostArea = 0;
    422 
    423     AssertPtrReturnVoid(poffVRAMHostArea);
    424     AssertPtrReturnVoid(pcbHostArea);
    425     VBoxQueryConfHGSMI(pCtx, VBOX_VBVA_CONF32_HOST_HEAP_SIZE, &cbHostArea);
    426     if (cbHostArea != 0)
    427     {
    428         uint32_t cbHostAreaMaxSize = cbVRAM / 4;
    429         /** @todo what is the idea of this? */
    430         if (cbHostAreaMaxSize >= VBVA_ADAPTER_INFORMATION_SIZE)
    431         {
    432             cbHostAreaMaxSize -= VBVA_ADAPTER_INFORMATION_SIZE;
    433         }
    434         if (cbHostArea > cbHostAreaMaxSize)
    435         {
    436             cbHostArea = cbHostAreaMaxSize;
    437         }
    438         /* Round up to 4096 bytes. */
    439         cbHostArea = (cbHostArea + 0xFFF) & ~0xFFF;
    440         offVRAMHostArea = offVRAMBaseMapping - cbHostArea;
    441     }
    442 
    443     *pcbHostArea = cbHostArea;
    444     *poffVRAMHostArea = offVRAMHostArea;
    445     // LogFunc(("offVRAMHostArea = 0x%08X, cbHostArea = 0x%08X\n",
    446     //          offVRAMHostArea, cbHostArea));
    447 }
    448 
    449 
    450 /**
    451  * Tell the host about the ways it can use to communicate back to us via an
    452  * HGSMI command
    453  *
    454  * @returns  iprt status value
    455  * @param  pCtx                  the context containing the heap to use
    456  * @param  offVRAMFlagsLocation  where we wish the host to place its flags
    457  *                               relative to the start of the VRAM
    458  * @param  fCaps                 additions HGSMI capabilities the guest
    459  *                               supports
    460  * @param  offVRAMHostArea       offset into VRAM of the host heap area
    461  * @param  cbHostArea            size in bytes of the host heap area
    462  */
    463 DECLHIDDEN(int) VBoxHGSMISendHostCtxInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    464                                          HGSMIOFFSET offVRAMFlagsLocation,
    465                                          uint32_t fCaps,
    466                                          uint32_t offVRAMHostArea,
    467                                          uint32_t cbHostArea)
    468 {
    469     // Log(("VBoxVideo::vboxSetupAdapterInfo\n"));
    470 
    471     /* setup the flags first to ensure they are initialized by the time the
    472      * host heap is ready */
    473     int rc = vboxHGSMIReportFlagsLocation(pCtx, offVRAMFlagsLocation);
    474     AssertRC(rc);
    475     if (RT_SUCCESS(rc) && fCaps)
    476     {
    477         /* Inform about caps */
    478         rc = vboxHGSMISendCapsInfo(pCtx, fCaps);
    479         AssertRC(rc);
    480     }
    481     if (RT_SUCCESS (rc))
    482     {
    483         /* Report the host heap location. */
    484         rc = vboxHGSMIReportHostArea(pCtx, offVRAMHostArea, cbHostArea);
    485         AssertRC(rc);
    486     }
    487     // Log(("VBoxVideo::vboxSetupAdapterInfo finished rc = %d\n", rc));
    488     return rc;
    489 }
    490 
    491 
    492258/** Sanity test on first call.  We do not worry about concurrency issues. */
    493259static int testQueryConf(PHGSMIGUESTCOMMANDCONTEXT pCtx)
  • trunk/src/VBox/Additions/common/VBoxVideo/HGSMIHost.cpp

    r66685 r66694  
    11/* $Id$ */
    22/** @file
    3  * VirtualBox Video driver, common code - HGSMI initialisation and helper
    4  * functions.
     3 * VirtualBox Video driver, common code - HGSMI host-to-guest communication.
    54 */
    65
     
    130129
    131130
    132 /**
    133  * Set up the HGSMI guest-to-host command context.
    134  * @returns iprt status value
    135  * @param  pCtx                    the context to set up
    136  * @param  pvGuestHeapMemory       a pointer to the mapped backing memory for
    137  *                                 the guest heap
    138  * @param  cbGuestHeapMemory       the size of the backing memory area
    139  * @param  offVRAMGuestHeapMemory  the offset of the memory pointed to by
    140  *                                 @a pvGuestHeapMemory within the video RAM
    141  * @param  pEnv                    HGSMI environment.
    142  */
    143 DECLHIDDEN(int) VBoxHGSMISetupGuestContext(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    144                                            void *pvGuestHeapMemory,
    145                                            uint32_t cbGuestHeapMemory,
    146                                            uint32_t offVRAMGuestHeapMemory,
    147                                            const HGSMIENV *pEnv)
    148 {
    149     /** @todo should we be using a fixed ISA port value here? */
    150     pCtx->port = (RTIOPORT)VGA_PORT_HGSMI_GUEST;
    151 #ifdef VBOX_WDDM_MINIPORT
    152     return VBoxSHGSMIInit(&pCtx->heapCtx, pvGuestHeapMemory,
    153                           cbGuestHeapMemory, offVRAMGuestHeapMemory, pEnv);
    154 #else
    155     return HGSMIHeapSetup(&pCtx->heapCtx, pvGuestHeapMemory,
    156                           cbGuestHeapMemory, offVRAMGuestHeapMemory, pEnv);
    157 #endif
    158 }
    159 
    160 
    161 /**
    162  * Allocate and initialise a command descriptor in the guest heap for a
    163  * guest-to-host command.
    164  *
    165  * @returns  pointer to the descriptor's command data buffer
    166  * @param  pCtx     the context containing the heap to be used
    167  * @param  cbData   the size of the command data to go into the descriptor
    168  * @param  u8Ch     the HGSMI channel to be used, set to the descriptor
    169  * @param  u16Op    the HGSMI command to be sent, set to the descriptor
    170  */
    171 DECLHIDDEN(void *) VBoxHGSMIBufferAlloc(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    172                                         HGSMISIZE cbData,
    173                                         uint8_t u8Ch,
    174                                         uint16_t u16Op)
    175 {
    176 #ifdef VBOX_WDDM_MINIPORT
    177     return VBoxSHGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op);
    178 #else
    179     return HGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op);
    180 #endif
    181 }
    182 
    183 
    184 /**
    185  * Free a descriptor allocated by @a VBoxHGSMIBufferAlloc.
    186  *
    187  * @param  pCtx      the context containing the heap used
    188  * @param  pvBuffer  the pointer returned by @a VBoxHGSMIBufferAlloc
    189  */
    190 DECLHIDDEN(void) VBoxHGSMIBufferFree(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    191                                      void *pvBuffer)
    192 {
    193 #ifdef VBOX_WDDM_MINIPORT
    194     VBoxSHGSMIHeapFree (&pCtx->heapCtx, pvBuffer);
    195 #else
    196     HGSMIHeapFree (&pCtx->heapCtx, pvBuffer);
    197 #endif
    198 }
    199 
    200 
    201 /**
    202  * Submit a command descriptor allocated by @a VBoxHGSMIBufferAlloc.
    203  *
    204  * @param  pCtx      the context containing the heap used
    205  * @param  pvBuffer  the pointer returned by @a VBoxHGSMIBufferAlloc
    206  */
    207 DECLHIDDEN(int) VBoxHGSMIBufferSubmit(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    208                                       void *pvBuffer)
    209 {
    210     /* Initialize the buffer and get the offset for port IO. */
    211     HGSMIOFFSET offBuffer = HGSMIHeapBufferOffset (HGSMIGUESTCMDHEAP_GET(&pCtx->heapCtx), pvBuffer);
    212 
    213     Assert(offBuffer != HGSMIOFFSET_VOID);
    214     if (offBuffer != HGSMIOFFSET_VOID)
    215     {
    216         /* Submit the buffer to the host. */
    217         VBVO_PORT_WRITE_U32(pCtx->port, offBuffer);
    218         /* Make the compiler aware that the host has changed memory. */
    219         ASMCompilerBarrier();
    220         return VINF_SUCCESS;
    221     }
    222 
    223     return VERR_INVALID_PARAMETER;
    224 }
    225 
    226 
    227 /** Detect whether HGSMI is supported by the host. */
    228 DECLHIDDEN(bool) VBoxHGSMIIsSupported(void)
    229 {
    230     uint16_t DispiId;
    231 
    232     VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_INDEX, VBE_DISPI_INDEX_ID);
    233     VBVO_PORT_WRITE_U16(VBE_DISPI_IOPORT_DATA, VBE_DISPI_ID_HGSMI);
    234 
    235     DispiId = VBVO_PORT_READ_U16(VBE_DISPI_IOPORT_DATA);
    236 
    237     return (DispiId == VBE_DISPI_ID_HGSMI);
    238 }
    239 
    240 
    241 /** Inform the host of the location of the host flags in VRAM via an HGSMI
    242  * command. */
    243 static int vboxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    244                                         HGSMIOFFSET offLocation)
    245 {
    246     HGSMIBUFFERLOCATION *p;
    247     int rc = VINF_SUCCESS;
    248 
    249     /* Allocate the IO buffer. */
    250     p = (HGSMIBUFFERLOCATION *)VBoxHGSMIBufferAlloc(pCtx,
    251                                               sizeof(HGSMIBUFFERLOCATION),
    252                                               HGSMI_CH_HGSMI,
    253                                               HGSMI_CC_HOST_FLAGS_LOCATION);
    254     if (p)
    255     {
    256         /* Prepare data to be sent to the host. */
    257         p->offLocation = offLocation;
    258         p->cbLocation  = sizeof(HGSMIHOSTFLAGS);
    259         rc = VBoxHGSMIBufferSubmit(pCtx, p);
    260         /* Free the IO buffer. */
    261         VBoxHGSMIBufferFree(pCtx, p);
    262     }
    263     else
    264         rc = VERR_NO_MEMORY;
    265     return rc;
    266 }
    267 
    268 
    269 /**
    270  * Inform the host of the location of the host flags in VRAM via an HGSMI
    271  * command.
    272  * @returns  IPRT status value.
    273  * @returns  VERR_NOT_IMPLEMENTED  if the host does not support the command.
    274  * @returns  VERR_NO_MEMORY        if a heap allocation fails.
    275  * @param    pCtx                  the context of the guest heap to use.
    276  * @param    offLocation           the offset chosen for the flags withing guest
    277  *                                 VRAM.
    278  */
    279 DECLHIDDEN(int) VBoxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    280                                              HGSMIOFFSET offLocation)
    281 {
    282     return vboxHGSMIReportFlagsLocation(pCtx, offLocation);
    283 }
    284 
    285 
    286 /** Notify the host of HGSMI-related guest capabilities via an HGSMI command.
    287  */
    288 static int vboxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    289                                  uint32_t fCaps)
    290 {
    291     VBVACAPS *pCaps;
    292     int rc = VINF_SUCCESS;
    293 
    294     /* Allocate the IO buffer. */
    295     pCaps = (VBVACAPS *)VBoxHGSMIBufferAlloc(pCtx,
    296                                        sizeof(VBVACAPS), HGSMI_CH_VBVA,
    297                                        VBVA_INFO_CAPS);
    298 
    299     if (pCaps)
    300     {
    301         /* Prepare data to be sent to the host. */
    302         pCaps->rc    = VERR_NOT_IMPLEMENTED;
    303         pCaps->fCaps = fCaps;
    304         rc = VBoxHGSMIBufferSubmit(pCtx, pCaps);
    305         if (RT_SUCCESS(rc))
    306         {
    307             AssertRC(pCaps->rc);
    308             rc = pCaps->rc;
    309         }
    310         /* Free the IO buffer. */
    311         VBoxHGSMIBufferFree(pCtx, pCaps);
    312     }
    313     else
    314         rc = VERR_NO_MEMORY;
    315     return rc;
    316 }
    317 
    318 
    319 /**
    320  * Notify the host of HGSMI-related guest capabilities via an HGSMI command.
    321  * @returns  IPRT status value.
    322  * @returns  VERR_NOT_IMPLEMENTED  if the host does not support the command.
    323  * @returns  VERR_NO_MEMORY        if a heap allocation fails.
    324  * @param    pCtx                  the context of the guest heap to use.
    325  * @param    fCaps                 the capabilities to report, see VBVACAPS.
    326  */
    327 DECLHIDDEN(int) VBoxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    328                                       uint32_t fCaps)
    329 {
    330     return vboxHGSMISendCapsInfo(pCtx, fCaps);
    331 }
    332 
    333 
    334131/** Tell the host about the location of the area of VRAM set aside for the host
    335132 * heap. */
     
    356153        rc = VERR_NO_MEMORY;
    357154    return rc;
    358 }
    359 
    360 
    361 /**
    362  * Get the information needed to map the basic communication structures in
    363  * device memory into our address space.  All pointer parameters are optional.
    364  *
    365  * @param  cbVRAM               how much video RAM is allocated to the device
    366  * @param  poffVRAMBaseMapping  where to save the offset from the start of the
    367  *                              device VRAM of the whole area to map
    368  * @param  pcbMapping           where to save the mapping size
    369  * @param  poffGuestHeapMemory  where to save the offset into the mapped area
    370  *                              of the guest heap backing memory
    371  * @param  pcbGuestHeapMemory   where to save the size of the guest heap
    372  *                              backing memory
    373  * @param  poffHostFlags        where to save the offset into the mapped area
    374  *                              of the host flags
    375  */
    376 DECLHIDDEN(void) VBoxHGSMIGetBaseMappingInfo(uint32_t cbVRAM,
    377                                              uint32_t *poffVRAMBaseMapping,
    378                                              uint32_t *pcbMapping,
    379                                              uint32_t *poffGuestHeapMemory,
    380                                              uint32_t *pcbGuestHeapMemory,
    381                                              uint32_t *poffHostFlags)
    382 {
    383     AssertPtrNullReturnVoid(poffVRAMBaseMapping);
    384     AssertPtrNullReturnVoid(pcbMapping);
    385     AssertPtrNullReturnVoid(poffGuestHeapMemory);
    386     AssertPtrNullReturnVoid(pcbGuestHeapMemory);
    387     AssertPtrNullReturnVoid(poffHostFlags);
    388     if (poffVRAMBaseMapping)
    389         *poffVRAMBaseMapping = cbVRAM - VBVA_ADAPTER_INFORMATION_SIZE;
    390     if (pcbMapping)
    391         *pcbMapping = VBVA_ADAPTER_INFORMATION_SIZE;
    392     if (poffGuestHeapMemory)
    393         *poffGuestHeapMemory = 0;
    394     if (pcbGuestHeapMemory)
    395         *pcbGuestHeapMemory =   VBVA_ADAPTER_INFORMATION_SIZE
    396                               - sizeof(HGSMIHOSTFLAGS);
    397     if (poffHostFlags)
    398         *poffHostFlags =   VBVA_ADAPTER_INFORMATION_SIZE
    399                          - sizeof(HGSMIHOSTFLAGS);
    400155}
    401156
     
    471226    /* setup the flags first to ensure they are initialized by the time the
    472227     * host heap is ready */
    473     int rc = vboxHGSMIReportFlagsLocation(pCtx, offVRAMFlagsLocation);
     228    int rc = VBoxHGSMIReportFlagsLocation(pCtx, offVRAMFlagsLocation);
    474229    AssertRC(rc);
    475230    if (RT_SUCCESS(rc) && fCaps)
    476231    {
    477232        /* Inform about caps */
    478         rc = vboxHGSMISendCapsInfo(pCtx, fCaps);
     233        rc = VBoxHGSMISendCapsInfo(pCtx, fCaps);
    479234        AssertRC(rc);
    480235    }
     
    488243    return rc;
    489244}
    490 
    491 
    492 /** Sanity test on first call.  We do not worry about concurrency issues. */
    493 static int testQueryConf(PHGSMIGUESTCOMMANDCONTEXT pCtx)
    494 {
    495     static bool cOnce = false;
    496     uint32_t ulValue = 0;
    497     int rc;
    498 
    499     if (cOnce)
    500         return VINF_SUCCESS;
    501     cOnce = true;
    502     rc = VBoxQueryConfHGSMI(pCtx, UINT32_MAX, &ulValue);
    503     if (RT_SUCCESS(rc) && ulValue == UINT32_MAX)
    504         return VINF_SUCCESS;
    505     cOnce = false;
    506     if (RT_FAILURE(rc))
    507         return rc;
    508     return VERR_INTERNAL_ERROR;
    509 }
    510 
    511 
    512 /**
    513  * Query the host for an HGSMI configuration parameter via an HGSMI command.
    514  * @returns iprt status value
    515  * @param  pCtx      the context containing the heap used
    516  * @param  u32Index  the index of the parameter to query,
    517  *                   @see VBVACONF32::u32Index
    518  * @param  u32DefValue defaut value
    519  * @param  pulValue  where to store the value of the parameter on success
    520  */
    521 DECLHIDDEN(int) VBoxQueryConfHGSMIDef(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    522                                       uint32_t u32Index, uint32_t u32DefValue, uint32_t *pulValue)
    523 {
    524     int rc = VINF_SUCCESS;
    525     VBVACONF32 *p;
    526     // LogFunc(("u32Index = %d\n", u32Index));
    527 
    528     rc = testQueryConf(pCtx);
    529     if (RT_FAILURE(rc))
    530         return rc;
    531     /* Allocate the IO buffer. */
    532     p = (VBVACONF32 *)VBoxHGSMIBufferAlloc(pCtx,
    533                                      sizeof(VBVACONF32), HGSMI_CH_VBVA,
    534                                      VBVA_QUERY_CONF32);
    535     if (p)
    536     {
    537         /* Prepare data to be sent to the host. */
    538         p->u32Index = u32Index;
    539         p->u32Value = u32DefValue;
    540         rc = VBoxHGSMIBufferSubmit(pCtx, p);
    541         if (RT_SUCCESS(rc))
    542         {
    543             *pulValue = p->u32Value;
    544             // LogFunc(("u32Value = %d\n", p->u32Value));
    545         }
    546         /* Free the IO buffer. */
    547         VBoxHGSMIBufferFree(pCtx, p);
    548     }
    549     else
    550         rc = VERR_NO_MEMORY;
    551     // LogFunc(("rc = %d\n", rc));
    552     return rc;
    553 }
    554 
    555 DECLHIDDEN(int) VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    556                                    uint32_t u32Index, uint32_t *pulValue)
    557 {
    558     return VBoxQueryConfHGSMIDef(pCtx, u32Index, UINT32_MAX, pulValue);
    559 }
    560 
    561 /**
    562  * Pass the host a new mouse pointer shape via an HGSMI command.
    563  *
    564  * @returns  success or failure
    565  * @param  pCtx      the context containing the heap to be used
    566  * @param  fFlags    cursor flags, @see VMMDevReqMousePointer::fFlags
    567  * @param  cHotX     horizontal position of the hot spot
    568  * @param  cHotY     vertical position of the hot spot
    569  * @param  cWidth    width in pixels of the cursor
    570  * @param  cHeight   height in pixels of the cursor
    571  * @param  pPixels   pixel data, @see VMMDevReqMousePointer for the format
    572  * @param  cbLength  size in bytes of the pixel data
    573  */
    574 DECLHIDDEN(int)  VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx,
    575                                              uint32_t fFlags,
    576                                              uint32_t cHotX,
    577                                              uint32_t cHotY,
    578                                              uint32_t cWidth,
    579                                              uint32_t cHeight,
    580                                              uint8_t *pPixels,
    581                                              uint32_t cbLength)
    582 {
    583     VBVAMOUSEPOINTERSHAPE *p;
    584     uint32_t cbData = 0;
    585     int rc = VINF_SUCCESS;
    586 
    587     if (fFlags & VBOX_MOUSE_POINTER_SHAPE)
    588     {
    589         /* Size of the pointer data: sizeof (AND mask) + sizeof (XOR_MASK) */
    590         cbData = ((((cWidth + 7) / 8) * cHeight + 3) & ~3)
    591                  + cWidth * 4 * cHeight;
    592         /* If shape is supplied, then always create the pointer visible.
    593          * See comments in 'vboxUpdatePointerShape'
    594          */
    595         fFlags |= VBOX_MOUSE_POINTER_VISIBLE;
    596     }
    597     // LogFlowFunc(("cbData %d, %dx%d\n", cbData, cWidth, cHeight));
    598     if (cbData > cbLength)
    599     {
    600         // LogFunc(("calculated pointer data size is too big (%d bytes, limit %d)\n",
    601         //          cbData, cbLength));
    602         return VERR_INVALID_PARAMETER;
    603     }
    604     /* Allocate the IO buffer. */
    605     p = (VBVAMOUSEPOINTERSHAPE *)VBoxHGSMIBufferAlloc(pCtx,
    606                                                   sizeof(VBVAMOUSEPOINTERSHAPE)
    607                                                 + cbData,
    608                                                 HGSMI_CH_VBVA,
    609                                                 VBVA_MOUSE_POINTER_SHAPE);
    610     if (p)
    611     {
    612         /* Prepare data to be sent to the host. */
    613         /* Will be updated by the host. */
    614         p->i32Result = VINF_SUCCESS;
    615         /* We have our custom flags in the field */
    616         p->fu32Flags = fFlags;
    617         p->u32HotX   = cHotX;
    618         p->u32HotY   = cHotY;
    619         p->u32Width  = cWidth;
    620         p->u32Height = cHeight;
    621         if (p->fu32Flags & VBOX_MOUSE_POINTER_SHAPE)
    622             /* Copy the actual pointer data. */
    623             memcpy (p->au8Data, pPixels, cbData);
    624         rc = VBoxHGSMIBufferSubmit(pCtx, p);
    625         if (RT_SUCCESS(rc))
    626             rc = p->i32Result;
    627         /* Free the IO buffer. */
    628         VBoxHGSMIBufferFree(pCtx, p);
    629     }
    630     else
    631         rc = VERR_NO_MEMORY;
    632     // LogFlowFunc(("rc %d\n", rc));
    633     return rc;
    634 }
    635 
    636 
    637 /**
    638  * Report the guest cursor position.  The host may wish to use this information
    639  * to re-position its own cursor (though this is currently unlikely).  The
    640  * current host cursor position is returned.
    641  * @param  pCtx             The context containing the heap used.
    642  * @param  fReportPosition  Are we reporting a position?
    643  * @param  x                Guest cursor X position.
    644  * @param  y                Guest cursor Y position.
    645  * @param  pxHost           Host cursor X position is stored here.  Optional.
    646  * @param  pyHost           Host cursor Y position is stored here.  Optional.
    647  * @returns  iprt status code.
    648  * @returns  VERR_NO_MEMORY      HGSMI heap allocation failed.
    649  */
    650 DECLHIDDEN(int) VBoxHGSMICursorPosition(PHGSMIGUESTCOMMANDCONTEXT pCtx, bool fReportPosition, uint32_t x, uint32_t y,
    651                                         uint32_t *pxHost, uint32_t *pyHost)
    652 {
    653     int rc = VINF_SUCCESS;
    654     VBVACURSORPOSITION *p;
    655     // Log(("%s: x=%u, y=%u\n", __PRETTY_FUNCTION__, (unsigned)x, (unsigned)y));
    656 
    657     /* Allocate the IO buffer. */
    658     p = (VBVACURSORPOSITION *)VBoxHGSMIBufferAlloc(pCtx, sizeof(VBVACURSORPOSITION), HGSMI_CH_VBVA, VBVA_CURSOR_POSITION);
    659     if (p)
    660     {
    661         /* Prepare data to be sent to the host. */
    662         p->fReportPosition = fReportPosition ? 1 : 0;
    663         p->x = x;
    664         p->y = y;
    665         rc = VBoxHGSMIBufferSubmit(pCtx, p);
    666         if (RT_SUCCESS(rc))
    667         {
    668             if (pxHost)
    669                 *pxHost = p->x;
    670             if (pyHost)
    671                 *pyHost = p->y;
    672             // Log(("%s: return: x=%u, y=%u\n", __PRETTY_FUNCTION__, (unsigned)p->x, (unsigned)p->y));
    673         }
    674         /* Free the IO buffer. */
    675         VBoxHGSMIBufferFree(pCtx, p);
    676     }
    677     else
    678         rc = VERR_NO_MEMORY;
    679     // LogFunc(("rc = %d\n", rc));
    680     return rc;
    681 }
    682 
    683 
    684 /** @todo Mouse pointer position to be read from VMMDev memory, address of the memory region
    685  * can be queried from VMMDev via an IOCTL. This VMMDev memory region will contain
    686  * host information which is needed by the guest.
    687  *
    688  * Reading will not cause a switch to the host.
    689  *
    690  * Have to take into account:
    691  *  * synchronization: host must write to the memory only from EMT,
    692  *    large structures must be read under flag, which tells the host
    693  *    that the guest is currently reading the memory (OWNER flag?).
    694  *  * guest writes: may be allocate a page for the host info and make
    695  *    the page readonly for the guest.
    696  *  * the information should be available only for additions drivers.
    697  *  * VMMDev additions driver will inform the host which version of the info it expects,
    698  *    host must support all versions.
    699  *
    700  */
Note: See TracChangeset for help on using the changeset viewer.

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