motorola_pgalloc.h
上传用户:lgb322
上传日期:2013-02-24
资源大小:30529k
文件大小:5k
源码类别:

嵌入式Linux

开发平台:

Unix_Linux

  1. #ifndef _MOTOROLA_PGALLOC_H
  2. #define _MOTOROLA_PGALLOC_H
  3. extern struct pgtable_cache_struct {
  4. unsigned long *pmd_cache;
  5. unsigned long *pte_cache;
  6. /* This counts in units of pointer tables, of which can be eight per page. */
  7. unsigned long pgtable_cache_sz;
  8. } quicklists;
  9. #define pgd_quicklist ((unsigned long *)0)
  10. #define pmd_quicklist (quicklists.pmd_cache)
  11. #define pte_quicklist (quicklists.pte_cache)
  12. /* This isn't accurate because of fragmentation of allocated pages for
  13.    pointer tables, but that should not be a problem. */
  14. #define pgtable_cache_size ((quicklists.pgtable_cache_sz+7)/8)
  15. extern pte_t *get_pte_slow(pmd_t *pmd, unsigned long offset);
  16. extern pmd_t *get_pmd_slow(pgd_t *pgd, unsigned long offset);
  17. extern pmd_t *get_pointer_table(void);
  18. extern int free_pointer_table(pmd_t *);
  19. extern inline void flush_tlb_kernel_page(unsigned long addr)
  20. {
  21. if (CPU_IS_040_OR_060) {
  22. mm_segment_t old_fs = get_fs();
  23. set_fs(KERNEL_DS);
  24. __asm__ __volatile__(".chip 68040nt"
  25.      "pflush (%0)nt"
  26.      ".chip 68k"
  27.      : : "a" (addr));
  28. set_fs(old_fs);
  29. } else
  30. __asm__ __volatile__("pflush #4,#4,(%0)" : : "a" (addr));
  31. }
  32. extern inline pte_t *get_pte_fast(void)
  33. {
  34. unsigned long *ret;
  35. ret = pte_quicklist;
  36. if (ret) {
  37. pte_quicklist = (unsigned long *)*ret;
  38. ret[0] = 0;
  39. quicklists.pgtable_cache_sz -= 8;
  40. }
  41. return (pte_t *)ret;
  42. }
  43. #define pte_alloc_one_fast(mm,addr)  get_pte_fast()
  44. static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
  45. {
  46.   pte_t *pte;
  47. pte = (pte_t *) __get_free_page(GFP_KERNEL);
  48. if (pte) {
  49.          clear_page(pte);
  50.  __flush_page_to_ram((unsigned long)pte);
  51.  flush_tlb_kernel_page((unsigned long)pte);
  52.  nocache_page((unsigned long)pte);
  53. }
  54. return pte;
  55. }
  56. extern __inline__ pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
  57. {
  58.         return get_pointer_table();
  59. }
  60. extern inline void free_pte_fast(pte_t *pte)
  61. {
  62. *(unsigned long *)pte = (unsigned long)pte_quicklist;
  63. pte_quicklist = (unsigned long *)pte;
  64. quicklists.pgtable_cache_sz += 8;
  65. }
  66. extern inline void free_pte_slow(pte_t *pte)
  67. {
  68. cache_page((unsigned long)pte);
  69. free_page((unsigned long) pte);
  70. }
  71. extern inline pmd_t *get_pmd_fast(void)
  72. {
  73. unsigned long *ret;
  74. ret = pmd_quicklist;
  75. if (ret) {
  76. pmd_quicklist = (unsigned long *)*ret;
  77. ret[0] = 0;
  78. quicklists.pgtable_cache_sz--;
  79. }
  80. return (pmd_t *)ret;
  81. }
  82. #define pmd_alloc_one_fast(mm,addr) get_pmd_fast()
  83. extern inline void free_pmd_fast(pmd_t *pmd)
  84. {
  85. *(unsigned long *)pmd = (unsigned long)pmd_quicklist;
  86. pmd_quicklist = (unsigned long *) pmd;
  87. quicklists.pgtable_cache_sz++;
  88. }
  89. extern inline int free_pmd_slow(pmd_t *pmd)
  90. {
  91. return free_pointer_table(pmd);
  92. }
  93. /* The pgd cache is folded into the pmd cache, so these are dummy routines. */
  94. extern inline pgd_t *get_pgd_fast(void)
  95. {
  96. return (pgd_t *)0;
  97. }
  98. extern inline void free_pgd_fast(pgd_t *pgd)
  99. {
  100. }
  101. extern inline void free_pgd_slow(pgd_t *pgd)
  102. {
  103. }
  104. extern void __bad_pte(pmd_t *pmd);
  105. extern void __bad_pmd(pgd_t *pgd);
  106. extern inline void pte_free(pte_t *pte)
  107. {
  108. free_pte_fast(pte);
  109. }
  110. extern inline void pmd_free(pmd_t *pmd)
  111. {
  112. free_pmd_fast(pmd);
  113. }
  114. extern inline void pte_free_kernel(pte_t *pte)
  115. {
  116. free_pte_fast(pte);
  117. }
  118. extern inline pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address)
  119. {
  120. return pte_alloc(&init_mm,pmd, address);
  121. }
  122. extern inline void pmd_free_kernel(pmd_t *pmd)
  123. {
  124. free_pmd_fast(pmd);
  125. }
  126. extern inline pmd_t *pmd_alloc_kernel(pgd_t *pgd, unsigned long address)
  127. {
  128. return pmd_alloc(&init_mm,pgd, address);
  129. }
  130. extern inline void pgd_free(pgd_t *pgd)
  131. {
  132. free_pmd_fast((pmd_t *)pgd);
  133. }
  134. extern inline pgd_t *pgd_alloc(struct mm_struct *mm)
  135. {
  136. pgd_t *pgd = (pgd_t *)get_pmd_fast();
  137. if (!pgd)
  138. pgd = (pgd_t *)get_pointer_table();
  139. return pgd;
  140. }
  141. #define pmd_populate(MM, PMD, PTE) pmd_set(PMD, PTE)
  142. #define pgd_populate(MM, PGD, PMD) pgd_set(PGD, PMD)
  143. extern int do_check_pgt_cache(int, int);
  144. extern inline void set_pgdir(unsigned long address, pgd_t entry)
  145. {
  146. }
  147. /*
  148.  * flush all user-space atc entries.
  149.  */
  150. static inline void __flush_tlb(void)
  151. {
  152. if (CPU_IS_040_OR_060)
  153. __asm__ __volatile__(".chip 68040nt"
  154.      "pflushannt"
  155.      ".chip 68k");
  156. else
  157. __asm__ __volatile__("pflush #0,#4");
  158. }
  159. static inline void __flush_tlb040_one(unsigned long addr)
  160. {
  161. __asm__ __volatile__(".chip 68040nt"
  162.      "pflush (%0)nt"
  163.      ".chip 68k"
  164.      : : "a" (addr));
  165. }
  166. static inline void __flush_tlb_one(unsigned long addr)
  167. {
  168. if (CPU_IS_040_OR_060)
  169. __flush_tlb040_one(addr);
  170. else
  171. __asm__ __volatile__("pflush #0,#4,(%0)" : : "a" (addr));
  172. }
  173. #define flush_tlb() __flush_tlb()
  174. /*
  175.  * flush all atc entries (both kernel and user-space entries).
  176.  */
  177. static inline void flush_tlb_all(void)
  178. {
  179. if (CPU_IS_040_OR_060)
  180. __asm__ __volatile__(".chip 68040nt"
  181.      "pflushant"
  182.      ".chip 68k");
  183. else
  184. __asm__ __volatile__("pflusha");
  185. }
  186. static inline void flush_tlb_mm(struct mm_struct *mm)
  187. {
  188. if (mm == current->mm)
  189. __flush_tlb();
  190. }
  191. static inline void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr)
  192. {
  193. if (vma->vm_mm == current->mm)
  194. __flush_tlb_one(addr);
  195. }
  196. static inline void flush_tlb_range(struct mm_struct *mm,
  197.    unsigned long start, unsigned long end)
  198. {
  199. if (mm == current->mm)
  200. __flush_tlb();
  201. }
  202. extern inline void flush_tlb_pgtables(struct mm_struct *mm,
  203.       unsigned long start, unsigned long end)
  204. {
  205. }
  206. #endif /* _MOTOROLA_PGALLOC_H */