10_Protocols and Handles - manojkumarpaladugu/UEFI-BIOS-Development GitHub Wiki

Introduction:
The extensible nature of UEFI is built, to a large degree, around protocols. Protocols serve to enable communication between separately built modules, including drivers.

Drivers create protocols consisting of two parts. The body of a protocol is a C-style data structure known as a protocol interface structure, or just "interface". The interface typically contains an associated set of function pointers and data structures.

Every protocol has a GUID associated with it. The GUID serves as the name for the protocol. The GUID also indicates the organization of the data structure associated with the GUID. Note that the GUID is not part of the data structure itself.

Protocols are gathered into a single database. The database is not "flat."Instead, it allows protocols to be grouped together. Each group is known as a handle, and the handle is also the data type that refers to the group. The database is thus known as the handle database. Handles are allocated dynamically. Protocols are not required to be unique in the system, but they must be unique on a handle. In other words, a handle may not be associated with two protocols that have the same GUID.

Protocols are produced and consumed:
Protocols enable inter-module communication in UEFI. To enable this communication, one of the modules must create or "produce" the protocol. Other modules (including drivers) may then use or "consume" the protocol.

Drivers are both consumers and producers of protocols. For example, a UEFI Driver for a SCSI Host Controller on a PCI bus consumes the PCI I/O Protocol and produces the SCSI Host Controller Protocols.

Although it is legal to store data in a protocol, this is strongly discouraged for data items that may change over time. It is not a safe way to store dynamic data. Instead, functions that provide get/set operations (as in object-oriented programming) are safer and more extensible. The producer then uses InstallMultipleProtocolInterfaces() (as defined in the Boot Service chapter of the UEFI Specification) or similar to install the protocol into the handle database and make the protocol available to others.

The consumer has a somewhat simpler task. The consumer looks up the protocol in the handle database by GUID. With service protocols, for which there is only one instance in the entire handle database, the consumer can use the LocateProtocol() service. For protocols that may be present on multiple handles in the handle database, the LocateHandleBuffer() service can be used to locate the set of handles that support a specified protocol. The consumer can then use the OpenProtocol() service to lookup a protocol on a specific handle.

It is possible that the consumer is invoked before the producer. In this case, the consumer can request it be notified when new instances of the protocol are created. This is accomplished using the RegisterProtocolNotify() service.

Any UEFI image can use protocols during boot time. However, after ExitBootServices() is called, the handle database is no longer available to the image.

Construction of a protocol:
image

Multiple protocol instances:
Multiple protocols are installed on the same handle if the protocols provide services related to that one handle. There are several handle types. The most common are image handles and device handles. For example, if there are multiple I/O services for a single device that are abstracted through multiple protocols, then multiple protocols must be installed onto the handle for that device.

A handle may have many protocols attached to it. However, it may have only one protocol of each GUID name. In other words, a single handle may not produce more than one instance of any single protocol. This prevents nondeterministic behavior about which instance would be consumed by a given request. However, drivers may create multiple "instances" of a particular protocol and attach each instance to a different handle. This scenario is the case with the PCI I/O Protocol, where the PCI bus driver installs a PCI I/O Protocol instance for each PCI device. Each "instance" of the PCI I/O Protocol is configured with data values unique to that PCI device, including the location and size of the UEFI-conformant Option ROM (OpROM) image.

Tag Guid:
A protocol may be nothing more than a GUID with no associated data structure. This GUID is also known as a tag GUID. Such a protocol can be useful, for example, to mark a device handle as special in some way or allow other UEFI images to find the device handle easily by querying the system for the device handles with that protocol GUID attached.