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

嵌入式Linux

开发平台:

Unix_Linux

  1. /* sun3_pgalloc.h --
  2.  * reorganization around 2.3.39, routines moved from sun3_pgtable.h 
  3.  *
  4.  * moved 1/26/2000 Sam Creasey
  5.  */
  6. #ifndef _SUN3_PGALLOC_H
  7. #define _SUN3_PGALLOC_H
  8. /* Pagetable caches. */
  9. //todo: should implement for at least ptes. --m
  10. #define pgd_quicklist ((unsigned long *) 0)
  11. #define pmd_quicklist ((unsigned long *) 0)
  12. #define pte_quicklist ((unsigned long *) 0)
  13. #define pgtable_cache_size (0L)
  14. /* Allocation and deallocation of various flavours of pagetables. */
  15. extern inline int free_pmd_fast (pmd_t *pmdp) { return 0; }
  16. extern inline int free_pmd_slow (pmd_t *pmdp) { return 0; }
  17. extern inline pmd_t *get_pmd_fast (void) { return (pmd_t *) 0; }
  18. //todo: implement the following properly.
  19. #define get_pte_fast() ((pte_t *) 0)
  20. #define get_pte_slow pte_alloc
  21. #define free_pte_fast(pte)
  22. #define free_pte_slow pte_free
  23. /* FIXME - when we get this compiling */
  24. /* erm, now that it's compiling, what do we do with it? */
  25. #define _KERNPG_TABLE 0
  26. extern inline void pte_free_kernel(pte_t * pte)
  27. {
  28.         free_page((unsigned long) pte);
  29. }
  30. extern const char bad_pmd_string[];
  31. extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
  32. {
  33.         address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
  34.         if (pmd_none(*pmd)) {
  35.                 pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
  36.                 if (pmd_none(*pmd)) {
  37.                         if (page) {
  38.                                 pmd_val(*pmd) = _KERNPG_TABLE + __pa(page);
  39.                                 return page + address;
  40.                         }
  41.                         pmd_val(*pmd) = _KERNPG_TABLE + __pa((unsigned long)BAD_PAGETABLE);
  42.                         return NULL;
  43.                 }
  44.                 free_page((unsigned long) page);
  45.         }
  46.         if (pmd_bad(*pmd)) {
  47.                 printk(bad_pmd_string, pmd_val(*pmd));
  48. printk("at kernel pgd off %08xn", (unsigned int)pmd);
  49.                 pmd_val(*pmd) = _KERNPG_TABLE + __pa((unsigned long)BAD_PAGETABLE);
  50.                 return NULL;
  51.         }
  52.         return (pte_t *) __pmd_page(*pmd) + address;
  53. }
  54. /*
  55.  * allocating and freeing a pmd is trivial: the 1-entry pmd is
  56.  * inside the pgd, so has no extra memory associated with it.
  57.  */
  58. extern inline void pmd_free_kernel(pmd_t * pmd)
  59. {
  60. //        pmd_val(*pmd) = 0;
  61. }
  62. extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address)
  63. {
  64.         return (pmd_t *) pgd;
  65. }
  66. #define pmd_alloc_one_fast(mm, address) ({ BUG(); ((pmd_t *)1); })
  67. #define pmd_alloc_one(mm,address)       ({ BUG(); ((pmd_t *)2); })
  68. extern inline void pte_free(pte_t * pte)
  69. {
  70.         free_page((unsigned long) pte);
  71. }
  72. static inline pte_t *pte_alloc_one(struct mm_struct *mm, unsigned long address)
  73. {
  74. unsigned long page = __get_free_page(GFP_KERNEL);
  75. if (!page)
  76. return NULL;
  77. memset((void *)page, 0, PAGE_SIZE);
  78. // pmd_val(*pmd) = SUN3_PMD_MAGIC + __pa(page);
  79. /* pmd_val(*pmd) = __pa(page); */
  80. return (pte_t *) (page);
  81. }
  82. #define pte_alloc_one_fast(mm,addr) pte_alloc_one(mm,addr)
  83. #define pmd_populate(mm, pmd, pte) (pmd_val(*pmd) = __pa((unsigned long)pte))
  84. /*
  85.  * allocating and freeing a pmd is trivial: the 1-entry pmd is
  86.  * inside the pgd, so has no extra memory associated with it.
  87.  */
  88. extern inline void pmd_free(pmd_t * pmd)
  89. {
  90.         pmd_val(*pmd) = 0;
  91. }
  92. extern inline void pgd_free(pgd_t * pgd)
  93. {
  94.         free_page((unsigned long) pgd);
  95. }
  96. extern inline pgd_t * pgd_alloc(struct mm_struct *mm)
  97. {
  98.      pgd_t *new_pgd;
  99.      new_pgd = (pgd_t *)get_free_page(GFP_KERNEL);
  100.      memcpy(new_pgd, swapper_pg_dir, PAGE_SIZE);
  101.      memset(new_pgd, 0, (PAGE_OFFSET >> PGDIR_SHIFT));
  102.      return new_pgd;
  103. }
  104. #define pgd_populate(mm, pmd, pte) BUG()
  105. /* FIXME: the sun3 doesn't have a page table cache! 
  106.    (but the motorola routine should just return 0) */
  107. extern int do_check_pgt_cache(int, int);
  108. extern inline void set_pgdir(unsigned long address, pgd_t entry)
  109. {
  110. }
  111. /* Reserved PMEGs. */
  112. extern char sun3_reserved_pmeg[SUN3_PMEGS_NUM];
  113. extern unsigned long pmeg_vaddr[SUN3_PMEGS_NUM];
  114. extern unsigned char pmeg_alloc[SUN3_PMEGS_NUM];
  115. extern unsigned char pmeg_ctx[SUN3_PMEGS_NUM];
  116. /* Flush all userspace mappings one by one...  (why no flush command,
  117.    sun?) */
  118. static inline void flush_tlb_all(void)
  119. {
  120.        unsigned long addr;
  121.        unsigned char ctx, oldctx;
  122.        oldctx = sun3_get_context();
  123.        for(addr = 0x00000000; addr < TASK_SIZE; addr += SUN3_PMEG_SIZE) {
  124.        for(ctx = 0; ctx < 8; ctx++) {
  125.        sun3_put_context(ctx);
  126.        sun3_put_segmap(addr, SUN3_INVALID_PMEG);
  127.        }
  128.        }
  129.        sun3_put_context(oldctx);
  130.        /* erase all of the userspace pmeg maps, we've clobbered them
  131.   all anyway */
  132.        for(addr = 0; addr < SUN3_INVALID_PMEG; addr++) {
  133.        if(pmeg_alloc[addr] == 1) {
  134.        pmeg_alloc[addr] = 0;
  135.        pmeg_ctx[addr] = 0;
  136.        pmeg_vaddr[addr] = 0;
  137.        }
  138.        }
  139. }
  140. /* Clear user TLB entries within the context named in mm */
  141. static inline void flush_tlb_mm (struct mm_struct *mm)
  142. {
  143.      unsigned char oldctx;
  144.      unsigned char seg;
  145.      unsigned long i;
  146.      oldctx = sun3_get_context();
  147.      sun3_put_context(mm->context);
  148.      for(i = 0; i < TASK_SIZE; i += SUN3_PMEG_SIZE) {
  149.      seg = sun3_get_segmap(i);
  150.      if(seg == SUN3_INVALID_PMEG)
  151.      continue;
  152.      
  153.      sun3_put_segmap(i, SUN3_INVALID_PMEG);
  154.      pmeg_alloc[seg] = 0;
  155.      pmeg_ctx[seg] = 0;
  156.      pmeg_vaddr[seg] = 0;
  157.      }
  158.      sun3_put_context(oldctx);
  159.            
  160. }
  161. /* Flush a single TLB page. In this case, we're limited to flushing a
  162.    single PMEG */
  163. static inline void flush_tlb_page (struct vm_area_struct *vma,
  164.    unsigned long addr)
  165. {
  166. unsigned char oldctx;
  167. unsigned char i;
  168. oldctx = sun3_get_context();
  169. sun3_put_context(vma->vm_mm->context);
  170. addr &= ~SUN3_PMEG_MASK;
  171. if((i = sun3_get_segmap(addr)) != SUN3_INVALID_PMEG)
  172. {
  173. pmeg_alloc[i] = 0;
  174. pmeg_ctx[i] = 0;
  175. pmeg_vaddr[i] = 0;
  176. sun3_put_segmap (addr,  SUN3_INVALID_PMEG);     
  177. }
  178. sun3_put_context(oldctx);
  179. }
  180. /* Flush a range of pages from TLB. */
  181. static inline void flush_tlb_range (struct mm_struct *mm,
  182.       unsigned long start, unsigned long end)
  183. {
  184. unsigned char seg, oldctx;
  185. start &= ~SUN3_PMEG_MASK;
  186. oldctx = sun3_get_context();
  187. sun3_put_context(mm->context);
  188. while(start < end)
  189. {
  190. if((seg = sun3_get_segmap(start)) == SUN3_INVALID_PMEG) 
  191.      goto next;
  192. if(pmeg_ctx[seg] == mm->context) {
  193. pmeg_alloc[seg] = 0;
  194. pmeg_ctx[seg] = 0;
  195. pmeg_vaddr[seg] = 0;
  196. }
  197. sun3_put_segmap(start, SUN3_INVALID_PMEG);
  198. next:
  199. start += SUN3_PMEG_SIZE;
  200. }
  201. }
  202. /* Flush kernel page from TLB. */
  203. static inline void flush_tlb_kernel_page (unsigned long addr)
  204. {
  205. sun3_put_segmap (addr & ~(SUN3_PMEG_SIZE - 1), SUN3_INVALID_PMEG);
  206. }
  207. extern inline void flush_tlb_pgtables(struct mm_struct *mm,
  208.       unsigned long start, unsigned long end)
  209. {
  210. }
  211. #endif /* SUN3_PGALLOC_H */