UEFI里面的PCI驱动

还是顺着代码讲,首先找到入口函数在Core\EM\PCI\PciBus.c里面。

// Procedure: PciBusEntryPoint()
//
// Description: This function is the entry point for PCI BUS Driver.
// Since PCI BUS Driver follows EFI 1.1 driver model in it's entry point
// it will initialize some global data and install
// EFI_DRIVER_BINDING_PROTOCOL.
//
// Input:
// EFI_HANDLE	ImageHandle Image handle
// EFI_SYSTEM_TABLE *SystemTable Pointer to the EFI system table
//
// Output: EFI_STATUS
// EFI_SUCCESS 	When everything is going on fine!
// EFI_NOT_FOUND When something required is not found!
// EFI_DEVICE_ERROR When the device is not responding!
//
// Notes:
// Entry Points are used to locate or install protocol interface and
// notification events.

简单翻译一下,这个函数就是PCI BUS Driver 的入口,PCI BUS Driver遵守(follow)
EFI Driver model.它需要去初始化一些全局变量,以及安装EFI_DRIVER_BINDING_PROTOCOL.
后续会专门拿出一个章节来讲EFI DRIVER BINDING PROTOCOL
注意 Notes:
入口一般是用来locate 或者安装一些protocol interface 和notification event.

EFI_STATUS PciBusEntryPoint(INEFI_HANDLE        ImageHandle,

                                                        IN EFI_SYSTEM_TABLE *SystemTable)

{

//

//

//

这个函数最重要的就是下面这几句。

	//Install Multiple Prot Drv . Binding and Comp. Name
	Status = pBS->InstallMultipleProtocolInterfaces(
			&gPciBusDriverBinding.DriverBindingHandle,
			&gDriverBindingProtocolGuid,&gPciBusDriverBinding,
			NULL);
	// Here we can set up notification events if needed.
        
        //-----------------------------------------------------
	return Status;

在这里,它有去install 一个gPciBusDriverBinding Protocol. 这个protocol 还是在同一个文件里面。

EFI_DRIVER_BINDING_PROTOCOL gPciBusDriverBinding = {
	PciBusSupported,	// Supported
	PciBusStart,		// PciBusDrvStart,
	PciBusStop,		// PciBusDrvStop,
	NULL,			// Image Handle
 	NULL			// DriverBindingHandle
};

后续,我们就依次,逐个去分析这三个函数。

1.

// Procedure: PciBusSupported()
//
// Description: Suppoted Function of the EFI_DRIVER_BINDING_PROTOCOL
// for PCI Bus Driver.
//
// Notes:
// See EFI Specification for detail description
EFI_STATUS PciBusSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This,
            IN EFI_HANDLE        Controller,
            IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath)
{
    EFI_STATUS         Status;
    EFI_DEVICE_PATH_PROTOCOL     *ParentDevicePath;
    EFI_PCI_ROOT_BRIDGE_IO_PROTOCOL    *PciRootBridgeIo;
    EFI_DEVICE_PATH_PROTOCOL    *rdp=RemainingDevicePath;
//-----------------------------------------------------
    
    // Check if it is valid Device Path
    if (rdp != NULL) {
            if (isEndNode(rdp)) rdp = NULL:
        else {
        Status=CheckPciDevicePath(rdp);
        if (EFI_ERROR (Status)) return Status;
            }
         }
翻开uefi spec 277 页。

A Device Path is terminated by an End of Hardware Device Path node. This type of node has two sub_types

  • End This Instance of a Device Path(sub-type ox01). This type of node terminates one Device Path instance and denotes the start of another. This is only required when an environment variable represents multiple devices. An example of this would be the ConsoleOut environment variable that consist of both a VGA console and serial output console. This variable would describe a console output stream that is sent to both VGA and serial concurrently and thus has a Device Path that contains two complete Device paths.
  • End Entire Device Path(sub-type 0xFF). This type of node terminates an entire Device Path. Software searches for this sub-type to find the end of a Device Path. All Device Paths must end with this sub-type.
    Device Path End Structure
    MnemonicByte
    Offset
    Byte
    Length
    Description
    Type01Type 0x7F - End of Hardware Device Path
    Sub-Type11Sub-Type 0xFF -End Entire Device Path, or
    Sub-Type 0x01 - End This Instance of a Device Path and start a new Device Path
    Length22Length of this structure in bytes. Length is 4 bytes.

    // Open the IO Abstraction(s) needed to perform the supported test
    Status=pBS->openProtocol(Controller,
                &gDevicePathProtocolGuid,
                (VOID **)&ParentDevicePath,
                This->DriverBindingHandle,
                Controller,
                EFI_OPEN_PROTOCOL_BY_DRIVER);
    if (Status == EFI_ALREADY_STARTED) return EFI_SUCCESS;
    if (EFI_ERROR (Status)) return Status;
    
    pBS->CloseProtocol(Controller,&gDevicePathProtocolGuid,This->DriverBindingHandle,
              Controller);
    
    Status=pBS->OpenProtocol(Controller,
                &gPciRootBridgeIoProtocolGuid,
                (VOID **)&PciRootBridgeIo,
                This->DriverBindingHandle,
                Controller,
                EFI_OPEN_PROTOCOL_BY_DRIVER);
    if (Status==EFI_ALREADY_STARTED) return EFI_SUCCESS;

    pBS->CloseProtocol(Controller,&gPciRootBridgeIoProtocolGuid,This->DriverBindingHandle,
              Controller);

    return Status;
}

接下来,是PciBusStart()

这个函数主要是去枚举pci设备,然后去enable 各个设备。

 






评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值