+++ /dev/null
-\r
-/*++\r
-\r
-Copyright (c) 2011 - 2018, Intel Corporation. All rights reserved\r
- \r\r
- SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
- \r\r
-\r
-\r
-Module Name:\r
-\r
- IgdOpRegion.c\r
-\r
-Abstract:\r
-\r
- This is part of the implementation of an Intel Graphics drivers OpRegion /\r
- Software SCI interface between system BIOS, ASL code, and Graphics drivers.\r
- The code in this file will load the driver and initialize the interface\r
-\r
- Supporting Specifiction: OpRegion / Software SCI SPEC 0.70\r
-\r
- Acronyms:\r
- IGD: Internal Graphics Device\r
- NVS: ACPI Non Volatile Storage\r
- OpRegion: ACPI Operational Region\r
- VBT: Video BIOS Table (OEM customizable data)\r
-\r
---*/\r
-\r
-//\r
-// Include files\r
-//\r
-\r
-\r
-#include "IgdOpRegion.h"\r
-#include "VlvPlatformInit.h"\r
-#include <FrameworkDxe.h>\r
-#include <Uefi.h>\r
-#include <PchRegs.h>\r
-\r
-#include <Guid/DataHubRecords.h>\r
-\r
-#include <Protocol/IgdOpRegion.h>\r
-#include <Protocol/FrameworkHii.h>\r
-#include <Protocol/FirmwareVolume2.h>\r
-#include <Protocol/PlatformGopPolicy.h>\r
-#include <Protocol/PciIo.h>\r
-#include <Protocol/CpuIo.h>\r
-#include <Protocol/GlobalNvsArea.h>\r
-#include <Protocol/DxeSmmReadyToLock.h>\r
-#include <Protocol/PciRootBridgeIo.h>\r
-\r
-#include <Library/MemoryAllocationLib.h>\r
-#include <Library/BaseLib.h>\r
-#include <Library/S3BootScriptLib.h>\r
-#include <Library/IoLib.h>\r
-#include <Library/DevicePathLib.h>\r
-#include <Protocol/DriverBinding.h>\r
-#include <Library/PrintLib.h>\r
-#include <Library/BaseMemoryLib.h>\r
-\r
-\r
-\r
-UINT8 gSVER[12] = "Intel";\r
-\r
-extern DXE_VLV_PLATFORM_POLICY_PROTOCOL *DxePlatformSaPolicy;\r
-\r
-//\r
-// Global variables\r
-//\r
-\r
-IGD_OPREGION_PROTOCOL mIgdOpRegion;\r
-EFI_GUID mMiscSubClass = EFI_MISC_SUBCLASS_GUID;\r
-EFI_EVENT mConOutEvent;\r
-EFI_EVENT mSetGOPverEvent;\r
-VOID *mConOutReg;\r
-\r
-#define DEFAULT_FORM_BUFFER_SIZE 0xFFFF\r
-#ifndef ECP_FLAG\r
-#if 0\r
-/**\r
-\r
- Get the HII protocol interface\r
-\r
- @param Hii HII protocol interface\r
-\r
- @retval Status code\r
-\r
-**/\r
-static\r
-EFI_STATUS\r
-GetHiiInterface (\r
- OUT EFI_HII_PROTOCOL **Hii\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- //\r
- // There should only be one HII protocol\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiHiiProtocolGuid,\r
- NULL,\r
- (VOID **) Hii\r
- );\r
-\r
- return Status;;\r
-}\r
-#endif\r
-#endif\r
-\r
-/**\r
-\r
- Get VBT data.\r
-\r
- @param[in] VbtFileBuffer Pointer to VBT data buffer.\r
-\r
- @retval EFI_SUCCESS VBT data was returned.\r
- @retval EFI_NOT_FOUND VBT data not found.\r
- @exception EFI_UNSUPPORTED Invalid signature in VBT data.\r
-\r
-**/\r
-EFI_STATUS\r
-GetIntegratedIntelVbtPtr (\r
- OUT VBIOS_VBT_STRUCTURE **VbtFileBuffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_PHYSICAL_ADDRESS VbtAddress = 0;\r
- UINTN FvProtocolCount;\r
- EFI_HANDLE *FvHandles;\r
- EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv;\r
- UINTN Index;\r
- UINT32 AuthenticationStatus;\r
-\r
- UINT8 *Buffer;\r
- UINTN VbtBufferSize = 0;\r
-\r
- Buffer = 0;\r
- FvHandles = NULL;\r
- *VbtFileBuffer = NULL;\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiFirmwareVolume2ProtocolGuid,\r
- NULL,\r
- &FvProtocolCount,\r
- &FvHandles\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- for (Index = 0; Index < FvProtocolCount; Index++) {\r
- Status = gBS->HandleProtocol (\r
- FvHandles[Index],\r
- &gEfiFirmwareVolume2ProtocolGuid,\r
- (VOID **) &Fv\r
- );\r
- VbtBufferSize = 0;\r
- Status = Fv->ReadSection (\r
- Fv,\r
- &gBmpImageGuid,\r
- EFI_SECTION_RAW,\r
- 0,\r
- (void **)&Buffer,\r
- &VbtBufferSize,\r
- &AuthenticationStatus\r
- );\r
-\r
- if (!EFI_ERROR (Status)) {\r
- VbtAddress = (EFI_PHYSICAL_ADDRESS)(UINTN)Buffer;\r
- Status = EFI_SUCCESS;\r
- break;\r
- }\r
- }\r
- } else {\r
- Status = EFI_NOT_FOUND;\r
- }\r
-\r
- if (FvHandles != NULL) {\r
- FreePool(FvHandles);\r
- FvHandles = NULL;\r
- }\r
-\r
-\r
- //\r
- // Check VBT signature\r
- //\r
- *VbtFileBuffer = (VBIOS_VBT_STRUCTURE *) (UINTN) VbtAddress;\r
- if (*VbtFileBuffer != NULL) {\r
- if ((*((UINT32 *) ((*VbtFileBuffer)->HeaderSignature))) != VBT_SIGNATURE) {\r
- if (*VbtFileBuffer != NULL) {\r
- *VbtFileBuffer = NULL;\r
- }\r
- return EFI_UNSUPPORTED;\r
- }\r
- //\r
- // Check VBT size\r
- //\r
- if ((*VbtFileBuffer)->HeaderVbtSize > VbtBufferSize) {\r
- (*VbtFileBuffer)->HeaderVbtSize = (UINT16) VbtBufferSize;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-//\r
-// Function implementations.\r
-//\r
-/**\r
-\r
- Get a pointer to an uncompressed image of the Intel video BIOS.\r
-\r
- Note: This function would only be called if the video BIOS at 0xC000 is\r
- missing or not an Intel video BIOS. It may not be an Intel video BIOS\r
- if the Intel graphic contoller is considered a secondary adapter.\r
-\r
-\r
- @param VBiosROMImage Pointer to an uncompressed Intel video BIOS. This pointer must\r
- be set to NULL if an uncompressed image of the Intel Video BIOS\r
- is not obtainable.\r
-\r
-\r
- @retval EFI_SUCCESS VBiosPtr is updated.\r
-\r
-**/\r
-EFI_STATUS\r
-GetIntegratedIntelVBiosPtr (\r
- INTEL_VBIOS_OPTION_ROM_HEADER **VBiosImage\r
- )\r
-{\r
- EFI_HANDLE *HandleBuffer;\r
- UINTN HandleCount;\r
- UINTN Index;\r
- INTEL_VBIOS_PCIR_STRUCTURE *PcirBlockPtr;\r
- EFI_STATUS Status;\r
- EFI_PCI_IO_PROTOCOL *PciIo;\r
- INTEL_VBIOS_OPTION_ROM_HEADER *VBiosRomImage;\r
-\r
- //\r
- // Set as if an umcompressed Intel video BIOS image was not obtainable.\r
- //\r
- VBiosRomImage = NULL;\r
- *VBiosImage = NULL;\r
-\r
- //\r
- // Get all PCI IO protocols\r
- //\r
- Status = gBS->LocateHandleBuffer (\r
- ByProtocol,\r
- &gEfiPciIoProtocolGuid,\r
- NULL,\r
- &HandleCount,\r
- &HandleBuffer\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Find the video BIOS by checking each PCI IO handle for an Intel video\r
- // BIOS OPROM.\r
- //\r
- for (Index = 0; Index < HandleCount; Index++) {\r
- Status = gBS->HandleProtocol (\r
- HandleBuffer[Index],\r
- &gEfiPciIoProtocolGuid,\r
- (void **)&PciIo\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- VBiosRomImage = PciIo->RomImage;\r
-\r
- //\r
- // If this PCI device doesn't have a ROM image, skip to the next device.\r
- //\r
- if (!VBiosRomImage) {\r
- continue;\r
- }\r
-\r
- //\r
- // Get pointer to PCIR structure\r
- //\r
- PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *)((UINT8 *) VBiosRomImage + VBiosRomImage->PcirOffset);\r
-\r
- //\r
- // Check if we have an Intel video BIOS OPROM.\r
- //\r
- if ((VBiosRomImage->Signature == OPTION_ROM_SIGNATURE) &&\r
- (PcirBlockPtr->VendorId == IGD_VID) &&\r
- (PcirBlockPtr->ClassCode[0] == 0x00) &&\r
- (PcirBlockPtr->ClassCode[1] == 0x00) &&\r
- (PcirBlockPtr->ClassCode[2] == 0x03)\r
- ) {\r
- //\r
- // Found Intel video BIOS.\r
- //\r
- *VBiosImage = VBiosRomImage;\r
- return EFI_SUCCESS;\r
- }\r
- }\r
-\r
- //\r
- // No Intel video BIOS found.\r
- //\r
-\r
- //\r
- // Free any allocated buffers\r
- //\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-EFI_STATUS\r
-SearchChildHandle(\r
- EFI_HANDLE Father,\r
- EFI_HANDLE *Child\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN HandleIndex;\r
- EFI_GUID **ProtocolGuidArray = NULL;\r
- UINTN ArrayCount;\r
- UINTN ProtocolIndex;\r
- UINTN OpenInfoCount;\r
- UINTN OpenInfoIndex;\r
- EFI_OPEN_PROTOCOL_INFORMATION_ENTRY *OpenInfo = NULL;\r
- UINTN mHandleCount;\r
- EFI_HANDLE *mHandleBuffer= NULL;\r
-\r
- //\r
- // Retrieve the list of all handles from the handle database\r
- //\r
- Status = gBS->LocateHandleBuffer (\r
- AllHandles,\r
- NULL,\r
- NULL,\r
- &mHandleCount,\r
- &mHandleBuffer\r
- );\r
-\r
- for (HandleIndex = 0; HandleIndex < mHandleCount; HandleIndex++) {\r
- //\r
- // Retrieve the list of all the protocols on each handle\r
- //\r
- Status = gBS->ProtocolsPerHandle (\r
- mHandleBuffer[HandleIndex],\r
- &ProtocolGuidArray,\r
- &ArrayCount\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- for (ProtocolIndex = 0; ProtocolIndex < ArrayCount; ProtocolIndex++) {\r
- Status = gBS->OpenProtocolInformation (\r
- mHandleBuffer[HandleIndex],\r
- ProtocolGuidArray[ProtocolIndex],\r
- &OpenInfo,\r
- &OpenInfoCount\r
- );\r
- if (!EFI_ERROR (Status)) {\r
- for (OpenInfoIndex = 0; OpenInfoIndex < OpenInfoCount; OpenInfoIndex++) {\r
- if(OpenInfo[OpenInfoIndex].AgentHandle == Father) {\r
- if ((OpenInfo[OpenInfoIndex].Attributes & EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) == EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER) {\r
- *Child = mHandleBuffer[HandleIndex];\r
- Status = EFI_SUCCESS;\r
- goto TryReturn;\r
- }\r
- }\r
- }\r
- Status = EFI_NOT_FOUND;\r
- }\r
- }\r
- if(OpenInfo != NULL) {\r
- FreePool(OpenInfo);\r
- OpenInfo = NULL;\r
- }\r
- }\r
- FreePool (ProtocolGuidArray);\r
- ProtocolGuidArray = NULL;\r
- }\r
-TryReturn:\r
- if(OpenInfo != NULL) {\r
- FreePool (OpenInfo);\r
- OpenInfo = NULL;\r
- }\r
- if(ProtocolGuidArray != NULL) {\r
- FreePool(ProtocolGuidArray);\r
- ProtocolGuidArray = NULL;\r
- }\r
- if(mHandleBuffer != NULL) {\r
- FreePool (mHandleBuffer);\r
- mHandleBuffer = NULL;\r
- }\r
- return Status;\r
-}\r
-\r
-EFI_STATUS\r
-JudgeHandleIsPCIDevice(\r
- EFI_HANDLE Handle,\r
- UINT8 Device,\r
- UINT8 Funs\r
- )\r
-{\r
- EFI_STATUS Status;\r
- EFI_DEVICE_PATH *DPath;\r
-\r
- Status = gBS->HandleProtocol (\r
- Handle,\r
- &gEfiDevicePathProtocolGuid,\r
- (VOID **) &DPath\r
- );\r
- if(!EFI_ERROR(Status)) {\r
- while(!IsDevicePathEnd(DPath)) {\r
- if((DPath->Type == HARDWARE_DEVICE_PATH) && (DPath->SubType == HW_PCI_DP)) {\r
- PCI_DEVICE_PATH *PCIPath;\r
-\r
- PCIPath = (PCI_DEVICE_PATH*) DPath;\r
- DPath = NextDevicePathNode(DPath);\r
- if(IsDevicePathEnd(DPath) && (PCIPath->Device == Device) && (PCIPath->Function == Funs)) {\r
- return EFI_SUCCESS;\r
- }\r
- } else {\r
- DPath = NextDevicePathNode(DPath);\r
- }\r
- }\r
- }\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-EFI_STATUS\r
-GetDriverName(\r
- EFI_HANDLE Handle,\r
- CHAR16 *GopVersion\r
- )\r
-{\r
- EFI_DRIVER_BINDING_PROTOCOL *BindHandle = NULL;\r
- EFI_STATUS Status;\r
- UINT32 Version;\r
- UINT16 *Ptr;\r
-\r
- Status = gBS->OpenProtocol(\r
- Handle,\r
- &gEfiDriverBindingProtocolGuid,\r
- (VOID**)&BindHandle,\r
- NULL,\r
- NULL,\r
- EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
- );\r
- if (EFI_ERROR(Status)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Version = BindHandle->Version;\r
- Ptr = (UINT16*)&Version;\r
- UnicodeSPrint(GopVersion, 40, L"7.0.%04d", *(Ptr));\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-GetGOPDriverVersion(\r
- CHAR16 *GopVersion\r
- )\r
-{\r
- UINTN HandleCount;\r
- EFI_HANDLE *Handles= NULL;\r
- UINTN Index;\r
- EFI_STATUS Status;\r
- EFI_HANDLE Child = 0;\r
-\r
- Status = gBS->LocateHandleBuffer(\r
- ByProtocol,\r
- &gEfiDriverBindingProtocolGuid,\r
- NULL,\r
- &HandleCount,\r
- &Handles\r
- );\r
- for (Index = 0; Index < HandleCount ; Index++) {\r
- Status = SearchChildHandle(Handles[Index], &Child);\r
- if(!EFI_ERROR(Status)) {\r
- Status = JudgeHandleIsPCIDevice(Child, 0x02, 0x00);\r
- if(!EFI_ERROR(Status)) {\r
- return GetDriverName(Handles[Index], GopVersion);\r
- }\r
- }\r
- }\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-\r
-/**\r
- Get Intel GOP driver version and copy it into IGD OpRegion GVER. This version\r
- is picked up by IGD driver and displayed in CUI.\r
-\r
- @param Event A pointer to the Event that triggered the callback.\r
- @param Context A pointer to private data registered with the callback function.\r
-\r
- @retval EFI_SUCCESS Video BIOS VBT information returned.\r
- @retval EFI_UNSUPPORTED Could not find VBT information (*VBiosVbtPtr = NULL).\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-SetGOPVersionCallback (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- CHAR16 GopVersion[16] = {0};\r
- EFI_STATUS Status;\r
-\r
- Status = GetGOPDriverVersion(GopVersion);\r
- if(!EFI_ERROR(Status)) {\r
- StrCpy((CHAR16*)&(mIgdOpRegion.OpRegion->Header.GOPV[0]), GopVersion);\r
- return Status;\r
- }\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-/**\r
- Get Intel video BIOS VBT information (i.e. Pointer to VBT and VBT size).\r
- The VBT (Video BIOS Table) is a block of customizable data that is built\r
- within the video BIOS and edited by customers.\r
-\r
- @param Event A pointer to the Event that triggered the callback.\r
- @param Context A pointer to private data registered with the callback function.\r
-\r
- @retval EFI_SUCCESS Video BIOS VBT information returned.\r
- @retval EFI_UNSUPPORTED Could not find VBT information (*VBiosVbtPtr = NULL).\r
-\r
-**/\r
-EFI_STATUS\r
-GetVBiosVbtCallback (\r
- IN EFI_EVENT Event,\r
- IN VOID *Context\r
- )\r
-{\r
- INTEL_VBIOS_PCIR_STRUCTURE *PcirBlockPtr;\r
- UINT16 PciVenderId;\r
- UINT16 PciDeviceId;\r
- INTEL_VBIOS_OPTION_ROM_HEADER *VBiosPtr;\r
- VBIOS_VBT_STRUCTURE *VBiosVbtPtr;\r
- VBIOS_VBT_STRUCTURE *VbtFileBuffer = NULL;\r
-\r
- VBiosPtr = (INTEL_VBIOS_OPTION_ROM_HEADER *)(UINTN)(VBIOS_LOCATION_PRIMARY);\r
- PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *)((UINT8 *)VBiosPtr + VBiosPtr->PcirOffset);\r
- PciVenderId = PcirBlockPtr->VendorId;\r
- PciDeviceId = PcirBlockPtr->DeviceId;\r
-\r
- //\r
- // If the video BIOS is not at 0xC0000 or it is not an Intel video BIOS get\r
- // the integrated Intel video BIOS (must be uncompressed).\r
- //\r
- if ((VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId != IGD_VID) || (PciDeviceId != IGD_DID_VLV)) {\r
- GetIntegratedIntelVBiosPtr (&VBiosPtr);\r
-\r
- if(VBiosPtr) {\r
- //\r
- // Video BIOS found.\r
- //\r
- PcirBlockPtr = (INTEL_VBIOS_PCIR_STRUCTURE *)((UINT8 *)VBiosPtr + VBiosPtr->PcirOffset);\r
- PciVenderId = PcirBlockPtr->VendorId;\r
- if( (VBiosPtr->Signature != OPTION_ROM_SIGNATURE) || (PciVenderId != IGD_VID)) {\r
- //\r
- // Intel video BIOS not found.\r
- //\r
- VBiosVbtPtr = NULL;\r
- return EFI_UNSUPPORTED;\r
- }\r
- } else {\r
- //\r
- // No Video BIOS found, try to get VBT from FV.\r
- //\r
- GetIntegratedIntelVbtPtr (&VbtFileBuffer);\r
- if (VbtFileBuffer != NULL) {\r
- //\r
- // Video BIOS not found, use VBT from FV\r
- //\r
- DEBUG ((EFI_D_ERROR, "VBT data found\n"));\r
- (gBS->CopyMem) (\r
- mIgdOpRegion.OpRegion->VBT.GVD1,\r
- VbtFileBuffer,\r
- VbtFileBuffer->HeaderVbtSize\r
- );\r
- FreePool (VbtFileBuffer);\r
- return EFI_SUCCESS;\r
- }\r
- }\r
- if ((VBiosPtr == NULL) ) {\r
- //\r
- // Intel video BIOS not found.\r
- //\r
- VBiosVbtPtr = NULL;\r
- return EFI_UNSUPPORTED;\r
- }\r
- }\r
-\r
- DEBUG ((EFI_D_ERROR, "VBIOS found at 0x%X\n", VBiosPtr));\r
- VBiosVbtPtr = (VBIOS_VBT_STRUCTURE *) ((UINT8 *) VBiosPtr + VBiosPtr->VbtOffset);\r
-\r
- if ((*((UINT32 *) (VBiosVbtPtr->HeaderSignature))) != VBT_SIGNATURE) {\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- //\r
- // Initialize Video BIOS version with its build number.\r
- //\r
- mIgdOpRegion.OpRegion->Header.VVER[0] = VBiosVbtPtr->CoreBlockBiosBuild[0];\r
- mIgdOpRegion.OpRegion->Header.VVER[1] = VBiosVbtPtr->CoreBlockBiosBuild[1];\r
- mIgdOpRegion.OpRegion->Header.VVER[2] = VBiosVbtPtr->CoreBlockBiosBuild[2];\r
- mIgdOpRegion.OpRegion->Header.VVER[3] = VBiosVbtPtr->CoreBlockBiosBuild[3];\r
- (gBS->CopyMem) (\r
- mIgdOpRegion.OpRegion->VBT.GVD1,\r
- VBiosVbtPtr,\r
- VBiosVbtPtr->HeaderVbtSize\r
- );\r
-\r
- //\r
- // Return final status\r
- //\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Graphics OpRegion / Software SCI driver installation function.\r
-\r
- @param ImageHandle Handle for this drivers loaded image protocol.\r
- @param SystemTable EFI system table.\r
-\r
- @retval EFI_SUCCESS The driver installed without error.\r
- @retval EFI_ABORTED The driver encountered an error and could not complete\r
- installation of the ACPI tables.\r
-\r
-**/\r
-EFI_STATUS\r
-IgdOpRegionInit (\r
- void\r
- )\r
-{\r
- EFI_HANDLE Handle;\r
- EFI_STATUS Status;\r
- EFI_GLOBAL_NVS_AREA_PROTOCOL *GlobalNvsArea;\r
- UINT32 DwordData;\r
- EFI_CPU_IO_PROTOCOL *CpuIo;\r
- UINT16 Data16;\r
- UINT16 AcpiBase;\r
- VOID *gConOutNotifyReg;\r
-\r
-\r
- //\r
- // Locate the Global NVS Protocol.\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiGlobalNvsAreaProtocolGuid,\r
- NULL,\r
- (void **)&GlobalNvsArea\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Allocate an ACPI NVS memory buffer as the IGD OpRegion, zero initialize\r
- // the first 1K, and set the IGD OpRegion pointer in the Global NVS\r
- // area structure.\r
- //\r
- Status = (gBS->AllocatePool) (\r
- EfiACPIMemoryNVS,\r
- sizeof (IGD_OPREGION_STRUC),\r
- (void **)&mIgdOpRegion.OpRegion\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
- (gBS->SetMem) (\r
- mIgdOpRegion.OpRegion,\r
- sizeof (IGD_OPREGION_STRUC),\r
- 0\r
- );\r
- GlobalNvsArea->Area->IgdOpRegionAddress = (UINT32)(UINTN)(mIgdOpRegion.OpRegion);\r
-\r
- //\r
- // If IGD is disabled return\r
- //\r
- if (IgdMmPci32 (0) == 0xFFFFFFFF) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Initialize OpRegion Header\r
- //\r
-\r
- (gBS->CopyMem) (\r
- mIgdOpRegion.OpRegion->Header.SIGN,\r
- HEADER_SIGNATURE,\r
- sizeof(HEADER_SIGNATURE)\r
- );\r
-\r
-\r
- //\r
- // Set OpRegion Size in KBs\r
- //\r
- mIgdOpRegion.OpRegion->Header.SIZE = HEADER_SIZE/1024;\r
-\r
- //\r
- // FIXME: Need to check Header OVER Field and the supported version.\r
- //\r
- mIgdOpRegion.OpRegion->Header.OVER = (UINT32) (LShiftU64 (HEADER_OPREGION_VER, 16) + LShiftU64 (HEADER_OPREGION_REV, 8));\r
-#ifdef ECP_FLAG\r
- CopyMem(mIgdOpRegion.OpRegion->Header.SVER, gSVER, sizeof(gSVER));\r
-#else\r
- gBS->CopyMem(\r
- mIgdOpRegion.OpRegion->Header.SVER,\r
- gSVER,\r
- sizeof(gSVER)\r
- );\r
-#endif\r
- DEBUG ((EFI_D_ERROR, "System BIOS ID is %a\n", mIgdOpRegion.OpRegion->Header.SVER));\r
-\r
-\r
- mIgdOpRegion.OpRegion->Header.MBOX = HEADER_MBOX_SUPPORT;\r
-\r
- if( 1 == DxePlatformSaPolicy->IdleReserve) {\r
- mIgdOpRegion.OpRegion->Header.PCON = (mIgdOpRegion.OpRegion->Header.PCON & 0xFFFC) | BIT1;\r
- } else {\r
- mIgdOpRegion.OpRegion->Header.PCON = (mIgdOpRegion.OpRegion->Header.PCON & 0xFFFC) | (BIT1 | BIT0);\r
- }\r
-\r
- //\r
- //For graphics driver to identify if LPE Audio/HD Audio is enabled on the platform\r
- //\r
- mIgdOpRegion.OpRegion->Header.PCON &= AUDIO_TYPE_SUPPORT_MASK;\r
- mIgdOpRegion.OpRegion->Header.PCON &= AUDIO_TYPE_FIELD_MASK;\r
- if ( 1 == DxePlatformSaPolicy->AudioTypeSupport ) {\r
- mIgdOpRegion.OpRegion->Header.PCON = HD_AUDIO_SUPPORT;\r
- mIgdOpRegion.OpRegion->Header.PCON |= AUDIO_TYPE_FIELD_VALID;\r
- }\r
-\r
- //\r
- // Initialize OpRegion Mailbox 1 (Public ACPI Methods).\r
- //\r
- //<TODO> The initial setting of mailbox 1 fields is implementation specific.\r
- // Adjust them as needed many even coming from user setting in setup.\r
- //\r
- //Workaround to solve LVDS is off after entering OS in desktop platform\r
- //\r
- mIgdOpRegion.OpRegion->MBox1.CLID = DxePlatformSaPolicy->IgdPanelFeatures.LidStatus;\r
-\r
- //\r
- // Initialize OpRegion Mailbox 3 (ASLE Interrupt and Power Conservation).\r
- //\r
- //<TODO> The initial setting of mailbox 3 fields is implementation specific.\r
- // Adjust them as needed many even coming from user setting in setup.\r
- //\r
-\r
- //\r
- // Do not initialize TCHE. This field is written by the graphics driver only.\r
- //\r
-\r
- //\r
- // The ALSI field is generally initialized by ASL code by reading the embedded controller.\r
- //\r
-\r
- mIgdOpRegion.OpRegion->MBox3.BCLP = BACKLIGHT_BRIGHTNESS;\r
-\r
- mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT | PFIT_STRETCH);\r
- if ( DxePlatformSaPolicy->IgdPanelFeatures.PFITStatus == 2) {\r
- //\r
- // Center\r
- //\r
- mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT | PFIT_CENTER);\r
- } else if (DxePlatformSaPolicy->IgdPanelFeatures.PFITStatus == 1) {\r
- //\r
- // Stretch\r
- //\r
- mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT | PFIT_STRETCH);\r
- } else {\r
- //\r
- // Auto\r
- //\r
- mIgdOpRegion.OpRegion->MBox3.PFIT = (FIELD_VALID_BIT | PFIT_SETUP_AUTO);\r
- }\r
-\r
- //\r
- // Set Initial current Brightness\r
- //\r
- mIgdOpRegion.OpRegion->MBox3.CBLV = (INIT_BRIGHT_LEVEL | FIELD_VALID_BIT);\r
-\r
- //\r
- // <EXAMPLE> Create a static Backlight Brightness Level Duty cycle Mapping Table\r
- // Possible 20 entries (example used 10), each 16 bits as follows:\r
- // [15] = Field Valid bit, [14:08] = Level in Percentage (0-64h), [07:00] = Desired duty cycle (0 - FFh).\r
- //\r
- // % Brightness\r
- mIgdOpRegion.OpRegion->MBox3.BCLM[0] = ( ( 0 << 8 ) + ( 0xFF - 0xFC ) + WORD_FIELD_VALID_BIT);\r
- mIgdOpRegion.OpRegion->MBox3.BCLM[1] = ( ( 1 << 8 ) + ( 0xFF - 0xFC ) + WORD_FIELD_VALID_BIT);\r
- mIgdOpRegion.OpRegion->MBox3.BCLM[2] = ( ( 10 << 8 ) + ( 0xFF - 0xE5 ) + WORD_FIELD_VALID_BIT);\r
- mIgdOpRegion.OpRegion->MBox3.BCLM[3] = ( ( 19 << 8 ) + ( 0xFF - 0xCE ) + WORD_FIELD_VALID_BIT);\r
- mIgdOpRegion.OpRegion->MBox3.BCLM[4] = ( ( 28 << 8 ) + ( 0xFF - 0xB7 ) + WORD_FIELD_VALID_BIT);\r
- mIgdOpRegion.OpRegion->MBox3.BCLM[5] = ( ( 37 << 8 ) + ( 0xFF - 0xA0 ) + WORD_FIELD_VALID_BIT);\r
- mIgdOpRegion.OpRegion->MBox3.BCLM[6] = ( ( 46 << 8 ) + ( 0xFF - 0x89 ) + WORD_FIELD_VALID_BIT);\r
- mIgdOpRegion.OpRegion->MBox3.BCLM[7] = ( ( 55 << 8 ) + ( 0xFF - 0x72 ) + WORD_FIELD_VALID_BIT);\r
- mIgdOpRegion.OpRegion->MBox3.BCLM[8] = ( ( 64 << 8 ) + ( 0xFF - 0x5B ) + WORD_FIELD_VALID_BIT);\r
- mIgdOpRegion.OpRegion->MBox3.BCLM[9] = ( ( 73 << 8 ) + ( 0xFF - 0x44 ) + WORD_FIELD_VALID_BIT);\r
- mIgdOpRegion.OpRegion->MBox3.BCLM[10] = ( ( 82 << 8 ) + ( 0xFF - 0x2D ) + WORD_FIELD_VALID_BIT);\r
- mIgdOpRegion.OpRegion->MBox3.BCLM[11] = ( ( 91 << 8 ) + ( 0xFF - 0x16 ) + WORD_FIELD_VALID_BIT);\r
- mIgdOpRegion.OpRegion->MBox3.BCLM[12] = ( (100 << 8 ) + ( 0xFF - 0x00 ) + WORD_FIELD_VALID_BIT);\r
-\r
- mIgdOpRegion.OpRegion->MBox3.PCFT = ((UINT32) GlobalNvsArea->Area->IgdPowerConservation) | BIT31;\r
- //\r
- // Create the notification and register callback function on the PciIo installation,\r
- //\r
- //\r
- Status = gBS->CreateEvent (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
- (EFI_EVENT_NOTIFY)GetVBiosVbtCallback,\r
- NULL,\r
- &mConOutEvent\r
- );\r
-\r
- ASSERT_EFI_ERROR (Status);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
-\r
- }\r
-\r
- Status = gBS->RegisterProtocolNotify (\r
-#ifdef ECP_FLAG\r
- &gExitPmAuthProtocolGuid,\r
-#else\r
- &gEfiDxeSmmReadyToLockProtocolGuid,\r
-#endif\r
- mConOutEvent,\r
- &gConOutNotifyReg\r
- );\r
-\r
- Status = gBS->CreateEvent (\r
- EVT_NOTIFY_SIGNAL,\r
- TPL_CALLBACK,\r
- (EFI_EVENT_NOTIFY)SetGOPVersionCallback,\r
- NULL,\r
- &mSetGOPverEvent\r
- );\r
-\r
- ASSERT_EFI_ERROR (Status);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Status = gBS->RegisterProtocolNotify (\r
- &gEfiGraphicsOutputProtocolGuid,\r
- mSetGOPverEvent,\r
- &gConOutNotifyReg\r
- );\r
-\r
-\r
- //\r
- // Initialize hardware state:\r
- // Set ASLS Register to the OpRegion physical memory address.\r
- // Set SWSCI register bit 15 to a "1" to activate SCI interrupts.\r
- //\r
-\r
- IgdMmPci32 (IGD_ASLS_OFFSET) = (UINT32)(UINTN)(mIgdOpRegion.OpRegion);\r
- IgdMmPci16AndThenOr (IGD_SWSCI_OFFSET, ~(BIT0), BIT15);\r
-\r
- DwordData = IgdMmPci32 (IGD_ASLS_OFFSET);\r
- S3BootScriptSavePciCfgWrite (\r
- S3BootScriptWidthUint32,\r
- (UINTN) (EFI_PCI_ADDRESS (IGD_BUS, IGD_DEV, IGD_FUN_0, IGD_ASLS_OFFSET)),\r
- 1,\r
- &DwordData\r
- );\r
-\r
-\r
- DwordData = IgdMmPci32 (IGD_SWSCI_OFFSET);\r
- S3BootScriptSavePciCfgWrite (\r
- S3BootScriptWidthUint32,\r
- (UINTN) (EFI_PCI_ADDRESS (IGD_BUS, IGD_DEV, IGD_FUN_0, IGD_SWSCI_OFFSET)),\r
- 1,\r
- &DwordData\r
- );\r
-\r
- AcpiBase = MmPci16 (\r
- 0,\r
- DEFAULT_PCI_BUS_NUMBER_PCH,\r
- PCI_DEVICE_NUMBER_PCH_LPC,\r
- PCI_FUNCTION_NUMBER_PCH_LPC,\r
- R_PCH_LPC_ACPI_BASE\r
- ) & B_PCH_LPC_ACPI_BASE_BAR;\r
-\r
- //\r
- // Find the CPU I/O Protocol. ASSERT if not found.\r
- //\r
- Status = gBS->LocateProtocol (\r
- &gEfiCpuIoProtocolGuid,\r
- NULL,\r
- (void **)&CpuIo\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- CpuIo->Io.Read (\r
- CpuIo,\r
- EfiCpuIoWidthUint16,\r
- AcpiBase + R_PCH_ACPI_GPE0a_STS,\r
- 1,\r
- &Data16\r
- );\r
- //\r
- // Clear the B_PCH_ACPI_GPE0a_STS_GUNIT_SCI bit in R_PCH_ACPI_GPE0a_STS by writing a '1'.\r
- //\r
- Data16 |= B_PCH_ACPI_GPE0a_STS_GUNIT_SCI;\r
-\r
- CpuIo->Io.Write (\r
- CpuIo,\r
- EfiCpuIoWidthUint16,\r
- AcpiBase + R_PCH_ACPI_GPE0a_STS,\r
- 1,\r
- &Data16\r
- );\r
-\r
- //\r
- // Install OpRegion / Software SCI protocol\r
- //\r
- Handle = NULL;\r
- Status = gBS->InstallMultipleProtocolInterfaces (\r
- &Handle,\r
- &gIgdOpRegionProtocolGuid,\r
- &mIgdOpRegion,\r
- NULL\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- //\r
- // Return final status\r
- //\r
- return EFI_SUCCESS;\r
-}\r