/** @file | |
* | |
* VBox Host Guest Shared Memory Interface (HGSMI). | |
* OS-independent guest structures. | |
*/ | |
/* | |
* Copyright (C) 2006-2015 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 <VBox/HGSMI/HGSMI.h> | |
#include <VBox/HGSMI/HGSMIChSetup.h> | |
#include <VBox/VBoxVideo.h> | |
#ifdef VBOX_XPDM_MINIPORT | |
RT_C_DECLS_BEGIN | |
# include "miniport.h" | |
# include "ntddvdeo.h" | |
# include <Video.h> | |
RT_C_DECLS_END | |
#elif defined VBOX_GUESTR3XORGMOD | |
# include <compiler.h> | |
#else | |
# include <iprt/asm-amd64-x86.h> | |
#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) VBoxHGSMIReportFlagsLocation(PHGSMIGUESTCOMMANDCONTEXT pCtx, | |
HGSMIOFFSET offLocation); | |
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) VBoxHGSMIDestroyGuestContext(HGSMIGUESTCOMMANDCONTEXT *); | |
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) VBoxQueryConfHGSMIDef(PHGSMIGUESTCOMMANDCONTEXT pCtx, | |
uint32_t u32Index, uint32_t u32DefValue, 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__*/ |