/*
 * Copyright 2013 Google Inc.
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but without any warranty; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

#include <assert.h>
#include <stdint.h>

#include "base/coreboot/sysinfo.h"
#include "base/coreboot/tables.h"
#include "base/device_tree.h"
#include "base/fwdb.h"
#include "base/init_funcs.h"
#include "base/memory.h"

static int install_coreboot_data(DeviceTreeFixup *fixup, DeviceTree *tree)
{
	uint32_t addr_cells = 1, size_cells = 1;
	const char *firmware_path[] = { "firmware", NULL };
	DeviceTreeNode *firmware_node = dt_find_node(tree->root,
		firmware_path, &addr_cells, &size_cells, 1);

	// Need to add 'ranges' to the intermediate node to make 'reg' work.
	dt_add_bin_prop(firmware_node, "ranges", NULL, 0);

	const char *coreboot_path[] = { "coreboot", NULL };
	DeviceTreeNode *coreboot_node = dt_find_node(firmware_node,
		coreboot_path, &addr_cells, &size_cells, 1);

	dt_add_string_prop(coreboot_node, "compatible", "coreboot");

	E820MemRanges *e820 = get_e820_mem_ranges();
	if (!e820)
		return 1;

	E820MemRange *cbmem_range = NULL;
	for (int i = e820->num_ranges - 1; i >= 0; i--) {
		E820MemRange *range = &e820->ranges[i];
		if (range->handoff_tag == CB_MEM_TABLE) {
			cbmem_range = range;
			break;
		}
	}
	if (!cbmem_range)
		return 1;

	uint64_t reg_addrs[2];
	uint64_t reg_sizes[2];

	// First 'reg' address range is the coreboot table.
	reg_addrs[0] = (uintptr_t)get_sysinfo()->header;
	reg_sizes[0] = get_sysinfo()->header->header_bytes +
		       get_sysinfo()->header->table_bytes;

	// Second is the CBMEM area (which usually includes the coreboot table).
	reg_addrs[1] = cbmem_range->base;
	reg_sizes[1] = cbmem_range->size;

	dt_add_reg_prop(coreboot_node, reg_addrs, reg_sizes, 2,
			addr_cells, size_cells);

	// Expose board ID and RAM code exported from coreboot to userspace.
	if (get_sysinfo()->board_id != ~0) {
		dt_add_u32_prop(coreboot_node,
				"board-id", get_sysinfo()->board_id);
	}
	FwdbEntry ram_code_entry;
	if (fwdb_access("coreboot.ram_code", &ram_code_entry, NULL)) {
		uint32_t ram_code;
		assert(sizeof(ram_code) == ram_code_entry.size);
		ram_code = *(typeof(ram_code) *)ram_code_entry.ptr;
		dt_add_u32_prop(coreboot_node, "ram-code", ram_code);
	}

	return 0;
}

static DeviceTreeFixup coreboot_fixup = {
	.fixup = &install_coreboot_data
};

static int coreboot_setup(void)
{
	list_insert_after(&coreboot_fixup.list_node, &device_tree_fixups);
	return 0;
}

INIT_FUNC(coreboot_setup);
