VirtualBox

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

Last change on this file since 103914 was 98103, checked in by vboxsync, 21 months ago

Copyright year updates by scm.

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