/* Copyright (c) 2009, 2010 The Regents of the University of California.
 * Copyright (c) 2016 Google Inc
 * See LICENSE for details.
 *
 * Barret Rhoden <brho@cs.berkeley.edu>
 * Kevin Klues <klueska@cs.berkeley.edu> */

#include <page_alloc.h>
#include <pmap.h>
#include <kmalloc.h>
#include <arena.h>

/* Helper, allocates a free page. */
static struct page *get_a_free_page(void)
{
	void *addr;

	addr = kpages_alloc(PGSIZE, MEM_ATOMIC);
	if (!addr)
		return NULL;
	return kva2page(addr);
}

/**
 * @brief Allocates a physical page from a pool of unused physical memory.
 *
 * Zeroes the page.
 *
 * @param[out] page  set to point to the Page struct
 *                   of the newly allocated page
 *
 * @return ESUCCESS on success
 * @return -ENOMEM  otherwise
 */
error_t upage_alloc(struct proc *p, page_t **page, bool zero)
{
	struct page *pg = get_a_free_page();

	if (!pg)
		return -ENOMEM;
	*page = pg;
	if (zero)
		memset(page2kva(*page), 0, PGSIZE);
	return 0;
}

error_t kpage_alloc(page_t **page)
{
	struct page *pg = get_a_free_page();

	if (!pg)
		return -ENOMEM;
	*page = pg;
	return 0;
}

/* Helper: allocates a refcounted page of memory for the kernel's use and
 * returns the kernel address (kernbase), or 0 on error. */
void *kpage_alloc_addr(void)
{
	struct page *pg = get_a_free_page();

	if (!pg)
		return 0;
	return page2kva(pg);
}

void *kpage_zalloc_addr(void)
{
	void *retval = kpage_alloc_addr();
	if (retval)
		memset(retval, 0, PGSIZE);
	return retval;
}

/* Helper function for allocating from the kpages_arena.  This may be useful
 * later since we might send the caller to a different NUMA domain. */
void *kpages_alloc(size_t size, int flags)
{
	return arena_alloc(kpages_arena, size, flags);
}

void *kpages_zalloc(size_t size, int flags)
{
	void *ret = arena_alloc(kpages_arena, size, flags);

	if (!ret)
		return NULL;
	memset(ret, 0, size);
	return ret;
}

void kpages_free(void *addr, size_t size)
{
	arena_free(kpages_arena, addr, size);
}

/* Returns naturally aligned, contiguous pages of amount PGSIZE << order.  Linux
 * code might assume its allocations are aligned. (see dma_alloc_coherent and
 * bnx2x). */
void *get_cont_pages(size_t order, int flags)
{
	return arena_xalloc(kpages_arena, PGSIZE << order, PGSIZE << order,
	                    0, 0, NULL, NULL, flags);
}

void free_cont_pages(void *buf, size_t order)
{
	arena_xfree(kpages_arena, buf, PGSIZE << order);
}

/* Frees the page */
void page_decref(page_t *page)
{
	assert(!page_is_pagemap(page));
	kpages_free(page2kva(page), PGSIZE);
}

/* Attempts to get a lock on the page for IO operations.  If it is already
 * locked, it will block the kthread until it is unlocked.  Note that this is
 * really a "sleep on some event", not necessarily the IO, but it is "the page
 * is ready". */
void lock_page(struct page *page)
{
	/* when this returns, we have are the ones to have locked the page */
	sem_down(&page->pg_sem);
	assert(!(atomic_read(&page->pg_flags) & PG_LOCKED));
	atomic_or(&page->pg_flags, PG_LOCKED);
}

/* Unlocks the page, and wakes up whoever is waiting on the lock */
void unlock_page(struct page *page)
{
	atomic_and(&page->pg_flags, ~PG_LOCKED);
	sem_up(&page->pg_sem);
}

static void *__jumbo_pml2_alloc(struct arena *a, size_t size, int flags)
{
	return arena_xalloc(a, size, PML2_PTE_REACH, 0, 0, NULL, NULL, flags);
}

static struct arena *jumbo_pml2_arena;

/* Just for example; we could add qcaches too.  Do this after kmalloc_init(). */
void jumbo_arena_init(void)
{
	jumbo_pml2_arena = arena_create("jumbo_pml2", NULL, 0, PML2_PTE_REACH,
	                                __jumbo_pml2_alloc, arena_xfree,
	                                base_arena, 0, MEM_WAIT);
	assert(jumbo_pml2_arena);
}

void *jumbo_page_alloc(size_t nr, int flags)
{
	return arena_alloc(jumbo_pml2_arena, nr * PML2_PTE_REACH, flags);
}

void jumbo_page_free(void *buf, size_t nr)
{
	arena_free(jumbo_pml2_arena, buf, nr * PML2_PTE_REACH);
}
