linux/include/asm-sh64/pgalloc.h
<<
>>
Prefs
   1#ifndef __ASM_SH64_PGALLOC_H
   2#define __ASM_SH64_PGALLOC_H
   3
   4/*
   5 * This file is subject to the terms and conditions of the GNU General Public
   6 * License.  See the file "COPYING" in the main directory of this archive
   7 * for more details.
   8 *
   9 * include/asm-sh64/pgalloc.h
  10 *
  11 * Copyright (C) 2000, 2001  Paolo Alberelli
  12 * Copyright (C) 2003, 2004  Paul Mundt
  13 * Copyright (C) 2003, 2004  Richard Curnow
  14 *
  15 */
  16
  17#include <linux/mm.h>
  18#include <linux/quicklist.h>
  19#include <asm/page.h>
  20
  21static inline void pgd_init(unsigned long page)
  22{
  23        unsigned long *pgd = (unsigned long *)page;
  24        extern pte_t empty_bad_pte_table[PTRS_PER_PTE];
  25        int i;
  26
  27        for (i = 0; i < USER_PTRS_PER_PGD; i++)
  28                pgd[i] = (unsigned long)empty_bad_pte_table;
  29}
  30
  31/*
  32 * Allocate and free page tables. The xxx_kernel() versions are
  33 * used to allocate a kernel page table - this turns on ASN bits
  34 * if any.
  35 */
  36
  37static inline pgd_t *get_pgd_slow(void)
  38{
  39        unsigned int pgd_size = (USER_PTRS_PER_PGD * sizeof(pgd_t));
  40        pgd_t *ret = kmalloc(pgd_size, GFP_KERNEL);
  41        return ret;
  42}
  43
  44static inline pgd_t *pgd_alloc(struct mm_struct *mm)
  45{
  46        return quicklist_alloc(0, GFP_KERNEL, NULL);
  47}
  48
  49static inline void pgd_free(pgd_t *pgd)
  50{
  51        quicklist_free(0, NULL, pgd);
  52}
  53
  54static inline struct page *pte_alloc_one(struct mm_struct *mm,
  55                                         unsigned long address)
  56{
  57        void *pg = quicklist_alloc(0, GFP_KERNEL, NULL);
  58        return pg ? virt_to_page(pg) : NULL;
  59}
  60
  61static inline void pte_free_kernel(pte_t *pte)
  62{
  63        quicklist_free(0, NULL, pte);
  64}
  65
  66static inline void pte_free(struct page *pte)
  67{
  68        quicklist_free_page(0, NULL, pte);
  69}
  70
  71static inline pte_t *pte_alloc_one_kernel(struct mm_struct *mm,
  72                                           unsigned long address)
  73{
  74        return quicklist_alloc(0, GFP_KERNEL, NULL);
  75}
  76
  77#define __pte_free_tlb(tlb,pte) tlb_remove_page((tlb),(pte))
  78
  79/*
  80 * allocating and freeing a pmd is trivial: the 1-entry pmd is
  81 * inside the pgd, so has no extra memory associated with it.
  82 */
  83
  84#if defined(CONFIG_SH64_PGTABLE_2_LEVEL)
  85
  86#define pmd_alloc_one(mm, addr)         ({ BUG(); ((pmd_t *)2); })
  87#define pmd_free(x)                     do { } while (0)
  88#define pgd_populate(mm, pmd, pte)      BUG()
  89#define __pte_free_tlb(tlb,pte)         tlb_remove_page((tlb),(pte))
  90#define __pmd_free_tlb(tlb,pmd)         do { } while (0)
  91
  92#elif defined(CONFIG_SH64_PGTABLE_3_LEVEL)
  93
  94static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
  95{
  96        return quicklist_alloc(0, GFP_KERNEL, NULL);
  97}
  98
  99static inline void pmd_free(pmd_t *pmd)
 100{
 101        quicklist_free(0, NULL, pmd);
 102}
 103
 104#define pgd_populate(mm, pgd, pmd)      pgd_set(pgd, pmd)
 105#define __pmd_free_tlb(tlb,pmd)         pmd_free(pmd)
 106
 107#else
 108#error "No defined page table size"
 109#endif
 110
 111#define pmd_populate_kernel(mm, pmd, pte) \
 112        set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) (pte)))
 113
 114static inline void pmd_populate(struct mm_struct *mm, pmd_t *pmd,
 115                                struct page *pte)
 116{
 117        set_pmd(pmd, __pmd(_PAGE_TABLE + (unsigned long) page_address (pte)));
 118}
 119
 120static inline void check_pgt_cache(void)
 121{
 122        quicklist_trim(0, NULL, 25, 16);
 123}
 124
 125#endif /* __ASM_SH64_PGALLOC_H */
 126