4 Copyright (c) 2011 - 2014, Intel Corporation. All rights reserved
6 This program and the accompanying materials are licensed and made available under
7 the terms and conditions of the BSD License that accompanies this distribution.
8 The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
22 This is part of the implementation of an Intel Graphics drivers OpRegion /
23 Software SCI interface between system BIOS, ASL code, and Graphics drivers.
24 The code in this file will load the driver and initialize the interface
26 Supporting Specifiction: OpRegion / Software SCI SPEC 0.70
29 IGD: Internal Graphics Device
30 NVS: ACPI Non Volatile Storage
31 OpRegion: ACPI Operational Region
32 VBT: Video BIOS Table (OEM customizable data)
41 #include "IgdOpRegion.h"
42 #include "VlvPlatformInit.h"
43 #include <FrameworkDxe.h>
47 #include <Guid/DataHubRecords.h>
49 #include <Protocol/IgdOpRegion.h>
50 #include <Protocol/FrameworkHii.h>
51 #include <Protocol/FirmwareVolume.h>
52 #include <Protocol/PlatformGopPolicy.h>
53 #include <Protocol/PciIo.h>
54 #include <Protocol/CpuIo.h>
55 #include <Protocol/GlobalNvsArea.h>
56 #include <Protocol/DxeSmmReadyToLock.h>
57 #include <Protocol/PciRootBridgeIo.h>
59 #include <Library/MemoryAllocationLib.h>
60 #include <Library/BaseLib.h>
61 #include <Library/S3BootScriptLib.h>
62 #include <Library/IoLib.h>
63 #include <Library/DevicePathLib.h>
64 #include <Protocol/DriverBinding.h>
65 #include <Library/PrintLib.h>
66 #include <Library/BaseMemoryLib.h>
70 UINT8 gSVER
[12] = "Intel";
72 extern DXE_VLV_PLATFORM_POLICY_PROTOCOL
*DxePlatformSaPolicy
;
78 IGD_OPREGION_PROTOCOL mIgdOpRegion
;
79 EFI_GUID mMiscSubClass
= EFI_MISC_SUBCLASS_GUID
;
80 EFI_EVENT mConOutEvent
;
81 EFI_EVENT mSetGOPverEvent
;
84 #define DEFAULT_FORM_BUFFER_SIZE 0xFFFF
89 Get the HII protocol interface
91 @param Hii HII protocol interface
99 OUT EFI_HII_PROTOCOL
**Hii
105 // There should only be one HII protocol
107 Status
= gBS
->LocateProtocol (
108 &gEfiHiiProtocolGuid
,
122 @param[in] VbtFileBuffer Pointer to VBT data buffer.
124 @retval EFI_SUCCESS VBT data was returned.
125 @retval EFI_NOT_FOUND VBT data not found.
126 @exception EFI_UNSUPPORTED Invalid signature in VBT data.
130 GetIntegratedIntelVbtPtr (
131 OUT VBIOS_VBT_STRUCTURE
**VbtFileBuffer
135 EFI_PHYSICAL_ADDRESS VbtAddress
= 0;
137 UINTN FvProtocolCount
;
138 EFI_HANDLE
*FvHandles
;
139 EFI_FIRMWARE_VOLUME_PROTOCOL
*Fv
;
141 UINT32 AuthenticationStatus
;
144 UINTN VbtBufferSize
= 0;
148 *VbtFileBuffer
= NULL
;
149 Status
= gBS
->LocateHandleBuffer (
151 &gEfiFirmwareVolumeProtocolGuid
,
157 if (!EFI_ERROR (Status
)) {
158 for (Index
= 0; Index
< FvProtocolCount
; Index
++) {
159 Status
= gBS
->HandleProtocol (
161 &gEfiFirmwareVolumeProtocolGuid
,
165 Status
= Fv
->ReadSection (
172 &AuthenticationStatus
175 if (!EFI_ERROR (Status
)) {
176 VbtAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
177 VbtSize
= (UINT32
)VbtBufferSize
;
178 Status
= EFI_SUCCESS
;
183 Status
= EFI_NOT_FOUND
;
186 if (FvHandles
!= NULL
) {
193 // Check VBT signature
195 *VbtFileBuffer
= (VBIOS_VBT_STRUCTURE
*) (UINTN
) VbtAddress
;
196 if (*VbtFileBuffer
!= NULL
) {
197 if ((*((UINT32
*) ((*VbtFileBuffer
)->HeaderSignature
))) != VBT_SIGNATURE
) {
198 if (*VbtFileBuffer
!= NULL
) {
199 *VbtFileBuffer
= NULL
;
201 return EFI_UNSUPPORTED
;
206 if ((*VbtFileBuffer
)->HeaderVbtSize
> VbtBufferSize
) {
207 (*VbtFileBuffer
)->HeaderVbtSize
= (UINT16
) VbtBufferSize
;
215 // Function implementations.
219 Get a pointer to an uncompressed image of the Intel video BIOS.
221 Note: This function would only be called if the video BIOS at 0xC000 is
222 missing or not an Intel video BIOS. It may not be an Intel video BIOS
223 if the Intel graphic contoller is considered a secondary adapter.
226 @param VBiosROMImage Pointer to an uncompressed Intel video BIOS. This pointer must
227 be set to NULL if an uncompressed image of the Intel Video BIOS
231 @retval EFI_SUCCESS VBiosPtr is updated.
235 GetIntegratedIntelVBiosPtr (
236 INTEL_VBIOS_OPTION_ROM_HEADER
**VBiosImage
239 EFI_HANDLE
*HandleBuffer
;
242 INTEL_VBIOS_PCIR_STRUCTURE
*PcirBlockPtr
;
244 EFI_PCI_IO_PROTOCOL
*PciIo
;
245 INTEL_VBIOS_OPTION_ROM_HEADER
*VBiosRomImage
;
248 // Set as if an umcompressed Intel video BIOS image was not obtainable.
250 VBiosRomImage
= NULL
;
254 // Get all PCI IO protocols
256 Status
= gBS
->LocateHandleBuffer (
258 &gEfiPciIoProtocolGuid
,
263 ASSERT_EFI_ERROR (Status
);
266 // Find the video BIOS by checking each PCI IO handle for an Intel video
269 for (Index
= 0; Index
< HandleCount
; Index
++) {
270 Status
= gBS
->HandleProtocol (
272 &gEfiPciIoProtocolGuid
,
275 ASSERT_EFI_ERROR (Status
);
277 VBiosRomImage
= PciIo
->RomImage
;
280 // If this PCI device doesn't have a ROM image, skip to the next device.
282 if (!VBiosRomImage
) {
287 // Get pointer to PCIR structure
289 PcirBlockPtr
= (INTEL_VBIOS_PCIR_STRUCTURE
*)((UINT8
*) VBiosRomImage
+ VBiosRomImage
->PcirOffset
);
292 // Check if we have an Intel video BIOS OPROM.
294 if ((VBiosRomImage
->Signature
== OPTION_ROM_SIGNATURE
) &&
295 (PcirBlockPtr
->VendorId
== IGD_VID
) &&
296 (PcirBlockPtr
->ClassCode
[0] == 0x00) &&
297 (PcirBlockPtr
->ClassCode
[1] == 0x00) &&
298 (PcirBlockPtr
->ClassCode
[2] == 0x03)
301 // Found Intel video BIOS.
303 *VBiosImage
= VBiosRomImage
;
309 // No Intel video BIOS found.
313 // Free any allocated buffers
315 return EFI_UNSUPPORTED
;
326 EFI_GUID
**ProtocolGuidArray
= NULL
;
331 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfo
= NULL
;
333 EFI_HANDLE
*mHandleBuffer
= NULL
;
336 // Retrieve the list of all handles from the handle database
338 Status
= gBS
->LocateHandleBuffer (
346 for (HandleIndex
= 0; HandleIndex
< mHandleCount
; HandleIndex
++) {
348 // Retrieve the list of all the protocols on each handle
350 Status
= gBS
->ProtocolsPerHandle (
351 mHandleBuffer
[HandleIndex
],
355 if (!EFI_ERROR (Status
)) {
356 for (ProtocolIndex
= 0; ProtocolIndex
< ArrayCount
; ProtocolIndex
++) {
357 Status
= gBS
->OpenProtocolInformation (
358 mHandleBuffer
[HandleIndex
],
359 ProtocolGuidArray
[ProtocolIndex
],
363 if (!EFI_ERROR (Status
)) {
364 for (OpenInfoIndex
= 0; OpenInfoIndex
< OpenInfoCount
; OpenInfoIndex
++) {
365 if(OpenInfo
[OpenInfoIndex
].AgentHandle
== Father
) {
366 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
367 *Child
= mHandleBuffer
[HandleIndex
];
368 Status
= EFI_SUCCESS
;
373 Status
= EFI_NOT_FOUND
;
376 if(OpenInfo
!= NULL
) {
381 FreePool (ProtocolGuidArray
);
382 ProtocolGuidArray
= NULL
;
385 if(OpenInfo
!= NULL
) {
389 if(ProtocolGuidArray
!= NULL
) {
390 FreePool(ProtocolGuidArray
);
391 ProtocolGuidArray
= NULL
;
393 if(mHandleBuffer
!= NULL
) {
394 FreePool (mHandleBuffer
);
395 mHandleBuffer
= NULL
;
401 JudgeHandleIsPCIDevice(
408 EFI_DEVICE_PATH
*DPath
;
409 EFI_DEVICE_PATH
*DevicePath
;
411 Status
= gBS
->HandleProtocol (
413 &gEfiDevicePathProtocolGuid
,
416 if(!EFI_ERROR(Status
)) {
418 while(!IsDevicePathEnd(DPath
)) {
419 if((DPath
->Type
== HARDWARE_DEVICE_PATH
) && (DPath
->SubType
== HW_PCI_DP
)) {
420 PCI_DEVICE_PATH
*PCIPath
;
422 PCIPath
= (PCI_DEVICE_PATH
*) DPath
;
423 DPath
= NextDevicePathNode(DPath
);
424 if(IsDevicePathEnd(DPath
) && (PCIPath
->Device
== Device
) && (PCIPath
->Function
== Funs
)) {
428 DPath
= NextDevicePathNode(DPath
);
432 return EFI_UNSUPPORTED
;
441 EFI_DRIVER_BINDING_PROTOCOL
*BindHandle
= NULL
;
446 Status
= gBS
->OpenProtocol(
448 &gEfiDriverBindingProtocolGuid
,
452 EFI_OPEN_PROTOCOL_GET_PROTOCOL
454 if (EFI_ERROR(Status
)) {
455 return EFI_NOT_FOUND
;
458 Version
= BindHandle
->Version
;
459 Ptr
= (UINT16
*)&Version
;
460 UnicodeSPrint(GopVersion
, 40, L
"7.0.%04d", *(Ptr
));
470 EFI_HANDLE
*Handles
= NULL
;
473 EFI_HANDLE Child
= 0;
475 Status
= gBS
->LocateHandleBuffer(
477 &gEfiDriverBindingProtocolGuid
,
482 for (Index
= 0; Index
< HandleCount
; Index
++) {
483 Status
= SearchChildHandle(Handles
[Index
], &Child
);
484 if(!EFI_ERROR(Status
)) {
485 Status
= JudgeHandleIsPCIDevice(Child
, 0x02, 0x00);
486 if(!EFI_ERROR(Status
)) {
487 return GetDriverName(Handles
[Index
], GopVersion
);
491 return EFI_UNSUPPORTED
;
496 Get Intel GOP driver version and copy it into IGD OpRegion GVER. This version
497 is picked up by IGD driver and displayed in CUI.
499 @param Event A pointer to the Event that triggered the callback.
500 @param Context A pointer to private data registered with the callback function.
502 @retval EFI_SUCCESS Video BIOS VBT information returned.
503 @retval EFI_UNSUPPORTED Could not find VBT information (*VBiosVbtPtr = NULL).
508 SetGOPVersionCallback (
513 CHAR16 GopVersion
[16] = {0};
516 Status
= GetGOPDriverVersion(GopVersion
);
517 if(!EFI_ERROR(Status
)) {
518 StrCpy((CHAR16
*)&(mIgdOpRegion
.OpRegion
->Header
.GOPV
[0]), GopVersion
);
521 return EFI_UNSUPPORTED
;
525 Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).
526 The VBT (Video BIOS Table) is a block of customizable data that is built
527 within the video BIOS and edited by customers.
529 @param Event A pointer to the Event that triggered the callback.
530 @param Context A pointer to private data registered with the callback function.
532 @retval EFI_SUCCESS Video BIOS VBT information returned.
533 @retval EFI_UNSUPPORTED Could not find VBT information (*VBiosVbtPtr = NULL).
537 GetVBiosVbtCallback (
542 INTEL_VBIOS_PCIR_STRUCTURE
*PcirBlockPtr
;
545 INTEL_VBIOS_OPTION_ROM_HEADER
*VBiosPtr
;
546 VBIOS_VBT_STRUCTURE
*VBiosVbtPtr
;
547 VBIOS_VBT_STRUCTURE
*VbtFileBuffer
= NULL
;
549 VBiosPtr
= (INTEL_VBIOS_OPTION_ROM_HEADER
*)(UINTN
)(VBIOS_LOCATION_PRIMARY
);
550 PcirBlockPtr
= (INTEL_VBIOS_PCIR_STRUCTURE
*)((UINT8
*)VBiosPtr
+ VBiosPtr
->PcirOffset
);
551 PciVenderId
= PcirBlockPtr
->VendorId
;
552 PciDeviceId
= PcirBlockPtr
->DeviceId
;
555 // If the video BIOS is not at 0xC0000 or it is not an Intel video BIOS get
556 // the integrated Intel video BIOS (must be uncompressed).
558 if ((VBiosPtr
->Signature
!= OPTION_ROM_SIGNATURE
) || (PciVenderId
!= IGD_VID
) || (PciDeviceId
!= IGD_DID_VLV
)) {
559 GetIntegratedIntelVBiosPtr (&VBiosPtr
);
565 PcirBlockPtr
= (INTEL_VBIOS_PCIR_STRUCTURE
*)((UINT8
*)VBiosPtr
+ VBiosPtr
->PcirOffset
);
566 PciVenderId
= PcirBlockPtr
->VendorId
;
567 if( (VBiosPtr
->Signature
!= OPTION_ROM_SIGNATURE
) || (PciVenderId
!= IGD_VID
)) {
569 // Intel video BIOS not found.
572 return EFI_UNSUPPORTED
;
576 // No Video BIOS found, try to get VBT from FV.
578 GetIntegratedIntelVbtPtr (&VbtFileBuffer
);
579 if (VbtFileBuffer
!= NULL
) {
581 // Video BIOS not found, use VBT from FV
583 DEBUG ((EFI_D_ERROR
, "VBT data found\n"));
585 mIgdOpRegion
.OpRegion
->VBT
.GVD1
,
587 VbtFileBuffer
->HeaderVbtSize
589 FreePool (VbtFileBuffer
);
593 if ((VBiosPtr
== NULL
) ) {
595 // Intel video BIOS not found.
598 return EFI_UNSUPPORTED
;
602 DEBUG ((EFI_D_ERROR
, "VBIOS found at 0x%X\n", VBiosPtr
));
603 VBiosVbtPtr
= (VBIOS_VBT_STRUCTURE
*) ((UINT8
*) VBiosPtr
+ VBiosPtr
->VbtOffset
);
605 if ((*((UINT32
*) (VBiosVbtPtr
->HeaderSignature
))) != VBT_SIGNATURE
) {
606 return EFI_UNSUPPORTED
;
610 // Initialize Video BIOS version with its build number.
612 mIgdOpRegion
.OpRegion
->Header
.VVER
[0] = VBiosVbtPtr
->CoreBlockBiosBuild
[0];
613 mIgdOpRegion
.OpRegion
->Header
.VVER
[1] = VBiosVbtPtr
->CoreBlockBiosBuild
[1];
614 mIgdOpRegion
.OpRegion
->Header
.VVER
[2] = VBiosVbtPtr
->CoreBlockBiosBuild
[2];
615 mIgdOpRegion
.OpRegion
->Header
.VVER
[3] = VBiosVbtPtr
->CoreBlockBiosBuild
[3];
617 mIgdOpRegion
.OpRegion
->VBT
.GVD1
,
619 VBiosVbtPtr
->HeaderVbtSize
623 // Return final status
629 Graphics OpRegion / Software SCI driver installation function.
631 @param ImageHandle Handle for this drivers loaded image protocol.
632 @param SystemTable EFI system table.
634 @retval EFI_SUCCESS The driver installed without error.
635 @retval EFI_ABORTED The driver encountered an error and could not complete
636 installation of the ACPI tables.
646 EFI_GLOBAL_NVS_AREA_PROTOCOL
*GlobalNvsArea
;
648 EFI_CPU_IO_PROTOCOL
*CpuIo
;
651 VOID
*gConOutNotifyReg
;
655 // Locate the Global NVS Protocol.
657 Status
= gBS
->LocateProtocol (
658 &gEfiGlobalNvsAreaProtocolGuid
,
660 (void **)&GlobalNvsArea
662 ASSERT_EFI_ERROR (Status
);
665 // Allocate an ACPI NVS memory buffer as the IGD OpRegion, zero initialize
666 // the first 1K, and set the IGD OpRegion pointer in the Global NVS
669 Status
= (gBS
->AllocatePool
) (
671 sizeof (IGD_OPREGION_STRUC
),
672 (void **)&mIgdOpRegion
.OpRegion
674 ASSERT_EFI_ERROR (Status
);
676 mIgdOpRegion
.OpRegion
,
677 sizeof (IGD_OPREGION_STRUC
),
680 GlobalNvsArea
->Area
->IgdOpRegionAddress
= (UINT32
)(UINTN
)(mIgdOpRegion
.OpRegion
);
683 // If IGD is disabled return
685 if (IgdMmPci32 (0) == 0xFFFFFFFF) {
690 // Initialize OpRegion Header
694 mIgdOpRegion
.OpRegion
->Header
.SIGN
,
696 sizeof(HEADER_SIGNATURE
)
701 // Set OpRegion Size in KBs
703 mIgdOpRegion
.OpRegion
->Header
.SIZE
= HEADER_SIZE
/1024;
706 // FIXME: Need to check Header OVER Field and the supported version.
708 mIgdOpRegion
.OpRegion
->Header
.OVER
= (UINT32
) (LShiftU64 (HEADER_OPREGION_VER
, 16) + LShiftU64 (HEADER_OPREGION_REV
, 8));
710 CopyMem(mIgdOpRegion
.OpRegion
->Header
.SVER
, gSVER
, sizeof(gSVER
));
713 mIgdOpRegion
.OpRegion
->Header
.SVER
,
718 DEBUG ((EFI_D_ERROR
, "System BIOS ID is %a\n", mIgdOpRegion
.OpRegion
->Header
.SVER
));
721 mIgdOpRegion
.OpRegion
->Header
.MBOX
= HEADER_MBOX_SUPPORT
;
723 if( 1 == DxePlatformSaPolicy
->IdleReserve
) {
724 mIgdOpRegion
.OpRegion
->Header
.PCON
= (mIgdOpRegion
.OpRegion
->Header
.PCON
& 0xFFFC) | BIT1
;
726 mIgdOpRegion
.OpRegion
->Header
.PCON
= (mIgdOpRegion
.OpRegion
->Header
.PCON
& 0xFFFC) | (BIT1
| BIT0
);
730 //For graphics driver to identify if LPE Audio/HD Audio is enabled on the platform
732 mIgdOpRegion
.OpRegion
->Header
.PCON
&= AUDIO_TYPE_SUPPORT_MASK
;
733 mIgdOpRegion
.OpRegion
->Header
.PCON
&= AUDIO_TYPE_FIELD_MASK
;
734 if ( 1 == DxePlatformSaPolicy
->AudioTypeSupport
) {
735 mIgdOpRegion
.OpRegion
->Header
.PCON
= HD_AUDIO_SUPPORT
;
736 mIgdOpRegion
.OpRegion
->Header
.PCON
|= AUDIO_TYPE_FIELD_VALID
;
740 // Initialize OpRegion Mailbox 1 (Public ACPI Methods).
742 //<TODO> The initial setting of mailbox 1 fields is implementation specific.
743 // Adjust them as needed many even coming from user setting in setup.
745 //Workaround to solve LVDS is off after entering OS in desktop platform
747 mIgdOpRegion
.OpRegion
->MBox1
.CLID
= DxePlatformSaPolicy
->IgdPanelFeatures
.LidStatus
;
750 // Initialize OpRegion Mailbox 3 (ASLE Interrupt and Power Conservation).
752 //<TODO> The initial setting of mailbox 3 fields is implementation specific.
753 // Adjust them as needed many even coming from user setting in setup.
757 // Do not initialize TCHE. This field is written by the graphics driver only.
761 // The ALSI field is generally initialized by ASL code by reading the embedded controller.
764 mIgdOpRegion
.OpRegion
->MBox3
.BCLP
= BACKLIGHT_BRIGHTNESS
;
766 mIgdOpRegion
.OpRegion
->MBox3
.PFIT
= (FIELD_VALID_BIT
| PFIT_STRETCH
);
767 if ( DxePlatformSaPolicy
->IgdPanelFeatures
.PFITStatus
== 2) {
771 mIgdOpRegion
.OpRegion
->MBox3
.PFIT
= (FIELD_VALID_BIT
| PFIT_CENTER
);
772 } else if (DxePlatformSaPolicy
->IgdPanelFeatures
.PFITStatus
== 1) {
776 mIgdOpRegion
.OpRegion
->MBox3
.PFIT
= (FIELD_VALID_BIT
| PFIT_STRETCH
);
781 mIgdOpRegion
.OpRegion
->MBox3
.PFIT
= (FIELD_VALID_BIT
| PFIT_SETUP_AUTO
);
785 // Set Initial current Brightness
787 mIgdOpRegion
.OpRegion
->MBox3
.CBLV
= (INIT_BRIGHT_LEVEL
| FIELD_VALID_BIT
);
790 // <EXAMPLE> Create a static Backlight Brightness Level Duty cycle Mapping Table
791 // Possible 20 entries (example used 10), each 16 bits as follows:
792 // [15] = Field Valid bit, [14:08] = Level in Percentage (0-64h), [07:00] = Desired duty cycle (0 - FFh).
795 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[0] = ( ( 0 << 8 ) + ( 0xFF - 0xFC ) + WORD_FIELD_VALID_BIT
);
796 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[1] = ( ( 1 << 8 ) + ( 0xFF - 0xFC ) + WORD_FIELD_VALID_BIT
);
797 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[2] = ( ( 10 << 8 ) + ( 0xFF - 0xE5 ) + WORD_FIELD_VALID_BIT
);
798 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[3] = ( ( 19 << 8 ) + ( 0xFF - 0xCE ) + WORD_FIELD_VALID_BIT
);
799 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[4] = ( ( 28 << 8 ) + ( 0xFF - 0xB7 ) + WORD_FIELD_VALID_BIT
);
800 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[5] = ( ( 37 << 8 ) + ( 0xFF - 0xA0 ) + WORD_FIELD_VALID_BIT
);
801 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[6] = ( ( 46 << 8 ) + ( 0xFF - 0x89 ) + WORD_FIELD_VALID_BIT
);
802 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[7] = ( ( 55 << 8 ) + ( 0xFF - 0x72 ) + WORD_FIELD_VALID_BIT
);
803 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[8] = ( ( 64 << 8 ) + ( 0xFF - 0x5B ) + WORD_FIELD_VALID_BIT
);
804 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[9] = ( ( 73 << 8 ) + ( 0xFF - 0x44 ) + WORD_FIELD_VALID_BIT
);
805 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[10] = ( ( 82 << 8 ) + ( 0xFF - 0x2D ) + WORD_FIELD_VALID_BIT
);
806 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[11] = ( ( 91 << 8 ) + ( 0xFF - 0x16 ) + WORD_FIELD_VALID_BIT
);
807 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[12] = ( (100 << 8 ) + ( 0xFF - 0x00 ) + WORD_FIELD_VALID_BIT
);
809 mIgdOpRegion
.OpRegion
->MBox3
.PCFT
= ((UINT32
) GlobalNvsArea
->Area
->IgdPowerConservation
) | BIT31
;
811 // Create the notification and register callback function on the PciIo installation,
814 Status
= gBS
->CreateEvent (
817 (EFI_EVENT_NOTIFY
)GetVBiosVbtCallback
,
822 ASSERT_EFI_ERROR (Status
);
823 if (EFI_ERROR (Status
)) {
828 Status
= gBS
->RegisterProtocolNotify (
830 &gExitPmAuthProtocolGuid
,
832 &gEfiDxeSmmReadyToLockProtocolGuid
,
838 Status
= gBS
->CreateEvent (
841 (EFI_EVENT_NOTIFY
)SetGOPVersionCallback
,
846 ASSERT_EFI_ERROR (Status
);
847 if (EFI_ERROR (Status
)) {
851 Status
= gBS
->RegisterProtocolNotify (
852 &gEfiGraphicsOutputProtocolGuid
,
859 // Initialize hardware state:
860 // Set ASLS Register to the OpRegion physical memory address.
861 // Set SWSCI register bit 15 to a "1" to activate SCI interrupts.
864 IgdMmPci32 (IGD_ASLS_OFFSET
) = (UINT32
)(UINTN
)(mIgdOpRegion
.OpRegion
);
865 IgdMmPci16AndThenOr (IGD_SWSCI_OFFSET
, ~(BIT0
), BIT15
);
867 DwordData
= IgdMmPci32 (IGD_ASLS_OFFSET
);
868 S3BootScriptSavePciCfgWrite (
869 S3BootScriptWidthUint32
,
870 (UINTN
) (EFI_PCI_ADDRESS (IGD_BUS
, IGD_DEV
, IGD_FUN_0
, IGD_ASLS_OFFSET
)),
876 DwordData
= IgdMmPci32 (IGD_SWSCI_OFFSET
);
877 S3BootScriptSavePciCfgWrite (
878 S3BootScriptWidthUint32
,
879 (UINTN
) (EFI_PCI_ADDRESS (IGD_BUS
, IGD_DEV
, IGD_FUN_0
, IGD_SWSCI_OFFSET
)),
886 DEFAULT_PCI_BUS_NUMBER_PCH
,
887 PCI_DEVICE_NUMBER_PCH_LPC
,
888 PCI_FUNCTION_NUMBER_PCH_LPC
,
890 ) & B_PCH_LPC_ACPI_BASE_BAR
;
893 // Find the CPU I/O Protocol. ASSERT if not found.
895 Status
= gBS
->LocateProtocol (
896 &gEfiCpuIoProtocolGuid
,
900 ASSERT_EFI_ERROR (Status
);
905 AcpiBase
+ R_PCH_ACPI_GPE0a_STS
,
910 // Clear the B_PCH_ACPI_GPE0a_STS_GUNIT_SCI bit in R_PCH_ACPI_GPE0a_STS by writing a '1'.
912 Data16
|= B_PCH_ACPI_GPE0a_STS_GUNIT_SCI
;
917 AcpiBase
+ R_PCH_ACPI_GPE0a_STS
,
923 // Install OpRegion / Software SCI protocol
926 Status
= gBS
->InstallMultipleProtocolInterfaces (
928 &gIgdOpRegionProtocolGuid
,
932 ASSERT_EFI_ERROR (Status
);
935 // Return final status