VirtualBox

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

Last change on this file since 82781 was 82109, checked in by vboxsync, 4 years ago

DevVGA: Splitting up the VGASTATE structure. bugref:9218

  • 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 82109 2019-11-22 20:24:21Z 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 pThis;
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
190/**
191 * Called by vgaR3Construct() to initialize the state.
192 *
193 * @returns VBox status code.
194 */
195int vboxVDMAConstruct(PVGASTATE pThis, PVGASTATECC pThisCC, uint32_t cPipeElements)
196{
197 RT_NOREF(cPipeElements);
198 PVBOXVDMAHOST pVdma = (PVBOXVDMAHOST)RTMemAllocZ(sizeof(*pVdma));
199 Assert(pVdma);
200 if (pVdma)
201 {
202 pVdma->pHgsmi = pThisCC->pHGSMI;
203 pVdma->pThis = pThis;
204
205 pThisCC->pVdma = pVdma;
206 return VINF_SUCCESS;
207 }
208 return VERR_NO_MEMORY;
209}
210
211/**
212 * Called by vgaR3Reset() to do reset.
213 */
214void vboxVDMAReset(struct VBOXVDMAHOST *pVdma)
215{
216 RT_NOREF(pVdma);
217}
218
219/**
220 * Called by vgaR3Destruct() to do cleanup.
221 */
222void vboxVDMADestruct(struct VBOXVDMAHOST *pVdma)
223{
224 if (!pVdma)
225 return;
226 RTMemFree(pVdma);
227}
228
229/**
230 * Handle VBVA_VDMA_CTL, see vbvaChannelHandler
231 *
232 * @param pVdma The VDMA channel.
233 * @param pCmd The control command to handle. Considered volatile.
234 * @param cbCmd The size of the command. At least sizeof(VBOXVDMA_CTL).
235 */
236void vboxVDMAControl(struct VBOXVDMAHOST *pVdma, VBOXVDMA_CTL RT_UNTRUSTED_VOLATILE_GUEST *pCmd, uint32_t cbCmd)
237{
238 RT_NOREF(cbCmd);
239 PHGSMIINSTANCE pIns = pVdma->pHgsmi;
240
241 VBOXVDMA_CTL_TYPE enmCtl = pCmd->enmCtl;
242 RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
243
244 int rc;
245 if (enmCtl < VBOXVDMA_CTL_TYPE_END)
246 {
247 RT_UNTRUSTED_VALIDATED_FENCE();
248
249 switch (enmCtl)
250 {
251 case VBOXVDMA_CTL_TYPE_ENABLE:
252 rc = VINF_SUCCESS;
253 break;
254 case VBOXVDMA_CTL_TYPE_DISABLE:
255 rc = VINF_SUCCESS;
256 break;
257 case VBOXVDMA_CTL_TYPE_FLUSH:
258 rc = VINF_SUCCESS;
259 break;
260 case VBOXVDMA_CTL_TYPE_WATCHDOG:
261 rc = VERR_NOT_SUPPORTED;
262 break;
263 default:
264 AssertFailedBreakStmt(rc = VERR_IPE_NOT_REACHED_DEFAULT_CASE);
265 }
266 }
267 else
268 {
269 RT_UNTRUSTED_VALIDATED_FENCE();
270 ASSERT_GUEST_FAILED();
271 rc = VERR_NOT_SUPPORTED;
272 }
273
274 pCmd->i32Result = rc;
275 rc = VBoxSHGSMICommandComplete(pIns, pCmd);
276 AssertRC(rc);
277}
278
279/**
280 * Handle VBVA_VDMA_CMD, see vbvaChannelHandler().
281 *
282 * @param pVdma The VDMA channel.
283 * @param pCmd The command to handle. Considered volatile.
284 * @param cbCmd The size of the command. At least sizeof(VBOXVDMACBUF_DR).
285 * @thread EMT
286 */
287void vboxVDMACommand(struct VBOXVDMAHOST *pVdma, VBOXVDMACBUF_DR RT_UNTRUSTED_VOLATILE_GUEST *pCmd, uint32_t cbCmd)
288{
289 /*
290 * Process the command.
291 */
292 bool fAsyncCmd = false;
293 RT_NOREF(cbCmd);
294 int rc = VERR_NOT_IMPLEMENTED;
295
296 /*
297 * Complete the command unless it's asynchronous (e.g. chromium).
298 */
299 if (!fAsyncCmd)
300 {
301 pCmd->rc = rc;
302 int rc2 = VBoxSHGSMICommandComplete(pVdma->pHgsmi, pCmd);
303 AssertRC(rc2);
304 }
305}
306
307
308
309/*
310 *
311 *
312 * Saved state.
313 * Saved state.
314 * Saved state.
315 *
316 *
317 */
318
319int vboxVDMASaveStateExecPrep(struct VBOXVDMAHOST *pVdma)
320{
321 RT_NOREF(pVdma);
322 return VINF_SUCCESS;
323}
324
325int vboxVDMASaveStateExecDone(struct VBOXVDMAHOST *pVdma)
326{
327 RT_NOREF(pVdma);
328 return VINF_SUCCESS;
329}
330
331int vboxVDMASaveStateExecPerform(PCPDMDEVHLPR3 pHlp, struct VBOXVDMAHOST *pVdma, PSSMHANDLE pSSM)
332{
333 int rc;
334 RT_NOREF(pVdma);
335
336 rc = pHlp->pfnSSMPutU32(pSSM, UINT32_MAX);
337 AssertRCReturn(rc, rc);
338 return VINF_SUCCESS;
339}
340
341int vboxVDMASaveLoadExecPerform(PCPDMDEVHLPR3 pHlp, struct VBOXVDMAHOST *pVdma, PSSMHANDLE pSSM, uint32_t u32Version)
342{
343 uint32_t u32;
344 int rc = pHlp->pfnSSMGetU32(pSSM, &u32);
345 AssertLogRelRCReturn(rc, rc);
346
347 if (u32 != UINT32_MAX)
348 {
349 RT_NOREF(pVdma, u32Version);
350 WARN(("Unsupported VBVACtl info!\n"));
351 return VERR_VERSION_MISMATCH;
352 }
353
354 return VINF_SUCCESS;
355}
356
357int vboxVDMASaveLoadDone(struct VBOXVDMAHOST *pVdma)
358{
359 RT_NOREF(pVdma);
360 return VINF_SUCCESS;
361}
362
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use