page.h 5.6 KB
Newer Older
L
Linus Torvalds 已提交
1 2 3 4 5 6 7 8 9 10 11
/*
 *  include/asm-s390/page.h
 *
 *  S390 version
 *    Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation
 *    Author(s): Hartmut Penner (hp@de.ibm.com)
 */

#ifndef _S390_PAGE_H
#define _S390_PAGE_H

12
#include <linux/const.h>
L
Linus Torvalds 已提交
13 14 15 16
#include <asm/types.h>

/* PAGE_SHIFT determines the page size */
#define PAGE_SHIFT      12
17
#define PAGE_SIZE	(_AC(1,UL) << PAGE_SHIFT)
L
Linus Torvalds 已提交
18
#define PAGE_MASK       (~(PAGE_SIZE-1))
19 20
#define PAGE_DEFAULT_ACC	0
#define PAGE_DEFAULT_KEY	(PAGE_DEFAULT_ACC << 4)
L
Linus Torvalds 已提交
21

22 23 24 25 26 27 28 29 30 31
#define HPAGE_SHIFT	20
#define HPAGE_SIZE	(1UL << HPAGE_SHIFT)
#define HPAGE_MASK	(~(HPAGE_SIZE - 1))
#define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)

#define ARCH_HAS_SETCLEAR_HUGE_PTE
#define ARCH_HAS_HUGE_PTE_TYPE
#define ARCH_HAS_PREPARE_HUGEPAGE
#define ARCH_HAS_HUGEPAGE_CLEAR_FLUSH

32
#include <asm/setup.h>
L
Linus Torvalds 已提交
33 34 35 36
#ifndef __ASSEMBLY__

static inline void clear_page(void *page)
{
37 38 39 40 41 42 43 44 45 46 47 48 49
	if (MACHINE_HAS_PFMF) {
		asm volatile(
			"	.insn	rre,0xb9af0000,%0,%1"
			: : "d" (0x10000), "a" (page) : "memory", "cc");
	} else {
		register unsigned long reg1 asm ("1") = 0;
		register void *reg2 asm ("2") = page;
		register unsigned long reg3 asm ("3") = 4096;
		asm volatile(
			"	mvcl	2,0"
			: "+d" (reg2), "+d" (reg3) : "d" (reg1)
			: "memory", "cc");
	}
L
Linus Torvalds 已提交
50 51 52 53
}

static inline void copy_page(void *to, void *from)
{
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
	if (MACHINE_HAS_MVPG) {
		register unsigned long reg0 asm ("0") = 0;
		asm volatile(
			"	mvpg	%0,%1"
			: : "a" (to), "a" (from), "d" (reg0)
			: "memory", "cc");
	} else
		asm volatile(
			"	mvc	0(256,%0),0(%1)\n"
			"	mvc	256(256,%0),256(%1)\n"
			"	mvc	512(256,%0),512(%1)\n"
			"	mvc	768(256,%0),768(%1)\n"
			"	mvc	1024(256,%0),1024(%1)\n"
			"	mvc	1280(256,%0),1280(%1)\n"
			"	mvc	1536(256,%0),1536(%1)\n"
			"	mvc	1792(256,%0),1792(%1)\n"
			"	mvc	2048(256,%0),2048(%1)\n"
			"	mvc	2304(256,%0),2304(%1)\n"
			"	mvc	2560(256,%0),2560(%1)\n"
			"	mvc	2816(256,%0),2816(%1)\n"
			"	mvc	3072(256,%0),3072(%1)\n"
			"	mvc	3328(256,%0),3328(%1)\n"
			"	mvc	3584(256,%0),3584(%1)\n"
			"	mvc	3840(256,%0),3840(%1)\n"
			: : "a" (to), "a" (from) : "memory");
L
Linus Torvalds 已提交
79 80 81 82 83
}

#define clear_user_page(page, vaddr, pg)	clear_page(page)
#define copy_user_page(to, from, vaddr, pg)	copy_page(to, from)

84 85
#define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \
	alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr)
L
Linus Torvalds 已提交
86 87 88 89 90 91 92
#define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE

/*
 * These are used to make use of C type-checking..
 */

typedef struct { unsigned long pgprot; } pgprot_t;
93
typedef struct { unsigned long pgste; } pgste_t;
L
Linus Torvalds 已提交
94 95
typedef struct { unsigned long pte; } pte_t;
typedef struct { unsigned long pmd; } pmd_t;
M
Martin Schwidefsky 已提交
96
typedef struct { unsigned long pud; } pud_t;
L
Linus Torvalds 已提交
97
typedef struct { unsigned long pgd; } pgd_t;
98
typedef pte_t *pgtable_t;
L
Linus Torvalds 已提交
99

100
#define pgprot_val(x)	((x).pgprot)
101
#define pgste_val(x)	((x).pgste)
102 103
#define pte_val(x)	((x).pte)
#define pmd_val(x)	((x).pmd)
M
Martin Schwidefsky 已提交
104
#define pud_val(x)	((x).pud)
L
Linus Torvalds 已提交
105 106
#define pgd_val(x)      ((x).pgd)

107
#define __pgste(x)	((pgste_t) { (x) } )
L
Linus Torvalds 已提交
108 109
#define __pte(x)        ((pte_t) { (x) } )
#define __pmd(x)        ((pmd_t) { (x) } )
110
#define __pud(x)	((pud_t) { (x) } )
L
Linus Torvalds 已提交
111 112 113
#define __pgd(x)        ((pgd_t) { (x) } )
#define __pgprot(x)     ((pgprot_t) { (x) } )

114 115
static inline void page_set_storage_key(unsigned long addr,
					unsigned char skey, int mapped)
L
Linus Torvalds 已提交
116
{
117 118 119 120 121
	if (!mapped)
		asm volatile(".insn rrf,0xb22b0000,%0,%1,8,0"
			     : : "d" (skey), "a" (addr));
	else
		asm volatile("sske %0,%1" : : "d" (skey), "a" (addr));
L
Linus Torvalds 已提交
122 123
}

124
static inline unsigned char page_get_storage_key(unsigned long addr)
L
Linus Torvalds 已提交
125
{
126
	unsigned char skey;
L
Linus Torvalds 已提交
127

128
	asm volatile("iske %0,%1" : "=d" (skey) : "a" (addr));
L
Linus Torvalds 已提交
129 130 131
	return skey;
}

132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176
static inline int page_reset_referenced(unsigned long addr)
{
	unsigned int ipm;

	asm volatile(
		"	rrbe	0,%1\n"
		"	ipm	%0\n"
		: "=d" (ipm) : "a" (addr) : "cc");
	return !!(ipm & 0x20000000);
}

/* Bits int the storage key */
#define _PAGE_CHANGED		0x02	/* HW changed bit		*/
#define _PAGE_REFERENCED	0x04	/* HW referenced bit		*/
#define _PAGE_FP_BIT		0x08	/* HW fetch protection bit	*/
#define _PAGE_ACC_BITS		0xf0	/* HW access control bits	*/

/*
 * Test and clear dirty bit in storage key.
 * We can't clear the changed bit atomically. This is a potential
 * race against modification of the referenced bit. This function
 * should therefore only be called if it is not mapped in any
 * address space.
 */
#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY
static inline int page_test_and_clear_dirty(unsigned long pfn, int mapped)
{
	unsigned char skey;

	skey = page_get_storage_key(pfn << PAGE_SHIFT);
	if (!(skey & _PAGE_CHANGED))
		return 0;
	page_set_storage_key(pfn << PAGE_SHIFT, skey & ~_PAGE_CHANGED, mapped);
	return 1;
}

/*
 * Test and clear referenced bit in storage key.
 */
#define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG
static inline int page_test_and_clear_young(unsigned long pfn)
{
	return page_reset_referenced(pfn << PAGE_SHIFT);
}

177 178 179 180
struct page;
void arch_free_page(struct page *page, int order);
void arch_alloc_page(struct page *page, int order);

181 182 183 184 185
static inline int devmem_is_allowed(unsigned long pfn)
{
	return 0;
}

186 187 188
#define HAVE_ARCH_FREE_PAGE
#define HAVE_ARCH_ALLOC_PAGE

L
Linus Torvalds 已提交
189 190 191 192 193 194 195
#endif /* !__ASSEMBLY__ */

#define __PAGE_OFFSET           0x0UL
#define PAGE_OFFSET             0x0UL
#define __pa(x)                 (unsigned long)(x)
#define __va(x)                 (void *)(unsigned long)(x)
#define virt_to_page(kaddr)	pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)
196
#define page_to_phys(page)	(page_to_pfn(page) << PAGE_SHIFT)
L
Linus Torvalds 已提交
197 198
#define virt_addr_valid(kaddr)	pfn_valid(__pa(kaddr) >> PAGE_SHIFT)

199
#define VM_DATA_DEFAULT_FLAGS	(VM_READ | VM_WRITE | \
L
Linus Torvalds 已提交
200 201
				 VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)

202
#include <asm-generic/memory_model.h>
203
#include <asm-generic/getorder.h>
204

M
Martin Schwidefsky 已提交
205 206
#define __HAVE_ARCH_GATE_AREA 1

L
Linus Torvalds 已提交
207
#endif /* _S390_PAGE_H */