/* MN10300 Virtual kernel memory mappings for high memory
 *
 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 * - Derived from include/asm-i386/highmem.h
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public Licence
 * as published by the Free Software Foundation; either version
 * 2 of the Licence, or (at your option) any later version.
 */
#ifndef _ASM_HIGHMEM_H
#define _ASM_HIGHMEM_H

#ifdef __KERNEL__

#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/highmem.h>
#include <asm/kmap_types.h>
#include <asm/pgtable.h>

/* undef for production */
#undef HIGHMEM_DEBUG

/* declarations for highmem.c */
extern unsigned long highstart_pfn, highend_pfn;

extern pte_t *kmap_pte;
extern pgprot_t kmap_prot;
extern pte_t *pkmap_page_table;

extern void __init kmap_init(void);

/*
 * Right now we initialize only a single pte table. It can be extended
 * easily, subsequent pte tables have to be allocated in one physical
 * chunk of RAM.
 */
#define PKMAP_BASE	0xfe000000UL
#define LAST_PKMAP	1024
#define LAST_PKMAP_MASK (LAST_PKMAP - 1)
#define PKMAP_NR(virt)  ((virt - PKMAP_BASE) >> PAGE_SHIFT)
#define PKMAP_ADDR(nr)  (PKMAP_BASE + ((nr) << PAGE_SHIFT))

extern unsigned long kmap_high(struct page *page);
extern void kunmap_high(struct page *page);

static inline unsigned long kmap(struct page *page)
{
	if (in_interrupt())
		BUG();
	if (page < highmem_start_page)
		return page_address(page);
	return kmap_high(page);
}

static inline void kunmap(struct page *page)
{
	if (in_interrupt())
		BUG();
	if (page < highmem_start_page)
		return;
	kunmap_high(page);
}

/*
 * The use of kmap_atomic/kunmap_atomic is discouraged - kmap/kunmap
 * gives a more generic (and caching) interface. But kmap_atomic can
 * be used in IRQ contexts, so in some (very limited) cases we need
 * it.
 */
static inline void *kmap_atomic(struct page *page)
{
	unsigned long vaddr;
	int idx, type;

	preempt_disable();
	pagefault_disable();
	if (page < highmem_start_page)
		return page_address(page);

	type = kmap_atomic_idx_push();
	idx = type + KM_TYPE_NR * smp_processor_id();
	vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx);
#if HIGHMEM_DEBUG
	if (!pte_none(*(kmap_pte - idx)))
		BUG();
#endif
	set_pte(kmap_pte - idx, mk_pte(page, kmap_prot));
	local_flush_tlb_one(vaddr);

	return (void *)vaddr;
}

static inline void __kunmap_atomic(unsigned long vaddr)
{
	int type;

	if (vaddr < FIXADDR_START) { /* FIXME */
		pagefault_enable();
		preempt_enable();
		return;
	}

	type = kmap_atomic_idx();

#if HIGHMEM_DEBUG
	{
		unsigned int idx;
		idx = type + KM_TYPE_NR * smp_processor_id();

		if (vaddr != __fix_to_virt(FIX_KMAP_BEGIN + idx))
			BUG();

		/*
		 * force other mappings to Oops if they'll try to access
		 * this pte without first remap it
		 */
		pte_clear(kmap_pte - idx);
		local_flush_tlb_one(vaddr);
	}
#endif

	kmap_atomic_idx_pop();
	pagefault_enable();
	preempt_enable();
}
#endif /* __KERNEL__ */

#endif /* _ASM_HIGHMEM_H */
