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_wrap.h>
63 #include <ipxe/efi/efi_block.h>
64 
65 /** ACPI table protocol protocol */
68 
69 /** Boot filename */
71 
72 /** EFI SAN device private data */
74  /** SAN device */
75  struct san_device *sandev;
76  /** EFI handle */
78  /** Media descriptor */
80  /** Block I/O protocol */
82  /** Device path protocol */
84 };
85 
86 /**
87  * Read from or write to EFI block device
88  *
89  * @v sandev SAN device
90  * @v lba Starting LBA
91  * @v data Data buffer
92  * @v len Size of buffer
93  * @v sandev_rw SAN device read/write method
94  * @ret rc Return status code
95  */
96 static int efi_block_rw ( struct san_device *sandev, uint64_t lba,
97  void *data, size_t len,
98  int ( * sandev_rw ) ( struct san_device *sandev,
99  uint64_t lba,
100  unsigned int count,
101  void *buffer ) ) {
102  struct efi_block_data *block = sandev->priv;
103  unsigned int count;
104  int rc;
105 
106  /* Sanity check */
107  count = ( len / block->media.BlockSize );
108  if ( ( count * block->media.BlockSize ) != len ) {
109  DBGC ( sandev->drive, "EFIBLK %#02x impossible length %#zx\n",
110  sandev->drive, len );
111  return -EINVAL;
112  }
113 
114  /* Read from / write to block device */
115  if ( ( rc = sandev_rw ( sandev, lba, count, data ) ) != 0 ) {
116  DBGC ( sandev->drive, "EFIBLK %#02x I/O failed: %s\n",
117  sandev->drive, strerror ( rc ) );
118  return rc;
119  }
120 
121  return 0;
122 }
123 
124 /**
125  * Reset EFI block device
126  *
127  * @v block_io Block I/O protocol
128  * @v verify Perform extended verification
129  * @ret efirc EFI status code
130  */
132  BOOLEAN verify __unused ) {
133  struct efi_block_data *block =
135  struct san_device *sandev = block->sandev;
136  int rc;
137 
138  DBGC2 ( sandev->drive, "EFIBLK %#02x reset\n", sandev->drive );
139  efi_snp_claim();
140  rc = sandev_reset ( sandev );
141  efi_snp_release();
142  return EFIRC ( rc );
143 }
144 
145 /**
146  * Read from EFI block device
147  *
148  * @v block_io Block I/O protocol
149  * @v media Media identifier
150  * @v lba Starting LBA
151  * @v len Size of buffer
152  * @v data Data buffer
153  * @ret efirc EFI status code
154  */
155 static EFI_STATUS EFIAPI
157  EFI_LBA lba, UINTN len, VOID *data ) {
158  struct efi_block_data *block =
160  struct san_device *sandev = block->sandev;
161  int rc;
162 
163  DBGC2 ( sandev->drive, "EFIBLK %#02x read LBA %#08llx to %p+%#08zx\n",
164  sandev->drive, lba, data, ( ( size_t ) len ) );
165  efi_snp_claim();
166  rc = efi_block_rw ( sandev, lba, data, len, sandev_read );
167  efi_snp_release();
168  return EFIRC ( rc );
169 }
170 
171 /**
172  * Write to EFI block device
173  *
174  * @v block_io Block I/O protocol
175  * @v media Media identifier
176  * @v lba Starting LBA
177  * @v len Size of buffer
178  * @v data Data buffer
179  * @ret efirc EFI status code
180  */
181 static EFI_STATUS EFIAPI
183  EFI_LBA lba, UINTN len, VOID *data ) {
184  struct efi_block_data *block =
186  struct san_device *sandev = block->sandev;
187  int rc;
188 
189  DBGC2 ( sandev->drive, "EFIBLK %#02x write LBA %#08llx from "
190  "%p+%#08zx\n", sandev->drive, lba, data, ( ( size_t ) len ) );
191  efi_snp_claim();
192  rc = efi_block_rw ( sandev, lba, data, len, sandev_write );
193  efi_snp_release();
194  return EFIRC ( rc );
195 }
196 
197 /**
198  * Flush data to EFI block device
199  *
200  * @v block_io Block I/O protocol
201  * @ret efirc EFI status code
202  */
203 static EFI_STATUS EFIAPI
205  struct efi_block_data *block =
207  struct san_device *sandev = block->sandev;
208 
209  DBGC2 ( sandev->drive, "EFIBLK %#02x flush\n", sandev->drive );
210 
211  /* Nothing to do */
212  return 0;
213 }
214 
215 /**
216  * Connect all possible drivers to EFI block device
217  *
218  * @v drive Drive number
219  * @v handle Block device handle
220  */
221 static void efi_block_connect ( unsigned int drive, EFI_HANDLE handle ) {
222  int rc;
223 
224  /* Try to connect all possible drivers to this block device */
225  if ( ( rc = efi_connect ( handle, NULL ) ) != 0 ) {
226  DBGC ( drive, "EFIBLK %#02x could not connect drivers: %s\n",
227  drive, strerror ( rc ) );
228  /* May not be an error; may already be connected */
229  }
230  DBGC2 ( drive, "EFIBLK %#02x supports protocols:\n", drive );
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  DBGC ( drive, "EFIBLK %#02x has no URIs\n", drive );
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 ( drive, "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 ( drive, "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 ( drive, "EFIBLK %#02x has no device path\n", drive );
300  goto err_describe;
301  }
302  DBGC2 ( drive, "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 ( drive, "EFIBLK %#02x could not install protocols: %s\n",
313  drive, strerror ( rc ) );
314  goto err_install;
315  }
316  DBGC ( drive, "EFIBLK %#02x installed as SAN drive %s\n",
317  drive, efi_handle_name ( block->handle ) );
318 
319  /* Connect all possible protocols */
320  efi_block_connect ( drive, block->handle );
321 
322  return drive;
323 
324  if ( ( efirc = bs->UninstallMultipleProtocolInterfaces (
325  block->handle,
326  &efi_block_io_protocol_guid, &block->block_io,
328  NULL ) ) != 0 ) {
329  DBGC ( drive, "EFIBLK %#02x could not uninstall protocols: "
330  "%s\n", drive, strerror ( -EEFI ( efirc ) ) );
331  leak = 1;
332  }
333  efi_nullify_block ( &block->block_io );
334  err_install:
335  if ( ! leak ) {
336  free ( block->path );
337  block->path = NULL;
338  }
339  err_describe:
340  err_active:
342  err_register:
343  if ( ! leak )
344  sandev_put ( sandev );
345  err_alloc:
346  err_no_uris:
347  if ( leak )
348  DBGC ( drive, "EFIBLK %#02x nullified and leaked\n", drive );
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  DBGC ( drive, "EFIBLK %#02x is not a SAN drive\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 ( drive, "EFIBLK %#02x could not uninstall protocols: "
380  "%s\n", 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 ( drive, "EFIBLK %#02x nullified and leaked\n", drive );
401 }
402 
403 /** An installed ACPI table */
405  /** List of installed tables */
406  struct list_head list;
407  /** Table key */
409 };
410 
411 /** List of installed ACPI tables */
412 static LIST_HEAD ( efi_acpi_tables );
413 
414 /**
415  * Install ACPI table
416  *
417  * @v hdr ACPI description header
418  * @ret rc Return status code
419  */
420 static int efi_block_install ( struct acpi_header *hdr ) {
421  size_t len = le32_to_cpu ( hdr->length );
422  struct efi_acpi_table *installed;
423  EFI_STATUS efirc;
424  int rc;
425 
426  /* Allocate installed table record */
427  installed = zalloc ( sizeof ( *installed ) );
428  if ( ! installed ) {
429  rc = -ENOMEM;
430  goto err_alloc;
431  }
432 
433  /* Fill in common parameters */
434  strncpy ( hdr->oem_id, "FENSYS", sizeof ( hdr->oem_id ) );
435  strncpy ( hdr->oem_table_id, "iPXE", sizeof ( hdr->oem_table_id ) );
436 
437  /* Fix up ACPI checksum */
439 
440  /* Install table */
441  if ( ( efirc = acpi->InstallAcpiTable ( acpi, hdr, len,
442  &installed->key ) ) != 0 ){
443  rc = -EEFI ( efirc );
444  DBGC ( acpi, "EFIBLK could not install %s: %s\n",
445  acpi_name ( hdr->signature ), strerror ( rc ) );
446  DBGC2_HDA ( acpi, 0, hdr, len );
447  goto err_install;
448  }
449 
450  /* Add to list of installed tables */
451  list_add_tail ( &installed->list, &efi_acpi_tables );
452 
453  DBGC ( acpi, "EFIBLK installed %s as ACPI table %#lx\n",
454  acpi_name ( hdr->signature ),
455  ( ( unsigned long ) installed->key ) );
456  DBGC2_HDA ( acpi, 0, hdr, len );
457  return 0;
458 
459  list_del ( &installed->list );
460  err_install:
461  free ( installed );
462  err_alloc:
463  return rc;
464 }
465 
466 /**
467  * Describe EFI block devices
468  *
469  * @ret rc Return status code
470  */
471 static int efi_block_describe ( void ) {
472  struct efi_acpi_table *installed;
473  struct efi_acpi_table *tmp;
474  UINTN key;
475  EFI_STATUS efirc;
476  int rc;
477 
478  /* Sanity check */
479  if ( ! acpi ) {
480  DBG ( "EFIBLK has no ACPI table protocol\n" );
481  return -ENOTSUP;
482  }
483 
484  /* Uninstall any existing ACPI tables */
485  list_for_each_entry_safe ( installed, tmp, &efi_acpi_tables, list ) {
486  key = installed->key;
487  if ( ( efirc = acpi->UninstallAcpiTable ( acpi, key ) ) != 0 ) {
488  rc = -EEFI ( efirc );
489  DBGC ( acpi, "EFIBLK could not uninstall ACPI table "
490  "%#lx: %s\n", ( ( unsigned long ) key ),
491  strerror ( rc ) );
492  /* Continue anyway */
493  }
494  list_del ( &installed->list );
495  free ( installed );
496  }
497 
498  /* Install ACPI tables */
499  if ( ( rc = acpi_install ( efi_block_install ) ) != 0 ) {
500  DBGC ( acpi, "EFIBLK could not install ACPI tables: %s\n",
501  strerror ( rc ) );
502  return rc;
503  }
504 
505  return 0;
506 }
507 
508 /**
509  * Open root directory within a filesystem
510  *
511  * @v drive Drive number
512  * @v handle Filesystem handle
513  * @v root Root directory file to fill in
514  * @ret rc Return status code
515  */
516 static int efi_block_root ( unsigned int drive, EFI_HANDLE handle,
517  EFI_FILE_PROTOCOL **root ) {
519  EFI_STATUS efirc;
520  int rc;
521 
522  /* Open filesystem protocol */
524  &fs ) ) != 0 ) {
525  DBGC ( drive, "EFIBLK %#02x could not open %s filesystem: %s\n",
526  drive, efi_handle_name ( handle ), strerror ( rc ) );
527  return rc;
528  }
529 
530  /* Open root volume */
531  if ( ( efirc = fs->OpenVolume ( fs, root ) ) != 0 ) {
532  rc = -EEFI ( efirc );
533  DBGC ( drive, "EFIBLK %#02x could not open %s root: %s\n",
534  drive, efi_handle_name ( handle ), strerror ( rc ) );
535  return rc;
536  }
537 
538  return 0;
539 }
540 
541 /**
542  * Check for existence of a file within a filesystem
543  *
544  * @v drive Drive number
545  * @v handle Filesystem handle
546  * @v root Root directory
547  * @v filename Filename (or NULL to use default)
548  * @ret rc Return status code
549  */
550 static int efi_block_filename ( unsigned int drive, EFI_HANDLE handle,
552  const char *filename ) {
553  CHAR16 tmp[ filename ? ( strlen ( filename ) + 1 /* wNUL */ ) : 0 ];
554  CHAR16 *wname;
555  EFI_FILE_PROTOCOL *file;
556  EFI_STATUS efirc;
557  int rc;
558 
559  /* Construct filename */
560  if ( filename ) {
561  efi_snprintf ( tmp, sizeof ( tmp ), "%s", filename );
562  wname = tmp;
563  } else {
564  wname = efi_block_boot_filename;
565  }
566 
567  /* Try opening file */
568  if ( ( efirc = root->Open ( root, &file, wname,
569  EFI_FILE_MODE_READ, 0 ) ) != 0 ) {
570  rc = -EEFI ( efirc );
571  DBGC ( drive, "EFIBLK %#02x could not open %s/%ls: %s\n",
572  drive, efi_handle_name ( handle ), wname,
573  strerror ( rc ) );
574  goto err_file;
575  }
576 
577  /* Success */
578  rc = 0;
579 
580  file->Close ( file );
581  err_file:
582  return rc;
583 }
584 
585 /**
586  * Check for EFI block device filesystem label
587  *
588  * @v drive Drive number
589  * @v root Root directory
590  * @v label Volume label
591  * @ret rc Return status code
592  */
593 static int efi_block_label ( unsigned int drive, EFI_FILE_PROTOCOL *root,
594  const char *label ) {
596  UINTN size;
597  char *actual;
598  EFI_STATUS efirc;
599  int rc;
600 
601  /* Get length of file system information */
602  size = 0;
603  root->GetInfo ( root, &efi_file_system_info_id, &size, NULL );
604 
605  /* Allocate file system information */
606  info = malloc ( size );
607  if ( ! info ) {
608  rc = -ENOMEM;
609  goto err_alloc_info;
610  }
611 
612  /* Get file system information */
613  if ( ( efirc = root->GetInfo ( root, &efi_file_system_info_id, &size,
614  info ) ) != 0 ) {
615  rc = -EEFI ( efirc );
616  DBGC ( drive, "EFIBLK %#02x could not get filesystem info: "
617  "%s\n", drive, strerror ( rc ) );
618  goto err_get_info;
619  }
620 
621  /* Construct volume label for comparison */
622  if ( asprintf ( &actual, "%ls", info->VolumeLabel ) < 0 ) {
623  rc = -ENOMEM;
624  goto err_alloc_label;
625  }
626 
627  /* Compare volume label */
628  if ( strcasecmp ( label, actual ) != 0 ) {
629  DBGC ( drive, "EFIBLK %#02x has wrong label \"%s\"\n",
630  drive, actual );
631  rc = -ENOENT;
632  goto err_compare;
633  }
634 
635  /* Success */
636  rc = 0;
637 
638  err_compare:
639  free ( actual );
640  err_alloc_label:
641  err_get_info:
642  free ( info );
643  err_alloc_info:
644  return rc;
645 }
646 
647 /**
648  * Check EFI block device filesystem match
649  *
650  * @v drive Drive number
651  * @v handle Filesystem handle
652  * @v path Block device path
653  * @v config Boot configuration parameters
654  * @v fspath Filesystem device path to fill in
655  * @ret rc Return status code
656  */
657 static int efi_block_match ( unsigned int drive, EFI_HANDLE handle,
659  struct san_boot_config *config,
660  EFI_DEVICE_PATH_PROTOCOL **fspath ) {
661  EFI_FILE *root;
662  union uuid guid;
663  int rc;
664 
665  /* Identify device path */
667  fspath ) ) != 0 ) {
668  DBGC ( drive, "EFIBLK %#02x could not open %s device path: "
669  "%s\n", drive, efi_handle_name ( handle ),
670  strerror ( rc ) );
671  goto err_open;
672  }
673 
674  /* Check if filesystem is a child of this block device */
675  if ( memcmp ( *fspath, path, efi_path_len ( path ) ) != 0 ) {
676  /* Not a child device */
677  rc = -ENOTTY;
678  DBGC2 ( drive, "EFIBLK %#02x is not parent of %s\n",
680  goto err_not_child;
681  }
682  DBGC ( drive, "EFIBLK %#02x contains filesystem %s\n",
683  drive, efi_devpath_text ( *fspath ) );
684 
685  /* Check if filesystem matches GUID, if applicable */
686  if ( config->uuid ) {
687  if ( ( rc = efi_path_guid ( *fspath, &guid ) ) != 0 ) {
688  DBGC ( drive, "EFIBLK %#02x could not determine GUID: "
689  "%s\n", drive, strerror ( rc ) );
690  goto err_no_guid;
691  }
692  if ( memcmp ( config->uuid, &guid, sizeof ( guid ) ) != 0 ) {
693  DBGC ( drive, "EFIBLK %#02x has wrong GUID %s\n",
694  drive, uuid_ntoa ( &guid ) );
695  rc = -ENOENT;
696  goto err_wrong_guid;
697  }
698  }
699 
700  /* Open root directory */
701  if ( ( rc = efi_block_root ( drive, handle, &root ) ) != 0 )
702  goto err_root;
703 
704  /* Check if filesystem contains boot filename */
705  if ( ( rc = efi_block_filename ( drive, handle, root,
706  config->filename ) ) != 0 ) {
707  goto err_filename;
708  }
709 
710  /* Check if filesystem contains additional filename, if applicable */
711  if ( config->extra &&
713  config->extra ) ) != 0 ) ) {
714  goto err_extra;
715  }
716 
717  /* Check volume label, if applicable */
718  if ( config->label &&
719  ( ( rc = efi_block_label ( drive, root,
720  config->label ) ) != 0 ) ) {
721  goto err_label;
722  }
723 
724  /* Success */
725  rc = 0;
726 
727  err_label:
728  err_extra:
729  err_filename:
730  root->Close ( root );
731  err_root:
732  err_wrong_guid:
733  err_no_guid:
734  err_not_child:
735  err_open:
736  return rc;
737 }
738 
739 /**
740  * Scan EFI block device for a matching filesystem
741  *
742  * @v drive Drive number
743  * @v handle Block device handle
744  * @v config Boot configuration parameters
745  * @v fspath Filesystem device path to fill in
746  * @ret rc Return status code
747  */
748 static int efi_block_scan ( unsigned int drive, EFI_HANDLE handle,
749  struct san_boot_config *config,
750  EFI_DEVICE_PATH_PROTOCOL **fspath ) {
753  EFI_HANDLE *handles;
754  UINTN count;
755  unsigned int i;
756  EFI_STATUS efirc;
757  int rc;
758 
759  /* Connect up possible file system drivers */
761 
762  /* Identify device path */
764  &path ) ) != 0 ) {
765  DBGC ( drive, "EFIBLK %#02x could not open device path: %s\n",
766  drive, strerror ( rc ) );
767  goto err_open;
768  }
769 
770  /* Locate all Simple File System protocol handles */
771  if ( ( efirc = bs->LocateHandleBuffer (
773  NULL, &count, &handles ) ) != 0 ) {
774  rc = -EEFI ( efirc );
775  DBGC ( drive, "EFIBLK %#02x cannot locate file systems: %s\n",
776  drive, strerror ( rc ) );
777  goto err_locate;
778  }
779 
780  /* Scan for a matching filesystem */
781  rc = -ENOENT;
782  for ( i = 0 ; i < count ; i++ ) {
783 
784  /* Check for a matching filesystem */
785  if ( ( rc = efi_block_match ( drive, handles[i], path,
786  config, fspath ) ) != 0 )
787  continue;
788 
789  break;
790  }
791 
792  bs->FreePool ( handles );
793  err_locate:
794  err_open:
795  return rc;
796 }
797 
798 /**
799  * Boot from EFI block device filesystem boot image
800  *
801  * @v drive Drive number
802  * @v fspath Filesystem device path
803  * @v filename Filename (or NULL to use default)
804  * @ret rc Return status code
805  */
806 static int efi_block_exec ( unsigned int drive,
807  EFI_DEVICE_PATH_PROTOCOL *fspath,
808  const char *filename ) {
811  FILEPATH_DEVICE_PATH *filepath;
814  size_t fspath_len;
815  size_t filepath_len;
816  size_t path_len;
817  EFI_STATUS efirc;
818  int rc;
819 
820  /* Construct device path for boot image */
821  end = efi_path_end ( fspath );
822  fspath_len = ( ( ( void * ) end ) - ( ( void * ) fspath ) );
823  filepath_len = ( SIZE_OF_FILEPATH_DEVICE_PATH +
824  ( filename ?
825  ( ( strlen ( filename ) + 1 /* NUL */ ) *
826  sizeof ( filepath->PathName[0] ) ) :
827  sizeof ( efi_block_boot_filename ) ) );
828  path_len = ( fspath_len + filepath_len + sizeof ( *end ) );
829  path = zalloc ( path_len );
830  if ( ! path ) {
831  rc = -ENOMEM;
832  goto err_alloc;
833  }
834  memcpy ( path, fspath, fspath_len );
835  filepath = ( ( ( void * ) path ) + fspath_len );
836  filepath->Header.Type = MEDIA_DEVICE_PATH;
837  filepath->Header.SubType = MEDIA_FILEPATH_DP;
838  filepath->Header.Length[0] = ( filepath_len & 0xff );
839  filepath->Header.Length[1] = ( filepath_len >> 8 );
840  if ( filename ) {
841  efi_sprintf ( filepath->PathName, "%s", filename );
842  } else {
844  sizeof ( efi_block_boot_filename ) );
845  }
846  end = ( ( ( void * ) filepath ) + filepath_len );
848  DBGC ( drive, "EFIBLK %#02x trying to load %s\n",
849  drive, efi_devpath_text ( path ) );
850 
851  /* Load image */
852  image = NULL;
853  if ( ( efirc = bs->LoadImage ( FALSE, efi_image_handle, path, NULL, 0,
854  &image ) ) != 0 ) {
855  rc = -EEFI ( efirc );
856  DBGC ( drive, "EFIBLK %#02x could not load: %s\n",
857  drive, strerror ( rc ) );
858  if ( efirc == EFI_SECURITY_VIOLATION ) {
859  goto err_load_security_violation;
860  } else {
861  goto err_load;
862  }
863  }
864 
865  /* Wrap calls made by the loaded image (for debugging) */
866  efi_wrap_image ( image );
867 
868  /* Start image */
869  efirc = bs->StartImage ( image, NULL, NULL );
870  rc = ( efirc ? -EEFI ( efirc ) : 0 );
871  DBGC ( drive, "EFIBLK %#02x boot image returned: %s\n",
872  drive, strerror ( rc ) );
873 
874  /* Remove wrapper */
875  efi_unwrap();
876 
877  err_load_security_violation:
878  bs->UnloadImage ( image );
879  err_load:
880  free ( path );
881  err_alloc:
882  return rc;
883 }
884 
885 /**
886  * Check that EFI block device is eligible for a local virtual drive number
887  *
888  * @v handle Block device handle
889  * @ret rc Return status code
890  *
891  * We assign virtual drive numbers for local (non-SAN) EFI block
892  * devices that represent complete disks, to provide roughly
893  * equivalent functionality to BIOS drive numbers.
894  */
896  struct san_device *sandev;
897  struct efi_block_data *block;
898  EFI_BLOCK_IO_PROTOCOL *blockio;
899  int rc;
900 
901  /* Check if handle belongs to a SAN device */
902  for_each_sandev ( sandev ) {
903  block = sandev->priv;
904  if ( handle == block->handle )
905  return -ENOTTY;
906  }
907 
908  /* Open block I/O protocol */
910  &blockio ) ) != 0 ) {
911  DBGC ( handle, "EFIBLK %s could not open block I/O: %s\n",
912  efi_handle_name ( handle ), strerror ( rc ) );
913  return rc;
914  }
915 
916  /* Do not assign drive numbers for partitions */
917  if ( blockio->Media->LogicalPartition ) {
918  DBGC2 ( handle, "EFLBLK %s is a partition\n",
919  efi_handle_name ( handle ) );
920  return -ENOTTY;
921  }
922 
923  return 0;
924 }
925 
926 /**
927  * Boot from EFI block device
928  *
929  * @v drive Drive number
930  * @v config Boot configuration parameters
931  * @ret rc Return status code
932  */
933 static int efi_block_boot ( unsigned int drive,
934  struct san_boot_config *config ) {
936  EFI_DEVICE_PATH_PROTOCOL *fspath = NULL;
937  EFI_HANDLE *handles;
939  UINTN count;
940  struct san_device *sandev;
941  struct efi_block_data *block;
942  unsigned int vdrive;
943  unsigned int index;
944  EFI_STATUS efirc;
945  int rc;
946 
947  /* Ensure that any local drives are connected */
949 
950  /* Release SNP devices */
951  efi_snp_release();
952 
953  /* Locate all block I/O protocol handles */
954  if ( ( efirc = bs->LocateHandleBuffer ( ByProtocol,
956  NULL, &count,
957  &handles ) ) != 0 ) {
958  rc = -EEFI ( efirc );
959  DBGC ( drive, "EFIBLK %#02x cannot locate block I/O: %s\n",
960  drive, strerror ( rc ) );
961  goto err_locate_block_io;
962  }
963 
964  /* Try booting from the first matching block device, if any */
965  rc = -ENOENT;
966  for ( vdrive = 0, index = 0 ; ; vdrive++ ) {
967 
968  /* Identify next drive number and block I/O handle */
969  if ( ( sandev = sandev_next ( vdrive ) ) &&
970  ( ( sandev->drive == vdrive ) ||
971  ( sandev->drive <= SAN_DEFAULT_DRIVE ) ||
972  ( index >= count ) ) ) {
973 
974  /* There is a SAN drive that either:
975  *
976  * a) has the current virtual drive number, or
977  * b) has a drive number below SAN_DEFAULT_DRIVE, or
978  * c) has a drive number higher than any local drive
979  *
980  * Use this SAN drive, since the explicit SAN
981  * drive numbering takes precedence over the
982  * implicit local drive numbering.
983  */
984  block = sandev->priv;
985  handle = block->handle;
986 
987  /* Use SAN drive's explicit drive number */
988  vdrive = sandev->drive;
989  DBGC ( vdrive, "EFIBLK %#02x is SAN drive %s\n",
990  vdrive, efi_handle_name ( handle ) );
991 
992  } else if ( index < count ) {
993 
994  /* There is no SAN drive meeting any of the
995  * above criteria. Try the next block I/O
996  * handle.
997  */
998  handle = handles[index++];
999 
1000  /* Check if this handle is eligible to be
1001  * given a local virtual drive number.
1002  *
1003  * Do not record this as the overall error
1004  * status, since it is not an interesting
1005  * error.
1006  */
1007  if ( efi_block_local ( handle ) != 0 ) {
1008  /* Do not consume virtual drive number */
1009  vdrive--;
1010  continue;
1011  }
1012 
1013  /* Use the current virtual drive number, with
1014  * a minimum of SAN_DEFAULT_DRIVE to match
1015  * typical BIOS drive numbering.
1016  */
1017  if ( vdrive < SAN_DEFAULT_DRIVE )
1018  vdrive = SAN_DEFAULT_DRIVE;
1019  DBGC ( vdrive, "EFIBLK %#02x is local drive %s\n",
1020  vdrive, efi_handle_name ( handle ) );
1021 
1022  } else {
1023 
1024  /* No more SAN or local drives */
1025  break;
1026  }
1027 
1028  /* Skip non-matching drives */
1029  if ( drive && ( drive != vdrive ) )
1030  continue;
1031  DBGC ( vdrive, "EFIBLK %#02x attempting to boot\n", vdrive );
1032 
1033  /* Scan for a matching filesystem within this drive */
1034  if ( ( rc = efi_block_scan ( vdrive, handle, config,
1035  &fspath ) ) != 0 ) {
1036  continue;
1037  }
1038 
1039  /* Attempt to boot from the matched filesystem */
1040  rc = efi_block_exec ( vdrive, fspath, config->filename );
1041  break;
1042  }
1043 
1044  bs->FreePool ( handles );
1045  err_locate_block_io:
1046  efi_snp_claim();
1047  return rc;
1048 }
1049 
static int efi_block_describe(void)
Describe EFI block devices.
Definition: efi_block.c:471
#define EFI_REMOVABLE_MEDIA_FILE_NAME
Definition: ProcessorBind.h:74
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:221
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:408
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:96
#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:75
EFI_GUID efi_file_system_info_id
File system information GUID.
Definition: efi_guid.c:465
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:243
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:173
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:182
EFI_BLOCK_IO_PROTOCOL block_io
Block I/O protocol.
Definition: efi_block.c:81
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:895
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:73
#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:83
unsigned long tmp
Definition: linux_pci.h:64
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:657
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:336
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:66
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:420
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:806
static void efi_block_unhook(unsigned int drive)
Unhook EFI block device.
Definition: efi_block.c:357
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:933
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:131
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:443
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:550
static wchar_t efi_block_boot_filename[]
Boot filename.
Definition: efi_block.c:70
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:168
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
void efi_wrap_image(EFI_HANDLE handle)
Wrap calls made by a newly loaded image.
Definition: efi_wrap.c:1566
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:748
EFI_HANDLE handle
EFI handle.
Definition: efi_block.c:77
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:406
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:156
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
Definition: efi_path.c:919
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:144
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:204
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:593
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:357
Block IO protocol as defined in the UEFI 2.0 specification.
Reference counting.
EFI_BLOCK_IO_MEDIA media
Media descriptor.
Definition: efi_block.c:79
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:516
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
void efi_unwrap(void)
Remove boot services table wrapper.
Definition: efi_wrap.c:1542
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 driver interface.
EFI_DEVICE_PATH_PROTOCOL * efi_path_end(EFI_DEVICE_PATH_PROTOCOL *path)
Find end of device path.
Definition: efi_path.c:162
PROVIDE_SANBOOT(efi, san_hook, efi_block_hook)
An installed ACPI table.
Definition: efi_block.c:404
int efi_path_guid(EFI_DEVICE_PATH_PROTOCOL *path, union uuid *guid)
Get partition GUID from device path.
Definition: efi_path.c:260
The EFI_FILE_PROTOCOL provides file IO access to supported file systems.
union @391 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