/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2003-2004 Eric Biederman
 * Copyright (C) 2005-2010 coresystems GmbH
 * Copyright (C) 2014 Google Inc.
 *
 * 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; version 2 of the License.
 *
 * 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.
 */

#include <console/console.h>
#include <bootmem.h>
#include <cbmem.h>
#include <device/resource.h>
#include <stdlib.h>

static struct memranges bootmem;

void bootmem_init(void)
{
	const unsigned long cacheable = IORESOURCE_CACHEABLE;
	const unsigned long reserved = IORESOURCE_RESERVE;
	struct memranges *bm = &bootmem;

	/*
	 * Fill the memory map out. The order of operations is important in
	 * that each overlapping range will take over the next. Therefore,
	 * add cacheable resources as RAM then add the reserved resources.
	 */
	memranges_init(bm, cacheable, cacheable, LB_MEM_RAM);
	memranges_add_resources(bm, reserved, reserved, LB_MEM_RESERVED);

	/* Add memory used by CBMEM. */
	cbmem_add_bootmem();
}

void bootmem_add_range(uint64_t start, uint64_t size, uint32_t type)
{
	memranges_insert(&bootmem, start, size, type);
}

void bootmem_write_memory_table(struct lb_memory *mem)
{
	const struct range_entry *r;
	struct lb_memory_range *lb_r;

	lb_r = &mem->map[0];

	bootmem_dump_ranges();

	memranges_each_entry(r, &bootmem) {
		lb_r->start = pack_lb64(range_entry_base(r));
		lb_r->size = pack_lb64(range_entry_size(r));
		lb_r->type = range_entry_tag(r);

		lb_r++;
		mem->size += sizeof(struct lb_memory_range);
	}
}

struct range_strings {
	unsigned long tag;
	const char *str;
};

static const struct range_strings type_strings[] = {
	{ LB_MEM_RAM, "RAM" },
	{ LB_MEM_RESERVED, "RESERVED" },
	{ LB_MEM_ACPI, "ACPI" },
	{ LB_MEM_NVS, "NVS" },
	{ LB_MEM_UNUSABLE, "UNUSABLE" },
	{ LB_MEM_VENDOR_RSVD, "VENDOR RESERVED" },
	{ LB_MEM_TABLE, "CONFIGURATION TABLES" },
};

static const char *bootmem_range_string(unsigned long tag)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(type_strings); i++) {
		if (type_strings[i].tag == tag)
			return type_strings[i].str;
	}

	return "UNKNOWN!";
}

void bootmem_dump_ranges(void)
{
	int i;
	const struct range_entry *r;

	i = 0;
	memranges_each_entry(r, &bootmem) {
		printk(BIOS_DEBUG, "%2d. %016llx-%016llx: %s\n",
			i, range_entry_base(r), range_entry_end(r) - 1,
			bootmem_range_string(range_entry_tag(r)));
		i++;
	}
}

int bootmem_region_targets_usable_ram(uint64_t start, uint64_t size)
{
	const struct range_entry *r;
	uint64_t end = start + size;

	memranges_each_entry(r, &bootmem) {
		/* All further bootmem entries are beyond this range. */
		if (end <= range_entry_base(r))
			break;

		if (start >= range_entry_base(r) && end <= range_entry_end(r)) {
			if (range_entry_tag(r) == LB_MEM_RAM)
				return 1;
		}
	}
	return 0;
}

void *bootmem_allocate_buffer(size_t size)
{
	const struct range_entry *r;
	const struct range_entry *region;
	/* All allocated buffers fall below the 32-bit boundary. */
	const resource_t max_addr = 1ULL << 32;
	resource_t begin;
	resource_t end;

	/* 4KiB alignment. */
	size = ALIGN(size, 4096);
	region = NULL;
	memranges_each_entry(r, &bootmem) {
		if (range_entry_size(r) < size)
			continue;

		if (range_entry_tag(r) != LB_MEM_RAM)
			continue;

		if (range_entry_base(r) >= max_addr)
			continue;

		end = range_entry_end(r);
		if (end > max_addr)
			end = max_addr;

		if ((end - range_entry_base(r)) < size)
			continue;

		region = r;
	}

	if (region == NULL)
		return NULL;

	/* region now points to the highest usable region for the given size. */
	begin = range_entry_base(region);
	end = range_entry_end(region);
	if (end > max_addr)
		end = max_addr;
	begin = end - size;

	/* Mark buffer as unusuable for future buffer use. */
	bootmem_add_range(begin, size, LB_MEM_UNUSABLE);

	return (void *)(uintptr_t)begin;
}
