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_path.h>
58 #include <ipxe/efi/efi_null.h>
59 #include <ipxe/efi/efi_block.h>
60 
61 /** ACPI table protocol protocol */
64 
65 /** Boot filename */
66 static wchar_t efi_block_boot_filename[] = EFI_REMOVABLE_MEDIA_FILE_NAME;
67 
68 /** EFI SAN device private data */
70  /** SAN device */
71  struct san_device *sandev;
72  /** EFI handle */
74  /** Media descriptor */
76  /** Block I/O protocol */
78  /** Device path protocol */
80 };
81 
82 /**
83  * Read from or write to EFI block device
84  *
85  * @v sandev SAN device
86  * @v lba Starting LBA
87  * @v data Data buffer
88  * @v len Size of buffer
89  * @v sandev_rw SAN device read/write method
90  * @ret rc Return status code
91  */
92 static int efi_block_rw ( struct san_device *sandev, uint64_t lba,
93  void *data, size_t len,
94  int ( * sandev_rw ) ( struct san_device *sandev,
95  uint64_t lba, unsigned int count,
96  userptr_t buffer ) ) {
97  struct efi_block_data *block = sandev->priv;
98  unsigned int count;
99  int rc;
100 
101  /* Sanity check */
102  count = ( len / block->media.BlockSize );
103  if ( ( count * block->media.BlockSize ) != len ) {
104  DBGC ( sandev, "EFIBLK %#02x impossible length %#zx\n",
105  sandev->drive, len );
106  return -EINVAL;
107  }
108 
109  /* Read from / write to block device */
110  if ( ( rc = sandev_rw ( sandev, lba, count,
111  virt_to_user ( data ) ) ) != 0 ) {
112  DBGC ( sandev, "EFIBLK %#02x I/O failed: %s\n",
113  sandev->drive, strerror ( rc ) );
114  return rc;
115  }
116 
117  return 0;
118 }
119 
120 /**
121  * Reset EFI block device
122  *
123  * @v block_io Block I/O protocol
124  * @v verify Perform extended verification
125  * @ret efirc EFI status code
126  */
128  BOOLEAN verify __unused ) {
129  struct efi_block_data *block =
131  struct san_device *sandev = block->sandev;
132  int rc;
133 
134  DBGC2 ( sandev, "EFIBLK %#02x reset\n", sandev->drive );
135  efi_snp_claim();
136  rc = sandev_reset ( sandev );
137  efi_snp_release();
138  return EFIRC ( rc );
139 }
140 
141 /**
142  * Read from EFI block device
143  *
144  * @v block_io Block I/O protocol
145  * @v media Media identifier
146  * @v lba Starting LBA
147  * @v len Size of buffer
148  * @v data Data buffer
149  * @ret efirc EFI status code
150  */
151 static EFI_STATUS EFIAPI
153  EFI_LBA lba, UINTN len, VOID *data ) {
154  struct efi_block_data *block =
156  struct san_device *sandev = block->sandev;
157  int rc;
158 
159  DBGC2 ( sandev, "EFIBLK %#02x read LBA %#08llx to %p+%#08zx\n",
160  sandev->drive, lba, data, ( ( size_t ) len ) );
161  efi_snp_claim();
162  rc = efi_block_rw ( sandev, lba, data, len, sandev_read );
163  efi_snp_release();
164  return EFIRC ( rc );
165 }
166 
167 /**
168  * Write to EFI block device
169  *
170  * @v block_io Block I/O protocol
171  * @v media Media identifier
172  * @v lba Starting LBA
173  * @v len Size of buffer
174  * @v data Data buffer
175  * @ret efirc EFI status code
176  */
177 static EFI_STATUS EFIAPI
179  EFI_LBA lba, UINTN len, VOID *data ) {
180  struct efi_block_data *block =
182  struct san_device *sandev = block->sandev;
183  int rc;
184 
185  DBGC2 ( sandev, "EFIBLK %#02x write LBA %#08llx from %p+%#08zx\n",
186  sandev->drive, lba, data, ( ( size_t ) len ) );
187  efi_snp_claim();
188  rc = efi_block_rw ( sandev, lba, data, len, sandev_write );
189  efi_snp_release();
190  return EFIRC ( rc );
191 }
192 
193 /**
194  * Flush data to EFI block device
195  *
196  * @v block_io Block I/O protocol
197  * @ret efirc EFI status code
198  */
199 static EFI_STATUS EFIAPI
201  struct efi_block_data *block =
203  struct san_device *sandev = block->sandev;
204 
205  DBGC2 ( sandev, "EFIBLK %#02x flush\n", sandev->drive );
206 
207  /* Nothing to do */
208  return 0;
209 }
210 
211 /**
212  * Connect all possible drivers to EFI block device
213  *
214  * @v sandev SAN device
215  */
216 static void efi_block_connect ( struct san_device *sandev ) {
218  struct efi_block_data *block = sandev->priv;
219  EFI_STATUS efirc;
220  int rc;
221 
222  /* Try to connect all possible drivers to this block device */
223  if ( ( efirc = bs->ConnectController ( block->handle, NULL,
224  NULL, TRUE ) ) != 0 ) {
225  rc = -EEFI ( efirc );
226  DBGC ( sandev, "EFIBLK %#02x could not connect drivers: %s\n",
227  sandev->drive, strerror ( rc ) );
228  /* May not be an error; may already be connected */
229  }
230  DBGC2 ( sandev, "EFIBLK %#02x supports protocols:\n", sandev->drive );
231  DBGC2_EFI_PROTOCOLS ( sandev, block->handle );
232 }
233 
234 /**
235  * Hook EFI block device
236  *
237  * @v drive Drive number
238  * @v uris List of URIs
239  * @v count Number of URIs
240  * @v flags Flags
241  * @ret drive Drive number, or negative error
242  */
243 static int efi_block_hook ( unsigned int drive, struct uri **uris,
244  unsigned int count, unsigned int flags ) {
246  struct san_device *sandev;
247  struct efi_block_data *block;
248  int leak = 0;
249  EFI_STATUS efirc;
250  int rc;
251 
252  /* Sanity check */
253  if ( ! count ) {
254  DBG ( "EFIBLK has no URIs\n" );
255  rc = -ENOTTY;
256  goto err_no_uris;
257  }
258 
259  /* Allocate and initialise structure */
260  sandev = alloc_sandev ( uris, count, sizeof ( *block ) );
261  if ( ! sandev ) {
262  rc = -ENOMEM;
263  goto err_alloc;
264  }
265  block = sandev->priv;
266  block->sandev = sandev;
267  block->media.MediaPresent = 1;
268  block->media.LogicalBlocksPerPhysicalBlock = 1;
269  block->block_io.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
270  block->block_io.Media = &block->media;
271  block->block_io.Reset = efi_block_io_reset;
272  block->block_io.ReadBlocks = efi_block_io_read;
273  block->block_io.WriteBlocks = efi_block_io_write;
274  block->block_io.FlushBlocks = efi_block_io_flush;
275 
276  /* Register SAN device */
277  if ( ( rc = register_sandev ( sandev, drive, flags ) ) != 0 ) {
278  DBGC ( sandev, "EFIBLK %#02x could not register: %s\n",
279  drive, strerror ( rc ) );
280  goto err_register;
281  }
282 
283  /* Update media descriptor */
284  block->media.BlockSize =
286  block->media.LastBlock =
287  ( ( sandev->capacity.blocks >> sandev->blksize_shift ) - 1 );
288 
289  /* Construct device path */
290  if ( ! sandev->active ) {
291  rc = -ENODEV;
292  DBGC ( sandev, "EFIBLK %#02x not active after registration\n",
293  drive );
294  goto err_active;
295  }
296  block->path = efi_describe ( &sandev->active->block );
297  if ( ! block->path ) {
298  rc = -ENODEV;
299  DBGC ( sandev, "EFIBLK %#02x has no device path\n", drive );
300  goto err_describe;
301  }
302  DBGC ( sandev, "EFIBLK %#02x has device path %s\n",
303  drive, efi_devpath_text ( block->path ) );
304 
305  /* Install protocols */
306  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
307  &block->handle,
308  &efi_block_io_protocol_guid, &block->block_io,
310  NULL ) ) != 0 ) {
311  rc = -EEFI ( efirc );
312  DBGC ( sandev, "EFIBLK %#02x could not install protocols: %s\n",
313  sandev->drive, strerror ( rc ) );
314  goto err_install;
315  }
316 
317  /* Connect all possible protocols */
319 
320  return drive;
321 
322  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
323  block->handle,
324  &efi_block_io_protocol_guid, &block->block_io,
326  NULL ) ) != 0 ) {
327  DBGC ( sandev, "EFIBLK %#02x could not uninstall protocols: "
328  "%s\n", sandev->drive, strerror ( -EEFI ( efirc ) ) );
329  leak = 1;
330  }
331  efi_nullify_block ( &block->block_io );
332  err_install:
333  if ( ! leak ) {
334  free ( block->path );
335  block->path = NULL;
336  }
337  err_describe:
338  err_active:
340  err_register:
341  if ( ! leak )
342  sandev_put ( sandev );
343  err_alloc:
344  err_no_uris:
345  if ( leak ) {
346  DBGC ( sandev, "EFIBLK %#02x nullified and leaked\n",
347  sandev->drive );
348  }
349  return rc;
350 }
351 
352 /**
353  * Unhook EFI block device
354  *
355  * @v drive Drive number
356  */
357 static void efi_block_unhook ( unsigned int drive ) {
359  struct san_device *sandev;
360  struct efi_block_data *block;
361  int leak = efi_shutdown_in_progress;
362  EFI_STATUS efirc;
363 
364  /* Find SAN device */
365  sandev = sandev_find ( drive );
366  if ( ! sandev ) {
367  DBG ( "EFIBLK cannot find drive %#02x\n", drive );
368  return;
369  }
370  block = sandev->priv;
371 
372  /* Uninstall protocols */
373  if ( ( ! efi_shutdown_in_progress ) &&
374  ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
375  block->handle,
376  &efi_block_io_protocol_guid, &block->block_io,
378  NULL ) ) != 0 ) ) {
379  DBGC ( sandev, "EFIBLK %#02x could not uninstall protocols: "
380  "%s\n", sandev->drive, strerror ( -EEFI ( efirc ) ) );
381  leak = 1;
382  }
383  efi_nullify_block ( &block->block_io );
384 
385  /* Free device path */
386  if ( ! leak ) {
387  free ( block->path );
388  block->path = NULL;
389  }
390 
391  /* Unregister SAN device */
393 
394  /* Drop reference to drive */
395  if ( ! leak )
396  sandev_put ( sandev );
397 
398  /* Report leakage, if applicable */
399  if ( leak && ( ! efi_shutdown_in_progress ) ) {
400  DBGC ( sandev, "EFIBLK %#02x nullified and leaked\n",
401  sandev->drive );
402  }
403 }
404 
405 /** An installed ACPI table */
407  /** List of installed tables */
408  struct list_head list;
409  /** Table key */
411 };
412 
413 /** List of installed ACPI tables */
414 static LIST_HEAD ( efi_acpi_tables );
415 
416 /**
417  * Install ACPI table
418  *
419  * @v hdr ACPI description header
420  * @ret rc Return status code
421  */
422 static int efi_block_install ( struct acpi_header *hdr ) {
423  size_t len = le32_to_cpu ( hdr->length );
424  struct efi_acpi_table *installed;
425  EFI_STATUS efirc;
426  int rc;
427 
428  /* Allocate installed table record */
429  installed = zalloc ( sizeof ( *installed ) );
430  if ( ! installed ) {
431  rc = -ENOMEM;
432  goto err_alloc;
433  }
434 
435  /* Fill in common parameters */
436  strncpy ( hdr->oem_id, "FENSYS", sizeof ( hdr->oem_id ) );
437  strncpy ( hdr->oem_table_id, "iPXE", sizeof ( hdr->oem_table_id ) );
438 
439  /* Fix up ACPI checksum */
441 
442  /* Install table */
443  if ( ( efirc = acpi->InstallAcpiTable ( acpi, hdr, len,
444  &installed->key ) ) != 0 ){
445  rc = -EEFI ( efirc );
446  DBGC ( acpi, "EFIBLK could not install %s: %s\n",
447  acpi_name ( hdr->signature ), strerror ( rc ) );
448  DBGC2_HDA ( acpi, 0, hdr, len );
449  goto err_install;
450  }
451 
452  /* Add to list of installed tables */
453  list_add_tail ( &installed->list, &efi_acpi_tables );
454 
455  DBGC ( acpi, "EFIBLK installed %s as ACPI table %#lx\n",
456  acpi_name ( hdr->signature ),
457  ( ( unsigned long ) installed->key ) );
458  DBGC2_HDA ( acpi, 0, hdr, len );
459  return 0;
460 
461  list_del ( &installed->list );
462  err_install:
463  free ( installed );
464  err_alloc:
465  return rc;
466 }
467 
468 /**
469  * Describe EFI block devices
470  *
471  * @ret rc Return status code
472  */
473 static int efi_block_describe ( void ) {
474  struct efi_acpi_table *installed;
475  struct efi_acpi_table *tmp;
476  UINTN key;
477  EFI_STATUS efirc;
478  int rc;
479 
480  /* Sanity check */
481  if ( ! acpi ) {
482  DBG ( "EFIBLK has no ACPI table protocol\n" );
483  return -ENOTSUP;
484  }
485 
486  /* Uninstall any existing ACPI tables */
487  list_for_each_entry_safe ( installed, tmp, &efi_acpi_tables, list ) {
488  key = installed->key;
489  if ( ( efirc = acpi->UninstallAcpiTable ( acpi, key ) ) != 0 ) {
490  rc = -EEFI ( efirc );
491  DBGC ( acpi, "EFIBLK could not uninstall ACPI table "
492  "%#lx: %s\n", ( ( unsigned long ) key ),
493  strerror ( rc ) );
494  /* Continue anyway */
495  }
496  list_del ( &installed->list );
497  free ( installed );
498  }
499 
500  /* Install ACPI tables */
501  if ( ( rc = acpi_install ( efi_block_install ) ) != 0 ) {
502  DBGC ( acpi, "EFIBLK could not install ACPI tables: %s\n",
503  strerror ( rc ) );
504  return rc;
505  }
506 
507  return 0;
508 }
509 
510 /**
511  * Try booting from child device of EFI block device
512  *
513  * @v sandev SAN device
514  * @v handle EFI handle
515  * @v filename Filename (or NULL to use default)
516  * @v image Image handle to fill in
517  * @ret rc Return status code
518  */
519 static int efi_block_boot_image ( struct san_device *sandev, EFI_HANDLE handle,
520  const char *filename, EFI_HANDLE *image ) {
522  struct efi_block_data *block = sandev->priv;
523  union {
525  void *interface;
526  } path;
527  EFI_DEVICE_PATH_PROTOCOL *boot_path;
528  FILEPATH_DEVICE_PATH *filepath;
530  size_t prefix_len;
531  size_t filepath_len;
532  size_t boot_path_len;
533  EFI_STATUS efirc;
534  int rc;
535 
536  /* Identify device path */
537  if ( ( efirc = bs->OpenProtocol ( handle,
539  &path.interface, efi_image_handle,
540  handle,
542  DBGC ( sandev, "EFIBLK %#02x found filesystem with no device "
543  "path??", sandev->drive );
544  rc = -EEFI ( efirc );
545  goto err_open_device_path;
546  }
547 
548  /* Check if this device is a child of our block device */
549  prefix_len = efi_path_len ( block->path );
550  if ( memcmp ( path.path, block->path, prefix_len ) != 0 ) {
551  /* Not a child device */
552  rc = -ENOTTY;
553  goto err_not_child;
554  }
555  DBGC ( sandev, "EFIBLK %#02x found child device %s\n",
556  sandev->drive, efi_devpath_text ( path.path ) );
557 
558  /* Construct device path for boot image */
559  end = efi_path_end ( path.path );
560  prefix_len = ( ( ( void * ) end ) - ( ( void * ) path.path ) );
561  filepath_len = ( SIZE_OF_FILEPATH_DEVICE_PATH +
562  ( filename ?
563  ( ( strlen ( filename ) + 1 /* NUL */ ) *
564  sizeof ( filepath->PathName[0] ) ) :
565  sizeof ( efi_block_boot_filename ) ) );
566  boot_path_len = ( prefix_len + filepath_len + sizeof ( *end ) );
567  boot_path = zalloc ( boot_path_len );
568  if ( ! boot_path ) {
569  rc = -ENOMEM;
570  goto err_alloc_path;
571  }
572  memcpy ( boot_path, path.path, prefix_len );
573  filepath = ( ( ( void * ) boot_path ) + prefix_len );
574  filepath->Header.Type = MEDIA_DEVICE_PATH;
575  filepath->Header.SubType = MEDIA_FILEPATH_DP;
576  filepath->Header.Length[0] = ( filepath_len & 0xff );
577  filepath->Header.Length[1] = ( filepath_len >> 8 );
578  if ( filename ) {
579  efi_sprintf ( filepath->PathName, "%s", filename );
580  } else {
582  sizeof ( efi_block_boot_filename ) );
583  }
584  end = ( ( ( void * ) filepath ) + filepath_len );
586  DBGC ( sandev, "EFIBLK %#02x trying to load %s\n",
587  sandev->drive, efi_devpath_text ( boot_path ) );
588 
589  /* Try loading boot image from this device */
590  *image = NULL;
591  if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, boot_path,
592  NULL, 0, image ) ) != 0 ) {
593  rc = -EEFI ( efirc );
594  DBGC ( sandev, "EFIBLK %#02x could not load image: %s\n",
595  sandev->drive, strerror ( rc ) );
596  if ( efirc == EFI_SECURITY_VIOLATION )
597  bs->UnloadImage ( *image );
598  goto err_load_image;
599  }
600 
601  /* Success */
602  rc = 0;
603 
604  err_load_image:
605  free ( boot_path );
606  err_alloc_path:
607  err_not_child:
608  err_open_device_path:
609  return rc;
610 }
611 
612 /**
613  * Boot from EFI block device
614  *
615  * @v drive Drive number
616  * @v filename Filename (or NULL to use default)
617  * @ret rc Return status code
618  */
619 static int efi_block_boot ( unsigned int drive, const char *filename ) {
621  struct san_device *sandev;
622  EFI_HANDLE *handles;
624  UINTN count;
625  unsigned int i;
626  EFI_STATUS efirc;
627  int rc;
628 
629  /* Find SAN device */
630  sandev = sandev_find ( drive );
631  if ( ! sandev ) {
632  DBG ( "EFIBLK cannot find drive %#02x\n", drive );
633  rc = -ENODEV;
634  goto err_sandev_find;
635  }
636 
637  /* Release SNP devices */
638  efi_snp_release();
639 
640  /* Connect all possible protocols */
641  efi_block_connect ( sandev );
642 
643  /* Locate all handles supporting the Simple File System protocol */
644  if ( ( efirc = bs->LocateHandleBuffer (
646  NULL, &count, &handles ) ) != 0 ) {
647  rc = -EEFI ( efirc );
648  DBGC ( sandev, "EFIBLK %#02x cannot locate file systems: %s\n",
649  sandev->drive, strerror ( rc ) );
650  goto err_locate_file_systems;
651  }
652 
653  /* Try booting from any available child device containing a
654  * suitable boot image. This is something of a wild stab in
655  * the dark, but should end up conforming to user expectations
656  * most of the time.
657  */
658  rc = -ENOENT;
659  for ( i = 0 ; i < count ; i++ ) {
660  if ( ( rc = efi_block_boot_image ( sandev, handles[i], filename,
661  &image ) ) != 0 )
662  continue;
663  DBGC ( sandev, "EFIBLK %#02x found boot image\n",
664  sandev->drive );
665  efirc = bs->StartImage ( image, NULL, NULL );
666  rc = ( efirc ? -EEFI ( efirc ) : 0 );
667  bs->UnloadImage ( image );
668  DBGC ( sandev, "EFIBLK %#02x boot image returned: %s\n",
669  sandev->drive, strerror ( rc ) );
670  break;
671  }
672 
673  bs->FreePool ( handles );
674  err_locate_file_systems:
675  efi_snp_claim();
676  err_sandev_find:
677  return rc;
678 }
679 
static int efi_block_describe(void)
Describe EFI block devices.
Definition: efi_block.c:473
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2030
#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:116
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:171
EFI_ACPI_TABLE_INSTALL_ACPI_TABLE InstallAcpiTable
Definition: AcpiTable.h:117
static int efi_block_boot(unsigned int drive, const char *filename)
Boot from EFI block device.
Definition: efi_block.c:619
EFI driver interface.
UINTN key
Table key.
Definition: efi_block.c:410
int san_describe(void)
Describe SAN devices for SAN-booted operating system.
uint32_t lba
Start address.
Definition: scsi.h:23
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:71
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.
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
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:243
EFI strings.
EFI_IMAGE_LOAD LoadImage
Definition: UefiSpec.h:1913
unsigned char BOOLEAN
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:216
struct interface block
Underlying block device interface.
Definition: sanboot.h:36
#define ENOENT
No such file or directory.
Definition: errno.h:514
unsigned int UINT32
Definition: ProcessorBind.h:98
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
Definition: UefiSpec.h:1945
unsigned long long uint64_t
Definition: stdint.h:13
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition: efi_path.c:106
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:178
EFI_BLOCK_IO_PROTOCOL block_io
Block I/O protocol.
Definition: efi_block.c:77
iPXE timers
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
EFI_IMAGE_UNLOAD UnloadImage
Definition: UefiSpec.h:1916
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:45
CHAR16 PathName[1]
A NULL-terminated Path string including directory and file names.
Definition: DevicePath.h:1086
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
Definition: efi_snp.h:91
EFI_DEVICE_PATH_PROTOCOL Header
Definition: DevicePath.h:1082
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:92
EFI SAN device private data.
Definition: efi_block.c:69
#define ENOTSUP
Operation not supported.
Definition: errno.h:589
A doubly-linked list entry (or list head)
Definition: list.h:18
static void efi_path_terminate(EFI_DEVICE_PATH_PROTOCOL *end)
Terminate device path.
Definition: efi_path.h:29
Data transfer interfaces.
EFI_DEVICE_PATH_PROTOCOL * path
Device path protocol.
Definition: efi_block.c:79
unsigned long tmp
Definition: linux_pci.h:53
char * strncpy(char *dest, const char *src, size_t max)
Copy string.
Definition: string.c:347
#define list_del(list)
Delete an entry from a list.
Definition: list.h:119
#define ENOMEM
Not enough space.
Definition: errno.h:534
#define EFI_BLOCK_IO_PROTOCOL_REVISION3
Definition: BlockIo.h:206
void * memcpy(void *dest, const void *src, size_t len) __nonnull
EFI_ACPI_TABLE_UNINSTALL_ACPI_TABLE UninstallAcpiTable
Definition: AcpiTable.h:118
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
An object interface.
Definition: interface.h:124
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:303
UINT64 EFI_LBA
Logical block address.
Definition: UefiBaseType.h:47
Object interfaces.
#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:62
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:422
static void efi_block_unhook(unsigned int drive)
Unhook EFI block device.
Definition: efi_block.c:357
unsigned int blksize_shift
Block size shift.
Definition: sanboot.h:73
void acpi_fix_checksum(struct acpi_header *acpi)
Fix up ACPI table checksum.
Definition: acpi.c:85
#define SIZE_OF_FILEPATH_DEVICE_PATH
Definition: DevicePath.h:1089
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:461
#define EFI_OPEN_PROTOCOL_GET_PROTOCOL
Definition: UefiSpec.h:1299
#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
EFI null interfaces.
Linked lists.
#define DBGC2_HDA(...)
Definition: compiler.h:523
int acpi_install(int(*install)(struct acpi_header *acpi))
Install ACPI tables.
Definition: acpi.c:336
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:127
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:1866
#define efi_sprintf(buf, fmt,...)
Write a formatted string to a buffer.
Definition: efi_strings.h:45
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
Definition: efi_init.c:34
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:1946
EFI_CONNECT_CONTROLLER ConnectController
Definition: UefiSpec.h:1929
#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:99
size_t strlen(const char *src)
Get length of string.
Definition: string.c:243
A SAN device.
Definition: sanboot.h:47
Processes.
static wchar_t efi_block_boot_filename[]
Boot filename.
Definition: efi_block.c:66
Data transfer interface opening.
EFI device paths.
EFI_IMAGE_START StartImage
Definition: UefiSpec.h:1914
#define MEDIA_DEVICE_PATH
Definition: DevicePath.h:991
UINT64 UINTN
Unsigned value of native width.
An ACPI description header.
Definition: acpi.h:163
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:143
#define VOID
Undeclared type.
Definition: Base.h:271
EFI_FREE_POOL FreePool
Definition: UefiSpec.h:1885
#define TRUE
Definition: tlan.h:46
EFI_HANDLE handle
EFI handle.
Definition: efi_block.c:73
EFI API.
#define EFI_SECURITY_VIOLATION
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:140
Block IO read only mode data and updated only via members of BlockIO.
Definition: BlockIo.h:130
#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:408
void san_unhook(unsigned int drive)
Unhook SAN device.
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:152
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition: efi_path.c:537
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:519
UINT8 Length[2]
Specific Device Path data.
Definition: DevicePath.h:58
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:119
#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:200
void efi_nullify_block(EFI_BLOCK_IO_PROTOCOL *block)
Nullify block I/O protocol.
Definition: efi_null.c:396
void * priv
Driver private data.
Definition: sanboot.h:78
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
Definition: UefiBaseType.h:31
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:53
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:190
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
#define DBGC2_EFI_PROTOCOLS(...)
Definition: efi.h:334
Block IO protocol as defined in the UEFI 2.0 specification.
Reference counting.
EFI_BLOCK_IO_MEDIA media
Media descriptor.
Definition: efi_block.c:75
uint32_t end
Ending offset.
Definition: netvsc.h:18
static char media[]
Definition: sundance.c:85
uint8_t data[48]
Additional event data.
Definition: ena.h:22
#define FALSE
Definition: tlan.h:45
UINT8 Type
0x01 Hardware Device Path.
Definition: DevicePath.h:46
Retrieve the set of handles from the handle database that support a specified protocol.
Definition: UefiSpec.h:1475
A Uniform Resource Identifier.
Definition: uri.h:64
EFI_SYSTEM_TABLE * efi_systab
EFI_OPEN_PROTOCOL OpenProtocol
Definition: UefiSpec.h:1935
iPXE EFI SNP interface
struct san_path * active
Current active path.
Definition: sanboot.h:83
The file provides the protocol to install or remove an ACPI table from a platform.
#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:216
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:114
#define NULL
NULL pointer (VOID *)
Definition: Base.h:321
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.
EFI_DEVICE_PATH_PROTOCOL * efi_path_end(EFI_DEVICE_PATH_PROTOCOL *path)
Find end of device path.
Definition: efi_path.c:95
PROVIDE_SANBOOT(efi, san_hook, efi_block_hook)
An installed ACPI table.
Definition: efi_block.c:406
union @382 key
Sense key.
Definition: scsi.h:18
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:163
Definition: efi.h:59
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:1943
size_t blksize
Block size.
Definition: blockdev.h:22
unsigned long userptr_t
A pointer to a user buffer.
Definition: uaccess.h:33
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition: efi_init.c:58
#define MEDIA_FILEPATH_DP
File Path Media Device Path SubType.
Definition: DevicePath.h:1080
uint8_t flags
Flags.
Definition: ena.h:18