/*
 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
 * Licensed under the GPL
 */

#include "linux/mm.h"
#include "linux/rbtree.h"
#include "linux/slab.h"
#include "linux/vmalloc.h"
#include "linux/bootmem.h"
#include "linux/module.h"
#include "asm/types.h"
#include "asm/pgtable.h"
#include "kern_util.h"
#include "user_util.h"
#include "mode_kern.h"
#include "mem.h"
#include "mem_user.h"
#include "os.h"
#include "kern.h"
#include "init.h"

struct phys_desc {
	struct rb_node rb;
	int fd;
	__u64 offset;
	void *virt;
	unsigned long phys;
	struct list_head list;
};

static struct rb_root phys_mappings = RB_ROOT;

static struct rb_node **find_rb(void *virt)
{
	struct rb_node **n = &phys_mappings.rb_node;
	struct phys_desc *d;

	while(*n != NULL){
		d = rb_entry(*n, struct phys_desc, rb);
		if(d->virt == virt)
			return(n);

		if(d->virt > virt)
			n = &(*n)->rb_left;
		else
			n = &(*n)->rb_right;
	}

	return(n);
}

static struct phys_desc *find_phys_mapping(void *virt)
{
	struct rb_node **n = find_rb(virt);

	if(*n == NULL)
		return(NULL);

	return(rb_entry(*n, struct phys_desc, rb));
}

static void insert_phys_mapping(struct phys_desc *desc)
{
	struct rb_node **n = find_rb(desc->virt);

	if(*n != NULL)
		panic("Physical remapping for %p already present",
		      desc->virt);

	rb_link_node(&desc->rb, (*n)->rb_parent, n);
	rb_insert_color(&desc->rb, &phys_mappings);
}

LIST_HEAD(descriptor_mappings);

struct desc_mapping {
	int fd;
	struct list_head list;
	struct list_head pages;
};

static struct desc_mapping *find_mapping(int fd)
{
	struct desc_mapping *desc;
	struct list_head *ele;

	list_for_each(ele, &descriptor_mappings){
		desc = list_entry(ele, struct desc_mapping, list);
		if(desc->fd == fd)
			return(desc);
	}

	return(NULL);
}

static struct desc_mapping *descriptor_mapping(int fd)
{
	struct desc_mapping *desc;

	desc = find_mapping(fd);
	if(desc != NULL)
		return(desc);

	desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
	if(desc == NULL)
		return(NULL);

	*desc = ((struct desc_mapping)
		{ .fd =		fd,
		  .list =	LIST_HEAD_INIT(desc->list),
		  .pages =	LIST_HEAD_INIT(desc->pages) });
	list_add(&desc->list, &descriptor_mappings);

	return(desc);
}

int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w)
{
	struct desc_mapping *fd_maps;
	struct phys_desc *desc;
	unsigned long phys;
	int err;

	fd_maps = descriptor_mapping(fd);
	if(fd_maps == NULL)
		return(-ENOMEM);

	phys = __pa(virt);
	desc = find_phys_mapping(virt);
  	if(desc != NULL)
		panic("Address 0x%p is already substituted\n", virt);

	err = -ENOMEM;
	desc = kmalloc(sizeof(*desc), GFP_ATOMIC);
	if(desc == NULL)
		goto out;

	*desc = ((struct phys_desc)
		{ .fd =			fd,
		  .offset =		offset,
		  .virt =		virt,
		  .phys =		__pa(virt),
		  .list = 		LIST_HEAD_INIT(desc->list) });
	insert_phys_mapping(desc);

	list_add(&desc->list, &fd_maps->pages);

	virt = (void *) ((unsigned long) virt & PAGE_MASK);
	err = os_map_memory(virt, fd, offset, PAGE_SIZE, 1, w, 0);
	if(!err)
		goto out;

	rb_erase(&desc->rb, &phys_mappings);
	kfree(desc);
 out:
	return(err);
}

static int physmem_fd = -1;

static void remove_mapping(struct phys_desc *desc)
{
	void *virt = desc->virt;
	int err;

	rb_erase(&desc->rb, &phys_mappings);
	list_del(&desc->list);
	kfree(desc);

	err = os_map_memory(virt, physmem_fd, __pa(virt), PAGE_SIZE, 1, 1, 0);
	if(err)
		panic("Failed to unmap block device page from physical memory, "
		      "errno = %d", -err);
}

int physmem_remove_mapping(void *virt)
{
	struct phys_desc *desc;

	virt = (void *) ((unsigned long) virt & PAGE_MASK);
	desc = find_phys_mapping(virt);
	if(desc == NULL)
		return(0);

	remove_mapping(desc);
	return(1);
}

void physmem_forget_descriptor(int fd)
{
	struct desc_mapping *desc;
	struct phys_desc *page;
	struct list_head *ele, *next;
	__u64 offset;
	void *addr;
	int err;

	desc = find_mapping(fd);
	if(desc == NULL)
		return;

	list_for_each_safe(ele, next, &desc->pages){
		page = list_entry(ele, struct phys_desc, list);
		offset = page->offset;
		addr = page->virt;
		remove_mapping(page);
		err = os_seek_file(fd, offset);
		if(err)
			panic("physmem_forget_descriptor - failed to seek "
			      "to %lld in fd %d, error = %d\n",
			      offset, fd, -err);
		err = os_read_file(fd, addr, PAGE_SIZE);
		if(err < 0)
			panic("physmem_forget_descriptor - failed to read "
			      "from fd %d to 0x%p, error = %d\n",
			      fd, addr, -err);
	}

	list_del(&desc->list);
	kfree(desc);
}

EXPORT_SYMBOL(physmem_forget_descriptor);
EXPORT_SYMBOL(physmem_remove_mapping);
EXPORT_SYMBOL(physmem_subst_mapping);

void arch_free_page(struct page *page, int order)
{
	void *virt;
	int i;

	for(i = 0; i < (1 << order); i++){
		virt = __va(page_to_phys(page + i));
		physmem_remove_mapping(virt);
	}
}

int is_remapped(void *virt)
{
  	struct phys_desc *desc = find_phys_mapping(virt);

	return(desc != NULL);
}

/* Changed during early boot */
unsigned long high_physmem;

extern unsigned long long physmem_size;

int init_maps(unsigned long physmem, unsigned long iomem, unsigned long highmem)
{
	struct page *p, *map;
	unsigned long phys_len, phys_pages, highmem_len, highmem_pages;
	unsigned long iomem_len, iomem_pages, total_len, total_pages;
	int i;

	phys_pages = physmem >> PAGE_SHIFT;
	phys_len = phys_pages * sizeof(struct page);

	iomem_pages = iomem >> PAGE_SHIFT;
	iomem_len = iomem_pages * sizeof(struct page);

	highmem_pages = highmem >> PAGE_SHIFT;
	highmem_len = highmem_pages * sizeof(struct page);

	total_pages = phys_pages + iomem_pages + highmem_pages;
	total_len = phys_len + iomem_pages + highmem_len;

	if(kmalloc_ok){
		map = kmalloc(total_len, GFP_KERNEL);
		if(map == NULL)
			map = vmalloc(total_len);
	}
	else map = alloc_bootmem_low_pages(total_len);

	if(map == NULL)
		return(-ENOMEM);

	for(i = 0; i < total_pages; i++){
		p = &map[i];
		set_page_count(p, 0);
		SetPageReserved(p);
		INIT_LIST_HEAD(&p->lru);
	}

	max_mapnr = total_pages;
	return(0);
}

/* Changed during early boot */
static unsigned long kmem_top = 0;

unsigned long get_kmem_end(void)
{
	if(kmem_top == 0)
		kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas);
	return(kmem_top);
}

void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
		int r, int w, int x)
{
	__u64 offset;
	int fd, err;

	fd = phys_mapping(phys, &offset);
	err = os_map_memory((void *) virt, fd, offset, len, r, w, x);
	if(err) {
		if(err == -ENOMEM)
			printk("try increasing the host's "
			       "/proc/sys/vm/max_map_count to <physical "
			       "memory size>/4096\n");
		panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, "
		      "err = %d\n", virt, fd, offset, len, r, w, x, err);
	}
}

#define PFN_UP(x) (((x) + PAGE_SIZE-1) >> PAGE_SHIFT)

extern int __syscall_stub_start, __binary_start;

void setup_physmem(unsigned long start, unsigned long reserve_end,
		   unsigned long len, unsigned long long highmem)
{
	unsigned long reserve = reserve_end - start;
	int pfn = PFN_UP(__pa(reserve_end));
	int delta = (len - reserve) >> PAGE_SHIFT;
	int err, offset, bootmap_size;

	physmem_fd = create_mem_file(len + highmem);

	offset = uml_reserved - uml_physmem;
	err = os_map_memory((void *) uml_reserved, physmem_fd, offset,
			    len - offset, 1, 1, 0);
	if(err < 0){
		os_print_error(err, "Mapping memory");
		exit(1);
	}

	/* Special kludge - This page will be mapped in to userspace processes
	 * from physmem_fd, so it needs to be written out there.
	 */
	os_seek_file(physmem_fd, __pa(&__syscall_stub_start));
	os_write_file(physmem_fd, &__syscall_stub_start, PAGE_SIZE);

	bootmap_size = init_bootmem(pfn, pfn + delta);
	free_bootmem(__pa(reserve_end) + bootmap_size,
		     len - bootmap_size - reserve);
}

int phys_mapping(unsigned long phys, __u64 *offset_out)
{
	struct phys_desc *desc = find_phys_mapping(__va(phys & PAGE_MASK));
	int fd = -1;

	if(desc != NULL){
		fd = desc->fd;
		*offset_out = desc->offset;
	}
	else if(phys < physmem_size){
		fd = physmem_fd;
		*offset_out = phys;
	}
	else if(phys < __pa(end_iomem)){
		struct iomem_region *region = iomem_regions;

		while(region != NULL){
			if((phys >= region->phys) &&
			   (phys < region->phys + region->size)){
				fd = region->fd;
				*offset_out = phys - region->phys;
				break;
			}
			region = region->next;
		}
	}
	else if(phys < __pa(end_iomem) + highmem){
		fd = physmem_fd;
		*offset_out = phys - iomem_size;
	}

	return(fd);
}

static int __init uml_mem_setup(char *line, int *add)
{
	char *retptr;
	physmem_size = memparse(line,&retptr);
	return 0;
}
__uml_setup("mem=", uml_mem_setup,
"mem=<Amount of desired ram>\n"
"    This controls how much \"physical\" memory the kernel allocates\n"
"    for the system. The size is specified as a number followed by\n"
"    one of 'k', 'K', 'm', 'M', which have the obvious meanings.\n"
"    This is not related to the amount of memory in the host.  It can\n"
"    be more, and the excess, if it's ever used, will just be swapped out.\n"
"	Example: mem=64M\n\n"
);

unsigned long find_iomem(char *driver, unsigned long *len_out)
{
	struct iomem_region *region = iomem_regions;

	while(region != NULL){
		if(!strcmp(region->driver, driver)){
			*len_out = region->size;
			return(region->virt);
		}
	}

	return(0);
}

int setup_iomem(void)
{
	struct iomem_region *region = iomem_regions;
	unsigned long iomem_start = high_physmem + PAGE_SIZE;
	int err;

	while(region != NULL){
		err = os_map_memory((void *) iomem_start, region->fd, 0,
				    region->size, 1, 1, 0);
		if(err)
			printk("Mapping iomem region for driver '%s' failed, "
			       "errno = %d\n", region->driver, -err);
		else {
			region->virt = iomem_start;
			region->phys = __pa(region->virt);
		}

		iomem_start += region->size + PAGE_SIZE;
		region = region->next;
	}

	return(0);
}

__initcall(setup_iomem);

/*
 * Overrides for Emacs so that we follow Linus's tabbing style.
 * Emacs will notice this stuff at the end of the file and automatically
 * adjust the settings for this buffer only.  This must remain at the end
 * of the file.
 * ---------------------------------------------------------------------------
 * Local variables:
 * c-file-style: "linux"
 * End:
 */
