VirtualBox

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

Last change on this file since 81428 was 80872, checked in by vboxsync, 5 years ago

Devices/Graphics,Main,include: remove obsolete Chromium code. bugref:9529

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 10.3 KB
Line 
1/* $Id: DevVGA_VDMA.cpp 80872 2019-09-17 20:54:03Z vboxsync $ */
2/** @file
3 * Video DMA (VDMA) support.
4 */
5
6/*
7 * Copyright (C) 2006-2019 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, void *pvThreadContext, void *pvChangeContext);
72
73typedef struct VBOXVDMATHREAD
74{
75 RTTHREAD hWorkerThread;
76 RTSEMEVENT hEvent;
77 volatile uint32_t u32State;
78 PFNVBOXVDMATHREAD_CHANGED pfnChanged;
79 void *pvChanged;
80} VBOXVDMATHREAD, *PVBOXVDMATHREAD;
81
82
83/* state transformations:
84 *
85 * submitter | processor
86 *
87 * LISTENING ---> PROCESSING
88 *
89 * */
90#define VBVAEXHOSTCONTEXT_STATE_LISTENING 0
91#define VBVAEXHOSTCONTEXT_STATE_PROCESSING 1
92
93#define VBVAEXHOSTCONTEXT_ESTATE_DISABLED -1
94#define VBVAEXHOSTCONTEXT_ESTATE_PAUSED 0
95#define VBVAEXHOSTCONTEXT_ESTATE_ENABLED 1
96
97typedef struct VBVAEXHOSTCONTEXT
98{
99 VBVABUFFER RT_UNTRUSTED_VOLATILE_GUEST *pVBVA;
100 /** Maximum number of data bytes addressible relative to pVBVA. */
101 uint32_t cbMaxData;
102 volatile int32_t i32State;
103 volatile int32_t i32EnableState;
104 volatile uint32_t u32cCtls;
105 /* critical section for accessing ctl lists */
106 RTCRITSECT CltCritSect;
107 RTLISTANCHOR GuestCtlList;
108 RTLISTANCHOR HostCtlList;
109#ifndef VBOXVDBG_MEMCACHE_DISABLE
110 RTMEMCACHE CtlCache;
111#endif
112} VBVAEXHOSTCONTEXT;
113
114typedef enum
115{
116 VBVAEXHOSTCTL_TYPE_UNDEFINED = 0,
117 VBVAEXHOSTCTL_TYPE_HH_INTERNAL_PAUSE,
118 VBVAEXHOSTCTL_TYPE_HH_INTERNAL_RESUME,
119 VBVAEXHOSTCTL_TYPE_HH_SAVESTATE,
120 VBVAEXHOSTCTL_TYPE_HH_LOADSTATE,
121 VBVAEXHOSTCTL_TYPE_HH_LOADSTATE_DONE,
122 VBVAEXHOSTCTL_TYPE_HH_BE_OPAQUE,
123 VBVAEXHOSTCTL_TYPE_HH_ON_HGCM_UNLOAD,
124 VBVAEXHOSTCTL_TYPE_GHH_BE_OPAQUE,
125 VBVAEXHOSTCTL_TYPE_GHH_ENABLE,
126 VBVAEXHOSTCTL_TYPE_GHH_ENABLE_PAUSED,
127 VBVAEXHOSTCTL_TYPE_GHH_DISABLE,
128 VBVAEXHOSTCTL_TYPE_GHH_RESIZE
129} VBVAEXHOSTCTL_TYPE;
130
131struct VBVAEXHOSTCTL;
132
133typedef DECLCALLBACK(void) FNVBVAEXHOSTCTL_COMPLETE(VBVAEXHOSTCONTEXT *pVbva, struct VBVAEXHOSTCTL *pCtl, int rc, void *pvComplete);
134typedef FNVBVAEXHOSTCTL_COMPLETE *PFNVBVAEXHOSTCTL_COMPLETE;
135
136typedef struct VBVAEXHOSTCTL
137{
138 RTLISTNODE Node;
139 VBVAEXHOSTCTL_TYPE enmType;
140 union
141 {
142 struct
143 {
144 void RT_UNTRUSTED_VOLATILE_GUEST *pvCmd;
145 uint32_t cbCmd;
146 } cmd;
147
148 struct
149 {
150 PSSMHANDLE pSSM;
151 uint32_t u32Version;
152 } state;
153 } u;
154 PFNVBVAEXHOSTCTL_COMPLETE pfnComplete;
155 void *pvComplete;
156} VBVAEXHOSTCTL;
157
158/* VBoxVBVAExHP**, i.e. processor functions, can NOT be called concurrently with each other,
159 * but can be called with other VBoxVBVAExS** (submitter) functions except Init/Start/Term aparently.
160 * Can only be called be the processor, i.e. the entity that acquired the processor state by direct or indirect call to the VBoxVBVAExHSCheckCommands
161 * see mor edetailed comments in headers for function definitions */
162typedef enum
163{
164 VBVAEXHOST_DATA_TYPE_NO_DATA = 0,
165 VBVAEXHOST_DATA_TYPE_CMD,
166 VBVAEXHOST_DATA_TYPE_HOSTCTL,
167 VBVAEXHOST_DATA_TYPE_GUESTCTL
168} VBVAEXHOST_DATA_TYPE;
169
170
171typedef struct VBOXVDMAHOST
172{
173 PHGSMIINSTANCE pHgsmi; /**< Same as VGASTATE::pHgsmi. */
174 PVGASTATE pVGAState;
175} VBOXVDMAHOST, *PVBOXVDMAHOST;
176
177
178/**
179 * List selector for VBoxVBVAExHCtlSubmit(), vdmaVBVACtlSubmit().
180 */
181typedef enum
182{
183 VBVAEXHOSTCTL_SOURCE_GUEST = 0,
184 VBVAEXHOSTCTL_SOURCE_HOST
185} VBVAEXHOSTCTL_SOURCE;
186
187
188/*********************************************************************************************************************************
189* Internal Functions *
190*********************************************************************************************************************************/
191
192
193/**
194 * Called by vgaR3Construct() to initialize the state.
195 *
196 * @returns VBox status code.
197 */
198int vboxVDMAConstruct(PVGASTATE pVGAState, uint32_t cPipeElements)
199{
200 RT_NOREF(cPipeElements);
201 int rc;
202 PVBOXVDMAHOST pVdma = (PVBOXVDMAHOST)RTMemAllocZ(sizeof(*pVdma));
203 Assert(pVdma);
204 if (pVdma)
205 {
206 pVdma->pHgsmi = pVGAState->pHGSMI;
207 pVdma->pVGAState = pVGAState;
208
209 rc = VINF_SUCCESS;
210 if (RT_SUCCESS(rc))
211 {
212 pVGAState->pVdma = pVdma;
213
214 return VINF_SUCCESS;
215 /* the timer is cleaned up automatically */
216 }
217 RTMemFree(pVdma);
218 }
219 else
220 rc = VERR_OUT_OF_RESOURCES;
221 return rc;
222}
223
224/**
225 * Called by vgaR3Reset() to do reset.
226 */
227void vboxVDMAReset(struct VBOXVDMAHOST *pVdma)
228{
229 RT_NOREF(pVdma);
230}
231
232/**
233 * Called by vgaR3Destruct() to do cleanup.
234 */
235void vboxVDMADestruct(struct VBOXVDMAHOST *pVdma)
236{
237 if (!pVdma)
238 return;
239 RTMemFree(pVdma);
240}
241
242/**
243 * Handle VBVA_VDMA_CTL, see vbvaChannelHandler
244 *
245 * @param pVdma The VDMA channel.
246 * @param pCmd The control command to handle. Considered volatile.
247 * @param cbCmd The size of the command. At least sizeof(VBOXVDMA_CTL).
248 */
249void vboxVDMAControl(struct VBOXVDMAHOST *pVdma, VBOXVDMA_CTL RT_UNTRUSTED_VOLATILE_GUEST *pCmd, uint32_t cbCmd)
250{
251 RT_NOREF(cbCmd);
252 PHGSMIINSTANCE pIns = pVdma->pHgsmi;
253
254 VBOXVDMA_CTL_TYPE enmCtl = pCmd->enmCtl;
255 RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
256
257 int rc;
258 if (enmCtl < VBOXVDMA_CTL_TYPE_END)
259 {
260 RT_UNTRUSTED_VALIDATED_FENCE();
261
262 switch (enmCtl)
263 {
264 case VBOXVDMA_CTL_TYPE_ENABLE:
265 rc = VINF_SUCCESS;
266 break;
267 case VBOXVDMA_CTL_TYPE_DISABLE:
268 rc = VINF_SUCCESS;
269 break;
270 case VBOXVDMA_CTL_TYPE_FLUSH:
271 rc = VINF_SUCCESS;
272 break;
273 case VBOXVDMA_CTL_TYPE_WATCHDOG:
274 rc = VERR_NOT_SUPPORTED;
275 break;
276 default:
277 AssertFailedBreakStmt(rc = VERR_IPE_NOT_REACHED_DEFAULT_CASE);
278 }
279 }
280 else
281 {
282 RT_UNTRUSTED_VALIDATED_FENCE();
283 ASSERT_GUEST_FAILED();
284 rc = VERR_NOT_SUPPORTED;
285 }
286
287 pCmd->i32Result = rc;
288 rc = VBoxSHGSMICommandComplete(pIns, pCmd);
289 AssertRC(rc);
290}
291
292/**
293 * Handle VBVA_VDMA_CMD, see vbvaChannelHandler().
294 *
295 * @param pVdma The VDMA channel.
296 * @param pCmd The command to handle. Considered volatile.
297 * @param cbCmd The size of the command. At least sizeof(VBOXVDMACBUF_DR).
298 * @thread EMT
299 */
300void vboxVDMACommand(struct VBOXVDMAHOST *pVdma, VBOXVDMACBUF_DR RT_UNTRUSTED_VOLATILE_GUEST *pCmd, uint32_t cbCmd)
301{
302 /*
303 * Process the command.
304 */
305 bool fAsyncCmd = false;
306 RT_NOREF(cbCmd);
307 int rc = VERR_NOT_IMPLEMENTED;
308
309 /*
310 * Complete the command unless it's asynchronous (e.g. chromium).
311 */
312 if (!fAsyncCmd)
313 {
314 pCmd->rc = rc;
315 int rc2 = VBoxSHGSMICommandComplete(pVdma->pHgsmi, pCmd);
316 AssertRC(rc2);
317 }
318}
319
320
321
322/*
323 *
324 *
325 * Saved state.
326 * Saved state.
327 * Saved state.
328 *
329 *
330 */
331
332int vboxVDMASaveStateExecPrep(struct VBOXVDMAHOST *pVdma)
333{
334 RT_NOREF(pVdma);
335 return VINF_SUCCESS;
336}
337
338int vboxVDMASaveStateExecDone(struct VBOXVDMAHOST *pVdma)
339{
340 RT_NOREF(pVdma);
341 return VINF_SUCCESS;
342}
343
344int vboxVDMASaveStateExecPerform(struct VBOXVDMAHOST *pVdma, PSSMHANDLE pSSM)
345{
346 int rc;
347 RT_NOREF(pVdma);
348
349 rc = SSMR3PutU32(pSSM, UINT32_MAX);
350 AssertRCReturn(rc, rc);
351 return VINF_SUCCESS;
352}
353
354int vboxVDMASaveLoadExecPerform(struct VBOXVDMAHOST *pVdma, PSSMHANDLE pSSM, uint32_t u32Version)
355{
356 uint32_t u32;
357 int rc = SSMR3GetU32(pSSM, &u32);
358 AssertLogRelRCReturn(rc, rc);
359
360 if (u32 != UINT32_MAX)
361 {
362 RT_NOREF(pVdma, u32Version);
363 WARN(("Unsupported VBVACtl info!\n"));
364 return VERR_VERSION_MISMATCH;
365 }
366
367 return VINF_SUCCESS;
368}
369
370int vboxVDMASaveLoadDone(struct VBOXVDMAHOST *pVdma)
371{
372 RT_NOREF(pVdma);
373 return VINF_SUCCESS;
374}
375
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