VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/Firmware2/VBoxPkg/VBoxVgaDxe/VBoxVga.c@ 29081

Last change on this file since 29081 was 29081, checked in by vboxsync, 15 years ago

more EFI exports to OSE

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