linux/arch/tile/include/asm/pgtable_64.h
<<
>>
Prefs
   1/*
   2 * Copyright 2011 Tilera Corporation. All Rights Reserved.
   3 *
   4 *   This program is free software; you can redistribute it and/or
   5 *   modify it under the terms of the GNU General Public License
   6 *   as published by the Free Software Foundation, version 2.
   7 *
   8 *   This program is distributed in the hope that it will be useful, but
   9 *   WITHOUT ANY WARRANTY; without even the implied warranty of
  10 *   MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  11 *   NON INFRINGEMENT.  See the GNU General Public License for
  12 *   more details.
  13 *
  14 */
  15
  16#ifndef _ASM_TILE_PGTABLE_64_H
  17#define _ASM_TILE_PGTABLE_64_H
  18
  19/* The level-0 page table breaks the address space into 32-bit chunks. */
  20#define PGDIR_SHIFT     HV_LOG2_L1_SPAN
  21#define PGDIR_SIZE      HV_L1_SPAN
  22#define PGDIR_MASK      (~(PGDIR_SIZE-1))
  23#define PTRS_PER_PGD    HV_L0_ENTRIES
  24#define SIZEOF_PGD      (PTRS_PER_PGD * sizeof(pgd_t))
  25
  26/*
  27 * The level-1 index is defined by the huge page size.  A PMD is composed
  28 * of PTRS_PER_PMD pgd_t's and is the middle level of the page table.
  29 */
  30#define PMD_SHIFT       HV_LOG2_PAGE_SIZE_LARGE
  31#define PMD_SIZE        HV_PAGE_SIZE_LARGE
  32#define PMD_MASK        (~(PMD_SIZE-1))
  33#define PTRS_PER_PMD    (1 << (PGDIR_SHIFT - PMD_SHIFT))
  34#define SIZEOF_PMD      (PTRS_PER_PMD * sizeof(pmd_t))
  35
  36/*
  37 * The level-2 index is defined by the difference between the huge
  38 * page size and the normal page size.  A PTE is composed of
  39 * PTRS_PER_PTE pte_t's and is the bottom level of the page table.
  40 * Note that the hypervisor docs use PTE for what we call pte_t, so
  41 * this nomenclature is somewhat confusing.
  42 */
  43#define PTRS_PER_PTE (1 << (HV_LOG2_PAGE_SIZE_LARGE - HV_LOG2_PAGE_SIZE_SMALL))
  44#define SIZEOF_PTE      (PTRS_PER_PTE * sizeof(pte_t))
  45
  46/*
  47 * Align the vmalloc area to an L2 page table, and leave a guard page
  48 * at the beginning and end.  The vmalloc code also puts in an internal
  49 * guard page between each allocation.
  50 */
  51#define _VMALLOC_END    HUGE_VMAP_BASE
  52#define VMALLOC_END     (_VMALLOC_END - PAGE_SIZE)
  53#define VMALLOC_START   (_VMALLOC_START + PAGE_SIZE)
  54
  55#define HUGE_VMAP_END   (HUGE_VMAP_BASE + PGDIR_SIZE)
  56
  57#ifndef __ASSEMBLY__
  58
  59/* We have no pud since we are a three-level page table. */
  60#include <asm-generic/pgtable-nopud.h>
  61
  62static inline int pud_none(pud_t pud)
  63{
  64        return pud_val(pud) == 0;
  65}
  66
  67static inline int pud_present(pud_t pud)
  68{
  69        return pud_val(pud) & _PAGE_PRESENT;
  70}
  71
  72#define pmd_ERROR(e) \
  73        pr_err("%s:%d: bad pmd 0x%016llx.\n", __FILE__, __LINE__, pmd_val(e))
  74
  75static inline void pud_clear(pud_t *pudp)
  76{
  77        __pte_clear(&pudp->pgd);
  78}
  79
  80static inline int pud_bad(pud_t pud)
  81{
  82        return ((pud_val(pud) & _PAGE_ALL) != _PAGE_TABLE);
  83}
  84
  85/* Return the page-table frame number (ptfn) that a pud_t points at. */
  86#define pud_ptfn(pud) hv_pte_get_ptfn((pud).pgd)
  87
  88/*
  89 * A given kernel pud_t maps to a kernel pmd_t table at a specific
  90 * virtual address.  Since kernel pmd_t tables can be aligned at
  91 * sub-page granularity, this macro can return non-page-aligned
  92 * pointers, despite its name.
  93 */
  94#define pud_page_vaddr(pud) \
  95        (__va((phys_addr_t)pud_ptfn(pud) << HV_LOG2_PAGE_TABLE_ALIGN))
  96
  97/*
  98 * A pud_t points to a pmd_t array.  Since we can have multiple per
  99 * page, we don't have a one-to-one mapping of pud_t's to pages.
 100 */
 101#define pud_page(pud) pfn_to_page(HV_PTFN_TO_PFN(pud_ptfn(pud)))
 102
 103static inline unsigned long pud_index(unsigned long address)
 104{
 105        return (address >> PUD_SHIFT) & (PTRS_PER_PUD - 1);
 106}
 107
 108#define pmd_offset(pud, address) \
 109        ((pmd_t *)pud_page_vaddr(*(pud)) + pmd_index(address))
 110
 111static inline void __set_pmd(pmd_t *pmdp, pmd_t pmdval)
 112{
 113        set_pte(pmdp, pmdval);
 114}
 115
 116/* Create a pmd from a PTFN and pgprot. */
 117static inline pmd_t ptfn_pmd(unsigned long ptfn, pgprot_t prot)
 118{
 119        return hv_pte_set_ptfn(prot, ptfn);
 120}
 121
 122/* Return the page-table frame number (ptfn) that a pmd_t points at. */
 123static inline unsigned long pmd_ptfn(pmd_t pmd)
 124{
 125        return hv_pte_get_ptfn(pmd);
 126}
 127
 128static inline void pmd_clear(pmd_t *pmdp)
 129{
 130        __pte_clear(pmdp);
 131}
 132
 133/* Normalize an address to having the correct high bits set. */
 134#define pgd_addr_normalize pgd_addr_normalize
 135static inline unsigned long pgd_addr_normalize(unsigned long addr)
 136{
 137        return ((long)addr << (CHIP_WORD_SIZE() - CHIP_VA_WIDTH())) >>
 138                (CHIP_WORD_SIZE() - CHIP_VA_WIDTH());
 139}
 140
 141/* We don't define any pgds for these addresses. */
 142static inline int pgd_addr_invalid(unsigned long addr)
 143{
 144        return addr >= MEM_HV_START ||
 145                (addr > MEM_LOW_END && addr < MEM_HIGH_START);
 146}
 147
 148/*
 149 * Use atomic instructions to provide atomicity against the hypervisor.
 150 */
 151#define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG
 152static inline int ptep_test_and_clear_young(struct vm_area_struct *vma,
 153                                            unsigned long addr, pte_t *ptep)
 154{
 155        return (__insn_fetchand(&ptep->val, ~HV_PTE_ACCESSED) >>
 156                HV_PTE_INDEX_ACCESSED) & 0x1;
 157}
 158
 159#define __HAVE_ARCH_PTEP_SET_WRPROTECT
 160static inline void ptep_set_wrprotect(struct mm_struct *mm,
 161                                      unsigned long addr, pte_t *ptep)
 162{
 163        __insn_fetchand(&ptep->val, ~HV_PTE_WRITABLE);
 164}
 165
 166#define __HAVE_ARCH_PTEP_GET_AND_CLEAR
 167static inline pte_t ptep_get_and_clear(struct mm_struct *mm,
 168                                       unsigned long addr, pte_t *ptep)
 169{
 170        return hv_pte(__insn_exch(&ptep->val, 0UL));
 171}
 172
 173#endif /* __ASSEMBLY__ */
 174
 175#endif /* _ASM_TILE_PGTABLE_64_H */
 176
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.