/*
 * Copyright (C) 2012, 2017, Red Hat Inc.
 *
 * This allocator provides contiguous physical addresses with page
 * granularity.
 */

#include "libcflat.h"
#include "asm/spinlock.h"
#include "asm/page.h"
#include "asm/io.h"
#include "alloc.h"
#include "alloc_phys.h"
#include "alloc_page.h"
#include "vmalloc.h"

static struct spinlock lock;
static void *vfree_top = 0;
static void *page_root;

void *alloc_vpages(ulong nr)
{
	spin_lock(&lock);
	vfree_top -= PAGE_SIZE * nr;
	spin_unlock(&lock);
	return vfree_top;
}

void *alloc_vpage(void)
{
	return alloc_vpages(1);
}

void init_alloc_vpage(void *top)
{
	vfree_top = top;
}

void *vmap(phys_addr_t phys, size_t size)
{
	void *mem, *p;
	unsigned pages;

	size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
	pages = size / PAGE_SIZE;
	mem = p = alloc_vpages(pages);

	phys &= ~(unsigned long long)(PAGE_SIZE - 1);
	while (pages--) {
		install_page(page_root, phys, p);
		phys += PAGE_SIZE;
		p += PAGE_SIZE;
	}
	return mem;
}

static void *vm_memalign(size_t alignment, size_t size)
{
	void *mem, *p;
	unsigned pages;

	assert(alignment <= PAGE_SIZE);
	size = (size + PAGE_SIZE - 1) & ~(PAGE_SIZE - 1);
	pages = size / PAGE_SIZE;
	mem = p = alloc_vpages(pages);
	while (pages--) {
		phys_addr_t pa = virt_to_phys(alloc_page());
		install_page(page_root, pa, p);
		p += PAGE_SIZE;
	}
	return mem;
}

static void vm_free(void *mem, size_t size)
{
	while (size) {
		free_page(phys_to_virt(virt_to_pte_phys(page_root, mem)));
		mem += PAGE_SIZE;
		size -= PAGE_SIZE;
	}
}

static struct alloc_ops vmalloc_ops = {
	.memalign = vm_memalign,
	.free = vm_free,
	.align_min = PAGE_SIZE,
};

void __attribute__((__weak__)) find_highmem(void)
{
}

void setup_vm()
{
	phys_addr_t base, top;

	if (alloc_ops == &vmalloc_ops)
		return;

	phys_alloc_get_unused(&base, &top);
	assert(base != top || page_alloc_initialized());
	/*
	 * Give low memory immediately to the page allocator,
	 * so that it can be used to allocate page tables.
	 */
	if (!page_alloc_initialized()) {
		base = (base + PAGE_SIZE - 1) & -PAGE_SIZE;
		top = top & -PAGE_SIZE;
		free_pages(phys_to_virt(base), top - base);
	}

	find_highmem();
	phys_alloc_get_unused(&base, &top);
	page_root = setup_mmu(top);
	if (base != top) {
		base = (base + PAGE_SIZE - 1) & -PAGE_SIZE;
		top = top & -PAGE_SIZE;
		free_pages(phys_to_virt(base), top - base);
	}

	alloc_ops = &vmalloc_ops;
}
