17.1 Bus Specific Driver Override Protocol Implementation
The implementation of the Bus Specific Driver Override Protocol for a specific bus driver is typically found in the file BusSpecificDriverOverride.c. Appendix A contains a template for a BusSpecificDriverOverride.c file for a UEFI Driver. The list of tasks to implement the Bus Specific Driver Override Protocol feature are as follows:
- Add the
EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
instance to the design of the private context data structure. - Add private fields to the design of the private context data structure that
support managing the set of driver image handles returned by
GetDriver()
. - Update private content data structure initialization to initialize the Bus
Specific Driver Override Protocol instance and the private fields used to
manage the set of driver image handles returned by
GetDriver()
. - Implement the
GetDriver()
service to return set-of-driver image handles from the private context data structure. - Implement private worker functions to add/remove driver image handles from set-of-driver image handles maintained in the private context data structure.
- Install the Bus Specific Driver Override Protocol onto the child handle the
bus driver produces in the Driver Binding
Start()
function. - Uninstall the Bus Specific Driver Override Protocol from the child handle the
bus driver produces in the Driver Binding
Stop()
function.
The Bus Specific Driver Override Protocol contains one service called
GetDriver()
that returns an ordered list of driver image handles for the UEFI
drivers that were loaded from a container of UEFI driver(s). There are many
ways to implement storage for the ordered list of driver image handled
including an array and linked lists.
PCI Use Case
: The order in which the image handles are returned by the PCI
Bus Driver matches the order in which the UEFI drivers were found in the PCI
option ROM, from the lowest address to the highest address. The PCI bus driver
is responsible for enumerating the PCI devices on a PCI bus. When a PCI device
is discovered, the PCI device is also checked to see if it has an attached PCI
option ROM. The PCI option ROM contents must follow the PCI Specification for
storing one or more images. The PCI bus driver walks the list of images in a
PCI option ROM looking for UEFI drivers. If a UEFI driver is found, it is
optionally decompressed using the Decompress Protocol and then loaded The
driver entry point is called using the UEFI boot services LoadImage()
and
StartImage()
. If LoadImage()
does not return an error, the UEFI driver must
be added to the end of the list of drivers the Bus Specific Driver Override Protocol
for that PCI device returns after the GetDriver()
service is called.
The example below shows the protocol interface structure for the Bus Specific
Driver Override Protocol for reference and is composed of a single service
called GetDriver()
.
Example 162-Bus Specific Driver Override Protocol
typedef struct _EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL
EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL;
///
/// This protocol matches one or more drivers to a controller. This protocol
/// is produced by a bus driver, and it is installed on the child handles of
/// buses that require a bus specific algorithm for matching drivers to
/// controllers.
///
struct _EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_PROTOCOL {
EFI_BUS_SPECIFIC_DRIVER_OVERRIDE_GET_DRIVER GetDriver;
};