Ejemplo n.º 1
0
static file_info_t *find_file_info_from_uuid(const uuid_t *uuid)
{
	int index;

	for (index = 0; index < file_info_count; index++) {
		if (compare_uuids(&files[index].name_uuid, uuid) == 0) {
			return &files[index];
		}
	}
	return NULL;
}
Ejemplo n.º 2
0
static entry_lookup_list_t *get_entry_lookup_from_uuid(const uuid_t *uuid)
{
	unsigned int lookup_index = 0;

	while (toc_entry_lookup_list[lookup_index].command_line_name != NULL) {
		if (compare_uuids(&toc_entry_lookup_list[lookup_index].name_uuid,
		    uuid) == 0) {
			return &toc_entry_lookup_list[lookup_index];
		}
		lookup_index++;
	}
	return NULL;
}
Ejemplo n.º 3
0
/* Open a file for access from package. */
static int fip_file_open(io_dev_info_t *dev_info, const uintptr_t spec,
			 io_entity_t *entity)
{
	int result;
	uintptr_t backend_handle;
	const io_uuid_spec_t *uuid_spec = (io_uuid_spec_t *)spec;
	size_t bytes_read;
	int found_file = 0;

	assert(uuid_spec != NULL);
	assert(entity != NULL);

	/* Can only have one file open at a time for the moment. We need to
	 * track state like file cursor position. We know the header lives at
	 * offset zero, so this entry should never be zero for an active file.
	 * When the system supports dynamic memory allocation we can allow more
	 * than one open file at a time if needed.
	 */
	if (current_file.entry.offset_address != 0) {
		WARN("fip_file_open : Only one open file at a time.\n");
		return -ENOMEM;
	}

	/* Attempt to access the FIP image */
	result = io_open(backend_dev_handle, backend_image_spec,
			 &backend_handle);
	if (result != 0) {
		WARN("Failed to open Firmware Image Package (%i)\n", result);
		result = -ENOENT;
		goto fip_file_open_exit;
	}

	/* Seek past the FIP header into the Table of Contents */
	result = io_seek(backend_handle, IO_SEEK_SET, sizeof(fip_toc_header_t));
	if (result != 0) {
		WARN("fip_file_open: failed to seek\n");
		result = -ENOENT;
		goto fip_file_open_close;
	}

	found_file = 0;
	do {
		result = io_read(backend_handle,
				 (uintptr_t)&current_file.entry,
				 sizeof(current_file.entry),
				 &bytes_read);
		if (result == 0) {
			if (compare_uuids(&current_file.entry.uuid,
					  &uuid_spec->uuid) == 0) {
				found_file = 1;
				break;
			}
		} else {
			WARN("Failed to read FIP (%i)\n", result);
			goto fip_file_open_close;
		}
	} while (compare_uuids(&current_file.entry.uuid, &uuid_null) != 0);

	if (found_file == 1) {
		/* All fine. Update entity info with file state and return. Set
		 * the file position to 0. The 'current_file.entry' holds the
		 * base and size of the file.
		 */
		current_file.file_pos = 0;
		entity->info = (uintptr_t)&current_file;
	} else {
		/* Did not find the file in the FIP. */
		current_file.entry.offset_address = 0;
		result = -ENOENT;
	}

 fip_file_open_close:
	io_close(backend_handle);

 fip_file_open_exit:
	return result;
}
Ejemplo n.º 4
0
/* Read and load existing package into memory. */
static int parse_fip(const char *fip_filename)
{
	FILE *fip;
	char *fip_buffer;
	char *fip_buffer_end;
	int fip_size, read_fip_size;
	fip_toc_header_t *toc_header;
	fip_toc_entry_t *toc_entry;
	bool found_last_toc_entry = false;
	file_info_t *file_info_entry;
	int status = -1;
	struct stat st;

	fip = fopen(fip_filename, "r");
	if (fip == NULL) {
		/* If the fip does not exist just return, it should not be
		 * considered as an error. The package will be created later
		 */
		status = 0;
		goto parse_fip_return;
	}

	if (stat(fip_filename, &st) != 0) {
		status = errno;
		goto parse_fip_fclose;
	} else {
		fip_size = (int)st.st_size;
	}

	/* Allocate a buffer to read the package */
	fip_buffer = (char *)malloc(fip_size);
	if (fip_buffer == NULL) {
		printf("ERROR: Cannot allocate %d bytes.\n", fip_size);
		status = errno;
		goto parse_fip_fclose;
	}
	fip_buffer_end = fip_buffer + fip_size;

	/* Read the file */
	read_fip_size = fread(fip_buffer, sizeof(char), fip_size, fip);
	if (read_fip_size != fip_size) {
		printf("ERROR: Cannot read the FIP.\n");
		status = EIO;
		goto parse_fip_free;
	}
	fclose(fip);
	fip = NULL;

	/* The package must at least contain the ToC Header */
	if (fip_size < sizeof(fip_toc_header_t)) {
		printf("ERROR: Given FIP is smaller than the ToC header.\n");
		status = EINVAL;
		goto parse_fip_free;
	}
	/* Set the ToC Header at the base of the buffer */
	toc_header = (fip_toc_header_t *)fip_buffer;
	/* The first toc entry should be just after the ToC header */
	toc_entry = (fip_toc_entry_t *)(toc_header + 1);

	/* While the ToC entry is contained into the buffer */
	int cnt = 0;
	while (((char *)toc_entry + sizeof(fip_toc_entry_t)) < fip_buffer_end) {
		cnt++;
		/* Check if the ToC Entry is the last one */
		if (compare_uuids(&toc_entry->uuid, &uuid_null) == 0) {
			found_last_toc_entry = true;
			status = 0;
			break;
		}

		/* Add the entry into file_info */

		/* Get the new entry in the array and clear it */
		file_info_entry = &files[file_info_count++];
		memset(file_info_entry, 0, sizeof(file_info_t));

		/* Copy the info from the ToC entry */
		copy_uuid(&file_info_entry->name_uuid, &toc_entry->uuid);
		file_info_entry->image_buffer = fip_buffer +
		  toc_entry->offset_address;
		file_info_entry->size = toc_entry->size;

		/* Check if there is a corresponding entry in lookup table */
		file_info_entry->entry =
		  get_entry_lookup_from_uuid(&toc_entry->uuid);

		/* Go to the next ToC entry */
		toc_entry++;
	}

	if (!found_last_toc_entry) {
		printf("ERROR: Given FIP does not have an end ToC entry.\n");
		status = EINVAL;
		goto parse_fip_free;
	} else {
		/* All is well, we should not free any of the loaded images */
		goto parse_fip_fclose;
	}

 parse_fip_free:
	if (fip_buffer != NULL) {
		free(fip_buffer);
		fip_buffer = NULL;
	}

 parse_fip_fclose:
	if (fip != NULL) {
		fclose(fip);
	}

 parse_fip_return:
	return status;
}