Linux kernel & device driver programming

Cross-Referenced Linux and Device Driver Code

[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ]
Version: [ 2.6.11.8 ] [ 2.6.25 ] [ 2.6.25.8 ] [ 2.6.31.13 ] Architecture: [ i386 ]
  1 /*
  2  *  arch/arm/include/asm/pgalloc.h
  3  *
  4  *  Copyright (C) 2000-2001 Russell King
  5  *
  6  * This program is free software; you can redistribute it and/or modify
  7  * it under the terms of the GNU General Public License version 2 as
  8  * published by the Free Software Foundation.
  9  */
 10 #ifndef _ASMARM_PGALLOC_H
 11 #define _ASMARM_PGALLOC_H
 12 
 13 #include <asm/domain.h>
 14 #include <asm/pgtable-hwdef.h>
 15 #include <asm/processor.h>
 16 #include <asm/cacheflush.h>
 17 #include <asm/tlbflush.h>
 18 
 19 #define check_pgt_cache()               do { } while (0)
 20 
 21 #ifdef CONFIG_MMU
 22 
 23 #define _PAGE_USER_TABLE        (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_USER))
 24 #define _PAGE_KERNEL_TABLE      (PMD_TYPE_TABLE | PMD_BIT4 | PMD_DOMAIN(DOMAIN_KERNEL))
 25 
 26 /*
 27  * Since we have only two-level page tables, these are trivial
 28  */
 29 #define pmd_alloc_one(mm,addr)          ({ BUG(); ((pmd_t *)2); })
 30 #define pmd_free(mm, pmd)               do { } while (0)
 31 #define pgd_populate(mm,pmd,pte)        BUG()
 32 
 33 extern pgd_t *get_pgd_slow(struct mm_struct *mm);
 34 extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd);
 35 
 36 #define pgd_alloc(mm)                   get_pgd_slow(mm)
 37 #define pgd_free(mm, pgd)               free_pgd_slow(mm, pgd)
 38 
 39 /*
 40  * Allocate one PTE table.
 41  *
 42  * This actually allocates two hardware PTE tables, but we wrap this up
 43  * into one table thus:
 44  *
 45  *  +------------+
 46  *  |  h/w pt 0  |
 47  *  +------------+
 48  *  |  h/w pt 1  |
 49  *  +------------+
 50  *  | Linux pt 0 |
 51  *  +------------+
 52  *  | Linux pt 1 |
 53  *  +------------+
 54  */
 55 static inline pte_t *
 56 pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr)
 57 {
 58         pte_t *pte;
 59 
 60         pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO);
 61         if (pte) {
 62                 clean_dcache_area(pte, sizeof(pte_t) * PTRS_PER_PTE);
 63                 pte += PTRS_PER_PTE;
 64         }
 65 
 66         return pte;
 67 }
 68 
 69 static inline pgtable_t
 70 pte_alloc_one(struct mm_struct *mm, unsigned long addr)
 71 {
 72         struct page *pte;
 73 
 74         pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0);
 75         if (pte) {
 76                 void *page = page_address(pte);
 77                 clean_dcache_area(page, sizeof(pte_t) * PTRS_PER_PTE);
 78                 pgtable_page_ctor(pte);
 79         }
 80 
 81         return pte;
 82 }
 83 
 84 /*
 85  * Free one PTE table.
 86  */
 87 static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte)
 88 {
 89         if (pte) {
 90                 pte -= PTRS_PER_PTE;
 91                 free_page((unsigned long)pte);
 92         }
 93 }
 94 
 95 static inline void pte_free(struct mm_struct *mm, pgtable_t pte)
 96 {
 97         pgtable_page_dtor(pte);
 98         __free_page(pte);
 99 }
100 
101 static inline void __pmd_populate(pmd_t *pmdp, unsigned long pmdval)
102 {
103         pmdp[0] = __pmd(pmdval);
104         pmdp[1] = __pmd(pmdval + 256 * sizeof(pte_t));
105         flush_pmd_entry(pmdp);
106 }
107 
108 /*
109  * Populate the pmdp entry with a pointer to the pte.  This pmd is part
110  * of the mm address space.
111  *
112  * Ensure that we always set both PMD entries.
113  */
114 static inline void
115 pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep)
116 {
117         unsigned long pte_ptr = (unsigned long)ptep;
118 
119         /*
120          * The pmd must be loaded with the physical
121          * address of the PTE table
122          */
123         pte_ptr -= PTRS_PER_PTE * sizeof(void *);
124         __pmd_populate(pmdp, __pa(pte_ptr) | _PAGE_KERNEL_TABLE);
125 }
126 
127 static inline void
128 pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep)
129 {
130         __pmd_populate(pmdp, page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE);
131 }
132 #define pmd_pgtable(pmd) pmd_page(pmd)
133 
134 #endif /* CONFIG_MMU */
135 
136 #endif
137 
  This page was automatically generated by the LXR engine.