/*
 * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
 *
 * This work is licensed under the terms of the GNU LGPL, version 2.
 */
#include "alloc.h"
#include "asm/spinlock.h"
#include "asm/io.h"

#define PHYS_ALLOC_NR_REGIONS	256

struct phys_alloc_region {
	phys_addr_t base;
	phys_addr_t size;
};

static struct phys_alloc_region regions[PHYS_ALLOC_NR_REGIONS];
static int nr_regions;

static struct spinlock lock;
static phys_addr_t base, top, align_min;

void phys_alloc_show(void)
{
	int i;

	spin_lock(&lock);
	printf("phys_alloc minimum alignment: %#" PRIx64 "\n",
		(u64)align_min);
	for (i = 0; i < nr_regions; ++i)
		printf("%016" PRIx64 "-%016" PRIx64 " [%s]\n",
			(u64)regions[i].base,
			(u64)(regions[i].base + regions[i].size - 1),
			"USED");
	printf("%016" PRIx64 "-%016" PRIx64 " [%s]\n",
		(u64)base, (u64)(top - 1), "FREE");
	spin_unlock(&lock);
}

void phys_alloc_init(phys_addr_t base_addr, phys_addr_t size)
{
	spin_lock(&lock);
	base = base_addr;
	top = base + size;
	align_min = DEFAULT_MINIMUM_ALIGNMENT;
	nr_regions = 0;
	spin_unlock(&lock);
}

void phys_alloc_set_minimum_alignment(phys_addr_t align)
{
	assert(align && !(align & (align - 1)));
	spin_lock(&lock);
	align_min = align;
	spin_unlock(&lock);
}

static phys_addr_t phys_alloc_aligned_safe(phys_addr_t size,
					   phys_addr_t align, bool safe)
{
	static bool warned = false;
	phys_addr_t addr, size_orig = size;
	u64 top_safe;

	spin_lock(&lock);

	top_safe = top;

	if (safe && sizeof(long) == 4)
		top_safe = MIN(top_safe, 1ULL << 32);

	align = MAX(align, align_min);

	addr = ALIGN(base, align);
	size += addr - base;

	if ((top_safe - base) < size) {
		printf("phys_alloc: requested=%#" PRIx64
		       " (align=%#" PRIx64 "), "
		       "need=%#" PRIx64 ", but free=%#" PRIx64 ". "
		       "top=%#" PRIx64 ", top_safe=%#" PRIx64 "\n",
		       (u64)size_orig, (u64)align, (u64)size, top_safe - base,
		       (u64)top, top_safe);
		spin_unlock(&lock);
		return INVALID_PHYS_ADDR;
	}

	base += size;

	if (nr_regions < PHYS_ALLOC_NR_REGIONS) {
		regions[nr_regions].base = addr;
		regions[nr_regions].size = size_orig;
		++nr_regions;
	} else if (!warned) {
		printf("WARNING: phys_alloc: No free log entries, "
		       "can no longer log allocations...\n");
		warned = true;
	}

	spin_unlock(&lock);

	return addr;
}

static phys_addr_t phys_zalloc_aligned_safe(phys_addr_t size,
					    phys_addr_t align, bool safe)
{
	phys_addr_t addr = phys_alloc_aligned_safe(size, align, safe);
	if (addr == INVALID_PHYS_ADDR)
		return addr;

	memset(phys_to_virt(addr), 0, size);
	return addr;
}

phys_addr_t phys_alloc_aligned(phys_addr_t size, phys_addr_t align)
{
	return phys_alloc_aligned_safe(size, align, false);
}

phys_addr_t phys_zalloc_aligned(phys_addr_t size, phys_addr_t align)
{
	return phys_zalloc_aligned_safe(size, align, false);
}

phys_addr_t phys_alloc(phys_addr_t size)
{
	return phys_alloc_aligned(size, align_min);
}

phys_addr_t phys_zalloc(phys_addr_t size)
{
	return phys_zalloc_aligned(size, align_min);
}

static void *early_malloc(size_t size)
{
	phys_addr_t addr = phys_alloc_aligned_safe(size, align_min, true);
	if (addr == INVALID_PHYS_ADDR)
		return NULL;

	return phys_to_virt(addr);
}

static void *early_calloc(size_t nmemb, size_t size)
{
	phys_addr_t addr = phys_zalloc_aligned_safe(nmemb * size,
						    align_min, true);
	if (addr == INVALID_PHYS_ADDR)
		return NULL;

	return phys_to_virt(addr);
}

static void early_free(void *ptr __unused)
{
}

static void *early_memalign(size_t alignment, size_t size)
{
	phys_addr_t addr;

	assert(alignment && !(alignment & (alignment - 1)));

	addr = phys_alloc_aligned_safe(size, alignment, true);
	if (addr == INVALID_PHYS_ADDR)
		return NULL;

	return phys_to_virt(addr);
}

static struct alloc_ops early_alloc_ops = {
	.malloc = early_malloc,
	.calloc = early_calloc,
	.free = early_free,
	.memalign = early_memalign,
};

struct alloc_ops *alloc_ops = &early_alloc_ops;
