/* 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, since the
	 * sems are not irqsave. */
	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!  Get help!");
	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;
	}
}
