示例#1
0
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
}
示例#2
0
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);
	}
}
示例#3
0
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);
}
示例#4
0
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);
}
示例#5
0
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));
}
示例#8
0
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));
}
示例#11
0
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);
}
示例#13
0
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);
}
示例#14
0
/**
 * 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);
}
示例#15
0
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);
}
示例#16
0
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);
}
示例#17
0
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);
}
示例#18
0
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));
}
示例#19
0
static efi_status_t EFIAPI efi_file_flush(struct efi_file_handle *file)
{
	EFI_ENTRY("%p", file);
	return EFI_EXIT(EFI_SUCCESS);
}
示例#20
0
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));
}