/* 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 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);
void tlb_shootdown_global(void);
bool regions_collide_unsafe(uintptr_t start1, uintptr_t end1,
                            uintptr_t start2, uintptr_t end2);

/* Arch specific implementations for these */
void map_segment(pgdir_t pgdir, uintptr_t va, size_t size, physaddr_t pa,
                 int perm, int pml_shift);
int unmap_segment(pgdir_t pgdir, uintptr_t va, size_t size);
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);
void arch_add_intermediate_pts(pgdir_t pgdir, uintptr_t va, size_t len);

static inline page_t *ppn2page(size_t ppn)
{
	if (ppn >= max_nr_pages)
		warn("%s called with ppn (%p) larger than max_nr_pages (%p)",
		     __func__, ppn, max_nr_pages);
	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("%s called with pa (%p) larger than max_nr_pages (%p)",
		     __func__, pa, max_nr_pages);
	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>
