1c6557e7fSMartin Schwidefsky /* 2c6557e7fSMartin Schwidefsky * include/asm-s390/page.h 3c6557e7fSMartin Schwidefsky * 4c6557e7fSMartin Schwidefsky * S390 version 5c6557e7fSMartin Schwidefsky * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation 6c6557e7fSMartin Schwidefsky * Author(s): Hartmut Penner (hp@de.ibm.com) 7c6557e7fSMartin Schwidefsky */ 8c6557e7fSMartin Schwidefsky 9c6557e7fSMartin Schwidefsky #ifndef _S390_PAGE_H 10c6557e7fSMartin Schwidefsky #define _S390_PAGE_H 11c6557e7fSMartin Schwidefsky 12c6557e7fSMartin Schwidefsky #include <linux/const.h> 13c6557e7fSMartin Schwidefsky #include <asm/types.h> 14c6557e7fSMartin Schwidefsky 15c6557e7fSMartin Schwidefsky /* PAGE_SHIFT determines the page size */ 16c6557e7fSMartin Schwidefsky #define PAGE_SHIFT 12 17c6557e7fSMartin Schwidefsky #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) 18c6557e7fSMartin Schwidefsky #define PAGE_MASK (~(PAGE_SIZE-1)) 19c6557e7fSMartin Schwidefsky #define PAGE_DEFAULT_ACC 0 20c6557e7fSMartin Schwidefsky #define PAGE_DEFAULT_KEY (PAGE_DEFAULT_ACC << 4) 21c6557e7fSMartin Schwidefsky 22c6557e7fSMartin Schwidefsky #define HPAGE_SHIFT 20 23c6557e7fSMartin Schwidefsky #define HPAGE_SIZE (1UL << HPAGE_SHIFT) 24c6557e7fSMartin Schwidefsky #define HPAGE_MASK (~(HPAGE_SIZE - 1)) 25c6557e7fSMartin Schwidefsky #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) 26c6557e7fSMartin Schwidefsky 27c6557e7fSMartin Schwidefsky #define ARCH_HAS_SETCLEAR_HUGE_PTE 28c6557e7fSMartin Schwidefsky #define ARCH_HAS_HUGE_PTE_TYPE 29c6557e7fSMartin Schwidefsky #define ARCH_HAS_PREPARE_HUGEPAGE 30c6557e7fSMartin Schwidefsky #define ARCH_HAS_HUGEPAGE_CLEAR_FLUSH 31c6557e7fSMartin Schwidefsky 32c6557e7fSMartin Schwidefsky #include <asm/setup.h> 33c6557e7fSMartin Schwidefsky #ifndef __ASSEMBLY__ 34c6557e7fSMartin Schwidefsky 35c6557e7fSMartin Schwidefsky static inline void clear_page(void *page) 36c6557e7fSMartin Schwidefsky { 37c6557e7fSMartin Schwidefsky if (MACHINE_HAS_PFMF) { 38c6557e7fSMartin Schwidefsky asm volatile( 39c6557e7fSMartin Schwidefsky " .insn rre,0xb9af0000,%0,%1" 40c6557e7fSMartin Schwidefsky : : "d" (0x10000), "a" (page) : "memory", "cc"); 41c6557e7fSMartin Schwidefsky } else { 42c6557e7fSMartin Schwidefsky register unsigned long reg1 asm ("1") = 0; 43c6557e7fSMartin Schwidefsky register void *reg2 asm ("2") = page; 44c6557e7fSMartin Schwidefsky register unsigned long reg3 asm ("3") = 4096; 45c6557e7fSMartin Schwidefsky asm volatile( 46c6557e7fSMartin Schwidefsky " mvcl 2,0" 47c6557e7fSMartin Schwidefsky : "+d" (reg2), "+d" (reg3) : "d" (reg1) 48c6557e7fSMartin Schwidefsky : "memory", "cc"); 49c6557e7fSMartin Schwidefsky } 50c6557e7fSMartin Schwidefsky } 51c6557e7fSMartin Schwidefsky 52c6557e7fSMartin Schwidefsky static inline void copy_page(void *to, void *from) 53c6557e7fSMartin Schwidefsky { 54c6557e7fSMartin Schwidefsky if (MACHINE_HAS_MVPG) { 55c6557e7fSMartin Schwidefsky register unsigned long reg0 asm ("0") = 0; 56c6557e7fSMartin Schwidefsky asm volatile( 57c6557e7fSMartin Schwidefsky " mvpg %0,%1" 58c6557e7fSMartin Schwidefsky : : "a" (to), "a" (from), "d" (reg0) 59c6557e7fSMartin Schwidefsky : "memory", "cc"); 60c6557e7fSMartin Schwidefsky } else 61c6557e7fSMartin Schwidefsky asm volatile( 62c6557e7fSMartin Schwidefsky " mvc 0(256,%0),0(%1)\n" 63c6557e7fSMartin Schwidefsky " mvc 256(256,%0),256(%1)\n" 64c6557e7fSMartin Schwidefsky " mvc 512(256,%0),512(%1)\n" 65c6557e7fSMartin Schwidefsky " mvc 768(256,%0),768(%1)\n" 66c6557e7fSMartin Schwidefsky " mvc 1024(256,%0),1024(%1)\n" 67c6557e7fSMartin Schwidefsky " mvc 1280(256,%0),1280(%1)\n" 68c6557e7fSMartin Schwidefsky " mvc 1536(256,%0),1536(%1)\n" 69c6557e7fSMartin Schwidefsky " mvc 1792(256,%0),1792(%1)\n" 70c6557e7fSMartin Schwidefsky " mvc 2048(256,%0),2048(%1)\n" 71c6557e7fSMartin Schwidefsky " mvc 2304(256,%0),2304(%1)\n" 72c6557e7fSMartin Schwidefsky " mvc 2560(256,%0),2560(%1)\n" 73c6557e7fSMartin Schwidefsky " mvc 2816(256,%0),2816(%1)\n" 74c6557e7fSMartin Schwidefsky " mvc 3072(256,%0),3072(%1)\n" 75c6557e7fSMartin Schwidefsky " mvc 3328(256,%0),3328(%1)\n" 76c6557e7fSMartin Schwidefsky " mvc 3584(256,%0),3584(%1)\n" 77c6557e7fSMartin Schwidefsky " mvc 3840(256,%0),3840(%1)\n" 78c6557e7fSMartin Schwidefsky : : "a" (to), "a" (from) : "memory"); 79c6557e7fSMartin Schwidefsky } 80c6557e7fSMartin Schwidefsky 81c6557e7fSMartin Schwidefsky #define clear_user_page(page, vaddr, pg) clear_page(page) 82c6557e7fSMartin Schwidefsky #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) 83c6557e7fSMartin Schwidefsky 84c6557e7fSMartin Schwidefsky #define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ 85c6557e7fSMartin Schwidefsky alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) 86c6557e7fSMartin Schwidefsky #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE 87c6557e7fSMartin Schwidefsky 88c6557e7fSMartin Schwidefsky /* 89c6557e7fSMartin Schwidefsky * These are used to make use of C type-checking.. 90c6557e7fSMartin Schwidefsky */ 91c6557e7fSMartin Schwidefsky 92c6557e7fSMartin Schwidefsky typedef struct { unsigned long pgprot; } pgprot_t; 93*b2fa47e6SMartin Schwidefsky typedef struct { unsigned long pgste; } pgste_t; 94c6557e7fSMartin Schwidefsky typedef struct { unsigned long pte; } pte_t; 95c6557e7fSMartin Schwidefsky typedef struct { unsigned long pmd; } pmd_t; 96c6557e7fSMartin Schwidefsky typedef struct { unsigned long pud; } pud_t; 97c6557e7fSMartin Schwidefsky typedef struct { unsigned long pgd; } pgd_t; 98c6557e7fSMartin Schwidefsky typedef pte_t *pgtable_t; 99c6557e7fSMartin Schwidefsky 100c6557e7fSMartin Schwidefsky #define pgprot_val(x) ((x).pgprot) 101*b2fa47e6SMartin Schwidefsky #define pgste_val(x) ((x).pgste) 102c6557e7fSMartin Schwidefsky #define pte_val(x) ((x).pte) 103c6557e7fSMartin Schwidefsky #define pmd_val(x) ((x).pmd) 104c6557e7fSMartin Schwidefsky #define pud_val(x) ((x).pud) 105c6557e7fSMartin Schwidefsky #define pgd_val(x) ((x).pgd) 106c6557e7fSMartin Schwidefsky 107*b2fa47e6SMartin Schwidefsky #define __pgste(x) ((pgste_t) { (x) } ) 108c6557e7fSMartin Schwidefsky #define __pte(x) ((pte_t) { (x) } ) 109c6557e7fSMartin Schwidefsky #define __pmd(x) ((pmd_t) { (x) } ) 110*b2fa47e6SMartin Schwidefsky #define __pud(x) ((pud_t) { (x) } ) 111c6557e7fSMartin Schwidefsky #define __pgd(x) ((pgd_t) { (x) } ) 112c6557e7fSMartin Schwidefsky #define __pgprot(x) ((pgprot_t) { (x) } ) 113c6557e7fSMartin Schwidefsky 1142d42552dSMartin Schwidefsky static inline void page_set_storage_key(unsigned long addr, 1152d42552dSMartin Schwidefsky unsigned char skey, int mapped) 116c6557e7fSMartin Schwidefsky { 117e2b8d7afSMartin Schwidefsky if (!mapped) 118e2b8d7afSMartin Schwidefsky asm volatile(".insn rrf,0xb22b0000,%0,%1,8,0" 119e2b8d7afSMartin Schwidefsky : : "d" (skey), "a" (addr)); 120e2b8d7afSMartin Schwidefsky else 121c6557e7fSMartin Schwidefsky asm volatile("sske %0,%1" : : "d" (skey), "a" (addr)); 122c6557e7fSMartin Schwidefsky } 123c6557e7fSMartin Schwidefsky 1242d42552dSMartin Schwidefsky static inline unsigned char page_get_storage_key(unsigned long addr) 125c6557e7fSMartin Schwidefsky { 1262d42552dSMartin Schwidefsky unsigned char skey; 127c6557e7fSMartin Schwidefsky 1282d42552dSMartin Schwidefsky asm volatile("iske %0,%1" : "=d" (skey) : "a" (addr)); 129c6557e7fSMartin Schwidefsky return skey; 130c6557e7fSMartin Schwidefsky } 131c6557e7fSMartin Schwidefsky 1322d42552dSMartin Schwidefsky static inline int page_reset_referenced(unsigned long addr) 1332d42552dSMartin Schwidefsky { 1342d42552dSMartin Schwidefsky unsigned int ipm; 1352d42552dSMartin Schwidefsky 1362d42552dSMartin Schwidefsky asm volatile( 1372d42552dSMartin Schwidefsky " rrbe 0,%1\n" 1382d42552dSMartin Schwidefsky " ipm %0\n" 1392d42552dSMartin Schwidefsky : "=d" (ipm) : "a" (addr) : "cc"); 1402d42552dSMartin Schwidefsky return !!(ipm & 0x20000000); 1412d42552dSMartin Schwidefsky } 1422d42552dSMartin Schwidefsky 1432d42552dSMartin Schwidefsky /* Bits int the storage key */ 1442d42552dSMartin Schwidefsky #define _PAGE_CHANGED 0x02 /* HW changed bit */ 1452d42552dSMartin Schwidefsky #define _PAGE_REFERENCED 0x04 /* HW referenced bit */ 1462d42552dSMartin Schwidefsky #define _PAGE_FP_BIT 0x08 /* HW fetch protection bit */ 1472d42552dSMartin Schwidefsky #define _PAGE_ACC_BITS 0xf0 /* HW access control bits */ 1482d42552dSMartin Schwidefsky 1492d42552dSMartin Schwidefsky /* 1502d42552dSMartin Schwidefsky * Test and clear dirty bit in storage key. 1512d42552dSMartin Schwidefsky * We can't clear the changed bit atomically. This is a potential 1522d42552dSMartin Schwidefsky * race against modification of the referenced bit. This function 1532d42552dSMartin Schwidefsky * should therefore only be called if it is not mapped in any 1542d42552dSMartin Schwidefsky * address space. 1552d42552dSMartin Schwidefsky */ 1562d42552dSMartin Schwidefsky #define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY 1572d42552dSMartin Schwidefsky static inline int page_test_and_clear_dirty(unsigned long pfn, int mapped) 1582d42552dSMartin Schwidefsky { 1592d42552dSMartin Schwidefsky unsigned char skey; 1602d42552dSMartin Schwidefsky 1612d42552dSMartin Schwidefsky skey = page_get_storage_key(pfn << PAGE_SHIFT); 1622d42552dSMartin Schwidefsky if (!(skey & _PAGE_CHANGED)) 1632d42552dSMartin Schwidefsky return 0; 1642d42552dSMartin Schwidefsky page_set_storage_key(pfn << PAGE_SHIFT, skey & ~_PAGE_CHANGED, mapped); 1652d42552dSMartin Schwidefsky return 1; 1662d42552dSMartin Schwidefsky } 1672d42552dSMartin Schwidefsky 1682d42552dSMartin Schwidefsky /* 1692d42552dSMartin Schwidefsky * Test and clear referenced bit in storage key. 1702d42552dSMartin Schwidefsky */ 1712d42552dSMartin Schwidefsky #define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG 1722d42552dSMartin Schwidefsky static inline int page_test_and_clear_young(unsigned long pfn) 1732d42552dSMartin Schwidefsky { 1742d42552dSMartin Schwidefsky return page_reset_referenced(pfn << PAGE_SHIFT); 1752d42552dSMartin Schwidefsky } 1762d42552dSMartin Schwidefsky 177c6557e7fSMartin Schwidefsky struct page; 178c6557e7fSMartin Schwidefsky void arch_free_page(struct page *page, int order); 179c6557e7fSMartin Schwidefsky void arch_alloc_page(struct page *page, int order); 180c6557e7fSMartin Schwidefsky 181ec6743bbSHendrik Brueckner static inline int devmem_is_allowed(unsigned long pfn) 182ec6743bbSHendrik Brueckner { 183ec6743bbSHendrik Brueckner return 0; 184ec6743bbSHendrik Brueckner } 185ec6743bbSHendrik Brueckner 186c6557e7fSMartin Schwidefsky #define HAVE_ARCH_FREE_PAGE 187c6557e7fSMartin Schwidefsky #define HAVE_ARCH_ALLOC_PAGE 188c6557e7fSMartin Schwidefsky 189c6557e7fSMartin Schwidefsky #endif /* !__ASSEMBLY__ */ 190c6557e7fSMartin Schwidefsky 191c6557e7fSMartin Schwidefsky #define __PAGE_OFFSET 0x0UL 192c6557e7fSMartin Schwidefsky #define PAGE_OFFSET 0x0UL 193c6557e7fSMartin Schwidefsky #define __pa(x) (unsigned long)(x) 194c6557e7fSMartin Schwidefsky #define __va(x) (void *)(unsigned long)(x) 195c6557e7fSMartin Schwidefsky #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) 196c6557e7fSMartin Schwidefsky #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) 197c6557e7fSMartin Schwidefsky #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) 198c6557e7fSMartin Schwidefsky 199c6557e7fSMartin Schwidefsky #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ 200c6557e7fSMartin Schwidefsky VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) 201c6557e7fSMartin Schwidefsky 202c6557e7fSMartin Schwidefsky #include <asm-generic/memory_model.h> 2035b17e1cdSArnd Bergmann #include <asm-generic/getorder.h> 204c6557e7fSMartin Schwidefsky 205b020632eSMartin Schwidefsky #define __HAVE_ARCH_GATE_AREA 1 206b020632eSMartin Schwidefsky 207c6557e7fSMartin Schwidefsky #endif /* _S390_PAGE_H */ 208