1e07dc26bSmrg/* 2e07dc26bSmrg * Copyright (C) 2006-2017 Oracle Corporation 3e07dc26bSmrg * 4e07dc26bSmrg * Permission is hereby granted, free of charge, to any person obtaining a 5e07dc26bSmrg * copy of this software and associated documentation files (the "Software"), 6e07dc26bSmrg * to deal in the Software without restriction, including without limitation 7e07dc26bSmrg * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8e07dc26bSmrg * and/or sell copies of the Software, and to permit persons to whom the 9e07dc26bSmrg * Software is furnished to do so, subject to the following conditions: 10e07dc26bSmrg * 11e07dc26bSmrg * The above copyright notice and this permission notice shall be included in 12e07dc26bSmrg * all copies or substantial portions of the Software. 13e07dc26bSmrg * 14e07dc26bSmrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15e07dc26bSmrg * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16e07dc26bSmrg * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17e07dc26bSmrg * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 18e07dc26bSmrg * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19e07dc26bSmrg * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20e07dc26bSmrg * OTHER DEALINGS IN THE SOFTWARE. 21e07dc26bSmrg */ 22e07dc26bSmrg 23e07dc26bSmrg 24e07dc26bSmrg#ifndef ___VBox_Graphics_HGSMI_h 25e07dc26bSmrg#define ___VBox_Graphics_HGSMI_h 26e07dc26bSmrg 27e07dc26bSmrg#include "VBoxVideoIPRT.h" 28e07dc26bSmrg 29e07dc26bSmrg#include "HGSMIDefs.h" 30e07dc26bSmrg#include "HGSMIChannels.h" 31e07dc26bSmrg#include "HGSMIMemAlloc.h" 32e07dc26bSmrg 33e07dc26bSmrg/* 34e07dc26bSmrg * Basic mechanism for the HGSMI is to prepare and pass data buffer to the host and the guest. 35e07dc26bSmrg * Data inside these buffers are opaque for the HGSMI and are interpreted by higher levels. 36e07dc26bSmrg * 37e07dc26bSmrg * Every shared memory buffer passed between the guest/host has the following structure: 38e07dc26bSmrg * 39e07dc26bSmrg * HGSMIBUFFERHEADER header; 40e07dc26bSmrg * uint8_t data[header.u32BufferSize]; 41e07dc26bSmrg * HGSMIBUFFERTAIL tail; 42e07dc26bSmrg * 43e07dc26bSmrg * Note: Offset of the 'header' in the memory is used for virtual hardware IO. 44e07dc26bSmrg * 45e07dc26bSmrg * Buffers are verifyed using the offset and the content of the header and the tail, 46e07dc26bSmrg * which are constant during a call. 47e07dc26bSmrg * 48e07dc26bSmrg * Invalid buffers are ignored. 49e07dc26bSmrg * 50e07dc26bSmrg * Actual 'data' is not verifyed, as it is expected that the data can be changed by the 51e07dc26bSmrg * called function. 52e07dc26bSmrg * 53e07dc26bSmrg * Since only the offset of the buffer is passed in a IO operation, the header and tail 54e07dc26bSmrg * must contain: 55e07dc26bSmrg * * size of data in this buffer; 56e07dc26bSmrg * * checksum for buffer verification. 57e07dc26bSmrg * 58e07dc26bSmrg * For segmented transfers: 59e07dc26bSmrg * * the sequence identifier; 60e07dc26bSmrg * * offset of the current segment in the sequence; 61e07dc26bSmrg * * total bytes in the transfer. 62e07dc26bSmrg * 63e07dc26bSmrg * Additionally contains: 64e07dc26bSmrg * * the channel ID; 65e07dc26bSmrg * * the channel information. 66e07dc26bSmrg */ 67e07dc26bSmrg 68e07dc26bSmrgtypedef struct HGSMIHEAP 69e07dc26bSmrg{ 70e07dc26bSmrg HGSMIAREA area; /* Description. */ 71e07dc26bSmrg HGSMIMADATA ma; /* Memory allocator */ 72e07dc26bSmrg} HGSMIHEAP; 73e07dc26bSmrg 74e07dc26bSmrg/* The size of the array of channels. Array indexes are uint8_t. Note: the value must not be changed. */ 75e07dc26bSmrg#define HGSMI_NUMBER_OF_CHANNELS 0x100 76e07dc26bSmrg 77e07dc26bSmrg/* Channel handler called when the guest submits a buffer. */ 78e07dc26bSmrgtypedef DECLCALLBACK(int) FNHGSMICHANNELHANDLER(void *pvHandler, uint16_t u16ChannelInfo, void *pvBuffer, HGSMISIZE cbBuffer); 79e07dc26bSmrgtypedef FNHGSMICHANNELHANDLER *PFNHGSMICHANNELHANDLER; 80e07dc26bSmrg 81e07dc26bSmrg/* Information about a handler: pfn + context. */ 82e07dc26bSmrgtypedef struct _HGSMICHANNELHANDLER 83e07dc26bSmrg{ 84e07dc26bSmrg PFNHGSMICHANNELHANDLER pfnHandler; 85e07dc26bSmrg void *pvHandler; 86e07dc26bSmrg} HGSMICHANNELHANDLER; 87e07dc26bSmrg 88e07dc26bSmrg/* Channel description. */ 89e07dc26bSmrgtypedef struct _HGSMICHANNEL 90e07dc26bSmrg{ 91e07dc26bSmrg HGSMICHANNELHANDLER handler; /* The channel handler. */ 92e07dc26bSmrg const char *pszName; /* NULL for hardcoded channels or RTStrDup'ed name. */ 93e07dc26bSmrg uint8_t u8Channel; /* The channel id, equal to the channel index in the array. */ 94e07dc26bSmrg uint8_t u8Flags; /* HGSMI_CH_F_* */ 95e07dc26bSmrg} HGSMICHANNEL; 96e07dc26bSmrg 97e07dc26bSmrgtypedef struct _HGSMICHANNELINFO 98e07dc26bSmrg{ 99e07dc26bSmrg HGSMICHANNEL Channels[HGSMI_NUMBER_OF_CHANNELS]; /* Channel handlers indexed by the channel id. 100e07dc26bSmrg * The array is accessed under the instance lock. 101e07dc26bSmrg */ 102e07dc26bSmrg} HGSMICHANNELINFO; 103e07dc26bSmrg 104e07dc26bSmrg 105e07dc26bSmrgRT_C_DECLS_BEGIN 106e07dc26bSmrg 107e07dc26bSmrgDECLINLINE(HGSMIBUFFERHEADER *) HGSMIBufferHeaderFromPtr(void *pvBuffer) 108e07dc26bSmrg{ 109e07dc26bSmrg return (HGSMIBUFFERHEADER *)pvBuffer; 110e07dc26bSmrg} 111e07dc26bSmrg 112e07dc26bSmrgDECLINLINE(uint8_t *) HGSMIBufferDataFromPtr(void *pvBuffer) 113e07dc26bSmrg{ 114e07dc26bSmrg return (uint8_t *)pvBuffer + sizeof(HGSMIBUFFERHEADER); 115e07dc26bSmrg} 116e07dc26bSmrg 117e07dc26bSmrgDECLINLINE(HGSMIBUFFERTAIL *) HGSMIBufferTailFromPtr(void *pvBuffer, 118e07dc26bSmrg uint32_t u32DataSize) 119e07dc26bSmrg{ 120e07dc26bSmrg return (HGSMIBUFFERTAIL *)(HGSMIBufferDataFromPtr(pvBuffer) + u32DataSize); 121e07dc26bSmrg} 122e07dc26bSmrg 123e07dc26bSmrgDECLINLINE(HGSMISIZE) HGSMIBufferMinimumSize(void) 124e07dc26bSmrg{ 125e07dc26bSmrg return sizeof(HGSMIBUFFERHEADER) + sizeof(HGSMIBUFFERTAIL); 126e07dc26bSmrg} 127e07dc26bSmrg 128e07dc26bSmrgDECLINLINE(HGSMIBUFFERHEADER *) HGSMIBufferHeaderFromData(const void *pvData) 129e07dc26bSmrg{ 130e07dc26bSmrg return (HGSMIBUFFERHEADER *)((uint8_t *)pvData - sizeof(HGSMIBUFFERHEADER)); 131e07dc26bSmrg} 132e07dc26bSmrg 133e07dc26bSmrgDECLINLINE(HGSMISIZE) HGSMIBufferRequiredSize(uint32_t u32DataSize) 134e07dc26bSmrg{ 135e07dc26bSmrg return HGSMIBufferMinimumSize() + u32DataSize; 136e07dc26bSmrg} 137e07dc26bSmrg 138e07dc26bSmrgDECLINLINE(HGSMIOFFSET) HGSMIPointerToOffset(const HGSMIAREA *pArea, 139e07dc26bSmrg const void *pv) 140e07dc26bSmrg{ 141e07dc26bSmrg return pArea->offBase + (HGSMIOFFSET)((uint8_t *)pv - pArea->pu8Base); 142e07dc26bSmrg} 143e07dc26bSmrg 144e07dc26bSmrgDECLINLINE(void *) HGSMIOffsetToPointer(const HGSMIAREA *pArea, 145e07dc26bSmrg HGSMIOFFSET offBuffer) 146e07dc26bSmrg{ 147e07dc26bSmrg return pArea->pu8Base + (offBuffer - pArea->offBase); 148e07dc26bSmrg} 149e07dc26bSmrg 150e07dc26bSmrgDECLINLINE(uint8_t *) HGSMIBufferDataFromOffset(const HGSMIAREA *pArea, 151e07dc26bSmrg HGSMIOFFSET offBuffer) 152e07dc26bSmrg{ 153e07dc26bSmrg void *pvBuffer = HGSMIOffsetToPointer(pArea, offBuffer); 154e07dc26bSmrg return HGSMIBufferDataFromPtr(pvBuffer); 155e07dc26bSmrg} 156e07dc26bSmrg 157e07dc26bSmrgDECLINLINE(HGSMIOFFSET) HGSMIBufferOffsetFromData(const HGSMIAREA *pArea, 158e07dc26bSmrg void *pvData) 159e07dc26bSmrg{ 160e07dc26bSmrg HGSMIBUFFERHEADER *pHeader = HGSMIBufferHeaderFromData(pvData); 161e07dc26bSmrg return HGSMIPointerToOffset(pArea, pHeader); 162e07dc26bSmrg} 163e07dc26bSmrg 164e07dc26bSmrgDECLINLINE(uint8_t *) HGSMIBufferDataAndChInfoFromOffset(const HGSMIAREA *pArea, 165e07dc26bSmrg HGSMIOFFSET offBuffer, 166e07dc26bSmrg uint16_t *pu16ChannelInfo) 167e07dc26bSmrg{ 168e07dc26bSmrg HGSMIBUFFERHEADER *pHeader = (HGSMIBUFFERHEADER *)HGSMIOffsetToPointer(pArea, offBuffer); 169e07dc26bSmrg *pu16ChannelInfo = pHeader->u16ChannelInfo; 170e07dc26bSmrg return HGSMIBufferDataFromPtr(pHeader); 171e07dc26bSmrg} 172e07dc26bSmrg 173e07dc26bSmrguint32_t HGSMIChecksum(HGSMIOFFSET offBuffer, 174e07dc26bSmrg const HGSMIBUFFERHEADER *pHeader, 175e07dc26bSmrg const HGSMIBUFFERTAIL *pTail); 176e07dc26bSmrg 177e07dc26bSmrgint HGSMIAreaInitialize(HGSMIAREA *pArea, 178e07dc26bSmrg void *pvBase, 179e07dc26bSmrg HGSMISIZE cbArea, 180e07dc26bSmrg HGSMIOFFSET offBase); 181e07dc26bSmrg 182e07dc26bSmrgvoid HGSMIAreaClear(HGSMIAREA *pArea); 183e07dc26bSmrg 184e07dc26bSmrgDECLINLINE(bool) HGSMIAreaContainsOffset(const HGSMIAREA *pArea, HGSMIOFFSET off) 185e07dc26bSmrg{ 186e07dc26bSmrg return off >= pArea->offBase && off - pArea->offBase < pArea->cbArea; 187e07dc26bSmrg} 188e07dc26bSmrg 189e07dc26bSmrgDECLINLINE(bool) HGSMIAreaContainsPointer(const HGSMIAREA *pArea, const void *pv) 190e07dc26bSmrg{ 191e07dc26bSmrg return (uintptr_t)pv >= (uintptr_t)pArea->pu8Base && (uintptr_t)pv - (uintptr_t)pArea->pu8Base < pArea->cbArea; 192e07dc26bSmrg} 193e07dc26bSmrg 194e07dc26bSmrgHGSMIOFFSET HGSMIBufferInitializeSingle(const HGSMIAREA *pArea, 195e07dc26bSmrg HGSMIBUFFERHEADER *pHeader, 196e07dc26bSmrg HGSMISIZE cbBuffer, 197e07dc26bSmrg uint8_t u8Channel, 198e07dc26bSmrg uint16_t u16ChannelInfo); 199e07dc26bSmrg 200e07dc26bSmrgint HGSMIHeapSetup(HGSMIHEAP *pHeap, 201e07dc26bSmrg void *pvBase, 202e07dc26bSmrg HGSMISIZE cbArea, 203e07dc26bSmrg HGSMIOFFSET offBase, 204e07dc26bSmrg const HGSMIENV *pEnv); 205e07dc26bSmrg 206e07dc26bSmrgvoid HGSMIHeapDestroy(HGSMIHEAP *pHeap); 207e07dc26bSmrg 208e07dc26bSmrgvoid *HGSMIHeapBufferAlloc(HGSMIHEAP *pHeap, 209e07dc26bSmrg HGSMISIZE cbBuffer); 210e07dc26bSmrg 211e07dc26bSmrgvoid HGSMIHeapBufferFree(HGSMIHEAP *pHeap, 212e07dc26bSmrg void *pvBuf); 213e07dc26bSmrg 214e07dc26bSmrgvoid *HGSMIHeapAlloc(HGSMIHEAP *pHeap, 215e07dc26bSmrg HGSMISIZE cbData, 216e07dc26bSmrg uint8_t u8Channel, 217e07dc26bSmrg uint16_t u16ChannelInfo); 218e07dc26bSmrg 219e07dc26bSmrgvoid HGSMIHeapFree(HGSMIHEAP *pHeap, 220e07dc26bSmrg void *pvData); 221e07dc26bSmrg 222e07dc26bSmrgDECLINLINE(const HGSMIAREA *) HGSMIHeapArea(HGSMIHEAP *pHeap) 223e07dc26bSmrg{ 224e07dc26bSmrg return &pHeap->area; 225e07dc26bSmrg} 226e07dc26bSmrg 227e07dc26bSmrgDECLINLINE(HGSMIOFFSET) HGSMIHeapOffset(HGSMIHEAP *pHeap) 228e07dc26bSmrg{ 229e07dc26bSmrg return HGSMIHeapArea(pHeap)->offBase; 230e07dc26bSmrg} 231e07dc26bSmrg 232e07dc26bSmrgDECLINLINE(HGSMISIZE) HGSMIHeapSize(HGSMIHEAP *pHeap) 233e07dc26bSmrg{ 234e07dc26bSmrg return HGSMIHeapArea(pHeap)->cbArea; 235e07dc26bSmrg} 236e07dc26bSmrg 237e07dc26bSmrgDECLINLINE(HGSMIOFFSET) HGSMIHeapBufferOffset(HGSMIHEAP *pHeap, 238e07dc26bSmrg void *pvData) 239e07dc26bSmrg{ 240e07dc26bSmrg return HGSMIBufferOffsetFromData(HGSMIHeapArea(pHeap), pvData); 241e07dc26bSmrg} 242e07dc26bSmrg 243e07dc26bSmrgHGSMICHANNEL *HGSMIChannelFindById(HGSMICHANNELINFO *pChannelInfo, 244e07dc26bSmrg uint8_t u8Channel); 245e07dc26bSmrg 246e07dc26bSmrgint HGSMIChannelRegister(HGSMICHANNELINFO *pChannelInfo, 247e07dc26bSmrg uint8_t u8Channel, 248e07dc26bSmrg const char *pszName, 249e07dc26bSmrg PFNHGSMICHANNELHANDLER pfnChannelHandler, 250e07dc26bSmrg void *pvChannelHandler); 251e07dc26bSmrg 252e07dc26bSmrgint HGSMIBufferProcess(const HGSMIAREA *pArea, 253e07dc26bSmrg HGSMICHANNELINFO *pChannelInfo, 254e07dc26bSmrg HGSMIOFFSET offBuffer); 255e07dc26bSmrgRT_C_DECLS_END 256e07dc26bSmrg 257e07dc26bSmrg#endif /* !___VBox_Graphics_HGSMI_h */ 258e07dc26bSmrg 259