/** @file Copyright (c) 2017, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ #include #include #include #include #include #include #include #include EFI_STATUS TestPointCheckPciBusMaster ( VOID ) { UINTN Segment; UINTN SegmentCount; UINTN Bus; UINTN Device; UINTN Function; UINT16 VendorId; UINT16 Command; UINT8 HeaderType; EFI_STATUS Status; PCI_SEGMENT_INFO *PciSegmentInfo; PciSegmentInfo = GetPciSegmentInfo (&SegmentCount); if (PciSegmentInfo == NULL) { return EFI_OUT_OF_RESOURCES; } Status = EFI_SUCCESS; for (Segment = 0; Segment < SegmentCount; Segment++) { for (Bus = PciSegmentInfo[Segment].StartBusNumber; Bus <= PciSegmentInfo[Segment].EndBusNumber; Bus++) { for (Device = 0; Device <= 0x1F; Device++) { for (Function = 0; Function <= 0x7; Function++) { VendorId = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS(PciSegmentInfo[Segment].SegmentNumber, Bus, Device, Function, PCI_VENDOR_ID_OFFSET)); // // If VendorId = 0xffff, there does not exist a device at this // location. For each device, if there is any function on it, // there must be 1 function at Function 0. So if Func = 0, there // will be no more functions in the same device, so we can break // loop to deal with the next device. // if (VendorId == 0xffff && Function == 0) { break; } if (VendorId != 0xffff) { Command = PciSegmentRead16 (PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCI_COMMAND_OFFSET)); if ((Command & EFI_PCI_COMMAND_BUS_MASTER) != 0) { DEBUG ((DEBUG_INFO, "PCI BME enabled (S%04x.B%02x.D%02x.F%x - %04x)\n", Segment, Bus, Device, Function, Command)); TestPointLibAppendErrorString ( PLATFORM_TEST_POINT_ROLE_PLATFORM_IBV, NULL, TEST_POINT_BYTE2_END_OF_PEI_PCI_BUS_MASTER_DISABLED_ERROR_CODE \ TEST_POINT_END_OF_PEI \ TEST_POINT_BYTE2_END_OF_PEI_PCI_BUS_MASTER_DISABLED_ERROR_STRING ); Status = EFI_INVALID_PARAMETER; } // // If this is not a multi-function device, we can leave the loop // to deal with the next device. // HeaderType = PciSegmentRead8 (PCI_SEGMENT_LIB_ADDRESS(Segment, Bus, Device, Function, PCI_HEADER_TYPE_OFFSET)); if (Function == 0 && ((HeaderType & HEADER_TYPE_MULTI_FUNCTION) == 0x00)) { break; } } } } } } return Status; }