/*
 * arch/xtensa/mm/init.c
 *
 * Derived from MIPS, PPC.
 *
 * This file is subject to the terms and conditions of the GNU General Public
 * License.  See the file "COPYING" in the main directory of this archive
 * for more details.
 *
 * Copyright (C) 2001 - 2005 Tensilica Inc.
 *
 * Chris Zankel	<chris@zankel.net>
 * Joe Taylor	<joe@tensilica.com, joetylr@yahoo.com>
 * Marc Gauthier
 * Kevin Chea
 */

#include <linux/init.h>
#include <linux/signal.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/errno.h>
#include <linux/string.h>
#include <linux/types.h>
#include <linux/ptrace.h>
#include <linux/bootmem.h>
#include <linux/swap.h>

#include <asm/pgtable.h>
#include <asm/bootparam.h>
#include <asm/mmu_context.h>
#include <asm/tlb.h>
#include <asm/tlbflush.h>
#include <asm/page.h>
#include <asm/pgalloc.h>
#include <asm/pgtable.h>


#define DEBUG 0

DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
//static DEFINE_SPINLOCK(tlb_lock);

/*
 * This flag is used to indicate that the page was mapped and modified in
 * kernel space, so the cache is probably dirty at that address.
 * If cache aliasing is enabled and the page color mismatches, update_mmu_cache
 * synchronizes the caches if this bit is set.
 */

#define PG_cache_clean PG_arch_1

/* References to section boundaries */

extern char _ftext, _etext, _fdata, _edata, _rodata_end;
extern char __init_begin, __init_end;

/*
 * mem_reserve(start, end, must_exist)
 *
 * Reserve some memory from the memory pool.
 *
 * Parameters:
 *  start	Start of region,
 *  end		End of region,
 *  must_exist	Must exist in memory pool.
 *
 * Returns:
 *  0 (memory area couldn't be mapped)
 * -1 (success)
 */

int __init mem_reserve(unsigned long start, unsigned long end, int must_exist)
{
	int i;

	if (start == end)
		return 0;

	start = start & PAGE_MASK;
	end = PAGE_ALIGN(end);

	for (i = 0; i < sysmem.nr_banks; i++)
		if (start < sysmem.bank[i].end
		    && end >= sysmem.bank[i].start)
			break;

	if (i == sysmem.nr_banks) {
		if (must_exist)
			printk (KERN_WARNING "mem_reserve: [0x%0lx, 0x%0lx) "
				"not in any region!\n", start, end);
		return 0;
	}

	if (start > sysmem.bank[i].start) {
		if (end < sysmem.bank[i].end) {
			/* split entry */
			if (sysmem.nr_banks >= SYSMEM_BANKS_MAX)
				panic("meminfo overflow\n");
			sysmem.bank[sysmem.nr_banks].start = end;
			sysmem.bank[sysmem.nr_banks].end = sysmem.bank[i].end;
			sysmem.nr_banks++;
		}
		sysmem.bank[i].end = start;
	} else {
		if (end < sysmem.bank[i].end)
			sysmem.bank[i].start = end;
		else {
			/* remove entry */
			sysmem.nr_banks--;
			sysmem.bank[i].start = sysmem.bank[sysmem.nr_banks].start;
			sysmem.bank[i].end   = sysmem.bank[sysmem.nr_banks].end;
		}
	}
	return -1;
}


/*
 * Initialize the bootmem system and give it all the memory we have available.
 */

void __init bootmem_init(void)
{
	unsigned long pfn;
	unsigned long bootmap_start, bootmap_size;
	int i;

	max_low_pfn = max_pfn = 0;
	min_low_pfn = ~0;

	for (i=0; i < sysmem.nr_banks; i++) {
		pfn = PAGE_ALIGN(sysmem.bank[i].start) >> PAGE_SHIFT;
		if (pfn < min_low_pfn)
			min_low_pfn = pfn;
		pfn = PAGE_ALIGN(sysmem.bank[i].end - 1) >> PAGE_SHIFT;
		if (pfn > max_pfn)
			max_pfn = pfn;
	}

	if (min_low_pfn > max_pfn)
		panic("No memory found!\n");

	max_low_pfn = max_pfn < MAX_LOW_MEMORY >> PAGE_SHIFT ?
		max_pfn : MAX_LOW_MEMORY >> PAGE_SHIFT;

	/* Find an area to use for the bootmem bitmap. */

	bootmap_size = bootmem_bootmap_pages(max_low_pfn) << PAGE_SHIFT;
	bootmap_start = ~0;

	for (i=0; i<sysmem.nr_banks; i++)
		if (sysmem.bank[i].end - sysmem.bank[i].start >= bootmap_size) {
			bootmap_start = sysmem.bank[i].start;
			break;
		}

	if (bootmap_start == ~0UL)
		panic("Cannot find %ld bytes for bootmap\n", bootmap_size);

	/* Reserve the bootmem bitmap area */

	mem_reserve(bootmap_start, bootmap_start + bootmap_size, 1);
	bootmap_size = init_bootmem_node(NODE_DATA(0), min_low_pfn,
					 bootmap_start >> PAGE_SHIFT,
					 max_low_pfn);

	/* Add all remaining memory pieces into the bootmem map */

	for (i=0; i<sysmem.nr_banks; i++)
		free_bootmem(sysmem.bank[i].start,
			     sysmem.bank[i].end - sysmem.bank[i].start);

}


void __init paging_init(void)
{
	unsigned long zones_size[MAX_NR_ZONES];
	int i;

	/* All pages are DMA-able, so we put them all in the DMA zone. */

	zones_size[ZONE_DMA] = max_low_pfn;
	for (i = 1; i < MAX_NR_ZONES; i++)
		zones_size[i] = 0;

#ifdef CONFIG_HIGHMEM
	zones_size[ZONE_HIGHMEM] = max_pfn - max_low_pfn;
#endif

	/* Initialize the kernel's page tables. */

	memset(swapper_pg_dir, 0, PAGE_SIZE);

	free_area_init(zones_size);
}

/*
 * Flush the mmu and reset associated register to default values.
 */

void __init init_mmu (void)
{
	/* Writing zeros to the <t>TLBCFG special registers ensure
	 * that valid values exist in the register.  For existing
	 * PGSZID<w> fields, zero selects the first element of the
	 * page-size array.  For nonexistant PGSZID<w> fields, zero is
	 * the best value to write.  Also, when changing PGSZID<w>
	 * fields, the corresponding TLB must be flushed.
	 */
	set_itlbcfg_register (0);
	set_dtlbcfg_register (0);
	flush_tlb_all ();

	/* Set rasid register to a known value. */

	set_rasid_register (ASID_ALL_RESERVED);

	/* Set PTEVADDR special register to the start of the page
	 * table, which is in kernel mappable space (ie. not
	 * statically mapped).  This register's value is undefined on
	 * reset.
	 */
	set_ptevaddr_register (PGTABLE_START);
}

/*
 * Initialize memory pages.
 */

void __init mem_init(void)
{
	unsigned long codesize, reservedpages, datasize, initsize;
	unsigned long highmemsize, tmp, ram;

	max_mapnr = num_physpages = max_low_pfn;
	high_memory = (void *) __va(max_mapnr << PAGE_SHIFT);
	highmemsize = 0;

#ifdef CONFIG_HIGHMEM
#error HIGHGMEM not implemented in init.c
#endif

	totalram_pages += free_all_bootmem();

	reservedpages = ram = 0;
	for (tmp = 0; tmp < max_low_pfn; tmp++) {
		ram++;
		if (PageReserved(mem_map+tmp))
			reservedpages++;
	}

	codesize =  (unsigned long) &_etext - (unsigned long) &_ftext;
	datasize =  (unsigned long) &_edata - (unsigned long) &_fdata;
	initsize =  (unsigned long) &__init_end - (unsigned long) &__init_begin;

	printk("Memory: %luk/%luk available (%ldk kernel code, %ldk reserved, "
	       "%ldk data, %ldk init %ldk highmem)\n",
	       (unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
	       ram << (PAGE_SHIFT-10),
	       codesize >> 10,
	       reservedpages << (PAGE_SHIFT-10),
	       datasize >> 10,
	       initsize >> 10,
	       highmemsize >> 10);
}

void
free_reserved_mem(void *start, void *end)
{
	for (; start < end; start += PAGE_SIZE) {
		ClearPageReserved(virt_to_page(start));
		init_page_count(virt_to_page(start));
		free_page((unsigned long)start);
		totalram_pages++;
	}
}

#ifdef CONFIG_BLK_DEV_INITRD
extern int initrd_is_mapped;

void free_initrd_mem(unsigned long start, unsigned long end)
{
	if (initrd_is_mapped) {
		free_reserved_mem((void*)start, (void*)end);
		printk ("Freeing initrd memory: %ldk freed\n",(end-start)>>10);
	}
}
#endif

void free_initmem(void)
{
	free_reserved_mem(&__init_begin, &__init_end);
	printk("Freeing unused kernel memory: %dk freed\n",
	       (&__init_end - &__init_begin) >> 10);
}

void show_mem(void)
{
	int i, free = 0, total = 0, reserved = 0;
	int shared = 0, cached = 0;

	printk("Mem-info:\n");
	show_free_areas();
	printk("Free swap:       %6ldkB\n", nr_swap_pages<<(PAGE_SHIFT-10));
	i = max_mapnr;
	while (i-- > 0) {
		total++;
		if (PageReserved(mem_map+i))
			reserved++;
		else if (PageSwapCache(mem_map+i))
			cached++;
		else if (!page_count(mem_map + i))
			free++;
		else
			shared += page_count(mem_map + i) - 1;
	}
	printk("%d pages of RAM\n", total);
	printk("%d reserved pages\n", reserved);
	printk("%d pages shared\n", shared);
	printk("%d pages swap cached\n",cached);
	printk("%d free pages\n", free);
}

/* ------------------------------------------------------------------------- */

#if (DCACHE_WAY_SIZE > PAGE_SIZE)

/*
 * With cache aliasing, the page color of the page in kernel space and user
 * space might mismatch. We temporarily map the page to a different virtual
 * address with the same color and clear the page there.
 */

void clear_user_page(void *kaddr, unsigned long vaddr, struct page* page)
{

  	/*  There shouldn't be any entries for this page. */

	__flush_invalidate_dcache_page_phys(__pa(page_address(page)));

	if (!PAGE_COLOR_EQ(vaddr, kaddr)) {
		unsigned long v, p;

		/* Temporarily map page to DTLB_WAY_DCACHE_ALIAS0. */

		spin_lock(&tlb_lock);

		p = (unsigned long)pte_val((mk_pte(page,PAGE_KERNEL)));
		kaddr = (void*)PAGE_COLOR_MAP0(vaddr);
		v = (unsigned long)kaddr | DTLB_WAY_DCACHE_ALIAS0;
		__asm__ __volatile__("wdtlb %0,%1; dsync" : :"a" (p), "a" (v));

		clear_page(kaddr);

		spin_unlock(&tlb_lock);
	} else {
		clear_page(kaddr);
	}

	/* We need to make sure that i$ and d$ are coherent. */

	clear_bit(PG_cache_clean, &page->flags);
}

/*
 * With cache aliasing, we have to make sure that the page color of the page
 * in kernel space matches that of the virtual user address before we read
 * the page. If the page color differ, we create a temporary DTLB entry with
 * the corrent page color and use this 'temporary' address as the source.
 * We then use the same approach as in clear_user_page and copy the data
 * to the kernel space and clear the PG_cache_clean bit to synchronize caches
 * later.
 *
 * Note:
 * Instead of using another 'way' for the temporary DTLB entry, we could
 * probably use the same entry that points to the kernel address (after
 * saving the original value and restoring it when we are done).
 */

void copy_user_page(void* to, void* from, unsigned long vaddr,
    		    struct page* to_page)
{
	/* There shouldn't be any entries for the new page. */

	__flush_invalidate_dcache_page_phys(__pa(page_address(to_page)));

	spin_lock(&tlb_lock);

	if (!PAGE_COLOR_EQ(vaddr, from)) {
		unsigned long v, p, t;

		__asm__ __volatile__ ("pdtlb %1,%2; rdtlb1 %0,%1"
				      : "=a"(p), "=a"(t) : "a"(from));
		from = (void*)PAGE_COLOR_MAP0(vaddr);
		v = (unsigned long)from | DTLB_WAY_DCACHE_ALIAS0;
		__asm__ __volatile__ ("wdtlb %0,%1; dsync" ::"a" (p), "a" (v));
	}

	if (!PAGE_COLOR_EQ(vaddr, to)) {
		unsigned long v, p;

		p = (unsigned long)pte_val((mk_pte(to_page,PAGE_KERNEL)));
		to = (void*)PAGE_COLOR_MAP1(vaddr);
		v = (unsigned long)to | DTLB_WAY_DCACHE_ALIAS1;
		__asm__ __volatile__ ("wdtlb %0,%1; dsync" ::"a" (p), "a" (v));
	}
	copy_page(to, from);

	spin_unlock(&tlb_lock);

	/* We need to make sure that i$ and d$ are coherent. */

	clear_bit(PG_cache_clean, &to_page->flags);
}



/*
 * Any time the kernel writes to a user page cache page, or it is about to
 * read from a page cache page this routine is called.
 *
 * Note:
 * The kernel currently only provides one architecture bit in the page
 * flags that we use for I$/D$ coherency. Maybe, in future, we can
 * use a sepearte bit for deferred dcache aliasing:
 * If the page is not mapped yet, we only need to set a flag,
 * if mapped, we need to invalidate the page.
 */
// FIXME: we probably need this for WB caches not only for Page Coloring..

void flush_dcache_page(struct page *page)
{
	unsigned long addr = __pa(page_address(page));
	struct address_space *mapping = page_mapping(page);

	__flush_invalidate_dcache_page_phys(addr);

	if (!test_bit(PG_cache_clean, &page->flags))
		return;

	/* If this page hasn't been mapped, yet, handle I$/D$ coherency later.*/
#if 0
	if (mapping && !mapping_mapped(mapping))
		clear_bit(PG_cache_clean, &page->flags);
	else
#endif
		__invalidate_icache_page_phys(addr);
}

void flush_cache_range(struct vm_area_struct* vma, unsigned long s,
		       unsigned long e)
{
	__flush_invalidate_cache_all();
}

void flush_cache_page(struct vm_area_struct* vma, unsigned long address,
    		      unsigned long pfn)
{
	struct page *page = pfn_to_page(pfn);

	/* Remove any entry for the old mapping. */

	if (current->active_mm == vma->vm_mm) {
		unsigned long addr = __pa(page_address(page));
		__flush_invalidate_dcache_page_phys(addr);
		if ((vma->vm_flags & VM_EXEC) != 0)
			__invalidate_icache_page_phys(addr);
	} else {
		BUG();
	}
}

#endif	/* (DCACHE_WAY_SIZE > PAGE_SIZE) */


pte_t* pte_alloc_one_kernel (struct mm_struct* mm, unsigned long addr)
{
	pte_t* pte = (pte_t*)__get_free_pages(GFP_KERNEL|__GFP_REPEAT, 0);
	if (likely(pte)) {
	       	pte_t* ptep = (pte_t*)(pte_val(*pte) + PAGE_OFFSET);
		int i;
		for (i = 0; i < 1024; i++, ptep++)
			pte_clear(mm, addr, ptep);
	}
	return pte;
}

struct page* pte_alloc_one(struct mm_struct *mm, unsigned long addr)
{
	struct page *page;

	page = alloc_pages(GFP_KERNEL | __GFP_REPEAT, 0);

	if (likely(page)) {
		pte_t* ptep = kmap_atomic(page, KM_USER0);
		int i;

		for (i = 0; i < 1024; i++, ptep++)
			pte_clear(mm, addr, ptep);

		kunmap_atomic(ptep, KM_USER0);
	}
	return page;
}


/*
 * Handle D$/I$ coherency.
 *
 * Note:
 * We only have one architecture bit for the page flags, so we cannot handle
 * cache aliasing, yet.
 */

void
update_mmu_cache(struct vm_area_struct * vma, unsigned long addr, pte_t pte)
{
	unsigned long pfn = pte_pfn(pte);
	struct page *page;
	unsigned long vaddr = addr & PAGE_MASK;

	if (!pfn_valid(pfn))
		return;

	page = pfn_to_page(pfn);

	invalidate_itlb_mapping(addr);
	invalidate_dtlb_mapping(addr);

	/* We have a new mapping. Use it. */

	write_dtlb_entry(pte, dtlb_probe(addr));

	/* If the processor can execute from this page, synchronize D$/I$. */

	if ((vma->vm_flags & VM_EXEC) != 0) {

		write_itlb_entry(pte, itlb_probe(addr));

		/* Synchronize caches, if not clean. */

		if (!test_and_set_bit(PG_cache_clean, &page->flags)) {
			__flush_dcache_page(vaddr);
			__invalidate_icache_page(vaddr);
		}
	}
}

