163 DBGC2 ( sandev->
drive,
"EFIBLK %#02x read LBA %#08llx to %p+%#08zx\n",
189 DBGC2 ( sandev->
drive,
"EFIBLK %#02x write LBA %#08llx from " 226 DBGC (
drive,
"EFIBLK %#02x could not connect drivers: %s\n",
267 block->media.MediaPresent = 1;
268 block->media.LogicalBlocksPerPhysicalBlock = 1;
278 DBGC (
drive,
"EFIBLK %#02x could not register: %s\n",
284 block->media.BlockSize =
286 block->media.LastBlock =
292 DBGC (
drive,
"EFIBLK %#02x not active after registration\n",
297 if ( !
block->path ) {
302 DBGC2 (
drive,
"EFIBLK %#02x has device path %s\n",
312 DBGC (
drive,
"EFIBLK %#02x could not install protocols: %s\n",
316 DBGC (
drive,
"EFIBLK %#02x installed as SAN drive %s\n",
329 DBGC (
drive,
"EFIBLK %#02x could not uninstall protocols: " 379 DBGC (
drive,
"EFIBLK %#02x could not uninstall protocols: " 427 installed =
zalloc (
sizeof ( *installed ) );
435 strncpy (
hdr->oem_table_id,
"iPXE", sizeof (
hdr->oem_table_id ) );
442 &installed->
key ) ) != 0 ){
444 DBGC (
acpi,
"EFIBLK could not install %s: %s\n",
453 DBGC (
acpi,
"EFIBLK installed %s as ACPI table %#lx\n",
455 ( (
unsigned long ) installed->
key ) );
480 DBG (
"EFIBLK has no ACPI table protocol\n" );
489 DBGC (
acpi,
"EFIBLK could not uninstall ACPI table " 490 "%#lx: %s\n", ( (
unsigned long )
key ),
500 DBGC (
acpi,
"EFIBLK could not install ACPI tables: %s\n",
525 DBGC (
drive,
"EFIBLK %#02x could not open %s filesystem: %s\n",
531 if ( ( efirc =
fs->OpenVolume (
fs,
root ) ) != 0 ) {
533 DBGC (
drive,
"EFIBLK %#02x could not open %s root: %s\n",
552 const char *filename ) {
568 if ( ( efirc =
root->Open (
root, &file, wname,
571 DBGC (
drive,
"EFIBLK %#02x could not open %s/%ls: %s\n",
580 file->
Close ( file );
594 const char *
label ) {
616 DBGC (
drive,
"EFIBLK %#02x could not get filesystem info: " 622 if (
asprintf ( &actual,
"%ls",
info->VolumeLabel ) < 0 ) {
624 goto err_alloc_label;
629 DBGC (
drive,
"EFIBLK %#02x has wrong label \"%s\"\n",
668 DBGC (
drive,
"EFIBLK %#02x could not open %s device path: " 678 DBGC2 (
drive,
"EFIBLK %#02x is not parent of %s\n",
682 DBGC (
drive,
"EFIBLK %#02x contains filesystem %s\n",
686 if ( config->
uuid ) {
688 DBGC (
drive,
"EFIBLK %#02x could not determine GUID: " 693 DBGC (
drive,
"EFIBLK %#02x has wrong GUID %s\n",
711 if ( config->
extra &&
713 config->
extra ) ) != 0 ) ) {
718 if ( config->
label &&
720 config->
label ) ) != 0 ) ) {
765 DBGC (
drive,
"EFIBLK %#02x could not open device path: %s\n",
775 DBGC (
drive,
"EFIBLK %#02x cannot locate file systems: %s\n",
782 for ( i = 0 ; i <
count ; i++ ) {
786 config, fspath ) ) != 0 )
808 const char *filename ) {
822 fspath_len = ( ( (
void * )
end ) - ( (
void * ) fspath ) );
825 ( (
strlen ( filename ) + 1 ) *
826 sizeof ( filepath->
PathName[0] ) ) :
828 path_len = ( fspath_len + filepath_len +
sizeof ( *end ) );
829 path =
zalloc ( path_len );
834 memcpy ( path, fspath, fspath_len );
835 filepath = ( ( (
void * ) path ) + fspath_len );
846 end = ( ( (
void * ) filepath ) + filepath_len );
848 DBGC (
drive,
"EFIBLK %#02x trying to load %s\n",
856 DBGC (
drive,
"EFIBLK %#02x could not load: %s\n",
859 goto err_load_security_violation;
870 rc = ( efirc ? -
EEFI ( efirc ) : 0 );
871 DBGC (
drive,
"EFIBLK %#02x boot image returned: %s\n",
877 err_load_security_violation:
910 &blockio ) ) != 0 ) {
911 DBGC (
handle,
"EFIBLK %s could not open block I/O: %s\n",
957 &handles ) ) != 0 ) {
959 DBGC (
drive,
"EFIBLK %#02x cannot locate block I/O: %s\n",
961 goto err_locate_block_io;
966 for ( vdrive = 0,
index = 0 ; ; vdrive++ ) {
989 DBGC ( vdrive,
"EFIBLK %#02x is SAN drive %s\n",
1019 DBGC ( vdrive,
"EFIBLK %#02x is local drive %s\n",
1031 DBGC ( vdrive,
"EFIBLK %#02x attempting to boot\n", vdrive );
1035 &fspath ) ) != 0 ) {
1045 err_locate_block_io:
static int efi_block_describe(void)
Describe EFI block devices.
#define EFI_REMOVABLE_MEDIA_FILE_NAME
EFI_BOOT_SERVICES * BootServices
A pointer to the EFI Boot Services Table.
#define EINVAL
Invalid argument.
The EFI_ACPI_TABLE_PROTOCOL provides the ability for a component to install and uninstall ACPI tables...
int sandev_reset(struct san_device *sandev)
Reset SAN device.
struct arbelprm_rc_send_wqe rc
static void efi_block_connect(unsigned int drive, EFI_HANDLE handle)
Connect all possible drivers to EFI block device.
#define EEFI(efirc)
Convert an EFI status code to an iPXE status code.
EFI_ACPI_TABLE_INSTALL_ACPI_TABLE InstallAcpiTable
int efi_connect(EFI_HANDLE device, EFI_HANDLE driver)
Connect UEFI driver(s)
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.
#define le32_to_cpu(value)
struct stp_switch root
Root switch.
struct san_device * sandev
SAN device.
EFI_GUID efi_file_system_info_id
File system information GUID.
struct golan_inbox_hdr hdr
Message header.
static int efi_block_hook(unsigned int drive, struct uri **uris, unsigned int count, unsigned int flags)
Hook EFI block device.
uint16_t size
Buffer size.
void unregister_sandev(struct san_device *sandev)
Unregister SAN device.
int san_boot(unsigned int drive, struct san_boot_config *config)
Attempt to boot from a SAN device.
This protocol provides control over block devices.
struct interface block
Underlying block device interface.
#define ENOENT
No such file or directory.
EFI_INSTALL_MULTIPLE_PROTOCOL_INTERFACES InstallMultipleProtocolInterfaces
unsigned long long uint64_t
int strcasecmp(const char *first, const char *second)
Compare case-insensitive strings.
size_t efi_path_len(EFI_DEVICE_PATH_PROTOCOL *path)
Find length of device path (excluding terminator)
static void sandev_put(struct san_device *sandev)
Drop reference to SAN device.
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.
EFI_BLOCK_IO_PROTOCOL block_io
Block I/O protocol.
uint32_t buffer
Buffer index (or NETVSC_RNDIS_NO_BUFFER)
EFI_IMAGE_UNLOAD UnloadImage
static int efi_block_local(EFI_HANDLE handle)
Check that EFI block device is eligible for a local virtual drive number.
uint8_t drive
Drive number.
This protocol can be used on any device handle to obtain generic path/location information concerning...
CHAR16 PathName[1]
A NULL-terminated Path string including directory and file names.
static void efi_snp_claim(void)
Claim network devices for use by iPXE.
EFI_DEVICE_PATH_PROTOCOL Header
Uniform Resource Identifiers.
EFI SAN device private data.
#define ENOTSUP
Operation not supported.
A doubly-linked list entry (or list head)
static void efi_path_terminate(EFI_DEVICE_PATH_PROTOCOL *end)
Terminate device path.
Data transfer interfaces.
EFI_DEVICE_PATH_PROTOCOL * path
Device path protocol.
char * strncpy(char *dest, const char *src, size_t max)
Copy string.
#define list_del(list)
Delete an entry from a list.
#define ENOMEM
Not enough space.
#define EFI_BLOCK_IO_PROTOCOL_REVISION3
void * memcpy(void *dest, const void *src, size_t len) __nonnull
EFI_ACPI_TABLE_UNINSTALL_ACPI_TABLE UninstallAcpiTable
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.
void efi_driver_reconnect_all(void)
Reconnect original EFI drivers to all possible devices.
#define container_of(ptr, type, field)
Get containing structure.
SimpleFileSystem protocol as defined in the UEFI 2.0 specification.
EFI_GUID efi_simple_file_system_protocol_guid
Simple file system protocol GUID.
UINT64 EFI_LBA
Logical block address.
#define __unused
Declare a variable or data structure as unused.
#define list_add_tail(new, head)
Add a new entry to the tail of a list.
static EFI_ACPI_TABLE_PROTOCOL * acpi
ACPI table protocol protocol.
unsigned int drive
Drive number.
SAN boot configuration parameters.
union uuid * uuid
UUID (or NULL to ignore UUID)
int register_sandev(struct san_device *sandev, unsigned int drive, unsigned int flags)
Register SAN device.
static int efi_block_install(struct acpi_header *hdr)
Install ACPI table.
static int efi_block_exec(unsigned int drive, EFI_DEVICE_PATH_PROTOCOL *fspath, const char *filename)
Boot from EFI block device filesystem boot image.
static void efi_block_unhook(unsigned int drive)
Unhook EFI block device.
int efi_snprintf(wchar_t *wbuf, size_t wsize, const char *fmt,...)
Write a formatted string to a buffer.
static unsigned int count
Number of entries.
const char * filename
Boot filename (or NULL to use default)
unsigned int blksize_shift
Block size shift.
static int efi_block_boot(unsigned int drive, struct san_boot_config *config)
Boot from EFI block device.
void acpi_fix_checksum(struct acpi_header *acpi)
Fix up ACPI table checksum.
#define SIZE_OF_FILEPATH_DEVICE_PATH
EFI_REQUEST_PROTOCOL(EFI_ACPI_TABLE_PROTOCOL, &acpi)
uint64_t blocks
Total number of blocks.
ISO9660 CD-ROM specification.
const char * efi_devpath_text(EFI_DEVICE_PATH_PROTOCOL *path)
Get textual representation of device path.
#define list_for_each_entry_safe(pos, tmp, head, member)
Iterate over entries in a list, safe against deletion of the current entry.
int acpi_install(int(*install)(struct acpi_header *acpi))
Install ACPI tables.
const char * efi_handle_name(EFI_HANDLE handle)
Get name of an EFI handle.
static EFI_STATUS EFIAPI efi_block_io_reset(EFI_BLOCK_IO_PROTOCOL *block_io, BOOLEAN verify __unused)
Reset EFI block device.
char * strerror(int errno)
Retrieve string representation of error number.
static void(* free)(struct refcnt *refcnt))
void * zalloc(size_t size)
Allocate cleared memory.
#define efi_sprintf(buf, fmt,...)
Write a formatted string to a buffer.
EFI_HANDLE efi_image_handle
Image handle passed to entry point.
int asprintf(char **strp, const char *fmt,...)
Write a formatted string to newly allocated memory.
static LIST_HEAD(efi_acpi_tables)
List of installed ACPI tables.
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
#define ENODEV
No such device.
#define efi_open(handle, protocol, interface)
Open protocol for ephemeral use.
static void efi_snp_release(void)
Release network devices for use via SNP.
size_t strlen(const char *src)
Get length of string.
const char * label
Filesystem label (or NULL to ignore volume label)
uint64_t lba
Starting block number.
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.
static wchar_t efi_block_boot_filename[]
Boot filename.
Data transfer interface opening.
EFI_IMAGE_START StartImage
#define MEDIA_DEVICE_PATH
UINT64 UINTN
Unsigned value of native width.
#define for_each_sandev(sandev)
Iterate over all SAN devices.
struct san_device * sandev_next(unsigned int drive)
Find next SAN device by drive number.
EFI_GUID efi_device_path_protocol_guid
Device path protocol GUID.
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.
#define VOID
Undeclared type.
void * malloc(size_t size)
Allocate memory.
const char * uuid_ntoa(const union uuid *uuid)
Convert UUID to printable string.
void efi_wrap_image(EFI_HANDLE handle)
Wrap calls made by a newly loaded image.
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.
EFI_HANDLE handle
EFI handle.
#define EFI_SECURITY_VIOLATION
Enumeration of EFI_STATUS.
EFI_BLOCK_IO_MEDIA * Media
Pointer to the EFI_BLOCK_IO_MEDIA data for this device.
struct block_device_capacity capacity
Raw block device capacity.
struct list_head list
List of installed tables.
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.
EFI_DEVICE_PATH_PROTOCOL * efi_describe(struct interface *intf)
Describe object as an EFI device path.
UINT8 Length[2]
Specific Device Path data.
struct san_device * sandev_find(unsigned int drive)
Find SAN device by drive number.
EFI_GUID efi_block_io_protocol_guid
Block I/O protocol GUID.
uint8_t block[3][8]
DES-encrypted blocks.
#define ENOTTY
Inappropriate I/O control operation.
static EFI_STATUS EFIAPI efi_block_io_flush(EFI_BLOCK_IO_PROTOCOL *block_io)
Flush data to EFI block device.
const char * extra
Required extra filename (or NULL to ignore)
#define EFI_FILE_MODE_READ
void efi_nullify_block(EFI_BLOCK_IO_PROTOCOL *block)
Nullify block I/O protocol.
void * priv
Driver private data.
RETURN_STATUS EFI_STATUS
Function return status for EFI API.
UINT8 SubType
Varies by Type 0xFF End Entire Device Path, or 0x01 End This Instance of a Device Path and start a ne...
static int efi_block_label(unsigned int drive, EFI_FILE_PROTOCOL *root, const char *label)
Check for EFI block device filesystem label.
static const char * acpi_name(uint32_t signature)
Transcribe ACPI table signature (for debugging)
#define DBGC2_EFI_PROTOCOLS(...)
Block IO protocol as defined in the UEFI 2.0 specification.
EFI_BLOCK_IO_MEDIA media
Media descriptor.
uint32_t end
Ending offset.
uint8_t data[48]
Additional event data.
UINT8 Type
0x01 Hardware Device Path.
Retrieve the set of handles from the handle database that support a specified protocol.
A Uniform Resource Identifier.
EFI_SYSTEM_TABLE * efi_systab
struct san_path * active
Current active path.
#define SAN_DEFAULT_DRIVE
Default SAN drive number.
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.
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer)
Read from SAN device.
#define DBG(...)
Print a debugging message.
void efi_unwrap(void)
Remove boot services table wrapper.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
#define NULL
NULL pointer (VOID *)
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.
PROVIDE_SANBOOT(efi, san_hook, efi_block_hook)
int efi_path_guid(EFI_DEVICE_PATH_PROTOCOL *path, union uuid *guid)
Get partition GUID from device path.
The EFI_FILE_PROTOCOL provides file IO access to supported file systems.
#define EFIRC(rc)
Convert an iPXE status code to an EFI status code.
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.
EFI_LOCATE_HANDLE_BUFFER LocateHandleBuffer
size_t blksize
Block size.
int efi_shutdown_in_progress
EFI shutdown is in progress.
#define MEDIA_FILEPATH_DP
File Path Media Device Path SubType.
int sandev_write(struct san_device *sandev, uint64_t lba, unsigned int count, void *buffer)
Write to SAN device.