/*
 * Copyright (C) 2008-2009 Michal Simek <monstr@monstr.eu>
 * Copyright (C) 2008-2009 PetaLogix
 * Copyright (C) 2006 Atmark Techno, Inc.
 *
 * 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.
 */

#ifndef _ASM_MICROBLAZE_PGALLOC_H
#define _ASM_MICROBLAZE_PGALLOC_H

#ifdef CONFIG_MMU

#include <linux/kernel.h>	/* For min/max macros */
#include <linux/highmem.h>
#include <asm/setup.h>
#include <asm/io.h>
#include <asm/page.h>
#include <asm/cache.h>
#include <asm/pgtable.h>

#define PGDIR_ORDER	0

/*
 * This is handled very differently on MicroBlaze since out page tables
 * are all 0's and I want to be able to use these zero'd pages elsewhere
 * as well - it gives us quite a speedup.
 * -- Cort
 */
extern struct pgtable_cache_struct {
	unsigned long *pgd_cache;
	unsigned long *pte_cache;
	unsigned long pgtable_cache_sz;
} quicklists;

#define pgd_quicklist		(quicklists.pgd_cache)
#define pmd_quicklist		((unsigned long *)0)
#define pte_quicklist		(quicklists.pte_cache)
#define pgtable_cache_size	(quicklists.pgtable_cache_sz)

extern unsigned long *zero_cache; /* head linked list of pre-zero'd pages */
extern atomic_t zero_sz; /* # currently pre-zero'd pages */
extern atomic_t zeropage_hits; /* # zero'd pages request that we've done */
extern atomic_t zeropage_calls; /* # zero'd pages request that've been made */
extern atomic_t zerototal; /* # pages zero'd over time */

#define zero_quicklist		(zero_cache)
#define zero_cache_sz	 	(zero_sz)
#define zero_cache_calls	(zeropage_calls)
#define zero_cache_hits		(zeropage_hits)
#define zero_cache_total	(zerototal)

/*
 * return a pre-zero'd page from the list,
 * return NULL if none available -- Cort
 */
extern unsigned long get_zero_page_fast(void);

extern void __bad_pte(pmd_t *pmd);

static inline pgd_t *get_pgd_slow(void)
{
	pgd_t *ret;

	ret = (pgd_t *)__get_free_pages(GFP_KERNEL, PGDIR_ORDER);
	if (ret != NULL)
		clear_page(ret);
	return ret;
}

static inline pgd_t *get_pgd_fast(void)
{
	unsigned long *ret;

	ret = pgd_quicklist;
	if (ret != NULL) {
		pgd_quicklist = (unsigned long *)(*ret);
		ret[0] = 0;
		pgtable_cache_size--;
	} else
		ret = (unsigned long *)get_pgd_slow();
	return (pgd_t *)ret;
}

static inline void free_pgd_fast(pgd_t *pgd)
{
	*(unsigned long **)pgd = pgd_quicklist;
	pgd_quicklist = (unsigned long *) pgd;
	pgtable_cache_size++;
}

static inline void free_pgd_slow(pgd_t *pgd)
{
	free_page((unsigned long)pgd);
}

#define pgd_free(mm, pgd)        free_pgd_fast(pgd)
#define pgd_alloc(mm)		get_pgd_fast()

#define pmd_pgtable(pmd)	pmd_page(pmd)

/*
 * We don't have any real pmd's, and this code never triggers because
 * the pgd will always be present..
 */
#define pmd_alloc_one_fast(mm, address)	({ BUG(); ((pmd_t *)1); })
#define pmd_alloc_one(mm, address)	({ BUG(); ((pmd_t *)2); })

extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);

static inline struct page *pte_alloc_one(struct mm_struct *mm,
		unsigned long address)
{
	struct page *ptepage;

#ifdef CONFIG_HIGHPTE
	int flags = GFP_KERNEL | __GFP_HIGHMEM;
#else
	int flags = GFP_KERNEL;
#endif

	ptepage = alloc_pages(flags, 0);
	if (!ptepage)
		return NULL;
	clear_highpage(ptepage);
	if (!pgtable_page_ctor(ptepage)) {
		__free_page(ptepage);
		return NULL;
	}
	return ptepage;
}

static inline pte_t *pte_alloc_one_fast(struct mm_struct *mm,
		unsigned long address)
{
	unsigned long *ret;

	ret = pte_quicklist;
	if (ret != NULL) {
		pte_quicklist = (unsigned long *)(*ret);
		ret[0] = 0;
		pgtable_cache_size--;
	}
	return (pte_t *)ret;
}

static inline void pte_free_fast(pte_t *pte)
{
	*(unsigned long **)pte = pte_quicklist;
	pte_quicklist = (unsigned long *) pte;
	pgtable_cache_size++;
}

static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
{
	free_page((unsigned long)pte);
}

static inline void pte_free_slow(struct page *ptepage)
{
	__free_page(ptepage);
}

static inline void pte_free(struct mm_struct *mm, struct page *ptepage)
{
	pgtable_page_dtor(ptepage);
	__free_page(ptepage);
}

#define __pte_free_tlb(tlb, pte, addr)	pte_free((tlb)->mm, (pte))

#define pmd_populate(mm, pmd, pte) \
			(pmd_val(*(pmd)) = (unsigned long)page_address(pte))

#define pmd_populate_kernel(mm, pmd, pte) \
		(pmd_val(*(pmd)) = (unsigned long) (pte))

/*
 * We don't have any real pmd's, and this code never triggers because
 * the pgd will always be present..
 */
#define pmd_alloc_one(mm, address)	({ BUG(); ((pmd_t *)2); })
#define pmd_free(mm, x)			do { } while (0)
#define __pmd_free_tlb(tlb, x, addr)	pmd_free((tlb)->mm, x)
#define pgd_populate(mm, pmd, pte)	BUG()

extern int do_check_pgt_cache(int, int);

#endif /* CONFIG_MMU */

#define check_pgt_cache()		do { } while (0)

#endif /* _ASM_MICROBLAZE_PGALLOC_H */
