1 #ifndef _ASM_POWERPC_PGALLOC_32_H 2 #define _ASM_POWERPC_PGALLOC_32_H 3 4 #include <linux/threads.h> 5 6 /* For 32-bit, all levels of page tables are just drawn from get_free_page() */ 7 #define MAX_PGTABLE_INDEX_SIZE 0 8 9 extern void __bad_pte(pmd_t *pmd); 10 11 extern pgd_t *pgd_alloc(struct mm_struct *mm); 12 extern void pgd_free(struct mm_struct *mm, pgd_t *pgd); 13 14 /* 15 * We don't have any real pmd's, and this code never triggers because 16 * the pgd will always be present.. 17 */ 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 static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, 26 pte_t *pte) 27 { 28 *pmdp = __pmd(__pa(pte) | _PMD_PRESENT); 29 } 30 31 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp, 32 pgtable_t pte_page) 33 { 34 *pmdp = __pmd((page_to_pfn(pte_page) << PAGE_SHIFT) | _PMD_PRESENT); 35 } 36 37 #define pmd_pgtable(pmd) pmd_page(pmd) 38 #else 39 40 static inline void pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, 41 pte_t *pte) 42 { 43 *pmdp = __pmd((unsigned long)pte | _PMD_PRESENT); 44 } 45 46 static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmdp, 47 pgtable_t pte_page) 48 { 49 *pmdp = __pmd((unsigned long)lowmem_page_address(pte_page) | _PMD_PRESENT); 50 } 51 52 #define pmd_pgtable(pmd) pmd_page(pmd) 53 #endif 54 55 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 static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) 59 { 60 free_page((unsigned long)pte); 61 } 62 63 static inline void pte_free(struct mm_struct *mm, pgtable_t ptepage) 64 { 65 pgtable_page_dtor(ptepage); 66 __free_page(ptepage); 67 } 68 69 static inline void pgtable_free(void *table, unsigned index_size) 70 { 71 BUG_ON(index_size); /* 32-bit doesn't use this */ 72 free_page((unsigned long)table); 73 } 74 75 #define check_pgt_cache() do { } while (0) 76 77 #ifdef CONFIG_SMP 78 static inline void pgtable_free_tlb(struct mmu_gather *tlb, 79 void *table, int shift) 80 { 81 unsigned long pgf = (unsigned long)table; 82 BUG_ON(shift > MAX_PGTABLE_INDEX_SIZE); 83 pgf |= shift; 84 tlb_remove_table(tlb, (void *)pgf); 85 } 86 87 static inline void __tlb_remove_table(void *_table) 88 { 89 void *table = (void *)((unsigned long)_table & ~MAX_PGTABLE_INDEX_SIZE); 90 unsigned shift = (unsigned long)_table & MAX_PGTABLE_INDEX_SIZE; 91 92 pgtable_free(table, shift); 93 } 94 #else 95 static inline void pgtable_free_tlb(struct mmu_gather *tlb, 96 void *table, int shift) 97 { 98 pgtable_free(table, shift); 99 } 100 #endif 101 102 static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t table, 103 unsigned long address) 104 { 105 tlb_flush_pgtable(tlb, address); 106 pgtable_page_dtor(table); 107 pgtable_free_tlb(tlb, page_address(table), 0); 108 } 109 #endif /* _ASM_POWERPC_PGALLOC_32_H */ 110