/*
 *  include/asm-i386/kl_mem.h
 */

#ifndef __ASM_KL_MEM_H
#define __ASM_KL_MEM_H

#if CONFIG_X86_PAE
typedef struct { unsigned long pte_low, pte_high; } kl_pte_t;
typedef struct { unsigned long long pmd; } kl_pmd_t;
typedef struct { unsigned long long pgd; } kl_pgd_t;
#define kl_pte_val(x)	((x).pte_low | ((unsigned long long)(x).pte_high << 32))

static inline int kl_pgd_none(kl_pgd_t pgd)		{ return 0; }
static inline int kl_pgd_bad(kl_pgd_t pgd)		{ return 0; }

#define kl_pte_none(x)	(!(x).pte_low && !(x).pte_high)

#define KL_PGDIR_SHIFT        30
#define KL_PGDIR_SIZE         (1UL<<KL_PGDIR_SHIFT)
#define KL_PGDIR_MASK         (~(KL_PGDIR_SIZE-1))
#define KL_PMD_SHIFT          21
#define KL_PMD_SIZE           (1UL<<KL_PMD_SHIFT)
#define KL_PMD_MASK           (~(KL_PMD_SIZE-1))

#define KL_PTRS_PER_PGD       4
#define KL_PTRS_PER_PMD       512
#define KL_PTRS_PER_PTE       512

#define KL_PMD_BASE_MASK      (~((1ULL<<12)-1))
#define KL_PT_BASE_MASK       KL_PMD_BASE_MASK
#define KL_PAGE_BASE_MASK     KL_PMD_BASE_MASK

#define KL_PSE_OFFSET_MASK    ((1ULL<<21)-1)
#define KL_PSE_PAGE_MASK      (~KL_PSE_OFFSET_MASK)

#else /* !CONIG_X86_PAE */

typedef struct { unsigned long pte_low; } kl_pte_t;
typedef struct { unsigned long pmd; } kl_pmd_t;
typedef struct { unsigned long pgd; } kl_pgd_t;
#define kl_pte_val(x)	((x).pte_low)

static inline int kl_pgd_none(kl_pgd_t pgd)		{ return 0; }
static inline int kl_pgd_bad(kl_pgd_t pgd)		{ return 0; }

#define kl_pte_none(x)		(!(x).pte_low)

#define KL_PGDIR_SHIFT        22
#define KL_PGDIR_SIZE         (1UL<<KL_PGDIR_SHIFT)
#define KL_PGDIR_MASK         (~(KL_PGDIR_SIZE-1))
#define KL_PMD_SHIFT          KL_PGDIR_SHIFT
#define KL_PMD_SIZE           KL_PGDIR_SIZE
#define KL_PMD_MASK           KL_PGDIR_MASK

#define KL_PTRS_PER_PGD       1024
#define KL_PTRS_PER_PMD       1
#define KL_PTRS_PER_PTE       1024

#define KL_PMD_BASE_MASK      (~((1UL<<12)-1))
#define KL_PT_BASE_MASK       KL_PMD_BASE_MASK
#define KL_PAGE_BASE_MASK     KL_PMD_BASE_MASK

#define KL_PSE_OFFSET_MASK    ((1UL<<22)-1)
#define KL_PSE_PAGE_MASK      (~KL_PSE_OFFSET_MASK)

#endif /* !CONIG_X86_PAE */

/* Common definitions */
#define kl_pmd_val(x)	((x).pmd)
#define kl_pgd_val(x)	((x).pgd)

#define KL_PAGE_PRESENT		0x001
#define KL_PAGE_RW		0x002
#define KL_PAGE_USER		0x004
#define KL_PAGE_ACCESSED	0x020
#define KL_PAGE_DIRTY		0x040
#define KL_PAGE_PSE		0x080
#define KL_PAGE_GLOBAL		0x100

#define KL_KERNPG_TABLE	(KL_PAGE_PRESENT | KL_PAGE_RW | KL_PAGE_ACCESSED | KL_PAGE_DIRTY)

#define kl_pmd_none(x)	(!kl_pmd_val(x))
#define kl_pmd_bad(x)	((kl_pmd_val(x) & (~KL_PAGE_MASK & ~KL_PAGE_USER & \
			~KL_PAGE_GLOBAL & ~KL_PAGE_PSE)) != KL_KERNPG_TABLE)

/* Here bad means not present */
#define kl_pte_bad(x)	!(x.pte_low & KL_PAGE_PRESENT)

/* following is used for intels page size extension (4MB/2MB pages) */
#define KL_PSE_BIT            (1<<7)

#define KL_KADDR_IS_HIGHMEM(vaddr) (vaddr >= KL_HIGH_MEMORY)

#endif /* __ASM_KL_MEM_H */
