/* 
 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
 * Licensed under the GPL
 */

#include "linux/mm.h"
#include "asm/page.h"
#include "asm/pgalloc.h"
#include "asm/tlbflush.h"
#include "choose-mode.h"
#include "mode_kern.h"
#include "user_util.h"
#include "tlb.h"
#include "mem.h"
#include "mem_user.h"
#include "os.h"

#define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1))

void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
                      unsigned long end_addr, int force, int data,
                      void (*do_ops)(int, struct host_vm_op *, int))
{
        pgd_t *npgd;
        pud_t *npud;
        pmd_t *npmd;
        pte_t *npte;
        unsigned long addr, end;
        int r, w, x;
        struct host_vm_op ops[16];
        int op_index = -1, last_op = sizeof(ops) / sizeof(ops[0]) - 1;

        if(mm == NULL) return;

        for(addr = start_addr; addr < end_addr;){
                npgd = pgd_offset(mm, addr);
                if(!pgd_present(*npgd)){
                        end = ADD_ROUND(addr, PGDIR_SIZE);
                        if(end > end_addr)
                                end = end_addr;
                        if(force || pgd_newpage(*npgd)){
                                op_index = add_munmap(addr, end - addr, ops,
                                                      op_index, last_op, data,
                                                      do_ops);
                                pgd_mkuptodate(*npgd);
                        }
                        addr = end;
                        continue;
                }

                npud = pud_offset(npgd, addr);
                if(!pud_present(*npud)){
                        end = ADD_ROUND(addr, PUD_SIZE);
                        if(end > end_addr)
                                end = end_addr;
                        if(force || pud_newpage(*npud)){
                                op_index = add_munmap(addr, end - addr, ops,
                                                      op_index, last_op, data,
                                                      do_ops);
                                pud_mkuptodate(*npud);
                        }
                        addr = end;
                        continue;
                }

                npmd = pmd_offset(npud, addr);
                if(!pmd_present(*npmd)){
                        end = ADD_ROUND(addr, PMD_SIZE);
                        if(end > end_addr)
                                end = end_addr;
                        if(force || pmd_newpage(*npmd)){
                                op_index = add_munmap(addr, end - addr, ops,
                                                      op_index, last_op, data,
                                                      do_ops);
                                pmd_mkuptodate(*npmd);
                        }
                        addr = end;
                        continue;
                }

                npte = pte_offset_kernel(npmd, addr);
                r = pte_read(*npte);
                w = pte_write(*npte);
                x = pte_exec(*npte);
                if(!pte_dirty(*npte))
                        w = 0;
                if(!pte_young(*npte)){
                        r = 0;
                        w = 0;
                }
                if(force || pte_newpage(*npte)){
                        if(pte_present(*npte))
                                op_index = add_mmap(addr,
                                                    pte_val(*npte) & PAGE_MASK,
                                                    PAGE_SIZE, r, w, x, ops,
                                                    op_index, last_op, data,
                                                    do_ops);
                        else op_index = add_munmap(addr, PAGE_SIZE, ops,
                                                   op_index, last_op, data,
                                                   do_ops);
                }
                else if(pte_newprot(*npte))
                        op_index = add_mprotect(addr, PAGE_SIZE, r, w, x, ops,
                                                op_index, last_op, data,
                                                do_ops);

                *npte = pte_mkuptodate(*npte);
                addr += PAGE_SIZE;
        }
        (*do_ops)(data, ops, op_index);
}

int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
{
        struct mm_struct *mm;
        pgd_t *pgd;
        pud_t *pud;
        pmd_t *pmd;
        pte_t *pte;
        unsigned long addr, last;
        int updated = 0, err;

        mm = &init_mm;
        for(addr = start; addr < end;){
                pgd = pgd_offset(mm, addr);
                if(!pgd_present(*pgd)){
                        last = ADD_ROUND(addr, PGDIR_SIZE);
                        if(last > end)
                                last = end;
                        if(pgd_newpage(*pgd)){
                                updated = 1;
                                err = os_unmap_memory((void *) addr,
                                                      last - addr);
                                if(err < 0)
                                        panic("munmap failed, errno = %d\n",
                                              -err);
                        }
                        addr = last;
                        continue;
                }

                pud = pud_offset(pgd, addr);
                if(!pud_present(*pud)){
                        last = ADD_ROUND(addr, PUD_SIZE);
                        if(last > end)
                                last = end;
                        if(pud_newpage(*pud)){
                                updated = 1;
                                err = os_unmap_memory((void *) addr,
                                                      last - addr);
                                if(err < 0)
                                        panic("munmap failed, errno = %d\n",
                                              -err);
                        }
                        addr = last;
                        continue;
                }

                pmd = pmd_offset(pud, addr);
                if(!pmd_present(*pmd)){
                        last = ADD_ROUND(addr, PMD_SIZE);
                        if(last > end)
                                last = end;
                        if(pmd_newpage(*pmd)){
                                updated = 1;
                                err = os_unmap_memory((void *) addr,
                                                      last - addr);
                                if(err < 0)
                                        panic("munmap failed, errno = %d\n",
                                              -err);
                        }
                        addr = last;
                        continue;
                }

                pte = pte_offset_kernel(pmd, addr);
                if(!pte_present(*pte) || pte_newpage(*pte)){
                        updated = 1;
                        err = os_unmap_memory((void *) addr,
                                              PAGE_SIZE);
                        if(err < 0)
                                panic("munmap failed, errno = %d\n",
                                      -err);
                        if(pte_present(*pte))
                                map_memory(addr,
                                           pte_val(*pte) & PAGE_MASK,
                                           PAGE_SIZE, 1, 1, 1);
                }
                else if(pte_newprot(*pte)){
                        updated = 1;
                        protect_memory(addr, PAGE_SIZE, 1, 1, 1, 1);
                }
                addr += PAGE_SIZE;
        }
        return(updated);
}

void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
{
        address &= PAGE_MASK;
        flush_tlb_range(vma, address, address + PAGE_SIZE);
}

void flush_tlb_all(void)
{
        flush_tlb_mm(current->mm);
}
  
void flush_tlb_kernel_range(unsigned long start, unsigned long end)
{
        CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt,
                         flush_tlb_kernel_range_common, start, end);
}

void flush_tlb_kernel_vm(void)
{
        CHOOSE_MODE(flush_tlb_kernel_vm_tt(),
                    flush_tlb_kernel_range_common(start_vm, end_vm));
}

void __flush_tlb_one(unsigned long addr)
{
        CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr);
}

void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, 
     unsigned long end)
{
        CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, vma, start,
                         end);
}

void flush_tlb_mm(struct mm_struct *mm)
{
        CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm);
}

void force_flush_all(void)
{
        CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas());
}

pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
{
        return(pgd_offset(mm, address));
}

pud_t *pud_offset_proc(pgd_t *pgd, unsigned long address)
{
        return(pud_offset(pgd, address));
}

pmd_t *pmd_offset_proc(pud_t *pud, unsigned long address)
{
        return(pmd_offset(pud, address));
}

pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
{
        return(pte_offset_kernel(pmd, address));
}

pte_t *addr_pte(struct task_struct *task, unsigned long addr)
{
        pgd_t *pgd = pgd_offset(task->mm, addr);
        pud_t *pud = pud_offset(pgd, addr);
        pmd_t *pmd = pmd_offset(pud, addr);

        return(pte_offset_map(pmd, addr));
}

int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
     int r, int w, int x, struct host_vm_op *ops, int index,
     int last_filled, int data,
     void (*do_ops)(int, struct host_vm_op *, int))
{
        __u64 offset;
	struct host_vm_op *last;
	int fd;

	fd = phys_mapping(phys, &offset);
	if(index != -1){
		last = &ops[index];
		if((last->type == MMAP) &&
		   (last->u.mmap.addr + last->u.mmap.len == virt) &&
		   (last->u.mmap.r == r) && (last->u.mmap.w == w) &&
		   (last->u.mmap.x == x) && (last->u.mmap.fd == fd) &&
		   (last->u.mmap.offset + last->u.mmap.len == offset)){
			last->u.mmap.len += len;
			return(index);
		}
	}

	if(index == last_filled){
		(*do_ops)(data, ops, last_filled);
		index = -1;
	}

	ops[++index] = ((struct host_vm_op) { .type	= MMAP,
					      .u = { .mmap = {
						      .addr	= virt,
						      .len	= len,
						      .r	= r,
						      .w	= w,
						      .x	= x,
						      .fd	= fd,
						      .offset	= offset }
					      } });
	return(index);
}

int add_munmap(unsigned long addr, unsigned long len, struct host_vm_op *ops,
	       int index, int last_filled, int data,
	       void (*do_ops)(int, struct host_vm_op *, int))
{
	struct host_vm_op *last;

	if(index != -1){
		last = &ops[index];
		if((last->type == MUNMAP) &&
		   (last->u.munmap.addr + last->u.mmap.len == addr)){
			last->u.munmap.len += len;
			return(index);
		}
	}

	if(index == last_filled){
		(*do_ops)(data, ops, last_filled);
		index = -1;
	}

	ops[++index] = ((struct host_vm_op) { .type	= MUNMAP,
					      .u = { .munmap = {
						      .addr	= addr,
						      .len	= len } } });
	return(index);
}

int add_mprotect(unsigned long addr, unsigned long len, int r, int w, int x,
		 struct host_vm_op *ops, int index, int last_filled, int data,
		 void (*do_ops)(int, struct host_vm_op *, int))
{
	struct host_vm_op *last;

	if(index != -1){
		last = &ops[index];
		if((last->type == MPROTECT) &&
		   (last->u.mprotect.addr + last->u.mprotect.len == addr) &&
		   (last->u.mprotect.r == r) && (last->u.mprotect.w == w) &&
		   (last->u.mprotect.x == x)){
			last->u.mprotect.len += len;
			return(index);
		}
	}

	if(index == last_filled){
		(*do_ops)(data, ops, last_filled);
		index = -1;
	}

	ops[++index] = ((struct host_vm_op) { .type	= MPROTECT,
					      .u = { .mprotect = {
						      .addr	= addr,
						      .len	= len,
						      .r	= r,
						      .w	= w,
						      .x	= x } } });
	return(index);
}
