VirtualBox

source: vbox/trunk/src/VBox/Devices/Graphics/DevVGA_VDMA.cpp@ 85561

Last change on this file since 85561 was 85121, checked in by vboxsync, 4 years ago

iprt/cdefs.h: Refactored the typedef use of DECLCALLBACK as well as DECLCALLBACKMEMBER to wrap the whole expression, similar to the DECLR?CALLBACKMEMBER macros. This allows adding a throw() at the end when compiling with the VC++ compiler to indicate that the callbacks won't throw anything, so we can stop supressing the C5039 warning about passing functions that can potential throw C++ exceptions to extern C code that can't necessarily cope with such (unwind,++). Introduced a few _EX variations that allows specifying different/no calling convention too, as that's handy when dynamically resolving host APIs. Fixed numerous places missing DECLCALLBACK and such. Left two angry @todos regarding use of CreateThread. bugref:9794

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.8 KB
Line 
1/* $Id: DevVGA_VDMA.cpp 85121 2020-07-08 19:33:26Z vboxsync $ */
2/** @file
3 * Video DMA (VDMA) support.
4 */
5
6/*
7 * Copyright (C) 2006-2020 Oracle Corporation
8 *
9 * This file is part of VirtualBox Open Source Edition (OSE), as
10 * available from http://www.virtualbox.org. This file is free software;
11 * you can redistribute it and/or modify it under the terms of the GNU
12 * General Public License (GPL) as published by the Free Software
13 * Foundation, in version 2 as it comes in the "COPYING" file of the
14 * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
15 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
16 */
17
18
19/*********************************************************************************************************************************
20* Header Files *
21*********************************************************************************************************************************/
22#define LOG_GROUP LOG_GROUP_DEV_VGA
23#include <VBox/VMMDev.h>
24#include <VBox/vmm/pdmdev.h>
25#include <VBox/vmm/pgm.h>
26#include <VBoxVideo.h>
27#include <VBox/AssertGuest.h>
28#include <iprt/semaphore.h>
29#include <iprt/thread.h>
30#include <iprt/mem.h>
31#include <iprt/asm.h>
32#include <iprt/list.h>
33#include <iprt/param.h>
34
35#include "DevVGA.h"
36#include "HGSMI/SHGSMIHost.h"
37
38#ifdef DEBUG_misha
39# define VBOXVDBG_MEMCACHE_DISABLE
40#endif
41
42#ifndef VBOXVDBG_MEMCACHE_DISABLE
43# include <iprt/memcache.h>
44#endif
45
46
47/*********************************************************************************************************************************
48* Defined Constants And Macros *
49*********************************************************************************************************************************/
50#ifdef DEBUG_misha
51# define WARN_BP() do { AssertFailed(); } while (0)
52#else
53# define WARN_BP() do { } while (0)
54#endif
55#define WARN(_msg) do { \
56 LogRel(_msg); \
57 WARN_BP(); \
58 } while (0)
59
60#define VBOXVDMATHREAD_STATE_TERMINATED 0
61#define VBOXVDMATHREAD_STATE_CREATING 1
62#define VBOXVDMATHREAD_STATE_CREATED 3
63#define VBOXVDMATHREAD_STATE_TERMINATING 4
64
65
66/*********************************************************************************************************************************
67* Structures and Typedefs *
68*********************************************************************************************************************************/
69struct VBOXVDMATHREAD;
70
71typedef DECLCALLBACKPTR(void, PFNVBOXVDMATHREAD_CHANGED,(struct VBOXVDMATHREAD *pThread, int rc,
72 void *pvThreadContext, void *pvChangeContext));
73
74typedef struct VBOXVDMATHREAD
75{
76 RTTHREAD hWorkerThread;
77 RTSEMEVENT hEvent;
78 volatile uint32_t u32State;
79 PFNVBOXVDMATHREAD_CHANGED pfnChanged;
80 void *pvChanged;
81} VBOXVDMATHREAD, *PVBOXVDMATHREAD;
82
83
84/* state transformations:
85 *
86 * submitter | processor
87 *
88 * LISTENING ---> PROCESSING
89 *
90 * */
91#define VBVAEXHOSTCONTEXT_STATE_LISTENING 0
92#define VBVAEXHOSTCONTEXT_STATE_PROCESSING 1
93
94#define VBVAEXHOSTCONTEXT_ESTATE_DISABLED -1
95#define VBVAEXHOSTCONTEXT_ESTATE_PAUSED 0
96#define VBVAEXHOSTCONTEXT_ESTATE_ENABLED 1
97
98typedef struct VBVAEXHOSTCONTEXT
99{
100 VBVABUFFER RT_UNTRUSTED_VOLATILE_GUEST *pVBVA;
101 /** Maximum number of data bytes addressible relative to pVBVA. */
102 uint32_t cbMaxData;
103 volatile int32_t i32State;
104 volatile int32_t i32EnableState;
105 volatile uint32_t u32cCtls;
106 /* critical section for accessing ctl lists */
107 RTCRITSECT CltCritSect;
108 RTLISTANCHOR GuestCtlList;
109 RTLISTANCHOR HostCtlList;
110#ifndef VBOXVDBG_MEMCACHE_DISABLE
111 RTMEMCACHE CtlCache;
112#endif
113} VBVAEXHOSTCONTEXT;
114
115typedef enum
116{
117 VBVAEXHOSTCTL_TYPE_UNDEFINED = 0,
118 VBVAEXHOSTCTL_TYPE_HH_INTERNAL_PAUSE,
119 VBVAEXHOSTCTL_TYPE_HH_INTERNAL_RESUME,
120 VBVAEXHOSTCTL_TYPE_HH_SAVESTATE,
121 VBVAEXHOSTCTL_TYPE_HH_LOADSTATE,
122 VBVAEXHOSTCTL_TYPE_HH_LOADSTATE_DONE,
123 VBVAEXHOSTCTL_TYPE_HH_BE_OPAQUE,
124 VBVAEXHOSTCTL_TYPE_HH_ON_HGCM_UNLOAD,
125 VBVAEXHOSTCTL_TYPE_GHH_BE_OPAQUE,
126 VBVAEXHOSTCTL_TYPE_GHH_ENABLE,
127 VBVAEXHOSTCTL_TYPE_GHH_ENABLE_PAUSED,
128 VBVAEXHOSTCTL_TYPE_GHH_DISABLE,
129 VBVAEXHOSTCTL_TYPE_GHH_RESIZE
130} VBVAEXHOSTCTL_TYPE;
131
132struct VBVAEXHOSTCTL;
133
134typedef DECLCALLBACKTYPE(void, FNVBVAEXHOSTCTL_COMPLETE,(VBVAEXHOSTCONTEXT *pVbva, struct VBVAEXHOSTCTL *pCtl, int rc, void *pvComplete));
135typedef FNVBVAEXHOSTCTL_COMPLETE *PFNVBVAEXHOSTCTL_COMPLETE;
136
137typedef struct VBVAEXHOSTCTL
138{
139 RTLISTNODE Node;
140 VBVAEXHOSTCTL_TYPE enmType;
141 union
142 {
143 struct
144 {
145 void RT_UNTRUSTED_VOLATILE_GUEST *pvCmd;
146 uint32_t cbCmd;
147 } cmd;
148
149 struct
150 {
151 PSSMHANDLE pSSM;
152 uint32_t u32Version;
153 } state;
154 } u;
155 PFNVBVAEXHOSTCTL_COMPLETE pfnComplete;
156 void *pvComplete;
157} VBVAEXHOSTCTL;
158
159/* VBoxVBVAExHP**, i.e. processor functions, can NOT be called concurrently with each other,
160 * but can be called with other VBoxVBVAExS** (submitter) functions except Init/Start/Term aparently.
161 * Can only be called be the processor, i.e. the entity that acquired the processor state by direct or indirect call to the VBoxVBVAExHSCheckCommands
162 * see mor edetailed comments in headers for function definitions */
163typedef enum
164{
165 VBVAEXHOST_DATA_TYPE_NO_DATA = 0,
166 VBVAEXHOST_DATA_TYPE_CMD,
167 VBVAEXHOST_DATA_TYPE_HOSTCTL,
168 VBVAEXHOST_DATA_TYPE_GUESTCTL
169} VBVAEXHOST_DATA_TYPE;
170
171
172typedef struct VBOXVDMAHOST
173{
174 PHGSMIINSTANCE pHgsmi; /**< Same as VGASTATE::pHgsmi. */
175 PVGASTATE pThis;
176} VBOXVDMAHOST, *PVBOXVDMAHOST;
177
178
179/**
180 * List selector for VBoxVBVAExHCtlSubmit(), vdmaVBVACtlSubmit().
181 */
182typedef enum
183{
184 VBVAEXHOSTCTL_SOURCE_GUEST = 0,
185 VBVAEXHOSTCTL_SOURCE_HOST
186} VBVAEXHOSTCTL_SOURCE;
187
188
189
190
191/**
192 * Called by vgaR3Construct() to initialize the state.
193 *
194 * @returns VBox status code.
195 */
196int vboxVDMAConstruct(PVGASTATE pThis, PVGASTATECC pThisCC, uint32_t cPipeElements)
197{
198 RT_NOREF(cPipeElements);
199 PVBOXVDMAHOST pVdma = (PVBOXVDMAHOST)RTMemAllocZ(sizeof(*pVdma));
200 Assert(pVdma);
201 if (pVdma)
202 {
203 pVdma->pHgsmi = pThisCC->pHGSMI;
204 pVdma->pThis = pThis;
205
206 pThisCC->pVdma = pVdma;
207 return VINF_SUCCESS;
208 }
209 return VERR_NO_MEMORY;
210}
211
212/**
213 * Called by vgaR3Reset() to do reset.
214 */
215void vboxVDMAReset(struct VBOXVDMAHOST *pVdma)
216{
217 RT_NOREF(pVdma);
218}
219
220/**
221 * Called by vgaR3Destruct() to do cleanup.
222 */
223void vboxVDMADestruct(struct VBOXVDMAHOST *pVdma)
224{
225 if (!pVdma)
226 return;
227 RTMemFree(pVdma);
228}
229
230/**
231 * Handle VBVA_VDMA_CTL, see vbvaChannelHandler
232 *
233 * @param pVdma The VDMA channel.
234 * @param pCmd The control command to handle. Considered volatile.
235 * @param cbCmd The size of the command. At least sizeof(VBOXVDMA_CTL).
236 */
237void vboxVDMAControl(struct VBOXVDMAHOST *pVdma, VBOXVDMA_CTL RT_UNTRUSTED_VOLATILE_GUEST *pCmd, uint32_t cbCmd)
238{
239 RT_NOREF(cbCmd);
240 PHGSMIINSTANCE pIns = pVdma->pHgsmi;
241
242 VBOXVDMA_CTL_TYPE enmCtl = pCmd->enmCtl;
243 RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
244
245 int rc;
246 if (enmCtl < VBOXVDMA_CTL_TYPE_END)
247 {
248 RT_UNTRUSTED_VALIDATED_FENCE();
249
250 switch (enmCtl)
251 {
252 case VBOXVDMA_CTL_TYPE_ENABLE:
253 rc = VINF_SUCCESS;
254 break;
255 case VBOXVDMA_CTL_TYPE_DISABLE:
256 rc = VINF_SUCCESS;
257 break;
258 case VBOXVDMA_CTL_TYPE_FLUSH:
259 rc = VINF_SUCCESS;
260 break;
261 case VBOXVDMA_CTL_TYPE_WATCHDOG:
262 rc = VERR_NOT_SUPPORTED;
263 break;
264 default:
265 AssertFailedBreakStmt(rc = VERR_IPE_NOT_REACHED_DEFAULT_CASE);
266 }
267 }
268 else
269 {
270 RT_UNTRUSTED_VALIDATED_FENCE();
271 ASSERT_GUEST_FAILED();
272 rc = VERR_NOT_SUPPORTED;
273 }
274
275 pCmd->i32Result = rc;
276 rc = VBoxSHGSMICommandComplete(pIns, pCmd);
277 AssertRC(rc);
278}
279
280/**
281 * Handle VBVA_VDMA_CMD, see vbvaChannelHandler().
282 *
283 * @param pVdma The VDMA channel.
284 * @param pCmd The command to handle. Considered volatile.
285 * @param cbCmd The size of the command. At least sizeof(VBOXVDMACBUF_DR).
286 * @thread EMT
287 */
288void vboxVDMACommand(struct VBOXVDMAHOST *pVdma, VBOXVDMACBUF_DR RT_UNTRUSTED_VOLATILE_GUEST *pCmd, uint32_t cbCmd)
289{
290 /*
291 * Process the command.
292 */
293 bool fAsyncCmd = false;
294 RT_NOREF(cbCmd);
295 int rc = VERR_NOT_IMPLEMENTED;
296
297 /*
298 * Complete the command unless it's asynchronous (e.g. chromium).
299 */
300 if (!fAsyncCmd)
301 {
302 pCmd->rc = rc;
303 int rc2 = VBoxSHGSMICommandComplete(pVdma->pHgsmi, pCmd);
304 AssertRC(rc2);
305 }
306}
307
308
309
310/*
311 *
312 *
313 * Saved state.
314 * Saved state.
315 * Saved state.
316 *
317 *
318 */
319
320int vboxVDMASaveStateExecPrep(struct VBOXVDMAHOST *pVdma)
321{
322 RT_NOREF(pVdma);
323 return VINF_SUCCESS;
324}
325
326int vboxVDMASaveStateExecDone(struct VBOXVDMAHOST *pVdma)
327{
328 RT_NOREF(pVdma);
329 return VINF_SUCCESS;
330}
331
332int vboxVDMASaveStateExecPerform(PCPDMDEVHLPR3 pHlp, struct VBOXVDMAHOST *pVdma, PSSMHANDLE pSSM)
333{
334 int rc;
335 RT_NOREF(pVdma);
336
337 rc = pHlp->pfnSSMPutU32(pSSM, UINT32_MAX);
338 AssertRCReturn(rc, rc);
339 return VINF_SUCCESS;
340}
341
342int vboxVDMASaveLoadExecPerform(PCPDMDEVHLPR3 pHlp, struct VBOXVDMAHOST *pVdma, PSSMHANDLE pSSM, uint32_t u32Version)
343{
344 uint32_t u32;
345 int rc = pHlp->pfnSSMGetU32(pSSM, &u32);
346 AssertLogRelRCReturn(rc, rc);
347
348 if (u32 != UINT32_MAX)
349 {
350 RT_NOREF(pVdma, u32Version);
351 WARN(("Unsupported VBVACtl info!\n"));
352 return VERR_VERSION_MISMATCH;
353 }
354
355 return VINF_SUCCESS;
356}
357
358int vboxVDMASaveLoadDone(struct VBOXVDMAHOST *pVdma)
359{
360 RT_NOREF(pVdma);
361 return VINF_SUCCESS;
362}
363
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