VirtualBox

source: vbox/trunk/include/VBox/HGSMI/HGSMI.h@ 35350

Last change on this file since 35350 was 34727, checked in by vboxsync, 14 years ago

gcc-4.5 does not compile this assertion

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 11.8 KB
Line 
1/** @file
2 *
3 * VBox Host Guest Shared Memory Interface (HGSMI).
4 * Host/Guest shared part.
5 */
6
7/*
8 * Copyright (C) 2006-2008 Oracle Corporation
9 *
10 * This file is part of VirtualBox Open Source Edition (OSE), as
11 * available from http://www.virtualbox.org. This file is free software;
12 * you can redistribute it and/or modify it under the terms of the GNU
13 * General Public License (GPL) as published by the Free Software
14 * Foundation, in version 2 as it comes in the "COPYING" file of the
15 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
16 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
17 *
18 * The contents of this file may alternatively be used under the terms
19 * of the Common Development and Distribution License Version 1.0
20 * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
21 * VirtualBox OSE distribution, in which case the provisions of the
22 * CDDL are applicable instead of those of the GPL.
23 *
24 * You may elect to license modified versions of this file under the
25 * terms and conditions of either the GPL or the CDDL or both.
26 */
27
28
29#ifndef __HGSMI_h__
30#define __HGSMI_h__
31
32#include <iprt/assert.h>
33#include <iprt/types.h>
34
35#include <VBox/HGSMI/HGSMIChannels.h>
36
37/* HGSMI uses 32 bit offsets and sizes. */
38typedef uint32_t HGSMISIZE;
39typedef uint32_t HGSMIOFFSET;
40
41#define HGSMIOFFSET_VOID ((HGSMIOFFSET)~0)
42
43/*
44 * Basic mechanism for the HGSMI is to prepare and pass data buffer to the host and the guest.
45 * Data inside these buffers are opaque for the HGSMI and are interpreted by higher levels.
46 *
47 * Every shared memory buffer passed between the guest/host has the following structure:
48 *
49 * HGSMIBUFFERHEADER header;
50 * uint8_t data[header.u32BufferSize];
51 * HGSMIBUFFERTAIL tail;
52 *
53 * Note: Offset of the 'header' in the memory is used for virtual hardware IO.
54 *
55 * Buffers are verifyed using the offset and the content of the header and the tail,
56 * which are constant during a call.
57 *
58 * Invalid buffers are ignored.
59 *
60 * Actual 'data' is not verifyed, as it is expected that the data can be changed by the
61 * called function.
62 *
63 * Since only the offset of the buffer is passed in a IO operation, the header and tail
64 * must contain:
65 * * size of data in this buffer;
66 * * checksum for buffer verification.
67 *
68 * For segmented transfers:
69 * * the sequence identifier;
70 * * offset of the current segment in the sequence;
71 * * total bytes in the transfer.
72 *
73 * Additionally contains:
74 * * the channel ID;
75 * * the channel information.
76 */
77
78
79/* Describes a shared memory area buffer.
80 * Used for calculations with offsets and for buffers verification.
81 */
82typedef struct _HGSMIAREA
83{
84 uint8_t *pu8Base; /* The starting address of the area. Corresponds to offset 'offBase'. */
85 HGSMIOFFSET offBase; /* The starting offset of the area. */
86 HGSMIOFFSET offLast; /* The last valid offset:
87 * offBase + cbArea - 1 - (sizeof (header) + sizeof (tail)).
88 */
89 HGSMISIZE cbArea; /* Size of the area. */
90} HGSMIAREA;
91
92
93/* The buffer description flags. */
94#define HGSMI_BUFFER_HEADER_F_SEQ_MASK 0x03 /* Buffer sequence type mask. */
95#define HGSMI_BUFFER_HEADER_F_SEQ_SINGLE 0x00 /* Single buffer, not a part of a sequence. */
96#define HGSMI_BUFFER_HEADER_F_SEQ_START 0x01 /* The first buffer in a sequence. */
97#define HGSMI_BUFFER_HEADER_F_SEQ_CONTINUE 0x02 /* A middle buffer in a sequence. */
98#define HGSMI_BUFFER_HEADER_F_SEQ_END 0x03 /* The last buffer in a sequence. */
99
100
101#pragma pack(1)
102/* 16 bytes buffer header. */
103typedef struct _HGSMIBUFFERHEADER
104{
105 uint32_t u32DataSize; /* Size of data that follows the header. */
106
107 uint8_t u8Flags; /* The buffer description: HGSMI_BUFFER_HEADER_F_* */
108
109 uint8_t u8Channel; /* The channel the data must be routed to. */
110 uint16_t u16ChannelInfo; /* Opaque to the HGSMI, used by the channel. */
111
112 union {
113 uint8_t au8Union[8]; /* Opaque placeholder to make the union 8 bytes. */
114
115 struct
116 { /* HGSMI_BUFFER_HEADER_F_SEQ_SINGLE */
117 uint32_t u32Reserved1; /* A reserved field, initialize to 0. */
118 uint32_t u32Reserved2; /* A reserved field, initialize to 0. */
119 } Buffer;
120
121 struct
122 { /* HGSMI_BUFFER_HEADER_F_SEQ_START */
123 uint32_t u32SequenceNumber; /* The sequence number, the same for all buffers in the sequence. */
124 uint32_t u32SequenceSize; /* The total size of the sequence. */
125 } SequenceStart;
126
127 struct
128 { /* HGSMI_BUFFER_HEADER_F_SEQ_CONTINUE and HGSMI_BUFFER_HEADER_F_SEQ_END */
129 uint32_t u32SequenceNumber; /* The sequence number, the same for all buffers in the sequence. */
130 uint32_t u32SequenceOffset; /* Data offset in the entire sequence. */
131 } SequenceContinue;
132 } u;
133
134} HGSMIBUFFERHEADER;
135
136/* 8 bytes buffer tail. */
137typedef struct _HGSMIBUFFERTAIL
138{
139 uint32_t u32Reserved; /* Reserved, must be initialized to 0. */
140 uint32_t u32Checksum; /* Verifyer for the buffer header and offset and for first 4 bytes of the tail. */
141} HGSMIBUFFERTAIL;
142#pragma pack()
143
144AssertCompile(sizeof (HGSMIBUFFERHEADER) == 16);
145AssertCompile(sizeof (HGSMIBUFFERTAIL) == 8);
146
147
148#pragma pack(1)
149typedef struct _HGSMIHEAP
150{
151 union
152 {
153 RTHEAPSIMPLE hPtr; /**< Pointer based heap. */
154 RTHEAPOFFSET hOff; /**< Offset based heap. */
155 } u;
156 HGSMIAREA area; /**< Description. */
157 int cRefs; /**< Number of heap allocations. */
158 bool fOffsetBased; /**< Set if offset based. */
159} HGSMIHEAP;
160#pragma pack()
161
162#pragma pack(1)
163/* The size of the array of channels. Array indexes are uint8_t. Note: the value must not be changed. */
164#define HGSMI_NUMBER_OF_CHANNELS 0x100
165
166/* Channel handler called when the guest submits a buffer. */
167typedef DECLCALLBACK(int) FNHGSMICHANNELHANDLER(void *pvHandler, uint16_t u16ChannelInfo, void *pvBuffer, HGSMISIZE cbBuffer);
168typedef FNHGSMICHANNELHANDLER *PFNHGSMICHANNELHANDLER;
169
170/* Information about a handler: pfn + context. */
171typedef struct _HGSMICHANNELHANDLER
172{
173 PFNHGSMICHANNELHANDLER pfnHandler;
174 void *pvHandler;
175} HGSMICHANNELHANDLER;
176
177/* Channel description. */
178typedef struct _HGSMICHANNEL
179{
180 HGSMICHANNELHANDLER handler; /* The channel handler. */
181 const char *pszName; /* NULL for hardcoded channels or RTStrDup'ed name. */
182 uint8_t u8Channel; /* The channel id, equal to the channel index in the array. */
183 uint8_t u8Flags; /* HGSMI_CH_F_* */
184} HGSMICHANNEL;
185
186typedef struct _HGSMICHANNELINFO
187{
188 HGSMICHANNEL Channels[HGSMI_NUMBER_OF_CHANNELS]; /* Channel handlers indexed by the channel id.
189 * The array is accessed under the instance lock.
190 */
191} HGSMICHANNELINFO;
192#pragma pack()
193
194
195RT_C_DECLS_BEGIN
196
197DECLINLINE(HGSMISIZE) HGSMIBufferMinimumSize (void)
198{
199 return sizeof (HGSMIBUFFERHEADER) + sizeof (HGSMIBUFFERTAIL);
200}
201
202DECLINLINE(uint8_t *) HGSMIBufferData (const HGSMIBUFFERHEADER *pHeader)
203{
204 return (uint8_t *)pHeader + sizeof (HGSMIBUFFERHEADER);
205}
206
207DECLINLINE(HGSMIBUFFERTAIL *) HGSMIBufferTail (const HGSMIBUFFERHEADER *pHeader)
208{
209 return (HGSMIBUFFERTAIL *)(HGSMIBufferData (pHeader) + pHeader->u32DataSize);
210}
211
212DECLINLINE(HGSMIBUFFERHEADER *) HGSMIBufferHeaderFromData (const void *pvData)
213{
214 return (HGSMIBUFFERHEADER *)((uint8_t *)pvData - sizeof (HGSMIBUFFERHEADER));
215}
216
217DECLINLINE(HGSMISIZE) HGSMIBufferRequiredSize (uint32_t u32DataSize)
218{
219 return HGSMIBufferMinimumSize () + u32DataSize;
220}
221
222DECLINLINE(HGSMIOFFSET) HGSMIPointerToOffset (const HGSMIAREA *pArea,
223 const HGSMIBUFFERHEADER *pHeader)
224{
225 return pArea->offBase + (HGSMIOFFSET)((uint8_t *)pHeader - pArea->pu8Base);
226}
227
228DECLINLINE(HGSMIBUFFERHEADER *) HGSMIOffsetToPointer (const HGSMIAREA *pArea,
229 HGSMIOFFSET offBuffer)
230{
231 return (HGSMIBUFFERHEADER *)(pArea->pu8Base + (offBuffer - pArea->offBase));
232}
233
234DECLINLINE(uint8_t *) HGSMIBufferDataFromOffset (const HGSMIAREA *pArea, HGSMIOFFSET offBuffer)
235{
236 HGSMIBUFFERHEADER *pHeader = HGSMIOffsetToPointer (pArea, offBuffer);
237 Assert(pHeader);
238 if(pHeader)
239 return HGSMIBufferData(pHeader);
240 return NULL;
241}
242
243DECLINLINE(uint8_t *) HGSMIBufferDataAndChInfoFromOffset (const HGSMIAREA *pArea, HGSMIOFFSET offBuffer, uint16_t * pChInfo)
244{
245 HGSMIBUFFERHEADER *pHeader = HGSMIOffsetToPointer (pArea, offBuffer);
246 Assert(pHeader);
247 if(pHeader)
248 {
249 *pChInfo = pHeader->u16ChannelInfo;
250 return HGSMIBufferData(pHeader);
251 }
252 return NULL;
253}
254
255HGSMICHANNEL *HGSMIChannelFindById (HGSMICHANNELINFO * pChannelInfo, uint8_t u8Channel);
256
257uint32_t HGSMIChecksum (HGSMIOFFSET offBuffer,
258 const HGSMIBUFFERHEADER *pHeader,
259 const HGSMIBUFFERTAIL *pTail);
260
261int HGSMIAreaInitialize (HGSMIAREA *pArea,
262 void *pvBase,
263 HGSMISIZE cbArea,
264 HGSMIOFFSET offBase);
265
266void HGSMIAreaClear (HGSMIAREA *pArea);
267
268DECLINLINE(bool) HGSMIAreaContainsOffset(HGSMIAREA *pArea, HGSMIOFFSET offSet)
269{
270 return pArea->offBase <= offSet && pArea->offBase + pArea->cbArea > offSet;
271}
272
273HGSMIOFFSET HGSMIBufferInitializeSingle (const HGSMIAREA *pArea,
274 HGSMIBUFFERHEADER *pHeader,
275 HGSMISIZE cbBuffer,
276 uint8_t u8Channel,
277 uint16_t u16ChannelInfo);
278
279int HGSMIHeapSetup (HGSMIHEAP *pHeap,
280 void *pvBase,
281 HGSMISIZE cbArea,
282 HGSMIOFFSET offBase,
283 bool fOffsetBased);
284
285int HGSMIHeapRelocate (HGSMIHEAP *pHeap,
286 void *pvBase,
287 uint32_t offHeapHandle,
288 uintptr_t offDelta,
289 HGSMISIZE cbArea,
290 HGSMIOFFSET offBase,
291 bool fOffsetBased);
292
293void HGSMIHeapSetupUnitialized (HGSMIHEAP *pHeap);
294bool HGSMIHeapIsItialized (HGSMIHEAP *pHeap);
295
296void HGSMIHeapDestroy (HGSMIHEAP *pHeap);
297
298void *HGSMIHeapAlloc (HGSMIHEAP *pHeap,
299 HGSMISIZE cbData,
300 uint8_t u8Channel,
301 uint16_t u16ChannelInfo);
302
303HGSMIOFFSET HGSMIHeapBufferOffset (HGSMIHEAP *pHeap,
304 void *pvData);
305
306void HGSMIHeapFree (HGSMIHEAP *pHeap,
307 void *pvData);
308
309DECLINLINE(HGSMIOFFSET) HGSMIHeapOffset(HGSMIHEAP *pHeap)
310{
311 return pHeap->area.offBase;
312}
313
314/* needed for heap relocation */
315DECLINLINE(HGSMIOFFSET) HGSMIHeapHandleLocationOffset(HGSMIHEAP *pHeap)
316{
317#if (__GNUC__ * 100 + __GNUC_MINOR__) < 405
318 /* does not work with gcc-4.5 */
319 AssertCompile((uintptr_t)NIL_RTHEAPSIMPLE == (uintptr_t)NIL_RTHEAPOFFSET);
320#endif
321 return pHeap->u.hPtr != NIL_RTHEAPSIMPLE
322 ? (HGSMIOFFSET)(pHeap->area.pu8Base - (uint8_t*)pHeap->u.hPtr)
323 : HGSMIOFFSET_VOID;
324}
325
326DECLINLINE(HGSMISIZE) HGSMIHeapSize(HGSMIHEAP *pHeap)
327{
328 return pHeap->area.cbArea;
329}
330
331int HGSMIChannelRegister (HGSMICHANNELINFO * pChannelInfo,
332 uint8_t u8Channel,
333 const char *pszName,
334 PFNHGSMICHANNELHANDLER pfnChannelHandler,
335 void *pvChannelHandler,
336 HGSMICHANNELHANDLER *pOldHandler);
337
338int HGSMIBufferProcess (HGSMIAREA *pArea,
339 HGSMICHANNELINFO * pChannelInfo,
340 HGSMIOFFSET offBuffer);
341RT_C_DECLS_END
342
343#endif /* __HGSMI_h__*/
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette