Changeset 66694 in vbox for trunk/src/VBox/Additions/common
- Timestamp:
- Apr 27, 2017 2:59:05 PM (8 years ago)
- svn:sync-xref-src-repo-rev:
- 115087
- 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 1 1 /* $Id$ */ 2 2 /** @file 3 * VirtualBox Video driver, common code - HGSMI initialisation and helper 4 * functions. 3 * VirtualBox Video driver, common code - HGSMI guest-to-host communication. 5 4 */ 6 5 … … 30 29 #include <VBoxVideoVBE.h> 31 30 #include <VBoxVideoIPRT.h> 32 33 /**34 * Initialise the host context structure.35 *36 * @param pCtx the context structure to initialise37 * @param pvBaseMapping where the basic HGSMI structures are mapped at38 * @param offHostFlags the offset of the host flags into the basic HGSMI39 * structures40 * @param pvHostAreaMapping where the area for the host heap is mapped at41 * @param offVRAMHostArea offset of the host heap area into VRAM42 * @param cbHostArea size in bytes of the host heap area43 */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 offset61 * @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 used72 * @param pvMem pointer into the heap as mapped in @a pCtx to the command to73 * be completed74 */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 reason97 * 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 131 31 132 32 /** … … 239 139 240 140 241 /** Inform the host of the location of the host flags in VRAM via an HGSMI242 * 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 else264 rc = VERR_NO_MEMORY;265 return rc;266 }267 268 269 141 /** 270 142 * Inform the host of the location of the host flags in VRAM via an HGSMI … … 280 152 HGSMIOFFSET offLocation) 281 153 { 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 */ 185 DECLHIDDEN(int) VBoxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx, 186 uint32_t fCaps) 290 187 { 291 188 VBVACAPS *pCaps; … … 310 207 /* Free the IO buffer. */ 311 208 VBoxHGSMIBufferFree(pCtx, pCaps); 312 }313 else314 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 host335 * 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);354 209 } 355 210 else … … 401 256 402 257 403 /**404 * Get the information needed to map the area used by the host to send back405 * requests.406 *407 * @param pCtx the context containing the heap to use408 * @param cbVRAM how much video RAM is allocated to the device409 * @param offVRAMBaseMapping the offset of the basic communication structures410 * into the guest's VRAM411 * @param poffVRAMHostArea where to store the offset into VRAM of the host412 * heap area413 * @param pcbHostArea where to store the size of the host heap area414 */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 an452 * HGSMI command453 *454 * @returns iprt status value455 * @param pCtx the context containing the heap to use456 * @param offVRAMFlagsLocation where we wish the host to place its flags457 * relative to the start of the VRAM458 * @param fCaps additions HGSMI capabilities the guest459 * supports460 * @param offVRAMHostArea offset into VRAM of the host heap area461 * @param cbHostArea size in bytes of the host heap area462 */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 the472 * 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 492 258 /** Sanity test on first call. We do not worry about concurrency issues. */ 493 259 static int testQueryConf(PHGSMIGUESTCOMMANDCONTEXT pCtx) -
trunk/src/VBox/Additions/common/VBoxVideo/HGSMIHost.cpp
r66685 r66694 1 1 /* $Id$ */ 2 2 /** @file 3 * VirtualBox Video driver, common code - HGSMI initialisation and helper 4 * functions. 3 * VirtualBox Video driver, common code - HGSMI host-to-guest communication. 5 4 */ 6 5 … … 130 129 131 130 132 /**133 * Set up the HGSMI guest-to-host command context.134 * @returns iprt status value135 * @param pCtx the context to set up136 * @param pvGuestHeapMemory a pointer to the mapped backing memory for137 * the guest heap138 * @param cbGuestHeapMemory the size of the backing memory area139 * @param offVRAMGuestHeapMemory the offset of the memory pointed to by140 * @a pvGuestHeapMemory within the video RAM141 * @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_MINIPORT152 return VBoxSHGSMIInit(&pCtx->heapCtx, pvGuestHeapMemory,153 cbGuestHeapMemory, offVRAMGuestHeapMemory, pEnv);154 #else155 return HGSMIHeapSetup(&pCtx->heapCtx, pvGuestHeapMemory,156 cbGuestHeapMemory, offVRAMGuestHeapMemory, pEnv);157 #endif158 }159 160 161 /**162 * Allocate and initialise a command descriptor in the guest heap for a163 * guest-to-host command.164 *165 * @returns pointer to the descriptor's command data buffer166 * @param pCtx the context containing the heap to be used167 * @param cbData the size of the command data to go into the descriptor168 * @param u8Ch the HGSMI channel to be used, set to the descriptor169 * @param u16Op the HGSMI command to be sent, set to the descriptor170 */171 DECLHIDDEN(void *) VBoxHGSMIBufferAlloc(PHGSMIGUESTCOMMANDCONTEXT pCtx,172 HGSMISIZE cbData,173 uint8_t u8Ch,174 uint16_t u16Op)175 {176 #ifdef VBOX_WDDM_MINIPORT177 return VBoxSHGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op);178 #else179 return HGSMIHeapAlloc (&pCtx->heapCtx, cbData, u8Ch, u16Op);180 #endif181 }182 183 184 /**185 * Free a descriptor allocated by @a VBoxHGSMIBufferAlloc.186 *187 * @param pCtx the context containing the heap used188 * @param pvBuffer the pointer returned by @a VBoxHGSMIBufferAlloc189 */190 DECLHIDDEN(void) VBoxHGSMIBufferFree(PHGSMIGUESTCOMMANDCONTEXT pCtx,191 void *pvBuffer)192 {193 #ifdef VBOX_WDDM_MINIPORT194 VBoxSHGSMIHeapFree (&pCtx->heapCtx, pvBuffer);195 #else196 HGSMIHeapFree (&pCtx->heapCtx, pvBuffer);197 #endif198 }199 200 201 /**202 * Submit a command descriptor allocated by @a VBoxHGSMIBufferAlloc.203 *204 * @param pCtx the context containing the heap used205 * @param pvBuffer the pointer returned by @a VBoxHGSMIBufferAlloc206 */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 HGSMI242 * 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 else264 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 HGSMI271 * 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 guest277 * 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 else314 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 131 /** Tell the host about the location of the area of VRAM set aside for the host 335 132 * heap. */ … … 356 153 rc = VERR_NO_MEMORY; 357 154 return rc; 358 }359 360 361 /**362 * Get the information needed to map the basic communication structures in363 * device memory into our address space. All pointer parameters are optional.364 *365 * @param cbVRAM how much video RAM is allocated to the device366 * @param poffVRAMBaseMapping where to save the offset from the start of the367 * device VRAM of the whole area to map368 * @param pcbMapping where to save the mapping size369 * @param poffGuestHeapMemory where to save the offset into the mapped area370 * of the guest heap backing memory371 * @param pcbGuestHeapMemory where to save the size of the guest heap372 * backing memory373 * @param poffHostFlags where to save the offset into the mapped area374 * of the host flags375 */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_SIZE396 - sizeof(HGSMIHOSTFLAGS);397 if (poffHostFlags)398 *poffHostFlags = VBVA_ADAPTER_INFORMATION_SIZE399 - sizeof(HGSMIHOSTFLAGS);400 155 } 401 156 … … 471 226 /* setup the flags first to ensure they are initialized by the time the 472 227 * host heap is ready */ 473 int rc = vboxHGSMIReportFlagsLocation(pCtx, offVRAMFlagsLocation);228 int rc = VBoxHGSMIReportFlagsLocation(pCtx, offVRAMFlagsLocation); 474 229 AssertRC(rc); 475 230 if (RT_SUCCESS(rc) && fCaps) 476 231 { 477 232 /* Inform about caps */ 478 rc = vboxHGSMISendCapsInfo(pCtx, fCaps);233 rc = VBoxHGSMISendCapsInfo(pCtx, fCaps); 479 234 AssertRC(rc); 480 235 } … … 488 243 return rc; 489 244 } 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 value515 * @param pCtx the context containing the heap used516 * @param u32Index the index of the parameter to query,517 * @see VBVACONF32::u32Index518 * @param u32DefValue defaut value519 * @param pulValue where to store the value of the parameter on success520 */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 else550 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 failure565 * @param pCtx the context containing the heap to be used566 * @param fFlags cursor flags, @see VMMDevReqMousePointer::fFlags567 * @param cHotX horizontal position of the hot spot568 * @param cHotY vertical position of the hot spot569 * @param cWidth width in pixels of the cursor570 * @param cHeight height in pixels of the cursor571 * @param pPixels pixel data, @see VMMDevReqMousePointer for the format572 * @param cbLength size in bytes of the pixel data573 */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 else631 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 information639 * to re-position its own cursor (though this is currently unlikely). The640 * 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 else678 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 region685 * can be queried from VMMDev via an IOCTL. This VMMDev memory region will contain686 * 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 host693 * that the guest is currently reading the memory (OWNER flag?).694 * * guest writes: may be allocate a page for the host info and make695 * 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.