UEFI principles and Programming (ix): How to use protocol in UEFI

Source: Internet
Author: User
Tags error code function prototype
How to use protocol in UEFI Preface

Start-up service provides a wealth of services for developers to operate protocol, we can use protocol can also develop protocol. This article mainly describes how to use protocol.
The use of protocol is generally divided into the following three steps:
1. Identify the Protocol object by initiating the service;
2. Use of the services provided by this Protocol;
3. Close the Open protocol
You can use the Openprotocolinformation service to view all the devices that open a protocol.
There are four types of start-up services, namely: Openprotocol, Handleprotocol, Locateprotocol and Localhandlebuffer. They are described separately below. First, Openprotocol service

Openprotocol is used to query whether the specified protocol is supported in the specified handle, and if so, the protocol is turned on, otherwise an error code is returned.
Openprotocol function prototypes in BS (Start-up service):

typedef
Efi_status
(Efiapi *efi_open_protocol) (in
    Efi_handle HANDLE, in
    efi_guid *protocol,
    Out VOID **interface,  OPTIONAL in
    efi_handle agenthandle, in
    efi_handle controllerhandle, in
    UINT32 Attributes
);

return value:

return value Description
Efi_success The interface information for the specified protocol was returned.
efi_unsupported The device does not support the specified protocol.
Efi_invalid_parameter Handle is NULL.
Efi_invalid_parameter Protocol is NULL.
Efi_invalid_parameter Interface is NULL.
Handle: Query Handle provides Protocol *protocol: Protocol to open (pointer to secondary Protocol GUID) **interface: Returns an open Protocol object Agenthandle: Open the image controllerhandle for this protocol: Open the Controller for this Protocol

Attributes: How to open this Protocol

Handle is the provider of the Protocol, if the Protocol is in the protocols list of handle, the pointer to the Protocol object is written to *interface, and efi_success is returned, otherwise efi_ Unsupported.
If Openprotocol is called in the driver, then Controllerhandle is the controller that owns the driver, which is the controller that requests the Protocol; Agenthandle is the Efi_driver_binding_ The handle of the Protocol object. Efi_driver_binding_protocol is a protocol that will be used by UEFI driver Development, which is responsible for driver installation and uninstallation.
If the application is called Openprotocol, then Agenthandle is the handle of the utility, which is the first parameter of Uefimain, which can be ignored at this time.
List of attribute values:
 
Note: Screenshots are from Uefi Spec 2_6. Refer to Uefi Spec for this section.

Openhandle Sample Program Snippet:

Open Blockio Efi_handle imagehandle;
Efi_driver_binding_protocol *this;
In Efi_hadnle controllerhandle; extern efi_guid Blockioprotocolguid;
Efi_block_io_protocol *blockio;
Efi_status STATUS;                     Using Openprotocol in your application, the general Controllerhandle will be set to null Status = Gbs->openprotocol (Controllerhandle, Handle &gefiblockioprotocolguid,//protocol &blockio,//INTERFAC
    E Imagehandle,//agenthandle NULL,//controllerhandle Efi_open_protocol_by_handle_protocol//attribute)//used in the drive, Openprotocol, Controllerhandle is the HANDLE Status of the Controller = gBS- >openprotocol (Controllerhandle,//handle &gefiblockioprotocolguid,//proto
    Col &blockio,//interface This->driverbindinghandle,//agenthandle Controllerhandle,//controllerhandle Efi_open_protocoL_get_protocol//attribute) 

Gefiblockioprotocolguid is a global variable, and the variable is defined in AUTOGEN.C. AUTOGEN.C is generated by the build tool based on the. inf and. Dec files, Gefiblockioprotocolguid is a variable of type Efi_guid and its efi_guid value is defined in. Dec. If you want to use Gefiblockioprotocolguid in an application or driver, you must declare it in [protocols] in the. inf file so that it is included in the AUTOGEN.C when it is preprocessed. Second, Handleprotocol service

The Openprotocol function is powerful, but the use is more complex, need to provide handle and protocol GUID, also provide Agenthandle, controllerhandle and attributes. But most of the time developers just want to get protocol objects through the Protocol GUID, and don't care about the details of how to open them. To make it easier for developers to use protocol, the start-up service provides handleprotocol to simplify opening protocol.
function prototypes for Handleprotocol services:

typedef
Efi_status
(Efiapi *efi_handle_protocol) (in
    Efi_handle HANDLE, in
    efi_guid *protocol,
    Out VOID **interface
);
return value Description
Efi_success The interface information for the specified protocol was returned.
efi_unsupported The device does not support the specified protocol.
Efi_invalid_parameter Handle is NULL.
Efi_invalid_parameter Protocol is NULL.
Efi_invalid_parameter Interface is NULL.

Handleprotocol is a simplified version of Openprotocol, which eliminates the need to pass in Agenthandle, Controllerhandle, and attribute when calling Handleprotocol. Its interior is actually still called the Openprotocol.
Handleprotocol's internal implementation:

Efi_status
Handleprotocol (
    in Efi_handle HANDLE, in
    efi_guid *protocol, out
    VOID **interface
)
{
    return Openprotocol (
        Handle,
        Protocol,
        Interface,
        eficoreimagehandle,
        NULL,
        efi_open_protocol_by_handle_protocol
    );
}

Handleprotocol Use Example:

Status = Gbs->handleprotocol (
    controllerhandle,                     //handle
    &gefiblockioprotocolguid,             // Protocol
    &blockio,                             //interface   
)
Third, Locateprotocol service

Openprotocol and Handleprotocol are used to open a protocol on a specified device, and to use these two functions, the first thing to do is to get a handle to the device. Sometimes the developer does not care about which device the protocol is on, especially when the system has only one instance of the protocol. The start service provides a locateprotocol (... ) service, which can find the first instance of the specified protocol from the UEFI kernel.
Locateprotocol Service function Prototype:

typedef
Efi_status
(Efiapi *efi_locate_protocol) (in
    efi_guid *protocol, in
    VOID *registration, OPTIONAL out
    VOID **interface
);
return value Description
Efi_success A protocol Instance matching protocol is found and returned in Interface.
Efi_invalid_parameter Interface is NULL.
Efi_not_found No protocol instances were found that match protocol and registration.

There may be more than one instance of a protocol in the UEFI kernel, for example, one Efi_disk_io_protocol instance per hard disk and each partition. Locateprotocol sequentially searches the handle linked list, returning the first instance of the protocol found.
The following example is used to find the first Simple_file_system_protocol instance in the system.

efi_simple_file_syste_protocol* simplefs;
Gbs->locateprotocol (
    gefisimplefilesystemprotocolguid,
    NULL,
    &simplefs
);
Iv. Locateprotocolbuffer Services

The first three are methods of finding protocol from the device. Sometimes developers need to find all the devices that support a protocol, such as finding all the devices that have Blockio installed in the system. Locatehandle and Locateprotocolbuffer provide this service.
Locateprotocolbuffer function Prototypes:

typedef
Efi_status
(Efiapi *efi_locate_handle_buffer) (
    in Efi_locate_search_type searchtype,//Lookup mode In
    efi_guid *protocol OPTIONAL,       //specified Protocol
    in VOID *searchkey OPTIONAL,          type of//protocol_notify
    in Out Uintn *nohandles,              //Returns the number of HANDLE found out
    efi_handle **buffer               //allocates HANDLE array and returns
);
return value Description
efi_success The array of handles was returned.
efi_not_found No handles match the search.
efi_buffer_too_small The buffersize is TOO SMALL for the result. BufferSize have been updated with the size needed to complete the request.
efi_invalid_parameter SearchType is not a member of Efi_locate_search_type
efi_invalid_parameter searchtype is byregisternotify and Searchkey is NULL.
efi_invalid_parameter searchtype is Byprotocol and Protocol is NULL.
efi_invalid_parameter One or more matches be found and buffersize is NULL.
efi_invalid_parameter buffersize is large enough for the result and Buffer is NULL.

There are three kinds of searchtype: Allhandles used to find out all the handle;byregisternotify in the system for finding all matching searchkey from registerprotocolnotify handle The Byprotocol is used to find handle that support the specified protocol from the system handle database.
Type definitions for SearchType:

typedef enum{
    Allhandles,
    byregisternotify,
    byprotocol
} efi_locate_search_type;

Locatehandle Service function Prototype:

typedef
Efi_status
(Efiapi *efi_locate_handle) (
    in Efi_locate_search_type searchtype, in
    efi_guid * Protocol OPTIONAL, in
    VOID *searchkey OPTIONAL, in Out
    uintn *buffersize, out Efi_handle *buffer
);
return value Description
efi_success The array of handles was returned.
efi_not_found No handles match the search.
efi_buffer_too_small The buffersize is TOO SMALL for the result. BufferSize have been updated with the size needed to complete the request.
efi_invalid_parameter SearchType is not a member of Efi_locate_search_type
efi_invalid_parameter searchtype is byregisternotify and Searchkey is NULL.
efi_invalid_parameter searchtype is Byprotocol and Protocol is NULL.
efi_invalid_parameter One or more matches be found and buffersize is NULL.
efi_invalid_parameter buffersize is large enough for the result and Buffer is NULL.

The biggest difference between the Locatehandle service and the Locatehandlebuffer service is that the caller is responsible for managing the memory occupied by the buffer array. v. Other protocol services

In addition to protocol and finding devices based on protocol these commonly used services, start the service about using protocol services there are Protocolsperhandle and openprotocolinformation. 1. Protocolsperhandle

The protocolsperhandle is used to obtain all the protocol supported by the specified device. These protocol GUIDs are returned by Protocolbuffer to the caller, and UEFI is responsible for allocating memory to Protocolbuffer, which is responsible for freeing the memory.
  
Protocolsperhandle function Prototypes:

typedef
Efi_status
(Efiapi *efi_protocols_per_handle) (
    in Efi_handle HANDLE, out
    efi_guid * * * Protocolbuffer, out
    uintn *protocolbuffercount
);
return value Description
Efi_success The list of protocol interface GUIDs installed on Handle is returned in Protocolbuffer. The number of protocol interface GUIDs is returned in Protocolbuffercount.
Efi_invalid_parameter Handle is NULL.
Efi_invalid_parameter Protocolbuffer is NULL.
Efi_invalid_parameter Protocolbuffercount is NULL.
Efi_out_of_resources There isn't enough pool memory to store the results
2. Openprotocolinformation

The openprotocolinformation is used to obtain open information for the specified protocol on the specified device.

Openprotocolinformation function Prototypes:

typedef
Efi_status
(Efiapi *efi_open_protocol_information) (
    in Efi_handle HANDLE, in
    efi_guid * Protocol, out
    efi_open_protocol_information_entry **entrybuffer, out
    uintn *entrycount
);  
return value Description
Efi_success The Open protocol information is returned in Entrybuffer,and the number of entries is returned entrycount.
Efi_not_found Handle does not a support for the protocol specified by protocol.
Efi_out_of_resources There is not enough resources available to allocate entrybuffer.
Efi_open_protocol_information_entry data Structure
typedef struct {
    efi_handle agenthandle;
    Efi_handle Controllerhandle;
    UINT32 Attributes;
    UINT32 opencount;
} Efi_open_protocol_information_entry;

Handle is the handle to this device, and the open information is stored in the Protocol_interdace openlist list. The same protocol on the device may be turned on and off many times. Protocol updates the Openlist list each time it is successfully opened and closed. After successful opening, a efi_open_protocol_information_entry is added to the device handle, if an item already exists in the Openlist list with the current (Agenthandle,controllerhandle, Attributes) is exactly the same, the item Opencount plus one. Closing protocol will reduce the opencount of the openlist counterpart by one, and opencount delete the corresponding item when it is zero. Vi. Closeprotocol Services

Protocol you need to close the open protocol with Closeprotocol after you have finished using it.
Closeprotocol function Prototypes:

typedef
Efi_status
(Efiapi *efi_close_protocol) (in
    Efi_handle HANDLE, in
    efi_guid *protocol,
    in Efi_handle Agenthandle,
    In Efi_handle controllerhandle
);
return value description
efi_success the protocol instance was closed.
efi_invalid_parameter Handle is NULL.
efi_invalid_parameter agenthandle is NULL.
efi_invalid_parameter controllerhandle is isn't null and Controllerhandle is null.
efi_invalid_parameter Protocol is NULL.
efi_not_found Handle does not support the protocol specified by protocol.
efi_not_found The protocol interface specified by Handle and protocol are not currently Open by Agenthandle and Controllerhandle.

The protocol opened through Handleprotocol and Locateprotocol cannot be closed because no agenthandle is specified. If you must close it, call Openprotocolinformation () to get agenthandle and Controllerhandle, and then close it. Vii. Summary

This part, do not live to explain the use of protocol method. Protocol provides a way to communicate between UEFI applications and UEFI drivers. With protocol, users can use the services provided by the driver, as well as other services provided by the system. Be familiar with the data structure of the protocol you use. reference "UEFI principles and Programming" Uefi Spec 2_6 EDK2 GitHub

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.