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

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

/* Helper.  Adds free entries to the base arena.  Most entries are page aligned,
 * though on some machines below EXTPHYSMEM we may have some that aren't. */
static void parse_mboot_region(struct multiboot_mmap_entry *entry, void *data)
{
	physaddr_t boot_freemem_paddr = (physaddr_t)data;
	physaddr_t start = entry->addr;
	size_t len = entry->len;
	extern char end[];

	if (entry->type != MULTIBOOT_MEMORY_AVAILABLE)
		return;
	/* Skip anything over max_paddr - might be bad entries(?) */
	if (start >= max_paddr)
		return;
	if (start + len > max_paddr)
		len = max_paddr - start;
	/* For paranoia, skip anything below EXTPHYSMEM.  If we ever change
	 * this, we'll need to deal with smp_boot's trampoline page. */
	if ((start < EXTPHYSMEM) && (start + len < EXTPHYSMEM))
		return;
	if ((start < EXTPHYSMEM) && (EXTPHYSMEM <= start + len)) {
		len = start + len - EXTPHYSMEM;
		start = EXTPHYSMEM;
	}
	/* Skip over any pages already allocated in boot_alloc().
	 * (boot_freemem_paddr is the next free addr.) */
	if ((start < boot_freemem_paddr)
	    && (boot_freemem_paddr <= start + len)) {
		len = start + len - boot_freemem_paddr;
		start = boot_freemem_paddr;
	}
	/* Skip any part that intersects with the kernel, which is linked and
	 * loaded from EXTPHYSMEM to end in kernel64.ld */
	if (regions_collide_unsafe(EXTPHYSMEM, PADDR(end), start, start + len))
	{
		len = start + len - PADDR(end);
		start = PADDR(end);
	}
	/* We need to give the arena PGSIZE-quantum segments. */
	if (PGOFF(start)) {
		len -= PGOFF(start);
		start = ROUNDUP(start, PGSIZE);
	}
	len = ROUNDDOWN(len, PGSIZE);
	if (!len)
		return;
	arena_add(base_arena, KADDR(start), len, MEM_WAIT);
}

/* Since we can't parse multiboot mmap entries, we need to just guess at what
 * pages are free and which ones aren't.
 *
 * Despite the lack of info from mbi, I know there is a magic hole in physical
 * memory that we can't use, from the IOAPIC_PBASE on up [0xfec00000,
 * 0xffffffff] (I'm being pessimistic).  But, that's not pessimistic enough!
 * Qemu still doesn't like that.   From using 0xe0000000 instead works for mine.
 * According to http://wiki.osdev.org/Memory_Map_(x86), some systems could
 * reserve from [0xc0000000, 0xffffffff].  Anyway, in lieu of real memory
 * detection, I'm just skipping that entire region.
 *
 * We may or may not have more free memory above this magic hole, depending on
 * both the amount of RAM we have as well as 32 vs 64 bit.
 *
 * So we'll go with two free memory regions:
 *
 * 	[ 0, ROUNDUP(boot_freemem_paddr, PGSIZE) ) = busy
 * 	[ ROUNDUP(boot_freemem_paddr, PGSIZE), TOP_OF_1 ) = free
 * 	[ MAGIC_HOLE, 0x0000000100000000 ) = busy
 * 	(and maybe this:)
 * 	[ 0x0000000100000000, max_paddr ) = free
 *
 * where TOP_OF_1 is the min of IOAPIC_PBASE and max_paddr.
 *
 * As with parsing mbi regions, this will ignore the hairy areas below
 * EXTPHYSMEM, and mark the entire kernel and anything we've boot alloc'd as
 * busy. */
static void account_for_pages(physaddr_t boot_freemem_paddr)
{
	physaddr_t top_of_busy = ROUNDUP(boot_freemem_paddr, PGSIZE);
	physaddr_t top_of_free_1 = MIN(0xc0000000, max_paddr);
	physaddr_t start_of_free_2;

	printk("Warning: poor memory detection (qemu?). May lose 1GB of RAM\n");
	arena_add(base_arena, KADDR(top_of_busy), top_of_free_1 - top_of_busy,
	          MEM_WAIT);
	/* If max_paddr is less than the start of our potential second free mem
	 * region, we can just leave.  We also don't want to poke around the
	 * pages array either (and accidentally run off the end of the array).
	 *
	 * Additionally, 32 bit doesn't acknowledge pmem above the 4GB mark. */
	start_of_free_2 = 0x0000000100000000;
	if (max_paddr < start_of_free_2)
		return;
	arena_add(base_arena, KADDR(start_of_free_2), max_paddr -
		  start_of_free_2, MEM_WAIT);
}

/* Initialize base arena based on available free memory.  After this, do not use
 * boot_alloc. */
void base_arena_init(struct multiboot_info *mbi)
{
	/* First, all memory is busy / not free by default.
	 *
	 * To avoid a variety of headaches, any memory below 1MB is considered
	 * busy.  Likewise, everything in the kernel, up to _end is also busy.
	 * And everything we've already boot_alloc'd is busy.  These chunks of
	 * memory are reported as 'free' by multiboot.  All of this memory is
	 * below boot_freemem_paddr.  We don't treat anything below that as
	 * free.
	 *
	 * We'll also abort the mapping for any addresses over max_paddr, since
	 * we'll never use them.  'pages' does not track them either.
	 *
	 * One special note: we actually use the memory at 0x1000 for smp_boot.
	 * It'll never get freed; just FYI. */
	physaddr_t boot_freemem_paddr;
	void *base_pg;

	/* Need to do the boot-allocs before our last look at the top of
	 * boot_freemem. */
	base_pg = boot_alloc(PGSIZE, PGSHIFT);
	base_arena = arena_builder(base_pg, "base", PGSIZE, NULL, NULL, NULL,
	                           0);
	boot_freemem_paddr = PADDR(ROUNDUP(boot_freemem, PGSIZE));
	if (mboot_has_mmaps(mbi)) {
		mboot_foreach_mmap(mbi, parse_mboot_region,
				   (void*)boot_freemem_paddr);
	} else {
		/* No multiboot mmap regions (probably run from qemu with
		 * -kernel) */
		account_for_pages(boot_freemem_paddr);
	}
}
