123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541 |
- /** @file
- @copyright
- Copyright 2004 - 2021 Intel Corporation. <BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include <PiDxe.h>
- #include "PciPlatform.h"
- #include <Library/PcdLib.h>
- #include <Library/PlatformOpromPolicyLib.h>
- #include <Protocol/DynamicSiLibraryProtocol.h>
- #include <Protocol/UbaCfgDb.h>
- #ifdef EFI_PCI_IOV_SUPPORT
- #include "PciIovPlatformPolicy.h"
- #endif
- #include <Library/UbaPlatLib.h>
- PCI_PLATFORM_PRIVATE_DATA mPciPrivateData;
- BOOLEAN FirstCall = TRUE;
- UINT8 sSataRaidLoadEfiDriverOption;
- UINT8 SataRaidLoadEfiDriverOption[PCH_MAX_SATA_CONTROLLERS];
- UINT8 BootNetworkOption;
- STATIC
- BOOLEAN
- InternalPlatformCheckPcieRootPort (
- IN UINTN Bus,
- IN UINT32 PcieSlotOpromBitMap
- )
- {
- EFI_STATUS Status;
- UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol = NULL;
- UINTN DataLength = 0;
- PLATFORM_OPTION_ROM_UPDATE_DATA OptionRomUpdateTable;
- Status = gBS->LocateProtocol (
- &gUbaConfigDatabaseProtocolGuid,
- NULL,
- &UbaConfigProtocol
- );
- if (EFI_ERROR(Status)) {
- DEBUG ((DEBUG_INFO," InternalPlatformCheckPcieRootPort fail!\n"));
- return TRUE;
- }
- DataLength = sizeof (OptionRomUpdateTable);
- Status = UbaConfigProtocol->GetData (
- UbaConfigProtocol,
- &gPlatformOptionRomUpdateConfigDataGuid,
- &OptionRomUpdateTable,
- &DataLength
- );
- if (EFI_ERROR(Status)) {
- DEBUG ((DEBUG_INFO,"InternalPlatformCheckPcieRootPort fail!\n"));
- return TRUE;
- }
- ASSERT (OptionRomUpdateTable.Signature == PLATFORM_OPTION_ROM_UPDATE_SIGNATURE);
- ASSERT (OptionRomUpdateTable.Version == PLATFORM_OPTION_ROM_UPDATE_VERSION);
- return OptionRomUpdateTable.CallCheckRootPort (Bus, PcieSlotOpromBitMap);
- }
- STATIC
- EFI_STATUS
- InternalGetSystemBoardInfo (
- IN OUT DXE_SYSTEM_BOARD_INFO **SystemboardInfoTableBuffer
- )
- {
- EFI_STATUS Status;
- UBA_CONFIG_DATABASE_PROTOCOL *UbaConfigProtocol = NULL;
- UINTN DataLength = 0;
- SYSTEM_BOARD_INFO_DATA SystemBoardInfoData;
- Status = gBS->LocateProtocol (
- &gUbaConfigDatabaseProtocolGuid,
- NULL,
- &UbaConfigProtocol
- );
- if (EFI_ERROR(Status)) {
- DEBUG ((EFI_D_ERROR," [GetSystemBoardInfo] Locate UbaConfigProtocol fail!\n"));
- return Status;
- }
- DataLength = sizeof(SystemBoardInfoData);
- Status = UbaConfigProtocol->GetData (
- UbaConfigProtocol,
- &gSystemBoardInfoConfigDataGuid,
- &SystemBoardInfoData,
- &DataLength
- );
- if (EFI_ERROR(Status)) {
- DEBUG ((EFI_D_ERROR," [GetSystemBoardInfo] Get Data fail!\n"));
- return Status;
- }
- ASSERT (SystemBoardInfoData.Signature == SYSTEM_SYSTEM_BOARD_INFO_SIGNATURE);
- ASSERT (SystemBoardInfoData.Version == SYSTEM_SYSTEM_BOARD_INFO_VERSION);
- *SystemboardInfoTableBuffer = SystemBoardInfoData.CallUpdate ();
- return Status;
- }
- /**
- Set the PciPolicy as EFI_RESERVE_ISA_IO_NO_ALIAS | EFI_RESERVE_VGA_IO_NO_ALIAS.
- @param This - The pointer to the Protocol itself.
- PciPolicy - the returned Policy.
- @retval EFI_UNSUPPORTED - Function not supported.
- @retval EFI_INVALID_PARAMETER - Invalid PciPolicy value.
- **/
- EFI_STATUS
- EFIAPI
- GetPlatformPolicy (
- IN CONST EFI_PCI_PLATFORM_PROTOCOL *This,
- OUT EFI_PCI_PLATFORM_POLICY *PciPolicy
- )
- {
- if (PciPolicy == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- return EFI_UNSUPPORTED;
- }
- /**
- Get an indicated image in raw sections.
- @param NameGuid - NameGuid of the image to get.
- @param Buffer - Buffer to store the image get.
- @param Size - size of the image get.
- @retval EFI_NOT_FOUND - Could not find the image.
- @retval EFI_LOAD_ERROR - Error occurred during image loading.
- @retval EFI_SUCCESS - Image has been successfully loaded.
- **/
- 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,
- &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)) {
- DEBUG((EFI_D_INFO, "Read the OROM successfully!\n"));
- break;
- }
- }
- if (Index >= HandleCount) {
- return EFI_NOT_FOUND;
- }
- return EFI_SUCCESS;
- }
- /**
- Return a PCI ROM image for the onboard device represented by PciHandle.
- @param This - Protocol instance pointer.
- PciHandle - PCI device to return the ROM image for.
- RomImage - PCI Rom Image for onboard device.
- RomSize - Size of RomImage in bytes.
- @retval EFI_SUCCESS - RomImage is valid.
- @retval EFI_NOT_FOUND - No RomImage.
- **/
- 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;
- UINTN Segment;
- UINTN Bus;
- UINTN Device;
- UINTN Function;
- UINT16 VendorId;
- UINT16 DeviceId;
- UINT16 DeviceClass;
- UINTN TableIndex;
- UINTN RomImageNumber;
- VOID *OpRomBase;
- UINTN OpRomSize;
- EFI_PCI_ROM_HEADER RomHeader;
- PCI_DATA_STRUCTURE *Pcir;
- OPROM_LOAD_POLICY OpromPolicy;
- BOOLEAN SlotOptionRomDisabled;
- DXE_SYSTEM_BOARD_INFO *SystemBoardInfo = NULL;
- UINT32 Index;
- DYNAMIC_SI_LIBARY_PROTOCOL *DynamicSiLibraryProtocol = NULL;
- OpRomBase = NULL;
- OpRomSize = 0;
- Status = gBS->LocateProtocol (&gDynamicSiLibraryProtocolGuid, NULL, &DynamicSiLibraryProtocol);
- if (EFI_ERROR (Status)) {
- ASSERT_EFI_ERROR (Status);
- return Status;
- }
- //
- // Get System Board Info
- //
- Status = InternalGetSystemBoardInfo (&SystemBoardInfo);
- ASSERT_EFI_ERROR (Status);
- if (EFI_ERROR (Status)) {
- DEBUG ((EFI_D_ERROR, "[GetPciRom] Get system board info fail!\n"));
- return Status;
- }
- Status = gBS->HandleProtocol (
- PciHandle,
- &gEfiPciIoProtocolGuid,
- (VOID **) &PciIo
- );
- if (EFI_ERROR (Status)) {
- return EFI_NOT_FOUND;
- }
- if (FirstCall == TRUE) {
- Status = GetOptionData (&gEfiSetupVariableGuid, OFFSET_OF(SYSTEM_CONFIGURATION, BootNetwork), &BootNetworkOption, sizeof(BootNetworkOption));
- if (EFI_ERROR (Status)) {
- BootNetworkOption = 0;
- }
- Status = GetOptionData (&gPchSetupVariableGuid,
- OFFSET_OF(PCH_SETUP, SataRaidLoadEfiDriver),
- &SataRaidLoadEfiDriverOption,
- sizeof(SataRaidLoadEfiDriverOption) * PCH_MAX_SATA_CONTROLLERS);
- if (EFI_ERROR (Status)) {
- for (Index = 0; Index < DynamicSiLibraryProtocol->MaxSataControllerNum(); Index++) {
- SataRaidLoadEfiDriverOption[Index] = 0;
- }
- }
- FirstCall = FALSE;
- }
- PciIo->GetLocation (PciIo, &Segment, &Bus, &Device, &Function);
- PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_CLASSCODE_OFFSET + 1, 1, &DeviceClass);
- //
- // Run PXE ROM only if Boot network is enabled
- //
- if ((BootNetworkOption == 0) &&
- (DeviceClass == ((PCI_CLASS_NETWORK << 8) | PCI_CLASS_NETWORK_ETHERNET))
- ) {
- return EFI_NOT_FOUND;
- }
- //
- // Run each PCI-E slot ROM only if PCI-E Slot Oprom is enabled.
- //
- if ( Bus != 0 ) {
- SlotOptionRomDisabled = InternalPlatformCheckPcieRootPort (Bus, PcdGet32(PcdOemSkuPcieSlotOpromBitMap));
- if (SlotOptionRomDisabled) {
- return EFI_NOT_FOUND;
- }
- }
- PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_VENDOR_ID_OFFSET, 1, &VendorId);
- PciIo->Pci.Read (PciIo, EfiPciIoWidthUint16, PCI_DEVICE_ID_OFFSET, 1, &DeviceId);
- //DEBUG ((EFI_D_INFO, "GetPciRom - VenID:DevID: %04x:%04x\n", (UINTN)VendorId, (UINTN)DeviceId));
- //
- // Fix MS-HD5770 video adapter can not work:
- // This device is not a OPROM 3.0 and does not have device id list as well.
- // It only have 1 device id in OPROM.
- // Device Id in OpROM is not same with the value in PCI configuration space
- // it will cause VBIOS fails to start
- //
- if ((VendorId == 0x1002) && (DeviceId == 0x68BE)) {
- DEBUG ((DEBUG_INFO, "MS-HD5770 video adapter\n"));
- RomHeader.Raw = PciIo->RomImage;
- if (RomHeader.Raw != NULL) {
- Pcir = (PCI_DATA_STRUCTURE *)(RomHeader.Raw + RomHeader.Generic->PcirOffset);
- if ((Pcir->VendorId == 0x1002) && (Pcir->DeviceId == 0x68B8)) {
- //
- // Assign same device id in PCI configuration space
- //
- Pcir->DeviceId = DeviceId;
- }
- } else {
- DEBUG ((EFI_D_ERROR, "MS-HD5770 video adapter detected but PciIo->RomImage == NULL!\n"));
- }
- }
- //Check if user disables the option rom loading for this device.
- if (!PlatformOpromLoadDevicePolicy(PciIo)) {
- return EFI_NOT_FOUND;
- }
- // If setup value requested EFI, we don't load the RAID OROM.
- if (VendorId == V_SATA_CFG_VENDOR_ID) {
- for (Index = 0; Index < DynamicSiLibraryProtocol->MaxSataControllerNum(); Index++) {
- if (Bus == DEFAULT_PCI_BUS_NUMBER_PCH &&
- Device == DynamicSiLibraryProtocol->SataDevNumber (Index) &&
- Function == DynamicSiLibraryProtocol->SataFuncNumber (Index) &&
- SataRaidLoadEfiDriverOption[Index] == 1) {
- return EFI_NOT_FOUND;
- }
- }
- }
- //
- // Loop through table of video option rom descriptions
- //
- RomImageNumber = 0;
- for (TableIndex = 0; SystemBoardInfo->PciOptionRomTable[TableIndex].VendorId != 0xffff; TableIndex++) {
- //
- // See if the PCI device specified by PciHandle matches at device in mPciOptionRomTable
- //
- if (VendorId != SystemBoardInfo->PciOptionRomTable[TableIndex].VendorId ||
- DeviceId != SystemBoardInfo->PciOptionRomTable[TableIndex].DeviceId ||
- Device != SystemBoardInfo->PciOptionRomTable[TableIndex].Device ||
- Function != SystemBoardInfo->PciOptionRomTable[TableIndex].Function
- ) {
- continue;
- }
- //Check if user wants to exclusively run this option rom for the device.
- OpromPolicy = PlatformOpromLoadTypePolicy(PciHandle, TableIndex);
- if(OpromPolicy == DONT_LOAD) {
- continue;
- }
- Status = GetRawImage (
- &SystemBoardInfo->PciOptionRomTable[TableIndex].FileName,
- &OpRomBase,
- &OpRomSize
- );
- if (EFI_ERROR (Status)) {
- continue;
- } else {
- RomImageNumber++;
- if (RomImageNumber == PcdGet8(PcdMaxOptionRomNumber) || OpromPolicy == EXCLUSIVE_LOAD) {
- break;
- }
- }
- }
- if (RomImageNumber == 0) {
- return EFI_NOT_FOUND;
- } else {
- *RomImage = OpRomBase;
- *RomSize = OpRomSize;
- return EFI_SUCCESS;
- }
- }
- /**
- GC_TODO: Add function description
- @param This - GC_TODO: add argument description
- @param Function - GC_TODO: add argument description
- @param Phase - GC_TODO: add argument description
- @retval EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
- @retval EFI_INVALID_PARAMETER - GC_TODO: Add description for return value
- @retval EFI_UNSUPPORTED - GC_TODO: Add description for return value
- @retval EFI_SUCCESS - GC_TODO: Add description for return value
- **/
- EFI_STATUS
- EFIAPI
- RegisterPciCallback (
- IN EFI_PCI_CALLBACK_PROTOCOL *This,
- IN EFI_PCI_CALLBACK_FUNC Function,
- IN EFI_PCI_ENUMERATION_PHASE Phase
- )
- {
- LIST_ENTRY *NodeEntry;
- PCI_CALLBACK_DATA *PciCallbackData;
- if (Function == NULL) {
- return EFI_INVALID_PARAMETER;
- }
- if ( (Phase & (EfiPciEnumerationDeviceScanning | EfiPciEnumerationBusNumberAssigned \
- | EfiPciEnumerationResourceAssigned)) == 0) {
- return EFI_INVALID_PARAMETER;
- }
- //
- // Check if the node has been added
- //
- NodeEntry = GetFirstNode (&mPciPrivateData.PciCallbackList);
- while (!IsNull (&mPciPrivateData.PciCallbackList, NodeEntry)) {
- PciCallbackData = PCI_CALLBACK_DATA_FROM_LINK (NodeEntry);
- if (PciCallbackData->Function == Function) {
- return EFI_UNSUPPORTED;
- }
- NodeEntry = GetNextNode (&mPciPrivateData.PciCallbackList, NodeEntry);
- }
- PciCallbackData = NULL;
- PciCallbackData = AllocateZeroPool (sizeof (PCI_CALLBACK_DATA));
- ASSERT (PciCallbackData != NULL);
- if(PciCallbackData != NULL){
- PciCallbackData->Signature = PCI_CALLBACK_DATA_SIGNATURE;
- PciCallbackData->Function = Function;
- PciCallbackData->Phase = Phase;
- InsertTailList (&mPciPrivateData.PciCallbackList, &PciCallbackData->Link);
- return EFI_SUCCESS;
- } else {
- return EFI_UNSUPPORTED;
- }
- }
- /**
- Main Entry point of the Pci Platform Driver.
- @param ImageHandle - Handle to the image.
- @param SystemTable - Handle to System Table.
- @retval EFI_STATUS - Status of the function calling.
- **/
- EFI_STATUS
- EFIAPI
- PciPlatformDriverEntry (
- IN EFI_HANDLE ImageHandle,
- IN EFI_SYSTEM_TABLE *SystemTable
- )
- {
- EFI_STATUS Status;
- EFI_HOB_GUID_TYPE *GuidHob;
- GuidHob = GetFirstGuidHob (&gEfiPlatformInfoGuid);
- ASSERT (GuidHob != NULL);
- if (GuidHob == NULL) {
- return EFI_NOT_FOUND;
- }
- mPciPrivateData.PlatformInfo = GET_GUID_HOB_DATA(GuidHob);
- //EDK2_TODO Check if clearing mPciPrivateData.PlatformInfo (got above) is intended.
- ZeroMem (&mPciPrivateData, sizeof (mPciPrivateData));
- InitializeListHead (&mPciPrivateData.PciCallbackList);
- mPciPrivateData.PciPlatform.PlatformNotify = PhaseNotify;
- mPciPrivateData.PciPlatform.PlatformPrepController = PlatformPrepController;
- mPciPrivateData.PciPlatform.GetPlatformPolicy = GetPlatformPolicy;
- mPciPrivateData.PciPlatform.GetPciRom = GetPciRom;
- mPciPrivateData.PciCallback.RegisterPciCallback = RegisterPciCallback;
- #ifdef EFI_PCI_IOV_SUPPORT
- mPciPrivateData.PciIovPlatform.GetSystemLowestPageSize = GetSystemLowestPageSize;
- mPciPrivateData.PciIovPlatform.GetPlatformPolicy = GetIovPlatformPolicy;
- #endif
- //
- // Install on a new handle
- //
- Status = gBS->InstallMultipleProtocolInterfaces (
- &mPciPrivateData.PciPlatformHandle,
- &gEfiPciPlatformProtocolGuid,
- &mPciPrivateData.PciPlatform,
- &gEfiPciCallbackProtocolGuid,
- &mPciPrivateData.PciCallback,
- #ifdef EFI_PCI_IOV_SUPPORT
- &gEfiPciIovPlatformProtocolGuid,
- &mPciPrivateData.PciIovPlatform,
- #endif
- NULL
- );
- return Status;
- }
|