/* See COPYRIGHT for copyright information.
 * Inlines, macros, and most function prototypes (c) the JOS project.
 *
 * Actual implementation:
 * Copyright (c) 2009 The Regents of the University of California
 * Barret Rhoden <brho@cs.berkeley.edu>
 * See LICENSE for details.
 *
 * Physical memory mangement, low-level virtual address space initialization and
 * management, and other things related to virtual->physical mappings.
 */

#pragma once

#include <ros/memlayout.h>
#include <sys/queue.h>
#include <multiboot.h>
#include <atomic.h>
#include <process.h>
#include <assert.h>
#include <page_alloc.h>
#include <multiboot.h>
#include <arch/pmap.h>

/* This macro takes a kernel virtual address -- an address that points above
 * KERNBASE, where the machine's maximum 256MB of physical memory is mapped --
 * and returns the corresponding physical address.  It panics if you pass it a
 * non-kernel virtual address.
 */
#define PADDR(kva)						\
({								\
	physaddr_t __m_pa, __m_kva = (physaddr_t) (kva);		\
	if (__m_kva < KERNBASE)					\
		panic("PADDR called with invalid kva %p", __m_kva);\
	if(__m_kva >= KERN_LOAD_ADDR)					\
		__m_pa = __m_kva - KERN_LOAD_ADDR;					\
	else					\
		__m_pa = __m_kva - KERNBASE;					\
	__m_pa; \
})

#define paddr_low32(p) ((uint32_t)(uintptr_t)PADDR(p))
#define paddr_high32(p) ((uint32_t)((uint64_t)PADDR(p) >> 32))

/* This macro takes a physical address and returns the corresponding kernel
 * virtual address.  It warns if you pass an invalid physical address. */
#define KADDR(pa)						\
({								\
	physaddr_t __m_pa = (pa);				\
	size_t __m_ppn = LA2PPN(__m_pa);			\
	if (__m_ppn > max_nr_pages)					\
		warn("KADDR called with invalid pa %p", __m_pa);\
	(void*) (__m_pa + KERNBASE);				\
})

#define KADDR_NOCHECK(pa) ((void*)(pa + KERNBASE))
#define KBASEADDR(kla) KADDR(PADDR(kla))

extern char bootstacktop[], bootstack[];

extern physaddr_t max_pmem;		/* Total amount of physical memory */
extern size_t max_nr_pages;		/* Total number of physical memory pages */
extern physaddr_t max_paddr;	/* Maximum addressable physical address */
extern size_t nr_free_pages;
extern struct multiboot_info *multiboot_kaddr;
extern uintptr_t boot_freemem;
extern uintptr_t boot_freelimit;

/* Pages are stored in an array, including for pages that we can never touch
 * (like reserved memory from the BIOS, fake regions, etc).  Pages are reference
 * counted, and free pages are kept on a linked list. */
extern struct page *pages;

extern physaddr_t boot_cr3;
extern pgdir_t boot_pgdir;

bool enable_pse(void);
void vm_init(void);

void pmem_init(struct multiboot_info *mbi);
void *boot_alloc(size_t amt, size_t align);
void *boot_zalloc(size_t amt, size_t align);

void page_check(void);
int	 page_insert(pgdir_t pgdir, struct page *page, void *va,
			int perm);
void page_remove(pgdir_t pgdir, void *va);
page_t* page_lookup(pgdir_t pgdir, void *va, pte_t *pte_store);
error_t	pagetable_remove(pgdir_t pgdir, void *va);
void	page_decref(page_t *pp);

void	tlb_invalidate(pgdir_t pgdir, void *ga);
void tlb_flush_global(void);
bool regions_collide_unsafe(uintptr_t start1, uintptr_t end1,
                            uintptr_t start2, uintptr_t end2);

/* Arch specific implementations for these */
pte_t pgdir_walk(pgdir_t pgdir, const void *va, int create);
int get_va_perms(pgdir_t pgdir, const void *va);
int arch_pgdir_setup(pgdir_t boot_copy, pgdir_t *new_pd);
physaddr_t arch_pgdir_get_cr3(pgdir_t pd);
void arch_pgdir_clear(pgdir_t *pd);
int arch_max_jumbo_page_shift(void);

static inline page_t *ppn2page(size_t ppn)
{
	if (ppn >= max_nr_pages)
		warn("ppn2page called with ppn (%08lu) larger than max_nr_pages", ppn);
	return &(pages[ppn]);
}

static inline ppn_t page2ppn(page_t *pp)
{
	return pp - pages;
}

static inline physaddr_t page2pa(page_t *pp)
{
	return page2ppn(pp) << PGSHIFT;
}

static inline page_t *pa2page(physaddr_t pa)
{
	if (LA2PPN(pa) >= max_nr_pages)
		warn("pa2page called with pa (%p) larger than max_nr_pages", pa);
	return &pages[LA2PPN(pa)];
}

static inline ppn_t pa2ppn(physaddr_t pa)
{
	return pa >> PGSHIFT;
}

static inline void *page2kva(page_t *pp)
{
	return KADDR(page2pa(pp));
}

static inline void *ppn2kva(size_t pp)
{
	return page2kva(ppn2page(pp));
}

static inline page_t* kva2page(void* addr)
{
	return pa2page(PADDR(addr));
}

static inline ppn_t kva2ppn(void* addr)
{
	return page2ppn(kva2page(addr));
}

static inline bool is_kaddr(void *addr)
{
	return (uintptr_t)addr >= KERNBASE;
}

static inline unsigned long nr_pages(size_t nr_bytes)
{
	return (nr_bytes >> PGSHIFT) + (PGOFF(nr_bytes) ? 1 : 0);
}

/* Including here, since these ops often rely on pmap.h helpers, which rely on
 * the generic arch/pmap.h.  It's likely that many of these ops will be inlined
 * for speed in pmap_ops. */
#include <arch/pmap_ops.h>
