/*
 * Copyright 2013, Google Inc.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are
 * met:
 *
 *    * Redistributions of source code must retain the above copyright
 * notice, this list of conditions and the following disclaimer.
 *    * Redistributions in binary form must reproduce the above
 * copyright notice, this list of conditions and the following disclaimer
 * in the documentation and/or other materials provided with the
 * distribution.
 *    * Neither the name of Google Inc. nor the names of its
 * contributors may be used to endorse or promote products derived from
 * this software without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 *
 * Alternatively, this software may be distributed under the terms of the
 * GNU General Public License ("GPL") version 2 as published by the Free
 * Software Foundation.
 */

#include <ctype.h>
#include <stdint.h>
#include <stdlib.h>
#include <zlib.h>

#include "flash.h"
#include "fdtmap.h"
#include "flash.h"
#include "libfdt.h"
#include "layout.h"

#ifdef DEBUG
#define debug(a, b...) printf(a, ##b)
#else
#define debug(a, b...)
#endif

/* An entry in the flashmap - we only care about the offset and length */
struct fmap_entry {
	uint32_t offset;
	uint32_t length;
};

/**
 * Look up a property in a node and check that it has a minimum length.
 *
 * @blob: FDT blob
 * @node: node to examine
 * @prop_name: name of property to find
 * @min_len: minimum property length in bytes
 * @err: 0 if ok, or -FDT_ERR_NOTFOUND if the property is not
			found, or -FDT_ERR_BADLAYOUT if not enough data
 * @return pointer to cell, which is only valid if err == 0
 */
static const void *get_prop_check_min_len(const void *blob, int node,
		const char *prop_name, int min_len, int *err)
{
	const void *cell;
	int len;

	debug("%s: %s\n", __func__, prop_name);
	cell = fdt_getprop(blob, node, prop_name, &len);
	if (!cell)
		*err = -FDT_ERR_NOTFOUND;
	else if (len < min_len)
		*err = -FDT_ERR_BADLAYOUT;
	else
		*err = 0;
	return cell;
}

static int fdtdec_get_int_array(const void *blob, int node,
		const char *prop_name, uint32_t *array, int count)
{
	const uint32_t *cell;
	int i, err = 0;

	debug("%s: %s\n", __func__, prop_name);
	cell = get_prop_check_min_len(blob, node, prop_name,
				      sizeof(uint32_t) * count, &err);
	if (!err) {
		for (i = 0; i < count; i++)
			array[i] = fdt32_to_cpu(cell[i]);
	}
	return err;
}

/**
 * Read a flash entry from the fdt
 *
 * @blob: FDT blob
 * @node: Offset of node to read
 * @name: Name of node being read
 * @entry: Place to put offset and size of this node
 * @return 0 if ok, -ve on error
 */
static int read_entry(const void *blob, int node, const char *name,
		      struct fmap_entry *entry)
{
	uint32_t reg[2];
	int ret;

	ret = fdtdec_get_int_array(blob, node, "reg", reg, 2);
	if (ret) {
		debug("Node '%s' has bad/missing 'reg' property\n", name);
		return ret;
	}
	entry->offset = reg[0];
	entry->length = reg[1];

	return 0;
}

static int scan_flashmap(const void *blob, romlayout_t *rom_entries,
			  int max_entries)
{
	int romimages;
	int offset;
	int depth;
	int node;

	offset = fdt_node_offset_by_compatible(blob, -1,
			"chromeos,flashmap");
	if (offset < 0)
		return offset;

	for (depth = romimages = 0; offset > 0 && depth >= 0; offset = node) {
		struct fmap_entry entry;
		const char *name;
		romlayout_t *rl;
		char *s;
		int ret;

		node = fdt_next_node(blob, offset, &depth);
		if (node < 0)
			return node;
		if (depth != 1)
			continue;

		name = fdt_getprop(blob, node, "label", NULL);
		ret = read_entry(blob, node, name, &entry);
		if (ret)
			return ret;

		if (romimages >= max_entries) {
			msg_gerr("ROM image contains too many regions\n");
			return -1;
		}
		rl = &rom_entries[romimages];
		rl->start = entry.offset;

		/*
		 * Flashrom rom entries use absolute addresses. So for non-zero
		 * length entries, we need to subtract 1 from offset + size to
		 * determine the end address.
		 */
		rl->end = entry.offset + entry.length;
		if (entry.length)
			rl->end--;

		/* Use an upper case name for flashrom, with _ instead of - */
		strncpy(rl->name, name, sizeof(rl->name));
		rl->name[sizeof(rl->name) - 1] = '\0';
		for (s = rl->name; *s; s++)
			if (*s == '-')
				*s = '_';
			else if (*s == '@')
				break;
			else
				*s = toupper(*s);
		*s = '\0';

		*rl->file = '\0';
		rl->included = 0;

		msg_gdbg("added fdtmap region \"%s\" (file=\"%s\") as %sincluded,"
			 " offset: 0x%08x, end: 0x%08x\n",
			  rl->name,
			  rl->file,
			  rl->included ? "" : "not ",
			  rl->start,
			  rl->end);
		romimages++;
	}

	msg_gdbg("Found %d regions\n", romimages);

	return romimages;
}

int fdtmap_add_entries_from_buf(const void *blob, romlayout_t *rom_entries,
				int max_entries)
{
	int count;

	count = scan_flashmap(blob, rom_entries, max_entries);
	if (count < 0) {
		msg_gerr("Failed to read flashmap: '%s'\n", fdt_strerror(count));
		return -1;
	}

	return count;
}

int fdtmap_find(void *source_handle,
		int (*read_chunk)(void *handle,
				  void *dest,
				  size_t offset,
				  size_t size),
		struct fdtmap_hdr *hdr,
		loff_t offset, uint8_t **buf)
{
	int fmap_size;
	uint32_t crc;

	if (memcmp(hdr->sig, FDTMAP_SIGNATURE, sizeof(hdr->sig)))
		return 0;

	msg_gdbg("%s: found possible fdtmap at offset %#lx\n",
		 __func__, (unsigned long)offset);

	fmap_size = hdr->size;
	*buf = malloc(fmap_size);
	msg_gdbg("%s: fdtmap size %#x\n", __func__, fmap_size);

	if (read_chunk(source_handle, *buf, offset + sizeof(*hdr), fmap_size)) {
		msg_gdbg("[L%d] failed to read %d bytes at offset %#lx\n",
			 __LINE__, fmap_size, (unsigned long)offset);
		return 0;
	}

	/* Sanity check, the FDT total size should equal fmap_size */
	if (fdt_totalsize(*buf) != fmap_size) {
		msg_gdbg("[L%d] FDT size %#x did not match header size %#x at %#lx\n",
			 __LINE__, fdt_totalsize(*buf),
			 fmap_size, (unsigned long)offset);
		return 0;
	}

	crc = crc32(0, Z_NULL, 0);
	crc = crc32(crc, *buf, fmap_size);
	/* Sanity check, the FDT total size should equal fmap_size */
	if (crc != hdr->crc32) {
		msg_gdbg("[L%d] CRC32 %#08x did not match expected %#08x at %#lx\n",
			 __LINE__, crc, hdr->crc32, (unsigned long)offset);
		return 0;
	}

	return 1;
}
