4 Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved
6 SPDX-License-Identifier: BSD-2-Clause-Patent
17 This is part of the implementation of an Intel Graphics drivers OpRegion /
18 Software SCI interface between system BIOS, ASL code, and Graphics drivers.
19 The code in this file will load the driver and initialize the interface
21 Supporting Specifiction: OpRegion / Software SCI SPEC 0.70
24 IGD: Internal Graphics Device
25 NVS: ACPI Non Volatile Storage
26 OpRegion: ACPI Operational Region
27 VBT: Video BIOS Table (OEM customizable data)
36 #include "IgdOpRegion.h"
37 #include "VlvPlatformInit.h"
38 #include <FrameworkDxe.h>
42 #include <Guid/DataHubRecords.h>
44 #include <Protocol/IgdOpRegion.h>
45 #include <Protocol/FrameworkHii.h>
46 #include <Protocol/FirmwareVolume2.h>
47 #include <Protocol/PlatformGopPolicy.h>
48 #include <Protocol/PciIo.h>
49 #include <Protocol/CpuIo.h>
50 #include <Protocol/GlobalNvsArea.h>
51 #include <Protocol/DxeSmmReadyToLock.h>
52 #include <Protocol/PciRootBridgeIo.h>
54 #include <Library/MemoryAllocationLib.h>
55 #include <Library/BaseLib.h>
56 #include <Library/S3BootScriptLib.h>
57 #include <Library/IoLib.h>
58 #include <Library/DevicePathLib.h>
59 #include <Protocol/DriverBinding.h>
60 #include <Library/PrintLib.h>
61 #include <Library/BaseMemoryLib.h>
65 UINT8 gSVER
[12] = "Intel";
67 extern DXE_VLV_PLATFORM_POLICY_PROTOCOL
*DxePlatformSaPolicy
;
73 IGD_OPREGION_PROTOCOL mIgdOpRegion
;
74 EFI_GUID mMiscSubClass
= EFI_MISC_SUBCLASS_GUID
;
75 EFI_EVENT mConOutEvent
;
76 EFI_EVENT mSetGOPverEvent
;
79 #define DEFAULT_FORM_BUFFER_SIZE 0xFFFF
84 Get the HII protocol interface
86 @param Hii HII protocol interface
94 OUT EFI_HII_PROTOCOL
**Hii
100 // There should only be one HII protocol
102 Status
= gBS
->LocateProtocol (
103 &gEfiHiiProtocolGuid
,
117 @param[in] VbtFileBuffer Pointer to VBT data buffer.
119 @retval EFI_SUCCESS VBT data was returned.
120 @retval EFI_NOT_FOUND VBT data not found.
121 @exception EFI_UNSUPPORTED Invalid signature in VBT data.
125 GetIntegratedIntelVbtPtr (
126 OUT VBIOS_VBT_STRUCTURE
**VbtFileBuffer
130 EFI_PHYSICAL_ADDRESS VbtAddress
= 0;
131 UINTN FvProtocolCount
;
132 EFI_HANDLE
*FvHandles
;
133 EFI_FIRMWARE_VOLUME2_PROTOCOL
*Fv
;
135 UINT32 AuthenticationStatus
;
138 UINTN VbtBufferSize
= 0;
142 *VbtFileBuffer
= NULL
;
143 Status
= gBS
->LocateHandleBuffer (
145 &gEfiFirmwareVolume2ProtocolGuid
,
151 if (!EFI_ERROR (Status
)) {
152 for (Index
= 0; Index
< FvProtocolCount
; Index
++) {
153 Status
= gBS
->HandleProtocol (
155 &gEfiFirmwareVolume2ProtocolGuid
,
159 Status
= Fv
->ReadSection (
166 &AuthenticationStatus
169 if (!EFI_ERROR (Status
)) {
170 VbtAddress
= (EFI_PHYSICAL_ADDRESS
)(UINTN
)Buffer
;
171 Status
= EFI_SUCCESS
;
176 Status
= EFI_NOT_FOUND
;
179 if (FvHandles
!= NULL
) {
186 // Check VBT signature
188 *VbtFileBuffer
= (VBIOS_VBT_STRUCTURE
*) (UINTN
) VbtAddress
;
189 if (*VbtFileBuffer
!= NULL
) {
190 if ((*((UINT32
*) ((*VbtFileBuffer
)->HeaderSignature
))) != VBT_SIGNATURE
) {
191 if (*VbtFileBuffer
!= NULL
) {
192 *VbtFileBuffer
= NULL
;
194 return EFI_UNSUPPORTED
;
199 if ((*VbtFileBuffer
)->HeaderVbtSize
> VbtBufferSize
) {
200 (*VbtFileBuffer
)->HeaderVbtSize
= (UINT16
) VbtBufferSize
;
208 // Function implementations.
212 Get a pointer to an uncompressed image of the Intel video BIOS.
214 Note: This function would only be called if the video BIOS at 0xC000 is
215 missing or not an Intel video BIOS. It may not be an Intel video BIOS
216 if the Intel graphic contoller is considered a secondary adapter.
219 @param VBiosROMImage Pointer to an uncompressed Intel video BIOS. This pointer must
220 be set to NULL if an uncompressed image of the Intel Video BIOS
224 @retval EFI_SUCCESS VBiosPtr is updated.
228 GetIntegratedIntelVBiosPtr (
229 INTEL_VBIOS_OPTION_ROM_HEADER
**VBiosImage
232 EFI_HANDLE
*HandleBuffer
;
235 INTEL_VBIOS_PCIR_STRUCTURE
*PcirBlockPtr
;
237 EFI_PCI_IO_PROTOCOL
*PciIo
;
238 INTEL_VBIOS_OPTION_ROM_HEADER
*VBiosRomImage
;
241 // Set as if an umcompressed Intel video BIOS image was not obtainable.
243 VBiosRomImage
= NULL
;
247 // Get all PCI IO protocols
249 Status
= gBS
->LocateHandleBuffer (
251 &gEfiPciIoProtocolGuid
,
256 ASSERT_EFI_ERROR (Status
);
259 // Find the video BIOS by checking each PCI IO handle for an Intel video
262 for (Index
= 0; Index
< HandleCount
; Index
++) {
263 Status
= gBS
->HandleProtocol (
265 &gEfiPciIoProtocolGuid
,
268 ASSERT_EFI_ERROR (Status
);
270 VBiosRomImage
= PciIo
->RomImage
;
273 // If this PCI device doesn't have a ROM image, skip to the next device.
275 if (!VBiosRomImage
) {
280 // Get pointer to PCIR structure
282 PcirBlockPtr
= (INTEL_VBIOS_PCIR_STRUCTURE
*)((UINT8
*) VBiosRomImage
+ VBiosRomImage
->PcirOffset
);
285 // Check if we have an Intel video BIOS OPROM.
287 if ((VBiosRomImage
->Signature
== OPTION_ROM_SIGNATURE
) &&
288 (PcirBlockPtr
->VendorId
== IGD_VID
) &&
289 (PcirBlockPtr
->ClassCode
[0] == 0x00) &&
290 (PcirBlockPtr
->ClassCode
[1] == 0x00) &&
291 (PcirBlockPtr
->ClassCode
[2] == 0x03)
294 // Found Intel video BIOS.
296 *VBiosImage
= VBiosRomImage
;
302 // No Intel video BIOS found.
306 // Free any allocated buffers
308 return EFI_UNSUPPORTED
;
319 EFI_GUID
**ProtocolGuidArray
= NULL
;
324 EFI_OPEN_PROTOCOL_INFORMATION_ENTRY
*OpenInfo
= NULL
;
326 EFI_HANDLE
*mHandleBuffer
= NULL
;
329 // Retrieve the list of all handles from the handle database
331 Status
= gBS
->LocateHandleBuffer (
339 for (HandleIndex
= 0; HandleIndex
< mHandleCount
; HandleIndex
++) {
341 // Retrieve the list of all the protocols on each handle
343 Status
= gBS
->ProtocolsPerHandle (
344 mHandleBuffer
[HandleIndex
],
348 if (!EFI_ERROR (Status
)) {
349 for (ProtocolIndex
= 0; ProtocolIndex
< ArrayCount
; ProtocolIndex
++) {
350 Status
= gBS
->OpenProtocolInformation (
351 mHandleBuffer
[HandleIndex
],
352 ProtocolGuidArray
[ProtocolIndex
],
356 if (!EFI_ERROR (Status
)) {
357 for (OpenInfoIndex
= 0; OpenInfoIndex
< OpenInfoCount
; OpenInfoIndex
++) {
358 if(OpenInfo
[OpenInfoIndex
].AgentHandle
== Father
) {
359 if ((OpenInfo
[OpenInfoIndex
].Attributes
& EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
) {
360 *Child
= mHandleBuffer
[HandleIndex
];
361 Status
= EFI_SUCCESS
;
366 Status
= EFI_NOT_FOUND
;
369 if(OpenInfo
!= NULL
) {
374 FreePool (ProtocolGuidArray
);
375 ProtocolGuidArray
= NULL
;
378 if(OpenInfo
!= NULL
) {
382 if(ProtocolGuidArray
!= NULL
) {
383 FreePool(ProtocolGuidArray
);
384 ProtocolGuidArray
= NULL
;
386 if(mHandleBuffer
!= NULL
) {
387 FreePool (mHandleBuffer
);
388 mHandleBuffer
= NULL
;
394 JudgeHandleIsPCIDevice(
401 EFI_DEVICE_PATH
*DPath
;
403 Status
= gBS
->HandleProtocol (
405 &gEfiDevicePathProtocolGuid
,
408 if(!EFI_ERROR(Status
)) {
409 while(!IsDevicePathEnd(DPath
)) {
410 if((DPath
->Type
== HARDWARE_DEVICE_PATH
) && (DPath
->SubType
== HW_PCI_DP
)) {
411 PCI_DEVICE_PATH
*PCIPath
;
413 PCIPath
= (PCI_DEVICE_PATH
*) DPath
;
414 DPath
= NextDevicePathNode(DPath
);
415 if(IsDevicePathEnd(DPath
) && (PCIPath
->Device
== Device
) && (PCIPath
->Function
== Funs
)) {
419 DPath
= NextDevicePathNode(DPath
);
423 return EFI_UNSUPPORTED
;
432 EFI_DRIVER_BINDING_PROTOCOL
*BindHandle
= NULL
;
437 Status
= gBS
->OpenProtocol(
439 &gEfiDriverBindingProtocolGuid
,
443 EFI_OPEN_PROTOCOL_GET_PROTOCOL
445 if (EFI_ERROR(Status
)) {
446 return EFI_NOT_FOUND
;
449 Version
= BindHandle
->Version
;
450 Ptr
= (UINT16
*)&Version
;
451 UnicodeSPrint(GopVersion
, 40, L
"7.0.%04d", *(Ptr
));
461 EFI_HANDLE
*Handles
= NULL
;
464 EFI_HANDLE Child
= 0;
466 Status
= gBS
->LocateHandleBuffer(
468 &gEfiDriverBindingProtocolGuid
,
473 for (Index
= 0; Index
< HandleCount
; Index
++) {
474 Status
= SearchChildHandle(Handles
[Index
], &Child
);
475 if(!EFI_ERROR(Status
)) {
476 Status
= JudgeHandleIsPCIDevice(Child
, 0x02, 0x00);
477 if(!EFI_ERROR(Status
)) {
478 return GetDriverName(Handles
[Index
], GopVersion
);
482 return EFI_UNSUPPORTED
;
487 Get Intel GOP driver version and copy it into IGD OpRegion GVER. This version
488 is picked up by IGD driver and displayed in CUI.
490 @param Event A pointer to the Event that triggered the callback.
491 @param Context A pointer to private data registered with the callback function.
493 @retval EFI_SUCCESS Video BIOS VBT information returned.
494 @retval EFI_UNSUPPORTED Could not find VBT information (*VBiosVbtPtr = NULL).
499 SetGOPVersionCallback (
504 CHAR16 GopVersion
[16] = {0};
507 Status
= GetGOPDriverVersion(GopVersion
);
508 if(!EFI_ERROR(Status
)) {
509 StrCpy((CHAR16
*)&(mIgdOpRegion
.OpRegion
->Header
.GOPV
[0]), GopVersion
);
512 return EFI_UNSUPPORTED
;
516 Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).
517 The VBT (Video BIOS Table) is a block of customizable data that is built
518 within the video BIOS and edited by customers.
520 @param Event A pointer to the Event that triggered the callback.
521 @param Context A pointer to private data registered with the callback function.
523 @retval EFI_SUCCESS Video BIOS VBT information returned.
524 @retval EFI_UNSUPPORTED Could not find VBT information (*VBiosVbtPtr = NULL).
528 GetVBiosVbtCallback (
533 INTEL_VBIOS_PCIR_STRUCTURE
*PcirBlockPtr
;
536 INTEL_VBIOS_OPTION_ROM_HEADER
*VBiosPtr
;
537 VBIOS_VBT_STRUCTURE
*VBiosVbtPtr
;
538 VBIOS_VBT_STRUCTURE
*VbtFileBuffer
= NULL
;
540 VBiosPtr
= (INTEL_VBIOS_OPTION_ROM_HEADER
*)(UINTN
)(VBIOS_LOCATION_PRIMARY
);
541 PcirBlockPtr
= (INTEL_VBIOS_PCIR_STRUCTURE
*)((UINT8
*)VBiosPtr
+ VBiosPtr
->PcirOffset
);
542 PciVenderId
= PcirBlockPtr
->VendorId
;
543 PciDeviceId
= PcirBlockPtr
->DeviceId
;
546 // If the video BIOS is not at 0xC0000 or it is not an Intel video BIOS get
547 // the integrated Intel video BIOS (must be uncompressed).
549 if ((VBiosPtr
->Signature
!= OPTION_ROM_SIGNATURE
) || (PciVenderId
!= IGD_VID
) || (PciDeviceId
!= IGD_DID_VLV
)) {
550 GetIntegratedIntelVBiosPtr (&VBiosPtr
);
556 PcirBlockPtr
= (INTEL_VBIOS_PCIR_STRUCTURE
*)((UINT8
*)VBiosPtr
+ VBiosPtr
->PcirOffset
);
557 PciVenderId
= PcirBlockPtr
->VendorId
;
558 if( (VBiosPtr
->Signature
!= OPTION_ROM_SIGNATURE
) || (PciVenderId
!= IGD_VID
)) {
560 // Intel video BIOS not found.
563 return EFI_UNSUPPORTED
;
567 // No Video BIOS found, try to get VBT from FV.
569 GetIntegratedIntelVbtPtr (&VbtFileBuffer
);
570 if (VbtFileBuffer
!= NULL
) {
572 // Video BIOS not found, use VBT from FV
574 DEBUG ((EFI_D_ERROR
, "VBT data found\n"));
576 mIgdOpRegion
.OpRegion
->VBT
.GVD1
,
578 VbtFileBuffer
->HeaderVbtSize
580 FreePool (VbtFileBuffer
);
584 if ((VBiosPtr
== NULL
) ) {
586 // Intel video BIOS not found.
589 return EFI_UNSUPPORTED
;
593 DEBUG ((EFI_D_ERROR
, "VBIOS found at 0x%X\n", VBiosPtr
));
594 VBiosVbtPtr
= (VBIOS_VBT_STRUCTURE
*) ((UINT8
*) VBiosPtr
+ VBiosPtr
->VbtOffset
);
596 if ((*((UINT32
*) (VBiosVbtPtr
->HeaderSignature
))) != VBT_SIGNATURE
) {
597 return EFI_UNSUPPORTED
;
601 // Initialize Video BIOS version with its build number.
603 mIgdOpRegion
.OpRegion
->Header
.VVER
[0] = VBiosVbtPtr
->CoreBlockBiosBuild
[0];
604 mIgdOpRegion
.OpRegion
->Header
.VVER
[1] = VBiosVbtPtr
->CoreBlockBiosBuild
[1];
605 mIgdOpRegion
.OpRegion
->Header
.VVER
[2] = VBiosVbtPtr
->CoreBlockBiosBuild
[2];
606 mIgdOpRegion
.OpRegion
->Header
.VVER
[3] = VBiosVbtPtr
->CoreBlockBiosBuild
[3];
608 mIgdOpRegion
.OpRegion
->VBT
.GVD1
,
610 VBiosVbtPtr
->HeaderVbtSize
614 // Return final status
620 Graphics OpRegion / Software SCI driver installation function.
622 @param ImageHandle Handle for this drivers loaded image protocol.
623 @param SystemTable EFI system table.
625 @retval EFI_SUCCESS The driver installed without error.
626 @retval EFI_ABORTED The driver encountered an error and could not complete
627 installation of the ACPI tables.
637 EFI_GLOBAL_NVS_AREA_PROTOCOL
*GlobalNvsArea
;
639 EFI_CPU_IO_PROTOCOL
*CpuIo
;
642 VOID
*gConOutNotifyReg
;
646 // Locate the Global NVS Protocol.
648 Status
= gBS
->LocateProtocol (
649 &gEfiGlobalNvsAreaProtocolGuid
,
651 (void **)&GlobalNvsArea
653 ASSERT_EFI_ERROR (Status
);
656 // Allocate an ACPI NVS memory buffer as the IGD OpRegion, zero initialize
657 // the first 1K, and set the IGD OpRegion pointer in the Global NVS
660 Status
= (gBS
->AllocatePool
) (
662 sizeof (IGD_OPREGION_STRUC
),
663 (void **)&mIgdOpRegion
.OpRegion
665 ASSERT_EFI_ERROR (Status
);
667 mIgdOpRegion
.OpRegion
,
668 sizeof (IGD_OPREGION_STRUC
),
671 GlobalNvsArea
->Area
->IgdOpRegionAddress
= (UINT32
)(UINTN
)(mIgdOpRegion
.OpRegion
);
674 // If IGD is disabled return
676 if (IgdMmPci32 (0) == 0xFFFFFFFF) {
681 // Initialize OpRegion Header
685 mIgdOpRegion
.OpRegion
->Header
.SIGN
,
687 sizeof(HEADER_SIGNATURE
)
692 // Set OpRegion Size in KBs
694 mIgdOpRegion
.OpRegion
->Header
.SIZE
= HEADER_SIZE
/1024;
697 // FIXME: Need to check Header OVER Field and the supported version.
699 mIgdOpRegion
.OpRegion
->Header
.OVER
= (UINT32
) (LShiftU64 (HEADER_OPREGION_VER
, 16) + LShiftU64 (HEADER_OPREGION_REV
, 8));
701 CopyMem(mIgdOpRegion
.OpRegion
->Header
.SVER
, gSVER
, sizeof(gSVER
));
704 mIgdOpRegion
.OpRegion
->Header
.SVER
,
709 DEBUG ((EFI_D_ERROR
, "System BIOS ID is %a\n", mIgdOpRegion
.OpRegion
->Header
.SVER
));
712 mIgdOpRegion
.OpRegion
->Header
.MBOX
= HEADER_MBOX_SUPPORT
;
714 if( 1 == DxePlatformSaPolicy
->IdleReserve
) {
715 mIgdOpRegion
.OpRegion
->Header
.PCON
= (mIgdOpRegion
.OpRegion
->Header
.PCON
& 0xFFFC) | BIT1
;
717 mIgdOpRegion
.OpRegion
->Header
.PCON
= (mIgdOpRegion
.OpRegion
->Header
.PCON
& 0xFFFC) | (BIT1
| BIT0
);
721 //For graphics driver to identify if LPE Audio/HD Audio is enabled on the platform
723 mIgdOpRegion
.OpRegion
->Header
.PCON
&= AUDIO_TYPE_SUPPORT_MASK
;
724 mIgdOpRegion
.OpRegion
->Header
.PCON
&= AUDIO_TYPE_FIELD_MASK
;
725 if ( 1 == DxePlatformSaPolicy
->AudioTypeSupport
) {
726 mIgdOpRegion
.OpRegion
->Header
.PCON
= HD_AUDIO_SUPPORT
;
727 mIgdOpRegion
.OpRegion
->Header
.PCON
|= AUDIO_TYPE_FIELD_VALID
;
731 // Initialize OpRegion Mailbox 1 (Public ACPI Methods).
733 //<TODO> The initial setting of mailbox 1 fields is implementation specific.
734 // Adjust them as needed many even coming from user setting in setup.
736 //Workaround to solve LVDS is off after entering OS in desktop platform
738 mIgdOpRegion
.OpRegion
->MBox1
.CLID
= DxePlatformSaPolicy
->IgdPanelFeatures
.LidStatus
;
741 // Initialize OpRegion Mailbox 3 (ASLE Interrupt and Power Conservation).
743 //<TODO> The initial setting of mailbox 3 fields is implementation specific.
744 // Adjust them as needed many even coming from user setting in setup.
748 // Do not initialize TCHE. This field is written by the graphics driver only.
752 // The ALSI field is generally initialized by ASL code by reading the embedded controller.
755 mIgdOpRegion
.OpRegion
->MBox3
.BCLP
= BACKLIGHT_BRIGHTNESS
;
757 mIgdOpRegion
.OpRegion
->MBox3
.PFIT
= (FIELD_VALID_BIT
| PFIT_STRETCH
);
758 if ( DxePlatformSaPolicy
->IgdPanelFeatures
.PFITStatus
== 2) {
762 mIgdOpRegion
.OpRegion
->MBox3
.PFIT
= (FIELD_VALID_BIT
| PFIT_CENTER
);
763 } else if (DxePlatformSaPolicy
->IgdPanelFeatures
.PFITStatus
== 1) {
767 mIgdOpRegion
.OpRegion
->MBox3
.PFIT
= (FIELD_VALID_BIT
| PFIT_STRETCH
);
772 mIgdOpRegion
.OpRegion
->MBox3
.PFIT
= (FIELD_VALID_BIT
| PFIT_SETUP_AUTO
);
776 // Set Initial current Brightness
778 mIgdOpRegion
.OpRegion
->MBox3
.CBLV
= (INIT_BRIGHT_LEVEL
| FIELD_VALID_BIT
);
781 // <EXAMPLE> Create a static Backlight Brightness Level Duty cycle Mapping Table
782 // Possible 20 entries (example used 10), each 16 bits as follows:
783 // [15] = Field Valid bit, [14:08] = Level in Percentage (0-64h), [07:00] = Desired duty cycle (0 - FFh).
786 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[0] = ( ( 0 << 8 ) + ( 0xFF - 0xFC ) + WORD_FIELD_VALID_BIT
);
787 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[1] = ( ( 1 << 8 ) + ( 0xFF - 0xFC ) + WORD_FIELD_VALID_BIT
);
788 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[2] = ( ( 10 << 8 ) + ( 0xFF - 0xE5 ) + WORD_FIELD_VALID_BIT
);
789 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[3] = ( ( 19 << 8 ) + ( 0xFF - 0xCE ) + WORD_FIELD_VALID_BIT
);
790 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[4] = ( ( 28 << 8 ) + ( 0xFF - 0xB7 ) + WORD_FIELD_VALID_BIT
);
791 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[5] = ( ( 37 << 8 ) + ( 0xFF - 0xA0 ) + WORD_FIELD_VALID_BIT
);
792 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[6] = ( ( 46 << 8 ) + ( 0xFF - 0x89 ) + WORD_FIELD_VALID_BIT
);
793 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[7] = ( ( 55 << 8 ) + ( 0xFF - 0x72 ) + WORD_FIELD_VALID_BIT
);
794 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[8] = ( ( 64 << 8 ) + ( 0xFF - 0x5B ) + WORD_FIELD_VALID_BIT
);
795 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[9] = ( ( 73 << 8 ) + ( 0xFF - 0x44 ) + WORD_FIELD_VALID_BIT
);
796 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[10] = ( ( 82 << 8 ) + ( 0xFF - 0x2D ) + WORD_FIELD_VALID_BIT
);
797 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[11] = ( ( 91 << 8 ) + ( 0xFF - 0x16 ) + WORD_FIELD_VALID_BIT
);
798 mIgdOpRegion
.OpRegion
->MBox3
.BCLM
[12] = ( (100 << 8 ) + ( 0xFF - 0x00 ) + WORD_FIELD_VALID_BIT
);
800 mIgdOpRegion
.OpRegion
->MBox3
.PCFT
= ((UINT32
) GlobalNvsArea
->Area
->IgdPowerConservation
) | BIT31
;
802 // Create the notification and register callback function on the PciIo installation,
805 Status
= gBS
->CreateEvent (
808 (EFI_EVENT_NOTIFY
)GetVBiosVbtCallback
,
813 ASSERT_EFI_ERROR (Status
);
814 if (EFI_ERROR (Status
)) {
819 Status
= gBS
->RegisterProtocolNotify (
821 &gExitPmAuthProtocolGuid
,
823 &gEfiDxeSmmReadyToLockProtocolGuid
,
829 Status
= gBS
->CreateEvent (
832 (EFI_EVENT_NOTIFY
)SetGOPVersionCallback
,
837 ASSERT_EFI_ERROR (Status
);
838 if (EFI_ERROR (Status
)) {
842 Status
= gBS
->RegisterProtocolNotify (
843 &gEfiGraphicsOutputProtocolGuid
,
850 // Initialize hardware state:
851 // Set ASLS Register to the OpRegion physical memory address.
852 // Set SWSCI register bit 15 to a "1" to activate SCI interrupts.
855 IgdMmPci32 (IGD_ASLS_OFFSET
) = (UINT32
)(UINTN
)(mIgdOpRegion
.OpRegion
);
856 IgdMmPci16AndThenOr (IGD_SWSCI_OFFSET
, ~(BIT0
), BIT15
);
858 DwordData
= IgdMmPci32 (IGD_ASLS_OFFSET
);
859 S3BootScriptSavePciCfgWrite (
860 S3BootScriptWidthUint32
,
861 (UINTN
) (EFI_PCI_ADDRESS (IGD_BUS
, IGD_DEV
, IGD_FUN_0
, IGD_ASLS_OFFSET
)),
867 DwordData
= IgdMmPci32 (IGD_SWSCI_OFFSET
);
868 S3BootScriptSavePciCfgWrite (
869 S3BootScriptWidthUint32
,
870 (UINTN
) (EFI_PCI_ADDRESS (IGD_BUS
, IGD_DEV
, IGD_FUN_0
, IGD_SWSCI_OFFSET
)),
877 DEFAULT_PCI_BUS_NUMBER_PCH
,
878 PCI_DEVICE_NUMBER_PCH_LPC
,
879 PCI_FUNCTION_NUMBER_PCH_LPC
,
881 ) & B_PCH_LPC_ACPI_BASE_BAR
;
884 // Find the CPU I/O Protocol. ASSERT if not found.
886 Status
= gBS
->LocateProtocol (
887 &gEfiCpuIoProtocolGuid
,
891 ASSERT_EFI_ERROR (Status
);
896 AcpiBase
+ R_PCH_ACPI_GPE0a_STS
,
901 // Clear the B_PCH_ACPI_GPE0a_STS_GUNIT_SCI bit in R_PCH_ACPI_GPE0a_STS by writing a '1'.
903 Data16
|= B_PCH_ACPI_GPE0a_STS_GUNIT_SCI
;
908 AcpiBase
+ R_PCH_ACPI_GPE0a_STS
,
914 // Install OpRegion / Software SCI protocol
917 Status
= gBS
->InstallMultipleProtocolInterfaces (
919 &gIgdOpRegionProtocolGuid
,
923 ASSERT_EFI_ERROR (Status
);
926 // Return final status