编写一个DXE driver 提供遍历pcie设备配置空间的protocol
PCIe (Peripheral Component Interconnect Express)设备配置空间是每个 PCIe 设备都具有的一个标准化寄存器集合,用于存储设备的硬件信息、资源需求和功能配置。
它分为两部分:
- PCI 兼容配置空间(前 256 字节):
与传统 PCI 设备兼容,包含设备的基本信息,如设备 ID、供应商 ID、类代码等。
包括 64 字节的 Header 和 192 字节的能力结构。 - PCIe 扩展配置空间(从 0x100 到 0xFFF,共 4096 字节):
提供额外的配置寄存器,支持更高级的功能,如 PCIe 能力寄存器。
扩展能力寄存器以链表形式管理,每个寄存器包含一个能力 ID 和一个指向下一个寄存器的指针。
.dsc
#
# create a new DXE protocol to traverse PcieMdeModulePkg/Universal/TraversePcieDxe/TraversePcieDxe.inf {<LibraryClasses>BasePciExpressLib|MdePkg/Library/BasePciExpressLib/BasePciExpressLib.inf}
#
.fdf
#
# create a new DXE protocol to traverse Pcie
INF MdeModulePkg/Universal/TraversePcieDxe/TraversePcieDxe.inf
#
.dec
# # create a new DXE protocol to traverse Pcie## Include/Protocol/TraversePcie.hgEfiTraversePcieProtocolGuid = { 0xAD3316CA, 0x5B03, 0xEFE4, {0x54, 0xE5, 0xF7, 0xC5, 0x04, 0x6E, 0x29, 0xD5 }}#
.inf
## @file
#
#
##[Defines]INF_VERSION = 0x00010005BASE_NAME = TraversePcieDxeFILE_GUID = AD3316CA-5B03-EFE4-54E5-F7C5046E29D5MODULE_TYPE = DXE_DRIVERVERSION_STRING = 1.0ENTRY_POINT = TraversePcieEntryPoint#
# The following information is for reference only and not required by the build tools.
#
# VALID_ARCHITECTURES = IA32 X64 EBC
#[Sources]
TraversePcie.c[Packages]MdePkg/MdePkg.decMdeModulePkg/MdeModulePkg.dec[LibraryClasses]DevicePathLibUefiBootServicesTableLibUefiDriverEntryPointBasePciExpressLibDebugLib[Protocols]gEfiTraversePcieProtocolGuid ## PRODUCES[Depex]TRUE
.c
/** @fileCopyright (c) 2006 - 2013, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent**/#include <Protocol/TraversePcie.h>
#include <Uefi.h>
#include <Library/UefiDriverEntryPoint.h>
#include <Library/UefiBootServicesTableLib.h>
#include <Library/DevicePathLib.h>
#include <Library/PcdLib.h>
#include <Library/PciExpressLib.h>
#include <Library/DebugLib.h>EFI_STATUS
EFIAPI
ToTraversePcie(IN CONST EFI_TRAVERSE_PCIE_PROTOCOL *ReadPcieNode)
{UINTN StartAddress;UINTN Size;UINT8 Buffer[4352];EFI_STATUS Status;StartAddress = 0xE0000000;Size = sizeof(Buffer);DEBUG((DEBUG_INFO,"\n\nStart to PCIeReadBuffer\n\n"));Status = PciExpressReadBuffer (StartAddress,Size,&Buffer);UINTN OX = 0;DEBUG((DEBUG_INFO,"\nPCIe: \n"));for (int index = 0; index < Size; index++){DEBUG((DEBUG_INFO,"%u ",Buffer[index]));OX++;if (OX == 15){OX = 0;DEBUG((DEBUG_INFO,"\n"));}}return Status;}GLOBAL_REMOVE_IF_UNREFERENCED CONST EFI_TRAVERSE_PCIE_PROTOCOL mTraversePcie = {ToTraversePcie
};EFI_STATUS
EFIAPI
TraversePcieEntryPoint (IN EFI_HANDLE ImageHandle,IN EFI_SYSTEM_TABLE *SystemTable)
{EFI_STATUS Status;EFI_HANDLE Handle;Handle = NULL;Status = EFI_UNSUPPORTED;DEBUG((DEBUG_INFO,"\n\nStart to traverse PCIe\n\n"));Status = gBS->InstallMultipleProtocolInterfaces (&Handle,&gEfiTraversePcieProtocolGuid,&mTraversePcie,NULL);return Status;
}
.h
/** @fileCopyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>SPDX-License-Identifier: BSD-2-Clause-Patent**/#ifndef __TRAVERSE_PCIE_PROTOCOL_H__
#define __TRAVERSE_PCIE_PROTOCOL_H__///
/// Traverse Pcie protocol
///
#define EFI_TRAVERSE_PCIE_PROTOCOL_GUID \{ \0xAD3316CA, 0x5B03, 0xEFE4, {0x54, 0xE5, 0xF7, 0xC5, 0x04, 0x6E, 0x29, 0xD5 } \}typedef struct _EFI_TRAVERSE_PCIE_PROTOCOL EFI_TRAVERSE_PCIE_PROTOCOL;typedef
EFI_STATUS
(EFIAPI *EFI_TRAVERSE_PCIE)(IN CONST EFI_TRAVERSE_PCIE_PROTOCOL *ReadPcieNode);struct _EFI_TRAVERSE_PCIE_PROTOCOL {EFI_TRAVERSE_PCIE ReadPcie;
};extern EFI_GUID gEfiTraversePcieProtocolGuid;#endif

