VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/VBoxPkg/VmwSvga3Dxe/Hardware.c

Last change on this file was 106066, checked in by vboxsync, 8 months ago

Manual copyright year updates.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 6.6 KB
Line 
1/** @file
2 This driver is a sample implementation of the Graphics Output Protocol for
3 the VMware SVGA 3 video controller.
4
5 Copyright (c) 2023 - 2024, Oracle and/or its affiliates.<BR>
6
7 SPDX-License-Identifier: BSD-2-Clause-Patent
8
9**/
10
11#include "VmwSvga3.h"
12
13
14/**
15 Read 4-bytes width VMware SVGA3 MMIO register.
16
17 @param VmwSvga3 The VMware SVGA3 Instance.
18 @param Offset The offset of the 4-bytes width operational register.
19
20 @return The register content read.
21 @retval If err, return 0xFFFFFFFF.
22
23**/
24UINT32
25VmwSvga3ReadReg (
26 IN VMWSVGA3_VIDEO_PRIVATE_DATA *VmwSvga3,
27 IN UINT32 Offset
28 )
29{
30 UINT32 Data;
31 EFI_STATUS Status;
32
33 Status = VmwSvga3->PciIo->Mem.Read (
34 VmwSvga3->PciIo,
35 EfiPciIoWidthUint32,
36 VMWSVGA3_MMIO_BAR,
37 Offset,
38 1,
39 &Data
40 );
41
42 if (EFI_ERROR (Status)) {
43 DEBUG ((DEBUG_ERROR, "VmwSvga3ReadReg: Pci Io Read error - %r at %d\n", Status, Offset));
44 Data = 0xFFFFFFFF;
45 }
46
47 return Data;
48}
49
50/**
51 Write the data to the 4-bytes width VMware SVGA3 MMIO register.
52
53 @param VmwSvga3 The VMware SVGA3 Instance.
54 @param Offset The offset of the 4-bytes width operational register.
55 @param Data The data to write.
56
57**/
58VOID
59VmwSvga3WriteReg (
60 IN VMWSVGA3_VIDEO_PRIVATE_DATA *VmwSvga3,
61 IN UINT32 Offset,
62 IN UINT32 Data
63 )
64{
65 EFI_STATUS Status;
66
67 Status = VmwSvga3->PciIo->Mem.Write (
68 VmwSvga3->PciIo,
69 EfiPciIoWidthUint32,
70 VMWSVGA3_MMIO_BAR,
71 Offset,
72 1,
73 &Data
74 );
75 if (EFI_ERROR (Status)) {
76 DEBUG ((DEBUG_ERROR, "VmwSvga3WriteReg: Pci Io Write error: %r at %d\n", Status, Offset));
77 }
78}
79
80/**
81 Initializes the given VMware SVGA3 video controller instance.
82
83 @param This The device instance.
84
85 @retval EFI_SUCCESS SVGA3 controller successfully initialised.
86 @retval EFI_UNSUPPORTED This device isn't supported.
87 @retval EFI_OUT_OF_RESOURCES Failed to allocate resources.
88
89**/
90EFI_STATUS
91VmwSvga3DeviceInit(
92 IN VMWSVGA3_VIDEO_PRIVATE_DATA *This
93 )
94{
95 UINTN NumberOfBytes = EFI_PAGES_TO_SIZE(1);
96 VMWSVGA3_DC_CMD_START_STOP_CTX *CmdDcStart;
97 EFI_STATUS Status;
98
99 VmwSvga3WriteReg(This, VMWSVGA3_REG_ID, VMWSVGA3_REG_ID_SVGA3);
100
101 if (VmwSvga3ReadReg(This, VMWSVGA3_REG_ID) != VMWSVGA3_REG_ID_SVGA3)
102 return EFI_UNSUPPORTED;
103
104 Status = This->PciIo->AllocateBuffer(This->PciIo, AllocateAnyPages,
105 EfiRuntimeServicesData, 1, (VOID **)&This->CmdBufHdr, 0);
106 if (EFI_ERROR(Status)) {
107 DEBUG ((DEBUG_ERROR, "VmwSvga3DeviceInit: memory allocation failed\n"));
108 return Status;
109 }
110
111 Status = This->PciIo->Map (
112 This->PciIo,
113 EfiPciIoOperationBusMasterCommonBuffer,
114 This->CmdBufHdr,
115 &NumberOfBytes,
116 &This->PhysicalAddressCmdBufHdr,
117 &This->CmdBufMapping
118 );
119 if (EFI_ERROR (Status)) {
120 DEBUG ((DEBUG_INFO, "VmwSvga3DeviceInit: Status=%x\n", Status));
121 return Status;
122 }
123
124 This->PhysicalAddressCmdBuf = This->PhysicalAddressCmdBufHdr + sizeof(*This->CmdBufHdr);
125 This->CmdBuf = This->CmdBufHdr + 1;
126 This->FrameBufferVramBarIndex = VMWSVGA3_VRAM_BAR;
127
128 VmwSvga3WriteReg(This, VMWSVGA3_REG_IRQMASK, 0); /* No interrupts enabled. */
129 VmwSvga3WriteReg(This, VMWSVGA3_REG_IRQ_STATUS, 0);
130 VmwSvga3WriteReg(This, VMWSVGA3_REG_ENABLE, 0);
131 VmwSvga3WriteReg(This, VMWSVGA3_REG_CONFIG_DONE, 0);
132
133 //
134 // Set up the device context
135 //
136 CmdDcStart = (VMWSVGA3_DC_CMD_START_STOP_CTX *)This->CmdBuf;
137
138 CmdDcStart->CmdId = VMWSVGA3_CMD_DC_START_STOP_CTX;
139 CmdDcStart->Enable = 1;
140 CmdDcStart->Context = VMWSVGA3_CB_CTX_0;
141
142 Status = VmwSvga3CmdBufProcess(This, sizeof(VMWSVGA3_DC_CMD_START_STOP_CTX), VMWSVGA3_CB_CTX_DEVICE);
143 if (EFI_ERROR (Status)) {
144 This->PciIo->Unmap (This->PciIo, This->CmdBufMapping);
145 This->PciIo->FreeBuffer (This->PciIo, 1, This->CmdBufHdr);
146 return Status;
147 }
148
149 return EFI_SUCCESS;
150}
151
152/**
153 Uninitializes the given VMware SVGA3 video controller instance, freeing all resources
154 acquired in VmwSvga3DeviceInit().
155
156 @param This The device instance.
157
158 @retval EFI_SUCCESS SVGA3 controller successfully destroyed.
159
160**/
161EFI_STATUS
162VmwSvga3DeviceUninit (
163 IN VMWSVGA3_VIDEO_PRIVATE_DATA *This
164 )
165{
166 EFI_STATUS Status;
167
168 //
169 // Teardown device context
170 //
171 VMWSVGA3_DC_CMD_START_STOP_CTX *CmdDcStart = (VMWSVGA3_DC_CMD_START_STOP_CTX *)This->CmdBuf;
172
173 CmdDcStart->CmdId = VMWSVGA3_CMD_DC_START_STOP_CTX;
174 CmdDcStart->Enable = 0;
175 CmdDcStart->Context = VMWSVGA3_CB_CTX_0;
176
177 Status = VmwSvga3CmdBufProcess(This, sizeof(VMWSVGA3_DC_CMD_START_STOP_CTX), VMWSVGA3_CB_CTX_DEVICE);
178 if (EFI_ERROR (Status)) {
179 DEBUG ((DEBUG_ERROR, "VmwSvga3DeviceUninit: Disabling device context failed -> Status=%x\n", Status));
180 }
181
182 This->PciIo->Unmap (This->PciIo, This->CmdBufMapping);
183 This->PciIo->FreeBuffer (This->PciIo, 1, This->CmdBufHdr);
184
185 return EFI_SUCCESS;
186}
187
188EFI_STATUS
189VmwSvga3CmdBufProcess (
190 IN VMWSVGA3_VIDEO_PRIVATE_DATA *This,
191 IN UINTN NumberOfBytes,
192 IN UINT32 Context
193 )
194{
195 EFI_STATUS Status;
196 VMWSVGA3_CB_HDR *CmdBufHdr = This->CmdBufHdr;
197
198 CmdBufHdr->Status = VMWSVGA3_CB_STATUS_NONE;
199 CmdBufHdr->Flags = VMWSVGA3_CB_FLAG_NO_IRQ;
200 CmdBufHdr->PhysicalAddress = This->PhysicalAddressCmdBuf;
201 CmdBufHdr->Length = NumberOfBytes;
202
203 DEBUG ((DEBUG_INFO, "VmwSvga3CmdBufProcess: PhysicalAddressCmdBufHdr=%Lx Context=%x\n", This->PhysicalAddressCmdBufHdr, Context));
204
205 VmwSvga3WriteReg(This, VMWSVGA3_REG_COMMAND_HIGH, (UINT32)(This->PhysicalAddressCmdBufHdr >> 32));
206 VmwSvga3WriteReg(This, VMWSVGA3_REG_COMMAND_LOW, (UINT32)This->PhysicalAddressCmdBufHdr | Context);
207
208 //
209 // Wait until the command buffer has completed.
210 //
211 while (CmdBufHdr->Status == VMWSVGA3_CB_STATUS_NONE);
212
213 if (CmdBufHdr->Status == VMWSVGA3_CB_STATUS_COMPLETED)
214 Status = EFI_SUCCESS;
215 else
216 Status = EFI_ABORTED;
217
218 return Status;
219}
220
Note: See TracBrowser for help on using the repository browser.

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