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