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)
 
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_pci_info (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  )

◆ 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 45 of file efi_utils.c.

46  {
48  union {
50  void *interface;
51  } u;
54  size_t len;
55  EFI_STATUS efirc;
56  int rc;
57 
58  /* Get device path */
59  if ( ( efirc = bs->OpenProtocol ( device,
61  &u.interface,
64  rc = -EEFI ( efirc );
65  DBGC ( device, "EFIDEV %s cannot open device path: %s\n",
66  efi_handle_name ( device ), strerror ( rc ) );
67  goto err_open_device_path;
68  }
69 
70  /* Create modifiable copy of device path */
71  len = ( efi_path_len ( u.path ) + sizeof ( EFI_DEVICE_PATH_PROTOCOL ));
72  path = malloc ( len );
73  if ( ! path ) {
74  rc = -ENOMEM;
75  goto err_alloc_path;
76  }
77  memcpy ( path, u.path, len );
78 
79  /* Locate parent device(s) */
80  while ( 1 ) {
81 
82  /* Check for presence of specified protocol */
83  end = path;
84  if ( ( efirc = bs->LocateDevicePath ( protocol, &end,
85  parent ) ) != 0 ) {
86  rc = -EEFI ( efirc );
87  DBGC ( device, "EFIDEV %s has no parent supporting "
88  "%s: %s\n", efi_devpath_text ( path ),
89  efi_guid_ntoa ( protocol ), strerror ( rc ) );
90  goto err_locate_protocol;
91  }
92 
93  /* Stop if we have skipped the requested number of devices */
94  if ( ! skip-- )
95  break;
96 
97  /* Trim device path */
99  end = efi_path_prev ( path, end );
101  }
102 
103  /* Success */
104  rc = 0;
105 
106  err_locate_protocol:
107  free ( path );
108  err_alloc_path:
111  err_open_device_path:
112  return rc;
113 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
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:171
#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:144
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:45
EFI_CLOSE_PROTOCOL CloseProtocol
Definition: UefiSpec.h:1987
static void efi_path_terminate(EFI_DEVICE_PATH_PROTOCOL *end)
Terminate device path.
Definition: efi_path.h:30
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:115
#define ENOMEM
Not enough space.
Definition: errno.h:534
A hardware device.
Definition: device.h:73
void * memcpy(void *dest, const void *src, size_t len) __nonnull
An object interface.
Definition: interface.h:124
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
Definition: efi_debug.c:461
#define EFI_OPEN_PROTOCOL_GET_PROTOCOL
Definition: UefiSpec.h:1344
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:808
const char * efi_guid_ntoa(CONST EFI_GUID *guid)
Convert GUID to a printable string.
Definition: efi_debug.c:254
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
EFI Boot Services Table.
Definition: UefiSpec.h:1917
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:34
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:143
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:583
uint32_t len
Length.
Definition: ena.h:14
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
union @17 u
uint32_t end
Ending offset.
Definition: netvsc.h:18
EFI_SYSTEM_TABLE * efi_systab
EFI_OPEN_PROTOCOL OpenProtocol
Definition: UefiSpec.h:1986
uint16_t protocol
Protocol ID.
Definition: stp.h:18
EFI_LOCATE_DEVICE_PATH LocateDevicePath
Definition: UefiSpec.h:1958

References EFI_SYSTEM_TABLE::BootServices, EFI_BOOT_SERVICES::CloseProtocol, DBGC, EEFI, efi_device_path_protocol_guid, efi_devpath_text(), efi_guid_ntoa(), efi_handle_name(), efi_image_handle, EFI_OPEN_PROTOCOL_GET_PROTOCOL, efi_path_len(), efi_path_prev(), efi_path_terminate(), efi_systab, end, ENOMEM, free, len, EFI_BOOT_SERVICES::LocateDevicePath, malloc(), memcpy(), EFI_BOOT_SERVICES::OpenProtocol, protocol, rc, strerror(), and u.

Referenced by chained_locate(), efi_pci_info(), 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 122 of file efi_utils.c.

122  {
124  void *devpath;
125  EFI_STATUS efirc;
126  int rc;
127 
128  /* Re-open the device path protocol */
129  if ( ( efirc = bs->OpenProtocol ( parent,
131  &devpath,
132  efi_image_handle, child,
134  ) ) != 0 ) {
135  rc = -EEFI ( efirc );
136  DBGC ( parent, "EFIDEV %s could not add child",
137  efi_handle_name ( parent ) );
138  DBGC ( parent, " %s: %s\n",
139  efi_handle_name ( child ), strerror ( rc ) );
140  DBGC_EFI_OPENERS ( parent, parent,
142  return rc;
143  }
144 
145  DBGC2 ( parent, "EFIDEV %s added child", efi_handle_name ( parent ) );
146  DBGC2 ( parent, " %s\n", efi_handle_name ( child ) );
147  return 0;
148 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
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:171
#define EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
Definition: UefiSpec.h:1346
#define DBGC(...)
Definition: compiler.h:505
#define DBGC_EFI_OPENERS(...)
Definition: efi.h:321
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:808
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
EFI Boot Services Table.
Definition: UefiSpec.h:1917
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:34
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:143
#define DBGC2(...)
Definition: compiler.h:522
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
EFI_SYSTEM_TABLE * efi_systab
EFI_OPEN_PROTOCOL OpenProtocol
Definition: UefiSpec.h:1986

References EFI_SYSTEM_TABLE::BootServices, DBGC, DBGC2, DBGC_EFI_OPENERS, EEFI, efi_device_path_protocol_guid, efi_handle_name(), efi_image_handle, EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER, efi_systab, EFI_BOOT_SERVICES::OpenProtocol, 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 156 of file efi_utils.c.

156  {
158 
160  efi_image_handle, child );
161  DBGC2 ( parent, "EFIDEV %s removed child", efi_handle_name ( parent ) );
162  DBGC2 ( parent, " %s\n", efi_handle_name ( child ) );
163 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2081
EFI_CLOSE_PROTOCOL CloseProtocol
Definition: UefiSpec.h:1987
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:808
EFI Boot Services Table.
Definition: UefiSpec.h:1917
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:34
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:143
#define DBGC2(...)
Definition: compiler.h:522
EFI_SYSTEM_TABLE * efi_systab

References EFI_SYSTEM_TABLE::BootServices, EFI_BOOT_SERVICES::CloseProtocol, DBGC2, efi_device_path_protocol_guid, efi_handle_name(), efi_image_handle, and efi_systab.

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

◆ efi_pci_info()

static int efi_pci_info ( 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 173 of file efi_utils.c.

174  {
176  struct efi_pci_device efipci;
177  int rc;
178 
179  /* Find parent PCI device */
181  &pci_device, 0 ) ) != 0 ) {
182  DBGC ( device, "EFIDEV %s is not a PCI device: %s\n",
183  efi_handle_name ( device ), strerror ( rc ) );
184  return rc;
185  }
186 
187  /* Get PCI device information */
188  if ( ( rc = efipci_info ( pci_device, &efipci ) ) != 0 ) {
189  DBGC ( device, "EFIDEV %s could not get PCI information: %s\n",
190  efi_handle_name ( device ), strerror ( rc ) );
191  return rc;
192  }
193 
194  /* Populate device information */
195  memcpy ( &dev->desc, &efipci.pci.dev.desc, sizeof ( dev->desc ) );
196  snprintf ( dev->name, sizeof ( dev->name ), "%s-%s",
197  prefix, efipci.pci.dev.name );
198 
199  return 0;
200 }
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:759
EFI_GUID efi_pci_io_protocol_guid
PCI I/O protocol GUID.
Definition: efi_guid.c:283
#define DBGC(...)
Definition: compiler.h:505
char name[40]
Name.
Definition: device.h:75
char prefix[4]
Definition: vmconsole.c:53
A hardware device.
Definition: device.h:73
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:808
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
A PCI device.
Definition: pci.h:206
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:45
An EFI PCI device.
Definition: efi_pci.h:21
struct device_description desc
Device description.
Definition: device.h:79
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382
Definition: efi.h:59

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 209 of file efi_utils.c.

210  {
211  int rc;
212 
213  /* Try getting underlying PCI device information */
214  if ( ( rc = efi_pci_info ( device, prefix, dev ) ) == 0 )
215  return;
216 
217  /* If we cannot get any underlying device information, fall
218  * back to providing information about the EFI handle.
219  */
220  DBGC ( device, "EFIDEV %s could not get underlying device "
221  "information\n", efi_handle_name ( device ) );
222  dev->desc.bus_type = BUS_TYPE_EFI;
223  snprintf ( dev->name, sizeof ( dev->name ), "%s-%p", prefix, device );
224 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
#define DBGC(...)
Definition: compiler.h:505
char name[40]
Name.
Definition: device.h:75
char prefix[4]
Definition: vmconsole.c:53
static int efi_pci_info(EFI_HANDLE device, const char *prefix, struct device *dev)
Get underlying PCI device information.
Definition: efi_utils.c:173
A hardware device.
Definition: device.h:73
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:808
#define BUS_TYPE_EFI
EFI bus type.
Definition: device.h:61
unsigned int bus_type
Bus type.
Definition: device.h:24
struct device_description desc
Device description.
Definition: device.h:79
int snprintf(char *buf, size_t size, const char *fmt,...)
Write a formatted string to a buffer.
Definition: vsprintf.c:382

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

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