VirtualBox

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

Last change on this file since 61103 was 58836, checked in by vboxsync, 9 years ago

EFI/Firmware: Move some VBox specific modifications for changing the video resolution to VBoxVgaDxe. Avoids flickering as the previous code was changing the resolution back and forth multiple times

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