一、支持访问PCI/PCIE设备的Protocol
UEFI中提供了两个主要的模块来支持PCI总线,一是PCI Host Bridge(PCI主桥)控制器驱动,另一个是PCI总线驱动。这两个模块是和特定的平台硬件绑定的,在这种机制下,屏蔽了不同的CPU架构差异,为软件开发者提供了比较一致的Protocol接口。
UEFI标准中提供了两类访问PCI/PCIE设备的Protocol——EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL和EFI_PCI_IO_PROTOCOL。前者为PCI根桥提供了抽象的IO功能,它由PCI Host Bus Controller(PCI主总线驱动器)产生,一般由PCI/PCIe总线驱动用来枚举设备、获得Option ROM、分配PCI设备资源等;后者由PCI/PCIE总线驱动为PCI/PCIE设备产生,一般由PCI/PCIE设备驱动用来访问PCI/PCIE设备的IO空间、Memory空间和配置空间。
1.1 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL提供了基本的内存、输入/输出(I/O)、PCI配置和直接访问内存的接口,这些接口用于将PCI控制器后面的PCI根桥控制器的访问进行抽象。
typedef struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL;
/// Provides the basic Memory, I/O, PCI configuration, and DMA interfaces that are
/// used to abstract accesses to PCI controllers behind a PCI Root Bridge Controller.
///提供了基本内存,I/O,PCI配置和直接内存访问(DMA)接口,这些接口用于抽象PCI控制器后PCI根桥的访问
struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL {
///
/// The EFI_HANDLE of the PCI Host Bridge of which this PCI Root Bridge is a member.
/// 这是PCI根桥所属的PCI主机桥的EFI_HANDLE
EFI_HANDLE ParentHandle; //包含这个PCI根桥的PCI主机桥的Handle
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM PollMem; //一个函数指针,指向用于轮询内存映射I/O空间的协议方法
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM PollIo; //一个函数指针,指向用于轮询I/O空间的协议的方法
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Mem; //一个函数指针,指向用于访问内存的协议方法
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Io; //一个函数指针,指向用于访问I/O空间的协议方法
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Pci; //一个函数指针,指向用于访问PCI配置空间的协议方法
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_COPY_MEM CopyMem; //一个函数指针,指向用于复制内存的协议方法
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_MAP Map; //一个函数指针,指向用于映射内存或I/O空间的协议方法
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_UNMAP Unmap; //一个函数指针,指向用于取消映射内存或I/O空间的协议方法
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ALLOCATE_BUFFER AllocateBuffer; //一个函数指针,用于指向分配内存缓冲区的协议方法
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FREE_BUFFER FreeBuffer; //一个函数指针,指向释放内存缓冲区的协议方法
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_FLUSH Flush; //一个函数指针,指向用于刷新缓存的协议方法
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_GET_ATTRIBUTES GetAttributes; //一个函数指针,指向用于获取PCI根桥属性的协议方法
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_SET_ATTRIBUTES SetAttributes; //一个函数指针,指向用于设置PCI根桥属性的协议方法
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_CONFIGURATION Configuration; //一个函数指针,指向配置PCI根桥的协议方法
///
/// The segment number that this PCI root bridge resides. PCI根桥所在的段号
///
UINT32 SegmentNumber;
};
在这里只介绍访问内存的接口Mem、访问I/O空间的接口Io、访问PCI配置空间的接口Pci。这三个接口的参数类型是一样的,都是EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS
typedef struct {
/// Read PCI controller registers in the PCI root bridge memory space.
/// 读数据
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_IO_MEM Read;
/