iPXE
Data Structures | Macros | Functions | Variables
efi_block.c File Reference

EFI block device protocols. More...

#include <stddef.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include <ipxe/refcnt.h>
#include <ipxe/list.h>
#include <ipxe/uri.h>
#include <ipxe/interface.h>
#include <ipxe/blockdev.h>
#include <ipxe/xfer.h>
#include <ipxe/open.h>
#include <ipxe/retry.h>
#include <ipxe/timer.h>
#include <ipxe/process.h>
#include <ipxe/sanboot.h>
#include <ipxe/iso9660.h>
#include <ipxe/acpi.h>
#include <ipxe/efi/efi.h>
#include <ipxe/efi/Protocol/BlockIo.h>
#include <ipxe/efi/Protocol/SimpleFileSystem.h>
#include <ipxe/efi/Protocol/AcpiTable.h>
#include <ipxe/efi/efi_driver.h>
#include <ipxe/efi/efi_strings.h>
#include <ipxe/efi/efi_snp.h>
#include <ipxe/efi/efi_utils.h>
#include <ipxe/efi/efi_block.h>

Go to the source code of this file.

Data Structures

struct  efi_block_vendor_path
 An iPXE EFI block device vendor device path. More...
 
struct  efi_block_data
 EFI SAN device private data. More...
 
struct  efi_acpi_table
 An installed ACPI table. More...
 

Macros

#define IPXE_BLOCK_DEVICE_PATH_GUID
 iPXE EFI block device vendor device path GUID More...
 

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
 
 EFI_REQUEST_PROTOCOL (EFI_ACPI_TABLE_PROTOCOL, &acpi)
 
static int efi_block_rw (struct san_device *sandev, uint64_t lba, void *data, size_t len, int(*sandev_rw)(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer))
 Read from or write to EFI block device. More...
 
static EFI_STATUS EFIAPI efi_block_io_reset (EFI_BLOCK_IO_PROTOCOL *block_io, BOOLEAN verify __unused)
 Reset EFI block device. More...
 
static EFI_STATUS EFIAPI efi_block_io_read (EFI_BLOCK_IO_PROTOCOL *block_io, UINT32 media __unused, EFI_LBA lba, UINTN len, VOID *data)
 Read from EFI block device. More...
 
static EFI_STATUS EFIAPI efi_block_io_write (EFI_BLOCK_IO_PROTOCOL *block_io, UINT32 media __unused, EFI_LBA lba, UINTN len, VOID *data)
 Write to EFI block device. More...
 
static EFI_STATUS EFIAPI efi_block_io_flush (EFI_BLOCK_IO_PROTOCOL *block_io)
 Flush data to EFI block device. More...
 
static void efi_block_connect (struct san_device *sandev)
 Connect all possible drivers to EFI block device. More...
 
static int efi_block_hook (unsigned int drive, struct uri **uris, unsigned int count, unsigned int flags)
 Hook EFI block device. More...
 
static void efi_block_unhook (unsigned int drive)
 Unhook EFI block device. More...
 
static LIST_HEAD (efi_acpi_tables)
 List of installed ACPI tables. More...
 
static int efi_block_install (struct acpi_header *hdr)
 Install ACPI table. More...
 
static int efi_block_describe (void)
 Describe EFI block devices. More...
 
static int efi_block_boot_image (struct san_device *sandev, EFI_HANDLE handle, const char *filename, EFI_HANDLE *image)
 Try booting from child device of EFI block device. More...
 
static int efi_block_boot (unsigned int drive, const char *filename)
 Boot from EFI block device. More...
 
 PROVIDE_SANBOOT (efi, san_hook, efi_block_hook)
 
 PROVIDE_SANBOOT (efi, san_unhook, efi_block_unhook)
 
 PROVIDE_SANBOOT (efi, san_describe, efi_block_describe)
 
 PROVIDE_SANBOOT (efi, san_boot, efi_block_boot)
 

Variables

static EFI_ACPI_TABLE_PROTOCOLacpi
 ACPI table protocol protocol. More...
 
static wchar_t efi_block_boot_filename [] = EFI_REMOVABLE_MEDIA_FILE_NAME
 Boot filename. More...
 
static EFI_GUID ipxe_block_device_path_guid = IPXE_BLOCK_DEVICE_PATH_GUID
 iPXE EFI block device vendor device path GUID More...
 

Detailed Description

EFI block device protocols.

Definition in file efi_block.c.

Macro Definition Documentation

◆ IPXE_BLOCK_DEVICE_PATH_GUID

#define IPXE_BLOCK_DEVICE_PATH_GUID
Value:
{ 0x8998b594, 0xf531, 0x4e87, \
{ 0x8b, 0xdf, 0x8f, 0x88, 0x54, 0x3e, 0x99, 0xd4 } }

iPXE EFI block device vendor device path GUID

Definition at line 68 of file efi_block.c.

Function Documentation

◆ FILE_LICENCE()

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )

◆ EFI_REQUEST_PROTOCOL()

EFI_REQUEST_PROTOCOL ( EFI_ACPI_TABLE_PROTOCOL  ,
acpi 
)

◆ efi_block_rw()

static int efi_block_rw ( struct san_device sandev,
uint64_t  lba,
void *  data,
size_t  len,
int(*)(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer sandev_rw 
)
static

Read from or write to EFI block device.

Parameters
sandevSAN device
lbaStarting LBA
dataData buffer
lenSize of buffer
sandev_rwSAN device read/write method
Return values
rcReturn status code

Definition at line 108 of file efi_block.c.

112  {
113  struct efi_block_data *block = sandev->priv;
114  unsigned int count;
115  int rc;
116 
117  /* Sanity check */
118  count = ( len / block->media.BlockSize );
119  if ( ( count * block->media.BlockSize ) != len ) {
120  DBGC ( sandev, "EFIBLK %#02x impossible length %#zx\n",
121  sandev->drive, len );
122  return -EINVAL;
123  }
124 
125  /* Read from / write to block device */
126  if ( ( rc = sandev_rw ( sandev, lba, count,
127  virt_to_user ( data ) ) ) != 0 ) {
128  DBGC ( sandev, "EFIBLK %#02x I/O failed: %s\n",
129  sandev->drive, strerror ( rc ) );
130  return rc;
131  }
132 
133  return 0;
134 }
#define EINVAL
Invalid argument.
Definition: errno.h:428
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t lba
Start address.
Definition: scsi.h:23
struct san_device * sandev
SAN device.
Definition: efi_block.c:87
static int sandev_rw(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer, int(*block_rw)(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, userptr_t buffer, size_t len))
Read from or write to SAN device.
Definition: sanboot.c:587
uint16_t block
Definition: tftp.h:12
#define DBGC(...)
Definition: compiler.h:505
EFI SAN device private data.
Definition: efi_block.c:85
unsigned int drive
Drive number.
Definition: sanboot.h:54
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
uint32_t len
Length.
Definition: ena.h:14
void * priv
Driver private data.
Definition: sanboot.h:78
uint16_t count
Number of entries.
Definition: ena.h:22
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12

References block, count, data, DBGC, san_device::drive, EINVAL, lba, len, san_device::priv, rc, efi_block_data::sandev, sandev_rw(), strerror(), and virt_to_user().

Referenced by efi_block_io_read(), and efi_block_io_write().

◆ efi_block_io_reset()

static EFI_STATUS EFIAPI efi_block_io_reset ( EFI_BLOCK_IO_PROTOCOL block_io,
BOOLEAN verify  __unused 
)
static

Reset EFI block device.

Parameters
block_ioBlock I/O protocol
verifyPerform extended verification
Return values
efircEFI status code

Definition at line 143 of file efi_block.c.

144  {
145  struct efi_block_data *block =
147  struct san_device *sandev = block->sandev;
148  int rc;
149 
150  DBGC2 ( sandev, "EFIBLK %#02x reset\n", sandev->drive );
151  efi_snp_claim();
152  rc = sandev_reset ( sandev );
153  efi_snp_release();
154  return EFIRC ( rc );
155 }
int sandev_reset(struct san_device *sandev)
Reset SAN device.
Definition: sanboot.c:565
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint16_t block
Definition: tftp.h:12
EFI_BLOCK_IO_PROTOCOL block_io
Block I/O protocol.
Definition: efi_block.c:93
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:88
EFI SAN device private data.
Definition: efi_block.c:85
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
unsigned int drive
Drive number.
Definition: sanboot.h:54
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition: efi_snp.h:96
A SAN device.
Definition: sanboot.h:47
#define DBGC2(...)
Definition: compiler.h:522
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:149

References block, efi_block_data::block_io, container_of, DBGC2, san_device::drive, efi_snp_claim(), efi_snp_release(), EFIRC, rc, and sandev_reset().

Referenced by efi_block_hook().

◆ efi_block_io_read()

static EFI_STATUS EFIAPI efi_block_io_read ( EFI_BLOCK_IO_PROTOCOL block_io,
UINT32 media  __unused,
EFI_LBA  lba,
UINTN  len,
VOID data 
)
static

Read from EFI block device.

Parameters
block_ioBlock I/O protocol
mediaMedia identifier
lbaStarting LBA
lenSize of buffer
dataData buffer
Return values
efircEFI status code

Definition at line 168 of file efi_block.c.

169  {
170  struct efi_block_data *block =
172  struct san_device *sandev = block->sandev;
173  int rc;
174 
175  DBGC2 ( sandev, "EFIBLK %#02x read LBA %#08llx to %p+%#08zx\n",
176  sandev->drive, lba, data, ( ( size_t ) len ) );
177  efi_snp_claim();
178  rc = efi_block_rw ( sandev, lba, data, len, sandev_read );
179  efi_snp_release();
180  return EFIRC ( rc );
181 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t lba
Start address.
Definition: scsi.h:23
uint16_t block
Definition: tftp.h:12
EFI_BLOCK_IO_PROTOCOL block_io
Block I/O protocol.
Definition: efi_block.c:93
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:88
static int efi_block_rw(struct san_device *sandev, uint64_t lba, void *data, size_t len, int(*sandev_rw)(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer))
Read from or write to EFI block device.
Definition: efi_block.c:108
EFI SAN device private data.
Definition: efi_block.c:85
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
unsigned int drive
Drive number.
Definition: sanboot.h:54
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Read from SAN device.
Definition: sanboot.c:636
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition: efi_snp.h:96
A SAN device.
Definition: sanboot.h:47
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:149

References block, efi_block_data::block_io, container_of, data, DBGC2, san_device::drive, efi_block_rw(), efi_snp_claim(), efi_snp_release(), EFIRC, lba, len, rc, and sandev_read().

Referenced by efi_block_hook().

◆ efi_block_io_write()

static EFI_STATUS EFIAPI efi_block_io_write ( EFI_BLOCK_IO_PROTOCOL block_io,
UINT32 media  __unused,
EFI_LBA  lba,
UINTN  len,
VOID data 
)
static

Write to EFI block device.

Parameters
block_ioBlock I/O protocol
mediaMedia identifier
lbaStarting LBA
lenSize of buffer
dataData buffer
Return values
efircEFI status code

Definition at line 194 of file efi_block.c.

195  {
196  struct efi_block_data *block =
198  struct san_device *sandev = block->sandev;
199  int rc;
200 
201  DBGC2 ( sandev, "EFIBLK %#02x write LBA %#08llx from %p+%#08zx\n",
202  sandev->drive, lba, data, ( ( size_t ) len ) );
203  efi_snp_claim();
204  rc = efi_block_rw ( sandev, lba, data, len, sandev_write );
205  efi_snp_release();
206  return EFIRC ( rc );
207 }
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
uint32_t lba
Start address.
Definition: scsi.h:23
uint16_t block
Definition: tftp.h:12
EFI_BLOCK_IO_PROTOCOL block_io
Block I/O protocol.
Definition: efi_block.c:93
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:88
static int efi_block_rw(struct san_device *sandev, uint64_t lba, void *data, size_t len, int(*sandev_rw)(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer))
Read from or write to EFI block device.
Definition: efi_block.c:108
EFI SAN device private data.
Definition: efi_block.c:85
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
unsigned int drive
Drive number.
Definition: sanboot.h:54
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition: efi_snp.h:96
A SAN device.
Definition: sanboot.h:47
uint32_t len
Length.
Definition: ena.h:14
#define DBGC2(...)
Definition: compiler.h:522
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
int sandev_write(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Write to SAN device.
Definition: sanboot.c:656
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:149

References block, efi_block_data::block_io, container_of, data, DBGC2, san_device::drive, efi_block_rw(), efi_snp_claim(), efi_snp_release(), EFIRC, lba, len, rc, and sandev_write().

Referenced by efi_block_hook().

◆ efi_block_io_flush()

static EFI_STATUS EFIAPI efi_block_io_flush ( EFI_BLOCK_IO_PROTOCOL block_io)
static

Flush data to EFI block device.

Parameters
block_ioBlock I/O protocol
Return values
efircEFI status code

Definition at line 216 of file efi_block.c.

216  {
217  struct efi_block_data *block =
219  struct san_device *sandev = block->sandev;
220 
221  DBGC2 ( sandev, "EFIBLK %#02x flush\n", sandev->drive );
222 
223  /* Nothing to do */
224  return 0;
225 }
uint16_t block
Definition: tftp.h:12
EFI_BLOCK_IO_PROTOCOL block_io
Block I/O protocol.
Definition: efi_block.c:93
EFI SAN device private data.
Definition: efi_block.c:85
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
unsigned int drive
Drive number.
Definition: sanboot.h:54
A SAN device.
Definition: sanboot.h:47
#define DBGC2(...)
Definition: compiler.h:522

References block, efi_block_data::block_io, container_of, DBGC2, and san_device::drive.

Referenced by efi_block_hook().

◆ efi_block_connect()

static void efi_block_connect ( struct san_device sandev)
static

Connect all possible drivers to EFI block device.

Parameters
sandevSAN device

Definition at line 232 of file efi_block.c.

232  {
234  struct efi_block_data *block = sandev->priv;
235  EFI_STATUS efirc;
236  int rc;
237 
238  /* Try to connect all possible drivers to this block device */
239  if ( ( efirc = bs->ConnectController ( block->handle, NULL,
240  NULL, 1 ) ) != 0 ) {
241  rc = -EEFI ( efirc );
242  DBGC ( sandev, "EFIBLK %#02x could not connect drivers: %s\n",
243  sandev->drive, strerror ( rc ) );
244  /* May not be an error; may already be connected */
245  }
246  DBGC2 ( sandev, "EFIBLK %#02x supports protocols:\n", sandev->drive );
247  DBGC2_EFI_PROTOCOLS ( sandev, block->handle );
248 }
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:157
struct san_device * sandev
SAN device.
Definition: efi_block.c:87
uint16_t block
Definition: tftp.h:12
#define DBGC(...)
Definition: compiler.h:505
EFI SAN device private data.
Definition: efi_block.c:85
unsigned int drive
Drive number.
Definition: sanboot.h:54
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
EFI Boot Services Table.
Definition: UefiSpec.h:1836
EFI_CONNECT_CONTROLLER ConnectController
Definition: UefiSpec.h:1899
#define DBGC2(...)
Definition: compiler.h:522
void * priv
Driver private data.
Definition: sanboot.h:78
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:35
#define DBGC2_EFI_PROTOCOLS(...)
Definition: efi.h:267
EFI_SYSTEM_TABLE * efi_systab
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References block, EFI_SYSTEM_TABLE::BootServices, EFI_BOOT_SERVICES::ConnectController, DBGC, DBGC2, DBGC2_EFI_PROTOCOLS, san_device::drive, EEFI, efi_systab, NULL, san_device::priv, rc, efi_block_data::sandev, and strerror().

Referenced by efi_block_boot(), and efi_block_hook().

◆ efi_block_hook()

static int efi_block_hook ( unsigned int  drive,
struct uri **  uris,
unsigned int  count,
unsigned int  flags 
)
static

Hook EFI block device.

Parameters
driveDrive number
urisList of URIs
countNumber of URIs
flagsFlags
Return values
driveDrive number, or negative error

Definition at line 259 of file efi_block.c.

260  {
264  struct efi_snp_device *snpdev;
265  struct san_device *sandev;
266  struct efi_block_data *block;
267  size_t prefix_len;
268  size_t uri_len;
269  size_t vendor_len;
270  size_t len;
271  char *uri_buf;
272  EFI_STATUS efirc;
273  int rc;
274 
275  /* Sanity check */
276  if ( ! count ) {
277  DBG ( "EFIBLK has no URIs\n" );
278  rc = -ENOTTY;
279  goto err_no_uris;
280  }
281 
282  /* Find an appropriate parent device handle */
283  snpdev = last_opened_snpdev();
284  if ( ! snpdev ) {
285  DBG ( "EFIBLK could not identify SNP device\n" );
286  rc = -ENODEV;
287  goto err_no_snpdev;
288  }
289 
290  /* Calculate length of private data */
291  prefix_len = efi_devpath_len ( snpdev->path );
292  uri_len = format_uri ( uris[0], NULL, 0 );
293  vendor_len = ( sizeof ( *vendor ) +
294  ( ( uri_len + 1 /* NUL */ ) * sizeof ( wchar_t ) ) );
295  len = ( sizeof ( *block ) + uri_len + 1 /* NUL */ + prefix_len +
296  vendor_len + sizeof ( *end ) );
297 
298  /* Allocate and initialise structure */
299  sandev = alloc_sandev ( uris, count, len );
300  if ( ! sandev ) {
301  rc = -ENOMEM;
302  goto err_alloc;
303  }
304  block = sandev->priv;
305  block->sandev = sandev;
306  block->media.MediaPresent = 1;
307  block->media.LogicalBlocksPerPhysicalBlock = 1;
308  block->block_io.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
309  block->block_io.Media = &block->media;
310  block->block_io.Reset = efi_block_io_reset;
311  block->block_io.ReadBlocks = efi_block_io_read;
312  block->block_io.WriteBlocks = efi_block_io_write;
313  block->block_io.FlushBlocks = efi_block_io_flush;
314  uri_buf = ( ( ( void * ) block ) + sizeof ( *block ) );
315  block->path = ( ( ( void * ) uri_buf ) + uri_len + 1 /* NUL */ );
316 
317  /* Construct device path */
318  memcpy ( block->path, snpdev->path, prefix_len );
319  vendor = ( ( ( void * ) block->path ) + prefix_len );
320  vendor->vendor.Header.Type = HARDWARE_DEVICE_PATH;
321  vendor->vendor.Header.SubType = HW_VENDOR_DP;
322  vendor->vendor.Header.Length[0] = ( vendor_len & 0xff );
323  vendor->vendor.Header.Length[1] = ( vendor_len >> 8 );
324  memcpy ( &vendor->vendor.Guid, &ipxe_block_device_path_guid,
325  sizeof ( vendor->vendor.Guid ) );
326  format_uri ( uris[0], uri_buf, ( uri_len + 1 /* NUL */ ) );
327  efi_snprintf ( vendor->uri, ( uri_len + 1 /* NUL */ ), "%s", uri_buf );
328  end = ( ( ( void * ) vendor ) + vendor_len );
329  end->Type = END_DEVICE_PATH_TYPE;
331  end->Length[0] = sizeof ( *end );
332  DBGC ( sandev, "EFIBLK %#02x has device path %s\n",
333  drive, efi_devpath_text ( block->path ) );
334 
335  /* Register SAN device */
336  if ( ( rc = register_sandev ( sandev, drive, flags ) ) != 0 ) {
337  DBGC ( sandev, "EFIBLK %#02x could not register: %s\n",
338  drive, strerror ( rc ) );
339  goto err_register;
340  }
341 
342  /* Update media descriptor */
343  block->media.BlockSize =
345  block->media.LastBlock =
346  ( ( sandev->capacity.blocks >> sandev->blksize_shift ) - 1 );
347 
348  /* Install protocols */
349  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
350  &block->handle,
351  &efi_block_io_protocol_guid, &block->block_io,
353  NULL ) ) != 0 ) {
354  rc = -EEFI ( efirc );
355  DBGC ( sandev, "EFIBLK %#02x could not install protocols: %s\n",
356  sandev->drive, strerror ( rc ) );
357  goto err_install;
358  }
359 
360  /* Connect all possible protocols */
362 
363  return drive;
364 
366  block->handle,
367  &efi_block_io_protocol_guid, &block->block_io,
369  err_install:
371  err_register:
372  sandev_put ( sandev );
373  err_alloc:
374  err_no_snpdev:
375  err_no_uris:
376  return rc;
377 }
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:157
#define END_DEVICE_PATH_TYPE
Definition: DevicePath.h:1327
struct san_device * sandev
SAN device.
Definition: efi_block.c:87
#define HARDWARE_DEVICE_PATH
Hardware Device Paths.
Definition: DevicePath.h:77
uint16_t block
Definition: tftp.h:12
void unregister_sandev(struct san_device *sandev)
Unregister SAN device.
Definition: sanboot.c:925
#define DBGC(...)
Definition: compiler.h:505
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1915
size_t efi_devpath_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition: efi_utils.c:59
static void sandev_put(struct san_device *sandev)
Drop reference to SAN device.
Definition: sanboot.h:202
static EFI_STATUS EFIAPI efi_block_io_write(EFI_BLOCK_IO_PROTOCOL *block_io, UINT32 media __unused, EFI_LBA lba, UINTN len, VOID *data)
Write to EFI block device.
Definition: efi_block.c:194
uint8_t drive
Drive number.
Definition: int13.h:16
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:51
EFI SAN device private data.
Definition: efi_block.c:85
struct efi_snp_device * last_opened_snpdev(void)
Get most recently opened SNP device.
Definition: efi_snp.c:1954
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define EFI_BLOCK_IO_PROTOCOL_REVISION3
Definition: BlockIo.h:212
void * memcpy(void *dest, const void *src, size_t len) __nonnull
#define HW_VENDOR_DP
Hardware Vendor Device Path SubType.
Definition: DevicePath.h:142
unsigned int drive
Drive number.
Definition: sanboot.h:54
int register_sandev(struct san_device *sandev, unsigned int drive, unsigned int flags)
Register SAN device.
Definition: sanboot.c:868
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
Definition: efi_strings.c:104
unsigned int blksize_shift
Block size shift.
Definition: sanboot.h:73
size_t format_uri(const struct uri *uri, char *buf, size_t len)
Format URI.
Definition: uri.c:457
uint64_t blocks
Total number of blocks.
Definition: blockdev.h:20
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
Definition: efi_debug.c:366
static EFI_STATUS EFIAPI efi_block_io_reset(EFI_BLOCK_IO_PROTOCOL *block_io, BOOLEAN verify __unused)
Reset EFI block device.
Definition: efi_block.c:143
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
EFI Boot Services Table.
Definition: UefiSpec.h:1836
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1916
An SNP device.
Definition: efi_snp.h:27
#define ENODEV
No such device.
Definition: errno.h:509
A SAN device.
Definition: sanboot.h:47
An iPXE EFI block device vendor device path.
Definition: efi_block.c:77
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:132
struct block_device_capacity capacity
Raw block device capacity.
Definition: sanboot.h:66
#define END_ENTIRE_DEVICE_PATH_SUBTYPE
Definition: DevicePath.h:1328
static EFI_STATUS EFIAPI efi_block_io_read(EFI_BLOCK_IO_PROTOCOL *block_io, UINT32 media __unused, EFI_LBA lba, UINTN len, VOID *data)
Read from EFI block device.
Definition: efi_block.c:168
union bootph_vendor vendor
uint32_t len
Length.
Definition: ena.h:14
EFI_GUID efi_block_io_protocol_guid
Block I/O protocol GUID.
Definition: efi_guid.c:108
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
static EFI_STATUS EFIAPI efi_block_io_flush(EFI_BLOCK_IO_PROTOCOL *block_io)
Flush data to EFI block device.
Definition: efi_block.c:216
void * priv
Driver private data.
Definition: sanboot.h:78
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:35
uint16_t count
Number of entries.
Definition: ena.h:22
uint32_t end
Ending offset.
Definition: netvsc.h:18
EFI_SYSTEM_TABLE * efi_systab
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
static void efi_block_connect(struct san_device *sandev)
Connect all possible drivers to EFI block device.
Definition: efi_block.c:232
EFI_DEVICE_PATH_PROTOCOL * path
The device path.
Definition: efi_snp.h:75
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
static EFI_GUID ipxe_block_device_path_guid
iPXE EFI block device vendor device path GUID
Definition: efi_block.c:74
struct san_device * alloc_sandev(struct uri **uris, unsigned int count, size_t priv_size)
Allocate SAN device.
Definition: sanboot.c:825
size_t blksize
Block size.
Definition: blockdev.h:22
uint8_t flags
Flags.
Definition: ena.h:18

References alloc_sandev(), block_device_capacity::blksize, san_device::blksize_shift, block, block_device_capacity::blocks, EFI_SYSTEM_TABLE::BootServices, san_device::capacity, count, DBG, DBGC, drive, san_device::drive, EEFI, efi_block_connect(), efi_block_io_flush(), efi_block_io_protocol_guid, EFI_BLOCK_IO_PROTOCOL_REVISION3, efi_block_io_read(), efi_block_io_reset(), efi_block_io_write(), efi_device_path_protocol_guid, efi_devpath_len(), efi_devpath_text(), efi_snprintf(), efi_systab, end, END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, ENODEV, ENOMEM, ENOTTY, flags, format_uri(), HARDWARE_DEVICE_PATH, HW_VENDOR_DP, EFI_BOOT_SERVICES::InstallMultipleProtocolInterfaces, ipxe_block_device_path_guid, last_opened_snpdev(), len, memcpy(), NULL, efi_snp_device::path, san_device::priv, rc, register_sandev(), efi_block_data::sandev, sandev_put(), strerror(), EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces, unregister_sandev(), and vendor.

◆ efi_block_unhook()

static void efi_block_unhook ( unsigned int  drive)
static

Unhook EFI block device.

Parameters
driveDrive number

Definition at line 384 of file efi_block.c.

384  {
386  struct san_device *sandev;
387  struct efi_block_data *block;
388 
389  /* Find SAN device */
390  sandev = sandev_find ( drive );
391  if ( ! sandev ) {
392  DBG ( "EFIBLK cannot find drive %#02x\n", drive );
393  return;
394  }
395  block = sandev->priv;
396 
397  /* Uninstall protocols */
399  block->handle,
400  &efi_block_io_protocol_guid, &block->block_io,
402 
403  /* Unregister SAN device */
405 
406  /* Drop reference to drive */
407  sandev_put ( sandev );
408 }
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2000
struct san_device * sandev
SAN device.
Definition: efi_block.c:87
uint16_t block
Definition: tftp.h:12
void unregister_sandev(struct san_device *sandev)
Unregister SAN device.
Definition: sanboot.c:925
static void sandev_put(struct san_device *sandev)
Drop reference to SAN device.
Definition: sanboot.h:202
uint8_t drive
Drive number.
Definition: int13.h:16
EFI SAN device private data.
Definition: efi_block.c:85
EFI Boot Services Table.
Definition: UefiSpec.h:1836
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1916
A SAN device.
Definition: sanboot.h:47
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:132
struct san_device * sandev_find(unsigned int drive)
Find SAN device by drive number.
Definition: sanboot.c:100
EFI_GUID efi_block_io_protocol_guid
Block I/O protocol GUID.
Definition: efi_guid.c:108
void * priv
Driver private data.
Definition: sanboot.h:78
EFI_SYSTEM_TABLE * efi_systab
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362

References block, EFI_SYSTEM_TABLE::BootServices, DBG, drive, efi_block_io_protocol_guid, efi_device_path_protocol_guid, efi_systab, NULL, san_device::priv, efi_block_data::sandev, sandev_find(), sandev_put(), EFI_BOOT_SERVICES::UninstallMultipleProtocolInterfaces, and unregister_sandev().

◆ LIST_HEAD()

static LIST_HEAD ( efi_acpi_tables  )
static

List of installed ACPI tables.

◆ efi_block_install()

static int efi_block_install ( struct acpi_header hdr)
static

Install ACPI table.

Parameters
hdrACPI description header
Return values
rcReturn status code

Definition at line 427 of file efi_block.c.

427  {
428  size_t len = le32_to_cpu ( hdr->length );
429  struct efi_acpi_table *installed;
430  EFI_STATUS efirc;
431  int rc;
432 
433  /* Allocate installed table record */
434  installed = zalloc ( sizeof ( *installed ) );
435  if ( ! installed ) {
436  rc = -ENOMEM;
437  goto err_alloc;
438  }
439 
440  /* Fill in common parameters */
441  strncpy ( hdr->oem_id, "FENSYS", sizeof ( hdr->oem_id ) );
442  strncpy ( hdr->oem_table_id, "iPXE", sizeof ( hdr->oem_table_id ) );
443 
444  /* Fix up ACPI checksum */
446 
447  /* Install table */
448  if ( ( efirc = acpi->InstallAcpiTable ( acpi, hdr, len,
449  &installed->key ) ) != 0 ){
450  rc = -EEFI ( efirc );
451  DBGC ( acpi, "EFIBLK could not install %s: %s\n",
452  acpi_name ( hdr->signature ), strerror ( rc ) );
453  DBGC_HDA ( acpi, 0, hdr, len );
454  goto err_install;
455  }
456 
457  /* Add to list of installed tables */
458  list_add_tail ( &installed->list, &efi_acpi_tables );
459 
460  DBGC ( acpi, "EFIBLK installed %s as ACPI table %#lx:\n",
461  acpi_name ( hdr->signature ),
462  ( ( unsigned long ) installed->key ) );
463  DBGC_HDA ( acpi, 0, hdr, len );
464  return 0;
465 
466  list_del ( &installed->list );
467  err_install:
468  free ( installed );
469  err_alloc:
470  return rc;
471 }
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:157
EFI_ACPI_TABLE_INSTALL_ACPI_TABLE InstallAcpiTable
Definition: AcpiTable.h:122
UINTN key
Table key.
Definition: efi_block.c:415
#define le32_to_cpu(value)
Definition: byteswap.h:113
#define DBGC(...)
Definition: compiler.h:505
char * strncpy(char *dest, const char *src, size_t max)
Copy string.
Definition: string.c:317
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define DBGC_HDA(...)
Definition: compiler.h:506
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition: efi_block.c:61
void acpi_fix_checksum(struct acpi_header *acpi)
Fix up ACPI table checksum.
Definition: acpi.c:76
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
uint32_t hdr
Message header.
Definition: intelvf.h:12
struct list_head list
List of installed tables.
Definition: efi_block.c:413
uint32_t len
Length.
Definition: ena.h:14
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:35
static const char * acpi_name(uint32_t signature)
Transcribe ACPI table signature (for debugging)
Definition: acpi.h:55
An installed ACPI table.
Definition: efi_block.c:411

References acpi, acpi_fix_checksum(), acpi_name(), DBGC, DBGC_HDA, EEFI, ENOMEM, free, hdr, _EFI_ACPI_TABLE_PROTOCOL::InstallAcpiTable, efi_acpi_table::key, le32_to_cpu, len, efi_acpi_table::list, list_add_tail, list_del, rc, strerror(), strncpy(), and zalloc().

Referenced by efi_block_describe().

◆ efi_block_describe()

static int efi_block_describe ( void  )
static

Describe EFI block devices.

Return values
rcReturn status code

Definition at line 478 of file efi_block.c.

478  {
479  struct efi_acpi_table *installed;
480  struct efi_acpi_table *tmp;
481  UINTN key;
482  EFI_STATUS efirc;
483  int rc;
484 
485  /* Sanity check */
486  if ( ! acpi ) {
487  DBG ( "EFIBLK has no ACPI table protocol\n" );
488  return -ENOTSUP;
489  }
490 
491  /* Uninstall any existing ACPI tables */
492  list_for_each_entry_safe ( installed, tmp, &efi_acpi_tables, list ) {
493  key = installed->key;
494  if ( ( efirc = acpi->UninstallAcpiTable ( acpi, key ) ) != 0 ) {
495  rc = -EEFI ( efirc );
496  DBGC ( acpi, "EFIBLK could not uninstall ACPI table "
497  "%#lx: %s\n", ( ( unsigned long ) key ),
498  strerror ( rc ) );
499  /* Continue anyway */
500  }
501  list_del ( &installed->list );
502  free ( installed );
503  }
504 
505  /* Install ACPI tables */
506  if ( ( rc = acpi_install ( efi_block_install ) ) != 0 ) {
507  DBGC ( acpi, "EFIBLK could not install ACPI tables: %s\n",
508  strerror ( rc ) );
509  return rc;
510  }
511 
512  return 0;
513 }
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:157
UINTN key
Table key.
Definition: efi_block.c:415
#define DBGC(...)
Definition: compiler.h:505
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
EFI_ACPI_TABLE_UNINSTALL_ACPI_TABLE UninstallAcpiTable
Definition: AcpiTable.h:123
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition: efi_block.c:61
static int efi_block_install(struct acpi_header *hdr)
Install ACPI table.
Definition: efi_block.c:427
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
Definition: list.h:447
int acpi_install(int(*install)(struct acpi_header *acpi))
Install ACPI tables.
Definition: acpi.c:357
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
uint8_t * tmp
Definition: entropy.h:156
UINT64 UINTN
Unsigned value of native width.
Definition: ProcessorBind.h:71
struct list_head list
List of installed tables.
Definition: efi_block.c:413
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:35
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
An installed ACPI table.
Definition: efi_block.c:411
union @375 key
Sense key.
Definition: scsi.h:18

References acpi, acpi_install(), DBG, DBGC, EEFI, efi_block_install(), ENOTSUP, free, key, efi_acpi_table::key, efi_acpi_table::list, list_del, list_for_each_entry_safe, rc, strerror(), tmp, and _EFI_ACPI_TABLE_PROTOCOL::UninstallAcpiTable.

◆ efi_block_boot_image()

static int efi_block_boot_image ( struct san_device sandev,
EFI_HANDLE  handle,
const char *  filename,
EFI_HANDLE image 
)
static

Try booting from child device of EFI block device.

Parameters
sandevSAN device
handleEFI handle
filenameFilename (or NULL to use default)
imageImage handle to fill in
Return values
rcReturn status code

Definition at line 524 of file efi_block.c.

525  {
527  struct efi_block_data *block = sandev->priv;
528  union {
530  void *interface;
531  } path;
532  EFI_DEVICE_PATH_PROTOCOL *boot_path;
533  FILEPATH_DEVICE_PATH *filepath;
535  size_t prefix_len;
536  size_t filepath_len;
537  size_t boot_path_len;
538  EFI_STATUS efirc;
539  int rc;
540 
541  /* Identify device path */
542  if ( ( efirc = bs->OpenProtocol ( handle,
544  &path.interface, efi_image_handle,
545  handle,
547  DBGC ( sandev, "EFIBLK %#02x found filesystem with no device "
548  "path??", sandev->drive );
549  rc = -EEFI ( efirc );
550  goto err_open_device_path;
551  }
552 
553  /* Check if this device is a child of our block device */
554  prefix_len = efi_devpath_len ( block->path );
555  if ( memcmp ( path.path, block->path, prefix_len ) != 0 ) {
556  /* Not a child device */
557  rc = -ENOTTY;
558  goto err_not_child;
559  }
560  DBGC ( sandev, "EFIBLK %#02x found child device %s\n",
561  sandev->drive, efi_devpath_text ( path.path ) );
562 
563  /* Construct device path for boot image */
564  end = efi_devpath_end ( path.path );
565  prefix_len = ( ( ( void * ) end ) - ( ( void * ) path.path ) );
566  filepath_len = ( SIZE_OF_FILEPATH_DEVICE_PATH +
567  ( filename ?
568  ( ( strlen ( filename ) + 1 /* NUL */ ) *
569  sizeof ( filepath->PathName[0] ) ) :
570  sizeof ( efi_block_boot_filename ) ) );
571  boot_path_len = ( prefix_len + filepath_len + sizeof ( *end ) );
572  boot_path = zalloc ( boot_path_len );
573  if ( ! boot_path ) {
574  rc = -ENOMEM;
575  goto err_alloc_path;
576  }
577  memcpy ( boot_path, path.path, prefix_len );
578  filepath = ( ( ( void * ) boot_path ) + prefix_len );
579  filepath->Header.Type = MEDIA_DEVICE_PATH;
580  filepath->Header.SubType = MEDIA_FILEPATH_DP;
581  filepath->Header.Length[0] = ( filepath_len & 0xff );
582  filepath->Header.Length[1] = ( filepath_len >> 8 );
583  if ( filename ) {
584  efi_sprintf ( filepath->PathName, "%s", filename );
585  } else {
587  sizeof ( efi_block_boot_filename ) );
588  }
589  end = ( ( ( void * ) filepath ) + filepath_len );
590  end->Type = END_DEVICE_PATH_TYPE;
592  end->Length[0] = sizeof ( *end );
593  DBGC ( sandev, "EFIBLK %#02x trying to load %s\n",
594  sandev->drive, efi_devpath_text ( boot_path ) );
595 
596  /* Try loading boot image from this device */
597  if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, boot_path,
598  NULL, 0, image ) ) != 0 ) {
599  rc = -EEFI ( efirc );
600  DBGC ( sandev, "EFIBLK %#02x could not load image: %s\n",
601  sandev->drive, strerror ( rc ) );
602  goto err_load_image;
603  }
604 
605  /* Success */
606  rc = 0;
607 
608  err_load_image:
609  free ( boot_path );
610  err_alloc_path:
611  err_not_child:
612  err_open_device_path:
613  return rc;
614 }
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:157
#define END_DEVICE_PATH_TYPE
Definition: DevicePath.h:1327
struct san_device * sandev
SAN device.
Definition: efi_block.c:87
EFI_IMAGE_LOAD LoadImage
Definition: UefiSpec.h:1883
uint16_t block
Definition: tftp.h:12
#define DBGC(...)
Definition: compiler.h:505
size_t efi_devpath_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition: efi_utils.c:59
An executable image.
Definition: image.h:24
This protocol can be used on any device handle to obtain generic path/location information concerning...
Definition: DevicePath.h:51
CHAR16 PathName[1]
A NULL-terminated Path string including directory and file names.
Definition: DevicePath.h:1041
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:1037
EFI SAN device private data.
Definition: efi_block.c:85
EFI_DEVICE_PATH_PROTOCOL * path
Device path protocol.
Definition: efi_block.c:95
#define ENOMEM
Not enough space.
Definition: errno.h:534
void * memcpy(void *dest, const void *src, size_t len) __nonnull
An object interface.
Definition: interface.h:109
unsigned int drive
Drive number.
Definition: sanboot.h:54
#define SIZE_OF_FILEPATH_DEVICE_PATH
Definition: DevicePath.h:1044
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
Definition: efi_debug.c:366
#define EFI_OPEN_PROTOCOL_GET_PROTOCOL
Definition: UefiSpec.h:1271
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
#define efi_sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition: efi_strings.h:43
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:30
size_t strlen(const char *src)
Get length of string.
Definition: string.c:213
static wchar_t efi_block_boot_filename[]
Boot filename.
Definition: efi_block.c:65
#define MEDIA_DEVICE_PATH
Definition: DevicePath.h:946
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
#define ENOTTY
Inappropriate I/O control operation.
Definition: errno.h:594
void * priv
Driver private data.
Definition: sanboot.h:78
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
uint32_t end
Ending offset.
Definition: netvsc.h:18
#define FALSE
Definition: tlan.h:45
UINT8 Type
0x01 Hardware Device Path.
Definition: DevicePath.h:52
EFI_SYSTEM_TABLE * efi_systab
EFI_OPEN_PROTOCOL OpenProtocol
Definition: UefiSpec.h:1905
uint16_t handle
Handle.
Definition: smbios.h:16
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
Definition: string.c:98
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
EFI_DEVICE_PATH_PROTOCOL * efi_devpath_end(EFI_DEVICE_PATH_PROTOCOL *path)
Find end of device path.
Definition: efi_utils.c:41
#define MEDIA_FILEPATH_DP
File Path Media Device Path SubType.
Definition: DevicePath.h:1035

References block, EFI_SYSTEM_TABLE::BootServices, DBGC, san_device::drive, EEFI, efi_block_boot_filename, efi_device_path_protocol_guid, efi_devpath_end(), efi_devpath_len(), efi_devpath_text(), efi_image_handle, EFI_OPEN_PROTOCOL_GET_PROTOCOL, efi_sprintf, efi_systab, end, END_DEVICE_PATH_TYPE, END_ENTIRE_DEVICE_PATH_SUBTYPE, ENOMEM, ENOTTY, FALSE, free, handle, FILEPATH_DEVICE_PATH::Header, EFI_DEVICE_PATH_PROTOCOL::Length, EFI_BOOT_SERVICES::LoadImage, MEDIA_DEVICE_PATH, MEDIA_FILEPATH_DP, memcmp(), memcpy(), NULL, EFI_BOOT_SERVICES::OpenProtocol, efi_block_data::path, FILEPATH_DEVICE_PATH::PathName, san_device::priv, rc, efi_block_data::sandev, SIZE_OF_FILEPATH_DEVICE_PATH, strerror(), strlen(), EFI_DEVICE_PATH_PROTOCOL::SubType, EFI_DEVICE_PATH_PROTOCOL::Type, and zalloc().

Referenced by efi_block_boot().

◆ efi_block_boot()

static int efi_block_boot ( unsigned int  drive,
const char *  filename 
)
static

Boot from EFI block device.

Parameters
driveDrive number
filenameFilename (or NULL to use default)
Return values
rcReturn status code

Definition at line 623 of file efi_block.c.

623  {
625  struct san_device *sandev;
626  EFI_HANDLE *handles;
628  UINTN count;
629  unsigned int i;
630  EFI_STATUS efirc;
631  int rc;
632 
633  /* Find SAN device */
634  sandev = sandev_find ( drive );
635  if ( ! sandev ) {
636  DBG ( "EFIBLK cannot find drive %#02x\n", drive );
637  rc = -ENODEV;
638  goto err_sandev_find;
639  }
640 
641  /* Release SNP devices */
642  efi_snp_release();
643 
644  /* Connect all possible protocols */
645  efi_block_connect ( sandev );
646 
647  /* Locate all handles supporting the Simple File System protocol */
648  if ( ( efirc = bs->LocateHandleBuffer (
650  NULL, &count, &handles ) ) != 0 ) {
651  rc = -EEFI ( efirc );
652  DBGC ( sandev, "EFIBLK %#02x cannot locate file systems: %s\n",
653  sandev->drive, strerror ( rc ) );
654  goto err_locate_file_systems;
655  }
656 
657  /* Try booting from any available child device containing a
658  * suitable boot image. This is something of a wild stab in
659  * the dark, but should end up conforming to user expectations
660  * most of the time.
661  */
662  rc = -ENOENT;
663  for ( i = 0 ; i < count ; i++ ) {
664  if ( ( rc = efi_block_boot_image ( sandev, handles[i], filename,
665  &image ) ) != 0 )
666  continue;
667  DBGC ( sandev, "EFIBLK %#02x found boot image\n",
668  sandev->drive );
669  efirc = bs->StartImage ( image, NULL, NULL );
670  rc = ( efirc ? -EEFI ( efirc ) : 0 );
671  bs->UnloadImage ( image );
672  DBGC ( sandev, "EFIBLK %#02x boot image returned: %s\n",
673  sandev->drive, strerror ( rc ) );
674  break;
675  }
676 
677  bs->FreePool ( handles );
678  err_locate_file_systems:
679  efi_snp_claim();
680  err_sandev_find:
681  return rc;
682 }
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:157
#define DBGC(...)
Definition: compiler.h:505
#define ENOENT
No such file or directory.
Definition: errno.h:514
EFI_IMAGE_UNLOAD UnloadImage
Definition: UefiSpec.h:1886
An executable image.
Definition: image.h:24
uint8_t drive
Drive number.
Definition: int13.h:16
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:88
EFI_GUID efi_simple_file_system_protocol_guid
Simple file system protocol GUID.
Definition: efi_guid.c:232
unsigned int drive
Drive number.
Definition: sanboot.h:54
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
EFI Boot Services Table.
Definition: UefiSpec.h:1836
#define ENODEV
No such device.
Definition: errno.h:509
static void efi_snp_release(void)
Release network devices for use via SNP.
Definition: efi_snp.h:96
A SAN device.
Definition: sanboot.h:47
EFI_IMAGE_START StartImage
Definition: UefiSpec.h:1884
UINT64 UINTN
Unsigned value of native width.
Definition: ProcessorBind.h:71
EFI_FREE_POOL FreePool
Definition: UefiSpec.h:1855
static int efi_block_boot_image(struct san_device *sandev, EFI_HANDLE handle, const char *filename, EFI_HANDLE *image)
Try booting from child device of EFI block device.
Definition: efi_block.c:524
struct san_device * sandev_find(unsigned int drive)
Find SAN device by drive number.
Definition: sanboot.c:100
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:35
uint16_t count
Number of entries.
Definition: ena.h:22
Retrieve the set of handles from the handle database that support a specified protocol.
Definition: UefiSpec.h:1448
EFI_SYSTEM_TABLE * efi_systab
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
static void efi_block_connect(struct san_device *sandev)
Connect all possible drivers to EFI block device.
Definition: efi_block.c:232
#define NULL
NULL pointer (VOID *)
Definition: Base.h:362
Definition: efi.h:55
EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer
Definition: UefiSpec.h:1913

References EFI_SYSTEM_TABLE::BootServices, ByProtocol, count, DBG, DBGC, drive, san_device::drive, EEFI, efi_block_boot_image(), efi_block_connect(), efi_simple_file_system_protocol_guid, efi_snp_claim(), efi_snp_release(), efi_systab, ENODEV, ENOENT, EFI_BOOT_SERVICES::FreePool, EFI_BOOT_SERVICES::LocateHandleBuffer, NULL, rc, sandev_find(), EFI_BOOT_SERVICES::StartImage, strerror(), and EFI_BOOT_SERVICES::UnloadImage.

◆ PROVIDE_SANBOOT() [1/4]

PROVIDE_SANBOOT ( efi  ,
san_hook  ,
efi_block_hook   
)

◆ PROVIDE_SANBOOT() [2/4]

PROVIDE_SANBOOT ( efi  ,
san_unhook  ,
efi_block_unhook   
)

◆ PROVIDE_SANBOOT() [3/4]

PROVIDE_SANBOOT ( efi  ,
san_describe  ,
efi_block_describe   
)

◆ PROVIDE_SANBOOT() [4/4]

PROVIDE_SANBOOT ( efi  ,
san_boot  ,
efi_block_boot   
)

Variable Documentation

◆ acpi

◆ efi_block_boot_filename

wchar_t efi_block_boot_filename[] = EFI_REMOVABLE_MEDIA_FILE_NAME
static

Boot filename.

Definition at line 65 of file efi_block.c.

Referenced by efi_block_boot_image().

◆ ipxe_block_device_path_guid

EFI_GUID ipxe_block_device_path_guid = IPXE_BLOCK_DEVICE_PATH_GUID
static

iPXE EFI block device vendor device path GUID

Definition at line 74 of file efi_block.c.

Referenced by efi_block_hook().