iPXE
Functions
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. More...
 
int efi_child_add (EFI_HANDLE parent, EFI_HANDLE child)
 Add EFI device as child of another EFI device. More...
 
void efi_child_del (EFI_HANDLE parent, EFI_HANDLE child)
 Remove EFI device as child of another EFI device. More...
 
static int efi_device_info_pci (EFI_HANDLE device, const char *prefix, struct device *dev)
 Get underlying PCI device information. More...
 
void efi_device_info (EFI_HANDLE device, const char *prefix, struct device *dev)
 Get underlying device information. More...
 

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  {
49  EFI_DEVICE_PATH_PROTOCOL *devpath;
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",
60  efi_handle_name ( device ), strerror ( rc ) );
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 ),
83  efi_guid_ntoa ( protocol ), strerror ( rc ) );
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 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2099
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:175
#define DBGC(...)
Definition: compiler.h:505
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition: efi_path.c:174
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:46
static void efi_path_terminate(EFI_DEVICE_PATH_PROTOCOL *end)
Terminate device path.
Definition: efi_path.h:31
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
#define ENOMEM
Not enough space.
Definition: errno.h:535
A hardware device.
Definition: device.h:77
void * memcpy(void *dest, const void *src, size_t len) __nonnull
ring len
Length.
Definition: dwmac.h:231
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
Definition: efi_debug.c:247
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:652
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:55
EFI Boot Services Table.
Definition: UefiSpec.h:1931
#define efi_open(handle, protocol, interface)
Open protocol for ephemeral use.
Definition: efi.h:444
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:169
const char * efi_guid_ntoa(CONST EFI_GUID *guid)
Convert GUID to a printable string.
Definition: efi_guid.c:726
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:621
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:32
uint32_t end
Ending offset.
Definition: netvsc.h:18
EFI_SYSTEM_TABLE * efi_systab
uint16_t protocol
Protocol ID.
Definition: stp.h:19
EFI_LOCATE_DEVICE_PATH LocateDevicePath
Definition: UefiSpec.h:1972

References EFI_SYSTEM_TABLE::BootServices, DBGC, EEFI, efi_device_path_protocol_guid, efi_devpath_text(), efi_guid_ntoa(), 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  {
112  EFI_DEVICE_PATH_PROTOCOL *devpath;
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 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
#define DBGC_EFI_OPENERS(...)
Definition: efi.h:345
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:46
#define efi_open_by_child(handle, protocol, child, interface)
Open protocol for persistent use by a child controller.
Definition: efi.h:490
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:652
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:169
#define DBGC2(...)
Definition: compiler.h:522

References DBGC, DBGC2, DBGC_EFI_OPENERS, efi_device_path_protocol_guid, 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
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:652
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:169
#define DBGC2(...)
Definition: compiler.h:522

References DBGC2, efi_close_by_child(), efi_device_path_protocol_guid, 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()

static 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",
163  efi_handle_name ( device ), strerror ( rc ) );
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",
170  efi_handle_name ( device ), strerror ( rc ) );
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 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
int efipci_info(EFI_HANDLE device, struct efi_pci_device *efipci)
Get EFI PCI device information.
Definition: efi_pci.c:705
EFI_GUID efi_pci_io_protocol_guid
PCI I/O protocol GUID.
Definition: efi_guid.c:313
#define DBGC(...)
Definition: compiler.h:505
char name[40]
Name.
Definition: device.h:79
char prefix[4]
Definition: vmconsole.c:53
A hardware device.
Definition: device.h:77
void * memcpy(void *dest, const void *src, size_t len) __nonnull
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:652
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:79
A PCI device.
Definition: pci.h:211
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
An EFI PCI device.
Definition: efi_pci.h:22
struct device_description desc
Device description.
Definition: device.h:83
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:383
Definition: efi.h:62

References DBGC, device::desc, pci_device::dev, 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 ) );
202  dev->desc.bus_type = BUS_TYPE_EFI;
203  snprintf ( dev->name, sizeof ( dev->name ), "%s-%p", prefix, device );
204 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
char name[40]
Name.
Definition: device.h:79
char prefix[4]
Definition: vmconsole.c:53
A hardware device.
Definition: device.h:77
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:652
#define BUS_TYPE_EFI
EFI bus type.
Definition: device.h:62
unsigned int bus_type
Bus type.
Definition: device.h:25
struct device_description desc
Device description.
Definition: device.h:83
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:383
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

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

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