VirtualBox

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

最後變更 在這個檔案是 106061,由 vboxsync 提交於 2 月 前

Copyright year updates by scm.

  • 屬性 svn:eol-style 設為 native
  • 屬性 svn:keywords 設為 Author Date Id Revision
檔案大小: 9.1 KB
 
1/* $Id: HGSMIHostCmd.cpp 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * VirtualBox Video driver, common code - HGSMI host-to-guest communication.
4 */
5
6/*
7 * Copyright (C) 2006-2024 Oracle and/or its affiliates.
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, void RT_UNTRUSTED_VOLATILE_HOST *pvMem)
79{
80 HGSMIBUFFERHEADER RT_UNTRUSTED_VOLATILE_GUEST *pHdr = HGSMIBufferHeaderFromData(pvMem);
81 HGSMIOFFSET offMem = HGSMIPointerToOffset(&pCtx->areaCtx, pHdr);
82 Assert(offMem != HGSMIOFFSET_VOID);
83 if (offMem != HGSMIOFFSET_VOID)
84 HGSMINotifyHostCmdComplete(pCtx, offMem);
85}
86
87
88/** Submit an incoming host command to the appropriate handler. */
89static void hgsmiHostCmdProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx,
90 HGSMIOFFSET offBuffer)
91{
92 int rc = HGSMIBufferProcess(&pCtx->areaCtx, &pCtx->channels, offBuffer);
93 Assert(!RT_FAILURE(rc));
94 if(RT_FAILURE(rc))
95 {
96 /* failure means the command was not submitted to the handler for some reason
97 * it's our responsibility to notify its completion in this case */
98 HGSMINotifyHostCmdComplete(pCtx, offBuffer);
99 }
100 /* if the cmd succeeded it's responsibility of the callback to complete it */
101}
102
103/** Get the next command from the host. */
104static HGSMIOFFSET hgsmiGetHostBuffer(PHGSMIHOSTCOMMANDCONTEXT pCtx)
105{
106 return VBVO_PORT_READ_U32(pCtx->port);
107}
108
109
110/** Get and handle the next command from the host. */
111static void hgsmiHostCommandQueryProcess(PHGSMIHOSTCOMMANDCONTEXT pCtx)
112{
113 HGSMIOFFSET offset = hgsmiGetHostBuffer(pCtx);
114 AssertReturnVoid(offset != HGSMIOFFSET_VOID);
115 hgsmiHostCmdProcess(pCtx, offset);
116}
117
118
119/** Drain the host command queue. */
120DECLHIDDEN(void) VBoxHGSMIProcessHostQueue(PHGSMIHOSTCOMMANDCONTEXT pCtx)
121{
122 while (pCtx->pfHostFlags->u32HostFlags & HGSMIHOSTFLAGS_COMMANDS_PENDING)
123 {
124 if (!ASMAtomicCmpXchgBool(&pCtx->fHostCmdProcessing, true, false))
125 return;
126 hgsmiHostCommandQueryProcess(pCtx);
127 ASMAtomicWriteBool(&pCtx->fHostCmdProcessing, false);
128 }
129}
130
131
132/** Tell the host about the location of the area of VRAM set aside for the host
133 * heap. */
134static int vboxHGSMIReportHostArea(PHGSMIGUESTCOMMANDCONTEXT pCtx,
135 uint32_t u32AreaOffset, uint32_t u32AreaSize)
136{
137 VBVAINFOHEAP *p;
138 int rc = VINF_SUCCESS;
139
140 /* Allocate the IO buffer. */
141 p = (VBVAINFOHEAP *)VBoxHGSMIBufferAlloc(pCtx,
142 sizeof (VBVAINFOHEAP), HGSMI_CH_VBVA,
143 VBVA_INFO_HEAP);
144 if (p)
145 {
146 /* Prepare data to be sent to the host. */
147 p->u32HeapOffset = u32AreaOffset;
148 p->u32HeapSize = u32AreaSize;
149 rc = VBoxHGSMIBufferSubmit(pCtx, p);
150 /* Free the IO buffer. */
151 VBoxHGSMIBufferFree(pCtx, p);
152 }
153 else
154 rc = VERR_NO_MEMORY;
155 return rc;
156}
157
158
159/**
160 * Get the information needed to map the area used by the host to send back
161 * requests.
162 *
163 * @param pCtx the context containing the heap to use
164 * @param cbVRAM how much video RAM is allocated to the device
165 * @param offVRAMBaseMapping the offset of the basic communication structures
166 * into the guest's VRAM
167 * @param poffVRAMHostArea where to store the offset into VRAM of the host
168 * heap area
169 * @param pcbHostArea where to store the size of the host heap area
170 */
171DECLHIDDEN(void) VBoxHGSMIGetHostAreaMapping(PHGSMIGUESTCOMMANDCONTEXT pCtx,
172 uint32_t cbVRAM,
173 uint32_t offVRAMBaseMapping,
174 uint32_t *poffVRAMHostArea,
175 uint32_t *pcbHostArea)
176{
177 uint32_t offVRAMHostArea = offVRAMBaseMapping, cbHostArea = 0;
178
179 AssertPtrReturnVoid(poffVRAMHostArea);
180 AssertPtrReturnVoid(pcbHostArea);
181 VBoxQueryConfHGSMI(pCtx, VBOX_VBVA_CONF32_HOST_HEAP_SIZE, &cbHostArea);
182 if (cbHostArea != 0)
183 {
184 uint32_t cbHostAreaMaxSize = cbVRAM / 4;
185 /** @todo what is the idea of this? */
186 if (cbHostAreaMaxSize >= VBVA_ADAPTER_INFORMATION_SIZE)
187 {
188 cbHostAreaMaxSize -= VBVA_ADAPTER_INFORMATION_SIZE;
189 }
190 if (cbHostArea > cbHostAreaMaxSize)
191 {
192 cbHostArea = cbHostAreaMaxSize;
193 }
194 /* Round up to 4096 bytes. */
195 cbHostArea = (cbHostArea + 0xFFF) & ~0xFFF;
196 offVRAMHostArea = offVRAMBaseMapping - cbHostArea;
197 }
198
199 *pcbHostArea = cbHostArea;
200 *poffVRAMHostArea = offVRAMHostArea;
201 // LogFunc(("offVRAMHostArea = 0x%08X, cbHostArea = 0x%08X\n",
202 // offVRAMHostArea, cbHostArea));
203}
204
205
206/**
207 * Tell the host about the ways it can use to communicate back to us via an
208 * HGSMI command
209 *
210 * @returns iprt status value
211 * @param pCtx the context containing the heap to use
212 * @param offVRAMFlagsLocation where we wish the host to place its flags
213 * relative to the start of the VRAM
214 * @param fCaps additions HGSMI capabilities the guest
215 * supports
216 * @param offVRAMHostArea offset into VRAM of the host heap area
217 * @param cbHostArea size in bytes of the host heap area
218 */
219DECLHIDDEN(int) VBoxHGSMISendHostCtxInfo(PHGSMIGUESTCOMMANDCONTEXT pCtx,
220 HGSMIOFFSET offVRAMFlagsLocation,
221 uint32_t fCaps,
222 uint32_t offVRAMHostArea,
223 uint32_t cbHostArea)
224{
225 // Log(("VBoxVideo::vboxSetupAdapterInfo\n"));
226
227 /* setup the flags first to ensure they are initialized by the time the
228 * host heap is ready */
229 int rc = VBoxHGSMIReportFlagsLocation(pCtx, offVRAMFlagsLocation);
230 AssertRC(rc);
231 if (RT_SUCCESS(rc) && fCaps)
232 {
233 /* Inform about caps */
234 rc = VBoxHGSMISendCapsInfo(pCtx, fCaps);
235 AssertRC(rc);
236 }
237 if (RT_SUCCESS (rc))
238 {
239 /* Report the host heap location. */
240 rc = vboxHGSMIReportHostArea(pCtx, offVRAMHostArea, cbHostArea);
241 AssertRC(rc);
242 }
243 // Log(("VBoxVideo::vboxSetupAdapterInfo finished rc = %d\n", rc));
244 return rc;
245}
注意: 瀏覽 TracBrowser 來幫助您使用儲存庫瀏覽器

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette