/** @file * * VBox Host Guest Shared Memory Interface (HGSMI). * OS-independent guest structures. */ /* * Copyright (C) 2006-2012 Oracle Corporation * * This file is part of VirtualBox Open Source Edition (OSE), as * available from http://www.virtualbox.org. This file is free software; * you can redistribute it and/or modify it under the terms of the GNU * General Public License (GPL) as published by the Free Software * Foundation, in version 2 as it comes in the "COPYING" file of the * VirtualBox OSE distribution. VirtualBox OSE is distributed in the * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind. * * The contents of this file may alternatively be used under the terms * of the Common Development and Distribution License Version 1.0 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the * VirtualBox OSE distribution, in which case the provisions of the * CDDL are applicable instead of those of the GPL. * * You may elect to license modified versions of this file under the * terms and conditions of either the GPL or the CDDL or both. */ #ifndef __HGSMI_GUEST_h__ #define __HGSMI_GUEST_h__ #include #include #include #ifdef VBOX_XPDM_MINIPORT RT_C_DECLS_BEGIN # include "miniport.h" # include "ntddvdeo.h" # include RT_C_DECLS_END #elif defined VBOX_GUESTR3XORGMOD # include #else # include #endif #ifdef VBOX_WDDM_MINIPORT # include "wddm/VBoxMPShgsmi.h" typedef VBOXSHGSMI HGSMIGUESTCMDHEAP; # define HGSMIGUESTCMDHEAP_GET(_p) (&(_p)->Heap) #else typedef HGSMIHEAP HGSMIGUESTCMDHEAP; # define HGSMIGUESTCMDHEAP_GET(_p) (_p) #endif RT_C_DECLS_BEGIN /** * Structure grouping the context needed for submitting commands to the host * via HGSMI */ typedef struct HGSMIGUESTCOMMANDCONTEXT { /** Information about the memory heap located in VRAM from which data * structures to be sent to the host are allocated. */ HGSMIGUESTCMDHEAP heapCtx; /** The I/O port used for submitting commands to the host by writing their * offsets into the heap. */ RTIOPORT port; } HGSMIGUESTCOMMANDCONTEXT, *PHGSMIGUESTCOMMANDCONTEXT; /** * Structure grouping the context needed for receiving commands from the host * via HGSMI */ typedef struct HGSMIHOSTCOMMANDCONTEXT { /** Information about the memory area located in VRAM in which the host * places data structures to be read by the guest. */ HGSMIAREA areaCtx; /** Convenience structure used for matching host commands to handlers. */ /** @todo handlers are registered individually in code rather than just * passing a static structure in order to gain extra flexibility. There is * currently no expected usage case for this though. Is the additional * complexity really justified? */ HGSMICHANNELINFO channels; /** Flag to indicate that one thread is currently processing the command * queue. */ volatile bool fHostCmdProcessing; /* Pointer to the VRAM location where the HGSMI host flags are kept. */ volatile HGSMIHOSTFLAGS *pfHostFlags; /** The I/O port used for receiving commands from the host as offsets into * the memory area and sending back confirmations (command completion, * IRQ acknowlegement). */ RTIOPORT port; } HGSMIHOSTCOMMANDCONTEXT, *PHGSMIHOSTCOMMANDCONTEXT; /** * Structure grouping the context needed for sending graphics acceleration * information to the host via VBVA. Each screen has its own VBVA buffer. */ typedef struct VBVABUFFERCONTEXT { /** Offset of the buffer in the VRAM section for the screen */ uint32_t offVRAMBuffer; /** Length of the buffer in bytes */ uint32_t cbBuffer; /** This flag is set if we wrote to the buffer faster than the host could * read it. */ bool fHwBufferOverflow; /** The VBVA record that we are currently preparing for the host, NULL if * none. */ struct VBVARECORD *pRecord; /** Pointer to the VBVA buffer mapped into the current address space. Will * be NULL if VBVA is not enabled. */ struct VBVABUFFER *pVBVA; } VBVABUFFERCONTEXT, *PVBVABUFFERCONTEXT; /** @name Helper functions * @{ */ /** Write an 8-bit value to an I/O port. */ DECLINLINE(void) VBoxVideoCmnPortWriteUchar(RTIOPORT Port, uint8_t Value) { #ifdef VBOX_XPDM_MINIPORT VideoPortWritePortUchar((PUCHAR)Port, Value); #elif defined VBOX_GUESTR3XORGMOD outb(Port, Value); #else /** @todo make these explicit */ ASMOutU8(Port, Value); #endif } /** Write a 16-bit value to an I/O port. */ DECLINLINE(void) VBoxVideoCmnPortWriteUshort(RTIOPORT Port, uint16_t Value) { #ifdef VBOX_XPDM_MINIPORT VideoPortWritePortUshort((PUSHORT)Port,Value); #elif defined VBOX_GUESTR3XORGMOD outw(Port, Value); #else ASMOutU16(Port, Value); #endif } /** Write a 32-bit value to an I/O port. */ DECLINLINE(void) VBoxVideoCmnPortWriteUlong(RTIOPORT Port, uint32_t Value) { #ifdef VBOX_XPDM_MINIPORT VideoPortWritePortUlong((PULONG)Port,Value); #elif defined VBOX_GUESTR3XORGMOD outl(Port, Value); #else ASMOutU32(Port, Value); #endif } /** Read an 8-bit value from an I/O port. */ DECLINLINE(uint8_t) VBoxVideoCmnPortReadUchar(RTIOPORT Port) { #ifdef VBOX_XPDM_MINIPORT return VideoPortReadPortUchar((PUCHAR)Port); #elif defined VBOX_GUESTR3XORGMOD return inb(Port); #else return ASMInU8(Port); #endif } /** Read a 16-bit value from an I/O port. */ DECLINLINE(uint16_t) VBoxVideoCmnPortReadUshort(RTIOPORT Port) { #ifdef VBOX_XPDM_MINIPORT return VideoPortReadPortUshort((PUSHORT)Port); #elif defined VBOX_GUESTR3XORGMOD return inw(Port); #else return ASMInU16(Port); #endif } /** Read a 32-bit value from an I/O port. */ DECLINLINE(uint32_t) VBoxVideoCmnPortReadUlong(RTIOPORT Port) { #ifdef VBOX_XPDM_MINIPORT return VideoPortReadPortUlong((PULONG)Port); #elif defined VBOX_GUESTR3XORGMOD return inl(Port); #else return ASMInU32(Port); #endif } /** @} */ /** @name Base HGSMI APIs * @{ */ /** Acknowlege an IRQ. */ DECLINLINE(void) VBoxHGSMIClearIrq(PHGSMIHOSTCOMMANDCONTEXT pCtx) { VBoxVideoCmnPortWriteUlong(pCtx->port, HGSMIOFFSET_VOID); } RTDECL(void) VBoxHGSMIHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx, void *pvMem); RTDECL(void) VBoxHGSMIProcessHostQueue(PHGSMIHOSTCOMMANDCONTEXT pCtx); RTDECL(bool) VBoxHGSMIIsSupported(void); RTDECL(void *) VBoxHGSMIBufferAlloc(PHGSMIGUESTCOMMANDCONTEXT pCtx, HGSMISIZE cbData, uint8_t u8Ch, uint16_t u16Op); RTDECL(void) VBoxHGSMIBufferFree(PHGSMIGUESTCOMMANDCONTEXT pCtx, void *pvBuffer); RTDECL(int) VBoxHGSMIBufferSubmit(PHGSMIGUESTCOMMANDCONTEXT pCtx, void *pvBuffer); RTDECL(void) VBoxHGSMIGetBaseMappingInfo(uint32_t cbVRAM, uint32_t *poffVRAMBaseMapping, uint32_t *pcbMapping, uint32_t *poffGuestHeapMemory, uint32_t *pcbGuestHeapMemory, uint32_t *poffHostFlags); RTDECL(int) VBoxHGSMISendCapsInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t fCaps); /** @todo we should provide a cleanup function too as part of the API */ RTDECL(int) VBoxHGSMISetupGuestContext(PHGSMIGUESTCOMMANDCONTEXT pCtx, void *pvGuestHeapMemory, uint32_t cbGuestHeapMemory, uint32_t offVRAMGuestHeapMemory, const HGSMIENV *pEnv); RTDECL(void) VBoxHGSMIGetHostAreaMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t cbVRAM, uint32_t offVRAMBaseMapping, uint32_t *poffVRAMHostArea, uint32_t *pcbHostArea); RTDECL(void) VBoxHGSMISetupHostContext(PHGSMIHOSTCOMMANDCONTEXT pCtx, void *pvBaseMapping, uint32_t offHostFlags, void *pvHostAreaMapping, uint32_t offVRAMHostArea, uint32_t cbHostArea); RTDECL(int) VBoxHGSMISendHostCtxInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx, HGSMIOFFSET offVRAMFlagsLocation, uint32_t fCaps, uint32_t offVRAMHostArea, uint32_t cbHostArea); RTDECL(int) VBoxQueryConfHGSMI(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t u32Index, uint32_t *pulValue); RTDECL(int) VBoxHGSMIUpdatePointerShape(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t fFlags, uint32_t cHotX, uint32_t cHotY, uint32_t cWidth, uint32_t cHeight, uint8_t *pPixels, uint32_t cbLength); RTDECL(int) VBoxHGSMICursorPosition(PHGSMIGUESTCOMMANDCONTEXT pCtx, bool fReportPosition, uint32_t x, uint32_t y, uint32_t *pxHost, uint32_t *pyHost); /** @} */ /** @name VBVA APIs * @{ */ RTDECL(bool) VBoxVBVAEnable(PVBVABUFFERCONTEXT pCtx, PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, struct VBVABUFFER *pVBVA, int32_t cScreen); RTDECL(void) VBoxVBVADisable(PVBVABUFFERCONTEXT pCtx, PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, int32_t cScreen); RTDECL(bool) VBoxVBVABufferBeginUpdate(PVBVABUFFERCONTEXT pCtx, PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx); RTDECL(void) VBoxVBVABufferEndUpdate(PVBVABUFFERCONTEXT pCtx); RTDECL(bool) VBoxVBVAWrite(PVBVABUFFERCONTEXT pCtx, PHGSMIGUESTCOMMANDCONTEXT pHGSMICtx, const void *pv, uint32_t cb); RTDECL(bool) VBoxVBVAOrderSupported(PVBVABUFFERCONTEXT pCtx, unsigned code); RTDECL(void) VBoxVBVASetupBufferContext(PVBVABUFFERCONTEXT pCtx, uint32_t offVRAMBuffer, uint32_t cbBuffer); /** @} */ /** @name Modesetting APIs * @{ */ RTDECL(uint32_t) VBoxHGSMIGetMonitorCount(PHGSMIGUESTCOMMANDCONTEXT pCtx); RTDECL(uint32_t) VBoxVideoGetVRAMSize(void); RTDECL(bool) VBoxVideoAnyWidthAllowed(void); RTDECL(uint16_t) VBoxHGSMIGetScreenFlags(PHGSMIGUESTCOMMANDCONTEXT pCtx); struct VBVAINFOVIEW; /** * Callback funtion called from @a VBoxHGSMISendViewInfo to initialise * the @a VBVAINFOVIEW structure for each screen. * * @returns iprt status code * @param pvData context data for the callback, passed to @a * VBoxHGSMISendViewInfo along with the callback * @param pInfo array of @a VBVAINFOVIEW structures to be filled in * @todo explicitly pass the array size */ typedef DECLCALLBACK(int) FNHGSMIFILLVIEWINFO(void *pvData, struct VBVAINFOVIEW *pInfo, uint32_t cViews); /** Pointer to a FNHGSMIFILLVIEWINFO callback */ typedef FNHGSMIFILLVIEWINFO *PFNHGSMIFILLVIEWINFO; RTDECL(int) VBoxHGSMISendViewInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t u32Count, PFNHGSMIFILLVIEWINFO pfnFill, void *pvData); RTDECL(void) VBoxVideoSetModeRegisters(uint16_t cWidth, uint16_t cHeight, uint16_t cVirtWidth, uint16_t cBPP, uint16_t fFlags, uint16_t cx, uint16_t cy); RTDECL(bool) VBoxVideoGetModeRegisters(uint16_t *pcWidth, uint16_t *pcHeight, uint16_t *pcVirtWidth, uint16_t *pcBPP, uint16_t *pfFlags); RTDECL(void) VBoxVideoDisableVBE(void); RTDECL(void) VBoxHGSMIProcessDisplayInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx, uint32_t cDisplay, int32_t cOriginX, int32_t cOriginY, uint32_t offStart, uint32_t cbPitch, uint32_t cWidth, uint32_t cHeight, uint16_t cBPP, uint16_t fFlags); RTDECL(int) VBoxHGSMIUpdateInputMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx, int32_t cOriginX, int32_t cOriginY, uint32_t cWidth, uint32_t cHeight); RTDECL(int) VBoxHGSMIGetModeHints(PHGSMIGUESTCOMMANDCONTEXT pCtx, unsigned cScreens, VBVAMODEHINT *paHints); /** @} */ RT_C_DECLS_END #endif /* __HGSMI_GUEST_h__*/