标签:
写在最前,摘自 K&R
The only legal operations on a structure are copying it or assigning to it as a unit, taking its address with & (读作
ampersand), and accessing its members,
翻译成中文是这样的,对于一个结构体而言,唯一合法的操作是把它当成一个整体去给它赋值,或者拷贝到另一个地方。
取它的地址,访问它的成员。
UEFI 定义了很多个I (interface). 说穿了,就是函数指针,或者函数原型,它定义了这个interface
需要有哪些功能,需要有哪些参数。至于这个函数的具体实现,各IBV就怎么搞都可以了。比如
EFI_PCI_IO_PROTOCOL.Pollmem() 摘自 UEFI SPEC Chapter 13.
Reads from the memory space of a PCI Root Bridge.
从pci root bridge 中去读(一段数据)
函数原型
typedef
EFI_STATUS
(EFI *API_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM) (
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This,
IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width,
IN UINT64 Address,
IN UINT64 Mask,
IN UINT64 Value,
IN UINT64 Delay,
OUT UINT64 *Result
);
参数
This 一个指向EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL的指针
Width 标识出对内存操作的宽度
Address 内存操作的基地址,调用这个函数的函数有义务去给它赋一个明确的值
Mask 用来去检测polling(轮询)的标准,即是否达到了结束轮询的标准
Value 用来和退出标准去比较的一个值
Dealy 以100纳秒为单位去延时。
Result 一个指针,指向操作后最后读的那个值。pointer to the last value read from the
memory location.
读多大,则取决于参数 width, 这个操作会重复进行直到timeout,(以100纳秒为单位) 或者 Resut & Mask = Value.
....
说了这么一大堆,可是我们应该怎么去实现这个函数呢?
首先,它是对pci 内存的操作,所以,BIOS 代码中,肯定会大量用到,我们以它为关键字,用source insight 搜一下。
返回两个结果:
typedef EFI_STATUS (EFIAPI *EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM)( IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL *This, IN EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH Width, IN UINT64 Address, IN UINT64 Mask, IN UINT64 Value, IN UINT64 Delay, OUT UINT64 *Result );
struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL {
///
/// The EFI_HANDLE of the PCI Host Bridge of which this PCI Root Bridge is a member.
///
EFI_HANDLE ParentHandle;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM PollMem;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_POLL_IO_MEM PollIo;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Mem;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Io;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_ACCESS Pci;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_COPY_MEM CopyMem;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_MAP Map;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_UNMAP Unmap;
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;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_SET_ATTRIBUTES SetAttributes;
EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_CONFIGURATION Configuration;
///
/// The segment number that this PCI root bridge resides.
///
UINT32 SegmentNumber;
}既然是一个类型,那与int , float , double ,本质上,也就是一样的,标识出不同的长度而已。
这时候,回到文章最开始,对于结构体的操作,只可能把它作为一个整体去赋值。
那么我们以这个结构体的名字为关键字去搜一把
typedef struct _EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL;
它把这种类型,重命名为了 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL。 以后_EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL 就是 EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL
那就以EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL 再搜一把,这时候,出来一大片,因为到处都要用下,这也正是UEFI的精华所在
可以看到,绝大多数情况都是声明了一个指向这个结构体类型的指针(方便使用嘛)
但是!! 顺着找,可以有这么一段:
static EFI_PCI_IO_PROTOCOL gPciIoInstance = {
PciIoPollMem,
PciIoPollIo,
{
PciIoMemRead,
PciIoMemWrite
},
{
PciIoIoRead,
PciIoIoWrite
},
{
PciIoConfigRead,
PciIoConfigWrite
},
PciIoCopyMem,
PciIoMap,
PciIoUnmap,
PciIoAllocateBuffer,
PciIoFreeBuffer,
PciIoFlush,
PciIoGetLocation,
PciIoAttributes,
PciIoGetBarAttributes,
PciIoSetBarAttributes,
0, //RomSize;
NULL //RomImage
};// Procedure: PciIoMemRead()
//
// Description: Protocol Function Performs a PCI Memory Read Cycle
//
// Notes: See EFI Specification for detail description
//
//----------------------------------------------------------------------------
//<AMI_PHDR_END>
EFI_STATUS PciIoMemRead(IN EFI_PCI_IO_PROTOCOL *This,
IN EFI_PCI_IO_PROTOCOL_WIDTH Width,
IN UINT8 BarIndex,
IN UINT64 Offset,
IN UINTN Count,
IN OUT VOID *Buffer)
{
EFI_STATUS Status;
PCI_DEV_INFO *dev=(PCI_DEV_INFO*)This;
//---------------------------------------------
if (Width < 0 || Width >= EfiPciIoWidthMaximum) return EFI_INVALID_PARAMETER;
Status=PciIoCheckBar(dev, BarIndex, tBarMem, Width, Count, &Offset);
if(EFI_ERROR(Status)) return EFI_UNSUPPORTED;
Status=dev->RbIo->Mem.Read(dev->RbIo,(EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL_WIDTH)Width,
Offset, Count, Buffer);
return Status;
标签:
原文地址:http://blog.csdn.net/robinsongsog/article/details/42396837