Tables
Figures
Examples
Acknowledgements
1 Introduction
1.1 Overview
1.2 Organization of this document
1.3 Related information
1.3.1 UEFI Specifications
1.3.2 Industry Standard Bus Specifications
1.3.3 Other specifications
1.3.4 EDK II and UDK2010 Development Kit
1.4 Typographic conventions
2 UEFI Driver Implementation Checklist
2.1 Design and implementation of UEFI drivers
2.2 How to implement features in EDK II
3 Foundation
3.1 Basic programming model
3.2 Objects managed by UEFI-based firmware
3.3 UEFI system table
3.4 Handle database
3.5 GUIDs
3.6 Protocols and handles
3.6.1 Protocols are produced and consumed
3.6.2 Protocol interface structure
3.6.3 Protocols provided in addition to the UEFI Specification
3.6.4 Multiple protocol instances
3.6.5 Tag GUID
3.7 UEFI images
3.7.1 Applications
3.7.2 Drivers
3.8 Events and task priority levels
3.8.1 Defining priority
3.8.2 Creating locks
3.8.3 Using callbacks
3.9 UEFI device paths
3.9.1 How drivers use device paths
3.9.2 IPF Considerations for device path data structures
3.9.3 Environment variables
3.10 UEFI driver model
3.10.1 Device driver
3.10.2 Bus driver
3.10.3 Hybrid driver
3.11 Service Drivers
3.12 Root Bridge Driver
3.13 Initializing Driver
3.14 UEFI Driver Model Connection Process
3.14.1 ConnectController()
3.14.2 Loading UEFI option ROM drivers
3.14.3 DisconnectController()
3.15 Platform initialization
3.15.1 Connecting PCI Root Bridges
3.15.2 Connecting the PCI bus
3.15.3 Connecting consoles
3.15.4 Console drivers
3.15.5 Console variables
3.15.6 ConIn
3.15.7 ConOut
3.15.8 ErrOut
3.15.9 Boot Manager Connect All Processing
3.15.10 Boot Manager Driver List Processing
3.15.11 Boot Manager BootNext Processing
3.15.12 Boot Manager Boot Option Processing
4 General Driver Design Guidelines
4.1 Common Coding Practices
4.1.1 Type Checking
4.1.2 Avoid Name Collisions
4.1.3 Maximize Warning Levels
4.1.4 Compiler Optimizations
4.2 Maximize Platform Compatibility
4.2.1 Never Assume all UEFI Drivers are Executed
4.2.2 Eliminate System Memory Assumptions
4.2.3 Use UEFI Memory Allocation Services
4.2.4 Do not make assumptions
4.2.5 Never Directly Access Hardware Resources
4.2.6 Memory ordering
4.2.7 DMA
4.2.8 Supporting Older EFI Specifications and UEFI Specifications
4.2.9 Reduce Poll Frequency
4.2.10 Minimize Time in Notification Functions
4.2.11 Use Proper Task Priority Levels
4.2.12 Design to be re-entrant
4.2.13 Do not use hidden PCI Option ROM Regions
4.2.14 Store Configuration Data with Device
4.2.15 Do not use hard-coded device path nodes
4.2.16 Do not cause errors on shared storage devices
4.2.17 Limit use of Console Services
4.2.18 Offer alternatives to function keys
4.3 Maximize CPU Compatibility
4.3.1 Assignment and comparison operators
4.3.2 Casting pointers
4.3.3 Converting pointers
4.3.4 UEFI Data Type Sizes
4.3.5 Negative Numbers
4.3.6 Returning Pointers in a Function Parameter
4.3.7 Array Subscripts
4.3.8 Piecemeal Structure Allocations
4.4 Optimization Techniques
4.4.1 Size Reduction
4.4.2 Performance Optimizations
4.4.3 CopyMem() and SetMem() Operations
5 UEFI Services
5.1 Services that UEFI drivers commonly use
5.1.1 Memory Allocation Services
5.1.2 Miscellaneous Services
5.1.3 Handle Database and Protocol Services
5.1.4 Task Priority Level(TPL) Services
5.1.5 Event services
5.1.6 SetTimer()
5.1.7 Stall()
5.2 Services that UEFI drivers rarely use
5.2.1 ConnectController() and DisconnectController()
5.2.2 ReinstallProtocolInterface()
5.2.3 LocateDevicePath()
5.2.4 LoadImage() and StartImage()
5.2.5 GetVariable() and SetVariable()
5.2.6 QueryVariableInfo ()
5.2.7 GetTime()
5.2.8 CalculateCrc32()
5.2.9 ConvertPointer()
5.2.10 InstallConfigurationTable()
5.2.11 GetNextMonotonicCount()
5.3 Services that UEFI drivers should not use
5.3.1 InstallProtocolInterface()
5.3.2 UninstallProtocolInterface()
5.3.3 HandleProtocol()
5.3.4 LocateHandle()
5.3.5 ProtocolsPerHandle()
5.3.6 RegisterProtocolNotify()
5.3.7 UnloadImage()
5.3.8 GetNextVariableName()
5.3.9 SetWatchdogTimer()
5.3.10 SetTime(), GetWakeupTime(), and SetWakeupTime()
5.3.11 GetMemoryMap()
5.3.12 ExitBootServices()
5.3.13 SetVirtualAddressMap()
5.3.14 QueryCapsuleCapabilities()
5.3.15 UpdateCapsule()
5.3.16 ResetSystem()
5.3.17 Exit()
5.3.18 GetNextHighMonotonicCount()
6 UEFI Driver Categories
6.1 Device drivers
6.1.1 Required Device Driver Features
6.1.2 Optional Device Driver Features
6.1.3 Compatibility with Older EFI/UEFI Specifications
6.1.4 Device drivers with one driver binding protocol
6.1.5 Device drivers with multiple driver binding protocols
6.1.6 Device driver protocol management
6.2 Bus drivers
6.2.1 Required Bus Driver Features
6.2.2 Optional Bus Driver Features
6.2.3 Bus drivers with one driver binding protocol
6.2.4 Bus drivers with multiple driver binding protocols
6.2.5 Bus driver protocol and child management
6.2.6 Bus drivers that produce one child in Start()
6.2.7 Bus drivers that produce all children in Start()
6.2.8 Bus drivers that produce at most one child in Start()
6.2.9 Bus drivers that produce no children in Start()
6.2.10 Bus drivers that produce children with multiple parents
6.3 Hybrid drivers
6.3.1 Required Hybrid Driver Features
6.3.2 Optional Hybrid Driver Features
6.4 Service Drivers
6.5 Root Bridge Drivers
6.6 Initializing Drivers
7 Driver Entry Point
7.1 Optional Features
7.2 UEFI Driver Model
7.2.1 Single Driver Binding Protocol
7.2.2 Multiple Driver Binding Protocols
7.2.3 Adding Driver Health Protocol Feature
7.2.4 Adding Driver Family Override Protocol Feature
7.3 Adding the Driver Supported EFI Version Protocol Feature
7.4 Adding HII Packages Feature
7.5 Adding HII Config Access Protocol Feature
7.6 Adding the Unload Feature
7.7 Adding the Exit Boot Services feature
7.8 Initializing Driver entry point
7.9 Service Driver entry point
7.10 Root bridge driver entry point
7.11 Runtime Drivers
8 Private Context Data Structures
8.1 Containing Record Macro
8.2 Data structure design
8.3 Allocating private context data structures
8.4 Freeing private context data structures
8.5 Retrieving private context data structures
9 Driver Binding Protocol
9.1 Driver Binding Protocol Implementations
9.2 Driver Binding Protocol Template
9.3 Testing Driver Binding Protocol
10 UEFI Service Binding Protocol
10.1 Service Binding Protocol Implementations
10.2 Service Driver
10.3 UEFI Driver Model Driver
11 UEFI Driver and Controller Names
11.1 Component Name Protocol Implementations
11.2 GetDriverName() Implementations
11.3 GetControllerName() Implementations
11.3.1 Device Drivers
11.3.2 Bus Drivers and Hybrid Drivers
11.4 Testing Component Name Protocols
12 UEFI Driver Configuration
12.1 HII overview
12.1.1 HII Database and Package Lists
12.2 General steps for implementing HII functionality
12.3 HII Protocols
12.3.1 HII Database Protocol and HII String Protocol
12.3.2 HII Config Routing Protocol
12.3.3 HII Config Access Protocol
12.3.4 Rarely used HII protocols
12.4 HII functionality
12.4.1 Branding, and displaying a banner
12.4.2 Specifying supported languages
12.4.3 Specifying configuration information
12.4.4 Making configuration data available to other drivers
12.4.5 Check to see if configuration parameters are valid
12.5 Forms and VFR files
12.6 HII Implementation Recommendations
12.6.1 Minimize callbacks
12.6.2 Don't reparse the package list
12.6.3 Concentrate on critical aspects of the driver
12.6.4 Perform usability testing
12.7 Porting to UEFI HII functionality
13 UEFI Driver Diagnostics
13.1 Driver Diagnostics Protocol Implementations
13.2 RunDiagnostics() Implementations
13.2.1 Device Drivers
13.2.2 Bus Drivers and Hybrid Drivers
13.2.3 RunDiagnostics() as a UEFI Application
13.3 Testing Driver Diagnostics Protocols
14 Driver Health Protocol
14.1 Driver Health Protocol Implementation
14.2 GetHealthStatus() Implementations
14.2.1 Device Drivers
14.2.2 Bus Drivers and Hybrid Drivers
14.3 Repair() Implementation
14.3.1 Device Drivers
14.3.2 Bus Drivers and Hybrid Drivers
15 Driver Family Override Protocol
15.1 Driver Family Override Protocol Implementation
15.2 GetVersion() Implementation
16 Driver Supported EFI Version Protocol
16.1 Driver Supported EFI Version Protocol Implementation
17 Bus-Specific Driver Override Protocol
17.1 Bus Specific Driver Override Protocol Implementation
17.2 Private Context Data Structure
17.3 Bus Specific Driver Override Protocol Installation
17.4 GetDriver() Implementation
17.5 Adding Driver Image Handles
18 PCI Driver Design Guidelines
18.1 PCI Root Bridge I/O Protocol Drivers
18.2 PCI Bus Drivers
18.2.1 Hot-plug PCI buses
18.3 PCI drivers
18.3.1 Supported()
18.3.2 Start() and Stop()
18.3.3 PCI Cards with Multiple PCI Controllers
18.4 Accessing PCI resources
18.4.1 Memory-mapped I/O ordering issues
18.4.2 Hardfail/Softfail
18.4.3 When a PCI device does not receive resources
18.5 PCI DMA
18.5.1 Map() Service Cautions
18.5.2 Weakly ordered memory transactions
18.5.3 Bus Master Read and Write Operations
18.5.4 Bus Master Common Buffer Operations
18.5.6 DMA Bus Master Read Operation
18.5.7 DMA Bus Master Write Operation
18.5.8 DMA Bus Master Common Buffer Operation
18.6 PCI Optimization Techniques
18.6.1 PCI I/O fill operations
18.6.2 PCI I/O FIFO operations
18.6.3 PCI I/O CopyMem() Operations
18.6.4 PCI Configuration Header Operations
18.6.5 PCI I/O MMIO Buffer Operations
18.6.6 PCI I/O Polling Operations
18.7 PCI Option ROM Images
18.7.1 EfiRom Utility
18.7.2 Using INF File to Generate PCI Option ROM Image
18.7.3 Using FDF File to Generate PCI Option ROM Image
19 USB Driver Design Guidelines
19.1 USB Host Controller Driver
19.1.1 Driver Binding Protocol Supported()
19.1.2 Driver Binding Protocol Start()
19.1.3 Driver Binding Protocol Stop()
19.1.4 USB 2 Host Controller Protocol Data Transfer Services
19.2 USB Bus Driver
19.3 USB Device Driver
19.3.1 Driver Binding Protocol Supported()
19.3.2 Driver Binding Protocol Start() and Stop()
19.3.3 I/O Protocol Implementations
19.3.4 State machine consideration
19.4 Debug Techniques
19.4.1 Debug Message Output
19.4.2 USB Bus Analyzer
19.4.3 USBCheck/USBCV Tool
19.5 Nonconforming USB Devices
20 SCSI Driver Design Guidelines
20.1 SCSI Host Controller Driver
20.1.1 Single-Channel SCSI Adapters
20.1.2 Multi-Channel SCSI Adapters
20.1.3 SCSI Adapters with RAID
20.1.4 Implementing driver binding protocol
20.1.5 Implementing Extended SCSI Pass Thru Protocol
20.1.6 SCSI command set device considerations
20.1.7 Discover a SCSI channel
20.1.8 SCSI Device Path
20.2 SCSI Bus Driver
20.3 SCSI Device Driver
20.3.1 Driver Binding Protocol Supported()
20.3.2 Driver Binding Protocol Start() and Stop()
20.3.3 I/O Protocol Implementations
21 ATA Driver Design Guidelines
21.1 ATA Host Controller Driver
21.1.1 Implementing Driver Binding Protocol
21.1.2 Implementing ATA Pass Thru Protocol
21.1.3 ATA Command Set Considerations
21.1.4 ATA Device Paths
21.2 ATA Bus Driver
22 Text Console Driver Design Guidelines
22.1 Assumptions
22.2 Simple Text Input Protocol Implementation
22.2.1 Reset() Implementation
22.2.2 ReadKeyStroke() and ReadKeyStrokeEx() Implementation
22.2.3 WaitForKey and WaitForKeyEx Notification Implementation
22.2.4 SetState() Implementation
22.2.5 RegisterKeyNotify() Implementation
22.2.6 UnregisterKeyNotify() Implementation
22.3 Simple Text Output Protocol Implementation
22.3.1 Reset() Implementation
22.3.2 OutputString() Implementation
22.3.3 TestString() Implementation
22.3.4 QueryMode() Implementation
22.3.5 SetMode() Implementation
22.3.6 SetAttribute() Implementation
22.3.7 ClearScreen() Implementation
22.3.8 SetCursorPosition() Implementation
22.3.9 EnableCursor() Implementation
22.4 Serial I/O Protocol Implementations
22.4.1 Reset() Implementation
22.4.2 SetAttributes() Implementation
22.4.3 SetControl() and GetControl() Implementation
22.4.4 Write() and Read() Implementation
23 Graphics Driver Design Guidelines
23.1 Assumptions
23.2 Graphics Output Protocol Implementation
23.2.1 Single output graphics adapters
23.2.2 Multiple output graphics adapters
23.2.3 Driver Binding Protocol Implementation
23.2.4 QueryMode(), SetMode(), and Blt() Implementation
23.3 EDID Discovered Protocol Implementation
23.4 EDID Active Protocol Implementation
23.5 EDID Override Protocol Implementation
23.5.1 GetEdid() Implementation
24 Mass Storage Driver Design Guidelines
24.1 Assumptions
24.2 Block I/O Protocol Implementations
24.2.1 Reset() Implementation
24.2.2 ReadBlocks() and ReadBlocksEx() Implementation
24.2.3 WriteBlocks() and WriteBlockEx() Implementation
24.2.4 FlushBlocks() and FlushBlocksEx() Implementation
24.3 Storage Security Protocol Implementation
25 Network Driver Design Guidelines
25.1 Assumptions
25.2 NII Protocol and UNDI Implementations
25.2.1 Exit Boot Services Event
25.2.2 Set Virtual Address Map Event
25.2.3 Memory leaks caused by UNDI
25.3 Simple Network Protocol Implementations
25.4 Managed Network Protocol Implementations
26 User Credential Driver Design Guidelines
26.1 Assumptions
26.2 User Credential Protocol Implementation
27 Load File Driver Design Guidelines
27.1 Assumptions
27.2 Load File Protocol Implementation
27.2.1 LoadFile() Implementation
28 IPF Platform Porting Considerations
28.1 General notes about porting to IPF platforms
28.2 Alignment Faults
28.3 Casting Pointers
28.4 Packed Structures
28.5 UEFI Device Paths
28.6 PCI Configuration Header 64-bit BAR
28.7 Speculation and floating point register usage
29 EFI Byte Code Porting Considerations
29.1 No Assembly Support
29.2 No C++ Support
29.3 No Floating Point Support
29.4 Use of sizeof()
29.4.1 Global Variable Initialization
29.4.2 CASE Statements
29.5 Natural Integers and Fixed Size Integers
29.6 Memory ordering
29.7 Performance considerations
29.7.1 Performance considerations for data types
29.8 UEFI Driver Entry Point
30 Building UEFI Drivers
30.1 Prerequisites
30.2 Create EDK II Package
30.3 Create UEFI Driver Directory
30.3.1 Disk I/O Driver Example
30.3.2 Reserved Directory Names
30.3.3 EBC Virtual Machine Driver Example
30.4 Adding a UEFI Driver to DSC File
30.5 Building a UEFI driver
31 Testing and Debugging UEFI Drivers
31.1 Native and EBC
31.2 Compiler Optimizations
31.3 UEFI Shell Debugging
31.3.1 Testing Specific Protocols
31.3.2 Other Testing
31.3.3 Loading UEFI drivers
31.3.4 Unloading UEFI drivers
31.3.5 Connecting UEFI Drivers
31.3.6 Driver and Device Information
31.3.7 Testing the Driver Configuration Protocol
31.3.8 Testing the Driver Diagnostics Protocols
31.4 Debugging code statements
31.4.1 Configuring DebugLib with EDK II
31.4.2 Capturing Debug Messages
31.5 POST codes
31.5.1 POST Card Debug
31.5.2 Other options
32 Distributing UEFI Drivers
32.1 PCI Option ROM
32.2 Integrated in Platform FLASH
32.3 EFI System Partition
Appendix A EDK II File Templates
A.1 UEFI Driver Template
A.2 UEFI Driver Optional Protocol Templates
A.2.1 ComponentName.c File
A.2.2 DriverConfiguration.c File
A.2.3 HiiConfigAccess.c File
A.2.4 DriverHealth.c File
A.2.5 DriverFamilyOverride.c File
A.2.6 BusSpecificDriverOverride.c File
A.2.7 DriverDiagnostics.c File
A.3 UEFI Driver I/O Protocol Templates
A.3.1 Usb2Hc.c File
A.3.2 ExtScsiPassThru.c File
A.3.3 AtaPassThru.c File
A.3.4 SimpleTextInput.c File
A.3.5 SimpleTextOutput.c File
A.3.6 SerialIo.c File
A.3.7 GraphicsOutput.c File
A.3.8 BlockIo.c File
A.3.9 NiiUndi.c File
A.3.10 SimpleNetwork.c File
A.3.11 UserCredential.c File
A.3.12 LoadFile.c File
A.4 Platform Specific UEFI Driver Templates
A.4.1 EdidOverride.c File
A.5 EDK II Package Extension Templates
A.5.1 Protocol File Template
A.5.2 GUID File Template
A.5.3 Library Class File Template
A.5.4 Including Protocols, GUIDs, and Library Classes
Appendix B EDK II Sample Drivers
Appendix C Glossary
Published with GitBook
12.6 HII Implementation Recommendations
EDK II Driver Writer's Guide for UEFI 2.3.1
DRAFT [12/01/2020 06:15:53]
Revision 1.10
12.6 HII Implementation Recommendations
EDK II Driver Writer's Guide for UEFI 2.3.1
DRAFT [12/01/2020 06:15:53]
Revision 1.10