/arch/s390/include/asm/pgtable.h
C Header | 1137 lines | 660 code | 141 blank | 336 comment | 62 complexity | 42d44d3e222c1a9a1e0d8ba7d7a05d22 MD5 | raw file
Possible License(s): LGPL-2.0, AGPL-1.0, GPL-2.0
- /*
- * include/asm-s390/pgtable.h
- *
- * S390 version
- * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
- * Author(s): Hartmut Penner (hp@de.ibm.com)
- * Ulrich Weigand (weigand@de.ibm.com)
- * Martin Schwidefsky (schwidefsky@de.ibm.com)
- *
- * Derived from "include/asm-i386/pgtable.h"
- */
- #ifndef _ASM_S390_PGTABLE_H
- #define _ASM_S390_PGTABLE_H
- /*
- * The Linux memory management assumes a three-level page table setup. For
- * s390 31 bit we "fold" the mid level into the top-level page table, so
- * that we physically have the same two-level page table as the s390 mmu
- * expects in 31 bit mode. For s390 64 bit we use three of the five levels
- * the hardware provides (region first and region second tables are not
- * used).
- *
- * The "pgd_xxx()" functions are trivial for a folded two-level
- * setup: the pgd is never bad, and a pmd always exists (as it's folded
- * into the pgd entry)
- *
- * This file contains the functions and defines necessary to modify and use
- * the S390 page table tree.
- */
- #ifndef __ASSEMBLY__
- #include <linux/sched.h>
- #include <linux/mm_types.h>
- #include <asm/bitops.h>
- #include <asm/bug.h>
- #include <asm/processor.h>
- extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096)));
- extern void paging_init(void);
- extern void vmem_map_init(void);
- /*
- * The S390 doesn't have any external MMU info: the kernel page
- * tables contain all the necessary information.
- */
- #define update_mmu_cache(vma, address, ptep) do { } while (0)
- /*
- * ZERO_PAGE is a global shared page that is always zero: used
- * for zero-mapped memory areas etc..
- */
- extern char empty_zero_page[PAGE_SIZE];
- #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
- #endif /* !__ASSEMBLY__ */
- /*
- * PMD_SHIFT determines the size of the area a second-level page
- * table can map
- * PGDIR_SHIFT determines what a third-level page table entry can map
- */
- #ifndef __s390x__
- # define PMD_SHIFT 20
- # define PUD_SHIFT 20
- # define PGDIR_SHIFT 20
- #else /* __s390x__ */
- # define PMD_SHIFT 20
- # define PUD_SHIFT 31
- # define PGDIR_SHIFT 42
- #endif /* __s390x__ */
- #define PMD_SIZE (1UL << PMD_SHIFT)
- #define PMD_MASK (~(PMD_SIZE-1))
- #define PUD_SIZE (1UL << PUD_SHIFT)
- #define PUD_MASK (~(PUD_SIZE-1))
- #define PGDIR_SIZE (1UL << PGDIR_SHIFT)
- #define PGDIR_MASK (~(PGDIR_SIZE-1))
- /*
- * entries per page directory level: the S390 is two-level, so
- * we don't really have any PMD directory physically.
- * for S390 segment-table entries are combined to one PGD
- * that leads to 1024 pte per pgd
- */
- #define PTRS_PER_PTE 256
- #ifndef __s390x__
- #define PTRS_PER_PMD 1
- #define PTRS_PER_PUD 1
- #else /* __s390x__ */
- #define PTRS_PER_PMD 2048
- #define PTRS_PER_PUD 2048
- #endif /* __s390x__ */
- #define PTRS_PER_PGD 2048
- #define FIRST_USER_ADDRESS 0
- #define pte_ERROR(e) \
- printk("%s:%d: bad pte %p.\n", __FILE__, __LINE__, (void *) pte_val(e))
- #define pmd_ERROR(e) \
- printk("%s:%d: bad pmd %p.\n", __FILE__, __LINE__, (void *) pmd_val(e))
- #define pud_ERROR(e) \
- printk("%s:%d: bad pud %p.\n", __FILE__, __LINE__, (void *) pud_val(e))
- #define pgd_ERROR(e) \
- printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e))
- #ifndef __ASSEMBLY__
- /*
- * The vmalloc area will always be on the topmost area of the kernel
- * mapping. We reserve 96MB (31bit) / 128GB (64bit) for vmalloc,
- * which should be enough for any sane case.
- * By putting vmalloc at the top, we maximise the gap between physical
- * memory and vmalloc to catch misplaced memory accesses. As a side
- * effect, this also makes sure that 64 bit module code cannot be used
- * as system call address.
- */
- extern unsigned long VMALLOC_START;
- #ifndef __s390x__
- #define VMALLOC_SIZE (96UL << 20)
- #define VMALLOC_END 0x7e000000UL
- #define VMEM_MAP_END 0x80000000UL
- #else /* __s390x__ */
- #define VMALLOC_SIZE (128UL << 30)
- #define VMALLOC_END 0x3e000000000UL
- #define VMEM_MAP_END 0x40000000000UL
- #endif /* __s390x__ */
- /*
- * VMEM_MAX_PHYS is the highest physical address that can be added to the 1:1
- * mapping. This needs to be calculated at compile time since the size of the
- * VMEM_MAP is static but the size of struct page can change.
- */
- #define VMEM_MAX_PAGES ((VMEM_MAP_END - VMALLOC_END) / sizeof(struct page))
- #define VMEM_MAX_PFN min(VMALLOC_START >> PAGE_SHIFT, VMEM_MAX_PAGES)
- #define VMEM_MAX_PHYS ((VMEM_MAX_PFN << PAGE_SHIFT) & ~((16 << 20) - 1))
- #define vmemmap ((struct page *) VMALLOC_END)
- /*
- * A 31 bit pagetable entry of S390 has following format:
- * | PFRA | | OS |
- * 0 0IP0
- * 00000000001111111111222222222233
- * 01234567890123456789012345678901
- *
- * I Page-Invalid Bit: Page is not available for address-translation
- * P Page-Protection Bit: Store access not possible for page
- *
- * A 31 bit segmenttable entry of S390 has following format:
- * | P-table origin | |PTL
- * 0 IC
- * 00000000001111111111222222222233
- * 01234567890123456789012345678901
- *
- * I Segment-Invalid Bit: Segment is not available for address-translation
- * C Common-Segment Bit: Segment is not private (PoP 3-30)
- * PTL Page-Table-Length: Page-table length (PTL+1*16 entries -> up to 256)
- *
- * The 31 bit segmenttable origin of S390 has following format:
- *
- * |S-table origin | | STL |
- * X **GPS
- * 00000000001111111111222222222233
- * 01234567890123456789012345678901
- *
- * X Space-Switch event:
- * G Segment-Invalid Bit: *
- * P Private-Space Bit: Segment is not private (PoP 3-30)
- * S Storage-Alteration:
- * STL Segment-Table-Length: Segment-table length (STL+1*16 entries -> up to 2048)
- *
- * A 64 bit pagetable entry of S390 has following format:
- * | PFRA |0IPC| OS |
- * 0000000000111111111122222222223333333333444444444455555555556666
- * 0123456789012345678901234567890123456789012345678901234567890123
- *
- * I Page-Invalid Bit: Page is not available for address-translation
- * P Page-Protection Bit: Store access not possible for page
- * C Change-bit override: HW is not required to set change bit
- *
- * A 64 bit segmenttable entry of S390 has following format:
- * | P-table origin | TT
- * 0000000000111111111122222222223333333333444444444455555555556666
- * 0123456789012345678901234567890123456789012345678901234567890123
- *
- * I Segment-Invalid Bit: Segment is not available for address-translation
- * C Common-Segment Bit: Segment is not private (PoP 3-30)
- * P Page-Protection Bit: Store access not possible for page
- * TT Type 00
- *
- * A 64 bit region table entry of S390 has following format:
- * | S-table origin | TF TTTL
- * 0000000000111111111122222222223333333333444444444455555555556666
- * 0123456789012345678901234567890123456789012345678901234567890123
- *
- * I Segment-Invalid Bit: Segment is not available for address-translation
- * TT Type 01
- * TF
- * TL Table length
- *
- * The 64 bit regiontable origin of S390 has following format:
- * | region table origon | DTTL
- * 0000000000111111111122222222223333333333444444444455555555556666
- * 0123456789012345678901234567890123456789012345678901234567890123
- *
- * X Space-Switch event:
- * G Segment-Invalid Bit:
- * P Private-Space Bit:
- * S Storage-Alteration:
- * R Real space
- * TL Table-Length:
- *
- * A storage key has the following format:
- * | ACC |F|R|C|0|
- * 0 3 4 5 6 7
- * ACC: access key
- * F : fetch protection bit
- * R : referenced bit
- * C : changed bit
- */
- /* Hardware bits in the page table entry */
- #define _PAGE_CO 0x100 /* HW Change-bit override */
- #define _PAGE_RO 0x200 /* HW read-only bit */
- #define _PAGE_INVALID 0x400 /* HW invalid bit */
- /* Software bits in the page table entry */
- #define _PAGE_SWT 0x001 /* SW pte type bit t */
- #define _PAGE_SWX 0x002 /* SW pte type bit x */
- #define _PAGE_SPECIAL 0x004 /* SW associated with special page */
- #define __HAVE_ARCH_PTE_SPECIAL
- /* Set of bits not changed in pte_modify */
- #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_SPECIAL)
- /* Six different types of pages. */
- #define _PAGE_TYPE_EMPTY 0x400
- #define _PAGE_TYPE_NONE 0x401
- #define _PAGE_TYPE_SWAP 0x403
- #define _PAGE_TYPE_FILE 0x601 /* bit 0x002 is used for offset !! */
- #define _PAGE_TYPE_RO 0x200
- #define _PAGE_TYPE_RW 0x000
- #define _PAGE_TYPE_EX_RO 0x202
- #define _PAGE_TYPE_EX_RW 0x002
- /*
- * Only four types for huge pages, using the invalid bit and protection bit
- * of a segment table entry.