VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware/VBoxPkg/VBoxVgaDxe/VBoxVga.c

Last change on this file was 106061, checked in by vboxsync, 5 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: 38.6 KB
Line 
1/* $Id: VBoxVga.c 106061 2024-09-16 14:03:52Z vboxsync $ */
2/** @file
3 * VBoxVga.c
4 */
5
6/*
7 * Copyright (C) 2009-2024 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 * The contents of this file may alternatively be used under the terms
26 * of the Common Development and Distribution License Version 1.0
27 * (CDDL), a copy of it is provided in the "COPYING.CDDL" file included
28 * in the VirtualBox distribution, in which case the provisions of the
29 * CDDL are applicable instead of those of the GPL.
30 *
31 * You may elect to license modified versions of this file under the
32 * terms and conditions of either the GPL or the CDDL or both.
33 *
34 * SPDX-License-Identifier: GPL-3.0-only OR CDDL-1.0
35 */
36
37/*
38 This code is based on:
39
40 Cirrus Logic 5430 Controller Driver.
41 This driver is a sample implementation of the UGA Draw and Graphics Output
42 Protocols for the Cirrus Logic 5430 family of PCI video controllers.
43 This driver is only usable in the EFI pre-boot environment.
44 This sample is intended to show how the UGA Draw and Graphics output Protocol
45 is able to function.
46 The UGA I/O Protocol is not implemented in this sample.
47 A fully compliant EFI UGA driver requires both
48 the UGA Draw and the UGA I/O Protocol. Please refer to Microsoft's
49 documentation on UGA for details on how to write a UGA driver that is able
50 to function both in the EFI pre-boot environment and from the OS runtime.
51
52 Copyright (c) 2006 - 2009, Intel Corporation
53 All rights reserved. This program and the accompanying materials
54 are licensed and made available under the terms and conditions of the BSD License
55 which accompanies this distribution. The full text of the license may be found at
56 http://opensource.org/licenses/bsd-license.php
57
58 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
59 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
60
61*/
62
63//
64// VirtualBox VGA Controller Driver
65//
66#include "VBoxVga.h"
67#include <IndustryStandard/Acpi.h>
68#include "iprt/asm.h"
69
70
71#define BOUTB(storage, count, aport, dport) \
72 do { \
73 for (i = 0 ; i < (count); ++i) \
74 if ((dport) == (aport) + 1) \
75 ASMOutU16((aport), ((UINT16)storage[i] << 8) | (UINT8)i); \
76 else { \
77 ASMOutU8((aport), (UINT8)i); \
78 ASMOutU8((dport), storage[i]); \
79 } \
80 } while (0)
81
82
83
84EFI_DRIVER_BINDING_PROTOCOL gVBoxVgaDriverBinding = {
85 VBoxVgaControllerDriverSupported,
86 VBoxVgaControllerDriverStart,
87 VBoxVgaControllerDriverStop,
88 0x10,
89 NULL,
90 NULL
91};
92
93///
94/// Generic Attribute Controller Register Settings
95///
96UINT8 AttributeController[21] = {
97 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
98 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
99 0x41, 0x00, 0x0F, 0x00, 0x00
100};
101
102///
103/// Generic Graphics Controller Register Settings
104///
105UINT8 GraphicsController[9] = {
106 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xff
107};
108
109///
110/// Generic Graphics Controller Sequencer Register Settings
111///
112UINT8 Seq_Default[5] = {
113 0x01, 0x01, 0x0f, 0x00, 0x0a
114};
115
116#if 0 // CRTC tables not used (and not checked for correctness), as VBE is much simpler
117//
118// 640 x 480 x 256 color @ 60 Hertz
119//
120UINT8 Crtc_640_480_256_60[25] = {
121 /* r0 = */0x5f, /* r1 = */0x4f, /* r2 = */0x50, /* r3 = */0x82,
122 /* r4 = */0x54, /* r5 = */0x80, /* r6 = */0x0b, /* r7 = */0x3e,
123 /* r8 = */0x00, /* r9 = */0x40, /* r10 = */0x00, /* r11 = */0x00,
124 /* r12 = */0x00, /* r13 = */0x00, /* r14 = */0x00, /* r15 = */0x00,
125 /* r16 = */0xea, /* r17 = */0x0c, /* r18 = */0xdf, /* r19 = */0x28,
126 /* r20 = */0x4f, /* r21 = */0xe7, /* r22 = */0x04, /* r23 = */0xe3,
127 /* r24 = */0xff
128};
129
130//
131// 800 x 600 x 256 color @ 60 Hertz
132//
133UINT8 Crtc_800_600_256_60[25] = {
134 /* r0 = */0x7f, /* r1 = */0x63, /* r2 = */0x64, /* r3 = */0x82,
135 /* r4 = */0x6b, /* r5 = */0x80, /* r6 = */0x0b, /* r7 = */0x3e,
136 /* r8 = */0x00, /* r9 = */0x60, /* r10 = */0x00, /* r11 = */0x00,
137 /* r12 = */0x00, /* r13 = */0x00, /* r14 = */0x00, /* r15 = */0x00,
138 /* r16 = */0xea, /* r17 = */0x0c, /* r18 = */0xdf, /* r19 = */0x28,
139 /* r20 = */0x4f, /* r21 = */0xe7, /* r22 = */0x04, /* r23 = */0xe3,
140 /* r24 = */0xff
141
142};
143
144//
145// 1024 x 768 x 256 color @ 60 Hertz
146//
147UINT8 Crtc_1024_768_256_60[25] = {
148 /* r0 = */0xa3, /* r1 = */0x7f, /* r2 = */0x81, /* r3 = */0x90,
149 /* r4 = */0x88, /* r5 = */0x05, /* r6 = */0x28, /* r7 = */0xfd,
150 /* r8 = */0x00, /* r9 = */0x60, /* r10 = */0x00, /* r11 = */0x00,
151 /* r12 = */0x00, /* r13 = */0x00, /* r14 = */0x00, /* r15 = */0x00,
152 /* r16 = */0x06, /* r17 = */0x0f, /* r18 = */0xff, /* r19 = */0x40,
153 /* r20 = */0x4f, /* r21 = */0x05, /* r22 = */0x1a, /* r23 = */0xe3,
154 /* r24 = */0xff
155};
156#endif
157
158///
159/// Table of supported video modes (sorted by increasing horizontal, then by
160/// increasing vertical resolution)
161///
162VBOX_VGA_VIDEO_MODES VBoxVgaVideoModes[] =
163{
164 { 640, 480, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // VGA 4:3
165 { 800, 600, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // SVGA 4:3
166 { 1024, 768, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // XGA 4:3
167 { 1152, 864, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // XGA+ 4:3
168 { 1280, 720, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // HD 16:9
169 { 1280, 800, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // WXGA 16:10
170 { 1280, 1024, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // SXGA 5:4
171 { 1400, 1050, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // SXGA+ 4:3
172 { 1440, 900, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // WXGA+ 16:10
173 { 1600, 900, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // HD+ 16:9
174 { 1600, 1200, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // UXGA 4:3
175 { 1680, 1050, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // WSXGA+ 16:10
176 { 1920, 1080, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // FHD 16:9
177 { 1920, 1200, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // WUXGA 16:10
178 { 2048, 1080, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // DCI_2K 19:10
179 { 2160, 1440, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // FHD+ 3:2
180 { 2304, 1440, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // unnamed 16:10
181 { 2560, 1440, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // QHD 16:9
182 { 2560, 1600, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // WQXGA 16:10
183 { 2880, 1800, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // QWXGA+ 16:10
184 { 3200, 1800, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // QHD+ 16:9
185 { 3200, 2048, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // WQSXGA 16:10
186 { 3840, 2160, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // 4K_UHD 16:9
187 { 3840, 2400, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // WQUXGA 16:10
188 { 4096, 2160, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // DCI_4K 19:10
189 { 4096, 3072, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // HXGA 4:3
190 { 5120, 2880, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // UHD+ 16:9
191 { 5120, 3200, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // WHXGA 16:10
192 { 6400, 4096, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // WHSXGA 16:10
193 { 6400, 4800, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // HUXGA 4:3
194 { 7680, 4320, 32, 60, NULL /* crtc */, NULL /* sequencer */, 0x01 }, // 8K_UHD2 16:9
195 { 0, }, // Custom video mode 0, do not delete, must be at the end!
196 { 0, }, // Custom video mode 1, do not delete, must be at the end!
197 { 0, }, // Custom video mode 2, do not delete, must be at the end!
198 { 0, }, // Custom video mode 3, do not delete, must be at the end!
199 { 0, }, // Custom video mode 4, do not delete, must be at the end!
200 { 0, }, // Custom video mode 5, do not delete, must be at the end!
201 { 0, }, // Custom video mode 6, do not delete, must be at the end!
202 { 0, }, // Custom video mode 7, do not delete, must be at the end!
203 { 0, }, // Custom video mode 8, do not delete, must be at the end!
204 { 0, }, // Custom video mode 9, do not delete, must be at the end!
205 { 0, }, // Custom video mode 10, do not delete, must be at the end!
206 { 0, }, // Custom video mode 11, do not delete, must be at the end!
207 { 0, }, // Custom video mode 12, do not delete, must be at the end!
208 { 0, }, // Custom video mode 13, do not delete, must be at the end!
209 { 0, }, // Custom video mode 14, do not delete, must be at the end!
210 { 0, } // Custom video mode 15, do not delete, must be at the end!
211};
212
213const UINT32 VBoxVgaVideoModeCount = sizeof(VBoxVgaVideoModes) / sizeof(VBoxVgaVideoModes[0]);
214
215typedef struct _APPLE_FRAMEBUFFERINFO_PROTOCOL APPLE_FRAMEBUFFERINFO_PROTOCOL;
216
217typedef
218EFI_STATUS
219(EFIAPI *APPLE_FRAMEBUFFERINFO_PROTOCOL_GET_INFO) (
220 IN APPLE_FRAMEBUFFERINFO_PROTOCOL *This,
221 OUT UINT32 *BaseAddr,
222 OUT UINT32 *Something,
223 OUT UINT32 *RowBytes,
224 OUT UINT32 *Width,
225 OUT UINT32 *Height,
226 OUT UINT32 *Depth);
227
228struct _APPLE_FRAMEBUFFERINFO_PROTOCOL {
229 APPLE_FRAMEBUFFERINFO_PROTOCOL_GET_INFO GetInfo;
230 VBOX_VGA_PRIVATE_DATA *Private;
231};
232
233EFI_STATUS EFIAPI
234GetFrameBufferInfo(IN APPLE_FRAMEBUFFERINFO_PROTOCOL *This,
235 OUT UINT32 *BaseAddr,
236 OUT UINT32 *Something,
237 OUT UINT32 *RowBytes,
238 OUT UINT32 *Width,
239 OUT UINT32 *Height,
240 OUT UINT32 *Depth);
241
242static APPLE_FRAMEBUFFERINFO_PROTOCOL gAppleFrameBufferInfo =
243{
244 GetFrameBufferInfo,
245 NULL
246};
247
248
249/*
250 * @todo move this function to the library.
251 */
252UINT32 VBoxVgaGetVmVariable(UINT32 Variable, CHAR8* Buffer, UINT32 Size)
253{
254 UINT32 VarLen, i;
255
256 ASMOutU32(EFI_INFO_PORT, Variable);
257 VarLen = ASMInU32(EFI_INFO_PORT);
258
259 for (i = 0; i < VarLen && i < Size; i++)
260 Buffer[i] = ASMInU8(EFI_INFO_PORT);
261
262 return VarLen;
263}
264
265
266/**
267 VBoxVgaControllerDriverSupported
268
269 TODO: This - add argument and description to function comment
270 TODO: Controller - add argument and description to function comment
271 TODO: RemainingDevicePath - add argument and description to function comment
272**/
273EFI_STATUS
274EFIAPI
275VBoxVgaControllerDriverSupported (
276 IN EFI_DRIVER_BINDING_PROTOCOL *This,
277 IN EFI_HANDLE Controller,
278 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
279 )
280{
281 EFI_STATUS Status;
282 EFI_PCI_IO_PROTOCOL *PciIo;
283 PCI_TYPE00 Pci;
284 EFI_DEV_PATH *Node;
285
286 //
287 // Open the PCI I/O Protocol
288 //
289 Status = gBS->OpenProtocol (
290 Controller,
291 &gEfiPciIoProtocolGuid,
292 (VOID **) &PciIo,
293 This->DriverBindingHandle,
294 Controller,
295 EFI_OPEN_PROTOCOL_BY_DRIVER
296 );
297 if (EFI_ERROR (Status)) {
298 DEBUG((DEBUG_INFO, "%a:%d status:%r\n", __FILE__, __LINE__, Status));
299 return Status;
300 }
301
302 //
303 // Read the PCI Configuration Header from the PCI Device
304 //
305 Status = PciIo->Pci.Read (
306 PciIo,
307 EfiPciIoWidthUint32,
308 0,
309 sizeof (Pci) / sizeof (UINT32),
310 &Pci
311 );
312 if (EFI_ERROR (Status)) {
313 DEBUG((DEBUG_INFO, "%a:%d status:%r\n", __FILE__, __LINE__, Status));
314 goto Done;
315 }
316
317 Status = EFI_UNSUPPORTED;
318 //
319 // See if the I/O enable is on. Most systems only allow one VGA device to be turned on
320 // at a time, so see if this is one that is turned on.
321 //
322 // if (((Pci.Hdr.Command & 0x01) == 0x01)) {
323 //
324 // See if this is a VirtualBox VGA or VMSVGA II PCI controller
325 //
326 if ( ((Pci.Hdr.VendorId == VBOX_VENDOR_ID) && (Pci.Hdr.DeviceId == VBOX_VGA_DEVICE_ID))
327 || ((Pci.Hdr.VendorId == VMSVGA_VENDOR_ID) && (Pci.Hdr.DeviceId == VMSVGA_II_DEVICE_ID))) {
328
329 Status = EFI_SUCCESS;
330 if (RemainingDevicePath != NULL) {
331 Node = (EFI_DEV_PATH *) RemainingDevicePath;
332 //
333 // Check if RemainingDevicePath is the End of Device Path Node,
334 // if yes, return EFI_SUCCESS
335 //
336 if (!IsDevicePathEnd (Node)) {
337 //
338 // If RemainingDevicePath isn't the End of Device Path Node,
339 // check its validation
340 //
341 if (Node->DevPath.Type != ACPI_DEVICE_PATH ||
342 Node->DevPath.SubType != ACPI_ADR_DP ||
343 DevicePathNodeLength(&Node->DevPath) != sizeof(ACPI_ADR_DEVICE_PATH)) {
344 DEBUG((DEBUG_INFO, "%a:%d status:%r\n", __FILE__, __LINE__, Status));
345 Status = EFI_UNSUPPORTED;
346 }
347 }
348 }
349 }
350
351Done:
352 //
353 // Close the PCI I/O Protocol
354 //
355 gBS->CloseProtocol (
356 Controller,
357 &gEfiPciIoProtocolGuid,
358 This->DriverBindingHandle,
359 Controller
360 );
361
362 DEBUG((DEBUG_INFO, "%a:%d status:%r\n", __FILE__, __LINE__, Status));
363 return Status;
364}
365
366/**
367 VBoxVgaControllerDriverStart
368
369 TODO: This - add argument and description to function comment
370 TODO: Controller - add argument and description to function comment
371 TODO: RemainingDevicePath - add argument and description to function comment
372**/
373EFI_STATUS
374EFIAPI
375VBoxVgaControllerDriverStart (
376 IN EFI_DRIVER_BINDING_PROTOCOL *This,
377 IN EFI_HANDLE Controller,
378 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath
379 )
380{
381 EFI_STATUS Status;
382 VBOX_VGA_PRIVATE_DATA *Private;
383 BOOLEAN PciAttributesSaved;
384 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
385 ACPI_ADR_DEVICE_PATH AcpiDeviceNode;
386 PCI_TYPE00 Pci;
387
388 PciAttributesSaved = FALSE;
389 //
390 // Allocate Private context data for UGA Draw interface.
391 //
392 Private = AllocateZeroPool (sizeof (VBOX_VGA_PRIVATE_DATA));
393 if (Private == NULL) {
394 Status = EFI_OUT_OF_RESOURCES;
395 goto Error;
396 }
397 gAppleFrameBufferInfo.Private = Private;
398 //
399 // Set up context record
400 //
401 Private->Signature = VBOX_VGA_PRIVATE_DATA_SIGNATURE;
402 Private->Handle = NULL;
403
404 //
405 // Open PCI I/O Protocol
406 //
407 Status = gBS->OpenProtocol (
408 Controller,
409 &gEfiPciIoProtocolGuid,
410 (VOID **) &Private->PciIo,
411 This->DriverBindingHandle,
412 Controller,
413 EFI_OPEN_PROTOCOL_BY_DRIVER
414 );
415 if (EFI_ERROR (Status)) {
416 goto Error;
417 }
418
419 //
420 // Read the PCI Configuration Header from the PCI Device again to figure out the model.
421 //
422 Status = Private->PciIo->Pci.Read (
423 Private->PciIo,
424 EfiPciIoWidthUint32,
425 0,
426 sizeof (Pci) / sizeof (UINT32),
427 &Pci
428 );
429 if (EFI_ERROR (Status)) {
430 DEBUG((DEBUG_INFO, "%a:%d status:%r\n", __FILE__, __LINE__, Status));
431 goto Error;
432 }
433
434 Private->DeviceType = Pci.Hdr.DeviceId;
435
436 //
437 // Save original PCI attributes
438 //
439 Status = Private->PciIo->Attributes (
440 Private->PciIo,
441 EfiPciIoAttributeOperationGet,
442 0,
443 &Private->OriginalPciAttributes
444 );
445
446 if (EFI_ERROR (Status)) {
447 goto Error;
448 }
449 PciAttributesSaved = TRUE;
450
451 Status = Private->PciIo->Attributes (
452 Private->PciIo,
453 EfiPciIoAttributeOperationEnable,
454 EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | EFI_PCI_IO_ATTRIBUTE_VGA_IO,
455 NULL
456 );
457 if (EFI_ERROR (Status)) {
458 goto Error;
459 }
460
461 //
462 // Get ParentDevicePath
463 //
464 Status = gBS->HandleProtocol (
465 Controller,
466 &gEfiDevicePathProtocolGuid,
467 (VOID **) &ParentDevicePath
468 );
469 if (EFI_ERROR (Status)) {
470 goto Error;
471 }
472
473 if (FeaturePcdGet (PcdSupportGop)) {
474 //
475 // Set Gop Device Path
476 //
477 if (RemainingDevicePath == NULL) {
478 ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH));
479 AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH;
480 AcpiDeviceNode.Header.SubType = ACPI_ADR_DP;
481 AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0);
482 SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH));
483
484 Private->GopDevicePath = AppendDevicePathNode (
485 ParentDevicePath,
486 (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode
487 );
488 } else if (!IsDevicePathEnd (RemainingDevicePath)) {
489 //
490 // If RemainingDevicePath isn't the End of Device Path Node,
491 // only scan the specified device by RemainingDevicePath
492 //
493 Private->GopDevicePath = AppendDevicePathNode (ParentDevicePath, RemainingDevicePath);
494 } else {
495 //
496 // If RemainingDevicePath is the End of Device Path Node,
497 // don't create child device and return EFI_SUCCESS
498 //
499 Private->GopDevicePath = NULL;
500 }
501
502 if (Private->GopDevicePath != NULL) {
503 //
504 // Create child handle and device path protocol first
505 //
506 Private->Handle = NULL;
507 Status = gBS->InstallMultipleProtocolInterfaces (
508 &Private->Handle,
509 &gEfiDevicePathProtocolGuid,
510 Private->GopDevicePath,
511 NULL
512 );
513 }
514 }
515
516 //
517 // Now do some model-specific setup.
518 //
519 if (Private->DeviceType == VMSVGA_II_DEVICE_ID) {
520 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *IOPortDesc;
521
522 // VMSVGA
523 Private->BarIndexFB = 1;
524
525 Private->PciIo->GetBarAttributes (
526 Private->PciIo,
527 0, // BAR 0 is the I/O port space
528 NULL,
529 (VOID**) &IOPortDesc
530 );
531 Private->IOBase = (UINT16)IOPortDesc->AddrRangeMin;
532
533 //
534 // Query the VRAM size (for proper mode filtering)
535 //
536 ASMOutU32(Private->IOBase + SVGA_INDEX_PORT, SVGA_REG_VRAM_SIZE);
537 Private->VRAMSize = ASMInU32(Private->IOBase + SVGA_VALUE_PORT);
538
539#if 0
540 // Not used because of buggy emulation(?) which is not fully compatible
541 // with the simple "legacy" VMSVGA II register interface.
542
543 // Enable the device, set initial mode
544 ASMOutU32(Private->IOBase + SVGA_INDEX_PORT, SVGA_REG_WIDTH);
545 ASMOutU32(Private->IOBase + SVGA_VALUE_PORT, 1024);
546 ASMOutU32(Private->IOBase + SVGA_INDEX_PORT, SVGA_REG_HEIGHT);
547 ASMOutU32(Private->IOBase + SVGA_VALUE_PORT, 768);
548 ASMOutU32(Private->IOBase + SVGA_INDEX_PORT, SVGA_REG_BYTES_PER_LINE);
549 ASMOutU32(Private->IOBase + SVGA_VALUE_PORT, 768 * 4);
550 ASMOutU32(Private->IOBase + SVGA_INDEX_PORT, SVGA_REG_BITS_PER_PIXEL);
551 ASMOutU32(Private->IOBase + SVGA_VALUE_PORT, 32);
552 ASMOutU32(Private->IOBase + SVGA_INDEX_PORT, SVGA_REG_CONFIG_DONE);
553 ASMOutU32(Private->IOBase + SVGA_VALUE_PORT, 1);
554
555 ASMOutU32(Private->IOBase + SVGA_INDEX_PORT, SVGA_REG_ENABLE);
556 ASMOutU32(Private->IOBase + SVGA_VALUE_PORT, SVGA_REG_ENABLE_ENABLE);
557#endif
558 } else {
559 // VBoxVGA / VBoxSVGA
560 Private->BarIndexFB = 0;
561 //
562 // Get VRAM size, needed for constructing a correct video mode list
563 //
564 Private->VRAMSize = ASMInU32(VBE_DISPI_IOPORT_DATA);
565 }
566
567
568 //
569 // Construct video mode list
570 //
571 Status = VBoxVgaVideoModeSetup (Private);
572 if (EFI_ERROR (Status)) {
573 goto Error;
574 }
575
576 if (FeaturePcdGet (PcdSupportUga)) {
577 //
578 // Start the UGA Draw software stack.
579 //
580 Status = VBoxVgaUgaDrawConstructor (Private);
581 ASSERT_EFI_ERROR (Status);
582
583 Private->UgaDevicePath = ParentDevicePath;
584 Status = gBS->InstallMultipleProtocolInterfaces (
585 &Controller,
586 //&gEfiUgaDrawProtocolGuid,
587 //&Private->UgaDraw,
588 &gEfiDevicePathProtocolGuid,
589 Private->UgaDevicePath,
590 NULL
591 );
592 Status = gBS->InstallMultipleProtocolInterfaces (
593 &Controller,
594 &gEfiUgaDrawProtocolGuid,
595 &Private->UgaDraw,
596 NULL
597 );
598
599 } else if (FeaturePcdGet (PcdSupportGop)) {
600 if (Private->GopDevicePath == NULL) {
601 //
602 // If RemainingDevicePath is the End of Device Path Node,
603 // don't create child device and return EFI_SUCCESS
604 //
605 Status = EFI_SUCCESS;
606 } else {
607
608 //
609 // Start the GOP software stack.
610 //
611 Status = VBoxVgaGraphicsOutputConstructor (Private);
612 ASSERT_EFI_ERROR (Status);
613
614 Status = gBS->InstallMultipleProtocolInterfaces (
615 &Private->Handle,
616 &gEfiGraphicsOutputProtocolGuid,
617 &Private->GraphicsOutput,
618 &gEfiEdidDiscoveredProtocolGuid,
619 &Private->EdidDiscovered,
620 &gEfiEdidActiveProtocolGuid,
621 &Private->EdidActive,
622 NULL
623 );
624 }
625 } else {
626 //
627 // This driver must support eithor GOP or UGA or both.
628 //
629 ASSERT (FALSE);
630 Status = EFI_UNSUPPORTED;
631 }
632
633Error:
634 if (EFI_ERROR (Status)) {
635 if (Private) {
636 if (Private->PciIo) {
637 if (PciAttributesSaved == TRUE) {
638 //
639 // Restore original PCI attributes
640 //
641 Private->PciIo->Attributes (
642 Private->PciIo,
643 EfiPciIoAttributeOperationSet,
644 Private->OriginalPciAttributes,
645 NULL
646 );
647 }
648 //
649 // Close the PCI I/O Protocol
650 //
651 gBS->CloseProtocol (
652 Private->Handle,
653 &gEfiPciIoProtocolGuid,
654 This->DriverBindingHandle,
655 Private->Handle
656 );
657 }
658
659 gBS->FreePool (Private);
660 }
661 }
662
663 return Status;
664}
665
666/**
667 VBoxVgaControllerDriverStop
668
669 TODO: This - add argument and description to function comment
670 TODO: Controller - add argument and description to function comment
671 TODO: NumberOfChildren - add argument and description to function comment
672 TODO: ChildHandleBuffer - add argument and description to function comment
673 TODO: EFI_SUCCESS - add return value to function comment
674**/
675EFI_STATUS
676EFIAPI
677VBoxVgaControllerDriverStop (
678 IN EFI_DRIVER_BINDING_PROTOCOL *This,
679 IN EFI_HANDLE Controller,
680 IN UINTN NumberOfChildren,
681 IN EFI_HANDLE *ChildHandleBuffer
682 )
683{
684 EFI_UGA_DRAW_PROTOCOL *UgaDraw;
685 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
686
687 EFI_STATUS Status;
688 VBOX_VGA_PRIVATE_DATA *Private;
689
690 if (FeaturePcdGet (PcdSupportUga)) {
691 Status = gBS->OpenProtocol (
692 Controller,
693 &gEfiUgaDrawProtocolGuid,
694 (VOID **) &UgaDraw,
695 This->DriverBindingHandle,
696 Controller,
697 EFI_OPEN_PROTOCOL_GET_PROTOCOL
698 );
699 if (EFI_ERROR (Status)) {
700 return Status;
701 }
702
703 //
704 // Get our private context information
705 //
706 Private = VBOX_VGA_PRIVATE_DATA_FROM_UGA_DRAW_THIS (UgaDraw);
707 VBoxVgaUgaDrawDestructor (Private);
708
709 if (FeaturePcdGet (PcdSupportGop)) {
710 VBoxVgaGraphicsOutputDestructor (Private);
711 //
712 // Remove the UGA and GOP protocol interface from the system
713 //
714 Status = gBS->UninstallMultipleProtocolInterfaces (
715 Private->Handle,
716 &gEfiUgaDrawProtocolGuid,
717 &Private->UgaDraw,
718 &gEfiGraphicsOutputProtocolGuid,
719 &Private->GraphicsOutput,
720 NULL
721 );
722 } else {
723 //
724 // Remove the UGA Draw interface from the system
725 //
726 Status = gBS->UninstallMultipleProtocolInterfaces (
727 Private->Handle,
728 &gEfiUgaDrawProtocolGuid,
729 &Private->UgaDraw,
730 NULL
731 );
732 }
733 } else {
734 Status = gBS->OpenProtocol (
735 Controller,
736 &gEfiGraphicsOutputProtocolGuid,
737 (VOID **) &GraphicsOutput,
738 This->DriverBindingHandle,
739 Controller,
740 EFI_OPEN_PROTOCOL_GET_PROTOCOL
741 );
742 if (EFI_ERROR (Status)) {
743 return Status;
744 }
745
746 //
747 // Get our private context information
748 //
749 Private = VBOX_VGA_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput);
750
751 VBoxVgaGraphicsOutputDestructor (Private);
752 //
753 // Remove the GOP protocol interface from the system
754 //
755 Status = gBS->UninstallMultipleProtocolInterfaces (
756 Private->Handle,
757 &gEfiGraphicsOutputProtocolGuid,
758 &Private->GraphicsOutput,
759 NULL
760 );
761 }
762
763 if (EFI_ERROR (Status)) {
764 return Status;
765 }
766
767 if (Private->ModeData) {
768 FreePool(Private->ModeData);
769 Private->ModeData = NULL;
770 }
771
772 //
773 // Restore original PCI attributes
774 //
775 Private->PciIo->Attributes (
776 Private->PciIo,
777 EfiPciIoAttributeOperationSet,
778 Private->OriginalPciAttributes,
779 NULL
780 );
781
782 //
783 // Close the PCI I/O Protocol
784 //
785 gBS->CloseProtocol (
786 Controller,
787 &gEfiPciIoProtocolGuid,
788 This->DriverBindingHandle,
789 Controller
790 );
791
792 //
793 // Free our instance data
794 //
795 gBS->FreePool (Private);
796
797 return EFI_SUCCESS;
798}
799
800/**
801 VBoxVgaUgaDrawDestructor
802
803 TODO: Private - add argument and description to function comment
804 TODO: EFI_SUCCESS - add return value to function comment
805**/
806EFI_STATUS
807VBoxVgaUgaDrawDestructor (
808 VBOX_VGA_PRIVATE_DATA *Private
809 )
810{
811 return EFI_SUCCESS;
812}
813
814/**
815 TODO: Add function description
816
817 @param Private TODO: add argument description
818 @param Index TODO: add argument description
819 @param Red TODO: add argument description
820 @param Green TODO: add argument description
821 @param Blue TODO: add argument description
822
823 TODO: add return values
824
825**/
826VOID
827SetPaletteColor (
828 VBOX_VGA_PRIVATE_DATA *Private,
829 UINTN Index,
830 UINT8 Red,
831 UINT8 Green,
832 UINT8 Blue
833 )
834{
835 ASMOutU8(PALETTE_INDEX_REGISTER, (UINT8) Index);
836 ASMOutU8(PALETTE_DATA_REGISTER, (UINT8) (Red >> 2));
837 ASMOutU8(PALETTE_DATA_REGISTER, (UINT8) (Green >> 2));
838 ASMOutU8(PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2));
839}
840
841/**
842 TODO: Add function description
843
844 @param Private TODO: add argument description
845
846 TODO: add return values
847
848**/
849VOID
850SetDefaultPalette (
851 VBOX_VGA_PRIVATE_DATA *Private
852 )
853{
854#if 1
855 UINTN Index;
856 UINTN RedIndex;
857 UINTN GreenIndex;
858 UINTN BlueIndex;
859 Index = 0;
860 for (RedIndex = 0; RedIndex < 8; RedIndex++) {
861 for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) {
862 for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) {
863 SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8) (GreenIndex << 5), (UINT8) (BlueIndex << 6));
864 Index++;
865 }
866 }
867 }
868#else
869 {
870 int i;
871 static const UINT8 s_a3bVgaDac[64*3] =
872 {
873 0x00, 0x00, 0x00,
874 0x00, 0x00, 0x2A,
875 0x00, 0x2A, 0x00,
876 0x00, 0x2A, 0x2A,
877 0x2A, 0x00, 0x00,
878 0x2A, 0x00, 0x2A,
879 0x2A, 0x2A, 0x00,
880 0x2A, 0x2A, 0x2A,
881 0x00, 0x00, 0x15,
882 0x00, 0x00, 0x3F,
883 0x00, 0x2A, 0x15,
884 0x00, 0x2A, 0x3F,
885 0x2A, 0x00, 0x15,
886 0x2A, 0x00, 0x3F,
887 0x2A, 0x2A, 0x15,
888 0x2A, 0x2A, 0x3F,
889 0x00, 0x15, 0x00,
890 0x00, 0x15, 0x2A,
891 0x00, 0x3F, 0x00,
892 0x00, 0x3F, 0x2A,
893 0x2A, 0x15, 0x00,
894 0x2A, 0x15, 0x2A,
895 0x2A, 0x3F, 0x00,
896 0x2A, 0x3F, 0x2A,
897 0x00, 0x15, 0x15,
898 0x00, 0x15, 0x3F,
899 0x00, 0x3F, 0x15,
900 0x00, 0x3F, 0x3F,
901 0x2A, 0x15, 0x15,
902 0x2A, 0x15, 0x3F,
903 0x2A, 0x3F, 0x15,
904 0x2A, 0x3F, 0x3F,
905 0x15, 0x00, 0x00,
906 0x15, 0x00, 0x2A,
907 0x15, 0x2A, 0x00,
908 0x15, 0x2A, 0x2A,
909 0x3F, 0x00, 0x00,
910 0x3F, 0x00, 0x2A,
911 0x3F, 0x2A, 0x00,
912 0x3F, 0x2A, 0x2A,
913 0x15, 0x00, 0x15,
914 0x15, 0x00, 0x3F,
915 0x15, 0x2A, 0x15,
916 0x15, 0x2A, 0x3F,
917 0x3F, 0x00, 0x15,
918 0x3F, 0x00, 0x3F,
919 0x3F, 0x2A, 0x15,
920 0x3F, 0x2A, 0x3F,
921 0x15, 0x15, 0x00,
922 0x15, 0x15, 0x2A,
923 0x15, 0x3F, 0x00,
924 0x15, 0x3F, 0x2A,
925 0x3F, 0x15, 0x00,
926 0x3F, 0x15, 0x2A,
927 0x3F, 0x3F, 0x00,
928 0x3F, 0x3F, 0x2A,
929 0x15, 0x15, 0x15,
930 0x15, 0x15, 0x3F,
931 0x15, 0x3F, 0x15,
932 0x15, 0x3F, 0x3F,
933 0x3F, 0x15, 0x15,
934 0x3F, 0x15, 0x3F,
935 0x3F, 0x3F, 0x15,
936 0x3F, 0x3F, 0x3F
937 };
938
939 for (i = 0; i < 64; ++i)
940 {
941 ASMOutU8(PALETTE_INDEX_REGISTER, (UINT8)i);
942 ASMOutU8(PALETTE_DATA_REGISTER, s_a3bVgaDac[i*3 + 0]);
943 ASMOutU8(PALETTE_DATA_REGISTER, s_a3bVgaDac[i*3 + 1]);
944 ASMOutU8(PALETTE_DATA_REGISTER, s_a3bVgaDac[i*3 + 2]);
945 }
946 }
947
948#endif
949}
950
951/**
952 TODO: Add function description
953
954 @param Private TODO: add argument description
955
956 TODO: add return values
957
958**/
959VOID
960ClearScreen (
961 VBOX_VGA_PRIVATE_DATA *Private
962 )
963{
964 EFI_GRAPHICS_OUTPUT_BLT_PIXEL blt;
965 blt.Blue = 0;
966 blt.Green = 0;
967 blt.Red = 0;
968 blt.Reserved = 0;
969 Private->PciIo->Mem.Write (
970 Private->PciIo,
971 EfiPciIoWidthFillUint32,
972 Private->BarIndexFB,
973 0,
974 Private->ModeData[Private->CurrentMode].HorizontalResolution
975 * Private->ModeData[Private->CurrentMode].VerticalResolution,
976 &blt
977 );
978}
979
980/**
981 TODO: Add function description
982
983 @param Private TODO: add argument description
984
985 TODO: add return values
986
987**/
988VOID
989DrawLogo (
990 VBOX_VGA_PRIVATE_DATA *Private,
991 UINTN ScreenWidth,
992 UINTN ScreenHeight
993 )
994{
995 DEBUG((DEBUG_INFO, "UGA is %a GOP is %a\n",
996 FeaturePcdGet(PcdSupportUga) ? "on" : "off",
997 FeaturePcdGet(PcdSupportGop) ? "on" : "off"
998 ));
999}
1000
1001/**
1002 TODO: Add function description
1003
1004 @param Private TODO: add argument description
1005 @param ModeData TODO: add argument description
1006
1007 TODO: add return values
1008
1009**/
1010VOID
1011InitializeGraphicsMode (
1012 VBOX_VGA_PRIVATE_DATA *Private,
1013 VBOX_VGA_VIDEO_MODES *ModeData
1014 )
1015{
1016 UINT16 DeviceId;
1017 EFI_STATUS Status;
1018 int i;
1019
1020 DEBUG((DEBUG_INFO, "%a:%d InitializeGraphicsMode: %dx%d bpp:%d\n", __FILE__, __LINE__, ModeData->Width, ModeData->Height, ModeData->ColorDepth));
1021
1022 //
1023 // Read the PCI ID from the PCI Device (dummy)
1024 //
1025 Status = Private->PciIo->Pci.Read (
1026 Private->PciIo,
1027 EfiPciIoWidthUint16,
1028 PCI_DEVICE_ID_OFFSET,
1029 1,
1030 &DeviceId
1031 );
1032 ASSERT_EFI_ERROR(Status);
1033
1034 ASMOutU8(MISC_OUTPUT_REGISTER, 0xc3);
1035 ASMOutU16(SEQ_ADDRESS_REGISTER, 0x0204);
1036
1037 ASMInU8(INPUT_STATUS_1_REGISTER); // reset attribute address/data flip-flop
1038 ASMOutU8(ATT_ADDRESS_REGISTER, 0); // blank screen using the attribute address register
1039
1040 ASMOutU16(CRTC_ADDRESS_REGISTER, 0x0011);
1041
1042 ASMOutU16(SEQ_ADDRESS_REGISTER, 0x0100);
1043 if (ModeData->SeqSettings)
1044 BOUTB(ModeData->SeqSettings, 5, SEQ_ADDRESS_REGISTER, SEQ_DATA_REGISTER);
1045 else
1046 BOUTB(Seq_Default, 5, SEQ_ADDRESS_REGISTER, SEQ_DATA_REGISTER);
1047 ASMOutU16(SEQ_ADDRESS_REGISTER, 0x0300);
1048
1049 BOUTB(GraphicsController, 9, GRAPH_ADDRESS_REGISTER, GRAPH_DATA_REGISTER);
1050
1051 ASMInU8(INPUT_STATUS_1_REGISTER); // reset attribute address/data flip-flop
1052 BOUTB(AttributeController, 21, ATT_ADDRESS_REGISTER, ATT_DATA_REGISTER);
1053
1054 ASMOutU8(MISC_OUTPUT_REGISTER, ModeData->MiscSetting);
1055
1056 if (ModeData->ColorDepth <= 8)
1057 {
1058 ASMOutU8(DAC_PIXEL_MASK_REGISTER, 0xff);
1059 SetDefaultPalette(Private);
1060 }
1061
1062 if (!ModeData->CrtcSettings)
1063 {
1064 // No CRTC settings, use VBE
1065 ASMOutU16(VBE_DISPI_IOPORT_INDEX, 0x00); ASMOutU16(VBE_DISPI_IOPORT_DATA, 0xb0c0); // ID
1066 ASMOutU16(VBE_DISPI_IOPORT_INDEX, 0x04); ASMOutU16(VBE_DISPI_IOPORT_DATA, 0); // ENABLE
1067 ASMOutU16(VBE_DISPI_IOPORT_INDEX, 0x01); ASMOutU16(VBE_DISPI_IOPORT_DATA, (UINT16)ModeData->Width); // XRES
1068 ASMOutU16(VBE_DISPI_IOPORT_INDEX, 0x02); ASMOutU16(VBE_DISPI_IOPORT_DATA, (UINT16)ModeData->Height); // YRES
1069 ASMOutU16(VBE_DISPI_IOPORT_INDEX, 0x03); ASMOutU16(VBE_DISPI_IOPORT_DATA, (UINT16)ModeData->ColorDepth); // BPP
1070 ASMOutU16(VBE_DISPI_IOPORT_INDEX, 0x05); ASMOutU16(VBE_DISPI_IOPORT_DATA, 0); // BANK
1071 ASMOutU16(VBE_DISPI_IOPORT_INDEX, 0x06); ASMOutU16(VBE_DISPI_IOPORT_DATA, (UINT16)ModeData->Width); // VIRT_WIDTH
1072 ASMOutU16(VBE_DISPI_IOPORT_INDEX, 0x07); ASMOutU16(VBE_DISPI_IOPORT_DATA, (UINT16)ModeData->Height); // VIRT_HEIGHT
1073 ASMOutU16(VBE_DISPI_IOPORT_INDEX, 0x08); ASMOutU16(VBE_DISPI_IOPORT_DATA, 0); // X_OFFSET
1074 ASMOutU16(VBE_DISPI_IOPORT_INDEX, 0x09); ASMOutU16(VBE_DISPI_IOPORT_DATA, 0); // Y_OFFSET
1075 ASMOutU16(VBE_DISPI_IOPORT_INDEX, 0x04); ASMOutU16(VBE_DISPI_IOPORT_DATA, 1); // ENABLE
1076 /// @todo enabling VBE is automatically tweaking the CRTC, GC, SC, clears the
1077 // screen and at the end unblanks graphics. So make sure that nothing is done
1078 // after this which needs blanking. Way too much magic, but that's how it is...
1079 }
1080 else
1081 {
1082 BOUTB(ModeData->CrtcSettings, 25, CRTC_ADDRESS_REGISTER, CRTC_DATA_REGISTER);
1083 }
1084
1085 ASMInU8(INPUT_STATUS_1_REGISTER); // reset attribute address/data flip-flop
1086 ASMOutU8(ATT_ADDRESS_REGISTER, 0x20); // unblank screen
1087
1088 ClearScreen(Private);
1089}
1090
1091/** Aka know as AppleGraphInfoProtocolGuid in other sources. */
1092#define EFI_UNKNOWN_2_PROTOCOL_GUID \
1093 { 0xE316E100, 0x0751, 0x4C49, {0x90, 0x56, 0x48, 0x6C, 0x7E, 0x47, 0x29, 0x03} }
1094
1095EFI_GUID gEfiAppleFrameBufferInfoGuid = EFI_UNKNOWN_2_PROTOCOL_GUID;
1096
1097EFI_STATUS EFIAPI
1098GetFrameBufferInfo(IN APPLE_FRAMEBUFFERINFO_PROTOCOL *This,
1099 OUT UINT32 *BaseAddr,
1100 OUT UINT32 *Something,
1101 OUT UINT32 *RowBytes,
1102 OUT UINT32 *Width,
1103 OUT UINT32 *Height,
1104 OUT UINT32 *Depth)
1105{
1106 EFI_ACPI_ADDRESS_SPACE_DESCRIPTOR *FrameBufDesc;
1107 UINT32 W, H, BPP;
1108 VBOX_VGA_PRIVATE_DATA *Private = This->Private;
1109 UINTN CurrentModeNumber = Private->CurrentMode;
1110 VBOX_VGA_MODE_DATA const *pCurrentMode = &Private->ModeData[CurrentModeNumber];
1111
1112 W = pCurrentMode->HorizontalResolution;
1113 H = pCurrentMode->VerticalResolution;
1114 BPP = pCurrentMode->ColorDepth;
1115 DEBUG((DEBUG_INFO, "%a:%d GetFrameBufferInfo: %dx%d bpp:%d\n", __FILE__, __LINE__, W, H, BPP));
1116
1117 Private->PciIo->GetBarAttributes (
1118 Private->PciIo,
1119 Private->BarIndexFB,
1120 NULL,
1121 (VOID**) &FrameBufDesc
1122 );
1123
1124
1125 /* EFI firmware remaps it here */
1126 *BaseAddr = (UINT32)FrameBufDesc->AddrRangeMin;
1127 *RowBytes = W * BPP / 8;
1128 *Width = W;
1129 *Height = H;
1130 *Depth = BPP;
1131 // what *Something shall be?
1132
1133 return EFI_SUCCESS;
1134}
1135
1136EFI_STATUS
1137EFIAPI
1138InitializeVBoxVga (
1139 IN EFI_HANDLE ImageHandle,
1140 IN EFI_SYSTEM_TABLE *SystemTable
1141 )
1142{
1143 EFI_STATUS Status;
1144
1145 Status = EfiLibInstallDriverBindingComponentName2 (
1146 ImageHandle,
1147 SystemTable,
1148 &gVBoxVgaDriverBinding,
1149 ImageHandle,
1150 &gVBoxVgaComponentName,
1151 &gVBoxVgaComponentName2
1152 );
1153 ASSERT_EFI_ERROR (Status);
1154
1155 //
1156 // Install EFI Driver Supported EFI Version Protocol required for
1157 // EFI drivers that are on PCI and other plug in cards.
1158 //
1159 gVBoxVgaDriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion);
1160 Status = gBS->InstallMultipleProtocolInterfaces (
1161 &ImageHandle,
1162 &gEfiDriverSupportedEfiVersionProtocolGuid,
1163 &gVBoxVgaDriverSupportedEfiVersion,
1164 &gEfiAppleFrameBufferInfoGuid,
1165 &gAppleFrameBufferInfo,
1166 NULL
1167 );
1168 ASSERT_EFI_ERROR (Status);
1169
1170 return Status;
1171}
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