/*
 * arch/score/mm/tlb-score.c
 *
 * Score Processor version.
 *
 * Copyright (C) 2009 Sunplus Core Technology Co., Ltd.
 *  Lennox Wu <lennox.wu@sunplusct.com>
 *  Chen Liqin <liqin.chen@sunplusct.com>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, see the file COPYING, or write
 * to the Free Software Foundation, Inc.,
 * 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
 */

#include <linux/highmem.h>
#include <linux/module.h>

#include <asm/irq.h>
#include <asm/mmu_context.h>
#include <asm/tlb.h>

#define TLBSIZE 32

unsigned long asid_cache = ASID_FIRST_VERSION;
EXPORT_SYMBOL(asid_cache);

void local_flush_tlb_all(void)
{
	unsigned long flags;
	unsigned long old_ASID;
	int entry;

	local_irq_save(flags);
	old_ASID = pevn_get() & ASID_MASK;
	pectx_set(0);			/* invalid */
	entry = tlblock_get();		/* skip locked entries*/

	for (; entry < TLBSIZE; entry++) {
		tlbpt_set(entry);
		pevn_set(KSEG1);
		barrier();
		tlb_write_indexed();
	}
	pevn_set(old_ASID);
	local_irq_restore(flags);
}

/*
 * If mm is currently active_mm, we can't really drop it. Instead,
 * we will get a new one for it.
 */
static inline void
drop_mmu_context(struct mm_struct *mm)
{
	unsigned long flags;

	local_irq_save(flags);
	get_new_mmu_context(mm);
	pevn_set(mm->context & ASID_MASK);
	local_irq_restore(flags);
}

void local_flush_tlb_mm(struct mm_struct *mm)
{
	if (mm->context != 0)
		drop_mmu_context(mm);
}

void local_flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
	unsigned long end)
{
	struct mm_struct *mm = vma->vm_mm;
	unsigned long vma_mm_context = mm->context;
	if (mm->context != 0) {
		unsigned long flags;
		int size;

		local_irq_save(flags);
		size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
		if (size <= TLBSIZE) {
			int oldpid = pevn_get() & ASID_MASK;
			int newpid = vma_mm_context & ASID_MASK;

			start &= PAGE_MASK;
			end += (PAGE_SIZE - 1);
			end &= PAGE_MASK;
			while (start < end) {
				int idx;

				pevn_set(start | newpid);
				start += PAGE_SIZE;
				barrier();
				tlb_probe();
				idx = tlbpt_get();
				pectx_set(0);
				pevn_set(KSEG1);
				if (idx < 0)
					continue;
				tlb_write_indexed();
			}
			pevn_set(oldpid);
		} else {
			/* Bigger than TLBSIZE, get new ASID directly */
			get_new_mmu_context(mm);
			if (mm == current->active_mm)
				pevn_set(vma_mm_context & ASID_MASK);
		}
		local_irq_restore(flags);
	}
}

void local_flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
	unsigned long flags;
	int size;

	local_irq_save(flags);
	size = (end - start + (PAGE_SIZE - 1)) >> PAGE_SHIFT;
	if (size <= TLBSIZE) {
		int pid = pevn_get();

		start &= PAGE_MASK;
		end += PAGE_SIZE - 1;
		end &= PAGE_MASK;

		while (start < end) {
			long idx;

			pevn_set(start);
			start += PAGE_SIZE;
			tlb_probe();
			idx = tlbpt_get();
			if (idx < 0)
				continue;
			pectx_set(0);
			pevn_set(KSEG1);
			barrier();
			tlb_write_indexed();
		}
		pevn_set(pid);
	} else {
		local_flush_tlb_all();
	}

	local_irq_restore(flags);
}

void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long page)
{
	if (!vma || vma->vm_mm->context != 0) {
		unsigned long flags;
		int oldpid, newpid, idx;
		unsigned long vma_ASID = vma->vm_mm->context;

		newpid = vma_ASID & ASID_MASK;
		page &= PAGE_MASK;
		local_irq_save(flags);
		oldpid = pevn_get() & ASID_MASK;
		pevn_set(page | newpid);
		barrier();
		tlb_probe();
		idx = tlbpt_get();
		pectx_set(0);
		pevn_set(KSEG1);
		if (idx < 0)		/* p_bit(31) - 1: miss, 0: hit*/
			goto finish;
		barrier();
		tlb_write_indexed();
finish:
		pevn_set(oldpid);
		local_irq_restore(flags);
	}
}

/*
 * This one is only used for pages with the global bit set so we don't care
 * much about the ASID.
 */
void local_flush_tlb_one(unsigned long page)
{
	unsigned long flags;
	int oldpid, idx;

	local_irq_save(flags);
	oldpid = pevn_get();
	page &= (PAGE_MASK << 1);
	pevn_set(page);
	barrier();
	tlb_probe();
	idx = tlbpt_get();
	pectx_set(0);
	if (idx >= 0) {
		/* Make sure all entries differ. */
		pevn_set(KSEG1);
		barrier();
		tlb_write_indexed();
	}
	pevn_set(oldpid);
	local_irq_restore(flags);
}

void __update_tlb(struct vm_area_struct *vma, unsigned long address, pte_t pte)
{
	unsigned long flags;
	int idx, pid;

	/*
	 * Handle debugger faulting in for debugee.
	 */
	if (current->active_mm != vma->vm_mm)
		return;

	pid = pevn_get() & ASID_MASK;

	local_irq_save(flags);
	address &= PAGE_MASK;
	pevn_set(address | pid);
	barrier();
	tlb_probe();
	idx = tlbpt_get();
	pectx_set(pte_val(pte));
	pevn_set(address | pid);
	if (idx < 0)
		tlb_write_random();
	else
		tlb_write_indexed();

	pevn_set(pid);
	local_irq_restore(flags);
}

void __cpuinit tlb_init(void)
{
	tlblock_set(0);
	local_flush_tlb_all();
	memcpy((void *)(EXCEPTION_VECTOR_BASE_ADDR + 0x100),
			&score7_FTLB_refill_Handler, 0xFC);
	flush_icache_range(EXCEPTION_VECTOR_BASE_ADDR + 0x100,
			EXCEPTION_VECTOR_BASE_ADDR + 0x1FC);
}
