pgalloc.h 2.8 KB
Newer Older
1 2 3 4 5
#ifndef _ASM_POWERPC_PGALLOC_32_H
#define _ASM_POWERPC_PGALLOC_32_H

#include <linux/threads.h>

6 7
/* For 32-bit, all levels of page tables are just drawn from get_free_page() */
#define MAX_PGTABLE_INDEX_SIZE	0
8

9 10 11
extern void __bad_pte(pmd_t *pmd);

extern pgd_t *pgd_alloc(struct mm_struct *mm);
12
extern void pgd_free(struct mm_struct *mm, pgd_t *pgd);
13 14 15 16 17

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

#ifndef CONFIG_BOOKE
24 25 26 27 28 29 30 31 32 33 34 35 36

static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp,
				       pte_t *pte)
{
	*pmdp = __pmd(__pa(pte) | _PMD_PRESENT);
}

static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp,
				pgtable_t pte_page)
{
	*pmdp = __pmd((page_to_pfn(pte_page) << PAGE_SHIFT) | _PMD_PRESENT);
}

37
#define pmd_pgtable(pmd) pmd_page(pmd)
38
#else
39 40 41 42 43 44 45 46 47 48 49 50 51

static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp,
				       pte_t *pte)
{
	*pmdp = __pmd((unsigned long)pte | _PMD_PRESENT);
}

static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp,
				pgtable_t pte_page)
{
	*pmdp = __pmd((unsigned long)lowmem_page_address(pte_page) | _PMD_PRESENT);
}

52
#define pmd_pgtable(pmd) pmd_page(pmd)
53 54 55
#endif

extern pte_t *pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr);
56
extern pgtable_t pte_alloc_one(struct mm_struct *mm, unsigned long addr);
57

58 59 60 61 62 63 64 65 66 67 68
static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
{
	free_page((unsigned long)pte);
}

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

69
static inline void pgtable_free(void *table, unsigned index_size)
70
{
71 72
	BUG_ON(index_size); /* 32-bit doesn't use this */
	free_page((unsigned long)table);
73
}
74 75 76

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

77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
#ifdef CONFIG_SMP
static inline void pgtable_free_tlb(struct mmu_gather *tlb,
				    void *table, int shift)
{
	unsigned long pgf = (unsigned long)table;
	BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE);
	pgf |= shift;
	tlb_remove_table(tlb, (void *)pgf);
}

static inline void __tlb_remove_table(void *_table)
{
	void *table = (void *)((unsigned long)_table & ~MAX_PGTABLE_INDEX_SIZE);
	unsigned shift = (unsigned long)_table & MAX_PGTABLE_INDEX_SIZE;

	pgtable_free(table, shift);
}
#else
static inline void pgtable_free_tlb(struct mmu_gather *tlb,
				    void *table, int shift)
{
	pgtable_free(table, shift);
}
#endif

static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table,
				  unsigned long address)
{
	tlb_flush_pgtable(tlb, address);
106 107
	pgtable_page_dtor(table);
	pgtable_free_tlb(tlb, page_address(table), 0);
108
}
109
#endif /* _ASM_POWERPC_PGALLOC_32_H */