// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright (c) 2011 The Chromium OS Authors. All rights reserved.
 */

#include <common.h>
#include <cbfs.h>
#include <log.h>
#include <malloc.h>
#include <asm/byteorder.h>

/* Offset of master header from the start of a coreboot ROM */
#define MASTER_HDR_OFFSET	0x38

static const u32 good_magic = 0x4f524243;
static const u8 good_file_magic[] = "LARCHIVE";

/**
 * struct cbfs_priv - Private data for this driver
 *
 * @initialised: true if this CBFS has been inited
 * @start: Start position of CBFS in memory, typically memory-mapped SPI flash
 * @header: Header read from the CBFS, byte-swapped so U-Boot can access it
 * @file_cache: List of file headers read from CBFS
 * @result: Success/error result
 */
struct cbfs_priv {
	bool initialized;
	void *start;
	struct cbfs_header header;
	struct cbfs_cachenode *file_cache;
	enum cbfs_result result;
};

static struct cbfs_priv cbfs_s;

const char *file_cbfs_error(void)
{
	switch (cbfs_s.result) {
	case CBFS_SUCCESS:
		return "Success";
	case CBFS_NOT_INITIALIZED:
		return "CBFS not initialized";
	case CBFS_BAD_HEADER:
		return "Bad CBFS header";
	case CBFS_BAD_FILE:
		return "Bad CBFS file";
	case CBFS_FILE_NOT_FOUND:
		return "File not found";
	default:
		return "Unknown";
	}
}

enum cbfs_result cbfs_get_result(void)
{
	return cbfs_s.result;
}

/* Do endian conversion on the CBFS header structure. */
static void swap_header(struct cbfs_header *dest, struct cbfs_header *src)
{
	dest->magic = be32_to_cpu(src->magic);
	dest->version = be32_to_cpu(src->version);
	dest->rom_size = be32_to_cpu(src->rom_size);
	dest->boot_block_size = be32_to_cpu(src->boot_block_size);
	dest->align = be32_to_cpu(src->align);
	dest->offset = be32_to_cpu(src->offset);
}

/* Do endian conversion on a CBFS file header. */
static void swap_file_header(struct cbfs_fileheader *dest,
			     const struct cbfs_fileheader *src)
{
	memcpy(&dest->magic, &src->magic, sizeof(dest->magic));
	dest->len = be32_to_cpu(src->len);
	dest->type = be32_to_cpu(src->type);
	dest->attributes_offset = be32_to_cpu(src->attributes_offset);
	dest->offset = be32_to_cpu(src->offset);
}

/*
 * Given a starting position in memory, scan forward, bounded by a size, and
 * find the next valid CBFS file. No memory is allocated by this function. The
 * caller is responsible for allocating space for the new file structure.
 *
 * @param start		The location in memory to start from.
 * @param size		The size of the memory region to search.
 * @param align		The alignment boundaries to check on.
 * @param new_node	A pointer to the file structure to load.
 * @param used		A pointer to the count of of bytes scanned through,
 *			including the file if one is found.
 *
 * @return 0 if a file is found, -ENOENT if one isn't, -EBADF if a bad header
 *	is found.
 */
static int file_cbfs_next_file(struct cbfs_priv *priv, void *start, int size,
			       int align, struct cbfs_cachenode *new_node,
			       int *used)
{
	struct cbfs_fileheader header;

	*used = 0;

	while (size >= align) {
		const struct cbfs_fileheader *file_header = start;
		u32 name_len;
		u32 step;

		/* Check if there's a file here. */
		if (memcmp(good_file_magic, &file_header->magic,
			   sizeof(file_header->magic))) {
			*used += align;
			size -= align;
			start += align;
			continue;
		}

		swap_file_header(&header, file_header);
		if (header.offset < sizeof(struct cbfs_fileheader)) {
			priv->result = CBFS_BAD_FILE;
			return -EBADF;
		}
		new_node->next = NULL;
		new_node->type = header.type;
		new_node->data = start + header.offset;
		new_node->data_length = header.len;
		name_len = header.offset - sizeof(struct cbfs_fileheader);
		new_node->name = (char *)file_header +
				sizeof(struct cbfs_fileheader);
		new_node->name_length = name_len;
		new_node->attributes_offset = header.attributes_offset;

		step = header.len;
		if (step % align)
			step = step + align - step % align;

		*used += step;
		return 0;
	}

	return -ENOENT;
}

/* Look through a CBFS instance and copy file metadata into regular memory. */
static int file_cbfs_fill_cache(struct cbfs_priv *priv, int size, int align)
{
	struct cbfs_cachenode *cache_node;
	struct cbfs_cachenode *new_node;
	struct cbfs_cachenode **cache_tail = &priv->file_cache;
	void *start;

	/* Clear out old information. */
	cache_node = priv->file_cache;
	while (cache_node) {
		struct cbfs_cachenode *old_node = cache_node;
		cache_node = cache_node->next;
		free(old_node);
	}
	priv->file_cache = NULL;

	start = priv->start;
	while (size >= align) {
		int used;
		int ret;

		new_node = (struct cbfs_cachenode *)
				malloc(sizeof(struct cbfs_cachenode));
		if (!new_node)
			return -ENOMEM;
		ret = file_cbfs_next_file(priv, start, size, align, new_node,
					  &used);

		if (ret < 0) {
			free(new_node);
			if (ret == -ENOENT)
				break;
			return ret;
		}
		*cache_tail = new_node;
		cache_tail = &new_node->next;

		size -= used;
		start += used;
	}
	priv->result = CBFS_SUCCESS;

	return 0;
}

/**
 * load_header() - Load the CBFS header
 *
 * Get the CBFS header out of the ROM and do endian conversion.
 *
 * @priv: Private data, which is inited by this function
 * @addr: Address of CBFS header in memory-mapped SPI flash
 * @return 0 if OK, -ENXIO if the header is bad
 */
static int load_header(struct cbfs_priv *priv, ulong addr)
{
	struct cbfs_header *header = &priv->header;
	struct cbfs_header *header_in_rom;

	memset(priv, '\0', sizeof(*priv));
	header_in_rom = (struct cbfs_header *)addr;
	swap_header(header, header_in_rom);

	if (header->magic != good_magic || header->offset >
			header->rom_size - header->boot_block_size) {
		priv->result = CBFS_BAD_HEADER;
		return -ENXIO;
	}

	return 0;
}

/**
 * file_cbfs_load_header() - Get the CBFS header out of the ROM, given the end
 *
 * @priv: Private data, which is inited by this function
 * @end_of_rom: Address of the last byte of the ROM (typically 0xffffffff)
 * @return 0 if OK, -ENXIO if the header is bad
 */
static int file_cbfs_load_header(struct cbfs_priv *priv, ulong end_of_rom)
{
	int offset = *(u32 *)(end_of_rom - 3);
	int ret;

	ret = load_header(priv, end_of_rom + offset + 1);
	if (ret)
		return ret;
	priv->start = (void *)(end_of_rom + 1 - priv->header.rom_size);

	return 0;
}

/**
 * cbfs_load_header_ptr() - Get the CBFS header out of the ROM, given the base
 *
 * @priv: Private data, which is inited by this function
 * @base: Address of the first byte of the ROM (e.g. 0xff000000)
 * @return 0 if OK, -ENXIO if the header is bad
 */
static int cbfs_load_header_ptr(struct cbfs_priv *priv, ulong base)
{
	int ret;

	ret = load_header(priv, base + MASTER_HDR_OFFSET);
	if (ret)
		return ret;
	priv->start = (void *)base;

	return 0;
}

static int cbfs_init(struct cbfs_priv *priv, ulong end_of_rom)
{
	int ret;

	ret = file_cbfs_load_header(priv, end_of_rom);
	if (ret)
		return ret;

	ret = file_cbfs_fill_cache(priv, priv->header.rom_size,
				   priv->header.align);
	if (ret)
		return ret;
	priv->initialized = true;

	return 0;
}

int file_cbfs_init(ulong end_of_rom)
{
	return cbfs_init(&cbfs_s, end_of_rom);
}

int cbfs_init_mem(ulong base, struct cbfs_priv **privp)
{
	struct cbfs_priv priv_s, *priv = &priv_s;
	int ret;

	/*
	 * Use a local variable to start with until we know that the CBFS is
	 * valid.
	 */
	ret = cbfs_load_header_ptr(priv, base);
	if (ret)
		return ret;

	ret = file_cbfs_fill_cache(priv, priv->header.rom_size,
				   priv->header.align);
	if (ret)
		return log_msg_ret("fill", ret);

	priv->initialized = true;
	priv = malloc(sizeof(priv_s));
	if (!priv)
		return -ENOMEM;
	memcpy(priv, &priv_s, sizeof(priv_s));
	*privp = priv;

	return 0;
}

const struct cbfs_header *file_cbfs_get_header(void)
{
	struct cbfs_priv *priv = &cbfs_s;

	if (priv->initialized) {
		priv->result = CBFS_SUCCESS;
		return &priv->header;
	} else {
		priv->result = CBFS_NOT_INITIALIZED;
		return NULL;
	}
}

const struct cbfs_cachenode *file_cbfs_get_first(void)
{
	struct cbfs_priv *priv = &cbfs_s;

	if (!priv->initialized) {
		priv->result = CBFS_NOT_INITIALIZED;
		return NULL;
	} else {
		priv->result = CBFS_SUCCESS;
		return priv->file_cache;
	}
}

void file_cbfs_get_next(const struct cbfs_cachenode **file)
{
	struct cbfs_priv *priv = &cbfs_s;

	if (!priv->initialized) {
		priv->result = CBFS_NOT_INITIALIZED;
		*file = NULL;
		return;
	}

	if (*file)
		*file = (*file)->next;
	priv->result = CBFS_SUCCESS;
}

const struct cbfs_cachenode *cbfs_find_file(struct cbfs_priv *priv,
					    const char *name)
{
	struct cbfs_cachenode *cache_node = priv->file_cache;

	if (!priv->initialized) {
		priv->result = CBFS_NOT_INITIALIZED;
		return NULL;
	}

	while (cache_node) {
		if (!strcmp(name, cache_node->name))
			break;
		cache_node = cache_node->next;
	}
	if (!cache_node)
		priv->result = CBFS_FILE_NOT_FOUND;
	else
		priv->result = CBFS_SUCCESS;

	return cache_node;
}

const struct cbfs_cachenode *file_cbfs_find(const char *name)
{
	return cbfs_find_file(&cbfs_s, name);
}

static int find_uncached(struct cbfs_priv *priv, const char *name, void *start,
			 struct cbfs_cachenode *node)
{
	int size = priv->header.rom_size;
	int align = priv->header.align;

	while (size >= align) {
		int used;
		int ret;

		ret = file_cbfs_next_file(priv, start, size, align, node,
					  &used);
		if (ret == -ENOENT)
			break;
		else if (ret)
			return ret;
		if (!strcmp(name, node->name))
			return 0;

		size -= used;
		start += used;
	}
	priv->result = CBFS_FILE_NOT_FOUND;

	return -ENOENT;
}

int file_cbfs_find_uncached(ulong end_of_rom, const char *name,
			    struct cbfs_cachenode *node)
{
	struct cbfs_priv priv;
	void *start;
	int ret;

	ret = file_cbfs_load_header(&priv, end_of_rom);
	if (ret)
		return ret;
	start = priv.start;

	return find_uncached(&priv, name, start, node);
}

int file_cbfs_find_uncached_base(ulong base, const char *name,
				 struct cbfs_cachenode *node)
{
	struct cbfs_priv priv;
	int ret;

	ret = cbfs_load_header_ptr(&priv, base);
	if (ret)
		return ret;

	return find_uncached(&priv, name, (void *)base, node);
}

const char *file_cbfs_name(const struct cbfs_cachenode *file)
{
	cbfs_s.result = CBFS_SUCCESS;

	return file->name;
}

u32 file_cbfs_size(const struct cbfs_cachenode *file)
{
	cbfs_s.result = CBFS_SUCCESS;

	return file->data_length;
}

u32 file_cbfs_type(const struct cbfs_cachenode *file)
{
	cbfs_s.result = CBFS_SUCCESS;

	return file->type;
}

long file_cbfs_read(const struct cbfs_cachenode *file, void *buffer,
		    unsigned long maxsize)
{
	u32 size;

	size = file->data_length;
	if (maxsize && size > maxsize)
		size = maxsize;

	memcpy(buffer, file->data, size);
	cbfs_s.result = CBFS_SUCCESS;

	return size;
}
