home *** CD-ROM | disk | FTP | other *** search
/ PC Welt 2006 November (DVD) / PCWELT_11_2006.ISO / casper / filesystem.squashfs / usr / src / linux-headers-2.6.17-6 / include / asm-s390 / pgalloc.h < prev    next >
Encoding:
C/C++ Source or Header  |  2006-08-11  |  3.7 KB  |  161 lines

  1. /*
  2.  *  include/asm-s390/pgalloc.h
  3.  *
  4.  *  S390 version
  5.  *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
  6.  *    Author(s): Hartmut Penner (hp@de.ibm.com)
  7.  *               Martin Schwidefsky (schwidefsky@de.ibm.com)
  8.  *
  9.  *  Derived from "include/asm-i386/pgalloc.h"
  10.  *    Copyright (C) 1994  Linus Torvalds
  11.  */
  12.  
  13. #ifndef _S390_PGALLOC_H
  14. #define _S390_PGALLOC_H
  15.  
  16. #include <linux/threads.h>
  17. #include <linux/gfp.h>
  18. #include <linux/mm.h>
  19.  
  20. #define check_pgt_cache()    do {} while (0)
  21.  
  22. extern void diag10(unsigned long addr);
  23.  
  24. /*
  25.  * Allocate and free page tables. The xxx_kernel() versions are
  26.  * used to allocate a kernel page table - this turns on ASN bits
  27.  * if any.
  28.  */
  29.  
  30. static inline pgd_t *pgd_alloc(struct mm_struct *mm)
  31. {
  32.     pgd_t *pgd;
  33.     int i;
  34.  
  35. #ifndef __s390x__
  36.     pgd = (pgd_t *) __get_free_pages(GFP_KERNEL,1);
  37.         if (pgd != NULL)
  38.         for (i = 0; i < USER_PTRS_PER_PGD; i++)
  39.             pmd_clear(pmd_offset(pgd + i, i*PGDIR_SIZE));
  40. #else /* __s390x__ */
  41.     pgd = (pgd_t *) __get_free_pages(GFP_KERNEL,2);
  42.         if (pgd != NULL)
  43.         for (i = 0; i < PTRS_PER_PGD; i++)
  44.             pgd_clear(pgd + i);
  45. #endif /* __s390x__ */
  46.     return pgd;
  47. }
  48.  
  49. static inline void pgd_free(pgd_t *pgd)
  50. {
  51. #ifndef __s390x__
  52.         free_pages((unsigned long) pgd, 1);
  53. #else /* __s390x__ */
  54.         free_pages((unsigned long) pgd, 2);
  55. #endif /* __s390x__ */
  56. }
  57.  
  58. #ifndef __s390x__
  59. /*
  60.  * page middle directory allocation/free routines.
  61.  * We use pmd cache only on s390x, so these are dummy routines. This
  62.  * code never triggers because the pgd will always be present.
  63.  */
  64. #define pmd_alloc_one(mm,address)       ({ BUG(); ((pmd_t *)2); })
  65. #define pmd_free(x)                     do { } while (0)
  66. #define __pmd_free_tlb(tlb,x)        do { } while (0)
  67. #define pgd_populate(mm, pmd, pte)      BUG()
  68. #else /* __s390x__ */
  69. static inline pmd_t * pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
  70. {
  71.     pmd_t *pmd;
  72.         int i;
  73.  
  74.     pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, 2);
  75.     if (pmd != NULL) {
  76.         for (i=0; i < PTRS_PER_PMD; i++)
  77.             pmd_clear(pmd+i);
  78.     }
  79.     return pmd;
  80. }
  81.  
  82. static inline void pmd_free (pmd_t *pmd)
  83. {
  84.     free_pages((unsigned long) pmd, 2);
  85. }
  86.  
  87. #define __pmd_free_tlb(tlb,pmd)            \
  88.     do {                    \
  89.         tlb_flush_mmu(tlb, 0, 0);    \
  90.         pmd_free(pmd);            \
  91.      } while (0)
  92.  
  93. static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd)
  94. {
  95.     pgd_val(*pgd) = _PGD_ENTRY | __pa(pmd);
  96. }
  97.  
  98. #endif /* __s390x__ */
  99.  
  100. static inline void 
  101. pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte)
  102. {
  103. #ifndef __s390x__
  104.     pmd_val(pmd[0]) = _PAGE_TABLE + __pa(pte);
  105.     pmd_val(pmd[1]) = _PAGE_TABLE + __pa(pte+256);
  106.     pmd_val(pmd[2]) = _PAGE_TABLE + __pa(pte+512);
  107.     pmd_val(pmd[3]) = _PAGE_TABLE + __pa(pte+768);
  108. #else /* __s390x__ */
  109.     pmd_val(*pmd) = _PMD_ENTRY + __pa(pte);
  110.     pmd_val1(*pmd) = _PMD_ENTRY + __pa(pte+256);
  111. #endif /* __s390x__ */
  112. }
  113.  
  114. static inline void
  115. pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *page)
  116. {
  117.     pmd_populate_kernel(mm, pmd, (pte_t *)((page-mem_map) << PAGE_SHIFT));
  118. }
  119.  
  120. /*
  121.  * page table entry allocation/free routines.
  122.  */
  123. static inline pte_t *
  124. pte_alloc_one_kernel(struct mm_struct *mm, unsigned long vmaddr)
  125. {
  126.     pte_t *pte;
  127.         int i;
  128.  
  129.     pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT);
  130.     if (pte != NULL) {
  131.         for (i=0; i < PTRS_PER_PTE; i++) {
  132.             pte_clear(mm, vmaddr, pte+i);
  133.             vmaddr += PAGE_SIZE;
  134.         }
  135.     }
  136.     return pte;
  137. }
  138.  
  139. static inline struct page *
  140. pte_alloc_one(struct mm_struct *mm, unsigned long vmaddr)
  141. {
  142.     pte_t *pte = pte_alloc_one_kernel(mm, vmaddr);
  143.     if (pte)
  144.         return virt_to_page(pte);
  145.     return 0;
  146. }
  147.  
  148. static inline void pte_free_kernel(pte_t *pte)
  149. {
  150.         free_page((unsigned long) pte);
  151. }
  152.  
  153. static inline void pte_free(struct page *pte)
  154. {
  155.         __free_page(pte);
  156. }
  157.  
  158. #define __pte_free_tlb(tlb,pte) tlb_remove_page(tlb,pte)
  159.  
  160. #endif /* _S390_PGALLOC_H */
  161.