#ifdef __SHARC__
#pragma nosharc
#define SINIT(x) x
#endif

/* See COPYRIGHT for copyright information. */
#include <arch/x86.h>
#include <arch/arch.h>
#include <arch/mmu.h>
#include <arch/apic.h>

#include <error.h>
#include <sys/queue.h>

#include <atomic.h>
#include <string.h>
#include <assert.h>
#include <pmap.h>
#include <kclock.h>
#include <env.h>
#include <stdio.h>
#include <kmalloc.h>
#include <page_alloc.h>

// These variables are set in i386_vm_init()
pde_t* boot_pgdir;		// Virtual address of boot time page directory
physaddr_t RO boot_cr3;		// Physical address of boot time page directory

// Global descriptor table.
//
// The kernel and user segments are identical (except for the DPL).
// To load the SS register, the CPL must equal the DPL.  Thus,
// we must duplicate the segments for the user and the kernel.
//
segdesc_t gdt_in_c[] =
{
	// 0x0 - unused (always faults -- for trapping NULL far pointers)
	SEG_NULL,

	// 0x8 - kernel code segment
	[GD_KT >> 3] = SEG(STA_X | STA_R, 0x0, 0xffffffff, 0),

	// 0x10 - kernel data segment
	[GD_KD >> 3] = SEG(STA_W, 0x0, 0xffffffff, 0),

	// 0x18 - user code segment
	[GD_UT >> 3] = SEG(STA_X | STA_R, 0x0, 0xffffffff, 3),

	// 0x20 - user data segment
	[GD_UD >> 3] = SEG(STA_W, 0x0, 0xffffffff, 3),

	// 0x28 - tss, initialized in idt_init()
	[GD_TSS >> 3] = SEG_NULL,

	// 0x30 - LDT, set per-process
	[GD_LDT >> 3] = SEG_NULL
};

/* Want gdt to be a pointer, not an array type (can replace it more easily) */
segdesc_t *gdt = gdt_in_c;

pseudodesc_t gdt_pd = {
	sizeof(gdt_in_c) - 1, (unsigned long) gdt_in_c
};

// --------------------------------------------------------------
// Set up initial memory mappings and turn on MMU.
// --------------------------------------------------------------

static void check_boot_pgdir(bool pse);

//
// Map [la, la+size) of linear address space to physical [pa, pa+size)
// in the page table rooted at pgdir.  Size is a multiple of PGSIZE.
// Use permission bits perm|PTE_P for the entries.
//
// To map with Jumbos, set PTE_PS in perm
static void
boot_map_segment(pde_t *COUNT(NPDENTRIES) pgdir, uintptr_t la, size_t size, physaddr_t pa, int perm)
{
	uintptr_t i;
	pte_t *pte;
	// la can be page unaligned, but weird things will happen
	// unless pa has the same offset.  pa always truncates any
	// possible offset.  will warn.  size can be weird too. 
	if (PGOFF(la)) {
		warn("la not page aligned in boot_map_segment!");
		size += PGOFF(la);
	}
	if (perm & PTE_PS) {
		if (JPGOFF(la) || JPGOFF(pa))
			panic("Tried to map a Jumbo page at an unaligned address!");
		// need to index with i instead of la + size, in case of wrap-around
		for (i = 0; i < size; i += JPGSIZE, la += JPGSIZE, pa += JPGSIZE) {
			pte = pgdir_walk(pgdir, (void*)la, 2);
			assert(pte);
			*pte = PTE_ADDR(pa) | PTE_P | perm;
		}
	} else {
		for (i = 0; i < size; i += PGSIZE, la += PGSIZE, pa += PGSIZE) {
			pte = pgdir_walk(pgdir, (void*)la, 1);
			assert(pte);
			if (*pte & PTE_PS)
				// if we start using the extra flag for PAT, which we aren't,
				// this will warn, since PTE_PS and PTE_PAT are the same....
				warn("Possibly attempting to map a regular page into a Jumbo PDE");
			*pte = PTE_ADDR(pa) | PTE_P | perm;
		}
	}
}

// Set up a two-level page table:
//    boot_pgdir is its linear (virtual) address of the root
//    boot_cr3 is the physical adresss of the root
// Then turn on paging.  Then effectively turn off segmentation.
// (i.e., the segment base addrs are set to zero).
// 
// This function only sets up the kernel part of the address space
// (ie. addresses >= ULIM).  The user part of the address space
// will be setup later.
//
// From UWLIM to ULIM, the user is allowed to read but not write.
// Above ULIM the user cannot read (or write). 
void
vm_init(void)
{
	pde_t* pgdir;
	uint32_t cr0, edx;
	size_t n;
	bool pse;

	pse = enable_pse();
	if (pse)
		cprintf("PSE capability detected.\n");

	// we paniced earlier if we don't support PGE.  turn it on now.
	// it's used in boot_map_segment, which covers all of the mappings that are
	// the same for all address spaces.  and also for the VPT mapping below.
	lcr4(rcr4() | CR4_PGE);

	// set up mtrr's for core0.  other cores will do the same later
	setup_default_mtrrs(0);

	/*
	 * PSE status: 
	 * - can walk and set up boot_map_segments with jumbos but can't
	 *   insert yet.  need to look at the page_dir and friends.
	 * - anything related to a single struct page still can't handle 
	 *   jumbos.  will need to think about and adjust Page functions
	 * - do we want to store info like this in the struct page?  or just check
	 *   by walking the PTE
	 * - when we alloc a page, and we want it to be 4MB, we'll need
	 *   to have contiguous memory, etc
	 * - there's a difference between having 4MB page table entries
	 *   and having 4MB Page tracking structs.  changing the latter will
	 *   break a lot of things
	 * - showmapping and friends work on a 4KB granularity, but map to the
	 *   correct entries
	 * - need to not insert / boot_map a single page into an area that is 
	 *   already holding a jumbo page.  will need to break the jumbo up so that
	 *   we can then insert the lone page.  currently warns.
	 * - some inherent issues with the pgdir_walks returning a PTE, and we
	 *   don't know whether it is a jumbo (PDE) or a regular PTE.
	 */

	//////////////////////////////////////////////////////////////////////
	// create initial page directory.
	pgdir = kpage_zalloc_addr();
	assert(pgdir);
	boot_pgdir = pgdir;
	boot_cr3 = PADDR(pgdir);
	// helpful if you want to manually walk with kvm / bochs
	//printk("pgdir va = %p, pgdir pa = %p\n\n", pgdir, PADDR(pgdir));

	//////////////////////////////////////////////////////////////////////
	// Recursively insert PD in itself as a page table, to form
	// a virtual page table at virtual address VPT.
	// (For now, you don't have understand the greater purpose of the
	// following two lines.  Unless you are eagle-eyed, in which case you
	// should already know.)

	// Permissions: kernel RW, user NONE, Global Page
	pgdir[PDX(VPT)] = PADDR(pgdir) | PTE_W | PTE_P | PTE_G;

	// same for UVPT
	// Permissions: kernel R, user R, Global Page
	pgdir[PDX(UVPT)] = PADDR(pgdir) | PTE_U | PTE_P | PTE_G;

	//////////////////////////////////////////////////////////////////////
	// Map all of physical memory at KERNBASE. 
	// Ie.  the VA range [KERNBASE, 2^32) should map to
	//      the PA range [0, 2^32 - KERNBASE)
	// We might not have 2^32 - KERNBASE bytes of physical memory, but
	// we just set up the mapping anyway.
	// Permissions: kernel RW, user NONE
	// Your code goes here: 
	
	// this maps all of the possible phys memory
	// note the use of unsigned underflow to get size = 0x40000000
	//boot_map_segment(pgdir, KERNBASE, -KERNBASE, 0, PTE_W);
	// but this only maps what is available, and saves memory.  every 4MB of
	// mapped memory requires a 2nd level page: 2^10 entries, each covering 2^12
	// need to modify tests below to account for this
	if (pse) {
		// map the first 4MB as regular entries, to support different MTRRs
		boot_map_segment(pgdir, KERNBASE, JPGSIZE, 0, PTE_W | PTE_G);
		boot_map_segment(pgdir, KERNBASE + JPGSIZE, max_paddr - JPGSIZE, JPGSIZE,
		                 PTE_W | PTE_G | PTE_PS);
	} else
		boot_map_segment(pgdir, KERNBASE, max_paddr, 0, PTE_W | PTE_G);

	// APIC mapping: using PAT (but not *the* PAT flag) to make these type UC
	// IOAPIC
	boot_map_segment(pgdir, IOAPIC_BASE, APIC_SIZE, IOAPIC_PBASE,
	                 PTE_PCD | PTE_PWT | PTE_W | PTE_G);
	// Local APIC
	boot_map_segment(pgdir, LAPIC_BASE, APIC_SIZE, LAPIC_PBASE,
	                 PTE_PCD | PTE_PWT | PTE_W | PTE_G);

	// Check that the initial page directory has been set up correctly.
	check_boot_pgdir(pse);

	//////////////////////////////////////////////////////////////////////
	// On x86, segmentation maps a VA to a LA (linear addr) and
	// paging maps the LA to a PA.  I.e. VA => LA => PA.  If paging is
	// turned off the LA is used as the PA.  Note: there is no way to
	// turn off segmentation.  The closest thing is to set the base
	// address to 0, so the VA => LA mapping is the identity.

	// Current mapping: VA KERNBASE+x => PA x.
	//     (segmentation base=-KERNBASE and paging is off)

	// From here on down we must maintain this VA KERNBASE + x => PA x
	// mapping, even though we are turning on paging and reconfiguring
	// segmentation.

	// Map VA 0:4MB same as VA KERNBASE, i.e. to PA 0:4MB.
	// (Limits our kernel to <4MB)
	/* They mean linear address 0:4MB, and the kernel < 4MB is only until 
	 * segmentation is turned off.
	 * once we turn on paging, segmentation is still on, so references to
	 * KERNBASE+x will get mapped to linear address x, which we need to make 
	 * sure can map to phys addr x, until we can turn off segmentation and
	 * KERNBASE+x maps to LA KERNBASE+x, which maps to PA x, via paging
	 */
	pgdir[0] = pgdir[PDX(KERNBASE)];

	// Install page table.
	lcr3(boot_cr3);

	// Turn on paging.
	cr0 = rcr0();
	// CD and NW should already be on, but just in case these turn on caching
	cr0 |= CR0_PE|CR0_PG|CR0_AM|CR0_WP|CR0_NE|CR0_MP;
	cr0 &= ~(CR0_TS|CR0_EM|CR0_CD|CR0_NW);
	lcr0(cr0);

	// Current mapping: KERNBASE+x => x => x.
	// (x < 4MB so uses paging pgdir[0])

	// Reload all segment registers.
	asm volatile("lgdt gdt_pd");
	asm volatile("movw %%ax,%%gs" :: "a" (GD_UD|3));
	asm volatile("movw %%ax,%%fs" :: "a" (GD_UD|3));
	asm volatile("movw %%ax,%%es" :: "a" (GD_KD));
	asm volatile("movw %%ax,%%ds" :: "a" (GD_KD));
	asm volatile("movw %%ax,%%ss" :: "a" (GD_KD));
	asm volatile("ljmp %0,$1f\n 1:\n" :: "i" (GD_KT));  // reload cs
	asm volatile("lldt %%ax" :: "a" (0));

	// Final mapping: KERNBASE+x => KERNBASE+x => x.

	// This mapping was only used after paging was turned on but
	// before the segment registers were reloaded.
	pgdir[0] = 0;

	// Flush the TLB for good measure, to kill the pgdir[0] mapping.
	tlb_flush_global();
}

void x86_cleanup_bootmem(void)
{
	#define trampoline_pg 0x00001000UL
	// Remove the mapping of the page used by the trampoline
	page_remove(boot_pgdir, (void*)trampoline_pg);
	// Remove the page table used for that mapping
	pagetable_remove(boot_pgdir, (void*)trampoline_pg);
}

//
// Checks that the kernel part of virtual address space
// has been setup roughly correctly(by i386_vm_init()).
//
// This function doesn't test every corner case,
// in fact it doesn't test the permission bits at all,
// but it is a pretty good sanity check. 
//
static physaddr_t check_va2pa(pde_t *COUNT(NPDENTRIES) pgdir, uintptr_t va);

static void
check_boot_pgdir(bool pse)
{
	uint32_t i, n;
	pde_t *pgdir, pte;

	pgdir = boot_pgdir;

	// check phys mem
	//for (i = 0; KERNBASE + i != 0; i += PGSIZE)
	// adjusted check to account for only mapping avail mem
	if (pse)
		for (i = 0; i < max_paddr; i += JPGSIZE)
			assert(check_va2pa(pgdir, KERNBASE + i) == i);
	else
		for (i = 0; i < max_paddr; i += PGSIZE)
			assert(check_va2pa(pgdir, KERNBASE + i) == i);

	// check for zero/non-zero in PDEs
	for (i = 0; i < NPDENTRIES; i++) {
		switch (i) {
		case PDX(VPT):
		case PDX(UVPT):
		case PDX(LAPIC_BASE): // LAPIC mapping.  TODO: remove when MTRRs are up
			assert(pgdir[i]);
			break;
		default:
			//if (i >= PDX(KERNBASE))
			// adjusted check to account for only mapping avail mem
			// and you can't KADDR maxpa (just above legal range)
			// max_paddr can be up to maxpa, so assume the worst
			if (i >= PDX(KERNBASE) && i <= PDX(KADDR(max_paddr-1)))
				assert(pgdir[i]);
			else
				assert(pgdir[i] == 0);
			break;
		}
	}

	/* check permissions
	 * user read-only.  check for user and write, should be only user
	 * eagle-eyed viewers should be able to explain the extra cases.
	 * for the mongoose-eyed, remember that weird shit happens when you loop
	 * through UVPT.  Specifically, you can't loop once, then look at a jumbo
	 * page that is kernel only.  That's the end of the page table for you, so
	 * having a U on the entry doesn't make sense.  Thus we check for a jumbo
	 * page, and special case it.  This will happen at 0xbf701000.  Why is this
	 * magical?  Get your eagle glasses and figure it out. */
	for (i = UWLIM; i < ULIM; i+=PGSIZE) {
		pte = get_va_perms(pgdir, (void*SAFE)TC(i));
		if (pte & PTE_P) {
			if (i == UVPT+(VPT >> 10))
				continue;
			if (*pgdir_walk(pgdir, (void*SAFE)TC(i), 0) & PTE_PS) {
				assert((pte & PTE_U) != PTE_U);
				assert((pte & PTE_W) != PTE_W);
			} else {
				assert((pte & PTE_U) == PTE_U);
				assert((pte & PTE_W) != PTE_W);
			}
		}
	}
	// kernel read-write.
	for (i = ULIM; i <= KERNBASE + max_paddr - PGSIZE; i+=PGSIZE) {
		pte = get_va_perms(pgdir, (void*SAFE)TC(i));
		if ((pte & PTE_P) && (i != VPT+(UVPT>>10))) {
			assert((pte & PTE_U) != PTE_U);
			assert((pte & PTE_W) == PTE_W);
		}
	}
	// special mappings
	pte = get_va_perms(pgdir, (void*SAFE)TC(UVPT+(VPT>>10)));
	assert((pte & PTE_U) != PTE_U);
	assert((pte & PTE_W) != PTE_W);

	// note this means the kernel cannot directly manipulate this virtual address
	// convince yourself this isn't a big deal, eagle-eyes!
	pte = get_va_perms(pgdir, (void*SAFE)TC(VPT+(UVPT>>10)));
	assert((pte & PTE_U) != PTE_U);
	assert((pte & PTE_W) != PTE_W);

	cprintf("check_boot_pgdir() succeeded!\n");
}

// This function returns the physical address of the page containing 'va',
// defined by the page directory 'pgdir'.  The hardware normally performs
// this functionality for us!  We define our own version to help check
// the check_boot_pgdir() function; it shouldn't be used elsewhere.

static physaddr_t
check_va2pa(pde_t *COUNT(NPDENTRIES) _pgdir, uintptr_t va)
{
	pte_t *COUNT(NPTENTRIES) p;
	pde_t *COUNT(1) pgdir;

	pgdir = &_pgdir[PDX(va)];
	if (!(*pgdir & PTE_P))
		return ~0;
	if (*pgdir & PTE_PS)
		return PTE_ADDR(*pgdir);
	p = (pte_t*COUNT(NPTENTRIES)) KADDR(PTE_ADDR(*pgdir));
	if (!(p[PTX(va)] & PTE_P))
		return ~0;
	return PTE_ADDR(p[PTX(va)]);
}

/* 
 * Remove the second level page table associated with virtual address va.
 * Will 0 out the PDE for that page table.
 * Panics if the page table has any present entries.
 * This should be called rarely and with good cause.
 * Currently errors if the PDE is jumbo or not present.
 */
error_t	pagetable_remove(pde_t *pgdir, void *va)
{
	pde_t* the_pde = &pgdir[PDX(va)];

	if (!(*the_pde & PTE_P) || (*the_pde & PTE_PS))
		return -EFAULT;
	pte_t* page_table = (pde_t*COUNT(NPTENTRIES))KADDR(PTE_ADDR(*the_pde));
	for (int i = 0; i < NPTENTRIES; i++) 
		if (page_table[i] & PTE_P)
			panic("Page table not empty during attempted removal!");
	*the_pde = 0;
	page_decref(pa2page(PADDR(page_table)));
	return 0;
}

// Given 'pgdir', a pointer to a page directory, pgdir_walk returns
// a pointer to the page table entry (PTE) for linear address 'va'.
// This requires walking the two-level page table structure.
//
// If the relevant page table doesn't exist in the page directory, then:
//    - If create == 0, pgdir_walk returns NULL.
//    - Otherwise, pgdir_walk tries to allocate a new page table
//	with page_alloc.  If this fails, pgdir_walk returns NULL.
//    - Otherwise, pgdir_walk returns a pointer into the new page table.
//
// Hint: you can turn a Page * into the physical address of the
// page it refers to with page2pa() from kern/pmap.h.
//
// Supports returning jumbo (4MB PSE) PTEs.  To create with a jumbo, pass in 2.
pte_t*
pgdir_walk(pde_t *pgdir, const void *SNT va, int create)
{
	pde_t* the_pde = &pgdir[PDX(va)];
	page_t *new_table;

	if (*the_pde & PTE_P) {
		if (*the_pde & PTE_PS)
			return (pte_t*)the_pde;
		return &((pde_t*COUNT(NPTENTRIES))KADDR(PTE_ADDR(*the_pde)))[PTX(va)];
	}
	if (!create)
		return NULL;
	if (create == 2) {
		if (JPGOFF(va))
			panic("Attempting to find a Jumbo PTE at an unaligned VA!");
		*the_pde = PTE_PS | PTE_P;
		return (pte_t*)the_pde;
	}
	if (kpage_alloc(&new_table))
		return NULL;
	memset(page2kva(new_table), 0, PGSIZE);
	/* storing our ref to new_table in the PTE */
	*the_pde = (pde_t)page2pa(new_table) | PTE_P | PTE_W | PTE_U;
	return &((pde_t*COUNT(NPTENTRIES))KADDR(PTE_ADDR(*the_pde)))[PTX(va)];
}

/* Returns the effective permissions for PTE_U, PTE_W, and PTE_P on a given
 * virtual address.  Note we need to consider the composition of every PTE in
 * the page table walk. */
int get_va_perms(pde_t *pgdir, const void *SNT va)
{
	pde_t the_pde = pgdir[PDX(va)];
	pte_t the_pte;

	if (!(the_pde & PTE_P))
		return 0;
	if (the_pde & PTE_PS)
		return the_pde & (PTE_U | PTE_W | PTE_P);
	the_pte = ((pde_t*COUNT(NPTENTRIES))KADDR(PTE_ADDR(the_pde)))[PTX(va)];
	if (!(the_pte & PTE_P))
		return 0;
	return the_pte & the_pde & (PTE_U | PTE_W | PTE_P);
}

void
page_check(void)
{
	page_t *pp, *pp0, *pp1, *pp2;
	page_list_t fl[1024];
	pte_t *ptep;

	// should be able to allocate three pages
	pp0 = pp1 = pp2 = 0;
	assert(kpage_alloc(&pp0) == 0);
	assert(kpage_alloc(&pp1) == 0);
	assert(kpage_alloc(&pp2) == 0);

	assert(pp0);
	assert(pp1 && pp1 != pp0);
	assert(pp2 && pp2 != pp1 && pp2 != pp0);

	// temporarily steal the rest of the free pages
	for(int i=0; i<llc_cache->num_colors; i++) {
		fl[i] = colored_page_free_list[i];
		LIST_INIT(&colored_page_free_list[i]);
	}

	// should be no free memory
	assert(kpage_alloc(&pp) == -ENOMEM);

	// Fill pp1 with bogus data and check for invalid tlb entries
	memset(page2kva(pp1), 0xFFFFFFFF, PGSIZE);

	// there is no page allocated at address 0
	assert(page_lookup(boot_pgdir, (void *) 0x0, &ptep) == NULL);

	// there is no free memory, so we can't allocate a page table 
	assert(page_insert(boot_pgdir, pp1, 0x0, 0) < 0);

	// free pp0 and try again: pp0 should be used for page table
	page_decref(pp0);
	assert(page_insert(boot_pgdir, pp1, 0x0, 0) == 0);
	tlb_invalidate(boot_pgdir, 0x0);
	// DEP Should have shot down invalid TLB entry - let's check
	{ TRUSTEDBLOCK
	  int *x = 0x0;
	  assert(*x == 0xFFFFFFFF);
	}
	assert(PTE_ADDR(boot_pgdir[0]) == page2pa(pp0));
	assert(check_va2pa(boot_pgdir, 0x0) == page2pa(pp1));
	assert(kref_refcnt(&pp1->pg_kref) == 2);
	assert(kref_refcnt(&pp0->pg_kref) == 1);

	// should be able to map pp2 at PGSIZE because pp0 is already allocated for page table
	assert(page_insert(boot_pgdir, pp2, (void*SNT) PGSIZE, 0) == 0);
	assert(check_va2pa(boot_pgdir, PGSIZE) == page2pa(pp2));
	assert(kref_refcnt(&pp2->pg_kref) == 2);

	// Make sure that pgdir_walk returns a pointer to the pte and
	// not the table or some other garbage
	{
	  pte_t *p = (pte_t*COUNT(NPTENTRIES))KADDR(PTE_ADDR(boot_pgdir[PDX(PGSIZE)]));
	  assert(pgdir_walk(boot_pgdir, (void *SNT)PGSIZE, 0) == &p[PTX(PGSIZE)]);
	}

	// should be no free memory
	assert(kpage_alloc(&pp) == -ENOMEM);

	// should be able to map pp2 at PGSIZE because it's already there
	assert(page_insert(boot_pgdir, pp2, (void*SNT) PGSIZE, PTE_U) == 0);
	assert(check_va2pa(boot_pgdir, PGSIZE) == page2pa(pp2));
	assert(kref_refcnt(&pp2->pg_kref) == 2);

	// Make sure that we actually changed the permission on pp2 when we re-mapped it
	{
	  pte_t *p = pgdir_walk(boot_pgdir, (void*SNT)PGSIZE, 0);
	  assert(((*p) & PTE_U) == PTE_U);
	}

	// pp2 should NOT be on the free list
	// could happen if ref counts are handled sloppily in page_insert
	assert(kpage_alloc(&pp) == -ENOMEM);

	// should not be able to map at PTSIZE because need free page for page table
	assert(page_insert(boot_pgdir, pp0, (void*SNT) PTSIZE, 0) < 0);

	// insert pp1 at PGSIZE (replacing pp2)
	assert(page_insert(boot_pgdir, pp1, (void*SNT) PGSIZE, 0) == 0);

	// should have pp1 at both 0 and PGSIZE, pp2 nowhere, ...
	assert(check_va2pa(boot_pgdir, 0) == page2pa(pp1));
	assert(check_va2pa(boot_pgdir, PGSIZE) == page2pa(pp1));
	// ... and ref counts should reflect this
	assert(kref_refcnt(&pp1->pg_kref) == 3);
	assert(kref_refcnt(&pp2->pg_kref) == 1);

	// pp2 should be returned by page_alloc
	page_decref(pp2);	/* should free it */
	assert(kpage_alloc(&pp) == 0 && pp == pp2);

	// unmapping pp1 at 0 should keep pp1 at PGSIZE
	page_remove(boot_pgdir, 0x0);
	assert(check_va2pa(boot_pgdir, 0x0) == ~0);
	assert(check_va2pa(boot_pgdir, PGSIZE) == page2pa(pp1));
	assert(kref_refcnt(&pp1->pg_kref) == 2);
	assert(kref_refcnt(&pp2->pg_kref) == 1);

	// unmapping pp1 at PGSIZE should free it
	page_remove(boot_pgdir, (void*SNT) PGSIZE);
	assert(check_va2pa(boot_pgdir, 0x0) == ~0);
	assert(check_va2pa(boot_pgdir, PGSIZE) == ~0);
	assert(kref_refcnt(&pp1->pg_kref) == 1);
	assert(kref_refcnt(&pp2->pg_kref) == 1);
	page_decref(pp1);

	// so it should be returned by page_alloc
	assert(kpage_alloc(&pp) == 0 && pp == pp1);

	// should be no free memory
	assert(kpage_alloc(&pp) == -ENOMEM);

	// forcibly take pp0 back
	assert(PTE_ADDR(boot_pgdir[0]) == page2pa(pp0));
	boot_pgdir[0] = 0;
	assert(kref_refcnt(&pp0->pg_kref) == 1);

	// Catch invalid pointer addition in pgdir_walk - i.e. pgdir + PDX(va)
	{
	  // Give back pp0 for a bit
	  page_decref(pp0);

	  void *SNT va = (void *SNT)((PGSIZE * NPDENTRIES) + PGSIZE);
	  pte_t *p2 = pgdir_walk(boot_pgdir, va, 1);
	  pte_t *p = (pte_t*COUNT(NPTENTRIES))KADDR(PTE_ADDR(boot_pgdir[PDX(va)]));
	  assert(p2 == &p[PTX(va)]);

	  // Clean up again
	  boot_pgdir[PDX(va)] = 0;
	}

	// give free list back
	for(int i=0; i<llc_cache->num_colors; i++)
		colored_page_free_list[i] = fl[i];

	// free the pages we took
	page_decref(pp0);
	page_decref(pp1);
	page_decref(pp2);
	assert(!kref_refcnt(&pp0->pg_kref));
	assert(!kref_refcnt(&pp1->pg_kref));
	assert(!kref_refcnt(&pp2->pg_kref));

	cprintf("page_check() succeeded!\n");
}

/* Walks len bytes from start, executing 'callback' on every PTE, passing it a
 * specific VA and whatever arg is passed in.  Note, this cannot handle jumbo
 * pages. */
int env_user_mem_walk(env_t* e, void* start, size_t len,
                      mem_walk_callback_t callback, void* arg)
{
	pte_t *pt;
	uint32_t pdeno, pteno;
	physaddr_t pa;

	assert((uintptr_t)start % PGSIZE == 0 && len % PGSIZE == 0);
	uintptr_t end = (uintptr_t)start+len;
	uint32_t pdeno_start = PDX(start);
	uint32_t pdeno_end = PDX(ROUNDUP(end,PTSIZE));
	/* concerned about overflow.  this should catch it for now, given the above
	 * assert. */
	assert((len == 0) || (pdeno_start < pdeno_end));

	for (pdeno = pdeno_start; pdeno < pdeno_end; pdeno++) {
		if (!(e->env_pgdir[pdeno] & PTE_P))
			continue;
		/* find the pa and a pointer to the page table */
		pa = PTE_ADDR(e->env_pgdir[pdeno]);
		pt = (pte_t*COUNT(NPTENTRIES)) KADDR(pa);
		/* figure out where we start and end within the page table */
		uint32_t pteno_start = (pdeno == pdeno_start ? PTX(start) : 0);
		uint32_t pteno_end = (pdeno == pdeno_end - 1 && PTX(end) != 0 ?
		                      PTX(end) : NPTENTRIES );
		int ret;
		for (pteno = pteno_start; pteno < pteno_end; pteno++) {
			if((ret = callback(e, &pt[pteno], PGADDR(pdeno, pteno, 0), arg)))
				return ret;
		}
	}
	return 0;
}

/* Frees (decrefs) all pages of the process's page table, including the page
 * directory.  Does not free the memory that is actually mapped. */
void env_pagetable_free(env_t* e)
{
	static_assert(UVPT % PTSIZE == 0);
	assert(e->env_cr3 != rcr3());
	for(uint32_t pdeno = 0; pdeno < PDX(UVPT); pdeno++)
	{
		// only look at mapped page tables
		if (!(e->env_pgdir[pdeno] & PTE_P))
			continue;

		// find the pa and va of the page table
		physaddr_t pa = PTE_ADDR(e->env_pgdir[pdeno]);

		// free the page table itself
		e->env_pgdir[pdeno] = 0;
		page_decref(pa2page(pa));
	}

	// free the page directory
	physaddr_t pa = e->env_cr3;
	e->env_cr3 = 0;
	page_decref(pa2page(pa));
	tlbflush();
}
