iPXE
efi_block.c
Go to the documentation of this file.
1 /*
2  * Copyright (C) 2016 Michael Brown <mbrown@fensystems.co.uk>.
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of the
7  * License, or any later version.
8  *
9  * This program is distributed in the hope that it will be useful, but
10  * WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12  * General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software
16  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
17  * 02110-1301, USA.
18  *
19  * You can also choose to distribute this program under the terms of
20  * the Unmodified Binary Distribution Licence (as given in the file
21  * COPYING.UBDL), provided that you have satisfied its requirements.
22  */
23 
24 FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL );
25 
26 /**
27  * @file
28  *
29  * EFI block device protocols
30  *
31  */
32 
33 #include <stddef.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <errno.h>
37 #include <ipxe/refcnt.h>
38 #include <ipxe/list.h>
39 #include <ipxe/uri.h>
40 #include <ipxe/interface.h>
41 #include <ipxe/blockdev.h>
42 #include <ipxe/xfer.h>
43 #include <ipxe/open.h>
44 #include <ipxe/retry.h>
45 #include <ipxe/timer.h>
46 #include <ipxe/process.h>
47 #include <ipxe/sanboot.h>
48 #include <ipxe/iso9660.h>
49 #include <ipxe/acpi.h>
50 #include <ipxe/efi/efi.h>
54 #include <ipxe/efi/efi_driver.h>
55 #include <ipxe/efi/efi_strings.h>
56 #include <ipxe/efi/efi_snp.h>
57 #include <ipxe/efi/efi_utils.h>
58 #include <ipxe/efi/efi_block.h>
59 
60 /** ACPI table protocol protocol */
63 
64 /** Boot filename */
65 static wchar_t efi_block_boot_filename[] = EFI_REMOVABLE_MEDIA_FILE_NAME;
66 
67 /** iPXE EFI block device vendor device path GUID */
68 #define IPXE_BLOCK_DEVICE_PATH_GUID \
69  { 0x8998b594, 0xf531, 0x4e87, \
70  { 0x8b, 0xdf, 0x8f, 0x88, 0x54, 0x3e, 0x99, 0xd4 } }
71 
72 /** iPXE EFI block device vendor device path GUID */
75 
76 /** An iPXE EFI block device vendor device path */
78  /** Generic vendor device path */
80  /** Block device URI */
81  CHAR16 uri[0];
82 } __attribute__ (( packed ));
83 
84 /** EFI SAN device private data */
86  /** SAN device */
87  struct san_device *sandev;
88  /** EFI handle */
90  /** Media descriptor */
92  /** Block I/O protocol */
94  /** Device path protocol */
96 };
97 
98 /**
99  * Read from or write to EFI block device
100  *
101  * @v sandev SAN device
102  * @v lba Starting LBA
103  * @v data Data buffer
104  * @v len Size of buffer
105  * @v sandev_rw SAN device read/write method
106  * @ret rc Return status code
107  */
108 static int efi_block_rw ( struct san_device *sandev, uint64_t lba,
109  void *data, size_t len,
110  int ( * sandev_rw ) ( struct san_device *sandev,
111  uint64_t lba, unsigned int count,
112  userptr_t buffer ) ) {
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 }
135 
136 /**
137  * Reset EFI block device
138  *
139  * @v block_io Block I/O protocol
140  * @v verify Perform extended verification
141  * @ret efirc EFI status code
142  */
144  BOOLEAN verify __unused ) {
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 }
156 
157 /**
158  * Read from EFI block device
159  *
160  * @v block_io Block I/O protocol
161  * @v media Media identifier
162  * @v lba Starting LBA
163  * @v len Size of buffer
164  * @v data Data buffer
165  * @ret efirc EFI status code
166  */
167 static EFI_STATUS EFIAPI
169  EFI_LBA lba, UINTN len, VOID *data ) {
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 }
182 
183 /**
184  * Write to EFI block device
185  *
186  * @v block_io Block I/O protocol
187  * @v media Media identifier
188  * @v lba Starting LBA
189  * @v len Size of buffer
190  * @v data Data buffer
191  * @ret efirc EFI status code
192  */
193 static EFI_STATUS EFIAPI
195  EFI_LBA lba, UINTN len, VOID *data ) {
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 }
208 
209 /**
210  * Flush data to EFI block device
211  *
212  * @v block_io Block I/O protocol
213  * @ret efirc EFI status code
214  */
215 static EFI_STATUS EFIAPI
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 }
226 
227 /**
228  * Connect all possible drivers to EFI block device
229  *
230  * @v sandev SAN device
231  */
232 static void efi_block_connect ( struct san_device *sandev ) {
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 }
249 
250 /**
251  * Hook EFI block device
252  *
253  * @v drive Drive number
254  * @v uris List of URIs
255  * @v count Number of URIs
256  * @v flags Flags
257  * @ret drive Drive number, or negative error
258  */
259 static int efi_block_hook ( unsigned int drive, struct uri **uris,
260  unsigned int count, unsigned int flags ) {
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 }
378 
379 /**
380  * Unhook EFI block device
381  *
382  * @v drive Drive number
383  */
384 static void efi_block_unhook ( unsigned int drive ) {
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 }
409 
410 /** An installed ACPI table */
412  /** List of installed tables */
413  struct list_head list;
414  /** Table key */
416 };
417 
418 /** List of installed ACPI tables */
419 static LIST_HEAD ( efi_acpi_tables );
420 
421 /**
422  * Install ACPI table
423  *
424  * @v hdr ACPI description header
425  * @ret rc Return status code
426  */
427 static int efi_block_install ( struct acpi_header *hdr ) {
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 }
472 
473 /**
474  * Describe EFI block devices
475  *
476  * @ret rc Return status code
477  */
478 static int efi_block_describe ( void ) {
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 }
514 
515 /**
516  * Try booting from child device of EFI block device
517  *
518  * @v sandev SAN device
519  * @v handle EFI handle
520  * @v filename Filename (or NULL to use default)
521  * @v image Image handle to fill in
522  * @ret rc Return status code
523  */
524 static int efi_block_boot_image ( struct san_device *sandev, EFI_HANDLE handle,
525  const char *filename, EFI_HANDLE *image ) {
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 }
615 
616 /**
617  * Boot from EFI block device
618  *
619  * @v drive Drive number
620  * @v filename Filename (or NULL to use default)
621  * @ret rc Return status code
622  */
623 static int efi_block_boot ( unsigned int drive, const char *filename ) {
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 }
683 
VENDOR_DEVICE_PATH vendor
Generic vendor device path.
Definition: efi_block.c:79
static int efi_block_describe(void)
Describe EFI block devices.
Definition: efi_block.c:478
#define __attribute__(x)
Definition: compiler.h:10
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2000
#define EINVAL
Invalid argument.
Definition: errno.h:428
The EFI_ACPI_TABLE_PROTOCOL provides the ability for a component to install and uninstall ACPI tables...
Definition: AcpiTable.h:121
int sandev_reset(struct san_device *sandev)
Reset SAN device.
Definition: sanboot.c:565
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
static int efi_block_boot(unsigned int drive, const char *filename)
Boot from EFI block device.
Definition: efi_block.c:623
EFI driver interface.
UINTN key
Table key.
Definition: efi_block.c:415
int san_describe(void)
Describe SAN devices for SAN-booted operating system.
uint32_t lba
Start address.
Definition: scsi.h:23
#define END_DEVICE_PATH_TYPE
Definition: DevicePath.h:1327
int san_hook(unsigned int drive, struct uri **uris, unsigned int count, unsigned int flags)
Hook SAN device.
#define le32_to_cpu(value)
Definition: byteswap.h:113
int san_boot(unsigned int drive, const char *filename)
Attempt to boot from a SAN device.
struct san_device * sandev
SAN device.
Definition: efi_block.c:87
128 bit buffer containing a unique identifier value.
Definition: Base.h:263
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
Error codes.
#define HARDWARE_DEVICE_PATH
Hardware Device Paths.
Definition: DevicePath.h:77
static int efi_block_hook(unsigned int drive, struct uri **uris, unsigned int count, unsigned int flags)
Hook EFI block device.
Definition: efi_block.c:259
EFI strings.
EFI_IMAGE_LOAD LoadImage
Definition: UefiSpec.h:1883
unsigned char BOOLEAN
Definition: ProcessorBind.h:61
uint16_t block
Definition: tftp.h:12
Retry timers.
void unregister_sandev(struct san_device *sandev)
Unregister SAN device.
Definition: sanboot.c:925
#define DBGC(...)
Definition: compiler.h:505
This protocol provides control over block devices.
Definition: BlockIo.h:222
#define ENOENT
No such file or directory.
Definition: errno.h:514
unsigned int UINT32
Definition: ProcessorBind.h:56
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1915
unsigned long long uint64_t
Definition: stdint.h:13
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
unsigned short CHAR16
Definition: ProcessorBind.h:59
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
EFI_BLOCK_IO_PROTOCOL block_io
Block I/O protocol.
Definition: efi_block.c:93
iPXE timers
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
EFI_IMAGE_UNLOAD UnloadImage
Definition: UefiSpec.h:1886
An executable image.
Definition: image.h:24
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
CHAR16 PathName[1]
A NULL-terminated Path string including directory and file names.
Definition: DevicePath.h:1041
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:88
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:1037
Uniform Resource Identifiers.
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
EFI utilities.
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
A doubly-linked list entry (or list head)
Definition: list.h:18
Data transfer interfaces.
EFI_DEVICE_PATH_PROTOCOL * path
Device path protocol.
Definition: efi_block.c:95
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
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
EFI_ACPI_TABLE_UNINSTALL_ACPI_TABLE UninstallAcpiTable
Definition: AcpiTable.h:123
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
An object interface.
Definition: interface.h:109
SimpleFileSystem protocol as defined in the UEFI 2.0 specification.
EFI_GUID efi_simple_file_system_protocol_guid
Simple file system protocol GUID.
Definition: efi_guid.c:232
UINT64 EFI_LBA
Logical block address.
Definition: UefiBaseType.h:51
#define DBGC_HDA(...)
Definition: compiler.h:506
Object interfaces.
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
Definition: list.h:93
#define HW_VENDOR_DP
Hardware Vendor Device Path SubType.
Definition: DevicePath.h:142
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
Definition: efi_block.c:61
The Vendor Device Path allows the creation of vendor-defined Device Paths.
Definition: DevicePath.h:149
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
static int efi_block_install(struct acpi_header *hdr)
Install ACPI table.
Definition: efi_block.c:427
static void efi_block_unhook(unsigned int drive)
Unhook EFI block device.
Definition: efi_block.c:384
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
void acpi_fix_checksum(struct acpi_header *acpi)
Fix up ACPI table checksum.
Definition: acpi.c:76
#define SIZE_OF_FILEPATH_DEVICE_PATH
Definition: DevicePath.h:1044
EFI_REQUEST_PROTOCOL(EFI_ACPI_TABLE_PROTOCOL, &acpi)
uint64_t blocks
Total number of blocks.
Definition: blockdev.h:20
ISO9660 CD-ROM specification.
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
#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
Linked lists.
int acpi_install(int(*install)(struct acpi_header *acpi))
Install ACPI tables.
Definition: acpi.c:357
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
Block devices.
char * strerror(int errno)
Retrieve string representation of error number.
Definition: strerror.c:78
ACPI data structures.
static void(* free)(struct refcnt *refcnt))
Definition: refcnt.h:54
#define EFIAPI
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
uint8_t * tmp
Definition: entropy.h:156
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 LIST_HEAD(efi_acpi_tables)
List of installed ACPI tables.
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1916
EFI_CONNECT_CONTROLLER ConnectController
Definition: UefiSpec.h:1899
An SNP device.
Definition: efi_snp.h:27
#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
size_t strlen(const char *src)
Get length of string.
Definition: string.c:213
A SAN device.
Definition: sanboot.h:47
An iPXE EFI block device vendor device path.
Definition: efi_block.c:77
Processes.
static wchar_t efi_block_boot_filename[]
Boot filename.
Definition: efi_block.c:65
Data transfer interface opening.
EFI_IMAGE_START StartImage
Definition: UefiSpec.h:1884
#define MEDIA_DEVICE_PATH
Definition: DevicePath.h:946
UINT64 UINTN
Unsigned value of native width.
Definition: ProcessorBind.h:71
An ACPI description header.
Definition: acpi.h:28
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:132
#define VOID
Undeclared type.
Definition: Base.h:319
EFI_FREE_POOL FreePool
Definition: UefiSpec.h:1855
EFI_HANDLE handle
EFI handle.
Definition: efi_block.c:89
EFI API.
uint32_t hdr
Message header.
Definition: intelvf.h:12
Block IO read only mode data and updated only via members of BlockIO.
Definition: BlockIo.h:136
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
struct block_device_capacity capacity
Raw block device capacity.
Definition: sanboot.h:66
struct list_head list
List of installed tables.
Definition: efi_block.c:413
void san_unhook(unsigned int drive)
Unhook SAN device.
#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
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
union bootph_vendor vendor
UINT8 Length[2]
Specific Device Path data.
Definition: DevicePath.h:64
uint32_t len
Length.
Definition: ena.h:14
struct san_device * sandev_find(unsigned int drive)
Find SAN device by drive number.
Definition: sanboot.c:100
#define DBGC2(...)
Definition: compiler.h:522
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
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
uint16_t count
Number of entries.
Definition: ena.h:22
static const char * acpi_name(uint32_t signature)
Transcribe ACPI table signature (for debugging)
Definition: acpi.h:55
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
#define DBGC2_EFI_PROTOCOLS(...)
Definition: efi.h:267
Block IO protocol as defined in the UEFI 2.0 specification.
Reference counting.
EFI_BLOCK_IO_MEDIA media
Media descriptor.
Definition: efi_block.c:91
uint32_t end
Ending offset.
Definition: netvsc.h:18
static char media[]
Definition: sundance.c:85
#define FALSE
Definition: tlan.h:45
UINT8 Type
0x01 Hardware Device Path.
Definition: DevicePath.h:52
#define IPXE_BLOCK_DEVICE_PATH_GUID
iPXE EFI block device vendor device path GUID
Definition: efi_block.c:68
Retrieve the set of handles from the handle database that support a specified protocol.
Definition: UefiSpec.h:1448
A Uniform Resource Identifier.
Definition: uri.h:50
EFI_SYSTEM_TABLE * efi_systab
EFI_OPEN_PROTOCOL OpenProtocol
Definition: UefiSpec.h:1905
iPXE EFI SNP interface
The file provides the protocol to install or remove an ACPI table from a platform.
struct arbelprm_port_state_change_st data
Message.
Definition: arbel.h:12
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
iPXE sanboot API
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
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
int sandev_write(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Write to SAN device.
Definition: sanboot.c:656
String functions.
PROVIDE_SANBOOT(efi, san_hook, efi_block_hook)
An installed ACPI table.
Definition: efi_block.c:411
static EFI_GUID ipxe_block_device_path_guid
iPXE EFI block device vendor device path GUID
Definition: efi_block.c:74
union @375 key
Sense key.
Definition: scsi.h:18
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:149
Definition: efi.h:55
FILE_LICENCE(GPL2_OR_LATER_OR_UBDL)
struct san_device * alloc_sandev(struct uri **uris, unsigned int count, size_t priv_size)
Allocate SAN device.
Definition: sanboot.c:825
EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer
Definition: UefiSpec.h:1913
EFI_DEVICE_PATH_PROTOCOL * efi_devpath_end(EFI_DEVICE_PATH_PROTOCOL *path)
Find end of device path.
Definition: efi_utils.c:41
size_t blksize
Block size.
Definition: blockdev.h:22
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33
#define MEDIA_FILEPATH_DP
File Path Media Device Path SubType.
Definition: DevicePath.h:1035
uint8_t flags
Flags.
Definition: ena.h:18