VirtualBox

source: vbox/trunk/src/VBox/Additions/common/VBoxVideo/HGSMIHostCmd.cpp@ 69309

Last change on this file since 69309 was 69309, checked in by vboxsync, 7 years ago

common/VBoxVideo: scm update and todo regarding syntax checking/library

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 9.1 KB
Line 
1/* $Id: HGSMIHostCmd.cpp 69309 2017-10-25 13:55:39Z vboxsync $ */
2/** @file
3 * VirtualBox Video driver, common code - HGSMI host-to-guest communication.
4 */
5
6/*
7 * Copyright (C) 2006-2017 Oracle Corporation
8 *
9 * Permission is hereby granted, free of charge, to any person
10 * obtaining a copy of this software and associated documentation
11 * files (the "Software"), to deal in the Software without
12 * restriction, including without limitation the rights to use,
13 * copy, modify, merge, publish, distribute, sublicense, and/or sell
14 * copies of the Software, and to permit persons to whom the
15 * Software is furnished to do so, subject to the following
16 * conditions:
17 *
18 * The above copyright notice and this permission notice shall be
19 * included in all copies or substantial portions of the Software.
20 *
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
23 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
25 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
27 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
28 * OTHER DEALINGS IN THE SOFTWARE.
29 */
30
31#include <VBoxVideoGuest.h>
32#include <VBoxVideoVBE.h>
33#include <VBoxVideoIPRT.h>
34#include <HGSMIHostCmd.h>
35
36/**
37 * Initialise the host context structure.
38 *
39 * @param pCtx the context structure to initialise
40 * @param pvBaseMapping where the basic HGSMI structures are mapped at
41 * @param offHostFlags the offset of the host flags into the basic HGSMI
42 * structures
43 * @param pvHostAreaMapping where the area for the host heap is mapped at
44 * @param offVRAMHostArea offset of the host heap area into VRAM
45 * @param cbHostArea size in bytes of the host heap area
46 */
47DECLHIDDEN(void) VBoxHGSMISetupHostContext(PHGSMIHOSTCOMMANDCONTEXT pCtx,
48 void *pvBaseMapping,
49 uint32_t offHostFlags,
50 void *pvHostAreaMapping,
51 uint32_t offVRAMHostArea,
52 uint32_t cbHostArea)
53{
54 uint8_t *pu8HostFlags = ((uint8_t *)pvBaseMapping) + offHostFlags;
55 pCtx->pfHostFlags = (HGSMIHOSTFLAGS *)pu8HostFlags;
56 /** @todo should we really be using a fixed ISA port value here? */
57 pCtx->port = (RTIOPORT)VGA_PORT_HGSMI_HOST;
58 HGSMIAreaInitialize(&pCtx->areaCtx, pvHostAreaMapping, cbHostArea,
59 offVRAMHostArea);
60}
61
62
63/** Send completion notification to the host for the command located at offset
64 * @a offt into the host command buffer. */
65static void HGSMINotifyHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx, HGSMIOFFSET offt)
66{
67 VBVO_PORT_WRITE_U32(pCtx->port, offt);
68}
69
70
71/**
72 * Inform the host that a command has been handled.
73 *
74 * @param pCtx the context containing the heap to be used
75 * @param pvMem pointer into the heap as mapped in @a pCtx to the command to
76 * be completed
77 */
78DECLHIDDEN(void) VBoxHGSMIHostCmdComplete(PHGSMIHOSTCOMMANDCONTEXT pCtx,
79 void *pvMem)
80{
81 HGSMIBUFFERHEADER *pHdr = HGSMIBufferHeaderFromData(pvMem);
82 HGSMIOFFSET offMem = HGSMIPointerToOffset(&pCtx->areaCtx, pHdr);
83 Assert(offMem != HGSMIOFFSET_VOID);
84 if(offMem != HGSMIOFFSET_VOID)
85 {
86 HGSMINotifyHostCmdComplete(pCtx, offMem);
87 }
88}
89
90
91/** Submit an incoming host command to the appropriate handler. */
92static void hgsmiHostCmdProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx,
93 HGSMIOFFSET offBuffer)
94{
95 int rc = HGSMIBufferProcess(&pCtx->areaCtx, &pCtx->channels, offBuffer);
96 Assert(!RT_FAILURE(rc));
97 if(RT_FAILURE(rc))
98 {
99 /* failure means the command was not submitted to the handler for some reason
100 * it's our responsibility to notify its completion in this case */
101 HGSMINotifyHostCmdComplete(pCtx, offBuffer);
102 }
103 /* if the cmd succeeded it's responsibility of the callback to complete it */
104}
105
106/** Get the next command from the host. */
107static HGSMIOFFSET hgsmiGetHostBuffer(PHGSMIHOSTCOMMANDCONTEXT pCtx)
108{
109 return VBVO_PORT_READ_U32(pCtx->port);
110}
111
112
113/** Get and handle the next command from the host. */
114static void hgsmiHostCommandQueryProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx)
115{
116 HGSMIOFFSET offset = hgsmiGetHostBuffer(pCtx);
117 AssertReturnVoid(offset != HGSMIOFFSET_VOID);
118 hgsmiHostCmdProcess(pCtx, offset);
119}
120
121
122/** Drain the host command queue. */
123DECLHIDDEN(void) VBoxHGSMIProcessHostQueue(PHGSMIHOSTCOMMANDCONTEXT pCtx)
124{
125 while (pCtx->pfHostFlags->u32HostFlags & HGSMIHOSTFLAGS_COMMANDS_PENDING)
126 {
127 if (!ASMAtomicCmpXchgBool(&pCtx->fHostCmdProcessing, true, false))
128 return;
129 hgsmiHostCommandQueryProcess(pCtx);
130 ASMAtomicWriteBool(&pCtx->fHostCmdProcessing, false);
131 }
132}
133
134
135/** Tell the host about the location of the area of VRAM set aside for the host
136 * heap. */
137static int vboxHGSMIReportHostArea(PHGSMIGUESTCOMMANDCONTEXT pCtx,
138 uint32_t u32AreaOffset, uint32_t u32AreaSize)
139{
140 VBVAINFOHEAP *p;
141 int rc = VINF_SUCCESS;
142
143 /* Allocate the IO buffer. */
144 p = (VBVAINFOHEAP *)VBoxHGSMIBufferAlloc(pCtx,
145 sizeof (VBVAINFOHEAP), HGSMI_CH_VBVA,
146 VBVA_INFO_HEAP);
147 if (p)
148 {
149 /* Prepare data to be sent to the host. */
150 p->u32HeapOffset = u32AreaOffset;
151 p->u32HeapSize = u32AreaSize;
152 rc = VBoxHGSMIBufferSubmit(pCtx, p);
153 /* Free the IO buffer. */
154 VBoxHGSMIBufferFree(pCtx, p);
155 }
156 else
157 rc = VERR_NO_MEMORY;
158 return rc;
159}
160
161
162/**
163 * Get the information needed to map the area used by the host to send back
164 * requests.
165 *
166 * @param pCtx the context containing the heap to use
167 * @param cbVRAM how much video RAM is allocated to the device
168 * @param offVRAMBaseMapping the offset of the basic communication structures
169 * into the guest's VRAM
170 * @param poffVRAMHostArea where to store the offset into VRAM of the host
171 * heap area
172 * @param pcbHostArea where to store the size of the host heap area
173 */
174DECLHIDDEN(void) VBoxHGSMIGetHostAreaMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx,
175 uint32_t cbVRAM,
176 uint32_t offVRAMBaseMapping,
177 uint32_t *poffVRAMHostArea,
178 uint32_t *pcbHostArea)
179{
180 uint32_t offVRAMHostArea = offVRAMBaseMapping, cbHostArea = 0;
181
182 AssertPtrReturnVoid(poffVRAMHostArea);
183 AssertPtrReturnVoid(pcbHostArea);
184 VBoxQueryConfHGSMI(pCtx, VBOX_VBVA_CONF32_HOST_HEAP_SIZE, &cbHostArea);
185 if (cbHostArea != 0)
186 {
187 uint32_t cbHostAreaMaxSize = cbVRAM / 4;
188 /** @todo what is the idea of this? */
189 if (cbHostAreaMaxSize >= VBVA_ADAPTER_INFORMATION_SIZE)
190 {
191 cbHostAreaMaxSize -= VBVA_ADAPTER_INFORMATION_SIZE;
192 }
193 if (cbHostArea > cbHostAreaMaxSize)
194 {
195 cbHostArea = cbHostAreaMaxSize;
196 }
197 /* Round up to 4096 bytes. */
198 cbHostArea = (cbHostArea + 0xFFF) & ~0xFFF;
199 offVRAMHostArea = offVRAMBaseMapping - cbHostArea;
200 }
201
202 *pcbHostArea = cbHostArea;
203 *poffVRAMHostArea = offVRAMHostArea;
204 // LogFunc(("offVRAMHostArea = 0x%08X, cbHostArea = 0x%08X\n",
205 // offVRAMHostArea, cbHostArea));
206}
207
208
209/**
210 * Tell the host about the ways it can use to communicate back to us via an
211 * HGSMI command
212 *
213 * @returns iprt status value
214 * @param pCtx the context containing the heap to use
215 * @param offVRAMFlagsLocation where we wish the host to place its flags
216 * relative to the start of the VRAM
217 * @param fCaps additions HGSMI capabilities the guest
218 * supports
219 * @param offVRAMHostArea offset into VRAM of the host heap area
220 * @param cbHostArea size in bytes of the host heap area
221 */
222DECLHIDDEN(int) VBoxHGSMISendHostCtxInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
223 HGSMIOFFSET offVRAMFlagsLocation,
224 uint32_t fCaps,
225 uint32_t offVRAMHostArea,
226 uint32_t cbHostArea)
227{
228 // Log(("VBoxVideo::vboxSetupAdapterInfo\n"));
229
230 /* setup the flags first to ensure they are initialized by the time the
231 * host heap is ready */
232 int rc = VBoxHGSMIReportFlagsLocation(pCtx, offVRAMFlagsLocation);
233 AssertRC(rc);
234 if (RT_SUCCESS(rc) && fCaps)
235 {
236 /* Inform about caps */
237 rc = VBoxHGSMISendCapsInfo(pCtx, fCaps);
238 AssertRC(rc);
239 }
240 if (RT_SUCCESS (rc))
241 {
242 /* Report the host heap location. */
243 rc = vboxHGSMIReportHostArea(pCtx, offVRAMHostArea, cbHostArea);
244 AssertRC(rc);
245 }
246 // Log(("VBoxVideo::vboxSetupAdapterInfo finished rc = %d\n", rc));
247 return rc;
248}
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