162 DBGC2 ( sandev->
drive,
"EFIBLK %#02x read LBA %#08llx to %p+%#08zx\n",
188 DBGC2 ( sandev->
drive,
"EFIBLK %#02x write LBA %#08llx from " 229 DBGC (
drive,
"EFIBLK %#02x could not connect drivers: %s\n",
270 block->media.MediaPresent = 1;
271 block->media.LogicalBlocksPerPhysicalBlock = 1;
281 DBGC (
drive,
"EFIBLK %#02x could not register: %s\n",
287 block->media.BlockSize =
289 block->media.LastBlock =
295 DBGC (
drive,
"EFIBLK %#02x not active after registration\n",
300 if ( !
block->path ) {
305 DBGC2 (
drive,
"EFIBLK %#02x has device path %s\n",
315 DBGC (
drive,
"EFIBLK %#02x could not install protocols: %s\n",
319 DBGC (
drive,
"EFIBLK %#02x installed as SAN drive %s\n",
332 DBGC (
drive,
"EFIBLK %#02x could not uninstall protocols: " 382 DBGC (
drive,
"EFIBLK %#02x could not uninstall protocols: " 430 installed =
zalloc (
sizeof ( *installed ) );
438 strncpy (
hdr->oem_table_id,
"iPXE", sizeof (
hdr->oem_table_id ) );
445 &installed->
key ) ) != 0 ){
447 DBGC (
acpi,
"EFIBLK could not install %s: %s\n",
456 DBGC (
acpi,
"EFIBLK installed %s as ACPI table %#lx\n",
458 ( (
unsigned long ) installed->
key ) );
483 DBG (
"EFIBLK has no ACPI table protocol\n" );
492 DBGC (
acpi,
"EFIBLK could not uninstall ACPI table " 493 "%#lx: %s\n", ( (
unsigned long )
key ),
503 DBGC (
acpi,
"EFIBLK could not install ACPI tables: %s\n",
535 DBGC (
drive,
"EFIBLK %#02x could not open %s filesystem: %s\n",
541 if ( ( efirc =
u.fs->OpenVolume (
u.fs,
root ) ) != 0 ) {
543 DBGC (
drive,
"EFIBLK %#02x could not open %s root: %s\n",
568 const char *filename ) {
584 if ( ( efirc =
root->Open (
root, &file, wname,
587 DBGC (
drive,
"EFIBLK %#02x could not open %s/%ls: %s\n",
596 file->
Close ( file );
610 const char *
label ) {
632 DBGC (
drive,
"EFIBLK %#02x could not get filesystem info: " 638 if (
asprintf ( &actual,
"%ls",
info->VolumeLabel ) < 0 ) {
640 goto err_alloc_label;
645 DBGC (
drive,
"EFIBLK %#02x has wrong label \"%s\"\n",
693 DBGC (
drive,
"EFIBLK %#02x could not open %s device path: " 704 DBGC2 (
drive,
"EFIBLK %#02x is not parent of %s\n",
708 DBGC (
drive,
"EFIBLK %#02x contains filesystem %s\n",
712 if ( config->
uuid ) {
714 DBGC (
drive,
"EFIBLK %#02x could not determine GUID: " 719 DBGC (
drive,
"EFIBLK %#02x has wrong GUID %s\n",
737 if ( config->
extra &&
739 config->
extra ) ) != 0 ) ) {
744 if ( config->
label &&
746 config->
label ) ) != 0 ) ) {
798 DBGC (
drive,
"EFIBLK %#02x could not open device path: %s\n",
808 DBGC (
drive,
"EFIBLK %#02x cannot locate file systems: %s\n",
815 for ( i = 0 ; i <
count ; i++ ) {
819 config, fspath ) ) != 0 )
842 const char *filename ) {
856 fspath_len = ( ( (
void * )
end ) - ( (
void * ) fspath ) );
859 ( (
strlen ( filename ) + 1 ) *
860 sizeof ( filepath->
PathName[0] ) ) :
862 path_len = ( fspath_len + filepath_len +
sizeof ( *end ) );
863 path =
zalloc ( path_len );
868 memcpy ( path, fspath, fspath_len );
869 filepath = ( ( (
void * ) path ) + fspath_len );
880 end = ( ( (
void * ) filepath ) + filepath_len );
882 DBGC (
drive,
"EFIBLK %#02x trying to load %s\n",
890 DBGC (
drive,
"EFIBLK %#02x could not load: %s\n",
893 goto err_load_security_violation;
901 rc = ( efirc ? -
EEFI ( efirc ) : 0 );
902 DBGC (
drive,
"EFIBLK %#02x boot image returned: %s\n",
905 err_load_security_violation:
949 DBGC (
handle,
"EFIBLK %s could not open block I/O: %s\n",
955 if (
u.blockio->Media->LogicalPartition ) {
1003 &handles ) ) != 0 ) {
1005 DBGC (
drive,
"EFIBLK %#02x cannot locate block I/O: %s\n",
1007 goto err_locate_block_io;
1012 for ( vdrive = 0,
index = 0 ; ; vdrive++ ) {
1035 DBGC ( vdrive,
"EFIBLK %#02x is SAN drive %s\n",
1065 DBGC ( vdrive,
"EFIBLK %#02x is local drive %s\n",
1077 DBGC ( vdrive,
"EFIBLK %#02x attempting to boot\n", vdrive );
1081 &fspath ) ) != 0 ) {
1091 err_locate_block_io:
static int efi_block_describe(void)
Describe EFI block devices.
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 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.
#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.
128 bit buffer containing a unique identifier value.
static int sandev_rw(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer, int(*block_rw)(struct interface *control, struct interface *data, uint64_t lba, unsigned int count, userptr_t buffer, size_t len))
Read from or write to SAN device.
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.
uint8_t size
Entry size (in 32-bit words)
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.
static int efi_block_rw(struct san_device *sandev, uint64_t lba, void *data, size_t len, int(*sandev_rw)(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer))
Read from or write to EFI block device.
EFI_CLOSE_PROTOCOL CloseProtocol
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.
uint32_t userptr_t
A pointer to a user buffer.
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.
uint16_t 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 EFI_OPEN_PROTOCOL_GET_PROTOCOL
#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.
int sandev_read(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Read from SAN device.
static LIST_HEAD(efi_acpi_tables)
List of installed ACPI tables.
EFI_UNINSTALL_MULTIPLE_PROTOCOL_INTERFACES UninstallMultipleProtocolInterfaces
EFI_CONNECT_CONTROLLER ConnectController
#define ENODEV
No such device.
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.
#define VOID
Undeclared type.
void * malloc(size_t size)
Allocate memory.
const char * uuid_ntoa(const union uuid *uuid)
Convert UUID to printable string.
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.
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)
userptr_t virt_to_user(volatile const void *addr)
Convert virtual address to user pointer.
#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
EFI_OPEN_PROTOCOL OpenProtocol
uint16_t protocol
Protocol ID.
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.
#define DBG(...)
Print a debugging message.
int memcmp(const void *first, const void *second, size_t len)
Compare memory regions.
#define NULL
NULL pointer (VOID *)
int sandev_write(struct san_device *sandev, uint64_t lba, unsigned int count, userptr_t buffer)
Write to SAN device.
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.