UEFI里面的PCI驱动

来源:互联网 发布:java职业生涯规划 编辑:程序博客网 时间:2024/05/22 01:33

还是顺着代码讲,首先找到入口函数在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_HANDLEImageHandle 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. NameStatus = 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,// SupportedPciBusStart,// 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 StructureMnemonicByte
    OffsetByte
    LengthDescriptionType01Type 0x7F - End of Hardware Device PathSub-Type11Sub-Type 0xFF -End Entire Device Path, or
    Sub-Type 0x01 - End This Instance of a Device Path and start a new Device PathLength22Length 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 各个设备。

 






0 0
原创粉丝点击