iPXE
efi_utils.c File Reference

EFI utilities. More...

#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/efi_path.h>
#include <ipxe/efi/efi_pci.h>
#include <ipxe/efi/efi_utils.h>

Go to the source code of this file.

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 FILE_SECBOOT (PERMITTED)
int efi_locate_device (EFI_HANDLE device, EFI_GUID *protocol, EFI_HANDLE *parent, unsigned int skip)
 Locate parent device supporting a given protocol.
int efi_child_add (EFI_HANDLE parent, EFI_HANDLE child)
 Add EFI device as child of another EFI device.
void efi_child_del (EFI_HANDLE parent, EFI_HANDLE child)
 Remove EFI device as child of another EFI device.
static int efi_device_info_pci (EFI_HANDLE device, const char *prefix, struct device *dev)
 Get underlying PCI device information.
void efi_device_info (EFI_HANDLE device, const char *prefix, struct device *dev)
 Get underlying device information.

Detailed Description

EFI utilities.

Definition in file efi_utils.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER )

◆ FILE_SECBOOT()

FILE_SECBOOT ( PERMITTED )

◆ efi_locate_device()

int efi_locate_device ( EFI_HANDLE device,
EFI_GUID * protocol,
EFI_HANDLE * parent,
unsigned int skip )

Locate parent device supporting a given protocol.

Parameters
deviceEFI device handle
protocolProtocol GUID
parentParent EFI device handle to fill in
skipNumber of protocol-supporting parent devices to skip
Return values
rcReturn status code

Definition at line 46 of file efi_utils.c.

47 {
48 EFI_BOOT_SERVICES *bs = efi_systab->BootServices;
52 size_t len;
53 EFI_STATUS efirc;
54 int rc;
55
56 /* Get device path */
58 &devpath ) ) != 0 ) {
59 DBGC ( device, "EFIDEV %s cannot open device path: %s\n",
61 goto err_open_device_path;
62 }
63
64 /* Create modifiable copy of device path */
65 len = ( efi_path_len ( devpath ) + sizeof ( *end ) );
66 path = malloc ( len );
67 if ( ! path ) {
68 rc = -ENOMEM;
69 goto err_alloc_path;
70 }
71 memcpy ( path, devpath, len );
72
73 /* Locate parent device(s) */
74 while ( 1 ) {
75
76 /* Check for presence of specified protocol */
77 end = path;
78 if ( ( efirc = bs->LocateDevicePath ( protocol, &end,
79 parent ) ) != 0 ) {
80 rc = -EEFI ( efirc );
81 DBGC ( device, "EFIDEV %s has no parent supporting "
82 "%s: %s\n", efi_devpath_text ( path ),
84 goto err_locate_protocol;
85 }
86
87 /* Stop if we have skipped the requested number of devices */
88 if ( ! skip-- )
89 break;
90
91 /* Trim device path */
93 end = efi_path_prev ( path, end );
95 }
96
97 err_locate_protocol:
98 free ( path );
99 err_alloc_path:
100 err_open_device_path:
101 return rc;
102}
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
struct arbelprm_rc_send_wqe rc
Definition arbel.h:3
ring len
Length.
Definition dwmac.h:226
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition efi_debug.c:652
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
Definition efi_debug.c:247
const char * efi_guid_ntoa(CONST EFI_GUID *guid)
Convert GUID to a printable string.
Definition efi_guid.c:726
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition efi_guid.c:169
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition efi_path.c:174
EFI_DEVICE_PATH_PROTOCOL * efi_path_prev(EFI_DEVICE_PATH_PROTOCOL *path, EFI_DEVICE_PATH_PROTOCOL *curr)
Find previous element of device path.
Definition efi_path.c:145
static void efi_path_terminate(EFI_DEVICE_PATH_PROTOCOL *end)
Terminate device path.
Definition efi_path.h:31
#define DBGC(...)
Definition compiler.h:505
#define ENOMEM
Not enough space.
Definition errno.h:535
#define efi_open(handle, protocol, interface)
Open protocol for ephemeral use.
Definition efi.h:444
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition efi.h:175
EFI_SYSTEM_TABLE * efi_systab
void * memcpy(void *dest, const void *src, size_t len) __nonnull
void * malloc(size_t size)
Allocate memory.
Definition malloc.c:621
uint32_t end
Ending offset.
Definition netvsc.h:7
static void(* free)(struct refcnt *refcnt))
Definition refcnt.h:55
uint16_t protocol
Protocol ID.
Definition stp.h:7
char * strerror(int errno)
Retrieve string representation of error number.
Definition strerror.c:79
EFI Boot Services Table.
Definition UefiSpec.h:1931
EFI_LOCATE_DEVICE_PATH LocateDevicePath
Definition UefiSpec.h:1972
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition DevicePath.h:46
A hardware device.
Definition device.h:77

References DBGC, EEFI, efi_device_path_protocol_guid, efi_devpath_text(), efi_guid_ntoa(), EFI_HANDLE, efi_handle_name(), efi_open, efi_path_len(), efi_path_prev(), efi_path_terminate(), efi_systab, end, ENOMEM, free, len, EFI_BOOT_SERVICES::LocateDevicePath, malloc(), memcpy(), protocol, rc, and strerror().

Referenced by chained_locate(), efi_autoexec_load(), efi_device_info_pci(), nii_pci_open(), and snpnet_supported().

◆ efi_child_add()

int efi_child_add ( EFI_HANDLE parent,
EFI_HANDLE child )

Add EFI device as child of another EFI device.

Parameters
parentEFI parent device handle
childEFI child device handle
Return values
rcReturn status code

Definition at line 111 of file efi_utils.c.

111 {
113 int rc;
114
115 /* Re-open the device path protocol */
117 child, &devpath ) ) != 0 ) {
118 DBGC ( parent, "EFIDEV %s could not add child",
119 efi_handle_name ( parent ) );
120 DBGC ( parent, " %s: %s\n",
121 efi_handle_name ( child ), strerror ( rc ) );
122 DBGC_EFI_OPENERS ( parent, parent,
124 return rc;
125 }
126
127 DBGC2 ( parent, "EFIDEV %s added child", efi_handle_name ( parent ) );
128 DBGC2 ( parent, " %s\n", efi_handle_name ( child ) );
129 return 0;
130}
#define DBGC2(...)
Definition compiler.h:522
#define DBGC_EFI_OPENERS(...)
Definition efi.h:345
#define efi_open_by_child(handle, protocol, child, interface)
Open protocol for persistent use by a child controller.
Definition efi.h:490

References DBGC, DBGC2, DBGC_EFI_OPENERS, efi_device_path_protocol_guid, EFI_HANDLE, efi_handle_name(), efi_open_by_child, rc, and strerror().

Referenced by efi_snp_hii_install(), and efi_snp_probe().

◆ efi_child_del()

void efi_child_del ( EFI_HANDLE parent,
EFI_HANDLE child )

Remove EFI device as child of another EFI device.

Parameters
parentEFI parent device handle
childEFI child device handle

Definition at line 138 of file efi_utils.c.

138 {
139
141 DBGC2 ( parent, "EFIDEV %s removed child", efi_handle_name ( parent ) );
142 DBGC2 ( parent, " %s\n", efi_handle_name ( child ) );
143}
void efi_close_by_child(EFI_HANDLE handle, EFI_GUID *protocol, EFI_HANDLE child)
Close protocol opened for persistent use by a child controller.
Definition efi_open.c:344

References DBGC2, efi_close_by_child(), efi_device_path_protocol_guid, EFI_HANDLE, and efi_handle_name().

Referenced by efi_snp_hii_install(), efi_snp_hii_uninstall(), efi_snp_probe(), and efi_snp_remove().

◆ efi_device_info_pci()

int efi_device_info_pci ( EFI_HANDLE device,
const char * prefix,
struct device * dev )
static

Get underlying PCI device information.

Parameters
deviceEFI device handle
prefixDevice name prefix
devGeneric device to fill in
Return values
rcReturn status code

Definition at line 153 of file efi_utils.c.

154 {
156 struct efi_pci_device efipci;
157 int rc;
158
159 /* Find parent PCI device */
161 &pci_device, 0 ) ) != 0 ) {
162 DBGC ( device, "EFIDEV %s is not a PCI device: %s\n",
164 return rc;
165 }
166
167 /* Get PCI device information */
168 if ( ( rc = efipci_info ( pci_device, &efipci ) ) != 0 ) {
169 DBGC ( device, "EFIDEV %s could not get PCI information: %s\n",
171 return rc;
172 }
173
174 /* Populate device information */
175 memcpy ( &dev->desc, &efipci.pci.dev.desc, sizeof ( dev->desc ) );
176 snprintf ( dev->name, sizeof ( dev->name ), "%s-%s",
177 prefix, efipci.pci.dev.name );
178
179 return 0;
180}
EFI_GUID efi_pci_io_protocol_guid
PCI I/O protocol GUID.
Definition efi_guid.c:313
int efipci_info(EFI_HANDLE device, struct efi_pci_device *efipci)
Get EFI PCI device information.
Definition efi_pci.c:711
int efi_locate_device(EFI_HANDLE device, EFI_GUID *protocol, EFI_HANDLE *parent, unsigned int skip)
Locate parent device supporting a given protocol.
Definition efi_utils.c:46
#define EFI_HANDLE
Definition efi.h:53
struct device_description desc
Device description.
Definition device.h:83
char name[40]
Name.
Definition device.h:79
An EFI PCI device.
Definition efi_pci.h:22
A PCI device.
Definition pci.h:211
char prefix[4]
Definition vmconsole.c:53
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition vsprintf.c:383

References DBGC, device::desc, pci_device::dev, EFI_HANDLE, efi_handle_name(), efi_locate_device(), efi_pci_io_protocol_guid, efipci_info(), memcpy(), device::name, efi_pci_device::pci, prefix, rc, snprintf(), and strerror().

Referenced by efi_device_info().

◆ efi_device_info()

void efi_device_info ( EFI_HANDLE device,
const char * prefix,
struct device * dev )

Get underlying device information.

Parameters
deviceEFI device handle
prefixDevice name prefix
devGeneric device to fill in

Definition at line 189 of file efi_utils.c.

190 {
191 int rc;
192
193 /* Try getting underlying PCI device information */
194 if ( ( rc = efi_device_info_pci ( device, prefix, dev ) ) == 0 )
195 return;
196
197 /* If we cannot get any underlying device information, fall
198 * back to providing information about the EFI handle.
199 */
200 DBGC ( device, "EFIDEV %s could not get underlying device "
201 "information\n", efi_handle_name ( device ) );
203 snprintf ( dev->name, sizeof ( dev->name ), "%s-%p", prefix, device );
204}
#define BUS_TYPE_EFI
EFI bus type.
Definition device.h:62
static int efi_device_info_pci(EFI_HANDLE device, const char *prefix, struct device *dev)
Get underlying PCI device information.
Definition efi_utils.c:153
unsigned int bus_type
Bus type.
Definition device.h:25

References device_description::bus_type, BUS_TYPE_EFI, DBGC, device::desc, efi_device_info_pci(), EFI_HANDLE, efi_handle_name(), device::name, prefix, rc, and snprintf().

Referenced by mnpnet_start(), nii_start(), snpnet_start(), and usbio_start().