/** @file Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent Module Name: PciPlatform.c Abstract: --*/ #include "PciPlatform.h" #include "PchRegs.h" #include "PchAccess.h" #include "VlvCommonDefinitions.h" #include "PlatformBootMode.h" #include #include #include #include #include #include "SetupMode.h" #include #include #include #include #include #include extern PCI_OPTION_ROM_TABLE mPciOptionRomTable[]; extern UINTN mSizeOptionRomTable; EFI_PCI_PLATFORM_PROTOCOL mPciPlatform = { PhaseNotify, PlatformPrepController, GetPlatformPolicy, GetPciRom }; EFI_HANDLE mPciPlatformHandle = NULL; SYSTEM_CONFIGURATION mSystemConfiguration; EFI_STATUS GetRawImage ( IN EFI_GUID *NameGuid, IN OUT VOID **Buffer, IN OUT UINTN *Size ) { EFI_STATUS Status; EFI_HANDLE *HandleBuffer; UINTN HandleCount; UINTN Index; EFI_FIRMWARE_VOLUME2_PROTOCOL *Fv; UINT32 AuthenticationStatus; Status = gBS->LocateHandleBuffer ( ByProtocol, &gEfiFirmwareVolume2ProtocolGuid, NULL, &HandleCount, &HandleBuffer ); if (EFI_ERROR (Status) || HandleCount == 0) { return EFI_NOT_FOUND; } // // Find desired image in all Fvs // for (Index = 0; Index < HandleCount; Index++) { Status = gBS->HandleProtocol( HandleBuffer[Index], &gEfiFirmwareVolume2ProtocolGuid, (VOID **) &Fv ); if ( EFI_ERROR ( Status ) ) { return EFI_LOAD_ERROR; } // // Try a raw file // *Buffer = NULL; *Size = 0; Status = Fv->ReadSection ( Fv, NameGuid, EFI_SECTION_RAW, 0, Buffer, Size, &AuthenticationStatus ); if ( !EFI_ERROR ( Status )) { break; } } if ( Index >= HandleCount ) { return EFI_NOT_FOUND; } return EFI_SUCCESS; } EFI_STATUS EFIAPI PhaseNotify ( IN EFI_PCI_PLATFORM_PROTOCOL *This, IN EFI_HANDLE HostBridge, IN EFI_PCI_HOST_BRIDGE_RESOURCE_ALLOCATION_PHASE Phase, IN EFI_PCI_CHIPSET_EXECUTION_PHASE ChipsetPhase ) { return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI PlatformPrepController ( IN EFI_PCI_PLATFORM_PROTOCOL *This, IN EFI_HANDLE HostBridge, IN EFI_HANDLE RootBridge, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_PCI_ADDRESS PciAddress, IN EFI_PCI_CONTROLLER_RESOURCE_ALLOCATION_PHASE Phase, IN EFI_PCI_CHIPSET_EXECUTION_PHASE ChipsetPhase ) { return EFI_UNSUPPORTED; } EFI_STATUS EFIAPI GetPlatformPolicy ( IN CONST EFI_PCI_PLATFORM_PROTOCOL *This, OUT EFI_PCI_PLATFORM_POLICY *PciPolicy ) { *PciPolicy = EFI_RESERVE_VGA_IO_ALIAS; return EFI_SUCCESS; } /** GetPciRom from platform specific location for specific PCI device @param This Protocol instance @param PciHandle Identify the specific PCI devic @param RomImage Returns the ROM Image memory location @param RomSize Returns Rom Image size @retval EFI_SUCCESS @retval EFI_NOT_FOUND @retval EFI_OUT_OF_RESOURCES **/ EFI_STATUS EFIAPI GetPciRom ( IN CONST EFI_PCI_PLATFORM_PROTOCOL *This, IN EFI_HANDLE PciHandle, OUT VOID **RomImage, OUT UINTN *RomSize ) { EFI_STATUS Status; EFI_PCI_IO_PROTOCOL *PciIo; EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *PciRootBridgeIo; UINTN Segment; UINTN Bus; UINTN Device; UINTN Function; UINT16 VendorId; UINT16 DeviceId; UINT16 DeviceClass; UINTN TableIndex; UINT8 Data8; BOOLEAN MfgMode; EFI_PLATFORM_SETUP_ID *BootModeBuffer; EFI_PEI_HOB_POINTERS GuidHob; MfgMode = FALSE; // // Check if system is in manufacturing mode. // GuidHob.Raw = GetHobList (); if (GuidHob.Raw == NULL) { return EFI_NOT_FOUND; } if ((GuidHob.Raw = GetNextGuidHob (&gEfiPlatformBootModeGuid, GuidHob.Raw)) != NULL) { BootModeBuffer = GET_GUID_HOB_DATA (GuidHob.Guid); if (!CompareMem (&BootModeBuffer->SetupName, MANUFACTURE_SETUP_NAME, StrSize (MANUFACTURE_SETUP_NAME))) { // // System is in manufacturing mode. // MfgMode = TRUE; } } Status = gBS->HandleProtocol ( PciHandle, &gEfiPciIoProtocolGuid, (void **)&PciIo ); if (EFI_ERROR (Status)) { return EFI_NOT_FOUND; } Status = gBS->LocateProtocol ( &gEfiPciRootBridgeIoProtocolGuid, NULL, (void **)&PciRootBridgeIo ); if (EFI_ERROR (Status)) { return EFI_NOT_FOUND; } PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 0x0A, 1, &DeviceClass); PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function); PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 0, 1, &VendorId); PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, 2, 1, &DeviceId); // // WA for PCIe SATA card (SYBA SY-PEX400-40) // if ((VendorId == 0x1B21) && (DeviceId == 0x0612)) { Data8 = 0x07; PciIo->Pci.Write (PciIo, EfiPciIoWidthUint8, 4, 1, &Data8); } // // Do not run RAID or AHCI Option ROM if IDE // if ( (DeviceClass == ((PCI_CLASS_MASS_STORAGE << 8 ) | PCI_CLASS_MASS_STORAGE_IDE)) ) { return EFI_NOT_FOUND; } // // Run PXE ROM only if Boot network is enabled and not in MFG mode // if (DeviceClass == ((PCI_CLASS_NETWORK << 8 ) | PCI_CLASS_NETWORK_ETHERNET)) { if (((mSystemConfiguration.BootNetwork == 0) && (MfgMode == FALSE )) || (mSystemConfiguration.FastBoot == 1)) { return EFI_NOT_FOUND; } } // // Loop through table of Onboard option rom descriptions // for (TableIndex = 0; mPciOptionRomTable[TableIndex].VendorId != 0xffff; TableIndex++) { // // See if the PCI device specified by PciHandle matches at device in mPciOptionRomTable // if (VendorId != mPciOptionRomTable[TableIndex].VendorId || DeviceId != mPciOptionRomTable[TableIndex].DeviceId || ((DeviceClass == ((PCI_CLASS_NETWORK << 8 ) | PCI_CLASS_NETWORK_ETHERNET)) && (mPciOptionRomTable[TableIndex].Flag != mSystemConfiguration.BootNetwork)) ) { continue; } Status = GetRawImage( &mPciOptionRomTable[TableIndex].FileName, RomImage, RomSize ); if ((VendorId == IGD_VID) && (DeviceId == IGD_DID_VLV_A0)) { *(UINT16 *)(((UINTN) *RomImage) + OPROM_DID_OFFSET) = IGD_DID_VLV_A0; } if ((VendorId == IGD_VID) && (DeviceId == IGD_DID_II)) { *(UINT16 *)(((UINTN) *RomImage) + OPROM_DID_OFFSET) = IGD_DID_II; } if ((VendorId == IGD_VID) && (DeviceId == IGD_DID_0BE4)) { *(UINT16 *)(((UINTN) *RomImage) + OPROM_DID_OFFSET) = IGD_DID_0BE4; } if ((VendorId == IGD_VID) && (DeviceId == IGD_DID_QS)) { *(UINT16 *)(((UINTN) *RomImage) + OPROM_DID_OFFSET) = IGD_DID_QS; } if (EFI_ERROR (Status)) { continue; } return EFI_SUCCESS; } return EFI_NOT_FOUND; } /** @param (Standard EFI Image entry - EFI_IMAGE_ENTRY_POINT) @retval EFI_STATUS **/ EFI_STATUS EFIAPI PciPlatformDriverEntry ( IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable ) { EFI_STATUS Status; UINTN VarSize; VarSize = sizeof(SYSTEM_CONFIGURATION); Status = gRT->GetVariable( L"Setup", &gEfiNormalSetupGuid, NULL, &VarSize, &mSystemConfiguration ); if (EFI_ERROR (Status) || VarSize != sizeof(SYSTEM_CONFIGURATION)) { //The setup variable is corrupted VarSize = sizeof(SYSTEM_CONFIGURATION); Status = gRT->GetVariable( L"SetupRecovery", &gEfiNormalSetupGuid, NULL, &VarSize, &mSystemConfiguration ); ASSERT_EFI_ERROR (Status); } // // Install on a new handle // Status = gBS->InstallProtocolInterface ( &mPciPlatformHandle, &gEfiPciPlatformProtocolGuid, EFI_NATIVE_INTERFACE, &mPciPlatform ); return Status; }