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 <stdio.h>
36 #include <string.h>
37 #include <strings.h>
38 #include <errno.h>
39 #include <ipxe/refcnt.h>
40 #include <ipxe/list.h>
41 #include <ipxe/uri.h>
42 #include <ipxe/interface.h>
43 #include <ipxe/blockdev.h>
44 #include <ipxe/xfer.h>
45 #include <ipxe/open.h>
46 #include <ipxe/retry.h>
47 #include <ipxe/timer.h>
48 #include <ipxe/process.h>
49 #include <ipxe/sanboot.h>
50 #include <ipxe/iso9660.h>
51 #include <ipxe/acpi.h>
52 #include <ipxe/efi/efi.h>
57 #include <ipxe/efi/efi_driver.h>
58 #include <ipxe/efi/efi_strings.h>
59 #include <ipxe/efi/efi_snp.h>
60 #include <ipxe/efi/efi_path.h>
61 #include <ipxe/efi/efi_null.h>
62 #include <ipxe/efi/efi_block.h>
63 
64 /** ACPI table protocol protocol */
67 
68 /** Boot filename */
69 static wchar_t efi_block_boot_filename[] = EFI_REMOVABLE_MEDIA_FILE_NAME;
70 
71 /** EFI SAN device private data */
73  /** SAN device */
74  struct san_device *sandev;
75  /** EFI handle */
77  /** Media descriptor */
79  /** Block I/O protocol */
81  /** Device path protocol */
83 };
84 
85 /**
86  * Read from or write to EFI block device
87  *
88  * @v sandev SAN device
89  * @v lba Starting LBA
90  * @v data Data buffer
91  * @v len Size of buffer
92  * @v sandev_rw SAN device read/write method
93  * @ret rc Return status code
94  */
95 static int efi_block_rw ( struct san_device *sandev, uint64_t lba,
96  void *data, size_t len,
97  int ( * sandev_rw ) ( struct san_device *sandev,
98  uint64_t lba,
99  unsigned int count,
100  void *buffer ) ) {
101  struct efi_block_data *block = sandev->priv;
102  unsigned int count;
103  int rc;
104 
105  /* Sanity check */
106  count = ( len / block->media.BlockSize );
107  if ( ( count * block->media.BlockSize ) != len ) {
108  DBGC ( sandev->drive, "EFIBLK %#02x impossible length %#zx\n",
109  sandev->drive, len );
110  return -EINVAL;
111  }
112 
113  /* Read from / write to block device */
114  if ( ( rc = sandev_rw ( sandev, lba, count, data ) ) != 0 ) {
115  DBGC ( sandev->drive, "EFIBLK %#02x I/O failed: %s\n",
116  sandev->drive, strerror ( rc ) );
117  return rc;
118  }
119 
120  return 0;
121 }
122 
123 /**
124  * Reset EFI block device
125  *
126  * @v block_io Block I/O protocol
127  * @v verify Perform extended verification
128  * @ret efirc EFI status code
129  */
131  BOOLEAN verify __unused ) {
132  struct efi_block_data *block =
134  struct san_device *sandev = block->sandev;
135  int rc;
136 
137  DBGC2 ( sandev->drive, "EFIBLK %#02x reset\n", sandev->drive );
138  efi_snp_claim();
139  rc = sandev_reset ( sandev );
140  efi_snp_release();
141  return EFIRC ( rc );
142 }
143 
144 /**
145  * Read from EFI block device
146  *
147  * @v block_io Block I/O protocol
148  * @v media Media identifier
149  * @v lba Starting LBA
150  * @v len Size of buffer
151  * @v data Data buffer
152  * @ret efirc EFI status code
153  */
154 static EFI_STATUS EFIAPI
156  EFI_LBA lba, UINTN len, VOID *data ) {
157  struct efi_block_data *block =
159  struct san_device *sandev = block->sandev;
160  int rc;
161 
162  DBGC2 ( sandev->drive, "EFIBLK %#02x read LBA %#08llx to %p+%#08zx\n",
163  sandev->drive, lba, data, ( ( size_t ) len ) );
164  efi_snp_claim();
165  rc = efi_block_rw ( sandev, lba, data, len, sandev_read );
166  efi_snp_release();
167  return EFIRC ( rc );
168 }
169 
170 /**
171  * Write to EFI block device
172  *
173  * @v block_io Block I/O protocol
174  * @v media Media identifier
175  * @v lba Starting LBA
176  * @v len Size of buffer
177  * @v data Data buffer
178  * @ret efirc EFI status code
179  */
180 static EFI_STATUS EFIAPI
182  EFI_LBA lba, UINTN len, VOID *data ) {
183  struct efi_block_data *block =
185  struct san_device *sandev = block->sandev;
186  int rc;
187 
188  DBGC2 ( sandev->drive, "EFIBLK %#02x write LBA %#08llx from "
189  "%p+%#08zx\n", sandev->drive, lba, data, ( ( size_t ) len ) );
190  efi_snp_claim();
191  rc = efi_block_rw ( sandev, lba, data, len, sandev_write );
192  efi_snp_release();
193  return EFIRC ( rc );
194 }
195 
196 /**
197  * Flush data to EFI block device
198  *
199  * @v block_io Block I/O protocol
200  * @ret efirc EFI status code
201  */
202 static EFI_STATUS EFIAPI
204  struct efi_block_data *block =
206  struct san_device *sandev = block->sandev;
207 
208  DBGC2 ( sandev->drive, "EFIBLK %#02x flush\n", sandev->drive );
209 
210  /* Nothing to do */
211  return 0;
212 }
213 
214 /**
215  * Connect all possible drivers to EFI block device
216  *
217  * @v drive Drive number
218  * @v handle Block device handle
219  */
220 static void efi_block_connect ( unsigned int drive, EFI_HANDLE handle ) {
221  int rc;
222 
223  /* Try to connect all possible drivers to this block device */
224  if ( ( rc = efi_connect ( handle, NULL ) ) != 0 ) {
225  DBGC ( drive, "EFIBLK %#02x could not connect drivers: %s\n",
226  drive, strerror ( rc ) );
227  /* May not be an error; may already be connected */
228  }
229  DBGC2 ( drive, "EFIBLK %#02x supports protocols:\n", drive );
231 }
232 
233 /**
234  * Hook EFI block device
235  *
236  * @v drive Drive number
237  * @v uris List of URIs
238  * @v count Number of URIs
239  * @v flags Flags
240  * @ret drive Drive number, or negative error
241  */
242 static int efi_block_hook ( unsigned int drive, struct uri **uris,
243  unsigned int count, unsigned int flags ) {
245  struct san_device *sandev;
246  struct efi_block_data *block;
247  int leak = 0;
248  EFI_STATUS efirc;
249  int rc;
250 
251  /* Sanity check */
252  if ( ! count ) {
253  DBGC ( drive, "EFIBLK %#02x has no URIs\n", drive );
254  rc = -ENOTTY;
255  goto err_no_uris;
256  }
257 
258  /* Allocate and initialise structure */
259  sandev = alloc_sandev ( uris, count, sizeof ( *block ) );
260  if ( ! sandev ) {
261  rc = -ENOMEM;
262  goto err_alloc;
263  }
264  block = sandev->priv;
265  block->sandev = sandev;
266  block->media.MediaPresent = 1;
267  block->media.LogicalBlocksPerPhysicalBlock = 1;
268  block->block_io.Revision = EFI_BLOCK_IO_PROTOCOL_REVISION3;
269  block->block_io.Media = &block->media;
270  block->block_io.Reset = efi_block_io_reset;
271  block->block_io.ReadBlocks = efi_block_io_read;
272  block->block_io.WriteBlocks = efi_block_io_write;
273  block->block_io.FlushBlocks = efi_block_io_flush;
274 
275  /* Register SAN device */
276  if ( ( rc = register_sandev ( sandev, drive, flags ) ) != 0 ) {
277  DBGC ( drive, "EFIBLK %#02x could not register: %s\n",
278  drive, strerror ( rc ) );
279  goto err_register;
280  }
281 
282  /* Update media descriptor */
283  block->media.BlockSize =
285  block->media.LastBlock =
286  ( ( sandev->capacity.blocks >> sandev->blksize_shift ) - 1 );
287 
288  /* Construct device path */
289  if ( ! sandev->active ) {
290  rc = -ENODEV;
291  DBGC ( drive, "EFIBLK %#02x not active after registration\n",
292  drive );
293  goto err_active;
294  }
295  block->path = efi_describe ( &sandev->active->block );
296  if ( ! block->path ) {
297  rc = -ENODEV;
298  DBGC ( drive, "EFIBLK %#02x has no device path\n", drive );
299  goto err_describe;
300  }
301  DBGC2 ( drive, "EFIBLK %#02x has device path %s\n",
302  drive, efi_devpath_text ( block->path ) );
303 
304  /* Install protocols */
305  if ( ( efirc = bs->InstallMultipleProtocolInterfaces (
306  &block->handle,
307  &efi_block_io_protocol_guid, &block->block_io,
309  NULL ) ) != 0 ) {
310  rc = -EEFI ( efirc );
311  DBGC ( drive, "EFIBLK %#02x could not install protocols: %s\n",
312  drive, strerror ( rc ) );
313  goto err_install;
314  }
315  DBGC ( drive, "EFIBLK %#02x installed as SAN drive %s\n",
316  drive, efi_handle_name ( block->handle ) );
317 
318  /* Connect all possible protocols */
319  efi_block_connect ( drive, block->handle );
320 
321  return drive;
322 
323  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
324  block->handle,
325  &efi_block_io_protocol_guid, &block->block_io,
327  NULL ) ) != 0 ) {
328  DBGC ( drive, "EFIBLK %#02x could not uninstall protocols: "
329  "%s\n", drive, strerror ( -EEFI ( efirc ) ) );
330  leak = 1;
331  }
332  efi_nullify_block ( &block->block_io );
333  err_install:
334  if ( ! leak ) {
335  free ( block->path );
336  block->path = NULL;
337  }
338  err_describe:
339  err_active:
341  err_register:
342  if ( ! leak )
343  sandev_put ( sandev );
344  err_alloc:
345  err_no_uris:
346  if ( leak )
347  DBGC ( drive, "EFIBLK %#02x nullified and leaked\n", drive );
348  return rc;
349 }
350 
351 /**
352  * Unhook EFI block device
353  *
354  * @v drive Drive number
355  */
356 static void efi_block_unhook ( unsigned int drive ) {
358  struct san_device *sandev;
359  struct efi_block_data *block;
360  int leak = efi_shutdown_in_progress;
361  EFI_STATUS efirc;
362 
363  /* Find SAN device */
364  sandev = sandev_find ( drive );
365  if ( ! sandev ) {
366  DBGC ( drive, "EFIBLK %#02x is not a SAN drive\n", drive );
367  return;
368  }
369  block = sandev->priv;
370 
371  /* Uninstall protocols */
372  if ( ( ! efi_shutdown_in_progress ) &&
373  ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
374  block->handle,
375  &efi_block_io_protocol_guid, &block->block_io,
377  NULL ) ) != 0 ) ) {
378  DBGC ( drive, "EFIBLK %#02x could not uninstall protocols: "
379  "%s\n", drive, strerror ( -EEFI ( efirc ) ) );
380  leak = 1;
381  }
382  efi_nullify_block ( &block->block_io );
383 
384  /* Free device path */
385  if ( ! leak ) {
386  free ( block->path );
387  block->path = NULL;
388  }
389 
390  /* Unregister SAN device */
392 
393  /* Drop reference to drive */
394  if ( ! leak )
395  sandev_put ( sandev );
396 
397  /* Report leakage, if applicable */
398  if ( leak && ( ! efi_shutdown_in_progress ) )
399  DBGC ( drive, "EFIBLK %#02x nullified and leaked\n", drive );
400 }
401 
402 /** An installed ACPI table */
404  /** List of installed tables */
405  struct list_head list;
406  /** Table key */
408 };
409 
410 /** List of installed ACPI tables */
411 static LIST_HEAD ( efi_acpi_tables );
412 
413 /**
414  * Install ACPI table
415  *
416  * @v hdr ACPI description header
417  * @ret rc Return status code
418  */
419 static int efi_block_install ( struct acpi_header *hdr ) {
420  size_t len = le32_to_cpu ( hdr->length );
421  struct efi_acpi_table *installed;
422  EFI_STATUS efirc;
423  int rc;
424 
425  /* Allocate installed table record */
426  installed = zalloc ( sizeof ( *installed ) );
427  if ( ! installed ) {
428  rc = -ENOMEM;
429  goto err_alloc;
430  }
431 
432  /* Fill in common parameters */
433  strncpy ( hdr->oem_id, "FENSYS", sizeof ( hdr->oem_id ) );
434  strncpy ( hdr->oem_table_id, "iPXE", sizeof ( hdr->oem_table_id ) );
435 
436  /* Fix up ACPI checksum */
438 
439  /* Install table */
440  if ( ( efirc = acpi->InstallAcpiTable ( acpi, hdr, len,
441  &installed->key ) ) != 0 ){
442  rc = -EEFI ( efirc );
443  DBGC ( acpi, "EFIBLK could not install %s: %s\n",
444  acpi_name ( hdr->signature ), strerror ( rc ) );
445  DBGC2_HDA ( acpi, 0, hdr, len );
446  goto err_install;
447  }
448 
449  /* Add to list of installed tables */
450  list_add_tail ( &installed->list, &efi_acpi_tables );
451 
452  DBGC ( acpi, "EFIBLK installed %s as ACPI table %#lx\n",
453  acpi_name ( hdr->signature ),
454  ( ( unsigned long ) installed->key ) );
455  DBGC2_HDA ( acpi, 0, hdr, len );
456  return 0;
457 
458  list_del ( &installed->list );
459  err_install:
460  free ( installed );
461  err_alloc:
462  return rc;
463 }
464 
465 /**
466  * Describe EFI block devices
467  *
468  * @ret rc Return status code
469  */
470 static int efi_block_describe ( void ) {
471  struct efi_acpi_table *installed;
472  struct efi_acpi_table *tmp;
473  UINTN key;
474  EFI_STATUS efirc;
475  int rc;
476 
477  /* Sanity check */
478  if ( ! acpi ) {
479  DBG ( "EFIBLK has no ACPI table protocol\n" );
480  return -ENOTSUP;
481  }
482 
483  /* Uninstall any existing ACPI tables */
484  list_for_each_entry_safe ( installed, tmp, &efi_acpi_tables, list ) {
485  key = installed->key;
486  if ( ( efirc = acpi->UninstallAcpiTable ( acpi, key ) ) != 0 ) {
487  rc = -EEFI ( efirc );
488  DBGC ( acpi, "EFIBLK could not uninstall ACPI table "
489  "%#lx: %s\n", ( ( unsigned long ) key ),
490  strerror ( rc ) );
491  /* Continue anyway */
492  }
493  list_del ( &installed->list );
494  free ( installed );
495  }
496 
497  /* Install ACPI tables */
498  if ( ( rc = acpi_install ( efi_block_install ) ) != 0 ) {
499  DBGC ( acpi, "EFIBLK could not install ACPI tables: %s\n",
500  strerror ( rc ) );
501  return rc;
502  }
503 
504  return 0;
505 }
506 
507 /**
508  * Open root directory within a filesystem
509  *
510  * @v drive Drive number
511  * @v handle Filesystem handle
512  * @v root Root directory file to fill in
513  * @ret rc Return status code
514  */
515 static int efi_block_root ( unsigned int drive, EFI_HANDLE handle,
516  EFI_FILE_PROTOCOL **root ) {
518  EFI_STATUS efirc;
519  int rc;
520 
521  /* Open filesystem protocol */
523  &fs ) ) != 0 ) {
524  DBGC ( drive, "EFIBLK %#02x could not open %s filesystem: %s\n",
525  drive, efi_handle_name ( handle ), strerror ( rc ) );
526  return rc;
527  }
528 
529  /* Open root volume */
530  if ( ( efirc = fs->OpenVolume ( fs, root ) ) != 0 ) {
531  rc = -EEFI ( efirc );
532  DBGC ( drive, "EFIBLK %#02x could not open %s root: %s\n",
533  drive, efi_handle_name ( handle ), strerror ( rc ) );
534  return rc;
535  }
536 
537  return 0;
538 }
539 
540 /**
541  * Check for existence of a file within a filesystem
542  *
543  * @v drive Drive number
544  * @v handle Filesystem handle
545  * @v root Root directory
546  * @v filename Filename (or NULL to use default)
547  * @ret rc Return status code
548  */
549 static int efi_block_filename ( unsigned int drive, EFI_HANDLE handle,
551  const char *filename ) {
552  CHAR16 tmp[ filename ? ( strlen ( filename ) + 1 /* wNUL */ ) : 0 ];
553  CHAR16 *wname;
554  EFI_FILE_PROTOCOL *file;
555  EFI_STATUS efirc;
556  int rc;
557 
558  /* Construct filename */
559  if ( filename ) {
560  efi_snprintf ( tmp, sizeof ( tmp ), "%s", filename );
561  wname = tmp;
562  } else {
563  wname = efi_block_boot_filename;
564  }
565 
566  /* Try opening file */
567  if ( ( efirc = root->Open ( root, &file, wname,
568  EFI_FILE_MODE_READ, 0 ) ) != 0 ) {
569  rc = -EEFI ( efirc );
570  DBGC ( drive, "EFIBLK %#02x could not open %s/%ls: %s\n",
571  drive, efi_handle_name ( handle ), wname,
572  strerror ( rc ) );
573  goto err_file;
574  }
575 
576  /* Success */
577  rc = 0;
578 
579  file->Close ( file );
580  err_file:
581  return rc;
582 }
583 
584 /**
585  * Check for EFI block device filesystem label
586  *
587  * @v drive Drive number
588  * @v root Root directory
589  * @v label Volume label
590  * @ret rc Return status code
591  */
592 static int efi_block_label ( unsigned int drive, EFI_FILE_PROTOCOL *root,
593  const char *label ) {
595  UINTN size;
596  char *actual;
597  EFI_STATUS efirc;
598  int rc;
599 
600  /* Get length of file system information */
601  size = 0;
602  root->GetInfo ( root, &efi_file_system_info_id, &size, NULL );
603 
604  /* Allocate file system information */
605  info = malloc ( size );
606  if ( ! info ) {
607  rc = -ENOMEM;
608  goto err_alloc_info;
609  }
610 
611  /* Get file system information */
612  if ( ( efirc = root->GetInfo ( root, &efi_file_system_info_id, &size,
613  info ) ) != 0 ) {
614  rc = -EEFI ( efirc );
615  DBGC ( drive, "EFIBLK %#02x could not get filesystem info: "
616  "%s\n", drive, strerror ( rc ) );
617  goto err_get_info;
618  }
619 
620  /* Construct volume label for comparison */
621  if ( asprintf ( &actual, "%ls", info->VolumeLabel ) < 0 ) {
622  rc = -ENOMEM;
623  goto err_alloc_label;
624  }
625 
626  /* Compare volume label */
627  if ( strcasecmp ( label, actual ) != 0 ) {
628  DBGC ( drive, "EFIBLK %#02x has wrong label \"%s\"\n",
629  drive, actual );
630  rc = -ENOENT;
631  goto err_compare;
632  }
633 
634  /* Success */
635  rc = 0;
636 
637  err_compare:
638  free ( actual );
639  err_alloc_label:
640  err_get_info:
641  free ( info );
642  err_alloc_info:
643  return rc;
644 }
645 
646 /**
647  * Check EFI block device filesystem match
648  *
649  * @v drive Drive number
650  * @v handle Filesystem handle
651  * @v path Block device path
652  * @v config Boot configuration parameters
653  * @v fspath Filesystem device path to fill in
654  * @ret rc Return status code
655  */
656 static int efi_block_match ( unsigned int drive, EFI_HANDLE handle,
658  struct san_boot_config *config,
659  EFI_DEVICE_PATH_PROTOCOL **fspath ) {
660  EFI_FILE *root;
661  union uuid guid;
662  int rc;
663 
664  /* Identify device path */
666  fspath ) ) != 0 ) {
667  DBGC ( drive, "EFIBLK %#02x could not open %s device path: "
668  "%s\n", drive, efi_handle_name ( handle ),
669  strerror ( rc ) );
670  goto err_open;
671  }
672 
673  /* Check if filesystem is a child of this block device */
674  if ( memcmp ( *fspath, path, efi_path_len ( path ) ) != 0 ) {
675  /* Not a child device */
676  rc = -ENOTTY;
677  DBGC2 ( drive, "EFIBLK %#02x is not parent of %s\n",
679  goto err_not_child;
680  }
681  DBGC ( drive, "EFIBLK %#02x contains filesystem %s\n",
682  drive, efi_devpath_text ( *fspath ) );
683 
684  /* Check if filesystem matches GUID, if applicable */
685  if ( config->uuid ) {
686  if ( ( rc = efi_path_guid ( *fspath, &guid ) ) != 0 ) {
687  DBGC ( drive, "EFIBLK %#02x could not determine GUID: "
688  "%s\n", drive, strerror ( rc ) );
689  goto err_no_guid;
690  }
691  if ( memcmp ( config->uuid, &guid, sizeof ( guid ) ) != 0 ) {
692  DBGC ( drive, "EFIBLK %#02x has wrong GUID %s\n",
693  drive, uuid_ntoa ( &guid ) );
694  rc = -ENOENT;
695  goto err_wrong_guid;
696  }
697  }
698 
699  /* Open root directory */
700  if ( ( rc = efi_block_root ( drive, handle, &root ) ) != 0 )
701  goto err_root;
702 
703  /* Check if filesystem contains boot filename */
704  if ( ( rc = efi_block_filename ( drive, handle, root,
705  config->filename ) ) != 0 ) {
706  goto err_filename;
707  }
708 
709  /* Check if filesystem contains additional filename, if applicable */
710  if ( config->extra &&
712  config->extra ) ) != 0 ) ) {
713  goto err_extra;
714  }
715 
716  /* Check volume label, if applicable */
717  if ( config->label &&
718  ( ( rc = efi_block_label ( drive, root,
719  config->label ) ) != 0 ) ) {
720  goto err_label;
721  }
722 
723  /* Success */
724  rc = 0;
725 
726  err_label:
727  err_extra:
728  err_filename:
729  root->Close ( root );
730  err_root:
731  err_wrong_guid:
732  err_no_guid:
733  err_not_child:
734  err_open:
735  return rc;
736 }
737 
738 /**
739  * Scan EFI block device for a matching filesystem
740  *
741  * @v drive Drive number
742  * @v handle Block device handle
743  * @v config Boot configuration parameters
744  * @v fspath Filesystem device path to fill in
745  * @ret rc Return status code
746  */
747 static int efi_block_scan ( unsigned int drive, EFI_HANDLE handle,
748  struct san_boot_config *config,
749  EFI_DEVICE_PATH_PROTOCOL **fspath ) {
752  EFI_HANDLE *handles;
753  UINTN count;
754  unsigned int i;
755  EFI_STATUS efirc;
756  int rc;
757 
758  /* Connect up possible file system drivers */
760 
761  /* Identify device path */
763  &path ) ) != 0 ) {
764  DBGC ( drive, "EFIBLK %#02x could not open device path: %s\n",
765  drive, strerror ( rc ) );
766  goto err_open;
767  }
768 
769  /* Locate all Simple File System protocol handles */
770  if ( ( efirc = bs->LocateHandleBuffer (
772  NULL, &count, &handles ) ) != 0 ) {
773  rc = -EEFI ( efirc );
774  DBGC ( drive, "EFIBLK %#02x cannot locate file systems: %s\n",
775  drive, strerror ( rc ) );
776  goto err_locate;
777  }
778 
779  /* Scan for a matching filesystem */
780  rc = -ENOENT;
781  for ( i = 0 ; i < count ; i++ ) {
782 
783  /* Check for a matching filesystem */
784  if ( ( rc = efi_block_match ( drive, handles[i], path,
785  config, fspath ) ) != 0 )
786  continue;
787 
788  break;
789  }
790 
791  bs->FreePool ( handles );
792  err_locate:
793  err_open:
794  return rc;
795 }
796 
797 /**
798  * Boot from EFI block device filesystem boot image
799  *
800  * @v drive Drive number
801  * @v fspath Filesystem device path
802  * @v filename Filename (or NULL to use default)
803  * @ret rc Return status code
804  */
805 static int efi_block_exec ( unsigned int drive,
806  EFI_DEVICE_PATH_PROTOCOL *fspath,
807  const char *filename ) {
810  FILEPATH_DEVICE_PATH *filepath;
813  size_t fspath_len;
814  size_t filepath_len;
815  size_t path_len;
816  EFI_STATUS efirc;
817  int rc;
818 
819  /* Construct device path for boot image */
820  end = efi_path_end ( fspath );
821  fspath_len = ( ( ( void * ) end ) - ( ( void * ) fspath ) );
822  filepath_len = ( SIZE_OF_FILEPATH_DEVICE_PATH +
823  ( filename ?
824  ( ( strlen ( filename ) + 1 /* NUL */ ) *
825  sizeof ( filepath->PathName[0] ) ) :
826  sizeof ( efi_block_boot_filename ) ) );
827  path_len = ( fspath_len + filepath_len + sizeof ( *end ) );
828  path = zalloc ( path_len );
829  if ( ! path ) {
830  rc = -ENOMEM;
831  goto err_alloc;
832  }
833  memcpy ( path, fspath, fspath_len );
834  filepath = ( ( ( void * ) path ) + fspath_len );
835  filepath->Header.Type = MEDIA_DEVICE_PATH;
836  filepath->Header.SubType = MEDIA_FILEPATH_DP;
837  filepath->Header.Length[0] = ( filepath_len & 0xff );
838  filepath->Header.Length[1] = ( filepath_len >> 8 );
839  if ( filename ) {
840  efi_sprintf ( filepath->PathName, "%s", filename );
841  } else {
843  sizeof ( efi_block_boot_filename ) );
844  }
845  end = ( ( ( void * ) filepath ) + filepath_len );
847  DBGC ( drive, "EFIBLK %#02x trying to load %s\n",
848  drive, efi_devpath_text ( path ) );
849 
850  /* Load image */
851  image = NULL;
852  if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, path, NULL, 0,
853  &image ) ) != 0 ) {
854  rc = -EEFI ( efirc );
855  DBGC ( drive, "EFIBLK %#02x could not load: %s\n",
856  drive, strerror ( rc ) );
857  if ( efirc == EFI_SECURITY_VIOLATION ) {
858  goto err_load_security_violation;
859  } else {
860  goto err_load;
861  }
862  }
863 
864  /* Start image */
865  efirc = bs->StartImage ( image, NULL, NULL );
866  rc = ( efirc ? -EEFI ( efirc ) : 0 );
867  DBGC ( drive, "EFIBLK %#02x boot image returned: %s\n",
868  drive, strerror ( rc ) );
869 
870  err_load_security_violation:
871  bs->UnloadImage ( image );
872  err_load:
873  free ( path );
874  err_alloc:
875  return rc;
876 }
877 
878 /**
879  * Check that EFI block device is eligible for a local virtual drive number
880  *
881  * @v handle Block device handle
882  * @ret rc Return status code
883  *
884  * We assign virtual drive numbers for local (non-SAN) EFI block
885  * devices that represent complete disks, to provide roughly
886  * equivalent functionality to BIOS drive numbers.
887  */
889  struct san_device *sandev;
890  struct efi_block_data *block;
891  EFI_BLOCK_IO_PROTOCOL *blockio;
892  int rc;
893 
894  /* Check if handle belongs to a SAN device */
895  for_each_sandev ( sandev ) {
896  block = sandev->priv;
897  if ( handle == block->handle )
898  return -ENOTTY;
899  }
900 
901  /* Open block I/O protocol */
903  &blockio ) ) != 0 ) {
904  DBGC ( handle, "EFIBLK %s could not open block I/O: %s\n",
905  efi_handle_name ( handle ), strerror ( rc ) );
906  return rc;
907  }
908 
909  /* Do not assign drive numbers for partitions */
910  if ( blockio->Media->LogicalPartition ) {
911  DBGC2 ( handle, "EFLBLK %s is a partition\n",
912  efi_handle_name ( handle ) );
913  return -ENOTTY;
914  }
915 
916  return 0;
917 }
918 
919 /**
920  * Boot from EFI block device
921  *
922  * @v drive Drive number
923  * @v config Boot configuration parameters
924  * @ret rc Return status code
925  */
926 static int efi_block_boot ( unsigned int drive,
927  struct san_boot_config *config ) {
929  EFI_DEVICE_PATH_PROTOCOL *fspath = NULL;
930  EFI_HANDLE *handles;
932  UINTN count;
933  struct san_device *sandev;
934  struct efi_block_data *block;
935  unsigned int vdrive;
936  unsigned int index;
937  EFI_STATUS efirc;
938  int rc;
939 
940  /* Ensure that any local drives are connected */
942 
943  /* Release SNP devices */
944  efi_snp_release();
945 
946  /* Locate all block I/O protocol handles */
947  if ( ( efirc = bs->LocateHandleBuffer ( ByProtocol,
949  NULL, &count,
950  &handles ) ) != 0 ) {
951  rc = -EEFI ( efirc );
952  DBGC ( drive, "EFIBLK %#02x cannot locate block I/O: %s\n",
953  drive, strerror ( rc ) );
954  goto err_locate_block_io;
955  }
956 
957  /* Try booting from the first matching block device, if any */
958  rc = -ENOENT;
959  for ( vdrive = 0, index = 0 ; ; vdrive++ ) {
960 
961  /* Identify next drive number and block I/O handle */
962  if ( ( sandev = sandev_next ( vdrive ) ) &&
963  ( ( sandev->drive == vdrive ) ||
964  ( sandev->drive <= SAN_DEFAULT_DRIVE ) ||
965  ( index >= count ) ) ) {
966 
967  /* There is a SAN drive that either:
968  *
969  * a) has the current virtual drive number, or
970  * b) has a drive number below SAN_DEFAULT_DRIVE, or
971  * c) has a drive number higher than any local drive
972  *
973  * Use this SAN drive, since the explicit SAN
974  * drive numbering takes precedence over the
975  * implicit local drive numbering.
976  */
977  block = sandev->priv;
978  handle = block->handle;
979 
980  /* Use SAN drive's explicit drive number */
981  vdrive = sandev->drive;
982  DBGC ( vdrive, "EFIBLK %#02x is SAN drive %s\n",
983  vdrive, efi_handle_name ( handle ) );
984 
985  } else if ( index < count ) {
986 
987  /* There is no SAN drive meeting any of the
988  * above criteria. Try the next block I/O
989  * handle.
990  */
991  handle = handles[index++];
992 
993  /* Check if this handle is eligible to be
994  * given a local virtual drive number.
995  *
996  * Do not record this as the overall error
997  * status, since it is not an interesting
998  * error.
999  */
1000  if ( efi_block_local ( handle ) != 0 ) {
1001  /* Do not consume virtual drive number */
1002  vdrive--;
1003  continue;
1004  }
1005 
1006  /* Use the current virtual drive number, with
1007  * a minimum of SAN_DEFAULT_DRIVE to match
1008  * typical BIOS drive numbering.
1009  */
1010  if ( vdrive < SAN_DEFAULT_DRIVE )
1011  vdrive = SAN_DEFAULT_DRIVE;
1012  DBGC ( vdrive, "EFIBLK %#02x is local drive %s\n",
1013  vdrive, efi_handle_name ( handle ) );
1014 
1015  } else {
1016 
1017  /* No more SAN or local drives */
1018  break;
1019  }
1020 
1021  /* Skip non-matching drives */
1022  if ( drive && ( drive != vdrive ) )
1023  continue;
1024  DBGC ( vdrive, "EFIBLK %#02x attempting to boot\n", vdrive );
1025 
1026  /* Scan for a matching filesystem within this drive */
1027  if ( ( rc = efi_block_scan ( vdrive, handle, config,
1028  &fspath ) ) != 0 ) {
1029  continue;
1030  }
1031 
1032  /* Attempt to boot from the matched filesystem */
1033  rc = efi_block_exec ( vdrive, fspath, config->filename );
1034  break;
1035  }
1036 
1037  bs->FreePool ( handles );
1038  err_locate_block_io:
1039  efi_snp_claim();
1040  return rc;
1041 }
1042 
static int efi_block_describe(void)
Describe EFI block devices.
Definition: efi_block.c:470
EFI_FILE_CLOSE Close
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
Definition: UefiSpec.h:2098
#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:575
struct arbelprm_rc_send_wqe rc
Definition: arbel.h:14
static void efi_block_connect(unsigned int drive, EFI_HANDLE handle)
Connect all possible drivers to EFI block device.
Definition: efi_block.c:220
A text label widget.
Definition: label.h:16
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
Definition: efi.h:174
EFI_ACPI_TABLE_INSTALL_ACPI_TABLE InstallAcpiTable
Definition: AcpiTable.h:117
u32 info
Definition: ar9003_mac.h:67
EFI driver interface.
int efi_connect(EFI_HANDLE device, EFI_HANDLE driver)
Connect UEFI driver(s)
Definition: efi_connect.c:57
UINTN key
Table key.
Definition: efi_block.c:407
int san_describe(void)
Describe SAN devices for SAN-booted operating system.
int san_hook(unsigned int drive, struct uri **uris, unsigned int count, unsigned int flags)
Hook SAN device.
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, void *buffer))
Read from or write to EFI block device.
Definition: efi_block.c:95
#define le32_to_cpu(value)
Definition: byteswap.h:113
struct stp_switch root
Root switch.
Definition: stp.h:26
struct san_device * sandev
SAN device.
Definition: efi_block.c:74
EFI_GUID efi_file_system_info_id
File system information GUID.
Definition: efi_guid.c:454
Error codes.
A universally unique ID.
Definition: uuid.h:15
struct golan_inbox_hdr hdr
Message header.
Definition: CIB_PRM.h:28
BOOLEAN LogicalPartition
TRUE if LBA 0 is the first block of a partition; otherwise FALSE.
Definition: BlockIo.h:152
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:242
EFI strings.
EFI_IMAGE_LOAD LoadImage
Definition: UefiSpec.h:1977
unsigned char BOOLEAN
Retry timers.
uint16_t size
Buffer size.
Definition: dwmac.h:14
void unregister_sandev(struct san_device *sandev)
Unregister SAN device.
Definition: sanboot.c:941
int san_boot(unsigned int drive, struct san_boot_config *config)
Attempt to boot from a SAN device.
#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:47
long index
Definition: bigint.h:62
#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:2009
unsigned long long uint64_t
Definition: stdint.h:13
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
Definition: string.c:208
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
Definition: efi_path.c:145
static void sandev_put(struct san_device *sandev)
Drop reference to SAN device.
Definition: sanboot.h:225
unsigned short CHAR16
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:181
EFI_BLOCK_IO_PROTOCOL block_io
Block I/O protocol.
Definition: efi_block.c:80
iPXE timers
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
Definition: netvsc.h:16
EFI_IMAGE_UNLOAD UnloadImage
Definition: UefiSpec.h:1980
An executable image.
Definition: image.h:23
static int efi_block_local(EFI_HANDLE handle)
Check that EFI block device is eligible for a local virtual drive number.
Definition: efi_block.c:888
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:1106
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:1102
Uniform Resource Identifiers.
EFI SAN device private data.
Definition: efi_block.c:72
#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:30
Data transfer interfaces.
EFI_DEVICE_PATH_PROTOCOL * path
Device path protocol.
Definition: efi_block.c:82
unsigned long tmp
Definition: linux_pci.h:63
char * strncpy(char *dest, const char *src, size_t max)
Copy string.
Definition: string.c:360
#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
static int efi_block_match(unsigned int drive, EFI_HANDLE handle, EFI_DEVICE_PATH_PROTOCOL *path, struct san_boot_config *config, EFI_DEVICE_PATH_PROTOCOL **fspath)
Check EFI block device filesystem match.
Definition: efi_block.c:656
void efi_driver_reconnect_all(void)
Reconnect original EFI drivers to all possible devices.
Definition: efi_driver.c:658
#define container_of(ptr, type, field)
Get containing structure.
Definition: stddef.h:35
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:329
UINT64 EFI_LBA
Logical block address.
Definition: UefiBaseType.h:47
#define __unused
Declare a variable or data structure as unused.
Definition: compiler.h:573
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:65
unsigned int drive
Drive number.
Definition: sanboot.h:65
ring len
Length.
Definition: dwmac.h:231
SAN boot configuration parameters.
Definition: sanboot.h:110
union uuid * uuid
UUID (or NULL to ignore UUID)
Definition: sanboot.h:118
int register_sandev(struct san_device *sandev, unsigned int drive, unsigned int flags)
Register SAN device.
Definition: sanboot.c:879
static int efi_block_install(struct acpi_header *hdr)
Install ACPI table.
Definition: efi_block.c:419
static int efi_block_exec(unsigned int drive, EFI_DEVICE_PATH_PROTOCOL *fspath, const char *filename)
Boot from EFI block device filesystem boot image.
Definition: efi_block.c:805
static void efi_block_unhook(unsigned int drive)
Unhook EFI block device.
Definition: efi_block.c:356
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
Definition: efi_strings.c:106
static unsigned int count
Number of entries.
Definition: dwmac.h:225
const char * filename
Boot filename (or NULL to use default)
Definition: sanboot.h:112
unsigned int blksize_shift
Block size shift.
Definition: sanboot.h:84
static int efi_block_boot(unsigned int drive, struct san_boot_config *config)
Boot from EFI block device.
Definition: efi_block.c:926
void acpi_fix_checksum(struct acpi_header *acpi)
Fix up ACPI table checksum.
Definition: acpi.c:79
#define SIZE_OF_FILEPATH_DEVICE_PATH
Definition: DevicePath.h:1109
EFI_REQUEST_PROTOCOL(EFI_ACPI_TABLE_PROTOCOL, &acpi)
uint64_t blocks
Total number of blocks.
Definition: blockdev.h:19
ISO9660 CD-ROM specification.
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
Definition: efi_debug.c:247
#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:458
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:343
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
Definition: efi_debug.c:652
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:130
uint32_t fs
Definition: librm.h:138
uint8_t flags
Flags.
Definition: ena.h:18
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:661
EFI Boot Services Table.
Definition: UefiSpec.h:1930
#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:35
int asprintf(char **strp, const char *fmt,...)
Write a formatted string to newly allocated memory.
Definition: asprintf.c:41
static LIST_HEAD(efi_acpi_tables)
List of installed ACPI tables.
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
Definition: UefiSpec.h:2010
#define ENODEV
No such device.
Definition: errno.h:509
#define efi_open(handle, protocol, interface)
Open protocol for ephemeral use.
Definition: efi.h:440
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:58
const char * label
Filesystem label (or NULL to ignore volume label)
Definition: sanboot.h:116
uint64_t lba
Starting block number.
Definition: int13.h:22
Processes.
static int efi_block_filename(unsigned int drive, EFI_HANDLE handle, EFI_FILE_PROTOCOL *root, const char *filename)
Check for existence of a file within a filesystem.
Definition: efi_block.c:549
static wchar_t efi_block_boot_filename[]
Boot filename.
Definition: efi_block.c:69
Data transfer interface opening.
EFI device paths.
EFI_IMAGE_START StartImage
Definition: UefiSpec.h:1978
#define MEDIA_DEVICE_PATH
Definition: DevicePath.h:1011
UINT64 UINTN
Unsigned value of native width.
#define for_each_sandev(sandev)
Iterate over all SAN devices.
Definition: sanboot.h:196
struct san_device * sandev_next(unsigned int drive)
Find next SAN device by drive number.
Definition: sanboot.c:107
An ACPI description header.
Definition: acpi.h:179
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
Definition: efi_guid.c:161
static int sandev_rw(struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer, int(*block_rw)(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, void *buffer, size_t len))
Read from or write to SAN device.
Definition: sanboot.c:597
#define VOID
Undeclared type.
Definition: Base.h:271
void * malloc(size_t size)
Allocate memory.
Definition: malloc.c:620
const char * uuid_ntoa(const union uuid *uuid)
Convert UUID to printable string.
Definition: uuid.c:45
EFI_FREE_POOL FreePool
Definition: UefiSpec.h:1949
static int efi_block_scan(unsigned int drive, EFI_HANDLE handle, struct san_boot_config *config, EFI_DEVICE_PATH_PROTOCOL **fspath)
Scan EFI block device for a matching filesystem.
Definition: efi_block.c:747
EFI_HANDLE handle
EFI handle.
Definition: efi_block.c:76
EFI API.
uint64_t guid
GUID.
Definition: edd.h:30
#define EFI_SECURITY_VIOLATION
Enumeration of EFI_STATUS.
Definition: UefiBaseType.h:140
EFI_BLOCK_IO_MEDIA * Media
Pointer to the EFI_BLOCK_IO_MEDIA data for this device.
Definition: BlockIo.h:226
Block IO read only mode data and updated only via members of BlockIO.
Definition: BlockIo.h:130
struct block_device_capacity capacity
Raw block device capacity.
Definition: sanboot.h:77
struct list_head list
List of installed tables.
Definition: efi_block.c:405
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:155
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition: efi_path.c:879
UINT8 Length[2]
Specific Device Path data.
Definition: DevicePath.h:58
struct san_device * sandev_find(unsigned int drive)
Find SAN device by drive number.
Definition: sanboot.c:91
#define DBGC2(...)
Definition: compiler.h:522
EFI_GUID efi_block_io_protocol_guid
Block I/O protocol GUID.
Definition: efi_guid.c:137
uint8_t block[3][8]
DES-encrypted blocks.
Definition: mschapv2.h:12
#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:203
const char * extra
Required extra filename (or NULL to ignore)
Definition: sanboot.h:114
#define EFI_FILE_MODE_READ
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:89
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
static int efi_block_label(unsigned int drive, EFI_FILE_PROTOCOL *root, const char *label)
Check for EFI block device filesystem label.
Definition: efi_block.c:592
static const char * acpi_name(uint32_t signature)
Transcribe ACPI table signature (for debugging)
Definition: acpi.h:206
#define DBGC2_EFI_PROTOCOLS(...)
Definition: efi.h:354
Block IO protocol as defined in the UEFI 2.0 specification.
Reference counting.
EFI_BLOCK_IO_MEDIA media
Media descriptor.
Definition: efi_block.c:78
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:1530
A Uniform Resource Identifier.
Definition: uri.h:64
EFI_SYSTEM_TABLE * efi_systab
iPXE EFI SNP interface
struct san_path * active
Current active path.
Definition: sanboot.h:94
#define SAN_DEFAULT_DRIVE
Default SAN drive number.
Definition: sanboot.h:33
The file provides the protocol to install or remove an ACPI table from a platform.
static int efi_block_root(unsigned int drive, EFI_HANDLE handle, EFI_FILE_PROTOCOL **root)
Open root directory within a filesystem.
Definition: efi_block.c:515
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer)
Read from SAN device.
Definition: sanboot.c:646
#define DBG(...)
Print a debugging message.
Definition: compiler.h:498
iPXE sanboot API
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
String functions.
Provides a GUID and a data structure that can be used with EFI_FILE_PROTOCOL.GetInfo() or EFI_FILE_PR...
EFI_DEVICE_PATH_PROTOCOL * efi_path_end(EFI_DEVICE_PATH_PROTOCOL *path)
Find end of device path.
Definition: efi_path.c:134
PROVIDE_SANBOOT(efi, san_hook, efi_block_hook)
An installed ACPI table.
Definition: efi_block.c:403
int efi_path_guid(EFI_DEVICE_PATH_PROTOCOL *path, union uuid *guid)
Get partition GUID from device path.
Definition: efi_path.c:232
The EFI_FILE_PROTOCOL provides file IO access to supported file systems.
union @390 key
Sense key.
Definition: scsi.h:17
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
Definition: efi.h:166
Definition: efi.h:61
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:836
EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer
Definition: UefiSpec.h:2007
size_t blksize
Block size.
Definition: blockdev.h:21
String functions.
int efi_shutdown_in_progress
EFI shutdown is in progress.
Definition: efi_init.c:59
#define MEDIA_FILEPATH_DP
File Path Media Device Path SubType.
Definition: DevicePath.h:1100
int sandev_write(struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer)
Write to SAN device.
Definition: sanboot.c:667