1 /** @file 2 Cirrus Logic 5430 Controller Driver. 3 This driver is a sample implementation of the UGA Draw and Graphics Output 4 Protocols for the Cirrus Logic 5430 family of PCI video controllers. 5 This driver is only usable in the EFI pre-boot environment. 6 This sample is intended to show how the UGA Draw and Graphics output Protocol 7 is able to function. 8 The UGA I/O Protocol is not implemented in this sample. 9 A fully compliant EFI UGA driver requires both 10 the UGA Draw and the UGA I/O Protocol. Please refer to Microsoft's 11 documentation on UGA for details on how to write a UGA driver that is able 12 to function both in the EFI pre-boot environment and from the OS runtime. 13 14 Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.<BR> 15 This program and the accompanying materials 16 are licensed and made available under the terms and conditions of the BSD License 17 which accompanies this distribution. The full text of the license may be found at 18 http://opensource.org/licenses/bsd-license.php 19 20 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, 21 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. 22 23 **/ 24 25 // 26 // Cirrus Logic 5430 Controller Driver 27 // 28 #include "CirrusLogic5430.h" 29 30 EFI_DRIVER_BINDING_PROTOCOL gCirrusLogic5430DriverBinding = { 31 CirrusLogic5430ControllerDriverSupported, 32 CirrusLogic5430ControllerDriverStart, 33 CirrusLogic5430ControllerDriverStop, 34 0x10, 35 NULL, 36 NULL 37 }; 38 39 /// 40 /// Generic Attribute Controller Register Settings 41 /// 42 UINT8 AttributeController[21] = { 43 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 44 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F, 45 0x41, 0x00, 0x0F, 0x00, 0x00 46 }; 47 48 /// 49 /// Generic Graphics Controller Register Settings 50 /// 51 UINT8 GraphicsController[9] = { 52 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x05, 0x0F, 0xFF 53 }; 54 55 // 56 // 640 x 480 x 256 color @ 60 Hertz 57 // 58 UINT8 Crtc_640_480_256_60[28] = { 59 0x5d, 0x4f, 0x50, 0x82, 0x53, 0x9f, 0x00, 0x3e, 60 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 61 0xe1, 0x83, 0xdf, 0x50, 0x00, 0xe7, 0x04, 0xe3, 62 0xff, 0x00, 0x00, 0x22 63 }; 64 65 UINT16 Seq_640_480_256_60[15] = { 66 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, 67 0x5b0c, 0x450d, 0x7e0e, 0x2b1b, 0x2f1c, 0x301d, 0x331e 68 }; 69 70 // 71 // 800 x 600 x 256 color @ 60 Hertz 72 // 73 UINT8 Crtc_800_600_256_60[28] = { 74 0x7F, 0x63, 0x64, 0x80, 0x6B, 0x1B, 0x72, 0xF0, 75 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 76 0x58, 0x8C, 0x57, 0x64, 0x00, 0x5F, 0x91, 0xE3, 77 0xFF, 0x00, 0x00, 0x22 78 }; 79 80 UINT16 Seq_800_600_256_60[15] = { 81 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, 82 0x5b0c, 0x450d, 0x510e, 0x2b1b, 0x2f1c, 0x301d, 0x3a1e 83 }; 84 85 // 86 // 1024 x 768 x 256 color @ 60 Hertz 87 // 88 UINT8 Crtc_1024_768_256_60[28] = { 89 0xA3, 0x7F, 0x80, 0x86, 0x85, 0x96, 0x24, 0xFD, 90 0x00, 0x60, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 91 0x02, 0x88, 0xFF, 0x80, 0x00, 0x00, 0x24, 0xE3, 92 0xFF, 0x4A, 0x00, 0x22 93 }; 94 95 UINT16 Seq_1024_768_256_60[15] = { 96 0x0100, 0x0101, 0x0f02, 0x0003, 0x0e04, 0x1107, 0x0008, 0x4a0b, 97 0x5b0c, 0x450d, 0x760e, 0x2b1b, 0x2f1c, 0x301d, 0x341e 98 }; 99 100 /// 101 /// Table of supported video modes 102 /// 103 CIRRUS_LOGIC_5430_VIDEO_MODES CirrusLogic5430VideoModes[] = { 104 { 640, 480, 8, 60, Crtc_640_480_256_60, Seq_640_480_256_60, 0xe3 }, 105 { 800, 600, 8, 60, Crtc_800_600_256_60, Seq_800_600_256_60, 0xef }, 106 { 1024, 768, 8, 60, Crtc_1024_768_256_60, Seq_1024_768_256_60, 0xef } 107 }; 108 109 110 /** 111 CirrusLogic5430ControllerDriverSupported 112 113 TODO: This - add argument and description to function comment 114 TODO: Controller - add argument and description to function comment 115 TODO: RemainingDevicePath - add argument and description to function comment 116 **/ 117 EFI_STATUS 118 EFIAPI 119 CirrusLogic5430ControllerDriverSupported ( 120 IN EFI_DRIVER_BINDING_PROTOCOL *This, 121 IN EFI_HANDLE Controller, 122 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath 123 ) 124 { 125 EFI_STATUS Status; 126 EFI_PCI_IO_PROTOCOL *PciIo; 127 PCI_TYPE00 Pci; 128 EFI_DEV_PATH *Node; 129 130 // 131 // Open the PCI I/O Protocol 132 // 133 Status = gBS->OpenProtocol ( 134 Controller, 135 &gEfiPciIoProtocolGuid, 136 (VOID **) &PciIo, 137 This->DriverBindingHandle, 138 Controller, 139 EFI_OPEN_PROTOCOL_BY_DRIVER 140 ); 141 if (EFI_ERROR (Status)) { 142 return Status; 143 } 144 145 // 146 // Read the PCI Configuration Header from the PCI Device 147 // 148 Status = PciIo->Pci.Read ( 149 PciIo, 150 EfiPciIoWidthUint32, 151 0, 152 sizeof (Pci) / sizeof (UINT32), 153 &Pci 154 ); 155 if (EFI_ERROR (Status)) { 156 goto Done; 157 } 158 159 Status = EFI_UNSUPPORTED; 160 // 161 // See if the I/O enable is on. Most systems only allow one VGA device to be turned on 162 // at a time, so see if this is one that is turned on. 163 // 164 // if (((Pci.Hdr.Command & 0x01) == 0x01)) { 165 // 166 // See if this is a Cirrus Logic PCI controller 167 // 168 if (Pci.Hdr.VendorId == CIRRUS_LOGIC_VENDOR_ID) { 169 // 170 // See if this is a 5430 or a 5446 PCI controller 171 // 172 if (Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_DEVICE_ID || 173 Pci.Hdr.DeviceId == CIRRUS_LOGIC_5430_ALTERNATE_DEVICE_ID || 174 Pci.Hdr.DeviceId == CIRRUS_LOGIC_5446_DEVICE_ID) { 175 176 Status = EFI_SUCCESS; 177 // 178 // If this is an Intel 945 graphics controller, 179 // go further check RemainingDevicePath validation 180 // 181 if (RemainingDevicePath != NULL) { 182 Node = (EFI_DEV_PATH *) RemainingDevicePath; 183 // 184 // Check if RemainingDevicePath is the End of Device Path Node, 185 // if yes, return EFI_SUCCESS 186 // 187 if (!IsDevicePathEnd (Node)) { 188 // 189 // If RemainingDevicePath isn't the End of Device Path Node, 190 // check its validation 191 // 192 if (Node->DevPath.Type != ACPI_DEVICE_PATH || 193 Node->DevPath.SubType != ACPI_ADR_DP || 194 DevicePathNodeLength(&Node->DevPath) != sizeof(ACPI_ADR_DEVICE_PATH)) { 195 Status = EFI_UNSUPPORTED; 196 } 197 } 198 } 199 } 200 } 201 202 Done: 203 // 204 // Close the PCI I/O Protocol 205 // 206 gBS->CloseProtocol ( 207 Controller, 208 &gEfiPciIoProtocolGuid, 209 This->DriverBindingHandle, 210 Controller 211 ); 212 213 return Status; 214 } 215 216 /** 217 CirrusLogic5430ControllerDriverStart 218 219 TODO: This - add argument and description to function comment 220 TODO: Controller - add argument and description to function comment 221 TODO: RemainingDevicePath - add argument and description to function comment 222 **/ 223 EFI_STATUS 224 EFIAPI 225 CirrusLogic5430ControllerDriverStart ( 226 IN EFI_DRIVER_BINDING_PROTOCOL *This, 227 IN EFI_HANDLE Controller, 228 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath 229 ) 230 { 231 EFI_STATUS Status; 232 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private; 233 BOOLEAN PciAttributesSaved; 234 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath; 235 ACPI_ADR_DEVICE_PATH AcpiDeviceNode; 236 UINT64 Supports; 237 238 PciAttributesSaved = FALSE; 239 // 240 // Allocate Private context data for UGA Draw inteface. 241 // 242 Private = AllocateZeroPool (sizeof (CIRRUS_LOGIC_5430_PRIVATE_DATA)); 243 if (Private == NULL) { 244 Status = EFI_OUT_OF_RESOURCES; 245 goto Error; 246 } 247 248 // 249 // Set up context record 250 // 251 Private->Signature = CIRRUS_LOGIC_5430_PRIVATE_DATA_SIGNATURE; 252 Private->Handle = NULL; 253 254 // 255 // Open PCI I/O Protocol 256 // 257 Status = gBS->OpenProtocol ( 258 Controller, 259 &gEfiPciIoProtocolGuid, 260 (VOID **) &Private->PciIo, 261 This->DriverBindingHandle, 262 Controller, 263 EFI_OPEN_PROTOCOL_BY_DRIVER 264 ); 265 if (EFI_ERROR (Status)) { 266 goto Error; 267 } 268 269 // 270 // Get supported PCI attributes 271 // 272 Status = Private->PciIo->Attributes ( 273 Private->PciIo, 274 EfiPciIoAttributeOperationSupported, 275 0, 276 &Supports 277 ); 278 if (EFI_ERROR (Status)) { 279 goto Error; 280 } 281 282 Supports &= (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16); 283 if (Supports == 0 || Supports == (EFI_PCI_IO_ATTRIBUTE_VGA_IO | EFI_PCI_IO_ATTRIBUTE_VGA_IO_16)) { 284 Status = EFI_UNSUPPORTED; 285 goto Error; 286 } 287 288 // 289 // Save original PCI attributes 290 // 291 Status = Private->PciIo->Attributes ( 292 Private->PciIo, 293 EfiPciIoAttributeOperationGet, 294 0, 295 &Private->OriginalPciAttributes 296 ); 297 298 if (EFI_ERROR (Status)) { 299 goto Error; 300 } 301 PciAttributesSaved = TRUE; 302 303 Status = Private->PciIo->Attributes ( 304 Private->PciIo, 305 EfiPciIoAttributeOperationEnable, 306 EFI_PCI_DEVICE_ENABLE | EFI_PCI_IO_ATTRIBUTE_VGA_MEMORY | Supports, 307 NULL 308 ); 309 if (EFI_ERROR (Status)) { 310 goto Error; 311 } 312 313 // 314 // Get ParentDevicePath 315 // 316 Status = gBS->HandleProtocol ( 317 Controller, 318 &gEfiDevicePathProtocolGuid, 319 (VOID **) &ParentDevicePath 320 ); 321 if (EFI_ERROR (Status)) { 322 goto Error; 323 } 324 325 if (FeaturePcdGet (PcdSupportGop)) { 326 // 327 // Set Gop Device Path 328 // 329 if (RemainingDevicePath == NULL) { 330 ZeroMem (&AcpiDeviceNode, sizeof (ACPI_ADR_DEVICE_PATH)); 331 AcpiDeviceNode.Header.Type = ACPI_DEVICE_PATH; 332 AcpiDeviceNode.Header.SubType = ACPI_ADR_DP; 333 AcpiDeviceNode.ADR = ACPI_DISPLAY_ADR (1, 0, 0, 1, 0, ACPI_ADR_DISPLAY_TYPE_VGA, 0, 0); 334 SetDevicePathNodeLength (&AcpiDeviceNode.Header, sizeof (ACPI_ADR_DEVICE_PATH)); 335 336 Private->GopDevicePath = AppendDevicePathNode ( 337 ParentDevicePath, 338 (EFI_DEVICE_PATH_PROTOCOL *) &AcpiDeviceNode 339 ); 340 } else if (!IsDevicePathEnd (RemainingDevicePath)) { 341 // 342 // If RemainingDevicePath isn't the End of Device Path Node, 343 // only scan the specified device by RemainingDevicePath 344 // 345 Private->GopDevicePath = AppendDevicePathNode (ParentDevicePath, RemainingDevicePath); 346 } else { 347 // 348 // If RemainingDevicePath is the End of Device Path Node, 349 // don't create child device and return EFI_SUCCESS 350 // 351 Private->GopDevicePath = NULL; 352 } 353 354 if (Private->GopDevicePath != NULL) { 355 // 356 // Creat child handle and device path protocol firstly 357 // 358 Private->Handle = NULL; 359 Status = gBS->InstallMultipleProtocolInterfaces ( 360 &Private->Handle, 361 &gEfiDevicePathProtocolGuid, 362 Private->GopDevicePath, 363 NULL 364 ); 365 } 366 } 367 368 // 369 // Construct video mode buffer 370 // 371 Status = CirrusLogic5430VideoModeSetup (Private); 372 if (EFI_ERROR (Status)) { 373 goto Error; 374 } 375 376 if (FeaturePcdGet (PcdSupportUga)) { 377 // 378 // Start the UGA Draw software stack. 379 // 380 Status = CirrusLogic5430UgaDrawConstructor (Private); 381 ASSERT_EFI_ERROR (Status); 382 383 Private->UgaDevicePath = ParentDevicePath; 384 Status = gBS->InstallMultipleProtocolInterfaces ( 385 &Controller, 386 &gEfiUgaDrawProtocolGuid, 387 &Private->UgaDraw, 388 &gEfiDevicePathProtocolGuid, 389 Private->UgaDevicePath, 390 NULL 391 ); 392 393 } else if (FeaturePcdGet (PcdSupportGop)) { 394 if (Private->GopDevicePath == NULL) { 395 // 396 // If RemainingDevicePath is the End of Device Path Node, 397 // don't create child device and return EFI_SUCCESS 398 // 399 Status = EFI_SUCCESS; 400 } else { 401 402 // 403 // Start the GOP software stack. 404 // 405 Status = CirrusLogic5430GraphicsOutputConstructor (Private); 406 ASSERT_EFI_ERROR (Status); 407 408 Status = gBS->InstallMultipleProtocolInterfaces ( 409 &Private->Handle, 410 &gEfiGraphicsOutputProtocolGuid, 411 &Private->GraphicsOutput, 412 &gEfiEdidDiscoveredProtocolGuid, 413 &Private->EdidDiscovered, 414 &gEfiEdidActiveProtocolGuid, 415 &Private->EdidActive, 416 NULL 417 ); 418 } 419 } else { 420 // 421 // This driver must support eithor GOP or UGA or both. 422 // 423 ASSERT (FALSE); 424 Status = EFI_UNSUPPORTED; 425 } 426 427 428 Error: 429 if (EFI_ERROR (Status)) { 430 if (Private) { 431 if (Private->PciIo) { 432 if (PciAttributesSaved == TRUE) { 433 // 434 // Restore original PCI attributes 435 // 436 Private->PciIo->Attributes ( 437 Private->PciIo, 438 EfiPciIoAttributeOperationSet, 439 Private->OriginalPciAttributes, 440 NULL 441 ); 442 } 443 // 444 // Close the PCI I/O Protocol 445 // 446 gBS->CloseProtocol ( 447 Private->Handle, 448 &gEfiPciIoProtocolGuid, 449 This->DriverBindingHandle, 450 Private->Handle 451 ); 452 } 453 454 gBS->FreePool (Private); 455 } 456 } 457 458 return Status; 459 } 460 461 /** 462 CirrusLogic5430ControllerDriverStop 463 464 TODO: This - add argument and description to function comment 465 TODO: Controller - add argument and description to function comment 466 TODO: NumberOfChildren - add argument and description to function comment 467 TODO: ChildHandleBuffer - add argument and description to function comment 468 TODO: EFI_SUCCESS - add return value to function comment 469 **/ 470 EFI_STATUS 471 EFIAPI 472 CirrusLogic5430ControllerDriverStop ( 473 IN EFI_DRIVER_BINDING_PROTOCOL *This, 474 IN EFI_HANDLE Controller, 475 IN UINTN NumberOfChildren, 476 IN EFI_HANDLE *ChildHandleBuffer 477 ) 478 { 479 EFI_UGA_DRAW_PROTOCOL *UgaDraw; 480 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; 481 482 EFI_STATUS Status; 483 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private; 484 485 if (FeaturePcdGet (PcdSupportUga)) { 486 Status = gBS->OpenProtocol ( 487 Controller, 488 &gEfiUgaDrawProtocolGuid, 489 (VOID **) &UgaDraw, 490 This->DriverBindingHandle, 491 Controller, 492 EFI_OPEN_PROTOCOL_GET_PROTOCOL 493 ); 494 if (EFI_ERROR (Status)) { 495 return Status; 496 } 497 // 498 // Get our private context information 499 // 500 Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_UGA_DRAW_THIS (UgaDraw); 501 CirrusLogic5430UgaDrawDestructor (Private); 502 503 if (FeaturePcdGet (PcdSupportGop)) { 504 CirrusLogic5430GraphicsOutputDestructor (Private); 505 // 506 // Remove the UGA and GOP protocol interface from the system 507 // 508 Status = gBS->UninstallMultipleProtocolInterfaces ( 509 Private->Handle, 510 &gEfiUgaDrawProtocolGuid, 511 &Private->UgaDraw, 512 &gEfiGraphicsOutputProtocolGuid, 513 &Private->GraphicsOutput, 514 NULL 515 ); 516 } else { 517 // 518 // Remove the UGA Draw interface from the system 519 // 520 Status = gBS->UninstallMultipleProtocolInterfaces ( 521 Private->Handle, 522 &gEfiUgaDrawProtocolGuid, 523 &Private->UgaDraw, 524 NULL 525 ); 526 } 527 } else { 528 Status = gBS->OpenProtocol ( 529 Controller, 530 &gEfiGraphicsOutputProtocolGuid, 531 (VOID **) &GraphicsOutput, 532 This->DriverBindingHandle, 533 Controller, 534 EFI_OPEN_PROTOCOL_GET_PROTOCOL 535 ); 536 if (EFI_ERROR (Status)) { 537 return Status; 538 } 539 540 // 541 // Get our private context information 542 // 543 Private = CIRRUS_LOGIC_5430_PRIVATE_DATA_FROM_GRAPHICS_OUTPUT_THIS (GraphicsOutput); 544 545 CirrusLogic5430GraphicsOutputDestructor (Private); 546 // 547 // Remove the GOP protocol interface from the system 548 // 549 Status = gBS->UninstallMultipleProtocolInterfaces ( 550 Private->Handle, 551 &gEfiUgaDrawProtocolGuid, 552 &Private->UgaDraw, 553 &gEfiGraphicsOutputProtocolGuid, 554 &Private->GraphicsOutput, 555 NULL 556 ); 557 } 558 559 if (EFI_ERROR (Status)) { 560 return Status; 561 } 562 563 // 564 // Restore original PCI attributes 565 // 566 Private->PciIo->Attributes ( 567 Private->PciIo, 568 EfiPciIoAttributeOperationSet, 569 Private->OriginalPciAttributes, 570 NULL 571 ); 572 573 // 574 // Close the PCI I/O Protocol 575 // 576 gBS->CloseProtocol ( 577 Controller, 578 &gEfiPciIoProtocolGuid, 579 This->DriverBindingHandle, 580 Controller 581 ); 582 583 // 584 // Free our instance data 585 // 586 gBS->FreePool (Private); 587 588 return EFI_SUCCESS; 589 } 590 591 /** 592 CirrusLogic5430UgaDrawDestructor 593 594 TODO: Private - add argument and description to function comment 595 TODO: EFI_SUCCESS - add return value to function comment 596 **/ 597 EFI_STATUS 598 CirrusLogic5430UgaDrawDestructor ( 599 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private 600 ) 601 { 602 return EFI_SUCCESS; 603 } 604 605 /** 606 TODO: Add function description 607 608 @param Private TODO: add argument description 609 @param Address TODO: add argument description 610 @param Data TODO: add argument description 611 612 TODO: add return values 613 614 **/ 615 VOID 616 outb ( 617 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, 618 UINTN Address, 619 UINT8 Data 620 ) 621 { 622 Private->PciIo->Io.Write ( 623 Private->PciIo, 624 EfiPciIoWidthUint8, 625 EFI_PCI_IO_PASS_THROUGH_BAR, 626 Address, 627 1, 628 &Data 629 ); 630 } 631 632 /** 633 TODO: Add function description 634 635 @param Private TODO: add argument description 636 @param Address TODO: add argument description 637 @param Data TODO: add argument description 638 639 TODO: add return values 640 641 **/ 642 VOID 643 outw ( 644 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, 645 UINTN Address, 646 UINT16 Data 647 ) 648 { 649 Private->PciIo->Io.Write ( 650 Private->PciIo, 651 EfiPciIoWidthUint16, 652 EFI_PCI_IO_PASS_THROUGH_BAR, 653 Address, 654 1, 655 &Data 656 ); 657 } 658 659 /** 660 TODO: Add function description 661 662 @param Private TODO: add argument description 663 @param Address TODO: add argument description 664 665 TODO: add return values 666 667 **/ 668 UINT8 669 inb ( 670 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, 671 UINTN Address 672 ) 673 { 674 UINT8 Data; 675 676 Private->PciIo->Io.Read ( 677 Private->PciIo, 678 EfiPciIoWidthUint8, 679 EFI_PCI_IO_PASS_THROUGH_BAR, 680 Address, 681 1, 682 &Data 683 ); 684 return Data; 685 } 686 687 /** 688 TODO: Add function description 689 690 @param Private TODO: add argument description 691 @param Address TODO: add argument description 692 693 TODO: add return values 694 695 **/ 696 UINT16 697 inw ( 698 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, 699 UINTN Address 700 ) 701 { 702 UINT16 Data; 703 704 Private->PciIo->Io.Read ( 705 Private->PciIo, 706 EfiPciIoWidthUint16, 707 EFI_PCI_IO_PASS_THROUGH_BAR, 708 Address, 709 1, 710 &Data 711 ); 712 return Data; 713 } 714 715 /** 716 TODO: Add function description 717 718 @param Private TODO: add argument description 719 @param Index TODO: add argument description 720 @param Red TODO: add argument description 721 @param Green TODO: add argument description 722 @param Blue TODO: add argument description 723 724 TODO: add return values 725 726 **/ 727 VOID 728 SetPaletteColor ( 729 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, 730 UINTN Index, 731 UINT8 Red, 732 UINT8 Green, 733 UINT8 Blue 734 ) 735 { 736 outb (Private, PALETTE_INDEX_REGISTER, (UINT8) Index); 737 outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Red >> 2)); 738 outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Green >> 2)); 739 outb (Private, PALETTE_DATA_REGISTER, (UINT8) (Blue >> 2)); 740 } 741 742 /** 743 TODO: Add function description 744 745 @param Private TODO: add argument description 746 747 TODO: add return values 748 749 **/ 750 VOID 751 SetDefaultPalette ( 752 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private 753 ) 754 { 755 UINTN Index; 756 UINTN RedIndex; 757 UINTN GreenIndex; 758 UINTN BlueIndex; 759 760 Index = 0; 761 for (RedIndex = 0; RedIndex < 8; RedIndex++) { 762 for (GreenIndex = 0; GreenIndex < 8; GreenIndex++) { 763 for (BlueIndex = 0; BlueIndex < 4; BlueIndex++) { 764 SetPaletteColor (Private, Index, (UINT8) (RedIndex << 5), (UINT8) (GreenIndex << 5), (UINT8) (BlueIndex << 6)); 765 Index++; 766 } 767 } 768 } 769 } 770 771 /** 772 TODO: Add function description 773 774 @param Private TODO: add argument description 775 776 TODO: add return values 777 778 **/ 779 VOID 780 ClearScreen ( 781 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private 782 ) 783 { 784 UINT32 Color; 785 786 Color = 0; 787 Private->PciIo->Mem.Write ( 788 Private->PciIo, 789 EfiPciIoWidthFillUint32, 790 0, 791 0, 792 0x100000 >> 2, 793 &Color 794 ); 795 } 796 797 /** 798 TODO: Add function description 799 800 @param Private TODO: add argument description 801 802 TODO: add return values 803 804 **/ 805 VOID 806 DrawLogo ( 807 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, 808 UINTN ScreenWidth, 809 UINTN ScreenHeight 810 ) 811 { 812 } 813 814 /** 815 TODO: Add function description 816 817 @param Private TODO: add argument description 818 @param ModeData TODO: add argument description 819 820 TODO: add return values 821 822 **/ 823 VOID 824 InitializeGraphicsMode ( 825 CIRRUS_LOGIC_5430_PRIVATE_DATA *Private, 826 CIRRUS_LOGIC_5430_VIDEO_MODES *ModeData 827 ) 828 { 829 UINT8 Byte; 830 UINTN Index; 831 UINT16 DeviceId; 832 EFI_STATUS Status; 833 834 Status = Private->PciIo->Pci.Read ( 835 Private->PciIo, 836 EfiPciIoWidthUint16, 837 PCI_DEVICE_ID_OFFSET, 838 1, 839 &DeviceId 840 ); 841 // 842 // Read the PCI Configuration Header from the PCI Device 843 // 844 ASSERT_EFI_ERROR (Status); 845 846 outw (Private, SEQ_ADDRESS_REGISTER, 0x1206); 847 outw (Private, SEQ_ADDRESS_REGISTER, 0x0012); 848 849 for (Index = 0; Index < 15; Index++) { 850 outw (Private, SEQ_ADDRESS_REGISTER, ModeData->SeqSettings[Index]); 851 } 852 853 if (DeviceId != CIRRUS_LOGIC_5446_DEVICE_ID) { 854 outb (Private, SEQ_ADDRESS_REGISTER, 0x0f); 855 Byte = (UINT8) ((inb (Private, SEQ_DATA_REGISTER) & 0xc7) ^ 0x30); 856 outb (Private, SEQ_DATA_REGISTER, Byte); 857 } 858 859 outb (Private, MISC_OUTPUT_REGISTER, ModeData->MiscSetting); 860 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0506); 861 outw (Private, SEQ_ADDRESS_REGISTER, 0x0300); 862 outw (Private, CRTC_ADDRESS_REGISTER, 0x2011); 863 864 for (Index = 0; Index < 28; Index++) { 865 outw (Private, CRTC_ADDRESS_REGISTER, (UINT16) ((ModeData->CrtcSettings[Index] << 8) | Index)); 866 } 867 868 for (Index = 0; Index < 9; Index++) { 869 outw (Private, GRAPH_ADDRESS_REGISTER, (UINT16) ((GraphicsController[Index] << 8) | Index)); 870 } 871 872 inb (Private, INPUT_STATUS_1_REGISTER); 873 874 for (Index = 0; Index < 21; Index++) { 875 outb (Private, ATT_ADDRESS_REGISTER, (UINT8) Index); 876 outb (Private, ATT_ADDRESS_REGISTER, AttributeController[Index]); 877 } 878 879 outb (Private, ATT_ADDRESS_REGISTER, 0x20); 880 881 outw (Private, GRAPH_ADDRESS_REGISTER, 0x0009); 882 outw (Private, GRAPH_ADDRESS_REGISTER, 0x000a); 883 outw (Private, GRAPH_ADDRESS_REGISTER, 0x000b); 884 outb (Private, DAC_PIXEL_MASK_REGISTER, 0xff); 885 886 SetDefaultPalette (Private); 887 ClearScreen (Private); 888 } 889 890 EFI_STATUS 891 EFIAPI 892 InitializeCirrusLogic5430 ( 893 IN EFI_HANDLE ImageHandle, 894 IN EFI_SYSTEM_TABLE *SystemTable 895 ) 896 { 897 EFI_STATUS Status; 898 899 Status = EfiLibInstallDriverBindingComponentName2 ( 900 ImageHandle, 901 SystemTable, 902 &gCirrusLogic5430DriverBinding, 903 ImageHandle, 904 &gCirrusLogic5430ComponentName, 905 &gCirrusLogic5430ComponentName2 906 ); 907 ASSERT_EFI_ERROR (Status); 908 909 // 910 // Install EFI Driver Supported EFI Version Protocol required for 911 // EFI drivers that are on PCI and other plug in cards. 912 // 913 gCirrusLogic5430DriverSupportedEfiVersion.FirmwareVersion = PcdGet32 (PcdDriverSupportedEfiVersion); 914 Status = gBS->InstallMultipleProtocolInterfaces ( 915 &ImageHandle, 916 &gEfiDriverSupportedEfiVersionProtocolGuid, 917 &gCirrusLogic5430DriverSupportedEfiVersion, 918 NULL 919 ); 920 ASSERT_EFI_ERROR (Status); 921 922 return Status; 923 } 924