/* Copyright (c) 2009,13 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * Arch independent physical memory and page table management.
 *
 * For page allocation, check out the family of page_alloc files. */

#include <arch/arch.h>
#include <arch/mmu.h>

#include <error.h>

#include <kmalloc.h>
#include <atomic.h>
#include <string.h>
#include <assert.h>
#include <pmap.h>
#include <process.h>
#include <stdio.h>
#include <mm.h>
#include <multiboot.h>
#include <arena.h>
#include <init.h>

physaddr_t max_pmem = 0;  /* Total amount of physical memory (bytes) */
physaddr_t max_paddr = 0; /* Maximum addressable physical address */
size_t max_nr_pages = 0;  /* Number of addressable physical memory pages */
struct page *pages = 0;
struct multiboot_info *multiboot_kaddr = 0;
uintptr_t boot_freemem = 0;
uintptr_t boot_freelimit = 0;

static size_t sizeof_mboot_mmentry(struct multiboot_mmap_entry *entry)
{
	/* Careful - len is a uint64 (need to cast down for 32 bit) */
	return (size_t)(entry->len);
}

static void adjust_max_pmem(struct multiboot_mmap_entry *entry, void *data)
{
	if (entry->type != MULTIBOOT_MEMORY_AVAILABLE)
		return;
	/* Careful - addr + len is a uint64 (need to cast down for 32 bit) */
	max_pmem = MAX(max_pmem, (size_t)(entry->addr + entry->len));
}

static void kpages_arena_init(void)
{
	void *kpages_pg;

	kpages_pg = arena_alloc(base_arena, PGSIZE, MEM_WAIT);
	kpages_arena = arena_builder(kpages_pg, "kpages", PGSIZE, arena_alloc,
	                             arena_free, base_arena, 8 * PGSIZE);
}

/**
 * @brief Initializes physical memory.  Determines the pmem layout, sets up the
 * base and kpages arenas, and turns on virtual memory/page tables.
 *
 * Regarding max_pmem vs max_paddr and max_nr_pages: max_pmem is the largest
 * physical address that is in a FREE region.  It includes RESERVED regions that
 * are below this point.  max_paddr is the largest physical address, <=
 * max_pmem, that the KERNBASE mapping can map.  It too may include reserved
 * ranges.  The 'pages' array will track all physical pages up to max_paddr.
 * There are max_nr_pages of them.  On 64 bit systems, max_pmem == max_paddr. */
void pmem_init(struct multiboot_info *mbi)
{
	mboot_detect_memory(mbi);
	mboot_print_mmap(mbi);
	/* adjust the max memory based on the mmaps, since the old detection
	 * doesn't help much on 64 bit systems */
	mboot_foreach_mmap(mbi, adjust_max_pmem, 0);
	/* KERN_VMAP_TOP - KERNBASE is the max amount of virtual addresses we
	 * can use for the physical memory mapping (aka - the KERNBASE mapping).
	 * Should't be an issue on 64b, but is usually for 32 bit. */
	max_paddr = MIN(max_pmem, KERN_VMAP_TOP - KERNBASE);
	/* Note not all of this memory is free. */
	max_nr_pages = max_paddr / PGSIZE;
	printk("Max physical RAM (appx, bytes): %lu\n", max_pmem);
	printk("Max addressable physical RAM (appx): %lu\n", max_paddr);
	printk("Highest page number (including reserved): %lu\n", max_nr_pages);
	/* We should init the page structs, but zeroing happens to work, except
	 * for the sems.  Those are init'd by the page cache before they are
	 * used. */
	pages = (struct page*)boot_zalloc(max_nr_pages * sizeof(struct page),
	                                  PGSIZE);
	base_arena_init(mbi);
	/* kpages will use some of the basic slab caches.  kmem_cache_init needs
	 * to not do memory allocations (which it doesn't, and it can
	 * base_alloc()). */
	kmem_cache_init();
	kpages_arena_init();
	printk("Base arena total mem: %lu\n", arena_amt_total(base_arena));
	vm_init();

	static_assert(PROCINFO_NUM_PAGES*PGSIZE <= PTSIZE);
	static_assert(PROCDATA_NUM_PAGES*PGSIZE <= PTSIZE);
}

static void set_largest_freezone(struct multiboot_mmap_entry *entry, void *data)
{
	struct multiboot_mmap_entry **boot_zone =
	       (struct multiboot_mmap_entry**)data;

	if (entry->type != MULTIBOOT_MEMORY_AVAILABLE)
		return;
	if (!*boot_zone || (sizeof_mboot_mmentry(entry) >
	                   sizeof_mboot_mmentry(*boot_zone)))
		*boot_zone = entry;
}

/* Initialize boot freemem and its limit.
 *
 * "end" is a symbol marking the end of the kernel.  This covers anything linked
 * in with the kernel (KFS, etc).  However, 'end' is a kernel load address,
 * which differs from kernbase addrs in 64 bit.  We need to use the kernbase
 * mapping for anything dynamic (because it could go beyond 1 GB).
 *
 * Ideally, we'll use the largest mmap zone, as reported by multiboot.  If we
 * don't have one (riscv), we'll just use the memory after the kernel.
 *
 * If we do have a zone, there is a chance we've already used some of it (for
 * the kernel, etc).  We'll use the lowest address in the zone that is
 * greater than "end" (and adjust the limit accordingly).  */
static void boot_alloc_init(void)
{
	extern char end[];
	uintptr_t boot_zone_start, boot_zone_end;
	uintptr_t end_kva = (uintptr_t)KBASEADDR(end);
	struct multiboot_mmap_entry *boot_zone = 0;

	/* Find our largest mmap_entry; that will set bootzone */
	mboot_foreach_mmap(multiboot_kaddr, set_largest_freezone, &boot_zone);
	if (boot_zone) {
		boot_zone_start = (uintptr_t)KADDR(boot_zone->addr);
		/* one issue for 32b is that the boot_zone_end could be beyond
		 * max_paddr and even wrap-around.  Do the min check as a
		 * uint64_t.  The result should be a safe, unwrapped 32/64b when
		 * cast to physaddr_t. */
		boot_zone_end = (uintptr_t)KADDR(MIN(boot_zone->addr +
						     boot_zone->len,
						     (uint64_t)max_paddr));
		/* using KERNBASE (kva, btw) which covers the kernel and
		 * anything before it (like the stuff below EXTPHYSMEM on x86)
		 */
		if (regions_collide_unsafe(KERNBASE, end_kva,
		                           boot_zone_start, boot_zone_end))
			boot_freemem = end_kva;
		else
			boot_freemem = boot_zone_start;
		boot_freelimit = boot_zone_end;
	} else {
		boot_freemem = end_kva;
		boot_freelimit = max_paddr + KERNBASE;
	}
	printd("boot_zone: %p, paddr base: 0x%llx, paddr len: 0x%llx\n",
	       boot_zone, boot_zone ? boot_zone->addr : 0,
	       boot_zone ? boot_zone->len : 0);
	printd("boot_freemem: %p, boot_freelimit %p\n", boot_freemem,
	       boot_freelimit);
}

/* Low-level allocator, used before page_alloc is on.  Returns size bytes,
 * aligned to align (should be a power of 2).  Retval is a kernbase addr.  Will
 * panic on failure. */
void *boot_alloc(size_t amt, size_t align)
{
	uintptr_t retval;

	if (!boot_freemem)
		boot_alloc_init();
	boot_freemem = ROUNDUP(boot_freemem, align);
	retval = boot_freemem;
	if (boot_freemem + amt > boot_freelimit){
		printk("boot_alloc: boot_freemem is 0x%x\n", boot_freemem);
		printk("boot_alloc: amt is %d\n", amt);
		printk("boot_freelimit is 0x%x\n", boot_freelimit);
		printk("boot_freemem + amt is > boot_freelimit\n");
		panic("Out of memory in boot alloc, you fool!\n");
	}
	boot_freemem += amt;
	printd("boot alloc from %p to %p\n", retval, boot_freemem);
	/* multiboot info probably won't ever conflict with our boot alloc */
	if (mboot_region_collides(multiboot_kaddr, retval, boot_freemem))
		panic("boot allocation could clobber multiboot info!");
	return (void*)retval;
}

void *boot_zalloc(size_t amt, size_t align)
{
	/* boot_alloc panics on failure */
	void *v = boot_alloc(amt, align);
	memset(v, 0, amt);
	return v;
}

/**
 * @brief Map the physical page 'pp' into the virtual address 'va' in page
 *        directory 'pgdir'
 *
 * Map the physical page 'pp' at virtual address 'va'.
 * The permissions (the low 12 bits) of the page table
 * entry should be set to 'perm|PTE_P'.
 *
 * Details:
 *   - If there is already a page mapped at 'va', it is page_remove()d.
 *   - If necessary, on demand, allocates a page table and inserts it into
 *     'pgdir'.
 *   - This saves your refcnt in the pgdir (refcnts going away soon).
 *   - The TLB must be invalidated if a page was formerly present at 'va'.
 *     (this is handled in page_remove)
 *
 * No support for jumbos here.  We will need to be careful when trying to
 * insert regular pages into something that was already jumbo.  We will
 * also need to be careful with our overloading of the PTE_PS and
 * PTE_PAT flags...
 *
 * @param[in] pgdir the page directory to insert the page into
 * @param[in] pp    a pointr to the page struct representing the
 *                  physical page that should be inserted.
 * @param[in] va    the virtual address where the page should be
 *                  inserted.
 * @param[in] perm  the permition bits with which to set up the
 *                  virtual mapping.
 *
 * @return ESUCCESS  on success
 * @return -ENOMEM   if a page table could not be allocated
 *                   into which the page should be inserted
 *
 */
int page_insert(pgdir_t pgdir, struct page *page, void *va, int perm)
{
	pte_t pte = pgdir_walk(pgdir, va, 1);

	if (!pte_walk_okay(pte))
		return -ENOMEM;
	/* Leftover from older times, but we no longer suppor this: */
	assert(!pte_is_mapped(pte));
	pte_write(pte, page2pa(page), perm);
	return 0;
}

/**
 * @brief Return the page mapped at virtual address 'va' in
 * page directory 'pgdir'.
 *
 * If pte_store is not NULL, then we store in it the address
 * of the pte for this page.  This is used by page_remove
 * but should not be used by other callers.
 *
 * For jumbos, right now this returns the first Page* in the 4MB range
 *
 * @param[in]  pgdir     the page directory from which we should do the lookup
 * @param[in]  va        the virtual address of the page we are looking up
 * @param[out] pte_store the address of the page table entry for the returned
 * 			 page
 *
 * @return PAGE the page mapped at virtual address 'va'
 * @return NULL No mapping exists at virtual address 'va', or it's paged out
 */
page_t *page_lookup(pgdir_t pgdir, void *va, pte_t *pte_store)
{
	pte_t pte = pgdir_walk(pgdir, va, 0);

	if (!pte_walk_okay(pte) || !pte_is_mapped(pte))
		return 0;
	if (pte_store)
		*pte_store = pte;
	return pa2page(pte_get_paddr(pte));
}

/**
 * @brief Unmaps the physical page at virtual address 'va' in page directory
 * 'pgdir'.
 *
 * If there is no physical page at that address, this function silently
 * does nothing.
 *
 * Details:
 *   - The ref count on the physical page is decrement when the page is removed
 *   - The physical page is freed if the refcount reaches 0.
 *   - The pg table entry corresponding to 'va' is set to 0.
 *     (if such a PTE exists)
 *   - The TLB is invalidated if an entry is removes from the pg dir/pg table.
 *
 * This may be wonky wrt Jumbo pages and decref.
 *
 * @param pgdir the page directory from with the page sholuld be removed
 * @param va    the virtual address at which the page we are trying to
 *              remove is mapped
 * TODO: consider deprecating this, or at least changing how it works with TLBs.
 * Might want to have the caller need to manage the TLB.  Also note it is used
 * in env_user_mem_free, minus the walk. */
void page_remove(pgdir_t pgdir, void *va)
{
	pte_t pte;
	page_t *page;

	pte = pgdir_walk(pgdir,va,0);
	if (!pte_walk_okay(pte) || pte_is_unmapped(pte))
		return;

	if (pte_is_mapped(pte)) {
		/* TODO: (TLB) need to do a shootdown, inval sucks.  And might
		 * want to manage the TLB / free pages differently. (like by the
		 * caller).  Careful about the proc/memory lock here. */
		page = pa2page(pte_get_paddr(pte));
		pte_clear(pte);
		tlb_invalidate(pgdir, va);
		page_decref(page);
	} else if (pte_is_paged_out(pte)) {
		/* TODO: (SWAP) need to free this from the swap */
		panic("Swapping not supported!");
		pte_clear(pte);
	}
}

/**
 * @brief Invalidate a TLB entry, but only if the page tables being
 * edited are the ones currently in use by the processor.
 *
 * TODO: (TLB) Need to sort this for cross core lovin'
 *
 * @param pgdir the page directory assocaited with the tlb entry
 *              we are trying to invalidate
 * @param va    the virtual address associated with the tlb entry
 *              we are trying to invalidate
 */
void tlb_invalidate(pgdir_t pgdir, void *va)
{
	// Flush the entry only if we're modifying the current address space.
	// For now, there is only one address space, so always invalidate.
	invlpg(va);
}

static void __tlb_global(uint32_t srcid, long a0, long a1, long a2)
{
	tlb_flush_global();
}

/* Does a global TLB flush on all cores. */
void tlb_shootdown_global(void)
{
	tlb_flush_global();
	if (booting)
		return;
	/* TODO: consider a helper for broadcast messages, though note that
	 * we're doing our flush immediately, which our caller expects from us
	 * before it returns. */
	for (int i = 0; i < num_cores; i++) {
		if (i == core_id())
			continue;
		send_kernel_message(i, __tlb_global, 0, 0, 0, KMSG_IMMEDIATE);
	}
}

/* Helper, returns true if any part of (start1, end1) is within (start2, end2).
 * Equality of endpoints (like end1 == start2) is okay.
 * Assumes no wrap-around. */
bool regions_collide_unsafe(uintptr_t start1, uintptr_t end1,
                            uintptr_t start2, uintptr_t end2)
{
	if (start1 <= start2) {
		if (end1 <= start2)
			return FALSE;
		return TRUE;
	} else {
		if (end2 <= start1)
			return FALSE;
		return TRUE;
	}
}
