iPXE
Data Structures | Macros | Functions
efi_snp.h File Reference

iPXE EFI SNP interface More...

#include <ipxe/list.h>
#include <ipxe/netdevice.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/Protocol/SimpleNetwork.h>
#include <ipxe/efi/Protocol/NetworkInterfaceIdentifier.h>
#include <ipxe/efi/Protocol/ComponentName2.h>
#include <ipxe/efi/Protocol/DevicePath.h>
#include <ipxe/efi/Protocol/HiiConfigAccess.h>
#include <ipxe/efi/Protocol/HiiDatabase.h>
#include <ipxe/efi/Protocol/LoadFile.h>

Go to the source code of this file.

Data Structures

struct  efi_snp_device
 An SNP device. More...
 

Macros

#define EFI_SNP_NUM_TX   32
 SNP transmit completion ring size. More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER)
 
int efi_snp_hii_install (struct efi_snp_device *snpdev)
 Install HII protocol and packages for SNP device. More...
 
int efi_snp_hii_uninstall (struct efi_snp_device *snpdev)
 Uninstall HII protocol and package for SNP device. More...
 
struct efi_snp_devicefind_snpdev (EFI_HANDLE handle)
 Find SNP device by EFI device handle. More...
 
struct efi_snp_devicelast_opened_snpdev (void)
 Get most recently opened SNP device. More...
 
void efi_snp_add_claim (int delta)
 Add to SNP claimed/released count. More...
 
static void efi_snp_claim (void)
 Claim network devices for use by iPXE. More...
 
static void efi_snp_release (void)
 Release network devices for use via SNP. More...
 

Detailed Description

iPXE EFI SNP interface

Definition in file efi_snp.h.

Macro Definition Documentation

◆ EFI_SNP_NUM_TX

#define EFI_SNP_NUM_TX   32

SNP transmit completion ring size.

Definition at line 24 of file efi_snp.h.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER  )

◆ efi_snp_hii_install()

int efi_snp_hii_install ( struct efi_snp_device snpdev)

Install HII protocol and packages for SNP device.

Parameters
snpdevSNP device
Return values
rcReturn status code

Definition at line 658 of file efi_snp_hii.c.

658  {
660  VENDOR_DEVICE_PATH *vendor_path;
661  EFI_DEVICE_PATH_PROTOCOL *path_end;
662  size_t path_prefix_len;
663  int leak = 0;
664  EFI_STATUS efirc;
665  int rc;
666 
667  /* Do nothing if HII database protocol is not supported */
668  if ( ! efihii ) {
669  rc = -ENOTSUP;
670  goto err_no_hii;
671  }
672 
673  /* Initialise HII protocol */
674  memcpy ( &snpdev->hii, &efi_snp_device_hii, sizeof ( snpdev->hii ) );
675 
676  /* Create HII package list */
677  snpdev->package_list = efi_snp_hii_package_list ( snpdev );
678  if ( ! snpdev->package_list ) {
679  DBGC ( snpdev, "SNPDEV %p could not create HII package list\n",
680  snpdev );
681  rc = -ENOMEM;
682  goto err_build_package_list;
683  }
684 
685  /* Allocate the new device path */
686  path_prefix_len = efi_path_len ( snpdev->path );
687  snpdev->hii_child_path = zalloc ( path_prefix_len +
688  sizeof ( *vendor_path ) +
689  sizeof ( *path_end ) );
690  if ( ! snpdev->hii_child_path ) {
691  DBGC ( snpdev,
692  "SNPDEV %p could not allocate HII child device path\n",
693  snpdev );
694  rc = -ENOMEM;
695  goto err_alloc_child_path;
696  }
697 
698  /* Populate the device path */
699  memcpy ( snpdev->hii_child_path, snpdev->path, path_prefix_len );
700  vendor_path = ( ( ( void * ) snpdev->hii_child_path ) +
701  path_prefix_len );
702  vendor_path->Header.Type = HARDWARE_DEVICE_PATH;
703  vendor_path->Header.SubType = HW_VENDOR_DP;
704  vendor_path->Header.Length[0] = sizeof ( *vendor_path );
705  efi_snp_hii_random_guid ( &vendor_path->Guid );
706  path_end = ( ( void * ) ( vendor_path + 1 ) );
707  path_end->Type = END_DEVICE_PATH_TYPE;
709  path_end->Length[0] = sizeof ( *path_end );
710 
711  /* Create device path and child handle for HII association */
712  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
713  &snpdev->hii_child_handle,
715  NULL ) ) != 0 ) {
716  rc = -EEFI ( efirc );
717  DBGC ( snpdev, "SNPDEV %p could not create HII child handle: "
718  "%s\n", snpdev, strerror ( rc ) );
719  goto err_hii_child_handle;
720  }
721 
722  /* Add HII packages */
723  if ( ( efirc = efihii->NewPackageList ( efihii, snpdev->package_list,
724  snpdev->hii_child_handle,
725  &snpdev->hii_handle ) ) != 0 ) {
726  rc = -EEFI ( efirc );
727  DBGC ( snpdev, "SNPDEV %p could not add HII packages: %s\n",
728  snpdev, strerror ( rc ) );
729  goto err_new_package_list;
730  }
731 
732  /* Install HII protocol */
733  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
734  &snpdev->hii_child_handle,
736  NULL ) ) != 0 ) {
737  rc = -EEFI ( efirc );
738  DBGC ( snpdev, "SNPDEV %p could not install HII protocol: %s\n",
739  snpdev, strerror ( rc ) );
740  goto err_install_protocol;
741  }
742 
743  /* Add as child of handle with SNP instance */
744  if ( ( rc = efi_child_add ( snpdev->handle,
745  snpdev->hii_child_handle ) ) != 0 ) {
746  DBGC ( snpdev,
747  "SNPDEV %p could not adopt HII child handle: %s\n",
748  snpdev, strerror ( rc ) );
749  goto err_efi_child_add;
750  }
751 
752  return 0;
753 
754  efi_child_del ( snpdev->handle, snpdev->hii_child_handle );
755  err_efi_child_add:
756  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
757  snpdev->hii_child_handle,
759  NULL ) ) != 0 ) {
760  DBGC ( snpdev, "SNPDEV %p could not uninstall HII protocol: "
761  "%s\n", snpdev, strerror ( -EEFI ( efirc ) ) );
762  leak = 1;
763  }
764  efi_nullify_hii ( &snpdev->hii );
765  err_install_protocol:
766  if ( ! leak )
768  err_new_package_list:
769  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
770  snpdev->hii_child_handle,
772  NULL ) ) != 0 ) {
773  DBGC ( snpdev, "SNPDEV %p could not uninstall HII path: %s\n",
774  snpdev, strerror ( -EEFI ( efirc ) ) );
775  leak = 1;
776  }
777  err_hii_child_handle:
778  if ( ! leak ) {
779  free ( snpdev->hii_child_path );
780  snpdev->hii_child_path = NULL;
781  }
782  err_alloc_child_path:
783  if ( ! leak ) {
784  free ( snpdev->package_list );
785  snpdev->package_list = NULL;
786  }
787  err_build_package_list:
788  err_no_hii:
789  return rc;
790 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2000
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:167
#define END_DEVICE_PATH_TYPE
Definition: DevicePath.h:1327
static void efi_snp_hii_random_guid(EFI_GUID *guid)
Generate a random GUID.
Definition: efi_snp_hii.c:113
EFI_HII_DATABASE_REMOVE_PACK RemovePackageList
Definition: HiiDatabase.h:517
#define HARDWARE_DEVICE_PATH
Hardware Device Paths.
Definition: DevicePath.h:77
#define DBGC(...)
Definition: compiler.h:505
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1915
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition: efi_path.c:67
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:51
int efi_child_add(EFI_HANDLE parent, EFI_HANDLE child)
Add EFI device as child of another EFI device.
Definition: efi_utils.c:94
EFI_HANDLE hii_child_handle
EFI child handle for HII association.
Definition: efi_snp.h:63
EFI_HII_CONFIG_ACCESS_PROTOCOL hii
HII configuration access protocol.
Definition: efi_snp.h:59
EFI_HANDLE handle
EFI device handle.
Definition: efi_snp.h:35
EFI_GUID efi_hii_config_access_protocol_guid
HII configuration access protocol GUID.
Definition: efi_guid.c:156
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
void efi_child_del(EFI_HANDLE parent, EFI_HANDLE child)
Remove EFI device as child of another EFI device.
Definition: efi_utils.c:128
EFI_HII_HANDLE hii_handle
HII handle.
Definition: efi_snp.h:67
EFI_GUID Guid
Vendor-assigned GUID that defines the data that follows.
Definition: DevicePath.h:154
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:150
EFI_HII_PACKAGE_LIST_HEADER * package_list
HII package list.
Definition: efi_snp.h:61
#define HW_VENDOR_DP
Hardware Vendor Device Path SubType.
Definition: DevicePath.h:142
The Vendor Device Path allows the creation of vendor-defined Device Paths.
Definition: DevicePath.h:149
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
void * zalloc(size_t size)
Allocate cleared memory.
Definition: malloc.c:624
EFI Boot Services Table.
Definition: UefiSpec.h:1836
void efi_nullify_hii(EFI_HII_CONFIG_ACCESS_PROTOCOL *hii)
Nullify HII configuration access protocol.
Definition: efi_null.c:301
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1916
static EFI_HII_PACKAGE_LIST_HEADER * efi_snp_hii_package_list(struct efi_snp_device *snpdev)
Build HII package list for SNP device.
Definition: efi_snp_hii.c:163
EFI_DEVICE_PATH_PROTOCOL * hii_child_path
Device path of HII child handle.
Definition: efi_snp.h:65
static EFI_HII_CONFIG_ACCESS_PROTOCOL efi_snp_device_hii
HII configuration access protocol.
Definition: efi_snp_hii.c:646
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:132
#define END_ENTIRE_DEVICE_PATH_SUBTYPE
Definition: DevicePath.h:1328
UINT8 Length[2]
Specific Device Path data.
Definition: DevicePath.h:64
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:35
UINT8 SubType
Varies by Type 0xFF End Entire Device Path, or 0x01 End This Instance of a Device Path and start a ne...
Definition: DevicePath.h:59
EFI_HII_DATABASE_NEW_PACK NewPackageList
Definition: HiiDatabase.h:516
UINT8 Type
0x01 Hardware Device Path.
Definition: DevicePath.h:52
EFI_SYSTEM_TABLE * efi_systab
EFI_DEVICE_PATH_PROTOCOL * path
The device path.
Definition: efi_snp.h:75
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static EFI_HII_DATABASE_PROTOCOL * efihii
EFI HII database protocol.
Definition: efi_snp_hii.c:80

References EFI_SYSTEM_TABLE::BootServices, DBGC, EEFI, efi_child_add(), efi_child_del(), efi_device_path_protocol_guid, efi_hii_config_access_protocol_guid, efi_nullify_hii(), efi_path_len(), efi_snp_device_hii, efi_snp_hii_package_list(), efi_snp_hii_random_guid(), efi_systab, efihii, END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, ENOMEM, ENOTSUP, free, VENDOR_DEVICE_PATH::Guid, efi_snp_device::handle, HARDWARE_DEVICE_PATH, VENDOR_DEVICE_PATH::Header, efi_snp_device::hii, efi_snp_device::hii_child_handle, efi_snp_device::hii_child_path, efi_snp_device::hii_handle, HW_VENDOR_DP, EFI_BOOT_SERVICES::InstallMultipleProtocolInterfaces, EFI_DEVICE_PATH_PROTOCOL::Length, memcpy(), _EFI_HII_DATABASE_PROTOCOL::NewPackageList, NULL, efi_snp_device::package_list, efi_snp_device::path, rc, _EFI_HII_DATABASE_PROTOCOL::RemovePackageList, strerror(), EFI_DEVICE_PATH_PROTOCOL::SubType, EFI_DEVICE_PATH_PROTOCOL::Type, EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces, and zalloc().

Referenced by efi_snp_probe().

◆ efi_snp_hii_uninstall()

int efi_snp_hii_uninstall ( struct efi_snp_device snpdev)

Uninstall HII protocol and package for SNP device.

Parameters
snpdevSNP device
Return values
leakUninstallation failed: leak memory

Definition at line 798 of file efi_snp_hii.c.

798  {
800  int leak = efi_shutdown_in_progress;
801  EFI_STATUS efirc;
802 
803  /* Do nothing if HII database protocol is not supported */
804  if ( ! efihii )
805  return 0;
806 
807  /* Uninstall protocols and remove package list */
808  efi_child_del ( snpdev->handle, snpdev->hii_child_handle );
809  if ( ( ! efi_shutdown_in_progress ) &&
810  ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
811  snpdev->hii_child_handle,
813  NULL ) ) != 0 ) ) {
814  DBGC ( snpdev, "SNPDEV %p could not uninstall HII protocol: "
815  "%s\n", snpdev, strerror ( -EEFI ( efirc ) ) );
816  leak = 1;
817  }
818  efi_nullify_hii ( &snpdev->hii );
819  if ( ! leak )
821  if ( ( ! efi_shutdown_in_progress ) &&
822  ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
823  snpdev->hii_child_handle,
825  NULL ) ) != 0 ) ) {
826  DBGC ( snpdev, "SNPDEV %p could not uninstall HII path: %s\n",
827  snpdev, strerror ( -EEFI ( efirc ) ) );
828  leak = 1;
829  }
830  if ( ! leak ) {
831  free ( snpdev->hii_child_path );
832  snpdev->hii_child_path = NULL;
833  free ( snpdev->package_list );
834  snpdev->package_list = NULL;
835  }
836 
837  /* Report leakage, if applicable */
838  if ( leak && ( ! efi_shutdown_in_progress ) )
839  DBGC ( snpdev, "SNPDEV %p HII nullified and leaked\n", snpdev );
840  return leak;
841 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2000
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:167
EFI_HII_DATABASE_REMOVE_PACK RemovePackageList
Definition: HiiDatabase.h:517
#define DBGC(...)
Definition: compiler.h:505
EFI_HANDLE hii_child_handle
EFI child handle for HII association.
Definition: efi_snp.h:63
EFI_HII_CONFIG_ACCESS_PROTOCOL hii
HII configuration access protocol.
Definition: efi_snp.h:59
EFI_HANDLE handle
EFI device handle.
Definition: efi_snp.h:35
EFI_GUID efi_hii_config_access_protocol_guid
HII configuration access protocol GUID.
Definition: efi_guid.c:156
void efi_child_del(EFI_HANDLE parent, EFI_HANDLE child)
Remove EFI device as child of another EFI device.
Definition: efi_utils.c:128
EFI_HII_HANDLE hii_handle
HII handle.
Definition: efi_snp.h:67
EFI_HII_PACKAGE_LIST_HEADER * package_list
HII package list.
Definition: efi_snp.h:61
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:1836
void efi_nullify_hii(EFI_HII_CONFIG_ACCESS_PROTOCOL *hii)
Nullify HII configuration access protocol.
Definition: efi_null.c:301
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1916
EFI_DEVICE_PATH_PROTOCOL * hii_child_path
Device path of HII child handle.
Definition: efi_snp.h:65
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:132
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:35
EFI_SYSTEM_TABLE * efi_systab
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition: efi_init.c:54
static EFI_HII_DATABASE_PROTOCOL * efihii
EFI HII database protocol.
Definition: efi_snp_hii.c:80

References EFI_SYSTEM_TABLE::BootServices, DBGC, EEFI, efi_child_del(), efi_device_path_protocol_guid, efi_hii_config_access_protocol_guid, efi_nullify_hii(), efi_shutdown_in_progress, efi_systab, efihii, free, efi_snp_device::handle, efi_snp_device::hii, efi_snp_device::hii_child_handle, efi_snp_device::hii_child_path, efi_snp_device::hii_handle, NULL, efi_snp_device::package_list, _EFI_HII_DATABASE_PROTOCOL::RemovePackageList, strerror(), and EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces.

Referenced by efi_snp_probe(), and efi_snp_remove().

◆ find_snpdev()

struct efi_snp_device* find_snpdev ( EFI_HANDLE  handle)

Find SNP device by EFI device handle.

Parameters
handleEFI device handle
Return values
snpdevSNP device, or NULL

Definition at line 1940 of file efi_snp.c.

1940  {
1941  struct efi_snp_device *snpdev;
1942 
1943  list_for_each_entry ( snpdev, &efi_snp_devices, list ) {
1944  if ( snpdev->handle == handle )
1945  return snpdev;
1946  }
1947  return NULL;
1948 }
EFI_HANDLE handle
EFI device handle.
Definition: efi_snp.h:35
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
An SNP device.
Definition: efi_snp.h:27
uint16_t handle
Handle.
Definition: smbios.h:16
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
struct list_head list
List of SNP devices.
Definition: efi_snp.h:29

References handle, efi_snp_device::handle, efi_snp_device::list, list_for_each_entry, and NULL.

Referenced by nii_supported(), and snp_supported().

◆ last_opened_snpdev()

struct efi_snp_device* last_opened_snpdev ( void  )

Get most recently opened SNP device.

Return values
snpdevMost recently opened SNP device, or NULL

Definition at line 1955 of file efi_snp.c.

1955  {
1956  struct net_device *netdev;
1957 
1959  if ( ! netdev )
1960  return NULL;
1961 
1962  return efi_snp_demux ( netdev );
1963 }
static struct net_device * netdev
Definition: gdbudp.c:52
struct net_device * last_opened_netdev(void)
Get most recently opened network device.
Definition: netdevice.c:1003
A network device.
Definition: netdevice.h:352
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static struct efi_snp_device * efi_snp_demux(struct net_device *netdev)
Locate SNP device corresponding to network device.
Definition: efi_snp.c:1608

References efi_snp_demux(), last_opened_netdev(), netdev, and NULL.

Referenced by efi_image_exec().

◆ efi_snp_add_claim()

void efi_snp_add_claim ( int  delta)

Add to SNP claimed/released count.

Parameters
deltaClaim count change

Definition at line 1970 of file efi_snp.c.

1970  {
1971  struct efi_snp_device *snpdev;
1972 
1973  /* Raise TPL if we are about to claim devices */
1974  if ( ! efi_snp_claimed )
1976 
1977  /* Claim SNP devices */
1978  efi_snp_claimed += delta;
1979  assert ( efi_snp_claimed >= 0 );
1980 
1981  /* Update SNP mode state for each interface */
1982  list_for_each_entry ( snpdev, &efi_snp_devices, list )
1983  efi_snp_set_state ( snpdev );
1984 
1985  /* Restore TPL if we have released devices */
1986  if ( ! efi_snp_claimed )
1988 }
void efi_raise_tpl(struct efi_saved_tpl *tpl)
Raise task priority level to TPL_CALLBACK.
Definition: efi_init.c:373
static void efi_snp_set_state(struct efi_snp_device *snpdev)
Set EFI SNP mode state.
Definition: efi_snp.c:91
static int efi_snp_claimed
Network devices are currently claimed for use by iPXE.
Definition: efi_snp.c:48
assert((readw(&hdr->flags) &(GTF_reading|GTF_writing))==0)
#define list_for_each_entry(pos, head, member)
Iterate over entries in a list.
Definition: list.h:420
static struct efi_saved_tpl efi_snp_saved_tpl
TPL prior to network devices being claimed.
Definition: efi_snp.c:51
An SNP device.
Definition: efi_snp.h:27
void efi_restore_tpl(struct efi_saved_tpl *tpl)
Restore task priority level.
Definition: efi_init.c:389
struct list_head list
List of SNP devices.
Definition: efi_snp.h:29

References assert(), efi_raise_tpl(), efi_restore_tpl(), efi_snp_claimed, efi_snp_saved_tpl, efi_snp_set_state(), efi_snp_device::list, and list_for_each_entry.

Referenced by efi_snp_claim(), and efi_snp_release().

◆ efi_snp_claim()

static void efi_snp_claim ( void  )
inlinestatic

Claim network devices for use by iPXE.

Definition at line 88 of file efi_snp.h.

88  {
89  efi_snp_add_claim ( +1 );
90 }
void efi_snp_add_claim(int delta)
Add to SNP claimed/released count.
Definition: efi_snp.c:1970

References efi_snp_add_claim().

Referenced by _efi_start(), efi_block_boot(), efi_block_io_read(), efi_block_io_reset(), efi_block_io_write(), efi_download_start(), efi_image_exec(), efi_pxe_dhcp(), efi_pxe_mtftp(), efi_pxe_udp_open(), and efi_snp_load_file().

◆ efi_snp_release()

static void efi_snp_release ( void  )
inlinestatic

Release network devices for use via SNP.

Definition at line 96 of file efi_snp.h.

96  {
97  efi_snp_add_claim ( -1 );
98 }
void efi_snp_add_claim(int delta)
Add to SNP claimed/released count.
Definition: efi_snp.c:1970

References efi_snp_add_claim().

Referenced by _efi_start(), efi_block_boot(), efi_block_io_read(), efi_block_io_reset(), efi_block_io_write(), efi_download_close(), efi_download_start(), efi_image_exec(), efi_pxe_dhcp(), efi_pxe_mtftp(), efi_pxe_udp_close(), and efi_snp_load_file().