static efi_status_t EFIAPI efi_get_time(struct efi_time *time, struct efi_time_cap *capabilities) { #if defined(CONFIG_CMD_DATE) && defined(CONFIG_DM_RTC) struct rtc_time tm; int r; struct udevice *dev; EFI_ENTRY("%p %p", time, capabilities); r = uclass_get_device(UCLASS_RTC, 0, &dev); if (r) return EFI_EXIT(EFI_DEVICE_ERROR); r = dm_rtc_get(dev, &tm); if (r) return EFI_EXIT(EFI_DEVICE_ERROR); memset(time, 0, sizeof(*time)); time->year = tm.tm_year; time->month = tm.tm_mon; time->day = tm.tm_mday; time->hour = tm.tm_hour; time->minute = tm.tm_min; time->daylight = tm.tm_isdst; return EFI_EXIT(EFI_SUCCESS); #else return EFI_DEVICE_ERROR; #endif }
static efi_status_t EFIAPI efi_file_getpos(struct efi_file_handle *file, efi_uintn_t *pos) { struct file_handle *fh = to_fh(file); EFI_ENTRY("%p, %p", file, pos); if (fh->offset <= SIZE_MAX) { *pos = fh->offset; return EFI_EXIT(EFI_SUCCESS); } else { return EFI_EXIT(EFI_DEVICE_ERROR); } }
static efi_status_t EFIAPI efi_file_open(struct efi_file_handle *file, struct efi_file_handle **new_handle, s16 *file_name, u64 open_mode, u64 attributes) { struct file_handle *fh = to_fh(file); EFI_ENTRY("%p, %p, \"%ls\", %llx, %llu", file, new_handle, file_name, open_mode, attributes); *new_handle = file_open(fh->fs, fh, file_name, open_mode); if (!*new_handle) return EFI_EXIT(EFI_NOT_FOUND); return EFI_EXIT(EFI_SUCCESS); }
static efi_status_t EFIAPI efi_file_delete(struct efi_file_handle *file) { struct file_handle *fh = to_fh(file); EFI_ENTRY("%p", file); file_close(fh); return EFI_EXIT(EFI_WARN_DELETE_FAILURE); }
static efi_status_t EFIAPI efi_file_read(struct efi_file_handle *file, efi_uintn_t *buffer_size, void *buffer) { struct file_handle *fh = to_fh(file); efi_status_t ret = EFI_SUCCESS; u64 bs; EFI_ENTRY("%p, %p, %p", file, buffer_size, buffer); if (!buffer_size || !buffer) { ret = EFI_INVALID_PARAMETER; goto error; } if (set_blk_dev(fh)) { ret = EFI_DEVICE_ERROR; goto error; } bs = *buffer_size; if (fh->isdir) ret = dir_read(fh, &bs, buffer); else ret = file_read(fh, &bs, buffer); if (bs <= SIZE_MAX) *buffer_size = bs; else *buffer_size = SIZE_MAX; error: return EFI_EXIT(ret); }
/* * Append device path node. * * This function implements the AppendDeviceNode service of the device path * utilities protocol. * * See the Unified Extensible Firmware Interface (UEFI) specification * for details. * * @device_path device path * @device_node device node * @return concatenated device path */ static struct efi_device_path * EFIAPI append_device_node( const struct efi_device_path *device_path, const struct efi_device_path *device_node) { EFI_ENTRY("%pD, %p", device_path, device_node); return EFI_EXIT(efi_dp_append_node(device_path, device_node)); }
/* * Append device path. * * This function implements the AppendDevicePath service of the device path * utilities protocol. * * See the Unified Extensible Firmware Interface (UEFI) specification * for details. * * @src1 1st device path * @src2 2nd device path * @return concatenated device path */ static struct efi_device_path * EFIAPI append_device_path( const struct efi_device_path *src1, const struct efi_device_path *src2) { EFI_ENTRY("%pD, %pD", src1, src2); return EFI_EXIT(efi_dp_append(src1, src2)); }
static efi_status_t EFIAPI efi_file_write(struct efi_file_handle *file, efi_uintn_t *buffer_size, void *buffer) { struct file_handle *fh = to_fh(file); efi_status_t ret = EFI_SUCCESS; loff_t actwrite; EFI_ENTRY("%p, %p, %p", file, buffer_size, buffer); if (set_blk_dev(fh)) { ret = EFI_DEVICE_ERROR; goto error; } if (fs_write(fh->path, (ulong)buffer, fh->offset, *buffer_size, &actwrite)) { ret = EFI_DEVICE_ERROR; goto error; } *buffer_size = actwrite; fh->offset += actwrite; error: return EFI_EXIT(ret); }
/* * Create device node. * * This function implements the CreateDeviceNode service of the device path * utilities protocol. * * See the Unified Extensible Firmware Interface (UEFI) specification * for details. * * @node_type node type * @node_sub_type node sub type * @node_length node length * @return device path node */ static struct efi_device_path * EFIAPI create_device_node( uint8_t node_type, uint8_t node_sub_type, uint16_t node_length) { EFI_ENTRY("%u, %u, %u", node_type, node_sub_type, node_length); return EFI_EXIT(efi_dp_create_device_node(node_type, node_sub_type, node_length)); }
/* * Get next device path instance. * * This function implements the GetNextDevicePathInstance service of the device * path utilities protocol. * * See the Unified Extensible Firmware Interface (UEFI) specification * for details. * * @device_path_instance next device path instance * @device_path_instance_size size of the device path instance * @return concatenated device path */ static struct efi_device_path * EFIAPI get_next_device_path_instance( struct efi_device_path **device_path_instance, efi_uintn_t *device_path_instance_size) { EFI_ENTRY("%pD, %p", device_path_instance, device_path_instance_size); return EFI_EXIT(efi_dp_get_next_instance(device_path_instance, device_path_instance_size)); }
static efi_status_t EFIAPI efi_file_setinfo(struct efi_file_handle *file, const efi_guid_t *info_type, efi_uintn_t buffer_size, void *buffer) { EFI_ENTRY("%p, %p, %zu, %p", file, info_type, buffer_size, buffer); return EFI_EXIT(EFI_UNSUPPORTED); }
/* * Get size of a device path. * * This function implements the GetDevicePathSize service of the device path * utilities protocol. The device path length includes the end of path tag * which may be an instance end. * * See the Unified Extensible Firmware Interface (UEFI) specification * for details. * * @device_path device path * @return size in bytes */ static efi_uintn_t EFIAPI get_device_path_size( const struct efi_device_path *device_path) { efi_uintn_t sz = 0; EFI_ENTRY("%pD", device_path); /* size includes the END node: */ if (device_path) sz = efi_dp_size(device_path) + sizeof(struct efi_device_path); return EFI_EXIT(sz); }
static efi_status_t EFIAPI efi_file_open(struct efi_file_handle *file, struct efi_file_handle **new_handle, u16 *file_name, u64 open_mode, u64 attributes) { struct file_handle *fh = to_fh(file); efi_status_t ret; EFI_ENTRY("%p, %p, \"%ls\", %llx, %llu", file, new_handle, (wchar_t *)file_name, open_mode, attributes); /* Check parameters */ if (!file || !new_handle || !file_name) { ret = EFI_INVALID_PARAMETER; goto out; } if (open_mode != EFI_FILE_MODE_READ && open_mode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE) && open_mode != (EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE)) { ret = EFI_INVALID_PARAMETER; goto out; } /* * The UEFI spec requires that attributes are only set in create mode. * The SCT does not care about this and sets EFI_FILE_DIRECTORY in * read mode. EDK2 does not check that attributes are zero if not in * create mode. * * So here we only check attributes in create mode and do not check * that they are zero otherwise. */ if ((open_mode & EFI_FILE_MODE_CREATE) && (attributes & (EFI_FILE_READ_ONLY | ~EFI_FILE_VALID_ATTR))) { ret = EFI_INVALID_PARAMETER; goto out; } /* Open file */ *new_handle = file_open(fh->fs, fh, file_name, open_mode, attributes); if (*new_handle) ret = EFI_SUCCESS; else ret = EFI_NOT_FOUND; out: return EFI_EXIT(ret); }
/** * efi_file_getpos() - get current position in file * * This function implements the GetPosition service of the EFI file protocol. * See the UEFI spec for details. * * @file: file handle * @pos: pointer to file position * Return: status code */ static efi_status_t EFIAPI efi_file_getpos(struct efi_file_handle *file, u64 *pos) { efi_status_t ret = EFI_SUCCESS; struct file_handle *fh = to_fh(file); EFI_ENTRY("%p, %p", file, pos); if (fh->isdir) { ret = EFI_UNSUPPORTED; goto out; } *pos = fh->offset; out: return EFI_EXIT(ret); }
static void EFIAPI efi_reset_system(enum efi_reset_type reset_type, efi_status_t reset_status, unsigned long data_size, void *reset_data) { EFI_ENTRY("%d %lx %lx %p", reset_type, reset_status, data_size, reset_data); switch (reset_type) { case EFI_RESET_COLD: case EFI_RESET_WARM: do_reset(NULL, 0, 0, NULL); break; case EFI_RESET_SHUTDOWN: /* We don't have anything to map this to */ break; } EFI_EXIT(EFI_SUCCESS); }
static efi_status_t EFIAPI efi_file_delete(struct efi_file_handle *file) { struct file_handle *fh = to_fh(file); efi_status_t ret = EFI_SUCCESS; EFI_ENTRY("%p", file); if (set_blk_dev(fh)) { ret = EFI_DEVICE_ERROR; goto error; } if (fs_unlink(fh->path)) ret = EFI_DEVICE_ERROR; file_close(fh); error: return EFI_EXIT(ret); }
static efi_status_t EFIAPI efi_file_setpos(struct efi_file_handle *file, efi_uintn_t pos) { struct file_handle *fh = to_fh(file); efi_status_t ret = EFI_SUCCESS; EFI_ENTRY("%p, %zu", file, pos); if (fh->isdir) { if (pos != 0) { ret = EFI_UNSUPPORTED; goto error; } fs_closedir(fh->dirs); fh->dirs = NULL; } if (pos == ~0ULL) { loff_t file_size; if (set_blk_dev(fh)) { ret = EFI_DEVICE_ERROR; goto error; } if (fs_size(fh->path, &file_size)) { ret = EFI_DEVICE_ERROR; goto error; } pos = file_size; } fh->offset = pos; error: return EFI_EXIT(ret); }
static efi_status_t EFIAPI efi_file_close(struct efi_file_handle *file) { struct file_handle *fh = to_fh(file); EFI_ENTRY("%p", file); return EFI_EXIT(file_close(fh)); }
static efi_status_t EFIAPI efi_file_flush(struct efi_file_handle *file) { EFI_ENTRY("%p", file); return EFI_EXIT(EFI_SUCCESS); }
static efi_status_t EFIAPI efi_file_getinfo(struct efi_file_handle *file, const efi_guid_t *info_type, efi_uintn_t *buffer_size, void *buffer) { struct file_handle *fh = to_fh(file); efi_status_t ret = EFI_SUCCESS; EFI_ENTRY("%p, %p, %p, %p", file, info_type, buffer_size, buffer); if (!guidcmp(info_type, &efi_file_info_guid)) { struct efi_file_info *info = buffer; char *filename = basename(fh); unsigned int required_size; loff_t file_size; /* check buffer size: */ required_size = sizeof(*info) + 2 * (strlen(filename) + 1); if (*buffer_size < required_size) { *buffer_size = required_size; ret = EFI_BUFFER_TOO_SMALL; goto error; } if (set_blk_dev(fh)) { ret = EFI_DEVICE_ERROR; goto error; } if (fs_size(fh->path, &file_size)) { ret = EFI_DEVICE_ERROR; goto error; } memset(info, 0, required_size); info->size = required_size; info->file_size = file_size; info->physical_size = file_size; if (fh->isdir) info->attribute |= EFI_FILE_DIRECTORY; ascii2unicode((u16 *)info->file_name, filename); } else if (!guidcmp(info_type, &efi_file_system_info_guid)) { struct efi_file_system_info *info = buffer; disk_partition_t part; efi_uintn_t required_size; int r; if (fh->fs->part >= 1) r = part_get_info(fh->fs->desc, fh->fs->part, &part); else r = part_get_info_whole_disk(fh->fs->desc, &part); if (r < 0) { ret = EFI_DEVICE_ERROR; goto error; } required_size = sizeof(info) + 2 * (strlen((const char *)part.name) + 1); if (*buffer_size < required_size) { *buffer_size = required_size; ret = EFI_BUFFER_TOO_SMALL; goto error; } memset(info, 0, required_size); info->size = required_size; info->read_only = true; info->volume_size = part.size * part.blksz; info->free_space = 0; info->block_size = part.blksz; /* * TODO: The volume label is not available in U-Boot. * Use the partition name as substitute. */ ascii2unicode((u16 *)info->volume_label, (const char *)part.name); } else { ret = EFI_UNSUPPORTED; } error: return EFI_EXIT(ret); }
/* * Duplicate a device path. * * This function implements the DuplicateDevicePath service of the device path * utilities protocol. * * The UEFI spec does not indicate what happens to the end tag. We follow the * EDK2 logic: In case the device path ends with an end of instance tag, the * copy will also end with an end of instance tag. * * See the Unified Extensible Firmware Interface (UEFI) specification * for details. * * @device_path device path * @return copy of the device path */ static struct efi_device_path * EFIAPI duplicate_device_path( const struct efi_device_path *device_path) { EFI_ENTRY("%pD", device_path); return EFI_EXIT(efi_dp_dup(device_path)); }
/* * Check if a device path contains more than one instance. * * This function implements the AppendDeviceNode service of the device path * utilities protocol. * * See the Unified Extensible Firmware Interface (UEFI) specification * for details. * * @device_path device path * @device_node device node * @return concatenated device path */ static bool EFIAPI is_device_path_multi_instance( const struct efi_device_path *device_path) { EFI_ENTRY("%pD", device_path); return EFI_EXIT(efi_dp_is_multi_instance(device_path)); }