VirtualBox

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

Last change on this file was 98103, checked in by vboxsync, 17 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
RevLine 
[55401]1/* $Id: DevVGA_VDMA.cpp 98103 2023-01-17 14:15:46Z vboxsync $ */
[26969]2/** @file
3 * Video DMA (VDMA) support.
4 */
5
6/*
[98103]7 * Copyright (C) 2006-2023 Oracle and/or its affiliates.
[26969]8 *
[96407]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
[26969]26 */
[63427]27
28
29/*********************************************************************************************************************************
30* Header Files *
31*********************************************************************************************************************************/
[65785]32#define LOG_GROUP LOG_GROUP_DEV_VGA
[51101]33#include <VBox/VMMDev.h>
[35346]34#include <VBox/vmm/pdmdev.h>
[55493]35#include <VBox/vmm/pgm.h>
[65381]36#include <VBoxVideo.h>
[71607]37#include <VBox/AssertGuest.h>
[27339]38#include <iprt/semaphore.h>
39#include <iprt/thread.h>
40#include <iprt/mem.h>
[33146]41#include <iprt/asm.h>
[50754]42#include <iprt/list.h>
[50831]43#include <iprt/param.h>
[26969]44
45#include "DevVGA.h"
46#include "HGSMI/SHGSMIHost.h"
47
[49507]48#ifdef DEBUG_misha
[50754]49# define VBOXVDBG_MEMCACHE_DISABLE
50#endif
51
52#ifndef VBOXVDBG_MEMCACHE_DISABLE
53# include <iprt/memcache.h>
54#endif
55
[63549]56
[63427]57/*********************************************************************************************************************************
58* Defined Constants And Macros *
59*********************************************************************************************************************************/
[50754]60#ifdef DEBUG_misha
[63427]61# define WARN_BP() do { AssertFailed(); } while (0)
[49507]62#else
[63427]63# define WARN_BP() do { } while (0)
[49507]64#endif
65#define WARN(_msg) do { \
66 LogRel(_msg); \
67 WARN_BP(); \
68 } while (0)
69
[51005]70#define VBOXVDMATHREAD_STATE_TERMINATED 0
71#define VBOXVDMATHREAD_STATE_CREATING 1
72#define VBOXVDMATHREAD_STATE_CREATED 3
73#define VBOXVDMATHREAD_STATE_TERMINATING 4
[27339]74
[63427]75
76/*********************************************************************************************************************************
77* Structures and Typedefs *
78*********************************************************************************************************************************/
[51005]79struct VBOXVDMATHREAD;
80
[85121]81typedef DECLCALLBACKPTR(void, PFNVBOXVDMATHREAD_CHANGED,(struct VBOXVDMATHREAD *pThread, int rc,
82 void *pvThreadContext, void *pvChangeContext));
[51005]83
[50754]84typedef struct VBOXVDMATHREAD
[26969]85{
[50754]86 RTTHREAD hWorkerThread;
[26969]87 RTSEMEVENT hEvent;
[50754]88 volatile uint32_t u32State;
[51005]89 PFNVBOXVDMATHREAD_CHANGED pfnChanged;
90 void *pvChanged;
[50754]91} VBOXVDMATHREAD, *PVBOXVDMATHREAD;
[26969]92
[27339]93
[49507]94/* state transformations:
95 *
96 * submitter | processor
[50754]97 *
[49507]98 * LISTENING ---> PROCESSING
99 *
100 * */
[50754]101#define VBVAEXHOSTCONTEXT_STATE_LISTENING 0
102#define VBVAEXHOSTCONTEXT_STATE_PROCESSING 1
[49507]103
[50754]104#define VBVAEXHOSTCONTEXT_ESTATE_DISABLED -1
105#define VBVAEXHOSTCONTEXT_ESTATE_PAUSED 0
106#define VBVAEXHOSTCONTEXT_ESTATE_ENABLED 1
107
[49507]108typedef struct VBVAEXHOSTCONTEXT
109{
[71607]110 VBVABUFFER RT_UNTRUSTED_VOLATILE_GUEST *pVBVA;
111 /** Maximum number of data bytes addressible relative to pVBVA. */
112 uint32_t cbMaxData;
[50754]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;
[50763]118 RTLISTANCHOR GuestCtlList;
119 RTLISTANCHOR HostCtlList;
[50754]120#ifndef VBOXVDBG_MEMCACHE_DISABLE
121 RTMEMCACHE CtlCache;
122#endif
[49507]123} VBVAEXHOSTCONTEXT;
124
[50754]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,
[51349]132 VBVAEXHOSTCTL_TYPE_HH_LOADSTATE_DONE,
[50754]133 VBVAEXHOSTCTL_TYPE_HH_BE_OPAQUE,
[51005]134 VBVAEXHOSTCTL_TYPE_HH_ON_HGCM_UNLOAD,
[50754]135 VBVAEXHOSTCTL_TYPE_GHH_BE_OPAQUE,
[51005]136 VBVAEXHOSTCTL_TYPE_GHH_ENABLE,
[51101]137 VBVAEXHOSTCTL_TYPE_GHH_ENABLE_PAUSED,
[51005]138 VBVAEXHOSTCTL_TYPE_GHH_DISABLE,
[51121]139 VBVAEXHOSTCTL_TYPE_GHH_RESIZE
[50754]140} VBVAEXHOSTCTL_TYPE;
141
142struct VBVAEXHOSTCTL;
143
[85121]144typedef DECLCALLBACKTYPE(void, FNVBVAEXHOSTCTL_COMPLETE,(VBVAEXHOSTCONTEXT *pVbva, struct VBVAEXHOSTCTL *pCtl, int rc, void *pvComplete));
[70596]145typedef FNVBVAEXHOSTCTL_COMPLETE *PFNVBVAEXHOSTCTL_COMPLETE;
[50754]146
147typedef struct VBVAEXHOSTCTL
148{
149 RTLISTNODE Node;
150 VBVAEXHOSTCTL_TYPE enmType;
151 union
152 {
153 struct
154 {
[71607]155 void RT_UNTRUSTED_VOLATILE_GUEST *pvCmd;
[50754]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
[49507]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 */
[50754]173typedef enum
174{
175 VBVAEXHOST_DATA_TYPE_NO_DATA = 0,
176 VBVAEXHOST_DATA_TYPE_CMD,
177 VBVAEXHOST_DATA_TYPE_HOSTCTL,
[50759]178 VBVAEXHOST_DATA_TYPE_GUESTCTL
[50754]179} VBVAEXHOST_DATA_TYPE;
[51357]180
181
[63427]182typedef struct VBOXVDMAHOST
183{
[70602]184 PHGSMIINSTANCE pHgsmi; /**< Same as VGASTATE::pHgsmi. */
[82109]185 PVGASTATE pThis;
[63427]186} VBOXVDMAHOST, *PVBOXVDMAHOST;
187
188
[70600]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
[50754]199
[63427]200
[80428]201/**
[70596]202 * Called by vgaR3Construct() to initialize the state.
203 *
204 * @returns VBox status code.
205 */
[82109]206int vboxVDMAConstruct(PVGASTATE pThis, PVGASTATECC pThisCC, uint32_t cPipeElements)
[27339]207{
[62951]208 RT_NOREF(cPipeElements);
[41974]209 PVBOXVDMAHOST pVdma = (PVBOXVDMAHOST)RTMemAllocZ(sizeof(*pVdma));
[27339]210 Assert(pVdma);
211 if (pVdma)
212 {
[82109]213 pVdma->pHgsmi = pThisCC->pHGSMI;
214 pVdma->pThis = pThis;
[41636]215
[82109]216 pThisCC->pVdma = pVdma;
217 return VINF_SUCCESS;
[27339]218 }
[82109]219 return VERR_NO_MEMORY;
[27339]220}
221
[70596]222/**
223 * Called by vgaR3Reset() to do reset.
224 */
225void vboxVDMAReset(struct VBOXVDMAHOST *pVdma)
[27339]226{
[80872]227 RT_NOREF(pVdma);
[26969]228}
229
[70596]230/**
[70597]231 * Called by vgaR3Destruct() to do cleanup.
[70596]232 */
233void vboxVDMADestruct(struct VBOXVDMAHOST *pVdma)
[26969]234{
[51507]235 if (!pVdma)
[70596]236 return;
[50754]237 RTMemFree(pVdma);
[27339]238}
239
[70596]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 */
[71590]247void vboxVDMAControl(struct VBOXVDMAHOST *pVdma, VBOXVDMA_CTL RT_UNTRUSTED_VOLATILE_GUEST *pCmd, uint32_t cbCmd)
[27339]248{
[62951]249 RT_NOREF(cbCmd);
[27339]250 PHGSMIINSTANCE pIns = pVdma->pHgsmi;
251
[70596]252 VBOXVDMA_CTL_TYPE enmCtl = pCmd->enmCtl;
[71603]253 RT_UNTRUSTED_NONVOLATILE_COPY_FENCE();
[71619]254
255 int rc;
[71603]256 if (enmCtl < VBOXVDMA_CTL_TYPE_END)
[26969]257 {
[71603]258 RT_UNTRUSTED_VALIDATED_FENCE();
259
260 switch (enmCtl)
261 {
262 case VBOXVDMA_CTL_TYPE_ENABLE:
[71619]263 rc = VINF_SUCCESS;
[71603]264 break;
265 case VBOXVDMA_CTL_TYPE_DISABLE:
[71619]266 rc = VINF_SUCCESS;
[71603]267 break;
268 case VBOXVDMA_CTL_TYPE_FLUSH:
[71619]269 rc = VINF_SUCCESS;
[71603]270 break;
[71619]271 case VBOXVDMA_CTL_TYPE_WATCHDOG:
272 rc = VERR_NOT_SUPPORTED;
[71603]273 break;
274 default:
[71619]275 AssertFailedBreakStmt(rc = VERR_IPE_NOT_REACHED_DEFAULT_CASE);
[71603]276 }
[26969]277 }
[71603]278 else
279 {
280 RT_UNTRUSTED_VALIDATED_FENCE();
[71619]281 ASSERT_GUEST_FAILED();
282 rc = VERR_NOT_SUPPORTED;
[71603]283 }
[26969]284
[71619]285 pCmd->i32Result = rc;
286 rc = VBoxSHGSMICommandComplete(pIns, pCmd);
[26969]287 AssertRC(rc);
288}
289
[70596]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).
[71607]296 * @thread EMT
[70596]297 */
[71590]298void vboxVDMACommand(struct VBOXVDMAHOST *pVdma, VBOXVDMACBUF_DR RT_UNTRUSTED_VOLATILE_GUEST *pCmd, uint32_t cbCmd)
[26969]299{
[71604]300 /*
301 * Process the command.
302 */
303 bool fAsyncCmd = false;
[80872]304 RT_NOREF(cbCmd);
305 int rc = VERR_NOT_IMPLEMENTED;
[71603]306
[71604]307 /*
308 * Complete the command unless it's asynchronous (e.g. chromium).
309 */
310 if (!fAsyncCmd)
[39603]311 {
312 pCmd->rc = rc;
[71604]313 int rc2 = VBoxSHGSMICommandComplete(pVdma->pHgsmi, pCmd);
314 AssertRC(rc2);
[39603]315 }
[26969]316}
[49507]317
[80428]318
319
[70596]320/*
321 *
322 *
323 * Saved state.
324 * Saved state.
325 * Saved state.
326 *
327 *
328 */
329
[62951]330int vboxVDMASaveStateExecPrep(struct VBOXVDMAHOST *pVdma)
[51005]331{
[80872]332 RT_NOREF(pVdma);
333 return VINF_SUCCESS;
[51005]334}
335
[62951]336int vboxVDMASaveStateExecDone(struct VBOXVDMAHOST *pVdma)
[51005]337{
[80872]338 RT_NOREF(pVdma);
339 return VINF_SUCCESS;
[51005]340}
341
[82048]342int vboxVDMASaveStateExecPerform(PCPDMDEVHLPR3 pHlp, struct VBOXVDMAHOST *pVdma, PSSMHANDLE pSSM)
[51005]343{
344 int rc;
[80872]345 RT_NOREF(pVdma);
[51005]346
[82048]347 rc = pHlp->pfnSSMPutU32(pSSM, UINT32_MAX);
[51005]348 AssertRCReturn(rc, rc);
[80872]349 return VINF_SUCCESS;
[51005]350}
351
[82048]352int vboxVDMASaveLoadExecPerform(PCPDMDEVHLPR3 pHlp, struct VBOXVDMAHOST *pVdma, PSSMHANDLE pSSM, uint32_t u32Version)
[51005]353{
354 uint32_t u32;
[82048]355 int rc = pHlp->pfnSSMGetU32(pSSM, &u32);
[56971]356 AssertLogRelRCReturn(rc, rc);
[51005]357
[63427]358 if (u32 != UINT32_MAX)
[51005]359 {
[80872]360 RT_NOREF(pVdma, u32Version);
361 WARN(("Unsupported VBVACtl info!\n"));
362 return VERR_VERSION_MISMATCH;
[51005]363 }
364
365 return VINF_SUCCESS;
366}
[51349]367
368int vboxVDMASaveLoadDone(struct VBOXVDMAHOST *pVdma)
369{
[80872]370 RT_NOREF(pVdma);
[51349]371 return VINF_SUCCESS;
372}
[63427]373
Note: See TracBrowser for help on using the repository browser.

© 2023 Oracle
ContactPrivacy policyTerms of Use