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;
136 UINTN FvProtocolCount
;
137 EFI_HANDLE
*FvHandles
;
138 EFI_FIRMWARE_VOLUME_PROTOCOL
*Fv
;
140 UINT32 AuthenticationStatus
;
143 UINTN VbtBufferSize
= 0;
147 *VbtFileBuffer
= NULL
;
148 Status
= gBS
->LocateHandleBuffer (
150 &gEfiFirmwareVolumeProtocolGuid
,
156 if (!EFI_ERROR (Status
)) {
157 for (Index
= 0; Index
< FvProtocolCount
; Index
++) {
158 Status
= gBS
->HandleProtocol (
160 &gEfiFirmwareVolumeProtocolGuid
,
164 Status
= Fv
->ReadSection (
171 &AuthenticationStatus
174 if (!EFI_ERROR (Status
)) {
175 VbtAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
176 Status
= EFI_SUCCESS
;
181 Status
= EFI_NOT_FOUND
;
184 if (FvHandles
!= NULL
) {
191 // Check VBT signature
193 *VbtFileBuffer
= (VBIOS_VBT_STRUCTURE
*) (UINTN
) VbtAddress
;
194 if (*VbtFileBuffer
!= NULL
) {
195 if ((*((UINT32
*) ((*VbtFileBuffer
)->HeaderSignature
))) != VBT_SIGNATURE
) {
196 if (*VbtFileBuffer
!= NULL
) {
197 *VbtFileBuffer
= NULL
;
199 return EFI_UNSUPPORTED
;
204 if ((*VbtFileBuffer
)->HeaderVbtSize
> VbtBufferSize
) {
205 (*VbtFileBuffer
)->HeaderVbtSize
= (UINT16
) VbtBufferSize
;
213 // Function implementations.
217 Get a pointer to an uncompressed image of the Intel video BIOS.
219 Note: This function would only be called if the video BIOS at 0xC000 is
220 missing or not an Intel video BIOS. It may not be an Intel video BIOS
221 if the Intel graphic contoller is considered a secondary adapter.
224 @param VBiosROMImage Pointer to an uncompressed Intel video BIOS. This pointer must
225 be set to NULL if an uncompressed image of the Intel Video BIOS
229 @retval EFI_SUCCESS VBiosPtr is updated.
233 GetIntegratedIntelVBiosPtr (
234 INTEL_VBIOS_OPTION_ROM_HEADER
**VBiosImage
237 EFI_HANDLE
*HandleBuffer
;
240 INTEL_VBIOS_PCIR_STRUCTURE
*PcirBlockPtr
;
242 EFI_PCI_IO_PROTOCOL
*PciIo
;
243 INTEL_VBIOS_OPTION_ROM_HEADER
*VBiosRomImage
;
246 // Set as if an umcompressed Intel video BIOS image was not obtainable.
248 VBiosRomImage
= NULL
;
252 // Get all PCI IO protocols
254 Status
= gBS
->LocateHandleBuffer (
256 &gEfiPciIoProtocolGuid
,
261 ASSERT_EFI_ERROR (Status
);
264 // Find the video BIOS by checking each PCI IO handle for an Intel video
267 for (Index
= 0; Index
< HandleCount
; Index
++) {
268 Status
= gBS
->HandleProtocol (
270 &gEfiPciIoProtocolGuid
,
273 ASSERT_EFI_ERROR (Status
);
275 VBiosRomImage
= PciIo
->RomImage
;
278 // If this PCI device doesn't have a ROM image, skip to the next device.
280 if (!VBiosRomImage
) {
285 // Get pointer to PCIR structure
287 PcirBlockPtr
= (INTEL_VBIOS_PCIR_STRUCTURE
*)((UINT8
*) VBiosRomImage
+ VBiosRomImage
->PcirOffset
);
290 // Check if we have an Intel video BIOS OPROM.
292 if ((VBiosRomImage
->Signature
== OPTION_ROM_SIGNATURE
) &&
293 (PcirBlockPtr
->VendorId
== IGD_VID
) &&
294 (PcirBlockPtr
->ClassCode
[0] == 0x00) &&
295 (PcirBlockPtr
->ClassCode
[1] == 0x00) &&
296 (PcirBlockPtr
->ClassCode
[2] == 0x03)
299 // Found Intel video BIOS.
301 *VBiosImage
= VBiosRomImage
;
307 // No Intel video BIOS found.
311 // Free any allocated buffers
313 return EFI_UNSUPPORTED
;
324 EFI_GUID
**ProtocolGuidArray
= NULL
;
329 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfo
= NULL
;
331 EFI_HANDLE
*mHandleBuffer
= NULL
;
334 // Retrieve the list of all handles from the handle database
336 Status
= gBS
->LocateHandleBuffer (
344 for (HandleIndex
= 0; HandleIndex
< mHandleCount
; HandleIndex
++) {
346 // Retrieve the list of all the protocols on each handle
348 Status
= gBS
->ProtocolsPerHandle (
349 mHandleBuffer
[HandleIndex
],
353 if (!EFI_ERROR (Status
)) {
354 for (ProtocolIndex
= 0; ProtocolIndex
< ArrayCount
; ProtocolIndex
++) {
355 Status
= gBS
->OpenProtocolInformation (
356 mHandleBuffer
[HandleIndex
],
357 ProtocolGuidArray
[ProtocolIndex
],
361 if (!EFI_ERROR (Status
)) {
362 for (OpenInfoIndex
= 0; OpenInfoIndex
< OpenInfoCount
; OpenInfoIndex
++) {
363 if(OpenInfo
[OpenInfoIndex
].AgentHandle
== Father
) {
364 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
365 *Child
= mHandleBuffer
[HandleIndex
];
366 Status
= EFI_SUCCESS
;
371 Status
= EFI_NOT_FOUND
;
374 if(OpenInfo
!= NULL
) {
379 FreePool (ProtocolGuidArray
);
380 ProtocolGuidArray
= NULL
;
383 if(OpenInfo
!= NULL
) {
387 if(ProtocolGuidArray
!= NULL
) {
388 FreePool(ProtocolGuidArray
);
389 ProtocolGuidArray
= NULL
;
391 if(mHandleBuffer
!= NULL
) {
392 FreePool (mHandleBuffer
);
393 mHandleBuffer
= NULL
;
399 JudgeHandleIsPCIDevice(
406 EFI_DEVICE_PATH
*DPath
;
408 Status
= gBS
->HandleProtocol (
410 &gEfiDevicePathProtocolGuid
,
413 if(!EFI_ERROR(Status
)) {
414 while(!IsDevicePathEnd(DPath
)) {
415 if((DPath
->Type
== HARDWARE_DEVICE_PATH
) && (DPath
->SubType
== HW_PCI_DP
)) {
416 PCI_DEVICE_PATH
*PCIPath
;
418 PCIPath
= (PCI_DEVICE_PATH
*) DPath
;
419 DPath
= NextDevicePathNode(DPath
);
420 if(IsDevicePathEnd(DPath
) && (PCIPath
->Device
== Device
) && (PCIPath
->Function
== Funs
)) {
424 DPath
= NextDevicePathNode(DPath
);
428 return EFI_UNSUPPORTED
;
437 EFI_DRIVER_BINDING_PROTOCOL
*BindHandle
= NULL
;
442 Status
= gBS
->OpenProtocol(
444 &gEfiDriverBindingProtocolGuid
,
448 EFI_OPEN_PROTOCOL_GET_PROTOCOL
450 if (EFI_ERROR(Status
)) {
451 return EFI_NOT_FOUND
;
454 Version
= BindHandle
->Version
;
455 Ptr
= (UINT16
*)&Version
;
456 UnicodeSPrint(GopVersion
, 40, L
"7.0.%04d", *(Ptr
));
466 EFI_HANDLE
*Handles
= NULL
;
469 EFI_HANDLE Child
= 0;
471 Status
= gBS
->LocateHandleBuffer(
473 &gEfiDriverBindingProtocolGuid
,
478 for (Index
= 0; Index
< HandleCount
; Index
++) {
479 Status
= SearchChildHandle(Handles
[Index
], &Child
);
480 if(!EFI_ERROR(Status
)) {
481 Status
= JudgeHandleIsPCIDevice(Child
, 0x02, 0x00);
482 if(!EFI_ERROR(Status
)) {
483 return GetDriverName(Handles
[Index
], GopVersion
);
487 return EFI_UNSUPPORTED
;
492 Get Intel GOP driver version and copy it into IGD OpRegion GVER. This version
493 is picked up by IGD driver and displayed in CUI.
495 @param Event A pointer to the Event that triggered the callback.
496 @param Context A pointer to private data registered with the callback function.
498 @retval EFI_SUCCESS Video BIOS VBT information returned.
499 @retval EFI_UNSUPPORTED Could not find VBT information (*VBiosVbtPtr = NULL).
504 SetGOPVersionCallback (
509 CHAR16 GopVersion
[16] = {0};
512 Status
= GetGOPDriverVersion(GopVersion
);
513 if(!EFI_ERROR(Status
)) {
514 StrCpy((CHAR16
*)&(mIgdOpRegion
.OpRegion
->Header
.GOPV
[0]), GopVersion
);
517 return EFI_UNSUPPORTED
;
521 Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).
522 The VBT (Video BIOS Table) is a block of customizable data that is built
523 within the video BIOS and edited by customers.
525 @param Event A pointer to the Event that triggered the callback.
526 @param Context A pointer to private data registered with the callback function.
528 @retval EFI_SUCCESS Video BIOS VBT information returned.
529 @retval EFI_UNSUPPORTED Could not find VBT information (*VBiosVbtPtr = NULL).
533 GetVBiosVbtCallback (
538 INTEL_VBIOS_PCIR_STRUCTURE
*PcirBlockPtr
;
541 INTEL_VBIOS_OPTION_ROM_HEADER
*VBiosPtr
;
542 VBIOS_VBT_STRUCTURE
*VBiosVbtPtr
;
543 VBIOS_VBT_STRUCTURE
*VbtFileBuffer
= NULL
;
545 VBiosPtr
= (INTEL_VBIOS_OPTION_ROM_HEADER
*)(UINTN
)(VBIOS_LOCATION_PRIMARY
);
546 PcirBlockPtr
= (INTEL_VBIOS_PCIR_STRUCTURE
*)((UINT8
*)VBiosPtr
+ VBiosPtr
->PcirOffset
);
547 PciVenderId
= PcirBlockPtr
->VendorId
;
548 PciDeviceId
= PcirBlockPtr
->DeviceId
;
551 // If the video BIOS is not at 0xC0000 or it is not an Intel video BIOS get
552 // the integrated Intel video BIOS (must be uncompressed).
554 if ((VBiosPtr
->Signature
!= OPTION_ROM_SIGNATURE
) || (PciVenderId
!= IGD_VID
) || (PciDeviceId
!= IGD_DID_VLV
)) {
555 GetIntegratedIntelVBiosPtr (&VBiosPtr
);
561 PcirBlockPtr
= (INTEL_VBIOS_PCIR_STRUCTURE
*)((UINT8
*)VBiosPtr
+ VBiosPtr
->PcirOffset
);
562 PciVenderId
= PcirBlockPtr
->VendorId
;
563 if( (VBiosPtr
->Signature
!= OPTION_ROM_SIGNATURE
) || (PciVenderId
!= IGD_VID
)) {
565 // Intel video BIOS not found.
568 return EFI_UNSUPPORTED
;
572 // No Video BIOS found, try to get VBT from FV.
574 GetIntegratedIntelVbtPtr (&VbtFileBuffer
);
575 if (VbtFileBuffer
!= NULL
) {
577 // Video BIOS not found, use VBT from FV
579 DEBUG ((EFI_D_ERROR
, "VBT data found\n"));
581 mIgdOpRegion
.OpRegion
->VBT
.GVD1
,
583 VbtFileBuffer
->HeaderVbtSize
585 FreePool (VbtFileBuffer
);
589 if ((VBiosPtr
== NULL
) ) {
591 // Intel video BIOS not found.
594 return EFI_UNSUPPORTED
;
598 DEBUG ((EFI_D_ERROR
, "VBIOS found at 0x%X\n", VBiosPtr
));
599 VBiosVbtPtr
= (VBIOS_VBT_STRUCTURE
*) ((UINT8
*) VBiosPtr
+ VBiosPtr
->VbtOffset
);
601 if ((*((UINT32
*) (VBiosVbtPtr
->HeaderSignature
))) != VBT_SIGNATURE
) {
602 return EFI_UNSUPPORTED
;
606 // Initialize Video BIOS version with its build number.
608 mIgdOpRegion
.OpRegion
->Header
.VVER
[0] = VBiosVbtPtr
->CoreBlockBiosBuild
[0];
609 mIgdOpRegion
.OpRegion
->Header
.VVER
[1] = VBiosVbtPtr
->CoreBlockBiosBuild
[1];
610 mIgdOpRegion
.OpRegion
->Header
.VVER
[2] = VBiosVbtPtr
->CoreBlockBiosBuild
[2];
611 mIgdOpRegion
.OpRegion
->Header
.VVER
[3] = VBiosVbtPtr
->CoreBlockBiosBuild
[3];
613 mIgdOpRegion
.OpRegion
->VBT
.GVD1
,
615 VBiosVbtPtr
->HeaderVbtSize
619 // Return final status
625 Graphics OpRegion / Software SCI driver installation function.
627 @param ImageHandle Handle for this drivers loaded image protocol.
628 @param SystemTable EFI system table.
630 @retval EFI_SUCCESS The driver installed without error.
631 @retval EFI_ABORTED The driver encountered an error and could not complete
632 installation of the ACPI tables.
642 EFI_GLOBAL_NVS_AREA_PROTOCOL
*GlobalNvsArea
;
644 EFI_CPU_IO_PROTOCOL
*CpuIo
;
647 VOID
*gConOutNotifyReg
;
651 // Locate the Global NVS Protocol.
653 Status
= gBS
->LocateProtocol (
654 &gEfiGlobalNvsAreaProtocolGuid
,
656 (void **)&GlobalNvsArea
658 ASSERT_EFI_ERROR (Status
);
661 // Allocate an ACPI NVS memory buffer as the IGD OpRegion, zero initialize
662 // the first 1K, and set the IGD OpRegion pointer in the Global NVS
665 Status
= (gBS
->AllocatePool
) (
667 sizeof (IGD_OPREGION_STRUC
),
668 (void **)&mIgdOpRegion
.OpRegion
670 ASSERT_EFI_ERROR (Status
);
672 mIgdOpRegion
.OpRegion
,
673 sizeof (IGD_OPREGION_STRUC
),
676 GlobalNvsArea
->Area
->IgdOpRegionAddress
= (UINT32
)(UINTN
)(mIgdOpRegion
.OpRegion
);
679 // If IGD is disabled return
681 if (IgdMmPci32 (0) == 0xFFFFFFFF) {
686 // Initialize OpRegion Header
690 mIgdOpRegion
.OpRegion
->Header
.SIGN
,
692 sizeof(HEADER_SIGNATURE
)
697 // Set OpRegion Size in KBs
699 mIgdOpRegion
.OpRegion
->Header
.SIZE
= HEADER_SIZE
/1024;
702 // FIXME: Need to check Header OVER Field and the supported version.
704 mIgdOpRegion
.OpRegion
->Header
.OVER
= (UINT32
) (LShiftU64 (HEADER_OPREGION_VER
, 16) + LShiftU64 (HEADER_OPREGION_REV
, 8));
706 CopyMem(mIgdOpRegion
.OpRegion
->Header
.SVER
, gSVER
, sizeof(gSVER
));
709 mIgdOpRegion
.OpRegion
->Header
.SVER
,
714 DEBUG ((EFI_D_ERROR
, "System BIOS ID is %a\n", mIgdOpRegion
.OpRegion
->Header
.SVER
));
717 mIgdOpRegion
.OpRegion
->Header
.MBOX
= HEADER_MBOX_SUPPORT
;
719 if( 1 == DxePlatformSaPolicy
->IdleReserve
) {
720 mIgdOpRegion
.OpRegion
->Header
.PCON
= (mIgdOpRegion
.OpRegion
->Header
.PCON
& 0xFFFC) | BIT1
;
722 mIgdOpRegion
.OpRegion
->Header
.PCON
= (mIgdOpRegion
.OpRegion
->Header
.PCON
& 0xFFFC) | (BIT1
| BIT0
);
726 //For graphics driver to identify if LPE Audio/HD Audio is enabled on the platform
728 mIgdOpRegion
.OpRegion
->Header
.PCON
&= AUDIO_TYPE_SUPPORT_MASK
;
729 mIgdOpRegion
.OpRegion
->Header
.PCON
&= AUDIO_TYPE_FIELD_MASK
;
730 if ( 1 == DxePlatformSaPolicy
->AudioTypeSupport
) {
731 mIgdOpRegion
.OpRegion
->Header
.PCON
= HD_AUDIO_SUPPORT
;
732 mIgdOpRegion
.OpRegion
->Header
.PCON
|= AUDIO_TYPE_FIELD_VALID
;
736 // Initialize OpRegion Mailbox 1 (Public ACPI Methods).
738 //<TODO> The initial setting of mailbox 1 fields is implementation specific.
739 // Adjust them as needed many even coming from user setting in setup.
741 //Workaround to solve LVDS is off after entering OS in desktop platform
743 mIgdOpRegion
.OpRegion
->MBox1
.CLID
= DxePlatformSaPolicy
->IgdPanelFeatures
.LidStatus
;
746 // Initialize OpRegion Mailbox 3 (ASLE Interrupt and Power Conservation).
748 //<TODO> The initial setting of mailbox 3 fields is implementation specific.
749 // Adjust them as needed many even coming from user setting in setup.
753 // Do not initialize TCHE. This field is written by the graphics driver only.
757 // The ALSI field is generally initialized by ASL code by reading the embedded controller.
760 mIgdOpRegion
.OpRegion
->MBox3
.BCLP
= BACKLIGHT_BRIGHTNESS
;
762 mIgdOpRegion
.OpRegion
->MBox3
.PFIT
= (FIELD_VALID_BIT
| PFIT_STRETCH
);
763 if ( DxePlatformSaPolicy
->IgdPanelFeatures
.PFITStatus
== 2) {
767 mIgdOpRegion
.OpRegion
->MBox3
.PFIT
= (FIELD_VALID_BIT
| PFIT_CENTER
);
768 } else if (DxePlatformSaPolicy
->IgdPanelFeatures
.PFITStatus
== 1) {
772 mIgdOpRegion
.OpRegion
->MBox3
.PFIT
= (FIELD_VALID_BIT
| PFIT_STRETCH
);
777 mIgdOpRegion
.OpRegion
->MBox3
.PFIT
= (FIELD_VALID_BIT
| PFIT_SETUP_AUTO
);
781 // Set Initial current Brightness
783 mIgdOpRegion
.OpRegion
->MBox3
.CBLV
= (INIT_BRIGHT_LEVEL
| FIELD_VALID_BIT
);
786 // <EXAMPLE> Create a static Backlight Brightness Level Duty cycle Mapping Table
787 // Possible 20 entries (example used 10), each 16 bits as follows:
788 // [15] = Field Valid bit, [14:08] = Level in Percentage (0-64h), [07:00] = Desired duty cycle (0 - FFh).
791 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[0] = ( ( 0 << 8 ) + ( 0xFF - 0xFC ) + WORD_FIELD_VALID_BIT
);
792 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[1] = ( ( 1 << 8 ) + ( 0xFF - 0xFC ) + WORD_FIELD_VALID_BIT
);
793 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[2] = ( ( 10 << 8 ) + ( 0xFF - 0xE5 ) + WORD_FIELD_VALID_BIT
);
794 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[3] = ( ( 19 << 8 ) + ( 0xFF - 0xCE ) + WORD_FIELD_VALID_BIT
);
795 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[4] = ( ( 28 << 8 ) + ( 0xFF - 0xB7 ) + WORD_FIELD_VALID_BIT
);
796 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[5] = ( ( 37 << 8 ) + ( 0xFF - 0xA0 ) + WORD_FIELD_VALID_BIT
);
797 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[6] = ( ( 46 << 8 ) + ( 0xFF - 0x89 ) + WORD_FIELD_VALID_BIT
);
798 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[7] = ( ( 55 << 8 ) + ( 0xFF - 0x72 ) + WORD_FIELD_VALID_BIT
);
799 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[8] = ( ( 64 << 8 ) + ( 0xFF - 0x5B ) + WORD_FIELD_VALID_BIT
);
800 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[9] = ( ( 73 << 8 ) + ( 0xFF - 0x44 ) + WORD_FIELD_VALID_BIT
);
801 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[10] = ( ( 82 << 8 ) + ( 0xFF - 0x2D ) + WORD_FIELD_VALID_BIT
);
802 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[11] = ( ( 91 << 8 ) + ( 0xFF - 0x16 ) + WORD_FIELD_VALID_BIT
);
803 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[12] = ( (100 << 8 ) + ( 0xFF - 0x00 ) + WORD_FIELD_VALID_BIT
);
805 mIgdOpRegion
.OpRegion
->MBox3
.PCFT
= ((UINT32
) GlobalNvsArea
->Area
->IgdPowerConservation
) | BIT31
;
807 // Create the notification and register callback function on the PciIo installation,
810 Status
= gBS
->CreateEvent (
813 (EFI_EVENT_NOTIFY
)GetVBiosVbtCallback
,
818 ASSERT_EFI_ERROR (Status
);
819 if (EFI_ERROR (Status
)) {
824 Status
= gBS
->RegisterProtocolNotify (
826 &gExitPmAuthProtocolGuid
,
828 &gEfiDxeSmmReadyToLockProtocolGuid
,
834 Status
= gBS
->CreateEvent (
837 (EFI_EVENT_NOTIFY
)SetGOPVersionCallback
,
842 ASSERT_EFI_ERROR (Status
);
843 if (EFI_ERROR (Status
)) {
847 Status
= gBS
->RegisterProtocolNotify (
848 &gEfiGraphicsOutputProtocolGuid
,
855 // Initialize hardware state:
856 // Set ASLS Register to the OpRegion physical memory address.
857 // Set SWSCI register bit 15 to a "1" to activate SCI interrupts.
860 IgdMmPci32 (IGD_ASLS_OFFSET
) = (UINT32
)(UINTN
)(mIgdOpRegion
.OpRegion
);
861 IgdMmPci16AndThenOr (IGD_SWSCI_OFFSET
, ~(BIT0
), BIT15
);
863 DwordData
= IgdMmPci32 (IGD_ASLS_OFFSET
);
864 S3BootScriptSavePciCfgWrite (
865 S3BootScriptWidthUint32
,
866 (UINTN
) (EFI_PCI_ADDRESS (IGD_BUS
, IGD_DEV
, IGD_FUN_0
, IGD_ASLS_OFFSET
)),
872 DwordData
= IgdMmPci32 (IGD_SWSCI_OFFSET
);
873 S3BootScriptSavePciCfgWrite (
874 S3BootScriptWidthUint32
,
875 (UINTN
) (EFI_PCI_ADDRESS (IGD_BUS
, IGD_DEV
, IGD_FUN_0
, IGD_SWSCI_OFFSET
)),
882 DEFAULT_PCI_BUS_NUMBER_PCH
,
883 PCI_DEVICE_NUMBER_PCH_LPC
,
884 PCI_FUNCTION_NUMBER_PCH_LPC
,
886 ) & B_PCH_LPC_ACPI_BASE_BAR
;
889 // Find the CPU I/O Protocol. ASSERT if not found.
891 Status
= gBS
->LocateProtocol (
892 &gEfiCpuIoProtocolGuid
,
896 ASSERT_EFI_ERROR (Status
);
901 AcpiBase
+ R_PCH_ACPI_GPE0a_STS
,
906 // Clear the B_PCH_ACPI_GPE0a_STS_GUNIT_SCI bit in R_PCH_ACPI_GPE0a_STS by writing a '1'.
908 Data16
|= B_PCH_ACPI_GPE0a_STS_GUNIT_SCI
;
913 AcpiBase
+ R_PCH_ACPI_GPE0a_STS
,
919 // Install OpRegion / Software SCI protocol
922 Status
= gBS
->InstallMultipleProtocolInterfaces (
924 &gIgdOpRegionProtocolGuid
,
928 ASSERT_EFI_ERROR (Status
);
931 // Return final status