diff options
Diffstat (limited to 'arch/s390/include')
135 files changed, 15320 insertions, 0 deletions
diff --git a/arch/s390/include/asm/Kbuild b/arch/s390/include/asm/Kbuild new file mode 100644 index 000000000000..63a23415fba6 --- /dev/null +++ b/arch/s390/include/asm/Kbuild | |||
@@ -0,0 +1,15 @@ | |||
1 | include include/asm-generic/Kbuild.asm | ||
2 | |||
3 | header-y += dasd.h | ||
4 | header-y += monwriter.h | ||
5 | header-y += qeth.h | ||
6 | header-y += tape390.h | ||
7 | header-y += ucontext.h | ||
8 | header-y += vtoc.h | ||
9 | header-y += zcrypt.h | ||
10 | header-y += chsc.h | ||
11 | |||
12 | unifdef-y += cmb.h | ||
13 | unifdef-y += debug.h | ||
14 | unifdef-y += chpid.h | ||
15 | unifdef-y += schid.h | ||
diff --git a/arch/s390/include/asm/airq.h b/arch/s390/include/asm/airq.h new file mode 100644 index 000000000000..1ac80d6b0588 --- /dev/null +++ b/arch/s390/include/asm/airq.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * include/asm-s390/airq.h | ||
3 | * | ||
4 | * Copyright IBM Corp. 2002,2007 | ||
5 | * Author(s): Ingo Adlung <adlung@de.ibm.com> | ||
6 | * Cornelia Huck <cornelia.huck@de.ibm.com> | ||
7 | * Arnd Bergmann <arndb@de.ibm.com> | ||
8 | * Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | ||
9 | */ | ||
10 | |||
11 | #ifndef _ASM_S390_AIRQ_H | ||
12 | #define _ASM_S390_AIRQ_H | ||
13 | |||
14 | typedef void (*adapter_int_handler_t)(void *, void *); | ||
15 | |||
16 | void *s390_register_adapter_interrupt(adapter_int_handler_t, void *, u8); | ||
17 | void s390_unregister_adapter_interrupt(void *, u8); | ||
18 | |||
19 | #endif /* _ASM_S390_AIRQ_H */ | ||
diff --git a/arch/s390/include/asm/appldata.h b/arch/s390/include/asm/appldata.h new file mode 100644 index 000000000000..79283dac8281 --- /dev/null +++ b/arch/s390/include/asm/appldata.h | |||
@@ -0,0 +1,90 @@ | |||
1 | /* | ||
2 | * include/asm-s390/appldata.h | ||
3 | * | ||
4 | * Copyright (C) IBM Corp. 2006 | ||
5 | * | ||
6 | * Author(s): Melissa Howland <melissah@us.ibm.com> | ||
7 | */ | ||
8 | |||
9 | #ifndef _ASM_S390_APPLDATA_H | ||
10 | #define _ASM_S390_APPLDATA_H | ||
11 | |||
12 | #include <asm/io.h> | ||
13 | |||
14 | #ifndef CONFIG_64BIT | ||
15 | |||
16 | #define APPLDATA_START_INTERVAL_REC 0x00 /* Function codes for */ | ||
17 | #define APPLDATA_STOP_REC 0x01 /* DIAG 0xDC */ | ||
18 | #define APPLDATA_GEN_EVENT_REC 0x02 | ||
19 | #define APPLDATA_START_CONFIG_REC 0x03 | ||
20 | |||
21 | /* | ||
22 | * Parameter list for DIAGNOSE X'DC' | ||
23 | */ | ||
24 | struct appldata_parameter_list { | ||
25 | u16 diag; /* The DIAGNOSE code X'00DC' */ | ||
26 | u8 function; /* The function code for the DIAGNOSE */ | ||
27 | u8 parlist_length; /* Length of the parameter list */ | ||
28 | u32 product_id_addr; /* Address of the 16-byte product ID */ | ||
29 | u16 reserved; | ||
30 | u16 buffer_length; /* Length of the application data buffer */ | ||
31 | u32 buffer_addr; /* Address of the application data buffer */ | ||
32 | } __attribute__ ((packed)); | ||
33 | |||
34 | #else /* CONFIG_64BIT */ | ||
35 | |||
36 | #define APPLDATA_START_INTERVAL_REC 0x80 | ||
37 | #define APPLDATA_STOP_REC 0x81 | ||
38 | #define APPLDATA_GEN_EVENT_REC 0x82 | ||
39 | #define APPLDATA_START_CONFIG_REC 0x83 | ||
40 | |||
41 | /* | ||
42 | * Parameter list for DIAGNOSE X'DC' | ||
43 | */ | ||
44 | struct appldata_parameter_list { | ||
45 | u16 diag; | ||
46 | u8 function; | ||
47 | u8 parlist_length; | ||
48 | u32 unused01; | ||
49 | u16 reserved; | ||
50 | u16 buffer_length; | ||
51 | u32 unused02; | ||
52 | u64 product_id_addr; | ||
53 | u64 buffer_addr; | ||
54 | } __attribute__ ((packed)); | ||
55 | |||
56 | #endif /* CONFIG_64BIT */ | ||
57 | |||
58 | struct appldata_product_id { | ||
59 | char prod_nr[7]; /* product number */ | ||
60 | u16 prod_fn; /* product function */ | ||
61 | u8 record_nr; /* record number */ | ||
62 | u16 version_nr; /* version */ | ||
63 | u16 release_nr; /* release */ | ||
64 | u16 mod_lvl; /* modification level */ | ||
65 | } __attribute__ ((packed)); | ||
66 | |||
67 | static inline int appldata_asm(struct appldata_product_id *id, | ||
68 | unsigned short fn, void *buffer, | ||
69 | unsigned short length) | ||
70 | { | ||
71 | struct appldata_parameter_list parm_list; | ||
72 | int ry; | ||
73 | |||
74 | if (!MACHINE_IS_VM) | ||
75 | return -ENOSYS; | ||
76 | parm_list.diag = 0xdc; | ||
77 | parm_list.function = fn; | ||
78 | parm_list.parlist_length = sizeof(parm_list); | ||
79 | parm_list.buffer_length = length; | ||
80 | parm_list.product_id_addr = (unsigned long) id; | ||
81 | parm_list.buffer_addr = virt_to_phys(buffer); | ||
82 | asm volatile( | ||
83 | " diag %1,%0,0xdc" | ||
84 | : "=d" (ry) | ||
85 | : "d" (&parm_list), "m" (parm_list), "m" (*id) | ||
86 | : "cc"); | ||
87 | return ry; | ||
88 | } | ||
89 | |||
90 | #endif /* _ASM_S390_APPLDATA_H */ | ||
diff --git a/arch/s390/include/asm/atomic.h b/arch/s390/include/asm/atomic.h new file mode 100644 index 000000000000..2d184655bc5d --- /dev/null +++ b/arch/s390/include/asm/atomic.h | |||
@@ -0,0 +1,285 @@ | |||
1 | #ifndef __ARCH_S390_ATOMIC__ | ||
2 | #define __ARCH_S390_ATOMIC__ | ||
3 | |||
4 | #include <linux/compiler.h> | ||
5 | |||
6 | /* | ||
7 | * include/asm-s390/atomic.h | ||
8 | * | ||
9 | * S390 version | ||
10 | * Copyright (C) 1999-2005 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
11 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | ||
12 | * Denis Joseph Barrow, | ||
13 | * Arnd Bergmann (arndb@de.ibm.com) | ||
14 | * | ||
15 | * Derived from "include/asm-i386/bitops.h" | ||
16 | * Copyright (C) 1992, Linus Torvalds | ||
17 | * | ||
18 | */ | ||
19 | |||
20 | /* | ||
21 | * Atomic operations that C can't guarantee us. Useful for | ||
22 | * resource counting etc.. | ||
23 | * S390 uses 'Compare And Swap' for atomicity in SMP enviroment | ||
24 | */ | ||
25 | |||
26 | typedef struct { | ||
27 | int counter; | ||
28 | } __attribute__ ((aligned (4))) atomic_t; | ||
29 | #define ATOMIC_INIT(i) { (i) } | ||
30 | |||
31 | #ifdef __KERNEL__ | ||
32 | |||
33 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | ||
34 | |||
35 | #define __CS_LOOP(ptr, op_val, op_string) ({ \ | ||
36 | typeof(ptr->counter) old_val, new_val; \ | ||
37 | asm volatile( \ | ||
38 | " l %0,%2\n" \ | ||
39 | "0: lr %1,%0\n" \ | ||
40 | op_string " %1,%3\n" \ | ||
41 | " cs %0,%1,%2\n" \ | ||
42 | " jl 0b" \ | ||
43 | : "=&d" (old_val), "=&d" (new_val), \ | ||
44 | "=Q" (((atomic_t *)(ptr))->counter) \ | ||
45 | : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \ | ||
46 | : "cc", "memory"); \ | ||
47 | new_val; \ | ||
48 | }) | ||
49 | |||
50 | #else /* __GNUC__ */ | ||
51 | |||
52 | #define __CS_LOOP(ptr, op_val, op_string) ({ \ | ||
53 | typeof(ptr->counter) old_val, new_val; \ | ||
54 | asm volatile( \ | ||
55 | " l %0,0(%3)\n" \ | ||
56 | "0: lr %1,%0\n" \ | ||
57 | op_string " %1,%4\n" \ | ||
58 | " cs %0,%1,0(%3)\n" \ | ||
59 | " jl 0b" \ | ||
60 | : "=&d" (old_val), "=&d" (new_val), \ | ||
61 | "=m" (((atomic_t *)(ptr))->counter) \ | ||
62 | : "a" (ptr), "d" (op_val), \ | ||
63 | "m" (((atomic_t *)(ptr))->counter) \ | ||
64 | : "cc", "memory"); \ | ||
65 | new_val; \ | ||
66 | }) | ||
67 | |||
68 | #endif /* __GNUC__ */ | ||
69 | |||
70 | static inline int atomic_read(const atomic_t *v) | ||
71 | { | ||
72 | barrier(); | ||
73 | return v->counter; | ||
74 | } | ||
75 | |||
76 | static inline void atomic_set(atomic_t *v, int i) | ||
77 | { | ||
78 | v->counter = i; | ||
79 | barrier(); | ||
80 | } | ||
81 | |||
82 | static __inline__ int atomic_add_return(int i, atomic_t * v) | ||
83 | { | ||
84 | return __CS_LOOP(v, i, "ar"); | ||
85 | } | ||
86 | #define atomic_add(_i, _v) atomic_add_return(_i, _v) | ||
87 | #define atomic_add_negative(_i, _v) (atomic_add_return(_i, _v) < 0) | ||
88 | #define atomic_inc(_v) atomic_add_return(1, _v) | ||
89 | #define atomic_inc_return(_v) atomic_add_return(1, _v) | ||
90 | #define atomic_inc_and_test(_v) (atomic_add_return(1, _v) == 0) | ||
91 | |||
92 | static __inline__ int atomic_sub_return(int i, atomic_t * v) | ||
93 | { | ||
94 | return __CS_LOOP(v, i, "sr"); | ||
95 | } | ||
96 | #define atomic_sub(_i, _v) atomic_sub_return(_i, _v) | ||
97 | #define atomic_sub_and_test(_i, _v) (atomic_sub_return(_i, _v) == 0) | ||
98 | #define atomic_dec(_v) atomic_sub_return(1, _v) | ||
99 | #define atomic_dec_return(_v) atomic_sub_return(1, _v) | ||
100 | #define atomic_dec_and_test(_v) (atomic_sub_return(1, _v) == 0) | ||
101 | |||
102 | static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t * v) | ||
103 | { | ||
104 | __CS_LOOP(v, ~mask, "nr"); | ||
105 | } | ||
106 | |||
107 | static __inline__ void atomic_set_mask(unsigned long mask, atomic_t * v) | ||
108 | { | ||
109 | __CS_LOOP(v, mask, "or"); | ||
110 | } | ||
111 | |||
112 | #define atomic_xchg(v, new) (xchg(&((v)->counter), new)) | ||
113 | |||
114 | static __inline__ int atomic_cmpxchg(atomic_t *v, int old, int new) | ||
115 | { | ||
116 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | ||
117 | asm volatile( | ||
118 | " cs %0,%2,%1" | ||
119 | : "+d" (old), "=Q" (v->counter) | ||
120 | : "d" (new), "Q" (v->counter) | ||
121 | : "cc", "memory"); | ||
122 | #else /* __GNUC__ */ | ||
123 | asm volatile( | ||
124 | " cs %0,%3,0(%2)" | ||
125 | : "+d" (old), "=m" (v->counter) | ||
126 | : "a" (v), "d" (new), "m" (v->counter) | ||
127 | : "cc", "memory"); | ||
128 | #endif /* __GNUC__ */ | ||
129 | return old; | ||
130 | } | ||
131 | |||
132 | static __inline__ int atomic_add_unless(atomic_t *v, int a, int u) | ||
133 | { | ||
134 | int c, old; | ||
135 | c = atomic_read(v); | ||
136 | for (;;) { | ||
137 | if (unlikely(c == u)) | ||
138 | break; | ||
139 | old = atomic_cmpxchg(v, c, c + a); | ||
140 | if (likely(old == c)) | ||
141 | break; | ||
142 | c = old; | ||
143 | } | ||
144 | return c != u; | ||
145 | } | ||
146 | |||
147 | #define atomic_inc_not_zero(v) atomic_add_unless((v), 1, 0) | ||
148 | |||
149 | #undef __CS_LOOP | ||
150 | |||
151 | #ifdef __s390x__ | ||
152 | typedef struct { | ||
153 | long long counter; | ||
154 | } __attribute__ ((aligned (8))) atomic64_t; | ||
155 | #define ATOMIC64_INIT(i) { (i) } | ||
156 | |||
157 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | ||
158 | |||
159 | #define __CSG_LOOP(ptr, op_val, op_string) ({ \ | ||
160 | typeof(ptr->counter) old_val, new_val; \ | ||
161 | asm volatile( \ | ||
162 | " lg %0,%2\n" \ | ||
163 | "0: lgr %1,%0\n" \ | ||
164 | op_string " %1,%3\n" \ | ||
165 | " csg %0,%1,%2\n" \ | ||
166 | " jl 0b" \ | ||
167 | : "=&d" (old_val), "=&d" (new_val), \ | ||
168 | "=Q" (((atomic_t *)(ptr))->counter) \ | ||
169 | : "d" (op_val), "Q" (((atomic_t *)(ptr))->counter) \ | ||
170 | : "cc", "memory" ); \ | ||
171 | new_val; \ | ||
172 | }) | ||
173 | |||
174 | #else /* __GNUC__ */ | ||
175 | |||
176 | #define __CSG_LOOP(ptr, op_val, op_string) ({ \ | ||
177 | typeof(ptr->counter) old_val, new_val; \ | ||
178 | asm volatile( \ | ||
179 | " lg %0,0(%3)\n" \ | ||
180 | "0: lgr %1,%0\n" \ | ||
181 | op_string " %1,%4\n" \ | ||
182 | " csg %0,%1,0(%3)\n" \ | ||
183 | " jl 0b" \ | ||
184 | : "=&d" (old_val), "=&d" (new_val), \ | ||
185 | "=m" (((atomic_t *)(ptr))->counter) \ | ||
186 | : "a" (ptr), "d" (op_val), \ | ||
187 | "m" (((atomic_t *)(ptr))->counter) \ | ||
188 | : "cc", "memory" ); \ | ||
189 | new_val; \ | ||
190 | }) | ||
191 | |||
192 | #endif /* __GNUC__ */ | ||
193 | |||
194 | static inline long long atomic64_read(const atomic64_t *v) | ||
195 | { | ||
196 | barrier(); | ||
197 | return v->counter; | ||
198 | } | ||
199 | |||
200 | static inline void atomic64_set(atomic64_t *v, long long i) | ||
201 | { | ||
202 | v->counter = i; | ||
203 | barrier(); | ||
204 | } | ||
205 | |||
206 | static __inline__ long long atomic64_add_return(long long i, atomic64_t * v) | ||
207 | { | ||
208 | return __CSG_LOOP(v, i, "agr"); | ||
209 | } | ||
210 | #define atomic64_add(_i, _v) atomic64_add_return(_i, _v) | ||
211 | #define atomic64_add_negative(_i, _v) (atomic64_add_return(_i, _v) < 0) | ||
212 | #define atomic64_inc(_v) atomic64_add_return(1, _v) | ||
213 | #define atomic64_inc_return(_v) atomic64_add_return(1, _v) | ||
214 | #define atomic64_inc_and_test(_v) (atomic64_add_return(1, _v) == 0) | ||
215 | |||
216 | static __inline__ long long atomic64_sub_return(long long i, atomic64_t * v) | ||
217 | { | ||
218 | return __CSG_LOOP(v, i, "sgr"); | ||
219 | } | ||
220 | #define atomic64_sub(_i, _v) atomic64_sub_return(_i, _v) | ||
221 | #define atomic64_sub_and_test(_i, _v) (atomic64_sub_return(_i, _v) == 0) | ||
222 | #define atomic64_dec(_v) atomic64_sub_return(1, _v) | ||
223 | #define atomic64_dec_return(_v) atomic64_sub_return(1, _v) | ||
224 | #define atomic64_dec_and_test(_v) (atomic64_sub_return(1, _v) == 0) | ||
225 | |||
226 | static __inline__ void atomic64_clear_mask(unsigned long mask, atomic64_t * v) | ||
227 | { | ||
228 | __CSG_LOOP(v, ~mask, "ngr"); | ||
229 | } | ||
230 | |||
231 | static __inline__ void atomic64_set_mask(unsigned long mask, atomic64_t * v) | ||
232 | { | ||
233 | __CSG_LOOP(v, mask, "ogr"); | ||
234 | } | ||
235 | |||
236 | #define atomic64_xchg(v, new) (xchg(&((v)->counter), new)) | ||
237 | |||
238 | static __inline__ long long atomic64_cmpxchg(atomic64_t *v, | ||
239 | long long old, long long new) | ||
240 | { | ||
241 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | ||
242 | asm volatile( | ||
243 | " csg %0,%2,%1" | ||
244 | : "+d" (old), "=Q" (v->counter) | ||
245 | : "d" (new), "Q" (v->counter) | ||
246 | : "cc", "memory"); | ||
247 | #else /* __GNUC__ */ | ||
248 | asm volatile( | ||
249 | " csg %0,%3,0(%2)" | ||
250 | : "+d" (old), "=m" (v->counter) | ||
251 | : "a" (v), "d" (new), "m" (v->counter) | ||
252 | : "cc", "memory"); | ||
253 | #endif /* __GNUC__ */ | ||
254 | return old; | ||
255 | } | ||
256 | |||
257 | static __inline__ int atomic64_add_unless(atomic64_t *v, | ||
258 | long long a, long long u) | ||
259 | { | ||
260 | long long c, old; | ||
261 | c = atomic64_read(v); | ||
262 | for (;;) { | ||
263 | if (unlikely(c == u)) | ||
264 | break; | ||
265 | old = atomic64_cmpxchg(v, c, c + a); | ||
266 | if (likely(old == c)) | ||
267 | break; | ||
268 | c = old; | ||
269 | } | ||
270 | return c != u; | ||
271 | } | ||
272 | |||
273 | #define atomic64_inc_not_zero(v) atomic64_add_unless((v), 1, 0) | ||
274 | |||
275 | #undef __CSG_LOOP | ||
276 | #endif | ||
277 | |||
278 | #define smp_mb__before_atomic_dec() smp_mb() | ||
279 | #define smp_mb__after_atomic_dec() smp_mb() | ||
280 | #define smp_mb__before_atomic_inc() smp_mb() | ||
281 | #define smp_mb__after_atomic_inc() smp_mb() | ||
282 | |||
283 | #include <asm-generic/atomic.h> | ||
284 | #endif /* __KERNEL__ */ | ||
285 | #endif /* __ARCH_S390_ATOMIC__ */ | ||
diff --git a/arch/s390/include/asm/auxvec.h b/arch/s390/include/asm/auxvec.h new file mode 100644 index 000000000000..0d340720fd99 --- /dev/null +++ b/arch/s390/include/asm/auxvec.h | |||
@@ -0,0 +1,4 @@ | |||
1 | #ifndef __ASMS390_AUXVEC_H | ||
2 | #define __ASMS390_AUXVEC_H | ||
3 | |||
4 | #endif | ||
diff --git a/arch/s390/include/asm/bitops.h b/arch/s390/include/asm/bitops.h new file mode 100644 index 000000000000..b4eb24ab5af9 --- /dev/null +++ b/arch/s390/include/asm/bitops.h | |||
@@ -0,0 +1,884 @@ | |||
1 | #ifndef _S390_BITOPS_H | ||
2 | #define _S390_BITOPS_H | ||
3 | |||
4 | /* | ||
5 | * include/asm-s390/bitops.h | ||
6 | * | ||
7 | * S390 version | ||
8 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
9 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
10 | * | ||
11 | * Derived from "include/asm-i386/bitops.h" | ||
12 | * Copyright (C) 1992, Linus Torvalds | ||
13 | * | ||
14 | */ | ||
15 | |||
16 | #ifdef __KERNEL__ | ||
17 | |||
18 | #ifndef _LINUX_BITOPS_H | ||
19 | #error only <linux/bitops.h> can be included directly | ||
20 | #endif | ||
21 | |||
22 | #include <linux/compiler.h> | ||
23 | |||
24 | /* | ||
25 | * 32 bit bitops format: | ||
26 | * bit 0 is the LSB of *addr; bit 31 is the MSB of *addr; | ||
27 | * bit 32 is the LSB of *(addr+4). That combined with the | ||
28 | * big endian byte order on S390 give the following bit | ||
29 | * order in memory: | ||
30 | * 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 \ | ||
31 | * 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 | ||
32 | * after that follows the next long with bit numbers | ||
33 | * 3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 | ||
34 | * 2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20 | ||
35 | * The reason for this bit ordering is the fact that | ||
36 | * in the architecture independent code bits operations | ||
37 | * of the form "flags |= (1 << bitnr)" are used INTERMIXED | ||
38 | * with operation of the form "set_bit(bitnr, flags)". | ||
39 | * | ||
40 | * 64 bit bitops format: | ||
41 | * bit 0 is the LSB of *addr; bit 63 is the MSB of *addr; | ||
42 | * bit 64 is the LSB of *(addr+8). That combined with the | ||
43 | * big endian byte order on S390 give the following bit | ||
44 | * order in memory: | ||
45 | * 3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 | ||
46 | * 2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20 | ||
47 | * 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 | ||
48 | * 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 | ||
49 | * after that follows the next long with bit numbers | ||
50 | * 7f 7e 7d 7c 7b 7a 79 78 77 76 75 74 73 72 71 70 | ||
51 | * 6f 6e 6d 6c 6b 6a 69 68 67 66 65 64 63 62 61 60 | ||
52 | * 5f 5e 5d 5c 5b 5a 59 58 57 56 55 54 53 52 51 50 | ||
53 | * 4f 4e 4d 4c 4b 4a 49 48 47 46 45 44 43 42 41 40 | ||
54 | * The reason for this bit ordering is the fact that | ||
55 | * in the architecture independent code bits operations | ||
56 | * of the form "flags |= (1 << bitnr)" are used INTERMIXED | ||
57 | * with operation of the form "set_bit(bitnr, flags)". | ||
58 | */ | ||
59 | |||
60 | /* bitmap tables from arch/S390/kernel/bitmap.S */ | ||
61 | extern const char _oi_bitmap[]; | ||
62 | extern const char _ni_bitmap[]; | ||
63 | extern const char _zb_findmap[]; | ||
64 | extern const char _sb_findmap[]; | ||
65 | |||
66 | #ifndef __s390x__ | ||
67 | |||
68 | #define __BITOPS_ALIGN 3 | ||
69 | #define __BITOPS_WORDSIZE 32 | ||
70 | #define __BITOPS_OR "or" | ||
71 | #define __BITOPS_AND "nr" | ||
72 | #define __BITOPS_XOR "xr" | ||
73 | |||
74 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | ||
75 | |||
76 | #define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ | ||
77 | asm volatile( \ | ||
78 | " l %0,%2\n" \ | ||
79 | "0: lr %1,%0\n" \ | ||
80 | __op_string " %1,%3\n" \ | ||
81 | " cs %0,%1,%2\n" \ | ||
82 | " jl 0b" \ | ||
83 | : "=&d" (__old), "=&d" (__new), \ | ||
84 | "=Q" (*(unsigned long *) __addr) \ | ||
85 | : "d" (__val), "Q" (*(unsigned long *) __addr) \ | ||
86 | : "cc"); | ||
87 | |||
88 | #else /* __GNUC__ */ | ||
89 | |||
90 | #define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ | ||
91 | asm volatile( \ | ||
92 | " l %0,0(%4)\n" \ | ||
93 | "0: lr %1,%0\n" \ | ||
94 | __op_string " %1,%3\n" \ | ||
95 | " cs %0,%1,0(%4)\n" \ | ||
96 | " jl 0b" \ | ||
97 | : "=&d" (__old), "=&d" (__new), \ | ||
98 | "=m" (*(unsigned long *) __addr) \ | ||
99 | : "d" (__val), "a" (__addr), \ | ||
100 | "m" (*(unsigned long *) __addr) : "cc"); | ||
101 | |||
102 | #endif /* __GNUC__ */ | ||
103 | |||
104 | #else /* __s390x__ */ | ||
105 | |||
106 | #define __BITOPS_ALIGN 7 | ||
107 | #define __BITOPS_WORDSIZE 64 | ||
108 | #define __BITOPS_OR "ogr" | ||
109 | #define __BITOPS_AND "ngr" | ||
110 | #define __BITOPS_XOR "xgr" | ||
111 | |||
112 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | ||
113 | |||
114 | #define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ | ||
115 | asm volatile( \ | ||
116 | " lg %0,%2\n" \ | ||
117 | "0: lgr %1,%0\n" \ | ||
118 | __op_string " %1,%3\n" \ | ||
119 | " csg %0,%1,%2\n" \ | ||
120 | " jl 0b" \ | ||
121 | : "=&d" (__old), "=&d" (__new), \ | ||
122 | "=Q" (*(unsigned long *) __addr) \ | ||
123 | : "d" (__val), "Q" (*(unsigned long *) __addr) \ | ||
124 | : "cc"); | ||
125 | |||
126 | #else /* __GNUC__ */ | ||
127 | |||
128 | #define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ | ||
129 | asm volatile( \ | ||
130 | " lg %0,0(%4)\n" \ | ||
131 | "0: lgr %1,%0\n" \ | ||
132 | __op_string " %1,%3\n" \ | ||
133 | " csg %0,%1,0(%4)\n" \ | ||
134 | " jl 0b" \ | ||
135 | : "=&d" (__old), "=&d" (__new), \ | ||
136 | "=m" (*(unsigned long *) __addr) \ | ||
137 | : "d" (__val), "a" (__addr), \ | ||
138 | "m" (*(unsigned long *) __addr) : "cc"); | ||
139 | |||
140 | |||
141 | #endif /* __GNUC__ */ | ||
142 | |||
143 | #endif /* __s390x__ */ | ||
144 | |||
145 | #define __BITOPS_WORDS(bits) (((bits)+__BITOPS_WORDSIZE-1)/__BITOPS_WORDSIZE) | ||
146 | #define __BITOPS_BARRIER() asm volatile("" : : : "memory") | ||
147 | |||
148 | #ifdef CONFIG_SMP | ||
149 | /* | ||
150 | * SMP safe set_bit routine based on compare and swap (CS) | ||
151 | */ | ||
152 | static inline void set_bit_cs(unsigned long nr, volatile unsigned long *ptr) | ||
153 | { | ||
154 | unsigned long addr, old, new, mask; | ||
155 | |||
156 | addr = (unsigned long) ptr; | ||
157 | /* calculate address for CS */ | ||
158 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | ||
159 | /* make OR mask */ | ||
160 | mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); | ||
161 | /* Do the atomic update. */ | ||
162 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR); | ||
163 | } | ||
164 | |||
165 | /* | ||
166 | * SMP safe clear_bit routine based on compare and swap (CS) | ||
167 | */ | ||
168 | static inline void clear_bit_cs(unsigned long nr, volatile unsigned long *ptr) | ||
169 | { | ||
170 | unsigned long addr, old, new, mask; | ||
171 | |||
172 | addr = (unsigned long) ptr; | ||
173 | /* calculate address for CS */ | ||
174 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | ||
175 | /* make AND mask */ | ||
176 | mask = ~(1UL << (nr & (__BITOPS_WORDSIZE - 1))); | ||
177 | /* Do the atomic update. */ | ||
178 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND); | ||
179 | } | ||
180 | |||
181 | /* | ||
182 | * SMP safe change_bit routine based on compare and swap (CS) | ||
183 | */ | ||
184 | static inline void change_bit_cs(unsigned long nr, volatile unsigned long *ptr) | ||
185 | { | ||
186 | unsigned long addr, old, new, mask; | ||
187 | |||
188 | addr = (unsigned long) ptr; | ||
189 | /* calculate address for CS */ | ||
190 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | ||
191 | /* make XOR mask */ | ||
192 | mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); | ||
193 | /* Do the atomic update. */ | ||
194 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR); | ||
195 | } | ||
196 | |||
197 | /* | ||
198 | * SMP safe test_and_set_bit routine based on compare and swap (CS) | ||
199 | */ | ||
200 | static inline int | ||
201 | test_and_set_bit_cs(unsigned long nr, volatile unsigned long *ptr) | ||
202 | { | ||
203 | unsigned long addr, old, new, mask; | ||
204 | |||
205 | addr = (unsigned long) ptr; | ||
206 | /* calculate address for CS */ | ||
207 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | ||
208 | /* make OR/test mask */ | ||
209 | mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); | ||
210 | /* Do the atomic update. */ | ||
211 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR); | ||
212 | __BITOPS_BARRIER(); | ||
213 | return (old & mask) != 0; | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * SMP safe test_and_clear_bit routine based on compare and swap (CS) | ||
218 | */ | ||
219 | static inline int | ||
220 | test_and_clear_bit_cs(unsigned long nr, volatile unsigned long *ptr) | ||
221 | { | ||
222 | unsigned long addr, old, new, mask; | ||
223 | |||
224 | addr = (unsigned long) ptr; | ||
225 | /* calculate address for CS */ | ||
226 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | ||
227 | /* make AND/test mask */ | ||
228 | mask = ~(1UL << (nr & (__BITOPS_WORDSIZE - 1))); | ||
229 | /* Do the atomic update. */ | ||
230 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND); | ||
231 | __BITOPS_BARRIER(); | ||
232 | return (old ^ new) != 0; | ||
233 | } | ||
234 | |||
235 | /* | ||
236 | * SMP safe test_and_change_bit routine based on compare and swap (CS) | ||
237 | */ | ||
238 | static inline int | ||
239 | test_and_change_bit_cs(unsigned long nr, volatile unsigned long *ptr) | ||
240 | { | ||
241 | unsigned long addr, old, new, mask; | ||
242 | |||
243 | addr = (unsigned long) ptr; | ||
244 | /* calculate address for CS */ | ||
245 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | ||
246 | /* make XOR/test mask */ | ||
247 | mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); | ||
248 | /* Do the atomic update. */ | ||
249 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR); | ||
250 | __BITOPS_BARRIER(); | ||
251 | return (old & mask) != 0; | ||
252 | } | ||
253 | #endif /* CONFIG_SMP */ | ||
254 | |||
255 | /* | ||
256 | * fast, non-SMP set_bit routine | ||
257 | */ | ||
258 | static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr) | ||
259 | { | ||
260 | unsigned long addr; | ||
261 | |||
262 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
263 | asm volatile( | ||
264 | " oc 0(1,%1),0(%2)" | ||
265 | : "=m" (*(char *) addr) : "a" (addr), | ||
266 | "a" (_oi_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc" ); | ||
267 | } | ||
268 | |||
269 | static inline void | ||
270 | __constant_set_bit(const unsigned long nr, volatile unsigned long *ptr) | ||
271 | { | ||
272 | unsigned long addr; | ||
273 | |||
274 | addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
275 | *(unsigned char *) addr |= 1 << (nr & 7); | ||
276 | } | ||
277 | |||
278 | #define set_bit_simple(nr,addr) \ | ||
279 | (__builtin_constant_p((nr)) ? \ | ||
280 | __constant_set_bit((nr),(addr)) : \ | ||
281 | __set_bit((nr),(addr)) ) | ||
282 | |||
283 | /* | ||
284 | * fast, non-SMP clear_bit routine | ||
285 | */ | ||
286 | static inline void | ||
287 | __clear_bit(unsigned long nr, volatile unsigned long *ptr) | ||
288 | { | ||
289 | unsigned long addr; | ||
290 | |||
291 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
292 | asm volatile( | ||
293 | " nc 0(1,%1),0(%2)" | ||
294 | : "=m" (*(char *) addr) : "a" (addr), | ||
295 | "a" (_ni_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc"); | ||
296 | } | ||
297 | |||
298 | static inline void | ||
299 | __constant_clear_bit(const unsigned long nr, volatile unsigned long *ptr) | ||
300 | { | ||
301 | unsigned long addr; | ||
302 | |||
303 | addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
304 | *(unsigned char *) addr &= ~(1 << (nr & 7)); | ||
305 | } | ||
306 | |||
307 | #define clear_bit_simple(nr,addr) \ | ||
308 | (__builtin_constant_p((nr)) ? \ | ||
309 | __constant_clear_bit((nr),(addr)) : \ | ||
310 | __clear_bit((nr),(addr)) ) | ||
311 | |||
312 | /* | ||
313 | * fast, non-SMP change_bit routine | ||
314 | */ | ||
315 | static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr) | ||
316 | { | ||
317 | unsigned long addr; | ||
318 | |||
319 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
320 | asm volatile( | ||
321 | " xc 0(1,%1),0(%2)" | ||
322 | : "=m" (*(char *) addr) : "a" (addr), | ||
323 | "a" (_oi_bitmap + (nr & 7)), "m" (*(char *) addr) : "cc" ); | ||
324 | } | ||
325 | |||
326 | static inline void | ||
327 | __constant_change_bit(const unsigned long nr, volatile unsigned long *ptr) | ||
328 | { | ||
329 | unsigned long addr; | ||
330 | |||
331 | addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
332 | *(unsigned char *) addr ^= 1 << (nr & 7); | ||
333 | } | ||
334 | |||
335 | #define change_bit_simple(nr,addr) \ | ||
336 | (__builtin_constant_p((nr)) ? \ | ||
337 | __constant_change_bit((nr),(addr)) : \ | ||
338 | __change_bit((nr),(addr)) ) | ||
339 | |||
340 | /* | ||
341 | * fast, non-SMP test_and_set_bit routine | ||
342 | */ | ||
343 | static inline int | ||
344 | test_and_set_bit_simple(unsigned long nr, volatile unsigned long *ptr) | ||
345 | { | ||
346 | unsigned long addr; | ||
347 | unsigned char ch; | ||
348 | |||
349 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
350 | ch = *(unsigned char *) addr; | ||
351 | asm volatile( | ||
352 | " oc 0(1,%1),0(%2)" | ||
353 | : "=m" (*(char *) addr) | ||
354 | : "a" (addr), "a" (_oi_bitmap + (nr & 7)), | ||
355 | "m" (*(char *) addr) : "cc", "memory"); | ||
356 | return (ch >> (nr & 7)) & 1; | ||
357 | } | ||
358 | #define __test_and_set_bit(X,Y) test_and_set_bit_simple(X,Y) | ||
359 | |||
360 | /* | ||
361 | * fast, non-SMP test_and_clear_bit routine | ||
362 | */ | ||
363 | static inline int | ||
364 | test_and_clear_bit_simple(unsigned long nr, volatile unsigned long *ptr) | ||
365 | { | ||
366 | unsigned long addr; | ||
367 | unsigned char ch; | ||
368 | |||
369 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
370 | ch = *(unsigned char *) addr; | ||
371 | asm volatile( | ||
372 | " nc 0(1,%1),0(%2)" | ||
373 | : "=m" (*(char *) addr) | ||
374 | : "a" (addr), "a" (_ni_bitmap + (nr & 7)), | ||
375 | "m" (*(char *) addr) : "cc", "memory"); | ||
376 | return (ch >> (nr & 7)) & 1; | ||
377 | } | ||
378 | #define __test_and_clear_bit(X,Y) test_and_clear_bit_simple(X,Y) | ||
379 | |||
380 | /* | ||
381 | * fast, non-SMP test_and_change_bit routine | ||
382 | */ | ||
383 | static inline int | ||
384 | test_and_change_bit_simple(unsigned long nr, volatile unsigned long *ptr) | ||
385 | { | ||
386 | unsigned long addr; | ||
387 | unsigned char ch; | ||
388 | |||
389 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
390 | ch = *(unsigned char *) addr; | ||
391 | asm volatile( | ||
392 | " xc 0(1,%1),0(%2)" | ||
393 | : "=m" (*(char *) addr) | ||
394 | : "a" (addr), "a" (_oi_bitmap + (nr & 7)), | ||
395 | "m" (*(char *) addr) : "cc", "memory"); | ||
396 | return (ch >> (nr & 7)) & 1; | ||
397 | } | ||
398 | #define __test_and_change_bit(X,Y) test_and_change_bit_simple(X,Y) | ||
399 | |||
400 | #ifdef CONFIG_SMP | ||
401 | #define set_bit set_bit_cs | ||
402 | #define clear_bit clear_bit_cs | ||
403 | #define change_bit change_bit_cs | ||
404 | #define test_and_set_bit test_and_set_bit_cs | ||
405 | #define test_and_clear_bit test_and_clear_bit_cs | ||
406 | #define test_and_change_bit test_and_change_bit_cs | ||
407 | #else | ||
408 | #define set_bit set_bit_simple | ||
409 | #define clear_bit clear_bit_simple | ||
410 | #define change_bit change_bit_simple | ||
411 | #define test_and_set_bit test_and_set_bit_simple | ||
412 | #define test_and_clear_bit test_and_clear_bit_simple | ||
413 | #define test_and_change_bit test_and_change_bit_simple | ||
414 | #endif | ||
415 | |||
416 | |||
417 | /* | ||
418 | * This routine doesn't need to be atomic. | ||
419 | */ | ||
420 | |||
421 | static inline int __test_bit(unsigned long nr, const volatile unsigned long *ptr) | ||
422 | { | ||
423 | unsigned long addr; | ||
424 | unsigned char ch; | ||
425 | |||
426 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
427 | ch = *(volatile unsigned char *) addr; | ||
428 | return (ch >> (nr & 7)) & 1; | ||
429 | } | ||
430 | |||
431 | static inline int | ||
432 | __constant_test_bit(unsigned long nr, const volatile unsigned long *addr) { | ||
433 | return (((volatile char *) addr) | ||
434 | [(nr^(__BITOPS_WORDSIZE-8))>>3] & (1<<(nr&7))) != 0; | ||
435 | } | ||
436 | |||
437 | #define test_bit(nr,addr) \ | ||
438 | (__builtin_constant_p((nr)) ? \ | ||
439 | __constant_test_bit((nr),(addr)) : \ | ||
440 | __test_bit((nr),(addr)) ) | ||
441 | |||
442 | /* | ||
443 | * Optimized find bit helper functions. | ||
444 | */ | ||
445 | |||
446 | /** | ||
447 | * __ffz_word_loop - find byte offset of first long != -1UL | ||
448 | * @addr: pointer to array of unsigned long | ||
449 | * @size: size of the array in bits | ||
450 | */ | ||
451 | static inline unsigned long __ffz_word_loop(const unsigned long *addr, | ||
452 | unsigned long size) | ||
453 | { | ||
454 | typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; | ||
455 | unsigned long bytes = 0; | ||
456 | |||
457 | asm volatile( | ||
458 | #ifndef __s390x__ | ||
459 | " ahi %1,-1\n" | ||
460 | " sra %1,5\n" | ||
461 | " jz 1f\n" | ||
462 | "0: c %2,0(%0,%3)\n" | ||
463 | " jne 1f\n" | ||
464 | " la %0,4(%0)\n" | ||
465 | " brct %1,0b\n" | ||
466 | "1:\n" | ||
467 | #else | ||
468 | " aghi %1,-1\n" | ||
469 | " srag %1,%1,6\n" | ||
470 | " jz 1f\n" | ||
471 | "0: cg %2,0(%0,%3)\n" | ||
472 | " jne 1f\n" | ||
473 | " la %0,8(%0)\n" | ||
474 | " brct %1,0b\n" | ||
475 | "1:\n" | ||
476 | #endif | ||
477 | : "+&a" (bytes), "+&d" (size) | ||
478 | : "d" (-1UL), "a" (addr), "m" (*(addrtype *) addr) | ||
479 | : "cc" ); | ||
480 | return bytes; | ||
481 | } | ||
482 | |||
483 | /** | ||
484 | * __ffs_word_loop - find byte offset of first long != 0UL | ||
485 | * @addr: pointer to array of unsigned long | ||
486 | * @size: size of the array in bits | ||
487 | */ | ||
488 | static inline unsigned long __ffs_word_loop(const unsigned long *addr, | ||
489 | unsigned long size) | ||
490 | { | ||
491 | typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; | ||
492 | unsigned long bytes = 0; | ||
493 | |||
494 | asm volatile( | ||
495 | #ifndef __s390x__ | ||
496 | " ahi %1,-1\n" | ||
497 | " sra %1,5\n" | ||
498 | " jz 1f\n" | ||
499 | "0: c %2,0(%0,%3)\n" | ||
500 | " jne 1f\n" | ||
501 | " la %0,4(%0)\n" | ||
502 | " brct %1,0b\n" | ||
503 | "1:\n" | ||
504 | #else | ||
505 | " aghi %1,-1\n" | ||
506 | " srag %1,%1,6\n" | ||
507 | " jz 1f\n" | ||
508 | "0: cg %2,0(%0,%3)\n" | ||
509 | " jne 1f\n" | ||
510 | " la %0,8(%0)\n" | ||
511 | " brct %1,0b\n" | ||
512 | "1:\n" | ||
513 | #endif | ||
514 | : "+&a" (bytes), "+&a" (size) | ||
515 | : "d" (0UL), "a" (addr), "m" (*(addrtype *) addr) | ||
516 | : "cc" ); | ||
517 | return bytes; | ||
518 | } | ||
519 | |||
520 | /** | ||
521 | * __ffz_word - add number of the first unset bit | ||
522 | * @nr: base value the bit number is added to | ||
523 | * @word: the word that is searched for unset bits | ||
524 | */ | ||
525 | static inline unsigned long __ffz_word(unsigned long nr, unsigned long word) | ||
526 | { | ||
527 | #ifdef __s390x__ | ||
528 | if (likely((word & 0xffffffff) == 0xffffffff)) { | ||
529 | word >>= 32; | ||
530 | nr += 32; | ||
531 | } | ||
532 | #endif | ||
533 | if (likely((word & 0xffff) == 0xffff)) { | ||
534 | word >>= 16; | ||
535 | nr += 16; | ||
536 | } | ||
537 | if (likely((word & 0xff) == 0xff)) { | ||
538 | word >>= 8; | ||
539 | nr += 8; | ||
540 | } | ||
541 | return nr + _zb_findmap[(unsigned char) word]; | ||
542 | } | ||
543 | |||
544 | /** | ||
545 | * __ffs_word - add number of the first set bit | ||
546 | * @nr: base value the bit number is added to | ||
547 | * @word: the word that is searched for set bits | ||
548 | */ | ||
549 | static inline unsigned long __ffs_word(unsigned long nr, unsigned long word) | ||
550 | { | ||
551 | #ifdef __s390x__ | ||
552 | if (likely((word & 0xffffffff) == 0)) { | ||
553 | word >>= 32; | ||
554 | nr += 32; | ||
555 | } | ||
556 | #endif | ||
557 | if (likely((word & 0xffff) == 0)) { | ||
558 | word >>= 16; | ||
559 | nr += 16; | ||
560 | } | ||
561 | if (likely((word & 0xff) == 0)) { | ||
562 | word >>= 8; | ||
563 | nr += 8; | ||
564 | } | ||
565 | return nr + _sb_findmap[(unsigned char) word]; | ||
566 | } | ||
567 | |||
568 | |||
569 | /** | ||
570 | * __load_ulong_be - load big endian unsigned long | ||
571 | * @p: pointer to array of unsigned long | ||
572 | * @offset: byte offset of source value in the array | ||
573 | */ | ||
574 | static inline unsigned long __load_ulong_be(const unsigned long *p, | ||
575 | unsigned long offset) | ||
576 | { | ||
577 | p = (unsigned long *)((unsigned long) p + offset); | ||
578 | return *p; | ||
579 | } | ||
580 | |||
581 | /** | ||
582 | * __load_ulong_le - load little endian unsigned long | ||
583 | * @p: pointer to array of unsigned long | ||
584 | * @offset: byte offset of source value in the array | ||
585 | */ | ||
586 | static inline unsigned long __load_ulong_le(const unsigned long *p, | ||
587 | unsigned long offset) | ||
588 | { | ||
589 | unsigned long word; | ||
590 | |||
591 | p = (unsigned long *)((unsigned long) p + offset); | ||
592 | #ifndef __s390x__ | ||
593 | asm volatile( | ||
594 | " ic %0,0(%1)\n" | ||
595 | " icm %0,2,1(%1)\n" | ||
596 | " icm %0,4,2(%1)\n" | ||
597 | " icm %0,8,3(%1)" | ||
598 | : "=&d" (word) : "a" (p), "m" (*p) : "cc"); | ||
599 | #else | ||
600 | asm volatile( | ||
601 | " lrvg %0,%1" | ||
602 | : "=d" (word) : "m" (*p) ); | ||
603 | #endif | ||
604 | return word; | ||
605 | } | ||
606 | |||
607 | /* | ||
608 | * The various find bit functions. | ||
609 | */ | ||
610 | |||
611 | /* | ||
612 | * ffz - find first zero in word. | ||
613 | * @word: The word to search | ||
614 | * | ||
615 | * Undefined if no zero exists, so code should check against ~0UL first. | ||
616 | */ | ||
617 | static inline unsigned long ffz(unsigned long word) | ||
618 | { | ||
619 | return __ffz_word(0, word); | ||
620 | } | ||
621 | |||
622 | /** | ||
623 | * __ffs - find first bit in word. | ||
624 | * @word: The word to search | ||
625 | * | ||
626 | * Undefined if no bit exists, so code should check against 0 first. | ||
627 | */ | ||
628 | static inline unsigned long __ffs (unsigned long word) | ||
629 | { | ||
630 | return __ffs_word(0, word); | ||
631 | } | ||
632 | |||
633 | /** | ||
634 | * ffs - find first bit set | ||
635 | * @x: the word to search | ||
636 | * | ||
637 | * This is defined the same way as | ||
638 | * the libc and compiler builtin ffs routines, therefore | ||
639 | * differs in spirit from the above ffz (man ffs). | ||
640 | */ | ||
641 | static inline int ffs(int x) | ||
642 | { | ||
643 | if (!x) | ||
644 | return 0; | ||
645 | return __ffs_word(1, x); | ||
646 | } | ||
647 | |||
648 | /** | ||
649 | * find_first_zero_bit - find the first zero bit in a memory region | ||
650 | * @addr: The address to start the search at | ||
651 | * @size: The maximum size to search | ||
652 | * | ||
653 | * Returns the bit-number of the first zero bit, not the number of the byte | ||
654 | * containing a bit. | ||
655 | */ | ||
656 | static inline unsigned long find_first_zero_bit(const unsigned long *addr, | ||
657 | unsigned long size) | ||
658 | { | ||
659 | unsigned long bytes, bits; | ||
660 | |||
661 | if (!size) | ||
662 | return 0; | ||
663 | bytes = __ffz_word_loop(addr, size); | ||
664 | bits = __ffz_word(bytes*8, __load_ulong_be(addr, bytes)); | ||
665 | return (bits < size) ? bits : size; | ||
666 | } | ||
667 | |||
668 | /** | ||
669 | * find_first_bit - find the first set bit in a memory region | ||
670 | * @addr: The address to start the search at | ||
671 | * @size: The maximum size to search | ||
672 | * | ||
673 | * Returns the bit-number of the first set bit, not the number of the byte | ||
674 | * containing a bit. | ||
675 | */ | ||
676 | static inline unsigned long find_first_bit(const unsigned long * addr, | ||
677 | unsigned long size) | ||
678 | { | ||
679 | unsigned long bytes, bits; | ||
680 | |||
681 | if (!size) | ||
682 | return 0; | ||
683 | bytes = __ffs_word_loop(addr, size); | ||
684 | bits = __ffs_word(bytes*8, __load_ulong_be(addr, bytes)); | ||
685 | return (bits < size) ? bits : size; | ||
686 | } | ||
687 | |||
688 | /** | ||
689 | * find_next_zero_bit - find the first zero bit in a memory region | ||
690 | * @addr: The address to base the search on | ||
691 | * @offset: The bitnumber to start searching at | ||
692 | * @size: The maximum size to search | ||
693 | */ | ||
694 | static inline int find_next_zero_bit (const unsigned long * addr, | ||
695 | unsigned long size, | ||
696 | unsigned long offset) | ||
697 | { | ||
698 | const unsigned long *p; | ||
699 | unsigned long bit, set; | ||
700 | |||
701 | if (offset >= size) | ||
702 | return size; | ||
703 | bit = offset & (__BITOPS_WORDSIZE - 1); | ||
704 | offset -= bit; | ||
705 | size -= offset; | ||
706 | p = addr + offset / __BITOPS_WORDSIZE; | ||
707 | if (bit) { | ||
708 | /* | ||
709 | * __ffz_word returns __BITOPS_WORDSIZE | ||
710 | * if no zero bit is present in the word. | ||
711 | */ | ||
712 | set = __ffz_word(0, *p >> bit) + bit; | ||
713 | if (set >= size) | ||
714 | return size + offset; | ||
715 | if (set < __BITOPS_WORDSIZE) | ||
716 | return set + offset; | ||
717 | offset += __BITOPS_WORDSIZE; | ||
718 | size -= __BITOPS_WORDSIZE; | ||
719 | p++; | ||
720 | } | ||
721 | return offset + find_first_zero_bit(p, size); | ||
722 | } | ||
723 | |||
724 | /** | ||
725 | * find_next_bit - find the first set bit in a memory region | ||
726 | * @addr: The address to base the search on | ||
727 | * @offset: The bitnumber to start searching at | ||
728 | * @size: The maximum size to search | ||
729 | */ | ||
730 | static inline int find_next_bit (const unsigned long * addr, | ||
731 | unsigned long size, | ||
732 | unsigned long offset) | ||
733 | { | ||
734 | const unsigned long *p; | ||
735 | unsigned long bit, set; | ||
736 | |||
737 | if (offset >= size) | ||
738 | return size; | ||
739 | bit = offset & (__BITOPS_WORDSIZE - 1); | ||
740 | offset -= bit; | ||
741 | size -= offset; | ||
742 | p = addr + offset / __BITOPS_WORDSIZE; | ||
743 | if (bit) { | ||
744 | /* | ||
745 | * __ffs_word returns __BITOPS_WORDSIZE | ||
746 | * if no one bit is present in the word. | ||
747 | */ | ||
748 | set = __ffs_word(0, *p & (~0UL << bit)); | ||
749 | if (set >= size) | ||
750 | return size + offset; | ||
751 | if (set < __BITOPS_WORDSIZE) | ||
752 | return set + offset; | ||
753 | offset += __BITOPS_WORDSIZE; | ||
754 | size -= __BITOPS_WORDSIZE; | ||
755 | p++; | ||
756 | } | ||
757 | return offset + find_first_bit(p, size); | ||
758 | } | ||
759 | |||
760 | /* | ||
761 | * Every architecture must define this function. It's the fastest | ||
762 | * way of searching a 140-bit bitmap where the first 100 bits are | ||
763 | * unlikely to be set. It's guaranteed that at least one of the 140 | ||
764 | * bits is cleared. | ||
765 | */ | ||
766 | static inline int sched_find_first_bit(unsigned long *b) | ||
767 | { | ||
768 | return find_first_bit(b, 140); | ||
769 | } | ||
770 | |||
771 | #include <asm-generic/bitops/fls.h> | ||
772 | #include <asm-generic/bitops/__fls.h> | ||
773 | #include <asm-generic/bitops/fls64.h> | ||
774 | |||
775 | #include <asm-generic/bitops/hweight.h> | ||
776 | #include <asm-generic/bitops/lock.h> | ||
777 | |||
778 | /* | ||
779 | * ATTENTION: intel byte ordering convention for ext2 and minix !! | ||
780 | * bit 0 is the LSB of addr; bit 31 is the MSB of addr; | ||
781 | * bit 32 is the LSB of (addr+4). | ||
782 | * That combined with the little endian byte order of Intel gives the | ||
783 | * following bit order in memory: | ||
784 | * 07 06 05 04 03 02 01 00 15 14 13 12 11 10 09 08 \ | ||
785 | * 23 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24 | ||
786 | */ | ||
787 | |||
788 | #define ext2_set_bit(nr, addr) \ | ||
789 | __test_and_set_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) | ||
790 | #define ext2_set_bit_atomic(lock, nr, addr) \ | ||
791 | test_and_set_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) | ||
792 | #define ext2_clear_bit(nr, addr) \ | ||
793 | __test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) | ||
794 | #define ext2_clear_bit_atomic(lock, nr, addr) \ | ||
795 | test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) | ||
796 | #define ext2_test_bit(nr, addr) \ | ||
797 | test_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) | ||
798 | |||
799 | static inline int ext2_find_first_zero_bit(void *vaddr, unsigned int size) | ||
800 | { | ||
801 | unsigned long bytes, bits; | ||
802 | |||
803 | if (!size) | ||
804 | return 0; | ||
805 | bytes = __ffz_word_loop(vaddr, size); | ||
806 | bits = __ffz_word(bytes*8, __load_ulong_le(vaddr, bytes)); | ||
807 | return (bits < size) ? bits : size; | ||
808 | } | ||
809 | |||
810 | static inline int ext2_find_next_zero_bit(void *vaddr, unsigned long size, | ||
811 | unsigned long offset) | ||
812 | { | ||
813 | unsigned long *addr = vaddr, *p; | ||
814 | unsigned long bit, set; | ||
815 | |||
816 | if (offset >= size) | ||
817 | return size; | ||
818 | bit = offset & (__BITOPS_WORDSIZE - 1); | ||
819 | offset -= bit; | ||
820 | size -= offset; | ||
821 | p = addr + offset / __BITOPS_WORDSIZE; | ||
822 | if (bit) { | ||
823 | /* | ||
824 | * s390 version of ffz returns __BITOPS_WORDSIZE | ||
825 | * if no zero bit is present in the word. | ||
826 | */ | ||
827 | set = ffz(__load_ulong_le(p, 0) >> bit) + bit; | ||
828 | if (set >= size) | ||
829 | return size + offset; | ||
830 | if (set < __BITOPS_WORDSIZE) | ||
831 | return set + offset; | ||
832 | offset += __BITOPS_WORDSIZE; | ||
833 | size -= __BITOPS_WORDSIZE; | ||
834 | p++; | ||
835 | } | ||
836 | return offset + ext2_find_first_zero_bit(p, size); | ||
837 | } | ||
838 | |||
839 | static inline unsigned long ext2_find_first_bit(void *vaddr, | ||
840 | unsigned long size) | ||
841 | { | ||
842 | unsigned long bytes, bits; | ||
843 | |||
844 | if (!size) | ||
845 | return 0; | ||
846 | bytes = __ffs_word_loop(vaddr, size); | ||
847 | bits = __ffs_word(bytes*8, __load_ulong_le(vaddr, bytes)); | ||
848 | return (bits < size) ? bits : size; | ||
849 | } | ||
850 | |||
851 | static inline int ext2_find_next_bit(void *vaddr, unsigned long size, | ||
852 | unsigned long offset) | ||
853 | { | ||
854 | unsigned long *addr = vaddr, *p; | ||
855 | unsigned long bit, set; | ||
856 | |||
857 | if (offset >= size) | ||
858 | return size; | ||
859 | bit = offset & (__BITOPS_WORDSIZE - 1); | ||
860 | offset -= bit; | ||
861 | size -= offset; | ||
862 | p = addr + offset / __BITOPS_WORDSIZE; | ||
863 | if (bit) { | ||
864 | /* | ||
865 | * s390 version of ffz returns __BITOPS_WORDSIZE | ||
866 | * if no zero bit is present in the word. | ||
867 | */ | ||
868 | set = ffs(__load_ulong_le(p, 0) >> bit) + bit; | ||
869 | if (set >= size) | ||
870 | return size + offset; | ||
871 | if (set < __BITOPS_WORDSIZE) | ||
872 | return set + offset; | ||
873 | offset += __BITOPS_WORDSIZE; | ||
874 | size -= __BITOPS_WORDSIZE; | ||
875 | p++; | ||
876 | } | ||
877 | return offset + ext2_find_first_bit(p, size); | ||
878 | } | ||
879 | |||
880 | #include <asm-generic/bitops/minix.h> | ||
881 | |||
882 | #endif /* __KERNEL__ */ | ||
883 | |||
884 | #endif /* _S390_BITOPS_H */ | ||
diff --git a/arch/s390/include/asm/bug.h b/arch/s390/include/asm/bug.h new file mode 100644 index 000000000000..384e3621e341 --- /dev/null +++ b/arch/s390/include/asm/bug.h | |||
@@ -0,0 +1,70 @@ | |||
1 | #ifndef _ASM_S390_BUG_H | ||
2 | #define _ASM_S390_BUG_H | ||
3 | |||
4 | #include <linux/kernel.h> | ||
5 | |||
6 | #ifdef CONFIG_BUG | ||
7 | |||
8 | #ifdef CONFIG_64BIT | ||
9 | #define S390_LONG ".quad" | ||
10 | #else | ||
11 | #define S390_LONG ".long" | ||
12 | #endif | ||
13 | |||
14 | #ifdef CONFIG_DEBUG_BUGVERBOSE | ||
15 | |||
16 | #define __EMIT_BUG(x) do { \ | ||
17 | asm volatile( \ | ||
18 | "0: j 0b+2\n" \ | ||
19 | "1:\n" \ | ||
20 | ".section .rodata.str,\"aMS\",@progbits,1\n" \ | ||
21 | "2: .asciz \""__FILE__"\"\n" \ | ||
22 | ".previous\n" \ | ||
23 | ".section __bug_table,\"a\"\n" \ | ||
24 | "3:\t" S390_LONG "\t1b,2b\n" \ | ||
25 | " .short %0,%1\n" \ | ||
26 | " .org 3b+%2\n" \ | ||
27 | ".previous\n" \ | ||
28 | : : "i" (__LINE__), \ | ||
29 | "i" (x), \ | ||
30 | "i" (sizeof(struct bug_entry))); \ | ||
31 | } while (0) | ||
32 | |||
33 | #else /* CONFIG_DEBUG_BUGVERBOSE */ | ||
34 | |||
35 | #define __EMIT_BUG(x) do { \ | ||
36 | asm volatile( \ | ||
37 | "0: j 0b+2\n" \ | ||
38 | "1:\n" \ | ||
39 | ".section __bug_table,\"a\"\n" \ | ||
40 | "2:\t" S390_LONG "\t1b\n" \ | ||
41 | " .short %0\n" \ | ||
42 | " .org 2b+%1\n" \ | ||
43 | ".previous\n" \ | ||
44 | : : "i" (x), \ | ||
45 | "i" (sizeof(struct bug_entry))); \ | ||
46 | } while (0) | ||
47 | |||
48 | #endif /* CONFIG_DEBUG_BUGVERBOSE */ | ||
49 | |||
50 | #define BUG() __EMIT_BUG(0) | ||
51 | |||
52 | #define WARN_ON(x) ({ \ | ||
53 | int __ret_warn_on = !!(x); \ | ||
54 | if (__builtin_constant_p(__ret_warn_on)) { \ | ||
55 | if (__ret_warn_on) \ | ||
56 | __EMIT_BUG(BUGFLAG_WARNING); \ | ||
57 | } else { \ | ||
58 | if (unlikely(__ret_warn_on)) \ | ||
59 | __EMIT_BUG(BUGFLAG_WARNING); \ | ||
60 | } \ | ||
61 | unlikely(__ret_warn_on); \ | ||
62 | }) | ||
63 | |||
64 | #define HAVE_ARCH_BUG | ||
65 | #define HAVE_ARCH_WARN_ON | ||
66 | #endif /* CONFIG_BUG */ | ||
67 | |||
68 | #include <asm-generic/bug.h> | ||
69 | |||
70 | #endif /* _ASM_S390_BUG_H */ | ||
diff --git a/arch/s390/include/asm/bugs.h b/arch/s390/include/asm/bugs.h new file mode 100644 index 000000000000..011f1e6a2a6c --- /dev/null +++ b/arch/s390/include/asm/bugs.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * include/asm-s390/bugs.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
7 | * | ||
8 | * Derived from "include/asm-i386/bugs.h" | ||
9 | * Copyright (C) 1994 Linus Torvalds | ||
10 | */ | ||
11 | |||
12 | /* | ||
13 | * This is included by init/main.c to check for architecture-dependent bugs. | ||
14 | * | ||
15 | * Needs: | ||
16 | * void check_bugs(void); | ||
17 | */ | ||
18 | |||
19 | static inline void check_bugs(void) | ||
20 | { | ||
21 | /* s390 has no bugs ... */ | ||
22 | } | ||
diff --git a/arch/s390/include/asm/byteorder.h b/arch/s390/include/asm/byteorder.h new file mode 100644 index 000000000000..1fe2492baa8d --- /dev/null +++ b/arch/s390/include/asm/byteorder.h | |||
@@ -0,0 +1,125 @@ | |||
1 | #ifndef _S390_BYTEORDER_H | ||
2 | #define _S390_BYTEORDER_H | ||
3 | |||
4 | /* | ||
5 | * include/asm-s390/byteorder.h | ||
6 | * | ||
7 | * S390 version | ||
8 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
9 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
10 | */ | ||
11 | |||
12 | #include <asm/types.h> | ||
13 | |||
14 | #ifdef __GNUC__ | ||
15 | |||
16 | #ifdef __s390x__ | ||
17 | static inline __u64 ___arch__swab64p(const __u64 *x) | ||
18 | { | ||
19 | __u64 result; | ||
20 | |||
21 | asm volatile("lrvg %0,%1" : "=d" (result) : "m" (*x)); | ||
22 | return result; | ||
23 | } | ||
24 | |||
25 | static inline __u64 ___arch__swab64(__u64 x) | ||
26 | { | ||
27 | __u64 result; | ||
28 | |||
29 | asm volatile("lrvgr %0,%1" : "=d" (result) : "d" (x)); | ||
30 | return result; | ||
31 | } | ||
32 | |||
33 | static inline void ___arch__swab64s(__u64 *x) | ||
34 | { | ||
35 | *x = ___arch__swab64p(x); | ||
36 | } | ||
37 | #endif /* __s390x__ */ | ||
38 | |||
39 | static inline __u32 ___arch__swab32p(const __u32 *x) | ||
40 | { | ||
41 | __u32 result; | ||
42 | |||
43 | asm volatile( | ||
44 | #ifndef __s390x__ | ||
45 | " icm %0,8,3(%1)\n" | ||
46 | " icm %0,4,2(%1)\n" | ||
47 | " icm %0,2,1(%1)\n" | ||
48 | " ic %0,0(%1)" | ||
49 | : "=&d" (result) : "a" (x), "m" (*x) : "cc"); | ||
50 | #else /* __s390x__ */ | ||
51 | " lrv %0,%1" | ||
52 | : "=d" (result) : "m" (*x)); | ||
53 | #endif /* __s390x__ */ | ||
54 | return result; | ||
55 | } | ||
56 | |||
57 | static inline __u32 ___arch__swab32(__u32 x) | ||
58 | { | ||
59 | #ifndef __s390x__ | ||
60 | return ___arch__swab32p(&x); | ||
61 | #else /* __s390x__ */ | ||
62 | __u32 result; | ||
63 | |||
64 | asm volatile("lrvr %0,%1" : "=d" (result) : "d" (x)); | ||
65 | return result; | ||
66 | #endif /* __s390x__ */ | ||
67 | } | ||
68 | |||
69 | static __inline__ void ___arch__swab32s(__u32 *x) | ||
70 | { | ||
71 | *x = ___arch__swab32p(x); | ||
72 | } | ||
73 | |||
74 | static __inline__ __u16 ___arch__swab16p(const __u16 *x) | ||
75 | { | ||
76 | __u16 result; | ||
77 | |||
78 | asm volatile( | ||
79 | #ifndef __s390x__ | ||
80 | " icm %0,2,1(%1)\n" | ||
81 | " ic %0,0(%1)\n" | ||
82 | : "=&d" (result) : "a" (x), "m" (*x) : "cc"); | ||
83 | #else /* __s390x__ */ | ||
84 | " lrvh %0,%1" | ||
85 | : "=d" (result) : "m" (*x)); | ||
86 | #endif /* __s390x__ */ | ||
87 | return result; | ||
88 | } | ||
89 | |||
90 | static __inline__ __u16 ___arch__swab16(__u16 x) | ||
91 | { | ||
92 | return ___arch__swab16p(&x); | ||
93 | } | ||
94 | |||
95 | static __inline__ void ___arch__swab16s(__u16 *x) | ||
96 | { | ||
97 | *x = ___arch__swab16p(x); | ||
98 | } | ||
99 | |||
100 | #ifdef __s390x__ | ||
101 | #define __arch__swab64(x) ___arch__swab64(x) | ||
102 | #define __arch__swab64p(x) ___arch__swab64p(x) | ||
103 | #define __arch__swab64s(x) ___arch__swab64s(x) | ||
104 | #endif /* __s390x__ */ | ||
105 | #define __arch__swab32(x) ___arch__swab32(x) | ||
106 | #define __arch__swab16(x) ___arch__swab16(x) | ||
107 | #define __arch__swab32p(x) ___arch__swab32p(x) | ||
108 | #define __arch__swab16p(x) ___arch__swab16p(x) | ||
109 | #define __arch__swab32s(x) ___arch__swab32s(x) | ||
110 | #define __arch__swab16s(x) ___arch__swab16s(x) | ||
111 | |||
112 | #ifndef __s390x__ | ||
113 | #if !defined(__STRICT_ANSI__) || defined(__KERNEL__) | ||
114 | # define __BYTEORDER_HAS_U64__ | ||
115 | # define __SWAB_64_THRU_32__ | ||
116 | #endif | ||
117 | #else /* __s390x__ */ | ||
118 | #define __BYTEORDER_HAS_U64__ | ||
119 | #endif /* __s390x__ */ | ||
120 | |||
121 | #endif /* __GNUC__ */ | ||
122 | |||
123 | #include <linux/byteorder/big_endian.h> | ||
124 | |||
125 | #endif /* _S390_BYTEORDER_H */ | ||
diff --git a/arch/s390/include/asm/cache.h b/arch/s390/include/asm/cache.h new file mode 100644 index 000000000000..9b866816863c --- /dev/null +++ b/arch/s390/include/asm/cache.h | |||
@@ -0,0 +1,19 @@ | |||
1 | /* | ||
2 | * include/asm-s390/cache.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * | ||
7 | * Derived from "include/asm-i386/cache.h" | ||
8 | * Copyright (C) 1992, Linus Torvalds | ||
9 | */ | ||
10 | |||
11 | #ifndef __ARCH_S390_CACHE_H | ||
12 | #define __ARCH_S390_CACHE_H | ||
13 | |||
14 | #define L1_CACHE_BYTES 256 | ||
15 | #define L1_CACHE_SHIFT 8 | ||
16 | |||
17 | #define __read_mostly __attribute__((__section__(".data.read_mostly"))) | ||
18 | |||
19 | #endif | ||
diff --git a/arch/s390/include/asm/cacheflush.h b/arch/s390/include/asm/cacheflush.h new file mode 100644 index 000000000000..49d5af916d01 --- /dev/null +++ b/arch/s390/include/asm/cacheflush.h | |||
@@ -0,0 +1,31 @@ | |||
1 | #ifndef _S390_CACHEFLUSH_H | ||
2 | #define _S390_CACHEFLUSH_H | ||
3 | |||
4 | /* Keep includes the same across arches. */ | ||
5 | #include <linux/mm.h> | ||
6 | |||
7 | /* Caches aren't brain-dead on the s390. */ | ||
8 | #define flush_cache_all() do { } while (0) | ||
9 | #define flush_cache_mm(mm) do { } while (0) | ||
10 | #define flush_cache_dup_mm(mm) do { } while (0) | ||
11 | #define flush_cache_range(vma, start, end) do { } while (0) | ||
12 | #define flush_cache_page(vma, vmaddr, pfn) do { } while (0) | ||
13 | #define flush_dcache_page(page) do { } while (0) | ||
14 | #define flush_dcache_mmap_lock(mapping) do { } while (0) | ||
15 | #define flush_dcache_mmap_unlock(mapping) do { } while (0) | ||
16 | #define flush_icache_range(start, end) do { } while (0) | ||
17 | #define flush_icache_page(vma,pg) do { } while (0) | ||
18 | #define flush_icache_user_range(vma,pg,adr,len) do { } while (0) | ||
19 | #define flush_cache_vmap(start, end) do { } while (0) | ||
20 | #define flush_cache_vunmap(start, end) do { } while (0) | ||
21 | |||
22 | #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ | ||
23 | memcpy(dst, src, len) | ||
24 | #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ | ||
25 | memcpy(dst, src, len) | ||
26 | |||
27 | #ifdef CONFIG_DEBUG_PAGEALLOC | ||
28 | void kernel_map_pages(struct page *page, int numpages, int enable); | ||
29 | #endif | ||
30 | |||
31 | #endif /* _S390_CACHEFLUSH_H */ | ||
diff --git a/arch/s390/include/asm/ccwdev.h b/arch/s390/include/asm/ccwdev.h new file mode 100644 index 000000000000..ba007d8df941 --- /dev/null +++ b/arch/s390/include/asm/ccwdev.h | |||
@@ -0,0 +1,192 @@ | |||
1 | /* | ||
2 | * include/asm-s390/ccwdev.h | ||
3 | * include/asm-s390x/ccwdev.h | ||
4 | * | ||
5 | * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Arnd Bergmann <arndb@de.ibm.com> | ||
7 | * | ||
8 | * Interface for CCW device drivers | ||
9 | */ | ||
10 | #ifndef _S390_CCWDEV_H_ | ||
11 | #define _S390_CCWDEV_H_ | ||
12 | |||
13 | #include <linux/device.h> | ||
14 | #include <linux/mod_devicetable.h> | ||
15 | #include <asm/fcx.h> | ||
16 | |||
17 | /* structs from asm/cio.h */ | ||
18 | struct irb; | ||
19 | struct ccw1; | ||
20 | struct ccw_dev_id; | ||
21 | |||
22 | /* simplified initializers for struct ccw_device: | ||
23 | * CCW_DEVICE and CCW_DEVICE_DEVTYPE initialize one | ||
24 | * entry in your MODULE_DEVICE_TABLE and set the match_flag correctly */ | ||
25 | #define CCW_DEVICE(cu, cum) \ | ||
26 | .cu_type=(cu), .cu_model=(cum), \ | ||
27 | .match_flags=(CCW_DEVICE_ID_MATCH_CU_TYPE \ | ||
28 | | (cum ? CCW_DEVICE_ID_MATCH_CU_MODEL : 0)) | ||
29 | |||
30 | #define CCW_DEVICE_DEVTYPE(cu, cum, dev, devm) \ | ||
31 | .cu_type=(cu), .cu_model=(cum), .dev_type=(dev), .dev_model=(devm),\ | ||
32 | .match_flags=CCW_DEVICE_ID_MATCH_CU_TYPE \ | ||
33 | | ((cum) ? CCW_DEVICE_ID_MATCH_CU_MODEL : 0) \ | ||
34 | | CCW_DEVICE_ID_MATCH_DEVICE_TYPE \ | ||
35 | | ((devm) ? CCW_DEVICE_ID_MATCH_DEVICE_MODEL : 0) | ||
36 | |||
37 | /* scan through an array of device ids and return the first | ||
38 | * entry that matches the device. | ||
39 | * | ||
40 | * the array must end with an entry containing zero match_flags | ||
41 | */ | ||
42 | static inline const struct ccw_device_id * | ||
43 | ccw_device_id_match(const struct ccw_device_id *array, | ||
44 | const struct ccw_device_id *match) | ||
45 | { | ||
46 | const struct ccw_device_id *id = array; | ||
47 | |||
48 | for (id = array; id->match_flags; id++) { | ||
49 | if ((id->match_flags & CCW_DEVICE_ID_MATCH_CU_TYPE) | ||
50 | && (id->cu_type != match->cu_type)) | ||
51 | continue; | ||
52 | |||
53 | if ((id->match_flags & CCW_DEVICE_ID_MATCH_CU_MODEL) | ||
54 | && (id->cu_model != match->cu_model)) | ||
55 | continue; | ||
56 | |||
57 | if ((id->match_flags & CCW_DEVICE_ID_MATCH_DEVICE_TYPE) | ||
58 | && (id->dev_type != match->dev_type)) | ||
59 | continue; | ||
60 | |||
61 | if ((id->match_flags & CCW_DEVICE_ID_MATCH_DEVICE_MODEL) | ||
62 | && (id->dev_model != match->dev_model)) | ||
63 | continue; | ||
64 | |||
65 | return id; | ||
66 | } | ||
67 | |||
68 | return NULL; | ||
69 | } | ||
70 | |||
71 | /** | ||
72 | * struct ccw_device - channel attached device | ||
73 | * @ccwlock: pointer to device lock | ||
74 | * @id: id of this device | ||
75 | * @drv: ccw driver for this device | ||
76 | * @dev: embedded device structure | ||
77 | * @online: online status of device | ||
78 | * @handler: interrupt handler | ||
79 | * | ||
80 | * @handler is a member of the device rather than the driver since a driver | ||
81 | * can have different interrupt handlers for different ccw devices | ||
82 | * (multi-subchannel drivers). | ||
83 | */ | ||
84 | struct ccw_device { | ||
85 | spinlock_t *ccwlock; | ||
86 | /* private: */ | ||
87 | struct ccw_device_private *private; /* cio private information */ | ||
88 | /* public: */ | ||
89 | struct ccw_device_id id; | ||
90 | struct ccw_driver *drv; | ||
91 | struct device dev; | ||
92 | int online; | ||
93 | void (*handler) (struct ccw_device *, unsigned long, struct irb *); | ||
94 | }; | ||
95 | |||
96 | |||
97 | /** | ||
98 | * struct ccw driver - device driver for channel attached devices | ||
99 | * @owner: owning module | ||
100 | * @ids: ids supported by this driver | ||
101 | * @probe: function called on probe | ||
102 | * @remove: function called on remove | ||
103 | * @set_online: called when setting device online | ||
104 | * @set_offline: called when setting device offline | ||
105 | * @notify: notify driver of device state changes | ||
106 | * @shutdown: called at device shutdown | ||
107 | * @driver: embedded device driver structure | ||
108 | * @name: device driver name | ||
109 | */ | ||
110 | struct ccw_driver { | ||
111 | struct module *owner; | ||
112 | struct ccw_device_id *ids; | ||
113 | int (*probe) (struct ccw_device *); | ||
114 | void (*remove) (struct ccw_device *); | ||
115 | int (*set_online) (struct ccw_device *); | ||
116 | int (*set_offline) (struct ccw_device *); | ||
117 | int (*notify) (struct ccw_device *, int); | ||
118 | void (*shutdown) (struct ccw_device *); | ||
119 | struct device_driver driver; | ||
120 | char *name; | ||
121 | }; | ||
122 | |||
123 | extern struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv, | ||
124 | const char *bus_id); | ||
125 | |||
126 | /* devices drivers call these during module load and unload. | ||
127 | * When a driver is registered, its probe method is called | ||
128 | * when new devices for its type pop up */ | ||
129 | extern int ccw_driver_register (struct ccw_driver *driver); | ||
130 | extern void ccw_driver_unregister (struct ccw_driver *driver); | ||
131 | |||
132 | struct ccw1; | ||
133 | |||
134 | extern int ccw_device_set_options_mask(struct ccw_device *, unsigned long); | ||
135 | extern int ccw_device_set_options(struct ccw_device *, unsigned long); | ||
136 | extern void ccw_device_clear_options(struct ccw_device *, unsigned long); | ||
137 | |||
138 | /* Allow for i/o completion notification after primary interrupt status. */ | ||
139 | #define CCWDEV_EARLY_NOTIFICATION 0x0001 | ||
140 | /* Report all interrupt conditions. */ | ||
141 | #define CCWDEV_REPORT_ALL 0x0002 | ||
142 | /* Try to perform path grouping. */ | ||
143 | #define CCWDEV_DO_PATHGROUP 0x0004 | ||
144 | /* Allow forced onlining of boxed devices. */ | ||
145 | #define CCWDEV_ALLOW_FORCE 0x0008 | ||
146 | |||
147 | extern int ccw_device_start(struct ccw_device *, struct ccw1 *, | ||
148 | unsigned long, __u8, unsigned long); | ||
149 | extern int ccw_device_start_timeout(struct ccw_device *, struct ccw1 *, | ||
150 | unsigned long, __u8, unsigned long, int); | ||
151 | extern int ccw_device_start_key(struct ccw_device *, struct ccw1 *, | ||
152 | unsigned long, __u8, __u8, unsigned long); | ||
153 | extern int ccw_device_start_timeout_key(struct ccw_device *, struct ccw1 *, | ||
154 | unsigned long, __u8, __u8, | ||
155 | unsigned long, int); | ||
156 | |||
157 | |||
158 | extern int ccw_device_resume(struct ccw_device *); | ||
159 | extern int ccw_device_halt(struct ccw_device *, unsigned long); | ||
160 | extern int ccw_device_clear(struct ccw_device *, unsigned long); | ||
161 | int ccw_device_tm_start_key(struct ccw_device *cdev, struct tcw *tcw, | ||
162 | unsigned long intparm, u8 lpm, u8 key); | ||
163 | int ccw_device_tm_start_key(struct ccw_device *, struct tcw *, | ||
164 | unsigned long, u8, u8); | ||
165 | int ccw_device_tm_start_timeout_key(struct ccw_device *, struct tcw *, | ||
166 | unsigned long, u8, u8, int); | ||
167 | int ccw_device_tm_start(struct ccw_device *, struct tcw *, | ||
168 | unsigned long, u8); | ||
169 | int ccw_device_tm_start_timeout(struct ccw_device *, struct tcw *, | ||
170 | unsigned long, u8, int); | ||
171 | int ccw_device_tm_intrg(struct ccw_device *cdev); | ||
172 | |||
173 | extern int ccw_device_set_online(struct ccw_device *cdev); | ||
174 | extern int ccw_device_set_offline(struct ccw_device *cdev); | ||
175 | |||
176 | |||
177 | extern struct ciw *ccw_device_get_ciw(struct ccw_device *, __u32 cmd); | ||
178 | extern __u8 ccw_device_get_path_mask(struct ccw_device *); | ||
179 | extern void ccw_device_get_id(struct ccw_device *, struct ccw_dev_id *); | ||
180 | |||
181 | #define get_ccwdev_lock(x) (x)->ccwlock | ||
182 | |||
183 | #define to_ccwdev(n) container_of(n, struct ccw_device, dev) | ||
184 | #define to_ccwdrv(n) container_of(n, struct ccw_driver, driver) | ||
185 | |||
186 | extern struct ccw_device *ccw_device_probe_console(void); | ||
187 | |||
188 | // FIXME: these have to go | ||
189 | extern int _ccw_device_get_subchannel_number(struct ccw_device *); | ||
190 | |||
191 | extern void *ccw_device_get_chp_desc(struct ccw_device *, int); | ||
192 | #endif /* _S390_CCWDEV_H_ */ | ||
diff --git a/arch/s390/include/asm/ccwgroup.h b/arch/s390/include/asm/ccwgroup.h new file mode 100644 index 000000000000..a27f68985a79 --- /dev/null +++ b/arch/s390/include/asm/ccwgroup.h | |||
@@ -0,0 +1,69 @@ | |||
1 | #ifndef S390_CCWGROUP_H | ||
2 | #define S390_CCWGROUP_H | ||
3 | |||
4 | struct ccw_device; | ||
5 | struct ccw_driver; | ||
6 | |||
7 | /** | ||
8 | * struct ccwgroup_device - ccw group device | ||
9 | * @creator_id: unique number of the driver | ||
10 | * @state: online/offline state | ||
11 | * @count: number of attached slave devices | ||
12 | * @dev: embedded device structure | ||
13 | * @cdev: variable number of slave devices, allocated as needed | ||
14 | */ | ||
15 | struct ccwgroup_device { | ||
16 | unsigned long creator_id; | ||
17 | enum { | ||
18 | CCWGROUP_OFFLINE, | ||
19 | CCWGROUP_ONLINE, | ||
20 | } state; | ||
21 | /* private: */ | ||
22 | atomic_t onoff; | ||
23 | struct mutex reg_mutex; | ||
24 | /* public: */ | ||
25 | unsigned int count; | ||
26 | struct device dev; | ||
27 | struct ccw_device *cdev[0]; | ||
28 | }; | ||
29 | |||
30 | /** | ||
31 | * struct ccwgroup_driver - driver for ccw group devices | ||
32 | * @owner: driver owner | ||
33 | * @name: driver name | ||
34 | * @max_slaves: maximum number of slave devices | ||
35 | * @driver_id: unique id | ||
36 | * @probe: function called on probe | ||
37 | * @remove: function called on remove | ||
38 | * @set_online: function called when device is set online | ||
39 | * @set_offline: function called when device is set offline | ||
40 | * @shutdown: function called when device is shut down | ||
41 | * @driver: embedded driver structure | ||
42 | */ | ||
43 | struct ccwgroup_driver { | ||
44 | struct module *owner; | ||
45 | char *name; | ||
46 | int max_slaves; | ||
47 | unsigned long driver_id; | ||
48 | |||
49 | int (*probe) (struct ccwgroup_device *); | ||
50 | void (*remove) (struct ccwgroup_device *); | ||
51 | int (*set_online) (struct ccwgroup_device *); | ||
52 | int (*set_offline) (struct ccwgroup_device *); | ||
53 | void (*shutdown)(struct ccwgroup_device *); | ||
54 | |||
55 | struct device_driver driver; | ||
56 | }; | ||
57 | |||
58 | extern int ccwgroup_driver_register (struct ccwgroup_driver *cdriver); | ||
59 | extern void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver); | ||
60 | int ccwgroup_create_from_string(struct device *root, unsigned int creator_id, | ||
61 | struct ccw_driver *cdrv, int num_devices, | ||
62 | const char *buf); | ||
63 | |||
64 | extern int ccwgroup_probe_ccwdev(struct ccw_device *cdev); | ||
65 | extern void ccwgroup_remove_ccwdev(struct ccw_device *cdev); | ||
66 | |||
67 | #define to_ccwgroupdev(x) container_of((x), struct ccwgroup_device, dev) | ||
68 | #define to_ccwgroupdrv(x) container_of((x), struct ccwgroup_driver, driver) | ||
69 | #endif | ||
diff --git a/arch/s390/include/asm/checksum.h b/arch/s390/include/asm/checksum.h new file mode 100644 index 000000000000..d5a8e7c1477c --- /dev/null +++ b/arch/s390/include/asm/checksum.h | |||
@@ -0,0 +1,166 @@ | |||
1 | #ifndef _S390_CHECKSUM_H | ||
2 | #define _S390_CHECKSUM_H | ||
3 | |||
4 | /* | ||
5 | * include/asm-s390/checksum.h | ||
6 | * S390 fast network checksum routines | ||
7 | * see also arch/S390/lib/checksum.c | ||
8 | * | ||
9 | * S390 version | ||
10 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
11 | * Author(s): Ulrich Hild (first version) | ||
12 | * Martin Schwidefsky (heavily optimized CKSM version) | ||
13 | * D.J. Barrow (third attempt) | ||
14 | */ | ||
15 | |||
16 | #include <asm/uaccess.h> | ||
17 | |||
18 | /* | ||
19 | * computes the checksum of a memory block at buff, length len, | ||
20 | * and adds in "sum" (32-bit) | ||
21 | * | ||
22 | * returns a 32-bit number suitable for feeding into itself | ||
23 | * or csum_tcpudp_magic | ||
24 | * | ||
25 | * this function must be called with even lengths, except | ||
26 | * for the last fragment, which may be odd | ||
27 | * | ||
28 | * it's best to have buff aligned on a 32-bit boundary | ||
29 | */ | ||
30 | static inline __wsum | ||
31 | csum_partial(const void *buff, int len, __wsum sum) | ||
32 | { | ||
33 | register unsigned long reg2 asm("2") = (unsigned long) buff; | ||
34 | register unsigned long reg3 asm("3") = (unsigned long) len; | ||
35 | |||
36 | asm volatile( | ||
37 | "0: cksm %0,%1\n" /* do checksum on longs */ | ||
38 | " jo 0b\n" | ||
39 | : "+d" (sum), "+d" (reg2), "+d" (reg3) : : "cc", "memory"); | ||
40 | return sum; | ||
41 | } | ||
42 | |||
43 | /* | ||
44 | * the same as csum_partial_copy, but copies from user space. | ||
45 | * | ||
46 | * here even more important to align src and dst on a 32-bit (or even | ||
47 | * better 64-bit) boundary | ||
48 | * | ||
49 | * Copy from userspace and compute checksum. If we catch an exception | ||
50 | * then zero the rest of the buffer. | ||
51 | */ | ||
52 | static inline __wsum | ||
53 | csum_partial_copy_from_user(const void __user *src, void *dst, | ||
54 | int len, __wsum sum, | ||
55 | int *err_ptr) | ||
56 | { | ||
57 | int missing; | ||
58 | |||
59 | missing = copy_from_user(dst, src, len); | ||
60 | if (missing) { | ||
61 | memset(dst + len - missing, 0, missing); | ||
62 | *err_ptr = -EFAULT; | ||
63 | } | ||
64 | |||
65 | return csum_partial(dst, len, sum); | ||
66 | } | ||
67 | |||
68 | |||
69 | static inline __wsum | ||
70 | csum_partial_copy_nocheck (const void *src, void *dst, int len, __wsum sum) | ||
71 | { | ||
72 | memcpy(dst,src,len); | ||
73 | return csum_partial(dst, len, sum); | ||
74 | } | ||
75 | |||
76 | /* | ||
77 | * Fold a partial checksum without adding pseudo headers | ||
78 | */ | ||
79 | static inline __sum16 csum_fold(__wsum sum) | ||
80 | { | ||
81 | #ifndef __s390x__ | ||
82 | register_pair rp; | ||
83 | |||
84 | asm volatile( | ||
85 | " slr %N1,%N1\n" /* %0 = H L */ | ||
86 | " lr %1,%0\n" /* %0 = H L, %1 = H L 0 0 */ | ||
87 | " srdl %1,16\n" /* %0 = H L, %1 = 0 H L 0 */ | ||
88 | " alr %1,%N1\n" /* %0 = H L, %1 = L H L 0 */ | ||
89 | " alr %0,%1\n" /* %0 = H+L+C L+H */ | ||
90 | " srl %0,16\n" /* %0 = H+L+C */ | ||
91 | : "+&d" (sum), "=d" (rp) : : "cc"); | ||
92 | #else /* __s390x__ */ | ||
93 | asm volatile( | ||
94 | " sr 3,3\n" /* %0 = H*65536 + L */ | ||
95 | " lr 2,%0\n" /* %0 = H L, 2/3 = H L / 0 0 */ | ||
96 | " srdl 2,16\n" /* %0 = H L, 2/3 = 0 H / L 0 */ | ||
97 | " alr 2,3\n" /* %0 = H L, 2/3 = L H / L 0 */ | ||
98 | " alr %0,2\n" /* %0 = H+L+C L+H */ | ||
99 | " srl %0,16\n" /* %0 = H+L+C */ | ||
100 | : "+&d" (sum) : : "cc", "2", "3"); | ||
101 | #endif /* __s390x__ */ | ||
102 | return (__force __sum16) ~sum; | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * This is a version of ip_compute_csum() optimized for IP headers, | ||
107 | * which always checksum on 4 octet boundaries. | ||
108 | * | ||
109 | */ | ||
110 | static inline __sum16 ip_fast_csum(const void *iph, unsigned int ihl) | ||
111 | { | ||
112 | return csum_fold(csum_partial(iph, ihl*4, 0)); | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * computes the checksum of the TCP/UDP pseudo-header | ||
117 | * returns a 32-bit checksum | ||
118 | */ | ||
119 | static inline __wsum | ||
120 | csum_tcpudp_nofold(__be32 saddr, __be32 daddr, | ||
121 | unsigned short len, unsigned short proto, | ||
122 | __wsum sum) | ||
123 | { | ||
124 | __u32 csum = (__force __u32)sum; | ||
125 | |||
126 | csum += (__force __u32)saddr; | ||
127 | if (csum < (__force __u32)saddr) | ||
128 | csum++; | ||
129 | |||
130 | csum += (__force __u32)daddr; | ||
131 | if (csum < (__force __u32)daddr) | ||
132 | csum++; | ||
133 | |||
134 | csum += len + proto; | ||
135 | if (csum < len + proto) | ||
136 | csum++; | ||
137 | |||
138 | return (__force __wsum)csum; | ||
139 | } | ||
140 | |||
141 | /* | ||
142 | * computes the checksum of the TCP/UDP pseudo-header | ||
143 | * returns a 16-bit checksum, already complemented | ||
144 | */ | ||
145 | |||
146 | static inline __sum16 | ||
147 | csum_tcpudp_magic(__be32 saddr, __be32 daddr, | ||
148 | unsigned short len, unsigned short proto, | ||
149 | __wsum sum) | ||
150 | { | ||
151 | return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); | ||
152 | } | ||
153 | |||
154 | /* | ||
155 | * this routine is used for miscellaneous IP-like checksums, mainly | ||
156 | * in icmp.c | ||
157 | */ | ||
158 | |||
159 | static inline __sum16 ip_compute_csum(const void *buff, int len) | ||
160 | { | ||
161 | return csum_fold(csum_partial(buff, len, 0)); | ||
162 | } | ||
163 | |||
164 | #endif /* _S390_CHECKSUM_H */ | ||
165 | |||
166 | |||
diff --git a/arch/s390/include/asm/chpid.h b/arch/s390/include/asm/chpid.h new file mode 100644 index 000000000000..dfe3c7f3439a --- /dev/null +++ b/arch/s390/include/asm/chpid.h | |||
@@ -0,0 +1,56 @@ | |||
1 | /* | ||
2 | * drivers/s390/cio/chpid.h | ||
3 | * | ||
4 | * Copyright IBM Corp. 2007 | ||
5 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_S390_CHPID_H | ||
9 | #define _ASM_S390_CHPID_H _ASM_S390_CHPID_H | ||
10 | |||
11 | #include <linux/string.h> | ||
12 | #include <asm/types.h> | ||
13 | |||
14 | #define __MAX_CHPID 255 | ||
15 | |||
16 | struct chp_id { | ||
17 | u8 reserved1; | ||
18 | u8 cssid; | ||
19 | u8 reserved2; | ||
20 | u8 id; | ||
21 | } __attribute__((packed)); | ||
22 | |||
23 | #ifdef __KERNEL__ | ||
24 | #include <asm/cio.h> | ||
25 | |||
26 | static inline void chp_id_init(struct chp_id *chpid) | ||
27 | { | ||
28 | memset(chpid, 0, sizeof(struct chp_id)); | ||
29 | } | ||
30 | |||
31 | static inline int chp_id_is_equal(struct chp_id *a, struct chp_id *b) | ||
32 | { | ||
33 | return (a->id == b->id) && (a->cssid == b->cssid); | ||
34 | } | ||
35 | |||
36 | static inline void chp_id_next(struct chp_id *chpid) | ||
37 | { | ||
38 | if (chpid->id < __MAX_CHPID) | ||
39 | chpid->id++; | ||
40 | else { | ||
41 | chpid->id = 0; | ||
42 | chpid->cssid++; | ||
43 | } | ||
44 | } | ||
45 | |||
46 | static inline int chp_id_is_valid(struct chp_id *chpid) | ||
47 | { | ||
48 | return (chpid->cssid <= __MAX_CSSID); | ||
49 | } | ||
50 | |||
51 | |||
52 | #define chp_id_for_each(c) \ | ||
53 | for (chp_id_init(c); chp_id_is_valid(c); chp_id_next(c)) | ||
54 | #endif /* __KERNEL */ | ||
55 | |||
56 | #endif /* _ASM_S390_CHPID_H */ | ||
diff --git a/arch/s390/include/asm/chsc.h b/arch/s390/include/asm/chsc.h new file mode 100644 index 000000000000..d38d0cf62d4b --- /dev/null +++ b/arch/s390/include/asm/chsc.h | |||
@@ -0,0 +1,127 @@ | |||
1 | /* | ||
2 | * ioctl interface for /dev/chsc | ||
3 | * | ||
4 | * Copyright 2008 IBM Corp. | ||
5 | * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_CHSC_H | ||
9 | #define _ASM_CHSC_H | ||
10 | |||
11 | #include <asm/chpid.h> | ||
12 | #include <asm/schid.h> | ||
13 | |||
14 | struct chsc_async_header { | ||
15 | __u16 length; | ||
16 | __u16 code; | ||
17 | __u32 cmd_dependend; | ||
18 | __u32 key : 4; | ||
19 | __u32 : 28; | ||
20 | struct subchannel_id sid; | ||
21 | } __attribute__ ((packed)); | ||
22 | |||
23 | struct chsc_async_area { | ||
24 | struct chsc_async_header header; | ||
25 | __u8 data[PAGE_SIZE - 16 /* size of chsc_async_header */]; | ||
26 | } __attribute__ ((packed)); | ||
27 | |||
28 | |||
29 | struct chsc_response_struct { | ||
30 | __u16 length; | ||
31 | __u16 code; | ||
32 | __u32 parms; | ||
33 | __u8 data[PAGE_SIZE - 8]; | ||
34 | } __attribute__ ((packed)); | ||
35 | |||
36 | struct chsc_chp_cd { | ||
37 | struct chp_id chpid; | ||
38 | int m; | ||
39 | int fmt; | ||
40 | struct chsc_response_struct cpcb; | ||
41 | }; | ||
42 | |||
43 | struct chsc_cu_cd { | ||
44 | __u16 cun; | ||
45 | __u8 cssid; | ||
46 | int m; | ||
47 | int fmt; | ||
48 | struct chsc_response_struct cucb; | ||
49 | }; | ||
50 | |||
51 | struct chsc_sch_cud { | ||
52 | struct subchannel_id schid; | ||
53 | int fmt; | ||
54 | struct chsc_response_struct scub; | ||
55 | }; | ||
56 | |||
57 | struct conf_id { | ||
58 | int m; | ||
59 | __u8 cssid; | ||
60 | __u8 ssid; | ||
61 | }; | ||
62 | |||
63 | struct chsc_conf_info { | ||
64 | struct conf_id id; | ||
65 | int fmt; | ||
66 | struct chsc_response_struct scid; | ||
67 | }; | ||
68 | |||
69 | struct ccl_parm_chpid { | ||
70 | int m; | ||
71 | struct chp_id chp; | ||
72 | }; | ||
73 | |||
74 | struct ccl_parm_cssids { | ||
75 | __u8 f_cssid; | ||
76 | __u8 l_cssid; | ||
77 | }; | ||
78 | |||
79 | struct chsc_comp_list { | ||
80 | struct { | ||
81 | enum { | ||
82 | CCL_CU_ON_CHP = 1, | ||
83 | CCL_CHP_TYPE_CAP = 2, | ||
84 | CCL_CSS_IMG = 4, | ||
85 | CCL_CSS_IMG_CONF_CHAR = 5, | ||
86 | CCL_IOP_CHP = 6, | ||
87 | } ctype; | ||
88 | int fmt; | ||
89 | struct ccl_parm_chpid chpid; | ||
90 | struct ccl_parm_cssids cssids; | ||
91 | } req; | ||
92 | struct chsc_response_struct sccl; | ||
93 | }; | ||
94 | |||
95 | struct chsc_dcal { | ||
96 | struct { | ||
97 | enum { | ||
98 | DCAL_CSS_IID_PN = 4, | ||
99 | } atype; | ||
100 | __u32 list_parm[2]; | ||
101 | int fmt; | ||
102 | } req; | ||
103 | struct chsc_response_struct sdcal; | ||
104 | }; | ||
105 | |||
106 | struct chsc_cpd_info { | ||
107 | struct chp_id chpid; | ||
108 | int m; | ||
109 | int fmt; | ||
110 | int rfmt; | ||
111 | int c; | ||
112 | struct chsc_response_struct chpdb; | ||
113 | }; | ||
114 | |||
115 | #define CHSC_IOCTL_MAGIC 'c' | ||
116 | |||
117 | #define CHSC_START _IOWR(CHSC_IOCTL_MAGIC, 0x81, struct chsc_async_area) | ||
118 | #define CHSC_INFO_CHANNEL_PATH _IOWR(CHSC_IOCTL_MAGIC, 0x82, \ | ||
119 | struct chsc_chp_cd) | ||
120 | #define CHSC_INFO_CU _IOWR(CHSC_IOCTL_MAGIC, 0x83, struct chsc_cu_cd) | ||
121 | #define CHSC_INFO_SCH_CU _IOWR(CHSC_IOCTL_MAGIC, 0x84, struct chsc_sch_cud) | ||
122 | #define CHSC_INFO_CI _IOWR(CHSC_IOCTL_MAGIC, 0x85, struct chsc_conf_info) | ||
123 | #define CHSC_INFO_CCL _IOWR(CHSC_IOCTL_MAGIC, 0x86, struct chsc_comp_list) | ||
124 | #define CHSC_INFO_CPD _IOWR(CHSC_IOCTL_MAGIC, 0x87, struct chsc_cpd_info) | ||
125 | #define CHSC_INFO_DCAL _IOWR(CHSC_IOCTL_MAGIC, 0x88, struct chsc_dcal) | ||
126 | |||
127 | #endif | ||
diff --git a/arch/s390/include/asm/cio.h b/arch/s390/include/asm/cio.h new file mode 100644 index 000000000000..6dccb071aec3 --- /dev/null +++ b/arch/s390/include/asm/cio.h | |||
@@ -0,0 +1,514 @@ | |||
1 | /* | ||
2 | * include/asm-s390/cio.h | ||
3 | * include/asm-s390x/cio.h | ||
4 | * | ||
5 | * Common interface for I/O on S/390 | ||
6 | */ | ||
7 | #ifndef _ASM_S390_CIO_H_ | ||
8 | #define _ASM_S390_CIO_H_ | ||
9 | |||
10 | #include <linux/spinlock.h> | ||
11 | #include <asm/types.h> | ||
12 | |||
13 | #ifdef __KERNEL__ | ||
14 | |||
15 | #define LPM_ANYPATH 0xff | ||
16 | #define __MAX_CSSID 0 | ||
17 | |||
18 | /** | ||
19 | * struct cmd_scsw - command-mode subchannel status word | ||
20 | * @key: subchannel key | ||
21 | * @sctl: suspend control | ||
22 | * @eswf: esw format | ||
23 | * @cc: deferred condition code | ||
24 | * @fmt: format | ||
25 | * @pfch: prefetch | ||
26 | * @isic: initial-status interruption control | ||
27 | * @alcc: address-limit checking control | ||
28 | * @ssi: suppress-suspended interruption | ||
29 | * @zcc: zero condition code | ||
30 | * @ectl: extended control | ||
31 | * @pno: path not operational | ||
32 | * @res: reserved | ||
33 | * @fctl: function control | ||
34 | * @actl: activity control | ||
35 | * @stctl: status control | ||
36 | * @cpa: channel program address | ||
37 | * @dstat: device status | ||
38 | * @cstat: subchannel status | ||
39 | * @count: residual count | ||
40 | */ | ||
41 | struct cmd_scsw { | ||
42 | __u32 key : 4; | ||
43 | __u32 sctl : 1; | ||
44 | __u32 eswf : 1; | ||
45 | __u32 cc : 2; | ||
46 | __u32 fmt : 1; | ||
47 | __u32 pfch : 1; | ||
48 | __u32 isic : 1; | ||
49 | __u32 alcc : 1; | ||
50 | __u32 ssi : 1; | ||
51 | __u32 zcc : 1; | ||
52 | __u32 ectl : 1; | ||
53 | __u32 pno : 1; | ||
54 | __u32 res : 1; | ||
55 | __u32 fctl : 3; | ||
56 | __u32 actl : 7; | ||
57 | __u32 stctl : 5; | ||
58 | __u32 cpa; | ||
59 | __u32 dstat : 8; | ||
60 | __u32 cstat : 8; | ||
61 | __u32 count : 16; | ||
62 | } __attribute__ ((packed)); | ||
63 | |||
64 | /** | ||
65 | * struct tm_scsw - transport-mode subchannel status word | ||
66 | * @key: subchannel key | ||
67 | * @eswf: esw format | ||
68 | * @cc: deferred condition code | ||
69 | * @fmt: format | ||
70 | * @x: IRB-format control | ||
71 | * @q: interrogate-complete | ||
72 | * @ectl: extended control | ||
73 | * @pno: path not operational | ||
74 | * @fctl: function control | ||
75 | * @actl: activity control | ||
76 | * @stctl: status control | ||
77 | * @tcw: TCW address | ||
78 | * @dstat: device status | ||
79 | * @cstat: subchannel status | ||
80 | * @fcxs: FCX status | ||
81 | * @schxs: subchannel-extended status | ||
82 | */ | ||
83 | struct tm_scsw { | ||
84 | u32 key:4; | ||
85 | u32 :1; | ||
86 | u32 eswf:1; | ||
87 | u32 cc:2; | ||
88 | u32 fmt:3; | ||
89 | u32 x:1; | ||
90 | u32 q:1; | ||
91 | u32 :1; | ||
92 | u32 ectl:1; | ||
93 | u32 pno:1; | ||
94 | u32 :1; | ||
95 | u32 fctl:3; | ||
96 | u32 actl:7; | ||
97 | u32 stctl:5; | ||
98 | u32 tcw; | ||
99 | u32 dstat:8; | ||
100 | u32 cstat:8; | ||
101 | u32 fcxs:8; | ||
102 | u32 schxs:8; | ||
103 | } __attribute__ ((packed)); | ||
104 | |||
105 | /** | ||
106 | * union scsw - subchannel status word | ||
107 | * @cmd: command-mode SCSW | ||
108 | * @tm: transport-mode SCSW | ||
109 | */ | ||
110 | union scsw { | ||
111 | struct cmd_scsw cmd; | ||
112 | struct tm_scsw tm; | ||
113 | } __attribute__ ((packed)); | ||
114 | |||
115 | int scsw_is_tm(union scsw *scsw); | ||
116 | u32 scsw_key(union scsw *scsw); | ||
117 | u32 scsw_eswf(union scsw *scsw); | ||
118 | u32 scsw_cc(union scsw *scsw); | ||
119 | u32 scsw_ectl(union scsw *scsw); | ||
120 | u32 scsw_pno(union scsw *scsw); | ||
121 | u32 scsw_fctl(union scsw *scsw); | ||
122 | u32 scsw_actl(union scsw *scsw); | ||
123 | u32 scsw_stctl(union scsw *scsw); | ||
124 | u32 scsw_dstat(union scsw *scsw); | ||
125 | u32 scsw_cstat(union scsw *scsw); | ||
126 | int scsw_is_solicited(union scsw *scsw); | ||
127 | int scsw_is_valid_key(union scsw *scsw); | ||
128 | int scsw_is_valid_eswf(union scsw *scsw); | ||
129 | int scsw_is_valid_cc(union scsw *scsw); | ||
130 | int scsw_is_valid_ectl(union scsw *scsw); | ||
131 | int scsw_is_valid_pno(union scsw *scsw); | ||
132 | int scsw_is_valid_fctl(union scsw *scsw); | ||
133 | int scsw_is_valid_actl(union scsw *scsw); | ||
134 | int scsw_is_valid_stctl(union scsw *scsw); | ||
135 | int scsw_is_valid_dstat(union scsw *scsw); | ||
136 | int scsw_is_valid_cstat(union scsw *scsw); | ||
137 | int scsw_cmd_is_valid_key(union scsw *scsw); | ||
138 | int scsw_cmd_is_valid_sctl(union scsw *scsw); | ||
139 | int scsw_cmd_is_valid_eswf(union scsw *scsw); | ||
140 | int scsw_cmd_is_valid_cc(union scsw *scsw); | ||
141 | int scsw_cmd_is_valid_fmt(union scsw *scsw); | ||
142 | int scsw_cmd_is_valid_pfch(union scsw *scsw); | ||
143 | int scsw_cmd_is_valid_isic(union scsw *scsw); | ||
144 | int scsw_cmd_is_valid_alcc(union scsw *scsw); | ||
145 | int scsw_cmd_is_valid_ssi(union scsw *scsw); | ||
146 | int scsw_cmd_is_valid_zcc(union scsw *scsw); | ||
147 | int scsw_cmd_is_valid_ectl(union scsw *scsw); | ||
148 | int scsw_cmd_is_valid_pno(union scsw *scsw); | ||
149 | int scsw_cmd_is_valid_fctl(union scsw *scsw); | ||
150 | int scsw_cmd_is_valid_actl(union scsw *scsw); | ||
151 | int scsw_cmd_is_valid_stctl(union scsw *scsw); | ||
152 | int scsw_cmd_is_valid_dstat(union scsw *scsw); | ||
153 | int scsw_cmd_is_valid_cstat(union scsw *scsw); | ||
154 | int scsw_cmd_is_solicited(union scsw *scsw); | ||
155 | int scsw_tm_is_valid_key(union scsw *scsw); | ||
156 | int scsw_tm_is_valid_eswf(union scsw *scsw); | ||
157 | int scsw_tm_is_valid_cc(union scsw *scsw); | ||
158 | int scsw_tm_is_valid_fmt(union scsw *scsw); | ||
159 | int scsw_tm_is_valid_x(union scsw *scsw); | ||
160 | int scsw_tm_is_valid_q(union scsw *scsw); | ||
161 | int scsw_tm_is_valid_ectl(union scsw *scsw); | ||
162 | int scsw_tm_is_valid_pno(union scsw *scsw); | ||
163 | int scsw_tm_is_valid_fctl(union scsw *scsw); | ||
164 | int scsw_tm_is_valid_actl(union scsw *scsw); | ||
165 | int scsw_tm_is_valid_stctl(union scsw *scsw); | ||
166 | int scsw_tm_is_valid_dstat(union scsw *scsw); | ||
167 | int scsw_tm_is_valid_cstat(union scsw *scsw); | ||
168 | int scsw_tm_is_valid_fcxs(union scsw *scsw); | ||
169 | int scsw_tm_is_valid_schxs(union scsw *scsw); | ||
170 | int scsw_tm_is_solicited(union scsw *scsw); | ||
171 | |||
172 | #define SCSW_FCTL_CLEAR_FUNC 0x1 | ||
173 | #define SCSW_FCTL_HALT_FUNC 0x2 | ||
174 | #define SCSW_FCTL_START_FUNC 0x4 | ||
175 | |||
176 | #define SCSW_ACTL_SUSPENDED 0x1 | ||
177 | #define SCSW_ACTL_DEVACT 0x2 | ||
178 | #define SCSW_ACTL_SCHACT 0x4 | ||
179 | #define SCSW_ACTL_CLEAR_PEND 0x8 | ||
180 | #define SCSW_ACTL_HALT_PEND 0x10 | ||
181 | #define SCSW_ACTL_START_PEND 0x20 | ||
182 | #define SCSW_ACTL_RESUME_PEND 0x40 | ||
183 | |||
184 | #define SCSW_STCTL_STATUS_PEND 0x1 | ||
185 | #define SCSW_STCTL_SEC_STATUS 0x2 | ||
186 | #define SCSW_STCTL_PRIM_STATUS 0x4 | ||
187 | #define SCSW_STCTL_INTER_STATUS 0x8 | ||
188 | #define SCSW_STCTL_ALERT_STATUS 0x10 | ||
189 | |||
190 | #define DEV_STAT_ATTENTION 0x80 | ||
191 | #define DEV_STAT_STAT_MOD 0x40 | ||
192 | #define DEV_STAT_CU_END 0x20 | ||
193 | #define DEV_STAT_BUSY 0x10 | ||
194 | #define DEV_STAT_CHN_END 0x08 | ||
195 | #define DEV_STAT_DEV_END 0x04 | ||
196 | #define DEV_STAT_UNIT_CHECK 0x02 | ||
197 | #define DEV_STAT_UNIT_EXCEP 0x01 | ||
198 | |||
199 | #define SCHN_STAT_PCI 0x80 | ||
200 | #define SCHN_STAT_INCORR_LEN 0x40 | ||
201 | #define SCHN_STAT_PROG_CHECK 0x20 | ||
202 | #define SCHN_STAT_PROT_CHECK 0x10 | ||
203 | #define SCHN_STAT_CHN_DATA_CHK 0x08 | ||
204 | #define SCHN_STAT_CHN_CTRL_CHK 0x04 | ||
205 | #define SCHN_STAT_INTF_CTRL_CHK 0x02 | ||
206 | #define SCHN_STAT_CHAIN_CHECK 0x01 | ||
207 | |||
208 | /* | ||
209 | * architectured values for first sense byte | ||
210 | */ | ||
211 | #define SNS0_CMD_REJECT 0x80 | ||
212 | #define SNS_CMD_REJECT SNS0_CMD_REJEC | ||
213 | #define SNS0_INTERVENTION_REQ 0x40 | ||
214 | #define SNS0_BUS_OUT_CHECK 0x20 | ||
215 | #define SNS0_EQUIPMENT_CHECK 0x10 | ||
216 | #define SNS0_DATA_CHECK 0x08 | ||
217 | #define SNS0_OVERRUN 0x04 | ||
218 | #define SNS0_INCOMPL_DOMAIN 0x01 | ||
219 | |||
220 | /* | ||
221 | * architectured values for second sense byte | ||
222 | */ | ||
223 | #define SNS1_PERM_ERR 0x80 | ||
224 | #define SNS1_INV_TRACK_FORMAT 0x40 | ||
225 | #define SNS1_EOC 0x20 | ||
226 | #define SNS1_MESSAGE_TO_OPER 0x10 | ||
227 | #define SNS1_NO_REC_FOUND 0x08 | ||
228 | #define SNS1_FILE_PROTECTED 0x04 | ||
229 | #define SNS1_WRITE_INHIBITED 0x02 | ||
230 | #define SNS1_INPRECISE_END 0x01 | ||
231 | |||
232 | /* | ||
233 | * architectured values for third sense byte | ||
234 | */ | ||
235 | #define SNS2_REQ_INH_WRITE 0x80 | ||
236 | #define SNS2_CORRECTABLE 0x40 | ||
237 | #define SNS2_FIRST_LOG_ERR 0x20 | ||
238 | #define SNS2_ENV_DATA_PRESENT 0x10 | ||
239 | #define SNS2_INPRECISE_END 0x04 | ||
240 | |||
241 | /** | ||
242 | * struct ccw1 - channel command word | ||
243 | * @cmd_code: command code | ||
244 | * @flags: flags, like IDA adressing, etc. | ||
245 | * @count: byte count | ||
246 | * @cda: data address | ||
247 | * | ||
248 | * The ccw is the basic structure to build channel programs that perform | ||
249 | * operations with the device or the control unit. Only Format-1 channel | ||
250 | * command words are supported. | ||
251 | */ | ||
252 | struct ccw1 { | ||
253 | __u8 cmd_code; | ||
254 | __u8 flags; | ||
255 | __u16 count; | ||
256 | __u32 cda; | ||
257 | } __attribute__ ((packed,aligned(8))); | ||
258 | |||
259 | #define CCW_FLAG_DC 0x80 | ||
260 | #define CCW_FLAG_CC 0x40 | ||
261 | #define CCW_FLAG_SLI 0x20 | ||
262 | #define CCW_FLAG_SKIP 0x10 | ||
263 | #define CCW_FLAG_PCI 0x08 | ||
264 | #define CCW_FLAG_IDA 0x04 | ||
265 | #define CCW_FLAG_SUSPEND 0x02 | ||
266 | |||
267 | #define CCW_CMD_READ_IPL 0x02 | ||
268 | #define CCW_CMD_NOOP 0x03 | ||
269 | #define CCW_CMD_BASIC_SENSE 0x04 | ||
270 | #define CCW_CMD_TIC 0x08 | ||
271 | #define CCW_CMD_STLCK 0x14 | ||
272 | #define CCW_CMD_SENSE_PGID 0x34 | ||
273 | #define CCW_CMD_SUSPEND_RECONN 0x5B | ||
274 | #define CCW_CMD_RDC 0x64 | ||
275 | #define CCW_CMD_RELEASE 0x94 | ||
276 | #define CCW_CMD_SET_PGID 0xAF | ||
277 | #define CCW_CMD_SENSE_ID 0xE4 | ||
278 | #define CCW_CMD_DCTL 0xF3 | ||
279 | |||
280 | #define SENSE_MAX_COUNT 0x20 | ||
281 | |||
282 | /** | ||
283 | * struct erw - extended report word | ||
284 | * @res0: reserved | ||
285 | * @auth: authorization check | ||
286 | * @pvrf: path-verification-required flag | ||
287 | * @cpt: channel-path timeout | ||
288 | * @fsavf: failing storage address validity flag | ||
289 | * @cons: concurrent sense | ||
290 | * @scavf: secondary ccw address validity flag | ||
291 | * @fsaf: failing storage address format | ||
292 | * @scnt: sense count, if @cons == %1 | ||
293 | * @res16: reserved | ||
294 | */ | ||
295 | struct erw { | ||
296 | __u32 res0 : 3; | ||
297 | __u32 auth : 1; | ||
298 | __u32 pvrf : 1; | ||
299 | __u32 cpt : 1; | ||
300 | __u32 fsavf : 1; | ||
301 | __u32 cons : 1; | ||
302 | __u32 scavf : 1; | ||
303 | __u32 fsaf : 1; | ||
304 | __u32 scnt : 6; | ||
305 | __u32 res16 : 16; | ||
306 | } __attribute__ ((packed)); | ||
307 | |||
308 | /** | ||
309 | * struct sublog - subchannel logout area | ||
310 | * @res0: reserved | ||
311 | * @esf: extended status flags | ||
312 | * @lpum: last path used mask | ||
313 | * @arep: ancillary report | ||
314 | * @fvf: field-validity flags | ||
315 | * @sacc: storage access code | ||
316 | * @termc: termination code | ||
317 | * @devsc: device-status check | ||
318 | * @serr: secondary error | ||
319 | * @ioerr: i/o-error alert | ||
320 | * @seqc: sequence code | ||
321 | */ | ||
322 | struct sublog { | ||
323 | __u32 res0 : 1; | ||
324 | __u32 esf : 7; | ||
325 | __u32 lpum : 8; | ||
326 | __u32 arep : 1; | ||
327 | __u32 fvf : 5; | ||
328 | __u32 sacc : 2; | ||
329 | __u32 termc : 2; | ||
330 | __u32 devsc : 1; | ||
331 | __u32 serr : 1; | ||
332 | __u32 ioerr : 1; | ||
333 | __u32 seqc : 3; | ||
334 | } __attribute__ ((packed)); | ||
335 | |||
336 | /** | ||
337 | * struct esw0 - Format 0 Extended Status Word (ESW) | ||
338 | * @sublog: subchannel logout | ||
339 | * @erw: extended report word | ||
340 | * @faddr: failing storage address | ||
341 | * @saddr: secondary ccw address | ||
342 | */ | ||
343 | struct esw0 { | ||
344 | struct sublog sublog; | ||
345 | struct erw erw; | ||
346 | __u32 faddr[2]; | ||
347 | __u32 saddr; | ||
348 | } __attribute__ ((packed)); | ||
349 | |||
350 | /** | ||
351 | * struct esw1 - Format 1 Extended Status Word (ESW) | ||
352 | * @zero0: reserved zeros | ||
353 | * @lpum: last path used mask | ||
354 | * @zero16: reserved zeros | ||
355 | * @erw: extended report word | ||
356 | * @zeros: three fullwords of zeros | ||
357 | */ | ||
358 | struct esw1 { | ||
359 | __u8 zero0; | ||
360 | __u8 lpum; | ||
361 | __u16 zero16; | ||
362 | struct erw erw; | ||
363 | __u32 zeros[3]; | ||
364 | } __attribute__ ((packed)); | ||
365 | |||
366 | /** | ||
367 | * struct esw2 - Format 2 Extended Status Word (ESW) | ||
368 | * @zero0: reserved zeros | ||
369 | * @lpum: last path used mask | ||
370 | * @dcti: device-connect-time interval | ||
371 | * @erw: extended report word | ||
372 | * @zeros: three fullwords of zeros | ||
373 | */ | ||
374 | struct esw2 { | ||
375 | __u8 zero0; | ||
376 | __u8 lpum; | ||
377 | __u16 dcti; | ||
378 | struct erw erw; | ||
379 | __u32 zeros[3]; | ||
380 | } __attribute__ ((packed)); | ||
381 | |||
382 | /** | ||
383 | * struct esw3 - Format 3 Extended Status Word (ESW) | ||
384 | * @zero0: reserved zeros | ||
385 | * @lpum: last path used mask | ||
386 | * @res: reserved | ||
387 | * @erw: extended report word | ||
388 | * @zeros: three fullwords of zeros | ||
389 | */ | ||
390 | struct esw3 { | ||
391 | __u8 zero0; | ||
392 | __u8 lpum; | ||
393 | __u16 res; | ||
394 | struct erw erw; | ||
395 | __u32 zeros[3]; | ||
396 | } __attribute__ ((packed)); | ||
397 | |||
398 | /** | ||
399 | * struct irb - interruption response block | ||
400 | * @scsw: subchannel status word | ||
401 | * @esw: extened status word, 4 formats | ||
402 | * @ecw: extended control word | ||
403 | * | ||
404 | * The irb that is handed to the device driver when an interrupt occurs. For | ||
405 | * solicited interrupts, the common I/O layer already performs checks whether | ||
406 | * a field is valid; a field not being valid is always passed as %0. | ||
407 | * If a unit check occured, @ecw may contain sense data; this is retrieved | ||
408 | * by the common I/O layer itself if the device doesn't support concurrent | ||
409 | * sense (so that the device driver never needs to perform basic sene itself). | ||
410 | * For unsolicited interrupts, the irb is passed as-is (expect for sense data, | ||
411 | * if applicable). | ||
412 | */ | ||
413 | struct irb { | ||
414 | union scsw scsw; | ||
415 | union { | ||
416 | struct esw0 esw0; | ||
417 | struct esw1 esw1; | ||
418 | struct esw2 esw2; | ||
419 | struct esw3 esw3; | ||
420 | } esw; | ||
421 | __u8 ecw[32]; | ||
422 | } __attribute__ ((packed,aligned(4))); | ||
423 | |||
424 | /** | ||
425 | * struct ciw - command information word (CIW) layout | ||
426 | * @et: entry type | ||
427 | * @reserved: reserved bits | ||
428 | * @ct: command type | ||
429 | * @cmd: command code | ||
430 | * @count: command count | ||
431 | */ | ||
432 | struct ciw { | ||
433 | __u32 et : 2; | ||
434 | __u32 reserved : 2; | ||
435 | __u32 ct : 4; | ||
436 | __u32 cmd : 8; | ||
437 | __u32 count : 16; | ||
438 | } __attribute__ ((packed)); | ||
439 | |||
440 | #define CIW_TYPE_RCD 0x0 /* read configuration data */ | ||
441 | #define CIW_TYPE_SII 0x1 /* set interface identifier */ | ||
442 | #define CIW_TYPE_RNI 0x2 /* read node identifier */ | ||
443 | |||
444 | /* | ||
445 | * Flags used as input parameters for do_IO() | ||
446 | */ | ||
447 | #define DOIO_ALLOW_SUSPEND 0x0001 /* allow for channel prog. suspend */ | ||
448 | #define DOIO_DENY_PREFETCH 0x0002 /* don't allow for CCW prefetch */ | ||
449 | #define DOIO_SUPPRESS_INTER 0x0004 /* suppress intermediate inter. */ | ||
450 | /* ... for suspended CCWs */ | ||
451 | /* Device or subchannel gone. */ | ||
452 | #define CIO_GONE 0x0001 | ||
453 | /* No path to device. */ | ||
454 | #define CIO_NO_PATH 0x0002 | ||
455 | /* Device has appeared. */ | ||
456 | #define CIO_OPER 0x0004 | ||
457 | /* Sick revalidation of device. */ | ||
458 | #define CIO_REVALIDATE 0x0008 | ||
459 | |||
460 | /** | ||
461 | * struct ccw_dev_id - unique identifier for ccw devices | ||
462 | * @ssid: subchannel set id | ||
463 | * @devno: device number | ||
464 | * | ||
465 | * This structure is not directly based on any hardware structure. The | ||
466 | * hardware identifies a device by its device number and its subchannel, | ||
467 | * which is in turn identified by its id. In order to get a unique identifier | ||
468 | * for ccw devices across subchannel sets, @struct ccw_dev_id has been | ||
469 | * introduced. | ||
470 | */ | ||
471 | struct ccw_dev_id { | ||
472 | u8 ssid; | ||
473 | u16 devno; | ||
474 | }; | ||
475 | |||
476 | /** | ||
477 | * ccw_device_id_is_equal() - compare two ccw_dev_ids | ||
478 | * @dev_id1: a ccw_dev_id | ||
479 | * @dev_id2: another ccw_dev_id | ||
480 | * Returns: | ||
481 | * %1 if the two structures are equal field-by-field, | ||
482 | * %0 if not. | ||
483 | * Context: | ||
484 | * any | ||
485 | */ | ||
486 | static inline int ccw_dev_id_is_equal(struct ccw_dev_id *dev_id1, | ||
487 | struct ccw_dev_id *dev_id2) | ||
488 | { | ||
489 | if ((dev_id1->ssid == dev_id2->ssid) && | ||
490 | (dev_id1->devno == dev_id2->devno)) | ||
491 | return 1; | ||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | extern void wait_cons_dev(void); | ||
496 | |||
497 | extern void css_schedule_reprobe(void); | ||
498 | |||
499 | extern void reipl_ccw_dev(struct ccw_dev_id *id); | ||
500 | |||
501 | struct cio_iplinfo { | ||
502 | u16 devno; | ||
503 | int is_qdio; | ||
504 | }; | ||
505 | |||
506 | extern int cio_get_iplinfo(struct cio_iplinfo *iplinfo); | ||
507 | |||
508 | /* Function from drivers/s390/cio/chsc.c */ | ||
509 | int chsc_sstpc(void *page, unsigned int op, u16 ctrl); | ||
510 | int chsc_sstpi(void *page, void *result, size_t size); | ||
511 | |||
512 | #endif | ||
513 | |||
514 | #endif | ||
diff --git a/arch/s390/include/asm/cmb.h b/arch/s390/include/asm/cmb.h new file mode 100644 index 000000000000..50196857d27a --- /dev/null +++ b/arch/s390/include/asm/cmb.h | |||
@@ -0,0 +1,58 @@ | |||
1 | #ifndef S390_CMB_H | ||
2 | #define S390_CMB_H | ||
3 | /** | ||
4 | * struct cmbdata - channel measurement block data for user space | ||
5 | * @size: size of the stored data | ||
6 | * @elapsed_time: time since last sampling | ||
7 | * @ssch_rsch_count: number of ssch and rsch | ||
8 | * @sample_count: number of samples | ||
9 | * @device_connect_time: time of device connect | ||
10 | * @function_pending_time: time of function pending | ||
11 | * @device_disconnect_time: time of device disconnect | ||
12 | * @control_unit_queuing_time: time of control unit queuing | ||
13 | * @device_active_only_time: time of device active only | ||
14 | * @device_busy_time: time of device busy (ext. format) | ||
15 | * @initial_command_response_time: initial command response time (ext. format) | ||
16 | * | ||
17 | * All values are stored as 64 bit for simplicity, especially | ||
18 | * in 32 bit emulation mode. All time values are normalized to | ||
19 | * nanoseconds. | ||
20 | * Currently, two formats are known, which differ by the size of | ||
21 | * this structure, i.e. the last two members are only set when | ||
22 | * the extended channel measurement facility (first shipped in | ||
23 | * z990 machines) is activated. | ||
24 | * Potentially, more fields could be added, which would result in a | ||
25 | * new ioctl number. | ||
26 | */ | ||
27 | struct cmbdata { | ||
28 | __u64 size; | ||
29 | __u64 elapsed_time; | ||
30 | /* basic and exended format: */ | ||
31 | __u64 ssch_rsch_count; | ||
32 | __u64 sample_count; | ||
33 | __u64 device_connect_time; | ||
34 | __u64 function_pending_time; | ||
35 | __u64 device_disconnect_time; | ||
36 | __u64 control_unit_queuing_time; | ||
37 | __u64 device_active_only_time; | ||
38 | /* extended format only: */ | ||
39 | __u64 device_busy_time; | ||
40 | __u64 initial_command_response_time; | ||
41 | }; | ||
42 | |||
43 | /* enable channel measurement */ | ||
44 | #define BIODASDCMFENABLE _IO(DASD_IOCTL_LETTER, 32) | ||
45 | /* enable channel measurement */ | ||
46 | #define BIODASDCMFDISABLE _IO(DASD_IOCTL_LETTER, 33) | ||
47 | /* read channel measurement data */ | ||
48 | #define BIODASDREADALLCMB _IOWR(DASD_IOCTL_LETTER, 33, struct cmbdata) | ||
49 | |||
50 | #ifdef __KERNEL__ | ||
51 | struct ccw_device; | ||
52 | extern int enable_cmf(struct ccw_device *cdev); | ||
53 | extern int disable_cmf(struct ccw_device *cdev); | ||
54 | extern u64 cmf_read(struct ccw_device *cdev, int index); | ||
55 | extern int cmf_readall(struct ccw_device *cdev, struct cmbdata *data); | ||
56 | |||
57 | #endif /* __KERNEL__ */ | ||
58 | #endif /* S390_CMB_H */ | ||
diff --git a/arch/s390/include/asm/compat.h b/arch/s390/include/asm/compat.h new file mode 100644 index 000000000000..de065b32381a --- /dev/null +++ b/arch/s390/include/asm/compat.h | |||
@@ -0,0 +1,233 @@ | |||
1 | #ifndef _ASM_S390X_COMPAT_H | ||
2 | #define _ASM_S390X_COMPAT_H | ||
3 | /* | ||
4 | * Architecture specific compatibility types | ||
5 | */ | ||
6 | #include <linux/types.h> | ||
7 | #include <linux/sched.h> | ||
8 | |||
9 | #define PSW32_MASK_PER 0x40000000UL | ||
10 | #define PSW32_MASK_DAT 0x04000000UL | ||
11 | #define PSW32_MASK_IO 0x02000000UL | ||
12 | #define PSW32_MASK_EXT 0x01000000UL | ||
13 | #define PSW32_MASK_KEY 0x00F00000UL | ||
14 | #define PSW32_MASK_MCHECK 0x00040000UL | ||
15 | #define PSW32_MASK_WAIT 0x00020000UL | ||
16 | #define PSW32_MASK_PSTATE 0x00010000UL | ||
17 | #define PSW32_MASK_ASC 0x0000C000UL | ||
18 | #define PSW32_MASK_CC 0x00003000UL | ||
19 | #define PSW32_MASK_PM 0x00000f00UL | ||
20 | |||
21 | #define PSW32_ADDR_AMODE31 0x80000000UL | ||
22 | #define PSW32_ADDR_INSN 0x7FFFFFFFUL | ||
23 | |||
24 | #define PSW32_BASE_BITS 0x00080000UL | ||
25 | |||
26 | #define PSW32_ASC_PRIMARY 0x00000000UL | ||
27 | #define PSW32_ASC_ACCREG 0x00004000UL | ||
28 | #define PSW32_ASC_SECONDARY 0x00008000UL | ||
29 | #define PSW32_ASC_HOME 0x0000C000UL | ||
30 | |||
31 | #define PSW32_MASK_MERGE(CURRENT,NEW) \ | ||
32 | (((CURRENT) & ~(PSW32_MASK_CC|PSW32_MASK_PM)) | \ | ||
33 | ((NEW) & (PSW32_MASK_CC|PSW32_MASK_PM))) | ||
34 | |||
35 | extern long psw32_user_bits; | ||
36 | |||
37 | #define COMPAT_USER_HZ 100 | ||
38 | |||
39 | typedef u32 compat_size_t; | ||
40 | typedef s32 compat_ssize_t; | ||
41 | typedef s32 compat_time_t; | ||
42 | typedef s32 compat_clock_t; | ||
43 | typedef s32 compat_pid_t; | ||
44 | typedef u16 __compat_uid_t; | ||
45 | typedef u16 __compat_gid_t; | ||
46 | typedef u32 __compat_uid32_t; | ||
47 | typedef u32 __compat_gid32_t; | ||
48 | typedef u16 compat_mode_t; | ||
49 | typedef u32 compat_ino_t; | ||
50 | typedef u16 compat_dev_t; | ||
51 | typedef s32 compat_off_t; | ||
52 | typedef s64 compat_loff_t; | ||
53 | typedef u16 compat_nlink_t; | ||
54 | typedef u16 compat_ipc_pid_t; | ||
55 | typedef s32 compat_daddr_t; | ||
56 | typedef u32 compat_caddr_t; | ||
57 | typedef __kernel_fsid_t compat_fsid_t; | ||
58 | typedef s32 compat_key_t; | ||
59 | typedef s32 compat_timer_t; | ||
60 | |||
61 | typedef s32 compat_int_t; | ||
62 | typedef s32 compat_long_t; | ||
63 | typedef s64 compat_s64; | ||
64 | typedef u32 compat_uint_t; | ||
65 | typedef u32 compat_ulong_t; | ||
66 | typedef u64 compat_u64; | ||
67 | |||
68 | struct compat_timespec { | ||
69 | compat_time_t tv_sec; | ||
70 | s32 tv_nsec; | ||
71 | }; | ||
72 | |||
73 | struct compat_timeval { | ||
74 | compat_time_t tv_sec; | ||
75 | s32 tv_usec; | ||
76 | }; | ||
77 | |||
78 | struct compat_stat { | ||
79 | compat_dev_t st_dev; | ||
80 | u16 __pad1; | ||
81 | compat_ino_t st_ino; | ||
82 | compat_mode_t st_mode; | ||
83 | compat_nlink_t st_nlink; | ||
84 | __compat_uid_t st_uid; | ||
85 | __compat_gid_t st_gid; | ||
86 | compat_dev_t st_rdev; | ||
87 | u16 __pad2; | ||
88 | u32 st_size; | ||
89 | u32 st_blksize; | ||
90 | u32 st_blocks; | ||
91 | u32 st_atime; | ||
92 | u32 st_atime_nsec; | ||
93 | u32 st_mtime; | ||
94 | u32 st_mtime_nsec; | ||
95 | u32 st_ctime; | ||
96 | u32 st_ctime_nsec; | ||
97 | u32 __unused4; | ||
98 | u32 __unused5; | ||
99 | }; | ||
100 | |||
101 | struct compat_flock { | ||
102 | short l_type; | ||
103 | short l_whence; | ||
104 | compat_off_t l_start; | ||
105 | compat_off_t l_len; | ||
106 | compat_pid_t l_pid; | ||
107 | }; | ||
108 | |||
109 | #define F_GETLK64 12 | ||
110 | #define F_SETLK64 13 | ||
111 | #define F_SETLKW64 14 | ||
112 | |||
113 | struct compat_flock64 { | ||
114 | short l_type; | ||
115 | short l_whence; | ||
116 | compat_loff_t l_start; | ||
117 | compat_loff_t l_len; | ||
118 | compat_pid_t l_pid; | ||
119 | }; | ||
120 | |||
121 | struct compat_statfs { | ||
122 | s32 f_type; | ||
123 | s32 f_bsize; | ||
124 | s32 f_blocks; | ||
125 | s32 f_bfree; | ||
126 | s32 f_bavail; | ||
127 | s32 f_files; | ||
128 | s32 f_ffree; | ||
129 | compat_fsid_t f_fsid; | ||
130 | s32 f_namelen; | ||
131 | s32 f_frsize; | ||
132 | s32 f_spare[6]; | ||
133 | }; | ||
134 | |||
135 | #define COMPAT_RLIM_OLD_INFINITY 0x7fffffff | ||
136 | #define COMPAT_RLIM_INFINITY 0xffffffff | ||
137 | |||
138 | typedef u32 compat_old_sigset_t; /* at least 32 bits */ | ||
139 | |||
140 | #define _COMPAT_NSIG 64 | ||
141 | #define _COMPAT_NSIG_BPW 32 | ||
142 | |||
143 | typedef u32 compat_sigset_word; | ||
144 | |||
145 | #define COMPAT_OFF_T_MAX 0x7fffffff | ||
146 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | ||
147 | |||
148 | /* | ||
149 | * A pointer passed in from user mode. This should not | ||
150 | * be used for syscall parameters, just declare them | ||
151 | * as pointers because the syscall entry code will have | ||
152 | * appropriately converted them already. | ||
153 | */ | ||
154 | typedef u32 compat_uptr_t; | ||
155 | |||
156 | static inline void __user *compat_ptr(compat_uptr_t uptr) | ||
157 | { | ||
158 | return (void __user *)(unsigned long)(uptr & 0x7fffffffUL); | ||
159 | } | ||
160 | |||
161 | static inline compat_uptr_t ptr_to_compat(void __user *uptr) | ||
162 | { | ||
163 | return (u32)(unsigned long)uptr; | ||
164 | } | ||
165 | |||
166 | static inline void __user *compat_alloc_user_space(long len) | ||
167 | { | ||
168 | unsigned long stack; | ||
169 | |||
170 | stack = KSTK_ESP(current); | ||
171 | if (test_thread_flag(TIF_31BIT)) | ||
172 | stack &= 0x7fffffffUL; | ||
173 | return (void __user *) (stack - len); | ||
174 | } | ||
175 | |||
176 | struct compat_ipc64_perm { | ||
177 | compat_key_t key; | ||
178 | __compat_uid32_t uid; | ||
179 | __compat_gid32_t gid; | ||
180 | __compat_uid32_t cuid; | ||
181 | __compat_gid32_t cgid; | ||
182 | compat_mode_t mode; | ||
183 | unsigned short __pad1; | ||
184 | unsigned short seq; | ||
185 | unsigned short __pad2; | ||
186 | unsigned int __unused1; | ||
187 | unsigned int __unused2; | ||
188 | }; | ||
189 | |||
190 | struct compat_semid64_ds { | ||
191 | struct compat_ipc64_perm sem_perm; | ||
192 | compat_time_t sem_otime; | ||
193 | compat_ulong_t __pad1; | ||
194 | compat_time_t sem_ctime; | ||
195 | compat_ulong_t __pad2; | ||
196 | compat_ulong_t sem_nsems; | ||
197 | compat_ulong_t __unused1; | ||
198 | compat_ulong_t __unused2; | ||
199 | }; | ||
200 | |||
201 | struct compat_msqid64_ds { | ||
202 | struct compat_ipc64_perm msg_perm; | ||
203 | compat_time_t msg_stime; | ||
204 | compat_ulong_t __pad1; | ||
205 | compat_time_t msg_rtime; | ||
206 | compat_ulong_t __pad2; | ||
207 | compat_time_t msg_ctime; | ||
208 | compat_ulong_t __pad3; | ||
209 | compat_ulong_t msg_cbytes; | ||
210 | compat_ulong_t msg_qnum; | ||
211 | compat_ulong_t msg_qbytes; | ||
212 | compat_pid_t msg_lspid; | ||
213 | compat_pid_t msg_lrpid; | ||
214 | compat_ulong_t __unused1; | ||
215 | compat_ulong_t __unused2; | ||
216 | }; | ||
217 | |||
218 | struct compat_shmid64_ds { | ||
219 | struct compat_ipc64_perm shm_perm; | ||
220 | compat_size_t shm_segsz; | ||
221 | compat_time_t shm_atime; | ||
222 | compat_ulong_t __pad1; | ||
223 | compat_time_t shm_dtime; | ||
224 | compat_ulong_t __pad2; | ||
225 | compat_time_t shm_ctime; | ||
226 | compat_ulong_t __pad3; | ||
227 | compat_pid_t shm_cpid; | ||
228 | compat_pid_t shm_lpid; | ||
229 | compat_ulong_t shm_nattch; | ||
230 | compat_ulong_t __unused1; | ||
231 | compat_ulong_t __unused2; | ||
232 | }; | ||
233 | #endif /* _ASM_S390X_COMPAT_H */ | ||
diff --git a/arch/s390/include/asm/cpcmd.h b/arch/s390/include/asm/cpcmd.h new file mode 100644 index 000000000000..48a9eab16429 --- /dev/null +++ b/arch/s390/include/asm/cpcmd.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * arch/s390/kernel/cpcmd.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | ||
7 | * Christian Borntraeger (cborntra@de.ibm.com), | ||
8 | */ | ||
9 | |||
10 | #ifndef _ASM_S390_CPCMD_H | ||
11 | #define _ASM_S390_CPCMD_H | ||
12 | |||
13 | /* | ||
14 | * the lowlevel function for cpcmd | ||
15 | * the caller of __cpcmd has to ensure that the response buffer is below 2 GB | ||
16 | */ | ||
17 | extern int __cpcmd(const char *cmd, char *response, int rlen, int *response_code); | ||
18 | |||
19 | /* | ||
20 | * cpcmd is the in-kernel interface for issuing CP commands | ||
21 | * | ||
22 | * cmd: null-terminated command string, max 240 characters | ||
23 | * response: response buffer for VM's textual response | ||
24 | * rlen: size of the response buffer, cpcmd will not exceed this size | ||
25 | * but will cap the output, if its too large. Everything that | ||
26 | * did not fit into the buffer will be silently dropped | ||
27 | * response_code: return pointer for VM's error code | ||
28 | * return value: the size of the response. The caller can check if the buffer | ||
29 | * was large enough by comparing the return value and rlen | ||
30 | * NOTE: If the response buffer is not below 2 GB, cpcmd can sleep | ||
31 | */ | ||
32 | extern int cpcmd(const char *cmd, char *response, int rlen, int *response_code); | ||
33 | |||
34 | #endif /* _ASM_S390_CPCMD_H */ | ||
diff --git a/arch/s390/include/asm/cpu.h b/arch/s390/include/asm/cpu.h new file mode 100644 index 000000000000..e5a6a9ba3adf --- /dev/null +++ b/arch/s390/include/asm/cpu.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * include/asm-s390/cpu.h | ||
3 | * | ||
4 | * Copyright IBM Corp. 2007 | ||
5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_S390_CPU_H_ | ||
9 | #define _ASM_S390_CPU_H_ | ||
10 | |||
11 | #include <linux/types.h> | ||
12 | #include <linux/percpu.h> | ||
13 | #include <linux/spinlock.h> | ||
14 | |||
15 | struct s390_idle_data { | ||
16 | spinlock_t lock; | ||
17 | unsigned int in_idle; | ||
18 | unsigned long long idle_count; | ||
19 | unsigned long long idle_enter; | ||
20 | unsigned long long idle_time; | ||
21 | }; | ||
22 | |||
23 | DECLARE_PER_CPU(struct s390_idle_data, s390_idle); | ||
24 | |||
25 | void s390_idle_leave(void); | ||
26 | |||
27 | static inline void s390_idle_check(void) | ||
28 | { | ||
29 | if ((&__get_cpu_var(s390_idle))->in_idle) | ||
30 | s390_idle_leave(); | ||
31 | } | ||
32 | |||
33 | #endif /* _ASM_S390_CPU_H_ */ | ||
diff --git a/arch/s390/include/asm/cputime.h b/arch/s390/include/asm/cputime.h new file mode 100644 index 000000000000..133ce054fc89 --- /dev/null +++ b/arch/s390/include/asm/cputime.h | |||
@@ -0,0 +1,177 @@ | |||
1 | /* | ||
2 | * include/asm-s390/cputime.h | ||
3 | * | ||
4 | * (C) Copyright IBM Corp. 2004 | ||
5 | * | ||
6 | * Author: Martin Schwidefsky <schwidefsky@de.ibm.com> | ||
7 | */ | ||
8 | |||
9 | #ifndef _S390_CPUTIME_H | ||
10 | #define _S390_CPUTIME_H | ||
11 | |||
12 | #include <asm/div64.h> | ||
13 | |||
14 | /* We want to use micro-second resolution. */ | ||
15 | |||
16 | typedef unsigned long long cputime_t; | ||
17 | typedef unsigned long long cputime64_t; | ||
18 | |||
19 | #ifndef __s390x__ | ||
20 | |||
21 | static inline unsigned int | ||
22 | __div(unsigned long long n, unsigned int base) | ||
23 | { | ||
24 | register_pair rp; | ||
25 | |||
26 | rp.pair = n >> 1; | ||
27 | asm ("dr %0,%1" : "+d" (rp) : "d" (base >> 1)); | ||
28 | return rp.subreg.odd; | ||
29 | } | ||
30 | |||
31 | #else /* __s390x__ */ | ||
32 | |||
33 | static inline unsigned int | ||
34 | __div(unsigned long long n, unsigned int base) | ||
35 | { | ||
36 | return n / base; | ||
37 | } | ||
38 | |||
39 | #endif /* __s390x__ */ | ||
40 | |||
41 | #define cputime_zero (0ULL) | ||
42 | #define cputime_max ((~0UL >> 1) - 1) | ||
43 | #define cputime_add(__a, __b) ((__a) + (__b)) | ||
44 | #define cputime_sub(__a, __b) ((__a) - (__b)) | ||
45 | #define cputime_div(__a, __n) ({ \ | ||
46 | unsigned long long __div = (__a); \ | ||
47 | do_div(__div,__n); \ | ||
48 | __div; \ | ||
49 | }) | ||
50 | #define cputime_halve(__a) ((__a) >> 1) | ||
51 | #define cputime_eq(__a, __b) ((__a) == (__b)) | ||
52 | #define cputime_gt(__a, __b) ((__a) > (__b)) | ||
53 | #define cputime_ge(__a, __b) ((__a) >= (__b)) | ||
54 | #define cputime_lt(__a, __b) ((__a) < (__b)) | ||
55 | #define cputime_le(__a, __b) ((__a) <= (__b)) | ||
56 | #define cputime_to_jiffies(__ct) (__div((__ct), 1000000 / HZ)) | ||
57 | #define cputime_to_scaled(__ct) (__ct) | ||
58 | #define jiffies_to_cputime(__hz) ((cputime_t)(__hz) * (1000000 / HZ)) | ||
59 | |||
60 | #define cputime64_zero (0ULL) | ||
61 | #define cputime64_add(__a, __b) ((__a) + (__b)) | ||
62 | #define cputime_to_cputime64(__ct) (__ct) | ||
63 | |||
64 | static inline u64 | ||
65 | cputime64_to_jiffies64(cputime64_t cputime) | ||
66 | { | ||
67 | do_div(cputime, 1000000 / HZ); | ||
68 | return cputime; | ||
69 | } | ||
70 | |||
71 | /* | ||
72 | * Convert cputime to milliseconds and back. | ||
73 | */ | ||
74 | static inline unsigned int | ||
75 | cputime_to_msecs(const cputime_t cputime) | ||
76 | { | ||
77 | return __div(cputime, 1000); | ||
78 | } | ||
79 | |||
80 | static inline cputime_t | ||
81 | msecs_to_cputime(const unsigned int m) | ||
82 | { | ||
83 | return (cputime_t) m * 1000; | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * Convert cputime to milliseconds and back. | ||
88 | */ | ||
89 | static inline unsigned int | ||
90 | cputime_to_secs(const cputime_t cputime) | ||
91 | { | ||
92 | return __div(cputime, 1000000); | ||
93 | } | ||
94 | |||
95 | static inline cputime_t | ||
96 | secs_to_cputime(const unsigned int s) | ||
97 | { | ||
98 | return (cputime_t) s * 1000000; | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * Convert cputime to timespec and back. | ||
103 | */ | ||
104 | static inline cputime_t | ||
105 | timespec_to_cputime(const struct timespec *value) | ||
106 | { | ||
107 | return value->tv_nsec / 1000 + (u64) value->tv_sec * 1000000; | ||
108 | } | ||
109 | |||
110 | static inline void | ||
111 | cputime_to_timespec(const cputime_t cputime, struct timespec *value) | ||
112 | { | ||
113 | #ifndef __s390x__ | ||
114 | register_pair rp; | ||
115 | |||
116 | rp.pair = cputime >> 1; | ||
117 | asm ("dr %0,%1" : "+d" (rp) : "d" (1000000 >> 1)); | ||
118 | value->tv_nsec = rp.subreg.even * 1000; | ||
119 | value->tv_sec = rp.subreg.odd; | ||
120 | #else | ||
121 | value->tv_nsec = (cputime % 1000000) * 1000; | ||
122 | value->tv_sec = cputime / 1000000; | ||
123 | #endif | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * Convert cputime to timeval and back. | ||
128 | * Since cputime and timeval have the same resolution (microseconds) | ||
129 | * this is easy. | ||
130 | */ | ||
131 | static inline cputime_t | ||
132 | timeval_to_cputime(const struct timeval *value) | ||
133 | { | ||
134 | return value->tv_usec + (u64) value->tv_sec * 1000000; | ||
135 | } | ||
136 | |||
137 | static inline void | ||
138 | cputime_to_timeval(const cputime_t cputime, struct timeval *value) | ||
139 | { | ||
140 | #ifndef __s390x__ | ||
141 | register_pair rp; | ||
142 | |||
143 | rp.pair = cputime >> 1; | ||
144 | asm ("dr %0,%1" : "+d" (rp) : "d" (1000000 >> 1)); | ||
145 | value->tv_usec = rp.subreg.even; | ||
146 | value->tv_sec = rp.subreg.odd; | ||
147 | #else | ||
148 | value->tv_usec = cputime % 1000000; | ||
149 | value->tv_sec = cputime / 1000000; | ||
150 | #endif | ||
151 | } | ||
152 | |||
153 | /* | ||
154 | * Convert cputime to clock and back. | ||
155 | */ | ||
156 | static inline clock_t | ||
157 | cputime_to_clock_t(cputime_t cputime) | ||
158 | { | ||
159 | return __div(cputime, 1000000 / USER_HZ); | ||
160 | } | ||
161 | |||
162 | static inline cputime_t | ||
163 | clock_t_to_cputime(unsigned long x) | ||
164 | { | ||
165 | return (cputime_t) x * (1000000 / USER_HZ); | ||
166 | } | ||
167 | |||
168 | /* | ||
169 | * Convert cputime64 to clock. | ||
170 | */ | ||
171 | static inline clock_t | ||
172 | cputime64_to_clock_t(cputime64_t cputime) | ||
173 | { | ||
174 | return __div(cputime, 1000000 / USER_HZ); | ||
175 | } | ||
176 | |||
177 | #endif /* _S390_CPUTIME_H */ | ||
diff --git a/arch/s390/include/asm/current.h b/arch/s390/include/asm/current.h new file mode 100644 index 000000000000..83cf36cde2da --- /dev/null +++ b/arch/s390/include/asm/current.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * include/asm-s390/current.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
7 | * | ||
8 | * Derived from "include/asm-i386/current.h" | ||
9 | */ | ||
10 | |||
11 | #ifndef _S390_CURRENT_H | ||
12 | #define _S390_CURRENT_H | ||
13 | |||
14 | #ifdef __KERNEL__ | ||
15 | #include <asm/lowcore.h> | ||
16 | |||
17 | struct task_struct; | ||
18 | |||
19 | #define current ((struct task_struct *const)S390_lowcore.current_task) | ||
20 | |||
21 | #endif | ||
22 | |||
23 | #endif /* !(_S390_CURRENT_H) */ | ||
diff --git a/arch/s390/include/asm/dasd.h b/arch/s390/include/asm/dasd.h new file mode 100644 index 000000000000..3f002e13d024 --- /dev/null +++ b/arch/s390/include/asm/dasd.h | |||
@@ -0,0 +1,270 @@ | |||
1 | /* | ||
2 | * File...........: linux/drivers/s390/block/dasd.c | ||
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | ||
4 | * Bugreports.to..: <Linux390@de.ibm.com> | ||
5 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 | ||
6 | * | ||
7 | * This file is the interface of the DASD device driver, which is exported to user space | ||
8 | * any future changes wrt the API will result in a change of the APIVERSION reported | ||
9 | * to userspace by the DASDAPIVER-ioctl | ||
10 | * | ||
11 | */ | ||
12 | |||
13 | #ifndef DASD_H | ||
14 | #define DASD_H | ||
15 | #include <linux/ioctl.h> | ||
16 | |||
17 | #define DASD_IOCTL_LETTER 'D' | ||
18 | |||
19 | #define DASD_API_VERSION 6 | ||
20 | |||
21 | /* | ||
22 | * struct dasd_information2_t | ||
23 | * represents any data about the device, which is visible to userspace. | ||
24 | * including foramt and featueres. | ||
25 | */ | ||
26 | typedef struct dasd_information2_t { | ||
27 | unsigned int devno; /* S/390 devno */ | ||
28 | unsigned int real_devno; /* for aliases */ | ||
29 | unsigned int schid; /* S/390 subchannel identifier */ | ||
30 | unsigned int cu_type : 16; /* from SenseID */ | ||
31 | unsigned int cu_model : 8; /* from SenseID */ | ||
32 | unsigned int dev_type : 16; /* from SenseID */ | ||
33 | unsigned int dev_model : 8; /* from SenseID */ | ||
34 | unsigned int open_count; | ||
35 | unsigned int req_queue_len; | ||
36 | unsigned int chanq_len; /* length of chanq */ | ||
37 | char type[4]; /* from discipline.name, 'none' for unknown */ | ||
38 | unsigned int status; /* current device level */ | ||
39 | unsigned int label_block; /* where to find the VOLSER */ | ||
40 | unsigned int FBA_layout; /* fixed block size (like AIXVOL) */ | ||
41 | unsigned int characteristics_size; | ||
42 | unsigned int confdata_size; | ||
43 | char characteristics[64]; /* from read_device_characteristics */ | ||
44 | char configuration_data[256]; /* from read_configuration_data */ | ||
45 | unsigned int format; /* format info like formatted/cdl/ldl/... */ | ||
46 | unsigned int features; /* dasd features like 'ro',... */ | ||
47 | unsigned int reserved0; /* reserved for further use ,... */ | ||
48 | unsigned int reserved1; /* reserved for further use ,... */ | ||
49 | unsigned int reserved2; /* reserved for further use ,... */ | ||
50 | unsigned int reserved3; /* reserved for further use ,... */ | ||
51 | unsigned int reserved4; /* reserved for further use ,... */ | ||
52 | unsigned int reserved5; /* reserved for further use ,... */ | ||
53 | unsigned int reserved6; /* reserved for further use ,... */ | ||
54 | unsigned int reserved7; /* reserved for further use ,... */ | ||
55 | } dasd_information2_t; | ||
56 | |||
57 | /* | ||
58 | * values to be used for dasd_information_t.format | ||
59 | * 0x00: NOT formatted | ||
60 | * 0x01: Linux disc layout | ||
61 | * 0x02: Common disc layout | ||
62 | */ | ||
63 | #define DASD_FORMAT_NONE 0 | ||
64 | #define DASD_FORMAT_LDL 1 | ||
65 | #define DASD_FORMAT_CDL 2 | ||
66 | /* | ||
67 | * values to be used for dasd_information_t.features | ||
68 | * 0x00: default features | ||
69 | * 0x01: readonly (ro) | ||
70 | * 0x02: use diag discipline (diag) | ||
71 | * 0x04: set the device initially online (internal use only) | ||
72 | * 0x08: enable ERP related logging | ||
73 | */ | ||
74 | #define DASD_FEATURE_DEFAULT 0x00 | ||
75 | #define DASD_FEATURE_READONLY 0x01 | ||
76 | #define DASD_FEATURE_USEDIAG 0x02 | ||
77 | #define DASD_FEATURE_INITIAL_ONLINE 0x04 | ||
78 | #define DASD_FEATURE_ERPLOG 0x08 | ||
79 | |||
80 | #define DASD_PARTN_BITS 2 | ||
81 | |||
82 | /* | ||
83 | * struct dasd_information_t | ||
84 | * represents any data about the data, which is visible to userspace | ||
85 | */ | ||
86 | typedef struct dasd_information_t { | ||
87 | unsigned int devno; /* S/390 devno */ | ||
88 | unsigned int real_devno; /* for aliases */ | ||
89 | unsigned int schid; /* S/390 subchannel identifier */ | ||
90 | unsigned int cu_type : 16; /* from SenseID */ | ||
91 | unsigned int cu_model : 8; /* from SenseID */ | ||
92 | unsigned int dev_type : 16; /* from SenseID */ | ||
93 | unsigned int dev_model : 8; /* from SenseID */ | ||
94 | unsigned int open_count; | ||
95 | unsigned int req_queue_len; | ||
96 | unsigned int chanq_len; /* length of chanq */ | ||
97 | char type[4]; /* from discipline.name, 'none' for unknown */ | ||
98 | unsigned int status; /* current device level */ | ||
99 | unsigned int label_block; /* where to find the VOLSER */ | ||
100 | unsigned int FBA_layout; /* fixed block size (like AIXVOL) */ | ||
101 | unsigned int characteristics_size; | ||
102 | unsigned int confdata_size; | ||
103 | char characteristics[64]; /* from read_device_characteristics */ | ||
104 | char configuration_data[256]; /* from read_configuration_data */ | ||
105 | } dasd_information_t; | ||
106 | |||
107 | /* | ||
108 | * Read Subsystem Data - Performance Statistics | ||
109 | */ | ||
110 | typedef struct dasd_rssd_perf_stats_t { | ||
111 | unsigned char invalid:1; | ||
112 | unsigned char format:3; | ||
113 | unsigned char data_format:4; | ||
114 | unsigned char unit_address; | ||
115 | unsigned short device_status; | ||
116 | unsigned int nr_read_normal; | ||
117 | unsigned int nr_read_normal_hits; | ||
118 | unsigned int nr_write_normal; | ||
119 | unsigned int nr_write_fast_normal_hits; | ||
120 | unsigned int nr_read_seq; | ||
121 | unsigned int nr_read_seq_hits; | ||
122 | unsigned int nr_write_seq; | ||
123 | unsigned int nr_write_fast_seq_hits; | ||
124 | unsigned int nr_read_cache; | ||
125 | unsigned int nr_read_cache_hits; | ||
126 | unsigned int nr_write_cache; | ||
127 | unsigned int nr_write_fast_cache_hits; | ||
128 | unsigned int nr_inhibit_cache; | ||
129 | unsigned int nr_bybass_cache; | ||
130 | unsigned int nr_seq_dasd_to_cache; | ||
131 | unsigned int nr_dasd_to_cache; | ||
132 | unsigned int nr_cache_to_dasd; | ||
133 | unsigned int nr_delayed_fast_write; | ||
134 | unsigned int nr_normal_fast_write; | ||
135 | unsigned int nr_seq_fast_write; | ||
136 | unsigned int nr_cache_miss; | ||
137 | unsigned char status2; | ||
138 | unsigned int nr_quick_write_promotes; | ||
139 | unsigned char reserved; | ||
140 | unsigned short ssid; | ||
141 | unsigned char reseved2[96]; | ||
142 | } __attribute__((packed)) dasd_rssd_perf_stats_t; | ||
143 | |||
144 | /* | ||
145 | * struct profile_info_t | ||
146 | * holds the profinling information | ||
147 | */ | ||
148 | typedef struct dasd_profile_info_t { | ||
149 | unsigned int dasd_io_reqs; /* number of requests processed at all */ | ||
150 | unsigned int dasd_io_sects; /* number of sectors processed at all */ | ||
151 | unsigned int dasd_io_secs[32]; /* histogram of request's sizes */ | ||
152 | unsigned int dasd_io_times[32]; /* histogram of requests's times */ | ||
153 | unsigned int dasd_io_timps[32]; /* histogram of requests's times per sector */ | ||
154 | unsigned int dasd_io_time1[32]; /* histogram of time from build to start */ | ||
155 | unsigned int dasd_io_time2[32]; /* histogram of time from start to irq */ | ||
156 | unsigned int dasd_io_time2ps[32]; /* histogram of time from start to irq */ | ||
157 | unsigned int dasd_io_time3[32]; /* histogram of time from irq to end */ | ||
158 | unsigned int dasd_io_nr_req[32]; /* histogram of # of requests in chanq */ | ||
159 | } dasd_profile_info_t; | ||
160 | |||
161 | /* | ||
162 | * struct format_data_t | ||
163 | * represents all data necessary to format a dasd | ||
164 | */ | ||
165 | typedef struct format_data_t { | ||
166 | int start_unit; /* from track */ | ||
167 | int stop_unit; /* to track */ | ||
168 | int blksize; /* sectorsize */ | ||
169 | int intensity; | ||
170 | } format_data_t; | ||
171 | |||
172 | /* | ||
173 | * values to be used for format_data_t.intensity | ||
174 | * 0/8: normal format | ||
175 | * 1/9: also write record zero | ||
176 | * 3/11: also write home address | ||
177 | * 4/12: invalidate track | ||
178 | */ | ||
179 | #define DASD_FMT_INT_FMT_R0 1 /* write record zero */ | ||
180 | #define DASD_FMT_INT_FMT_HA 2 /* write home address, also set FMT_R0 ! */ | ||
181 | #define DASD_FMT_INT_INVAL 4 /* invalidate tracks */ | ||
182 | #define DASD_FMT_INT_COMPAT 8 /* use OS/390 compatible disk layout */ | ||
183 | |||
184 | |||
185 | /* | ||
186 | * struct attrib_data_t | ||
187 | * represents the operation (cache) bits for the device. | ||
188 | * Used in DE to influence caching of the DASD. | ||
189 | */ | ||
190 | typedef struct attrib_data_t { | ||
191 | unsigned char operation:3; /* cache operation mode */ | ||
192 | unsigned char reserved:5; /* cache operation mode */ | ||
193 | __u16 nr_cyl; /* no of cyliners for read ahaed */ | ||
194 | __u8 reserved2[29]; /* for future use */ | ||
195 | } __attribute__ ((packed)) attrib_data_t; | ||
196 | |||
197 | /* definition of operation (cache) bits within attributes of DE */ | ||
198 | #define DASD_NORMAL_CACHE 0x0 | ||
199 | #define DASD_BYPASS_CACHE 0x1 | ||
200 | #define DASD_INHIBIT_LOAD 0x2 | ||
201 | #define DASD_SEQ_ACCESS 0x3 | ||
202 | #define DASD_SEQ_PRESTAGE 0x4 | ||
203 | #define DASD_REC_ACCESS 0x5 | ||
204 | |||
205 | |||
206 | /******************************************************************************** | ||
207 | * SECTION: Definition of IOCTLs | ||
208 | * | ||
209 | * Here ist how the ioctl-nr should be used: | ||
210 | * 0 - 31 DASD driver itself | ||
211 | * 32 - 239 still open | ||
212 | * 240 - 255 reserved for EMC | ||
213 | *******************************************************************************/ | ||
214 | |||
215 | /* Disable the volume (for Linux) */ | ||
216 | #define BIODASDDISABLE _IO(DASD_IOCTL_LETTER,0) | ||
217 | /* Enable the volume (for Linux) */ | ||
218 | #define BIODASDENABLE _IO(DASD_IOCTL_LETTER,1) | ||
219 | /* Issue a reserve/release command, rsp. */ | ||
220 | #define BIODASDRSRV _IO(DASD_IOCTL_LETTER,2) /* reserve */ | ||
221 | #define BIODASDRLSE _IO(DASD_IOCTL_LETTER,3) /* release */ | ||
222 | #define BIODASDSLCK _IO(DASD_IOCTL_LETTER,4) /* steal lock */ | ||
223 | /* reset profiling information of a device */ | ||
224 | #define BIODASDPRRST _IO(DASD_IOCTL_LETTER,5) | ||
225 | /* Quiesce IO on device */ | ||
226 | #define BIODASDQUIESCE _IO(DASD_IOCTL_LETTER,6) | ||
227 | /* Resume IO on device */ | ||
228 | #define BIODASDRESUME _IO(DASD_IOCTL_LETTER,7) | ||
229 | |||
230 | |||
231 | /* retrieve API version number */ | ||
232 | #define DASDAPIVER _IOR(DASD_IOCTL_LETTER,0,int) | ||
233 | /* Get information on a dasd device */ | ||
234 | #define BIODASDINFO _IOR(DASD_IOCTL_LETTER,1,dasd_information_t) | ||
235 | /* retrieve profiling information of a device */ | ||
236 | #define BIODASDPRRD _IOR(DASD_IOCTL_LETTER,2,dasd_profile_info_t) | ||
237 | /* Get information on a dasd device (enhanced) */ | ||
238 | #define BIODASDINFO2 _IOR(DASD_IOCTL_LETTER,3,dasd_information2_t) | ||
239 | /* Performance Statistics Read */ | ||
240 | #define BIODASDPSRD _IOR(DASD_IOCTL_LETTER,4,dasd_rssd_perf_stats_t) | ||
241 | /* Get Attributes (cache operations) */ | ||
242 | #define BIODASDGATTR _IOR(DASD_IOCTL_LETTER,5,attrib_data_t) | ||
243 | |||
244 | |||
245 | /* #define BIODASDFORMAT _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */ | ||
246 | #define BIODASDFMT _IOW(DASD_IOCTL_LETTER,1,format_data_t) | ||
247 | /* Set Attributes (cache operations) */ | ||
248 | #define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t) | ||
249 | |||
250 | |||
251 | #endif /* DASD_H */ | ||
252 | |||
253 | /* | ||
254 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
255 | * Emacs will notice this stuff at the end of the file and automatically | ||
256 | * adjust the settings for this buffer only. This must remain at the end | ||
257 | * of the file. | ||
258 | * --------------------------------------------------------------------------- | ||
259 | * Local variables: | ||
260 | * c-indent-level: 4 | ||
261 | * c-brace-imaginary-offset: 0 | ||
262 | * c-brace-offset: -4 | ||
263 | * c-argdecl-indent: 4 | ||
264 | * c-label-offset: -4 | ||
265 | * c-continued-statement-offset: 4 | ||
266 | * c-continued-brace-offset: 0 | ||
267 | * indent-tabs-mode: nil | ||
268 | * tab-width: 8 | ||
269 | * End: | ||
270 | */ | ||
diff --git a/arch/s390/include/asm/debug.h b/arch/s390/include/asm/debug.h new file mode 100644 index 000000000000..9450ce6e32de --- /dev/null +++ b/arch/s390/include/asm/debug.h | |||
@@ -0,0 +1,261 @@ | |||
1 | /* | ||
2 | * include/asm-s390/debug.h | ||
3 | * S/390 debug facility | ||
4 | * | ||
5 | * Copyright (C) 1999, 2000 IBM Deutschland Entwicklung GmbH, | ||
6 | * IBM Corporation | ||
7 | */ | ||
8 | |||
9 | #ifndef DEBUG_H | ||
10 | #define DEBUG_H | ||
11 | |||
12 | #include <linux/fs.h> | ||
13 | |||
14 | /* Note: | ||
15 | * struct __debug_entry must be defined outside of #ifdef __KERNEL__ | ||
16 | * in order to allow a user program to analyze the 'raw'-view. | ||
17 | */ | ||
18 | |||
19 | struct __debug_entry{ | ||
20 | union { | ||
21 | struct { | ||
22 | unsigned long long clock:52; | ||
23 | unsigned long long exception:1; | ||
24 | unsigned long long level:3; | ||
25 | unsigned long long cpuid:8; | ||
26 | } fields; | ||
27 | |||
28 | unsigned long long stck; | ||
29 | } id; | ||
30 | void* caller; | ||
31 | } __attribute__((packed)); | ||
32 | |||
33 | |||
34 | #define __DEBUG_FEATURE_VERSION 2 /* version of debug feature */ | ||
35 | |||
36 | #ifdef __KERNEL__ | ||
37 | #include <linux/string.h> | ||
38 | #include <linux/spinlock.h> | ||
39 | #include <linux/kernel.h> | ||
40 | #include <linux/time.h> | ||
41 | |||
42 | #define DEBUG_MAX_LEVEL 6 /* debug levels range from 0 to 6 */ | ||
43 | #define DEBUG_OFF_LEVEL -1 /* level where debug is switched off */ | ||
44 | #define DEBUG_FLUSH_ALL -1 /* parameter to flush all areas */ | ||
45 | #define DEBUG_MAX_VIEWS 10 /* max number of views in proc fs */ | ||
46 | #define DEBUG_MAX_NAME_LEN 64 /* max length for a debugfs file name */ | ||
47 | #define DEBUG_DEFAULT_LEVEL 3 /* initial debug level */ | ||
48 | |||
49 | #define DEBUG_DIR_ROOT "s390dbf" /* name of debug root directory in proc fs */ | ||
50 | |||
51 | #define DEBUG_DATA(entry) (char*)(entry + 1) /* data is stored behind */ | ||
52 | /* the entry information */ | ||
53 | |||
54 | typedef struct __debug_entry debug_entry_t; | ||
55 | |||
56 | struct debug_view; | ||
57 | |||
58 | typedef struct debug_info { | ||
59 | struct debug_info* next; | ||
60 | struct debug_info* prev; | ||
61 | atomic_t ref_count; | ||
62 | spinlock_t lock; | ||
63 | int level; | ||
64 | int nr_areas; | ||
65 | int pages_per_area; | ||
66 | int buf_size; | ||
67 | int entry_size; | ||
68 | debug_entry_t*** areas; | ||
69 | int active_area; | ||
70 | int *active_pages; | ||
71 | int *active_entries; | ||
72 | struct dentry* debugfs_root_entry; | ||
73 | struct dentry* debugfs_entries[DEBUG_MAX_VIEWS]; | ||
74 | struct debug_view* views[DEBUG_MAX_VIEWS]; | ||
75 | char name[DEBUG_MAX_NAME_LEN]; | ||
76 | mode_t mode; | ||
77 | } debug_info_t; | ||
78 | |||
79 | typedef int (debug_header_proc_t) (debug_info_t* id, | ||
80 | struct debug_view* view, | ||
81 | int area, | ||
82 | debug_entry_t* entry, | ||
83 | char* out_buf); | ||
84 | |||
85 | typedef int (debug_format_proc_t) (debug_info_t* id, | ||
86 | struct debug_view* view, char* out_buf, | ||
87 | const char* in_buf); | ||
88 | typedef int (debug_prolog_proc_t) (debug_info_t* id, | ||
89 | struct debug_view* view, | ||
90 | char* out_buf); | ||
91 | typedef int (debug_input_proc_t) (debug_info_t* id, | ||
92 | struct debug_view* view, | ||
93 | struct file* file, | ||
94 | const char __user *user_buf, | ||
95 | size_t in_buf_size, loff_t* offset); | ||
96 | |||
97 | int debug_dflt_header_fn(debug_info_t* id, struct debug_view* view, | ||
98 | int area, debug_entry_t* entry, char* out_buf); | ||
99 | |||
100 | struct debug_view { | ||
101 | char name[DEBUG_MAX_NAME_LEN]; | ||
102 | debug_prolog_proc_t* prolog_proc; | ||
103 | debug_header_proc_t* header_proc; | ||
104 | debug_format_proc_t* format_proc; | ||
105 | debug_input_proc_t* input_proc; | ||
106 | void* private_data; | ||
107 | }; | ||
108 | |||
109 | extern struct debug_view debug_hex_ascii_view; | ||
110 | extern struct debug_view debug_raw_view; | ||
111 | extern struct debug_view debug_sprintf_view; | ||
112 | |||
113 | /* do NOT use the _common functions */ | ||
114 | |||
115 | debug_entry_t* debug_event_common(debug_info_t* id, int level, | ||
116 | const void* data, int length); | ||
117 | |||
118 | debug_entry_t* debug_exception_common(debug_info_t* id, int level, | ||
119 | const void* data, int length); | ||
120 | |||
121 | /* Debug Feature API: */ | ||
122 | |||
123 | debug_info_t *debug_register(const char *name, int pages, int nr_areas, | ||
124 | int buf_size); | ||
125 | |||
126 | debug_info_t *debug_register_mode(const char *name, int pages, int nr_areas, | ||
127 | int buf_size, mode_t mode, uid_t uid, | ||
128 | gid_t gid); | ||
129 | |||
130 | void debug_unregister(debug_info_t* id); | ||
131 | |||
132 | void debug_set_level(debug_info_t* id, int new_level); | ||
133 | |||
134 | void debug_stop_all(void); | ||
135 | |||
136 | static inline debug_entry_t* | ||
137 | debug_event(debug_info_t* id, int level, void* data, int length) | ||
138 | { | ||
139 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) | ||
140 | return NULL; | ||
141 | return debug_event_common(id,level,data,length); | ||
142 | } | ||
143 | |||
144 | static inline debug_entry_t* | ||
145 | debug_int_event(debug_info_t* id, int level, unsigned int tag) | ||
146 | { | ||
147 | unsigned int t=tag; | ||
148 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) | ||
149 | return NULL; | ||
150 | return debug_event_common(id,level,&t,sizeof(unsigned int)); | ||
151 | } | ||
152 | |||
153 | static inline debug_entry_t * | ||
154 | debug_long_event (debug_info_t* id, int level, unsigned long tag) | ||
155 | { | ||
156 | unsigned long t=tag; | ||
157 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) | ||
158 | return NULL; | ||
159 | return debug_event_common(id,level,&t,sizeof(unsigned long)); | ||
160 | } | ||
161 | |||
162 | static inline debug_entry_t* | ||
163 | debug_text_event(debug_info_t* id, int level, const char* txt) | ||
164 | { | ||
165 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) | ||
166 | return NULL; | ||
167 | return debug_event_common(id,level,txt,strlen(txt)); | ||
168 | } | ||
169 | |||
170 | extern debug_entry_t * | ||
171 | debug_sprintf_event(debug_info_t* id,int level,char *string,...) | ||
172 | __attribute__ ((format(printf, 3, 4))); | ||
173 | |||
174 | |||
175 | static inline debug_entry_t* | ||
176 | debug_exception(debug_info_t* id, int level, void* data, int length) | ||
177 | { | ||
178 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) | ||
179 | return NULL; | ||
180 | return debug_exception_common(id,level,data,length); | ||
181 | } | ||
182 | |||
183 | static inline debug_entry_t* | ||
184 | debug_int_exception(debug_info_t* id, int level, unsigned int tag) | ||
185 | { | ||
186 | unsigned int t=tag; | ||
187 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) | ||
188 | return NULL; | ||
189 | return debug_exception_common(id,level,&t,sizeof(unsigned int)); | ||
190 | } | ||
191 | |||
192 | static inline debug_entry_t * | ||
193 | debug_long_exception (debug_info_t* id, int level, unsigned long tag) | ||
194 | { | ||
195 | unsigned long t=tag; | ||
196 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) | ||
197 | return NULL; | ||
198 | return debug_exception_common(id,level,&t,sizeof(unsigned long)); | ||
199 | } | ||
200 | |||
201 | static inline debug_entry_t* | ||
202 | debug_text_exception(debug_info_t* id, int level, const char* txt) | ||
203 | { | ||
204 | if ((!id) || (level > id->level) || (id->pages_per_area == 0)) | ||
205 | return NULL; | ||
206 | return debug_exception_common(id,level,txt,strlen(txt)); | ||
207 | } | ||
208 | |||
209 | |||
210 | extern debug_entry_t * | ||
211 | debug_sprintf_exception(debug_info_t* id,int level,char *string,...) | ||
212 | __attribute__ ((format(printf, 3, 4))); | ||
213 | |||
214 | int debug_register_view(debug_info_t* id, struct debug_view* view); | ||
215 | int debug_unregister_view(debug_info_t* id, struct debug_view* view); | ||
216 | |||
217 | /* | ||
218 | define the debug levels: | ||
219 | - 0 No debugging output to console or syslog | ||
220 | - 1 Log internal errors to syslog, ignore check conditions | ||
221 | - 2 Log internal errors and check conditions to syslog | ||
222 | - 3 Log internal errors to console, log check conditions to syslog | ||
223 | - 4 Log internal errors and check conditions to console | ||
224 | - 5 panic on internal errors, log check conditions to console | ||
225 | - 6 panic on both, internal errors and check conditions | ||
226 | */ | ||
227 | |||
228 | #ifndef DEBUG_LEVEL | ||
229 | #define DEBUG_LEVEL 4 | ||
230 | #endif | ||
231 | |||
232 | #define INTERNAL_ERRMSG(x,y...) "E" __FILE__ "%d: " x, __LINE__, y | ||
233 | #define INTERNAL_WRNMSG(x,y...) "W" __FILE__ "%d: " x, __LINE__, y | ||
234 | #define INTERNAL_INFMSG(x,y...) "I" __FILE__ "%d: " x, __LINE__, y | ||
235 | #define INTERNAL_DEBMSG(x,y...) "D" __FILE__ "%d: " x, __LINE__, y | ||
236 | |||
237 | #if DEBUG_LEVEL > 0 | ||
238 | #define PRINT_DEBUG(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | ||
239 | #define PRINT_INFO(x...) printk ( KERN_INFO PRINTK_HEADER x ) | ||
240 | #define PRINT_WARN(x...) printk ( KERN_WARNING PRINTK_HEADER x ) | ||
241 | #define PRINT_ERR(x...) printk ( KERN_ERR PRINTK_HEADER x ) | ||
242 | #define PRINT_FATAL(x...) panic ( PRINTK_HEADER x ) | ||
243 | #else | ||
244 | #define PRINT_DEBUG(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | ||
245 | #define PRINT_INFO(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | ||
246 | #define PRINT_WARN(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | ||
247 | #define PRINT_ERR(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | ||
248 | #define PRINT_FATAL(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | ||
249 | #endif /* DASD_DEBUG */ | ||
250 | |||
251 | #undef DEBUG_MALLOC | ||
252 | #ifdef DEBUG_MALLOC | ||
253 | void *b; | ||
254 | #define kmalloc(x...) (PRINT_INFO(" kmalloc %p\n",b=kmalloc(x)),b) | ||
255 | #define kfree(x) PRINT_INFO(" kfree %p\n",x);kfree(x) | ||
256 | #define get_zeroed_page(x...) (PRINT_INFO(" gfp %p\n",b=get_zeroed_page(x)),b) | ||
257 | #define __get_free_pages(x...) (PRINT_INFO(" gfps %p\n",b=__get_free_pages(x)),b) | ||
258 | #endif /* DEBUG_MALLOC */ | ||
259 | |||
260 | #endif /* __KERNEL__ */ | ||
261 | #endif /* DEBUG_H */ | ||
diff --git a/arch/s390/include/asm/delay.h b/arch/s390/include/asm/delay.h new file mode 100644 index 000000000000..78357314c450 --- /dev/null +++ b/arch/s390/include/asm/delay.h | |||
@@ -0,0 +1,22 @@ | |||
1 | /* | ||
2 | * include/asm-s390/delay.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
7 | * | ||
8 | * Derived from "include/asm-i386/delay.h" | ||
9 | * Copyright (C) 1993 Linus Torvalds | ||
10 | * | ||
11 | * Delay routines calling functions in arch/s390/lib/delay.c | ||
12 | */ | ||
13 | |||
14 | #ifndef _S390_DELAY_H | ||
15 | #define _S390_DELAY_H | ||
16 | |||
17 | extern void __udelay(unsigned long usecs); | ||
18 | extern void __delay(unsigned long loops); | ||
19 | |||
20 | #define udelay(n) __udelay(n) | ||
21 | |||
22 | #endif /* defined(_S390_DELAY_H) */ | ||
diff --git a/arch/s390/include/asm/device.h b/arch/s390/include/asm/device.h new file mode 100644 index 000000000000..d8f9872b0e2d --- /dev/null +++ b/arch/s390/include/asm/device.h | |||
@@ -0,0 +1,7 @@ | |||
1 | /* | ||
2 | * Arch specific extensions to struct device | ||
3 | * | ||
4 | * This file is released under the GPLv2 | ||
5 | */ | ||
6 | #include <asm-generic/device.h> | ||
7 | |||
diff --git a/arch/s390/include/asm/diag.h b/arch/s390/include/asm/diag.h new file mode 100644 index 000000000000..72b2e2f2d32d --- /dev/null +++ b/arch/s390/include/asm/diag.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /* | ||
2 | * s390 diagnose functions | ||
3 | * | ||
4 | * Copyright IBM Corp. 2007 | ||
5 | * Author(s): Michael Holzheu <holzheu@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_S390_DIAG_H | ||
9 | #define _ASM_S390_DIAG_H | ||
10 | |||
11 | /* | ||
12 | * Diagnose 10: Release pages | ||
13 | */ | ||
14 | extern void diag10(unsigned long addr); | ||
15 | |||
16 | /* | ||
17 | * Diagnose 14: Input spool file manipulation | ||
18 | */ | ||
19 | extern int diag14(unsigned long rx, unsigned long ry1, unsigned long subcode); | ||
20 | |||
21 | /* | ||
22 | * Diagnose 210: Get information about a virtual device | ||
23 | */ | ||
24 | struct diag210 { | ||
25 | u16 vrdcdvno; /* device number (input) */ | ||
26 | u16 vrdclen; /* data block length (input) */ | ||
27 | u8 vrdcvcla; /* virtual device class (output) */ | ||
28 | u8 vrdcvtyp; /* virtual device type (output) */ | ||
29 | u8 vrdcvsta; /* virtual device status (output) */ | ||
30 | u8 vrdcvfla; /* virtual device flags (output) */ | ||
31 | u8 vrdcrccl; /* real device class (output) */ | ||
32 | u8 vrdccrty; /* real device type (output) */ | ||
33 | u8 vrdccrmd; /* real device model (output) */ | ||
34 | u8 vrdccrft; /* real device feature (output) */ | ||
35 | } __attribute__((packed, aligned(4))); | ||
36 | |||
37 | extern int diag210(struct diag210 *addr); | ||
38 | |||
39 | #endif /* _ASM_S390_DIAG_H */ | ||
diff --git a/arch/s390/include/asm/div64.h b/arch/s390/include/asm/div64.h new file mode 100644 index 000000000000..6cd978cefb28 --- /dev/null +++ b/arch/s390/include/asm/div64.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/div64.h> | |||
diff --git a/arch/s390/include/asm/dma.h b/arch/s390/include/asm/dma.h new file mode 100644 index 000000000000..7425c6af6cd4 --- /dev/null +++ b/arch/s390/include/asm/dma.h | |||
@@ -0,0 +1,16 @@ | |||
1 | /* | ||
2 | * include/asm-s390/dma.h | ||
3 | * | ||
4 | * S390 version | ||
5 | */ | ||
6 | |||
7 | #ifndef _ASM_DMA_H | ||
8 | #define _ASM_DMA_H | ||
9 | |||
10 | #include <asm/io.h> /* need byte IO */ | ||
11 | |||
12 | #define MAX_DMA_ADDRESS 0x80000000 | ||
13 | |||
14 | #define free_dma(x) do { } while (0) | ||
15 | |||
16 | #endif /* _ASM_DMA_H */ | ||
diff --git a/arch/s390/include/asm/ebcdic.h b/arch/s390/include/asm/ebcdic.h new file mode 100644 index 000000000000..7f6f641d32f4 --- /dev/null +++ b/arch/s390/include/asm/ebcdic.h | |||
@@ -0,0 +1,49 @@ | |||
1 | /* | ||
2 | * include/asm-s390/ebcdic.h | ||
3 | * EBCDIC -> ASCII, ASCII -> EBCDIC conversion routines. | ||
4 | * | ||
5 | * S390 version | ||
6 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
7 | * Author(s): Martin Schwidefsky <schwidefsky@de.ibm.com> | ||
8 | */ | ||
9 | |||
10 | #ifndef _EBCDIC_H | ||
11 | #define _EBCDIC_H | ||
12 | |||
13 | #ifndef _S390_TYPES_H | ||
14 | #include <types.h> | ||
15 | #endif | ||
16 | |||
17 | extern __u8 _ascebc_500[256]; /* ASCII -> EBCDIC 500 conversion table */ | ||
18 | extern __u8 _ebcasc_500[256]; /* EBCDIC 500 -> ASCII conversion table */ | ||
19 | extern __u8 _ascebc[256]; /* ASCII -> EBCDIC conversion table */ | ||
20 | extern __u8 _ebcasc[256]; /* EBCDIC -> ASCII conversion table */ | ||
21 | extern __u8 _ebc_tolower[256]; /* EBCDIC -> lowercase */ | ||
22 | extern __u8 _ebc_toupper[256]; /* EBCDIC -> uppercase */ | ||
23 | |||
24 | static inline void | ||
25 | codepage_convert(const __u8 *codepage, volatile __u8 * addr, unsigned long nr) | ||
26 | { | ||
27 | if (nr-- <= 0) | ||
28 | return; | ||
29 | asm volatile( | ||
30 | " bras 1,1f\n" | ||
31 | " tr 0(1,%0),0(%2)\n" | ||
32 | "0: tr 0(256,%0),0(%2)\n" | ||
33 | " la %0,256(%0)\n" | ||
34 | "1: ahi %1,-256\n" | ||
35 | " jnm 0b\n" | ||
36 | " ex %1,0(1)" | ||
37 | : "+&a" (addr), "+&a" (nr) | ||
38 | : "a" (codepage) : "cc", "memory", "1"); | ||
39 | } | ||
40 | |||
41 | #define ASCEBC(addr,nr) codepage_convert(_ascebc, addr, nr) | ||
42 | #define EBCASC(addr,nr) codepage_convert(_ebcasc, addr, nr) | ||
43 | #define ASCEBC_500(addr,nr) codepage_convert(_ascebc_500, addr, nr) | ||
44 | #define EBCASC_500(addr,nr) codepage_convert(_ebcasc_500, addr, nr) | ||
45 | #define EBC_TOLOWER(addr,nr) codepage_convert(_ebc_tolower, addr, nr) | ||
46 | #define EBC_TOUPPER(addr,nr) codepage_convert(_ebc_toupper, addr, nr) | ||
47 | |||
48 | #endif | ||
49 | |||
diff --git a/arch/s390/include/asm/elf.h b/arch/s390/include/asm/elf.h new file mode 100644 index 000000000000..3cad56923815 --- /dev/null +++ b/arch/s390/include/asm/elf.h | |||
@@ -0,0 +1,196 @@ | |||
1 | /* | ||
2 | * include/asm-s390/elf.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/elf.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef __ASMS390_ELF_H | ||
10 | #define __ASMS390_ELF_H | ||
11 | |||
12 | /* s390 relocations defined by the ABIs */ | ||
13 | #define R_390_NONE 0 /* No reloc. */ | ||
14 | #define R_390_8 1 /* Direct 8 bit. */ | ||
15 | #define R_390_12 2 /* Direct 12 bit. */ | ||
16 | #define R_390_16 3 /* Direct 16 bit. */ | ||
17 | #define R_390_32 4 /* Direct 32 bit. */ | ||
18 | #define R_390_PC32 5 /* PC relative 32 bit. */ | ||
19 | #define R_390_GOT12 6 /* 12 bit GOT offset. */ | ||
20 | #define R_390_GOT32 7 /* 32 bit GOT offset. */ | ||
21 | #define R_390_PLT32 8 /* 32 bit PC relative PLT address. */ | ||
22 | #define R_390_COPY 9 /* Copy symbol at runtime. */ | ||
23 | #define R_390_GLOB_DAT 10 /* Create GOT entry. */ | ||
24 | #define R_390_JMP_SLOT 11 /* Create PLT entry. */ | ||
25 | #define R_390_RELATIVE 12 /* Adjust by program base. */ | ||
26 | #define R_390_GOTOFF32 13 /* 32 bit offset to GOT. */ | ||
27 | #define R_390_GOTPC 14 /* 32 bit PC rel. offset to GOT. */ | ||
28 | #define R_390_GOT16 15 /* 16 bit GOT offset. */ | ||
29 | #define R_390_PC16 16 /* PC relative 16 bit. */ | ||
30 | #define R_390_PC16DBL 17 /* PC relative 16 bit shifted by 1. */ | ||
31 | #define R_390_PLT16DBL 18 /* 16 bit PC rel. PLT shifted by 1. */ | ||
32 | #define R_390_PC32DBL 19 /* PC relative 32 bit shifted by 1. */ | ||
33 | #define R_390_PLT32DBL 20 /* 32 bit PC rel. PLT shifted by 1. */ | ||
34 | #define R_390_GOTPCDBL 21 /* 32 bit PC rel. GOT shifted by 1. */ | ||
35 | #define R_390_64 22 /* Direct 64 bit. */ | ||
36 | #define R_390_PC64 23 /* PC relative 64 bit. */ | ||
37 | #define R_390_GOT64 24 /* 64 bit GOT offset. */ | ||
38 | #define R_390_PLT64 25 /* 64 bit PC relative PLT address. */ | ||
39 | #define R_390_GOTENT 26 /* 32 bit PC rel. to GOT entry >> 1. */ | ||
40 | #define R_390_GOTOFF16 27 /* 16 bit offset to GOT. */ | ||
41 | #define R_390_GOTOFF64 28 /* 64 bit offset to GOT. */ | ||
42 | #define R_390_GOTPLT12 29 /* 12 bit offset to jump slot. */ | ||
43 | #define R_390_GOTPLT16 30 /* 16 bit offset to jump slot. */ | ||
44 | #define R_390_GOTPLT32 31 /* 32 bit offset to jump slot. */ | ||
45 | #define R_390_GOTPLT64 32 /* 64 bit offset to jump slot. */ | ||
46 | #define R_390_GOTPLTENT 33 /* 32 bit rel. offset to jump slot. */ | ||
47 | #define R_390_PLTOFF16 34 /* 16 bit offset from GOT to PLT. */ | ||
48 | #define R_390_PLTOFF32 35 /* 32 bit offset from GOT to PLT. */ | ||
49 | #define R_390_PLTOFF64 36 /* 16 bit offset from GOT to PLT. */ | ||
50 | #define R_390_TLS_LOAD 37 /* Tag for load insn in TLS code. */ | ||
51 | #define R_390_TLS_GDCALL 38 /* Tag for function call in general | ||
52 | dynamic TLS code. */ | ||
53 | #define R_390_TLS_LDCALL 39 /* Tag for function call in local | ||
54 | dynamic TLS code. */ | ||
55 | #define R_390_TLS_GD32 40 /* Direct 32 bit for general dynamic | ||
56 | thread local data. */ | ||
57 | #define R_390_TLS_GD64 41 /* Direct 64 bit for general dynamic | ||
58 | thread local data. */ | ||
59 | #define R_390_TLS_GOTIE12 42 /* 12 bit GOT offset for static TLS | ||
60 | block offset. */ | ||
61 | #define R_390_TLS_GOTIE32 43 /* 32 bit GOT offset for static TLS | ||
62 | block offset. */ | ||
63 | #define R_390_TLS_GOTIE64 44 /* 64 bit GOT offset for static TLS | ||
64 | block offset. */ | ||
65 | #define R_390_TLS_LDM32 45 /* Direct 32 bit for local dynamic | ||
66 | thread local data in LD code. */ | ||
67 | #define R_390_TLS_LDM64 46 /* Direct 64 bit for local dynamic | ||
68 | thread local data in LD code. */ | ||
69 | #define R_390_TLS_IE32 47 /* 32 bit address of GOT entry for | ||
70 | negated static TLS block offset. */ | ||
71 | #define R_390_TLS_IE64 48 /* 64 bit address of GOT entry for | ||
72 | negated static TLS block offset. */ | ||
73 | #define R_390_TLS_IEENT 49 /* 32 bit rel. offset to GOT entry for | ||
74 | negated static TLS block offset. */ | ||
75 | #define R_390_TLS_LE32 50 /* 32 bit negated offset relative to | ||
76 | static TLS block. */ | ||
77 | #define R_390_TLS_LE64 51 /* 64 bit negated offset relative to | ||
78 | static TLS block. */ | ||
79 | #define R_390_TLS_LDO32 52 /* 32 bit offset relative to TLS | ||
80 | block. */ | ||
81 | #define R_390_TLS_LDO64 53 /* 64 bit offset relative to TLS | ||
82 | block. */ | ||
83 | #define R_390_TLS_DTPMOD 54 /* ID of module containing symbol. */ | ||
84 | #define R_390_TLS_DTPOFF 55 /* Offset in TLS block. */ | ||
85 | #define R_390_TLS_TPOFF 56 /* Negate offset in static TLS | ||
86 | block. */ | ||
87 | #define R_390_20 57 /* Direct 20 bit. */ | ||
88 | #define R_390_GOT20 58 /* 20 bit GOT offset. */ | ||
89 | #define R_390_GOTPLT20 59 /* 20 bit offset to jump slot. */ | ||
90 | #define R_390_TLS_GOTIE20 60 /* 20 bit GOT offset for static TLS | ||
91 | block offset. */ | ||
92 | /* Keep this the last entry. */ | ||
93 | #define R_390_NUM 61 | ||
94 | |||
95 | /* | ||
96 | * These are used to set parameters in the core dumps. | ||
97 | */ | ||
98 | #ifndef __s390x__ | ||
99 | #define ELF_CLASS ELFCLASS32 | ||
100 | #else /* __s390x__ */ | ||
101 | #define ELF_CLASS ELFCLASS64 | ||
102 | #endif /* __s390x__ */ | ||
103 | #define ELF_DATA ELFDATA2MSB | ||
104 | #define ELF_ARCH EM_S390 | ||
105 | |||
106 | /* | ||
107 | * ELF register definitions.. | ||
108 | */ | ||
109 | |||
110 | #include <asm/ptrace.h> | ||
111 | #include <asm/user.h> | ||
112 | |||
113 | typedef s390_fp_regs elf_fpregset_t; | ||
114 | typedef s390_regs elf_gregset_t; | ||
115 | |||
116 | typedef s390_fp_regs compat_elf_fpregset_t; | ||
117 | typedef s390_compat_regs compat_elf_gregset_t; | ||
118 | |||
119 | #include <linux/sched.h> /* for task_struct */ | ||
120 | #include <asm/system.h> /* for save_access_regs */ | ||
121 | #include <asm/mmu_context.h> | ||
122 | |||
123 | /* | ||
124 | * This is used to ensure we don't load something for the wrong architecture. | ||
125 | */ | ||
126 | #define elf_check_arch(x) \ | ||
127 | (((x)->e_machine == EM_S390 || (x)->e_machine == EM_S390_OLD) \ | ||
128 | && (x)->e_ident[EI_CLASS] == ELF_CLASS) | ||
129 | #define compat_elf_check_arch(x) \ | ||
130 | (((x)->e_machine == EM_S390 || (x)->e_machine == EM_S390_OLD) \ | ||
131 | && (x)->e_ident[EI_CLASS] == ELF_CLASS) | ||
132 | #define compat_start_thread start_thread31 | ||
133 | |||
134 | /* For SVR4/S390 the function pointer to be registered with `atexit` is | ||
135 | passed in R14. */ | ||
136 | #define ELF_PLAT_INIT(_r, load_addr) \ | ||
137 | do { \ | ||
138 | _r->gprs[14] = 0; \ | ||
139 | } while (0) | ||
140 | |||
141 | #define CORE_DUMP_USE_REGSET | ||
142 | #define USE_ELF_CORE_DUMP | ||
143 | #define ELF_EXEC_PAGESIZE 4096 | ||
144 | |||
145 | /* This is the location that an ET_DYN program is loaded if exec'ed. Typical | ||
146 | use of this is to invoke "./ld.so someprog" to test out a new version of | ||
147 | the loader. We need to make sure that it is out of the way of the program | ||
148 | that it will "exec", and that there is sufficient room for the brk. */ | ||
149 | #define ELF_ET_DYN_BASE (STACK_TOP / 3 * 2) | ||
150 | |||
151 | /* This yields a mask that user programs can use to figure out what | ||
152 | instruction set this CPU supports. */ | ||
153 | |||
154 | extern unsigned long elf_hwcap; | ||
155 | #define ELF_HWCAP (elf_hwcap) | ||
156 | |||
157 | /* This yields a string that ld.so will use to load implementation | ||
158 | specific libraries for optimization. This is more specific in | ||
159 | intent than poking at uname or /proc/cpuinfo. | ||
160 | |||
161 | For the moment, we have only optimizations for the Intel generations, | ||
162 | but that could change... */ | ||
163 | |||
164 | #define ELF_PLATFORM_SIZE 8 | ||
165 | extern char elf_platform[]; | ||
166 | #define ELF_PLATFORM (elf_platform) | ||
167 | |||
168 | #ifndef __s390x__ | ||
169 | #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) | ||
170 | #else /* __s390x__ */ | ||
171 | #define SET_PERSONALITY(ex, ibcs2) \ | ||
172 | do { \ | ||
173 | if (ibcs2) \ | ||
174 | set_personality(PER_SVR4); \ | ||
175 | else if (current->personality != PER_LINUX32) \ | ||
176 | set_personality(PER_LINUX); \ | ||
177 | if ((ex).e_ident[EI_CLASS] == ELFCLASS32) \ | ||
178 | set_thread_flag(TIF_31BIT); \ | ||
179 | else \ | ||
180 | clear_thread_flag(TIF_31BIT); \ | ||
181 | } while (0) | ||
182 | #endif /* __s390x__ */ | ||
183 | |||
184 | /* | ||
185 | * An executable for which elf_read_implies_exec() returns TRUE will | ||
186 | * have the READ_IMPLIES_EXEC personality flag set automatically. | ||
187 | */ | ||
188 | #define elf_read_implies_exec(ex, executable_stack) \ | ||
189 | ({ \ | ||
190 | if (current->mm->context.noexec && \ | ||
191 | executable_stack != EXSTACK_DISABLE_X) \ | ||
192 | disable_noexec(current->mm, current); \ | ||
193 | current->mm->context.noexec == 0; \ | ||
194 | }) | ||
195 | |||
196 | #endif | ||
diff --git a/arch/s390/include/asm/emergency-restart.h b/arch/s390/include/asm/emergency-restart.h new file mode 100644 index 000000000000..108d8c48e42e --- /dev/null +++ b/arch/s390/include/asm/emergency-restart.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef _ASM_EMERGENCY_RESTART_H | ||
2 | #define _ASM_EMERGENCY_RESTART_H | ||
3 | |||
4 | #include <asm-generic/emergency-restart.h> | ||
5 | |||
6 | #endif /* _ASM_EMERGENCY_RESTART_H */ | ||
diff --git a/arch/s390/include/asm/errno.h b/arch/s390/include/asm/errno.h new file mode 100644 index 000000000000..e41d5b37c4d6 --- /dev/null +++ b/arch/s390/include/asm/errno.h | |||
@@ -0,0 +1,13 @@ | |||
1 | /* | ||
2 | * include/asm-s390/errno.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | */ | ||
7 | |||
8 | #ifndef _S390_ERRNO_H | ||
9 | #define _S390_ERRNO_H | ||
10 | |||
11 | #include <asm-generic/errno.h> | ||
12 | |||
13 | #endif | ||
diff --git a/arch/s390/include/asm/etr.h b/arch/s390/include/asm/etr.h new file mode 100644 index 000000000000..80ef58c61970 --- /dev/null +++ b/arch/s390/include/asm/etr.h | |||
@@ -0,0 +1,258 @@ | |||
1 | /* | ||
2 | * include/asm-s390/etr.h | ||
3 | * | ||
4 | * Copyright IBM Corp. 2006 | ||
5 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
6 | */ | ||
7 | #ifndef __S390_ETR_H | ||
8 | #define __S390_ETR_H | ||
9 | |||
10 | /* ETR attachment control register */ | ||
11 | struct etr_eacr { | ||
12 | unsigned int e0 : 1; /* port 0 stepping control */ | ||
13 | unsigned int e1 : 1; /* port 1 stepping control */ | ||
14 | unsigned int _pad0 : 5; /* must be 00100 */ | ||
15 | unsigned int dp : 1; /* data port control */ | ||
16 | unsigned int p0 : 1; /* port 0 change recognition control */ | ||
17 | unsigned int p1 : 1; /* port 1 change recognition control */ | ||
18 | unsigned int _pad1 : 3; /* must be 000 */ | ||
19 | unsigned int ea : 1; /* ETR alert control */ | ||
20 | unsigned int es : 1; /* ETR sync check control */ | ||
21 | unsigned int sl : 1; /* switch to local control */ | ||
22 | } __attribute__ ((packed)); | ||
23 | |||
24 | /* Port state returned by steai */ | ||
25 | enum etr_psc { | ||
26 | etr_psc_operational = 0, | ||
27 | etr_psc_semi_operational = 1, | ||
28 | etr_psc_protocol_error = 4, | ||
29 | etr_psc_no_symbols = 8, | ||
30 | etr_psc_no_signal = 12, | ||
31 | etr_psc_pps_mode = 13 | ||
32 | }; | ||
33 | |||
34 | /* Logical port state returned by stetr */ | ||
35 | enum etr_lpsc { | ||
36 | etr_lpsc_operational_step = 0, | ||
37 | etr_lpsc_operational_alt = 1, | ||
38 | etr_lpsc_semi_operational = 2, | ||
39 | etr_lpsc_protocol_error = 4, | ||
40 | etr_lpsc_no_symbol_sync = 8, | ||
41 | etr_lpsc_no_signal = 12, | ||
42 | etr_lpsc_pps_mode = 13 | ||
43 | }; | ||
44 | |||
45 | /* ETR status words */ | ||
46 | struct etr_esw { | ||
47 | struct etr_eacr eacr; /* attachment control register */ | ||
48 | unsigned int y : 1; /* stepping mode */ | ||
49 | unsigned int _pad0 : 5; /* must be 00000 */ | ||
50 | unsigned int p : 1; /* stepping port number */ | ||
51 | unsigned int q : 1; /* data port number */ | ||
52 | unsigned int psc0 : 4; /* port 0 state code */ | ||
53 | unsigned int psc1 : 4; /* port 1 state code */ | ||
54 | } __attribute__ ((packed)); | ||
55 | |||
56 | /* Second level data register status word */ | ||
57 | struct etr_slsw { | ||
58 | unsigned int vv1 : 1; /* copy of validity bit data frame 1 */ | ||
59 | unsigned int vv2 : 1; /* copy of validity bit data frame 2 */ | ||
60 | unsigned int vv3 : 1; /* copy of validity bit data frame 3 */ | ||
61 | unsigned int vv4 : 1; /* copy of validity bit data frame 4 */ | ||
62 | unsigned int _pad0 : 19; /* must by all zeroes */ | ||
63 | unsigned int n : 1; /* EAF port number */ | ||
64 | unsigned int v1 : 1; /* validity bit ETR data frame 1 */ | ||
65 | unsigned int v2 : 1; /* validity bit ETR data frame 2 */ | ||
66 | unsigned int v3 : 1; /* validity bit ETR data frame 3 */ | ||
67 | unsigned int v4 : 1; /* validity bit ETR data frame 4 */ | ||
68 | unsigned int _pad1 : 4; /* must be 0000 */ | ||
69 | } __attribute__ ((packed)); | ||
70 | |||
71 | /* ETR data frames */ | ||
72 | struct etr_edf1 { | ||
73 | unsigned int u : 1; /* untuned bit */ | ||
74 | unsigned int _pad0 : 1; /* must be 0 */ | ||
75 | unsigned int r : 1; /* service request bit */ | ||
76 | unsigned int _pad1 : 4; /* must be 0000 */ | ||
77 | unsigned int a : 1; /* time adjustment bit */ | ||
78 | unsigned int net_id : 8; /* ETR network id */ | ||
79 | unsigned int etr_id : 8; /* id of ETR which sends data frames */ | ||
80 | unsigned int etr_pn : 8; /* port number of ETR output port */ | ||
81 | } __attribute__ ((packed)); | ||
82 | |||
83 | struct etr_edf2 { | ||
84 | unsigned int etv : 32; /* Upper 32 bits of TOD. */ | ||
85 | } __attribute__ ((packed)); | ||
86 | |||
87 | struct etr_edf3 { | ||
88 | unsigned int rc : 8; /* failure reason code */ | ||
89 | unsigned int _pad0 : 3; /* must be 000 */ | ||
90 | unsigned int c : 1; /* ETR coupled bit */ | ||
91 | unsigned int tc : 4; /* ETR type code */ | ||
92 | unsigned int blto : 8; /* biased local time offset */ | ||
93 | /* (blto - 128) * 15 = minutes */ | ||
94 | unsigned int buo : 8; /* biased utc offset */ | ||
95 | /* (buo - 128) = leap seconds */ | ||
96 | } __attribute__ ((packed)); | ||
97 | |||
98 | struct etr_edf4 { | ||
99 | unsigned int ed : 8; /* ETS device dependent data */ | ||
100 | unsigned int _pad0 : 1; /* must be 0 */ | ||
101 | unsigned int buc : 5; /* biased ut1 correction */ | ||
102 | /* (buc - 16) * 0.1 seconds */ | ||
103 | unsigned int em : 6; /* ETS error magnitude */ | ||
104 | unsigned int dc : 6; /* ETS drift code */ | ||
105 | unsigned int sc : 6; /* ETS steering code */ | ||
106 | } __attribute__ ((packed)); | ||
107 | |||
108 | /* | ||
109 | * ETR attachment information block, two formats | ||
110 | * format 1 has 4 reserved words with a size of 64 bytes | ||
111 | * format 2 has 16 reserved words with a size of 96 bytes | ||
112 | */ | ||
113 | struct etr_aib { | ||
114 | struct etr_esw esw; | ||
115 | struct etr_slsw slsw; | ||
116 | unsigned long long tsp; | ||
117 | struct etr_edf1 edf1; | ||
118 | struct etr_edf2 edf2; | ||
119 | struct etr_edf3 edf3; | ||
120 | struct etr_edf4 edf4; | ||
121 | unsigned int reserved[16]; | ||
122 | } __attribute__ ((packed,aligned(8))); | ||
123 | |||
124 | /* ETR interruption parameter */ | ||
125 | struct etr_irq_parm { | ||
126 | unsigned int _pad0 : 8; | ||
127 | unsigned int pc0 : 1; /* port 0 state change */ | ||
128 | unsigned int pc1 : 1; /* port 1 state change */ | ||
129 | unsigned int _pad1 : 3; | ||
130 | unsigned int eai : 1; /* ETR alert indication */ | ||
131 | unsigned int _pad2 : 18; | ||
132 | } __attribute__ ((packed)); | ||
133 | |||
134 | /* Query TOD offset result */ | ||
135 | struct etr_ptff_qto { | ||
136 | unsigned long long physical_clock; | ||
137 | unsigned long long tod_offset; | ||
138 | unsigned long long logical_tod_offset; | ||
139 | unsigned long long tod_epoch_difference; | ||
140 | } __attribute__ ((packed)); | ||
141 | |||
142 | /* Inline assembly helper functions */ | ||
143 | static inline int etr_setr(struct etr_eacr *ctrl) | ||
144 | { | ||
145 | int rc = -ENOSYS; | ||
146 | |||
147 | asm volatile( | ||
148 | " .insn s,0xb2160000,0(%2)\n" | ||
149 | "0: la %0,0\n" | ||
150 | "1:\n" | ||
151 | EX_TABLE(0b,1b) | ||
152 | : "+d" (rc) : "m" (*ctrl), "a" (ctrl)); | ||
153 | return rc; | ||
154 | } | ||
155 | |||
156 | /* Stores a format 1 aib with 64 bytes */ | ||
157 | static inline int etr_stetr(struct etr_aib *aib) | ||
158 | { | ||
159 | int rc = -ENOSYS; | ||
160 | |||
161 | asm volatile( | ||
162 | " .insn s,0xb2170000,0(%2)\n" | ||
163 | "0: la %0,0\n" | ||
164 | "1:\n" | ||
165 | EX_TABLE(0b,1b) | ||
166 | : "+d" (rc) : "m" (*aib), "a" (aib)); | ||
167 | return rc; | ||
168 | } | ||
169 | |||
170 | /* Stores a format 2 aib with 96 bytes for specified port */ | ||
171 | static inline int etr_steai(struct etr_aib *aib, unsigned int func) | ||
172 | { | ||
173 | register unsigned int reg0 asm("0") = func; | ||
174 | int rc = -ENOSYS; | ||
175 | |||
176 | asm volatile( | ||
177 | " .insn s,0xb2b30000,0(%2)\n" | ||
178 | "0: la %0,0\n" | ||
179 | "1:\n" | ||
180 | EX_TABLE(0b,1b) | ||
181 | : "+d" (rc) : "m" (*aib), "a" (aib), "d" (reg0)); | ||
182 | return rc; | ||
183 | } | ||
184 | |||
185 | /* Function codes for the steai instruction. */ | ||
186 | #define ETR_STEAI_STEPPING_PORT 0x10 | ||
187 | #define ETR_STEAI_ALTERNATE_PORT 0x11 | ||
188 | #define ETR_STEAI_PORT_0 0x12 | ||
189 | #define ETR_STEAI_PORT_1 0x13 | ||
190 | |||
191 | static inline int etr_ptff(void *ptff_block, unsigned int func) | ||
192 | { | ||
193 | register unsigned int reg0 asm("0") = func; | ||
194 | register unsigned long reg1 asm("1") = (unsigned long) ptff_block; | ||
195 | int rc = -ENOSYS; | ||
196 | |||
197 | asm volatile( | ||
198 | " .word 0x0104\n" | ||
199 | " ipm %0\n" | ||
200 | " srl %0,28\n" | ||
201 | : "=d" (rc), "=m" (ptff_block) | ||
202 | : "d" (reg0), "d" (reg1), "m" (ptff_block) : "cc"); | ||
203 | return rc; | ||
204 | } | ||
205 | |||
206 | /* Function codes for the ptff instruction. */ | ||
207 | #define ETR_PTFF_QAF 0x00 /* query available functions */ | ||
208 | #define ETR_PTFF_QTO 0x01 /* query tod offset */ | ||
209 | #define ETR_PTFF_QSI 0x02 /* query steering information */ | ||
210 | #define ETR_PTFF_ATO 0x40 /* adjust tod offset */ | ||
211 | #define ETR_PTFF_STO 0x41 /* set tod offset */ | ||
212 | #define ETR_PTFF_SFS 0x42 /* set fine steering rate */ | ||
213 | #define ETR_PTFF_SGS 0x43 /* set gross steering rate */ | ||
214 | |||
215 | /* Functions needed by the machine check handler */ | ||
216 | void etr_switch_to_local(void); | ||
217 | void etr_sync_check(void); | ||
218 | |||
219 | /* STP interruption parameter */ | ||
220 | struct stp_irq_parm { | ||
221 | unsigned int _pad0 : 14; | ||
222 | unsigned int tsc : 1; /* Timing status change */ | ||
223 | unsigned int lac : 1; /* Link availability change */ | ||
224 | unsigned int tcpc : 1; /* Time control parameter change */ | ||
225 | unsigned int _pad2 : 15; | ||
226 | } __attribute__ ((packed)); | ||
227 | |||
228 | #define STP_OP_SYNC 1 | ||
229 | #define STP_OP_CTRL 3 | ||
230 | |||
231 | struct stp_sstpi { | ||
232 | unsigned int rsvd0; | ||
233 | unsigned int rsvd1 : 8; | ||
234 | unsigned int stratum : 8; | ||
235 | unsigned int vbits : 16; | ||
236 | unsigned int leaps : 16; | ||
237 | unsigned int tmd : 4; | ||
238 | unsigned int ctn : 4; | ||
239 | unsigned int rsvd2 : 3; | ||
240 | unsigned int c : 1; | ||
241 | unsigned int tst : 4; | ||
242 | unsigned int tzo : 16; | ||
243 | unsigned int dsto : 16; | ||
244 | unsigned int ctrl : 16; | ||
245 | unsigned int rsvd3 : 16; | ||
246 | unsigned int tto; | ||
247 | unsigned int rsvd4; | ||
248 | unsigned int ctnid[3]; | ||
249 | unsigned int rsvd5; | ||
250 | unsigned int todoff[4]; | ||
251 | unsigned int rsvd6[48]; | ||
252 | } __attribute__ ((packed)); | ||
253 | |||
254 | /* Functions needed by the machine check handler */ | ||
255 | void stp_sync_check(void); | ||
256 | void stp_island_check(void); | ||
257 | |||
258 | #endif /* __S390_ETR_H */ | ||
diff --git a/arch/s390/include/asm/extmem.h b/arch/s390/include/asm/extmem.h new file mode 100644 index 000000000000..33837d756184 --- /dev/null +++ b/arch/s390/include/asm/extmem.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * include/asm-s390x/extmem.h | ||
3 | * | ||
4 | * definitions for external memory segment support | ||
5 | * Copyright (C) 2003 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_S390X_DCSS_H | ||
9 | #define _ASM_S390X_DCSS_H | ||
10 | #ifndef __ASSEMBLY__ | ||
11 | |||
12 | /* possible values for segment type as returned by segment_info */ | ||
13 | #define SEG_TYPE_SW 0 | ||
14 | #define SEG_TYPE_EW 1 | ||
15 | #define SEG_TYPE_SR 2 | ||
16 | #define SEG_TYPE_ER 3 | ||
17 | #define SEG_TYPE_SN 4 | ||
18 | #define SEG_TYPE_EN 5 | ||
19 | #define SEG_TYPE_SC 6 | ||
20 | #define SEG_TYPE_EWEN 7 | ||
21 | |||
22 | #define SEGMENT_SHARED 0 | ||
23 | #define SEGMENT_EXCLUSIVE 1 | ||
24 | |||
25 | int segment_load (char *name, int segtype, unsigned long *addr, unsigned long *length); | ||
26 | void segment_unload(char *name); | ||
27 | void segment_save(char *name); | ||
28 | int segment_type (char* name); | ||
29 | int segment_modify_shared (char *name, int do_nonshared); | ||
30 | void segment_warning(int rc, char *seg_name); | ||
31 | |||
32 | #endif | ||
33 | #endif | ||
diff --git a/arch/s390/include/asm/fb.h b/arch/s390/include/asm/fb.h new file mode 100644 index 000000000000..c7df38030992 --- /dev/null +++ b/arch/s390/include/asm/fb.h | |||
@@ -0,0 +1,12 @@ | |||
1 | #ifndef _ASM_FB_H_ | ||
2 | #define _ASM_FB_H_ | ||
3 | #include <linux/fb.h> | ||
4 | |||
5 | #define fb_pgprotect(...) do {} while (0) | ||
6 | |||
7 | static inline int fb_is_primary_device(struct fb_info *info) | ||
8 | { | ||
9 | return 0; | ||
10 | } | ||
11 | |||
12 | #endif /* _ASM_FB_H_ */ | ||
diff --git a/arch/s390/include/asm/fcntl.h b/arch/s390/include/asm/fcntl.h new file mode 100644 index 000000000000..46ab12db5739 --- /dev/null +++ b/arch/s390/include/asm/fcntl.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/fcntl.h> | |||
diff --git a/arch/s390/include/asm/fcx.h b/arch/s390/include/asm/fcx.h new file mode 100644 index 000000000000..8be1f3a58042 --- /dev/null +++ b/arch/s390/include/asm/fcx.h | |||
@@ -0,0 +1,311 @@ | |||
1 | /* | ||
2 | * Functions for assembling fcx enabled I/O control blocks. | ||
3 | * | ||
4 | * Copyright IBM Corp. 2008 | ||
5 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_S390_FCX_H | ||
9 | #define _ASM_S390_FCX_H _ASM_S390_FCX_H | ||
10 | |||
11 | #include <linux/types.h> | ||
12 | |||
13 | #define TCW_FORMAT_DEFAULT 0 | ||
14 | #define TCW_TIDAW_FORMAT_DEFAULT 0 | ||
15 | #define TCW_FLAGS_INPUT_TIDA 1 << (23 - 5) | ||
16 | #define TCW_FLAGS_TCCB_TIDA 1 << (23 - 6) | ||
17 | #define TCW_FLAGS_OUTPUT_TIDA 1 << (23 - 7) | ||
18 | #define TCW_FLAGS_TIDAW_FORMAT(x) ((x) & 3) << (23 - 9) | ||
19 | #define TCW_FLAGS_GET_TIDAW_FORMAT(x) (((x) >> (23 - 9)) & 3) | ||
20 | |||
21 | /** | ||
22 | * struct tcw - Transport Control Word (TCW) | ||
23 | * @format: TCW format | ||
24 | * @flags: TCW flags | ||
25 | * @tccbl: Transport-Command-Control-Block Length | ||
26 | * @r: Read Operations | ||
27 | * @w: Write Operations | ||
28 | * @output: Output-Data Address | ||
29 | * @input: Input-Data Address | ||
30 | * @tsb: Transport-Status-Block Address | ||
31 | * @tccb: Transport-Command-Control-Block Address | ||
32 | * @output_count: Output Count | ||
33 | * @input_count: Input Count | ||
34 | * @intrg: Interrogate TCW Address | ||
35 | */ | ||
36 | struct tcw { | ||
37 | u32 format:2; | ||
38 | u32 :6; | ||
39 | u32 flags:24; | ||
40 | u32 :8; | ||
41 | u32 tccbl:6; | ||
42 | u32 r:1; | ||
43 | u32 w:1; | ||
44 | u32 :16; | ||
45 | u64 output; | ||
46 | u64 input; | ||
47 | u64 tsb; | ||
48 | u64 tccb; | ||
49 | u32 output_count; | ||
50 | u32 input_count; | ||
51 | u32 :32; | ||
52 | u32 :32; | ||
53 | u32 :32; | ||
54 | u32 intrg; | ||
55 | } __attribute__ ((packed, aligned(64))); | ||
56 | |||
57 | #define TIDAW_FLAGS_LAST 1 << (7 - 0) | ||
58 | #define TIDAW_FLAGS_SKIP 1 << (7 - 1) | ||
59 | #define TIDAW_FLAGS_DATA_INT 1 << (7 - 2) | ||
60 | #define TIDAW_FLAGS_TTIC 1 << (7 - 3) | ||
61 | #define TIDAW_FLAGS_INSERT_CBC 1 << (7 - 4) | ||
62 | |||
63 | /** | ||
64 | * struct tidaw - Transport-Indirect-Addressing Word (TIDAW) | ||
65 | * @flags: TIDAW flags. Can be an arithmetic OR of the following constants: | ||
66 | * %TIDAW_FLAGS_LAST, %TIDAW_FLAGS_SKIP, %TIDAW_FLAGS_DATA_INT, | ||
67 | * %TIDAW_FLAGS_TTIC, %TIDAW_FLAGS_INSERT_CBC | ||
68 | * @count: Count | ||
69 | * @addr: Address | ||
70 | */ | ||
71 | struct tidaw { | ||
72 | u32 flags:8; | ||
73 | u32 :24; | ||
74 | u32 count; | ||
75 | u64 addr; | ||
76 | } __attribute__ ((packed, aligned(16))); | ||
77 | |||
78 | /** | ||
79 | * struct tsa_iostat - I/O-Status Transport-Status Area (IO-Stat TSA) | ||
80 | * @dev_time: Device Time | ||
81 | * @def_time: Defer Time | ||
82 | * @queue_time: Queue Time | ||
83 | * @dev_busy_time: Device-Busy Time | ||
84 | * @dev_act_time: Device-Active-Only Time | ||
85 | * @sense: Sense Data (if present) | ||
86 | */ | ||
87 | struct tsa_iostat { | ||
88 | u32 dev_time; | ||
89 | u32 def_time; | ||
90 | u32 queue_time; | ||
91 | u32 dev_busy_time; | ||
92 | u32 dev_act_time; | ||
93 | u8 sense[32]; | ||
94 | } __attribute__ ((packed)); | ||
95 | |||
96 | /** | ||
97 | * struct tsa_ddpcs - Device-Detected-Program-Check Transport-Status Area (DDPC TSA) | ||
98 | * @rc: Reason Code | ||
99 | * @rcq: Reason Code Qualifier | ||
100 | * @sense: Sense Data (if present) | ||
101 | */ | ||
102 | struct tsa_ddpc { | ||
103 | u32 :24; | ||
104 | u32 rc:8; | ||
105 | u8 rcq[16]; | ||
106 | u8 sense[32]; | ||
107 | } __attribute__ ((packed)); | ||
108 | |||
109 | #define TSA_INTRG_FLAGS_CU_STATE_VALID 1 << (7 - 0) | ||
110 | #define TSA_INTRG_FLAGS_DEV_STATE_VALID 1 << (7 - 1) | ||
111 | #define TSA_INTRG_FLAGS_OP_STATE_VALID 1 << (7 - 2) | ||
112 | |||
113 | /** | ||
114 | * struct tsa_intrg - Interrogate Transport-Status Area (Intrg. TSA) | ||
115 | * @format: Format | ||
116 | * @flags: Flags. Can be an arithmetic OR of the following constants: | ||
117 | * %TSA_INTRG_FLAGS_CU_STATE_VALID, %TSA_INTRG_FLAGS_DEV_STATE_VALID, | ||
118 | * %TSA_INTRG_FLAGS_OP_STATE_VALID | ||
119 | * @cu_state: Controle-Unit State | ||
120 | * @dev_state: Device State | ||
121 | * @op_state: Operation State | ||
122 | * @sd_info: State-Dependent Information | ||
123 | * @dl_id: Device-Level Identifier | ||
124 | * @dd_data: Device-Dependent Data | ||
125 | */ | ||
126 | struct tsa_intrg { | ||
127 | u32 format:8; | ||
128 | u32 flags:8; | ||
129 | u32 cu_state:8; | ||
130 | u32 dev_state:8; | ||
131 | u32 op_state:8; | ||
132 | u32 :24; | ||
133 | u8 sd_info[12]; | ||
134 | u32 dl_id; | ||
135 | u8 dd_data[28]; | ||
136 | } __attribute__ ((packed)); | ||
137 | |||
138 | #define TSB_FORMAT_NONE 0 | ||
139 | #define TSB_FORMAT_IOSTAT 1 | ||
140 | #define TSB_FORMAT_DDPC 2 | ||
141 | #define TSB_FORMAT_INTRG 3 | ||
142 | |||
143 | #define TSB_FLAGS_DCW_OFFSET_VALID 1 << (7 - 0) | ||
144 | #define TSB_FLAGS_COUNT_VALID 1 << (7 - 1) | ||
145 | #define TSB_FLAGS_CACHE_MISS 1 << (7 - 2) | ||
146 | #define TSB_FLAGS_TIME_VALID 1 << (7 - 3) | ||
147 | #define TSB_FLAGS_FORMAT(x) ((x) & 7) | ||
148 | #define TSB_FORMAT(t) ((t)->flags & 7) | ||
149 | |||
150 | /** | ||
151 | * struct tsb - Transport-Status Block (TSB) | ||
152 | * @length: Length | ||
153 | * @flags: Flags. Can be an arithmetic OR of the following constants: | ||
154 | * %TSB_FLAGS_DCW_OFFSET_VALID, %TSB_FLAGS_COUNT_VALID, %TSB_FLAGS_CACHE_MISS, | ||
155 | * %TSB_FLAGS_TIME_VALID | ||
156 | * @dcw_offset: DCW Offset | ||
157 | * @count: Count | ||
158 | * @tsa: Transport-Status-Area | ||
159 | */ | ||
160 | struct tsb { | ||
161 | u32 length:8; | ||
162 | u32 flags:8; | ||
163 | u32 dcw_offset:16; | ||
164 | u32 count; | ||
165 | u32 :32; | ||
166 | union { | ||
167 | struct tsa_iostat iostat; | ||
168 | struct tsa_ddpc ddpc; | ||
169 | struct tsa_intrg intrg; | ||
170 | } __attribute__ ((packed)) tsa; | ||
171 | } __attribute__ ((packed, aligned(8))); | ||
172 | |||
173 | #define DCW_INTRG_FORMAT_DEFAULT 0 | ||
174 | |||
175 | #define DCW_INTRG_RC_UNSPECIFIED 0 | ||
176 | #define DCW_INTRG_RC_TIMEOUT 1 | ||
177 | |||
178 | #define DCW_INTRG_RCQ_UNSPECIFIED 0 | ||
179 | #define DCW_INTRG_RCQ_PRIMARY 1 | ||
180 | #define DCW_INTRG_RCQ_SECONDARY 2 | ||
181 | |||
182 | #define DCW_INTRG_FLAGS_MPM 1 < (7 - 0) | ||
183 | #define DCW_INTRG_FLAGS_PPR 1 < (7 - 1) | ||
184 | #define DCW_INTRG_FLAGS_CRIT 1 < (7 - 2) | ||
185 | |||
186 | /** | ||
187 | * struct dcw_intrg_data - Interrogate DCW data | ||
188 | * @format: Format. Should be %DCW_INTRG_FORMAT_DEFAULT | ||
189 | * @rc: Reason Code. Can be one of %DCW_INTRG_RC_UNSPECIFIED, | ||
190 | * %DCW_INTRG_RC_TIMEOUT | ||
191 | * @rcq: Reason Code Qualifier: Can be one of %DCW_INTRG_RCQ_UNSPECIFIED, | ||
192 | * %DCW_INTRG_RCQ_PRIMARY, %DCW_INTRG_RCQ_SECONDARY | ||
193 | * @lpm: Logical-Path Mask | ||
194 | * @pam: Path-Available Mask | ||
195 | * @pim: Path-Installed Mask | ||
196 | * @timeout: Timeout | ||
197 | * @flags: Flags. Can be an arithmetic OR of %DCW_INTRG_FLAGS_MPM, | ||
198 | * %DCW_INTRG_FLAGS_PPR, %DCW_INTRG_FLAGS_CRIT | ||
199 | * @time: Time | ||
200 | * @prog_id: Program Identifier | ||
201 | * @prog_data: Program-Dependent Data | ||
202 | */ | ||
203 | struct dcw_intrg_data { | ||
204 | u32 format:8; | ||
205 | u32 rc:8; | ||
206 | u32 rcq:8; | ||
207 | u32 lpm:8; | ||
208 | u32 pam:8; | ||
209 | u32 pim:8; | ||
210 | u32 timeout:16; | ||
211 | u32 flags:8; | ||
212 | u32 :24; | ||
213 | u32 :32; | ||
214 | u64 time; | ||
215 | u64 prog_id; | ||
216 | u8 prog_data[0]; | ||
217 | } __attribute__ ((packed)); | ||
218 | |||
219 | #define DCW_FLAGS_CC 1 << (7 - 1) | ||
220 | |||
221 | #define DCW_CMD_WRITE 0x01 | ||
222 | #define DCW_CMD_READ 0x02 | ||
223 | #define DCW_CMD_CONTROL 0x03 | ||
224 | #define DCW_CMD_SENSE 0x04 | ||
225 | #define DCW_CMD_SENSE_ID 0xe4 | ||
226 | #define DCW_CMD_INTRG 0x40 | ||
227 | |||
228 | /** | ||
229 | * struct dcw - Device-Command Word (DCW) | ||
230 | * @cmd: Command Code. Can be one of %DCW_CMD_WRITE, %DCW_CMD_READ, | ||
231 | * %DCW_CMD_CONTROL, %DCW_CMD_SENSE, %DCW_CMD_SENSE_ID, %DCW_CMD_INTRG | ||
232 | * @flags: Flags. Can be an arithmetic OR of %DCW_FLAGS_CC | ||
233 | * @cd_count: Control-Data Count | ||
234 | * @count: Count | ||
235 | * @cd: Control Data | ||
236 | */ | ||
237 | struct dcw { | ||
238 | u32 cmd:8; | ||
239 | u32 flags:8; | ||
240 | u32 :8; | ||
241 | u32 cd_count:8; | ||
242 | u32 count; | ||
243 | u8 cd[0]; | ||
244 | } __attribute__ ((packed)); | ||
245 | |||
246 | #define TCCB_FORMAT_DEFAULT 0x7f | ||
247 | #define TCCB_MAX_DCW 30 | ||
248 | #define TCCB_MAX_SIZE (sizeof(struct tccb_tcah) + \ | ||
249 | TCCB_MAX_DCW * sizeof(struct dcw) + \ | ||
250 | sizeof(struct tccb_tcat)) | ||
251 | #define TCCB_SAC_DEFAULT 0xf901 | ||
252 | #define TCCB_SAC_INTRG 0xf902 | ||
253 | |||
254 | /** | ||
255 | * struct tccb_tcah - Transport-Command-Area Header (TCAH) | ||
256 | * @format: Format. Should be %TCCB_FORMAT_DEFAULT | ||
257 | * @tcal: Transport-Command-Area Length | ||
258 | * @sac: Service-Action Code. Can be one of %TCCB_SAC_DEFAULT, %TCCB_SAC_INTRG | ||
259 | * @prio: Priority | ||
260 | */ | ||
261 | struct tccb_tcah { | ||
262 | u32 format:8; | ||
263 | u32 :24; | ||
264 | u32 :24; | ||
265 | u32 tcal:8; | ||
266 | u32 sac:16; | ||
267 | u32 :8; | ||
268 | u32 prio:8; | ||
269 | u32 :32; | ||
270 | } __attribute__ ((packed)); | ||
271 | |||
272 | /** | ||
273 | * struct tccb_tcat - Transport-Command-Area Trailer (TCAT) | ||
274 | * @count: Transport Count | ||
275 | */ | ||
276 | struct tccb_tcat { | ||
277 | u32 :32; | ||
278 | u32 count; | ||
279 | } __attribute__ ((packed)); | ||
280 | |||
281 | /** | ||
282 | * struct tccb - (partial) Transport-Command-Control Block (TCCB) | ||
283 | * @tcah: TCAH | ||
284 | * @tca: Transport-Command Area | ||
285 | */ | ||
286 | struct tccb { | ||
287 | struct tccb_tcah tcah; | ||
288 | u8 tca[0]; | ||
289 | } __attribute__ ((packed, aligned(8))); | ||
290 | |||
291 | struct tcw *tcw_get_intrg(struct tcw *tcw); | ||
292 | void *tcw_get_data(struct tcw *tcw); | ||
293 | struct tccb *tcw_get_tccb(struct tcw *tcw); | ||
294 | struct tsb *tcw_get_tsb(struct tcw *tcw); | ||
295 | |||
296 | void tcw_init(struct tcw *tcw, int r, int w); | ||
297 | void tcw_finalize(struct tcw *tcw, int num_tidaws); | ||
298 | |||
299 | void tcw_set_intrg(struct tcw *tcw, struct tcw *intrg_tcw); | ||
300 | void tcw_set_data(struct tcw *tcw, void *data, int use_tidal); | ||
301 | void tcw_set_tccb(struct tcw *tcw, struct tccb *tccb); | ||
302 | void tcw_set_tsb(struct tcw *tcw, struct tsb *tsb); | ||
303 | |||
304 | void tccb_init(struct tccb *tccb, size_t tccb_size, u32 sac); | ||
305 | void tsb_init(struct tsb *tsb); | ||
306 | struct dcw *tccb_add_dcw(struct tccb *tccb, size_t tccb_size, u8 cmd, u8 flags, | ||
307 | void *cd, u8 cd_count, u32 count); | ||
308 | struct tidaw *tcw_add_tidaw(struct tcw *tcw, int num_tidaws, u8 flags, | ||
309 | void *addr, u32 count); | ||
310 | |||
311 | #endif /* _ASM_S390_FCX_H */ | ||
diff --git a/arch/s390/include/asm/futex.h b/arch/s390/include/asm/futex.h new file mode 100644 index 000000000000..5c5d02de49e9 --- /dev/null +++ b/arch/s390/include/asm/futex.h | |||
@@ -0,0 +1,52 @@ | |||
1 | #ifndef _ASM_S390_FUTEX_H | ||
2 | #define _ASM_S390_FUTEX_H | ||
3 | |||
4 | #ifdef __KERNEL__ | ||
5 | |||
6 | #include <linux/futex.h> | ||
7 | #include <linux/uaccess.h> | ||
8 | #include <asm/errno.h> | ||
9 | |||
10 | static inline int futex_atomic_op_inuser (int encoded_op, int __user *uaddr) | ||
11 | { | ||
12 | int op = (encoded_op >> 28) & 7; | ||
13 | int cmp = (encoded_op >> 24) & 15; | ||
14 | int oparg = (encoded_op << 8) >> 20; | ||
15 | int cmparg = (encoded_op << 20) >> 20; | ||
16 | int oldval, ret; | ||
17 | |||
18 | if (encoded_op & (FUTEX_OP_OPARG_SHIFT << 28)) | ||
19 | oparg = 1 << oparg; | ||
20 | |||
21 | if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) | ||
22 | return -EFAULT; | ||
23 | |||
24 | pagefault_disable(); | ||
25 | ret = uaccess.futex_atomic_op(op, uaddr, oparg, &oldval); | ||
26 | pagefault_enable(); | ||
27 | |||
28 | if (!ret) { | ||
29 | switch (cmp) { | ||
30 | case FUTEX_OP_CMP_EQ: ret = (oldval == cmparg); break; | ||
31 | case FUTEX_OP_CMP_NE: ret = (oldval != cmparg); break; | ||
32 | case FUTEX_OP_CMP_LT: ret = (oldval < cmparg); break; | ||
33 | case FUTEX_OP_CMP_GE: ret = (oldval >= cmparg); break; | ||
34 | case FUTEX_OP_CMP_LE: ret = (oldval <= cmparg); break; | ||
35 | case FUTEX_OP_CMP_GT: ret = (oldval > cmparg); break; | ||
36 | default: ret = -ENOSYS; | ||
37 | } | ||
38 | } | ||
39 | return ret; | ||
40 | } | ||
41 | |||
42 | static inline int futex_atomic_cmpxchg_inatomic(int __user *uaddr, | ||
43 | int oldval, int newval) | ||
44 | { | ||
45 | if (! access_ok (VERIFY_WRITE, uaddr, sizeof(int))) | ||
46 | return -EFAULT; | ||
47 | |||
48 | return uaccess.futex_atomic_cmpxchg(uaddr, oldval, newval); | ||
49 | } | ||
50 | |||
51 | #endif /* __KERNEL__ */ | ||
52 | #endif /* _ASM_S390_FUTEX_H */ | ||
diff --git a/arch/s390/include/asm/hardirq.h b/arch/s390/include/asm/hardirq.h new file mode 100644 index 000000000000..89ec7056da28 --- /dev/null +++ b/arch/s390/include/asm/hardirq.h | |||
@@ -0,0 +1,51 @@ | |||
1 | /* | ||
2 | * include/asm-s390/hardirq.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | ||
7 | * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) | ||
8 | * | ||
9 | * Derived from "include/asm-i386/hardirq.h" | ||
10 | */ | ||
11 | |||
12 | #ifndef __ASM_HARDIRQ_H | ||
13 | #define __ASM_HARDIRQ_H | ||
14 | |||
15 | #include <linux/threads.h> | ||
16 | #include <linux/sched.h> | ||
17 | #include <linux/cache.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <asm/lowcore.h> | ||
20 | |||
21 | /* irq_cpustat_t is unused currently, but could be converted | ||
22 | * into a percpu variable instead of storing softirq_pending | ||
23 | * on the lowcore */ | ||
24 | typedef struct { | ||
25 | unsigned int __softirq_pending; | ||
26 | } irq_cpustat_t; | ||
27 | |||
28 | #define local_softirq_pending() (S390_lowcore.softirq_pending) | ||
29 | |||
30 | #define __ARCH_IRQ_STAT | ||
31 | #define __ARCH_HAS_DO_SOFTIRQ | ||
32 | |||
33 | #define HARDIRQ_BITS 8 | ||
34 | |||
35 | void clock_comparator_work(void); | ||
36 | |||
37 | static inline unsigned long long local_tick_disable(void) | ||
38 | { | ||
39 | unsigned long long old; | ||
40 | |||
41 | old = S390_lowcore.clock_comparator; | ||
42 | S390_lowcore.clock_comparator = -1ULL; | ||
43 | return old; | ||
44 | } | ||
45 | |||
46 | static inline void local_tick_enable(unsigned long long comp) | ||
47 | { | ||
48 | S390_lowcore.clock_comparator = comp; | ||
49 | } | ||
50 | |||
51 | #endif /* __ASM_HARDIRQ_H */ | ||
diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/hugetlb.h new file mode 100644 index 000000000000..670a1d1745d2 --- /dev/null +++ b/arch/s390/include/asm/hugetlb.h | |||
@@ -0,0 +1,184 @@ | |||
1 | /* | ||
2 | * IBM System z Huge TLB Page Support for Kernel. | ||
3 | * | ||
4 | * Copyright IBM Corp. 2008 | ||
5 | * Author(s): Gerald Schaefer <gerald.schaefer@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_S390_HUGETLB_H | ||
9 | #define _ASM_S390_HUGETLB_H | ||
10 | |||
11 | #include <asm/page.h> | ||
12 | #include <asm/pgtable.h> | ||
13 | |||
14 | |||
15 | #define is_hugepage_only_range(mm, addr, len) 0 | ||
16 | #define hugetlb_free_pgd_range free_pgd_range | ||
17 | |||
18 | void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, | ||
19 | pte_t *ptep, pte_t pte); | ||
20 | |||
21 | /* | ||
22 | * If the arch doesn't supply something else, assume that hugepage | ||
23 | * size aligned regions are ok without further preparation. | ||
24 | */ | ||
25 | static inline int prepare_hugepage_range(struct file *file, | ||
26 | unsigned long addr, unsigned long len) | ||
27 | { | ||
28 | if (len & ~HPAGE_MASK) | ||
29 | return -EINVAL; | ||
30 | if (addr & ~HPAGE_MASK) | ||
31 | return -EINVAL; | ||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | #define hugetlb_prefault_arch_hook(mm) do { } while (0) | ||
36 | |||
37 | int arch_prepare_hugepage(struct page *page); | ||
38 | void arch_release_hugepage(struct page *page); | ||
39 | |||
40 | static inline pte_t pte_mkhuge(pte_t pte) | ||
41 | { | ||
42 | /* | ||
43 | * PROT_NONE needs to be remapped from the pte type to the ste type. | ||
44 | * The HW invalid bit is also different for pte and ste. The pte | ||
45 | * invalid bit happens to be the same as the ste _SEGMENT_ENTRY_LARGE | ||
46 | * bit, so we don't have to clear it. | ||
47 | */ | ||
48 | if (pte_val(pte) & _PAGE_INVALID) { | ||
49 | if (pte_val(pte) & _PAGE_SWT) | ||
50 | pte_val(pte) |= _HPAGE_TYPE_NONE; | ||
51 | pte_val(pte) |= _SEGMENT_ENTRY_INV; | ||
52 | } | ||
53 | /* | ||
54 | * Clear SW pte bits SWT and SWX, there are no SW bits in a segment | ||
55 | * table entry. | ||
56 | */ | ||
57 | pte_val(pte) &= ~(_PAGE_SWT | _PAGE_SWX); | ||
58 | /* | ||
59 | * Also set the change-override bit because we don't need dirty bit | ||
60 | * tracking for hugetlbfs pages. | ||
61 | */ | ||
62 | pte_val(pte) |= (_SEGMENT_ENTRY_LARGE | _SEGMENT_ENTRY_CO); | ||
63 | return pte; | ||
64 | } | ||
65 | |||
66 | static inline pte_t huge_pte_wrprotect(pte_t pte) | ||
67 | { | ||
68 | pte_val(pte) |= _PAGE_RO; | ||
69 | return pte; | ||
70 | } | ||
71 | |||
72 | static inline int huge_pte_none(pte_t pte) | ||
73 | { | ||
74 | return (pte_val(pte) & _SEGMENT_ENTRY_INV) && | ||
75 | !(pte_val(pte) & _SEGMENT_ENTRY_RO); | ||
76 | } | ||
77 | |||
78 | static inline pte_t huge_ptep_get(pte_t *ptep) | ||
79 | { | ||
80 | pte_t pte = *ptep; | ||
81 | unsigned long mask; | ||
82 | |||
83 | if (!MACHINE_HAS_HPAGE) { | ||
84 | ptep = (pte_t *) (pte_val(pte) & _SEGMENT_ENTRY_ORIGIN); | ||
85 | if (ptep) { | ||
86 | mask = pte_val(pte) & | ||
87 | (_SEGMENT_ENTRY_INV | _SEGMENT_ENTRY_RO); | ||
88 | pte = pte_mkhuge(*ptep); | ||
89 | pte_val(pte) |= mask; | ||
90 | } | ||
91 | } | ||
92 | return pte; | ||
93 | } | ||
94 | |||
95 | static inline pte_t huge_ptep_get_and_clear(struct mm_struct *mm, | ||
96 | unsigned long addr, pte_t *ptep) | ||
97 | { | ||
98 | pte_t pte = huge_ptep_get(ptep); | ||
99 | |||
100 | pmd_clear((pmd_t *) ptep); | ||
101 | return pte; | ||
102 | } | ||
103 | |||
104 | static inline void __pmd_csp(pmd_t *pmdp) | ||
105 | { | ||
106 | register unsigned long reg2 asm("2") = pmd_val(*pmdp); | ||
107 | register unsigned long reg3 asm("3") = pmd_val(*pmdp) | | ||
108 | _SEGMENT_ENTRY_INV; | ||
109 | register unsigned long reg4 asm("4") = ((unsigned long) pmdp) + 5; | ||
110 | |||
111 | asm volatile( | ||
112 | " csp %1,%3" | ||
113 | : "=m" (*pmdp) | ||
114 | : "d" (reg2), "d" (reg3), "d" (reg4), "m" (*pmdp) : "cc"); | ||
115 | pmd_val(*pmdp) = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY; | ||
116 | } | ||
117 | |||
118 | static inline void __pmd_idte(unsigned long address, pmd_t *pmdp) | ||
119 | { | ||
120 | unsigned long sto = (unsigned long) pmdp - | ||
121 | pmd_index(address) * sizeof(pmd_t); | ||
122 | |||
123 | if (!(pmd_val(*pmdp) & _SEGMENT_ENTRY_INV)) { | ||
124 | asm volatile( | ||
125 | " .insn rrf,0xb98e0000,%2,%3,0,0" | ||
126 | : "=m" (*pmdp) | ||
127 | : "m" (*pmdp), "a" (sto), | ||
128 | "a" ((address & HPAGE_MASK)) | ||
129 | ); | ||
130 | } | ||
131 | pmd_val(*pmdp) = _SEGMENT_ENTRY_INV | _SEGMENT_ENTRY; | ||
132 | } | ||
133 | |||
134 | static inline void huge_ptep_invalidate(struct mm_struct *mm, | ||
135 | unsigned long address, pte_t *ptep) | ||
136 | { | ||
137 | pmd_t *pmdp = (pmd_t *) ptep; | ||
138 | |||
139 | if (!MACHINE_HAS_IDTE) { | ||
140 | __pmd_csp(pmdp); | ||
141 | if (mm->context.noexec) { | ||
142 | pmdp = get_shadow_table(pmdp); | ||
143 | __pmd_csp(pmdp); | ||
144 | } | ||
145 | return; | ||
146 | } | ||
147 | |||
148 | __pmd_idte(address, pmdp); | ||
149 | if (mm->context.noexec) { | ||
150 | pmdp = get_shadow_table(pmdp); | ||
151 | __pmd_idte(address, pmdp); | ||
152 | } | ||
153 | return; | ||
154 | } | ||
155 | |||
156 | #define huge_ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \ | ||
157 | ({ \ | ||
158 | int __changed = !pte_same(huge_ptep_get(__ptep), __entry); \ | ||
159 | if (__changed) { \ | ||
160 | huge_ptep_invalidate((__vma)->vm_mm, __addr, __ptep); \ | ||
161 | set_huge_pte_at((__vma)->vm_mm, __addr, __ptep, __entry); \ | ||
162 | } \ | ||
163 | __changed; \ | ||
164 | }) | ||
165 | |||
166 | #define huge_ptep_set_wrprotect(__mm, __addr, __ptep) \ | ||
167 | ({ \ | ||
168 | pte_t __pte = huge_ptep_get(__ptep); \ | ||
169 | if (pte_write(__pte)) { \ | ||
170 | if (atomic_read(&(__mm)->mm_users) > 1 || \ | ||
171 | (__mm) != current->active_mm) \ | ||
172 | huge_ptep_invalidate(__mm, __addr, __ptep); \ | ||
173 | set_huge_pte_at(__mm, __addr, __ptep, \ | ||
174 | huge_pte_wrprotect(__pte)); \ | ||
175 | } \ | ||
176 | }) | ||
177 | |||
178 | static inline void huge_ptep_clear_flush(struct vm_area_struct *vma, | ||
179 | unsigned long address, pte_t *ptep) | ||
180 | { | ||
181 | huge_ptep_invalidate(vma->vm_mm, address, ptep); | ||
182 | } | ||
183 | |||
184 | #endif /* _ASM_S390_HUGETLB_H */ | ||
diff --git a/arch/s390/include/asm/idals.h b/arch/s390/include/asm/idals.h new file mode 100644 index 000000000000..e82c10efe65a --- /dev/null +++ b/arch/s390/include/asm/idals.h | |||
@@ -0,0 +1,256 @@ | |||
1 | /* | ||
2 | * File...........: linux/include/asm-s390x/idals.h | ||
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | ||
4 | * Martin Schwidefsky <schwidefsky@de.ibm.com> | ||
5 | * Bugreports.to..: <Linux390@de.ibm.com> | ||
6 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 2000a | ||
7 | |||
8 | * History of changes | ||
9 | * 07/24/00 new file | ||
10 | * 05/04/02 code restructuring. | ||
11 | */ | ||
12 | |||
13 | #ifndef _S390_IDALS_H | ||
14 | #define _S390_IDALS_H | ||
15 | |||
16 | #include <linux/errno.h> | ||
17 | #include <linux/err.h> | ||
18 | #include <linux/types.h> | ||
19 | #include <linux/slab.h> | ||
20 | #include <asm/cio.h> | ||
21 | #include <asm/uaccess.h> | ||
22 | |||
23 | #ifdef __s390x__ | ||
24 | #define IDA_SIZE_LOG 12 /* 11 for 2k , 12 for 4k */ | ||
25 | #else | ||
26 | #define IDA_SIZE_LOG 11 /* 11 for 2k , 12 for 4k */ | ||
27 | #endif | ||
28 | #define IDA_BLOCK_SIZE (1L<<IDA_SIZE_LOG) | ||
29 | |||
30 | /* | ||
31 | * Test if an address/length pair needs an idal list. | ||
32 | */ | ||
33 | static inline int | ||
34 | idal_is_needed(void *vaddr, unsigned int length) | ||
35 | { | ||
36 | #ifdef __s390x__ | ||
37 | return ((__pa(vaddr) + length - 1) >> 31) != 0; | ||
38 | #else | ||
39 | return 0; | ||
40 | #endif | ||
41 | } | ||
42 | |||
43 | |||
44 | /* | ||
45 | * Return the number of idal words needed for an address/length pair. | ||
46 | */ | ||
47 | static inline unsigned int | ||
48 | idal_nr_words(void *vaddr, unsigned int length) | ||
49 | { | ||
50 | #ifdef __s390x__ | ||
51 | if (idal_is_needed(vaddr, length)) | ||
52 | return ((__pa(vaddr) & (IDA_BLOCK_SIZE-1)) + length + | ||
53 | (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG; | ||
54 | #endif | ||
55 | return 0; | ||
56 | } | ||
57 | |||
58 | /* | ||
59 | * Create the list of idal words for an address/length pair. | ||
60 | */ | ||
61 | static inline unsigned long * | ||
62 | idal_create_words(unsigned long *idaws, void *vaddr, unsigned int length) | ||
63 | { | ||
64 | #ifdef __s390x__ | ||
65 | unsigned long paddr; | ||
66 | unsigned int cidaw; | ||
67 | |||
68 | paddr = __pa(vaddr); | ||
69 | cidaw = ((paddr & (IDA_BLOCK_SIZE-1)) + length + | ||
70 | (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG; | ||
71 | *idaws++ = paddr; | ||
72 | paddr &= -IDA_BLOCK_SIZE; | ||
73 | while (--cidaw > 0) { | ||
74 | paddr += IDA_BLOCK_SIZE; | ||
75 | *idaws++ = paddr; | ||
76 | } | ||
77 | #endif | ||
78 | return idaws; | ||
79 | } | ||
80 | |||
81 | /* | ||
82 | * Sets the address of the data in CCW. | ||
83 | * If necessary it allocates an IDAL and sets the appropriate flags. | ||
84 | */ | ||
85 | static inline int | ||
86 | set_normalized_cda(struct ccw1 * ccw, void *vaddr) | ||
87 | { | ||
88 | #ifdef __s390x__ | ||
89 | unsigned int nridaws; | ||
90 | unsigned long *idal; | ||
91 | |||
92 | if (ccw->flags & CCW_FLAG_IDA) | ||
93 | return -EINVAL; | ||
94 | nridaws = idal_nr_words(vaddr, ccw->count); | ||
95 | if (nridaws > 0) { | ||
96 | idal = kmalloc(nridaws * sizeof(unsigned long), | ||
97 | GFP_ATOMIC | GFP_DMA ); | ||
98 | if (idal == NULL) | ||
99 | return -ENOMEM; | ||
100 | idal_create_words(idal, vaddr, ccw->count); | ||
101 | ccw->flags |= CCW_FLAG_IDA; | ||
102 | vaddr = idal; | ||
103 | } | ||
104 | #endif | ||
105 | ccw->cda = (__u32)(unsigned long) vaddr; | ||
106 | return 0; | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * Releases any allocated IDAL related to the CCW. | ||
111 | */ | ||
112 | static inline void | ||
113 | clear_normalized_cda(struct ccw1 * ccw) | ||
114 | { | ||
115 | #ifdef __s390x__ | ||
116 | if (ccw->flags & CCW_FLAG_IDA) { | ||
117 | kfree((void *)(unsigned long) ccw->cda); | ||
118 | ccw->flags &= ~CCW_FLAG_IDA; | ||
119 | } | ||
120 | #endif | ||
121 | ccw->cda = 0; | ||
122 | } | ||
123 | |||
124 | /* | ||
125 | * Idal buffer extension | ||
126 | */ | ||
127 | struct idal_buffer { | ||
128 | size_t size; | ||
129 | size_t page_order; | ||
130 | void *data[0]; | ||
131 | }; | ||
132 | |||
133 | /* | ||
134 | * Allocate an idal buffer | ||
135 | */ | ||
136 | static inline struct idal_buffer * | ||
137 | idal_buffer_alloc(size_t size, int page_order) | ||
138 | { | ||
139 | struct idal_buffer *ib; | ||
140 | int nr_chunks, nr_ptrs, i; | ||
141 | |||
142 | nr_ptrs = (size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_LOG; | ||
143 | nr_chunks = (4096 << page_order) >> IDA_SIZE_LOG; | ||
144 | ib = kmalloc(sizeof(struct idal_buffer) + nr_ptrs*sizeof(void *), | ||
145 | GFP_DMA | GFP_KERNEL); | ||
146 | if (ib == NULL) | ||
147 | return ERR_PTR(-ENOMEM); | ||
148 | ib->size = size; | ||
149 | ib->page_order = page_order; | ||
150 | for (i = 0; i < nr_ptrs; i++) { | ||
151 | if ((i & (nr_chunks - 1)) != 0) { | ||
152 | ib->data[i] = ib->data[i-1] + IDA_BLOCK_SIZE; | ||
153 | continue; | ||
154 | } | ||
155 | ib->data[i] = (void *) | ||
156 | __get_free_pages(GFP_KERNEL, page_order); | ||
157 | if (ib->data[i] != NULL) | ||
158 | continue; | ||
159 | // Not enough memory | ||
160 | while (i >= nr_chunks) { | ||
161 | i -= nr_chunks; | ||
162 | free_pages((unsigned long) ib->data[i], | ||
163 | ib->page_order); | ||
164 | } | ||
165 | kfree(ib); | ||
166 | return ERR_PTR(-ENOMEM); | ||
167 | } | ||
168 | return ib; | ||
169 | } | ||
170 | |||
171 | /* | ||
172 | * Free an idal buffer. | ||
173 | */ | ||
174 | static inline void | ||
175 | idal_buffer_free(struct idal_buffer *ib) | ||
176 | { | ||
177 | int nr_chunks, nr_ptrs, i; | ||
178 | |||
179 | nr_ptrs = (ib->size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_LOG; | ||
180 | nr_chunks = (4096 << ib->page_order) >> IDA_SIZE_LOG; | ||
181 | for (i = 0; i < nr_ptrs; i += nr_chunks) | ||
182 | free_pages((unsigned long) ib->data[i], ib->page_order); | ||
183 | kfree(ib); | ||
184 | } | ||
185 | |||
186 | /* | ||
187 | * Test if a idal list is really needed. | ||
188 | */ | ||
189 | static inline int | ||
190 | __idal_buffer_is_needed(struct idal_buffer *ib) | ||
191 | { | ||
192 | #ifdef __s390x__ | ||
193 | return ib->size > (4096ul << ib->page_order) || | ||
194 | idal_is_needed(ib->data[0], ib->size); | ||
195 | #else | ||
196 | return ib->size > (4096ul << ib->page_order); | ||
197 | #endif | ||
198 | } | ||
199 | |||
200 | /* | ||
201 | * Set channel data address to idal buffer. | ||
202 | */ | ||
203 | static inline void | ||
204 | idal_buffer_set_cda(struct idal_buffer *ib, struct ccw1 *ccw) | ||
205 | { | ||
206 | if (__idal_buffer_is_needed(ib)) { | ||
207 | // setup idals; | ||
208 | ccw->cda = (u32)(addr_t) ib->data; | ||
209 | ccw->flags |= CCW_FLAG_IDA; | ||
210 | } else | ||
211 | // we do not need idals - use direct addressing | ||
212 | ccw->cda = (u32)(addr_t) ib->data[0]; | ||
213 | ccw->count = ib->size; | ||
214 | } | ||
215 | |||
216 | /* | ||
217 | * Copy count bytes from an idal buffer to user memory | ||
218 | */ | ||
219 | static inline size_t | ||
220 | idal_buffer_to_user(struct idal_buffer *ib, void __user *to, size_t count) | ||
221 | { | ||
222 | size_t left; | ||
223 | int i; | ||
224 | |||
225 | BUG_ON(count > ib->size); | ||
226 | for (i = 0; count > IDA_BLOCK_SIZE; i++) { | ||
227 | left = copy_to_user(to, ib->data[i], IDA_BLOCK_SIZE); | ||
228 | if (left) | ||
229 | return left + count - IDA_BLOCK_SIZE; | ||
230 | to = (void __user *) to + IDA_BLOCK_SIZE; | ||
231 | count -= IDA_BLOCK_SIZE; | ||
232 | } | ||
233 | return copy_to_user(to, ib->data[i], count); | ||
234 | } | ||
235 | |||
236 | /* | ||
237 | * Copy count bytes from user memory to an idal buffer | ||
238 | */ | ||
239 | static inline size_t | ||
240 | idal_buffer_from_user(struct idal_buffer *ib, const void __user *from, size_t count) | ||
241 | { | ||
242 | size_t left; | ||
243 | int i; | ||
244 | |||
245 | BUG_ON(count > ib->size); | ||
246 | for (i = 0; count > IDA_BLOCK_SIZE; i++) { | ||
247 | left = copy_from_user(ib->data[i], from, IDA_BLOCK_SIZE); | ||
248 | if (left) | ||
249 | return left + count - IDA_BLOCK_SIZE; | ||
250 | from = (void __user *) from + IDA_BLOCK_SIZE; | ||
251 | count -= IDA_BLOCK_SIZE; | ||
252 | } | ||
253 | return copy_from_user(ib->data[i], from, count); | ||
254 | } | ||
255 | |||
256 | #endif | ||
diff --git a/arch/s390/include/asm/io.h b/arch/s390/include/asm/io.h new file mode 100644 index 000000000000..b7ff6afc3caa --- /dev/null +++ b/arch/s390/include/asm/io.h | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * include/asm-s390/io.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
7 | * | ||
8 | * Derived from "include/asm-i386/io.h" | ||
9 | */ | ||
10 | |||
11 | #ifndef _S390_IO_H | ||
12 | #define _S390_IO_H | ||
13 | |||
14 | #ifdef __KERNEL__ | ||
15 | |||
16 | #include <asm/page.h> | ||
17 | |||
18 | #define IO_SPACE_LIMIT 0xffffffff | ||
19 | |||
20 | /* | ||
21 | * Change virtual addresses to physical addresses and vv. | ||
22 | * These are pretty trivial | ||
23 | */ | ||
24 | static inline unsigned long virt_to_phys(volatile void * address) | ||
25 | { | ||
26 | unsigned long real_address; | ||
27 | asm volatile( | ||
28 | " lra %0,0(%1)\n" | ||
29 | " jz 0f\n" | ||
30 | " la %0,0\n" | ||
31 | "0:" | ||
32 | : "=a" (real_address) : "a" (address) : "cc"); | ||
33 | return real_address; | ||
34 | } | ||
35 | |||
36 | static inline void * phys_to_virt(unsigned long address) | ||
37 | { | ||
38 | return (void *) address; | ||
39 | } | ||
40 | |||
41 | /* | ||
42 | * Convert a physical pointer to a virtual kernel pointer for /dev/mem | ||
43 | * access | ||
44 | */ | ||
45 | #define xlate_dev_mem_ptr(p) __va(p) | ||
46 | |||
47 | /* | ||
48 | * Convert a virtual cached pointer to an uncached pointer | ||
49 | */ | ||
50 | #define xlate_dev_kmem_ptr(p) p | ||
51 | |||
52 | #endif /* __KERNEL__ */ | ||
53 | |||
54 | #endif | ||
diff --git a/arch/s390/include/asm/ioctl.h b/arch/s390/include/asm/ioctl.h new file mode 100644 index 000000000000..b279fe06dfe5 --- /dev/null +++ b/arch/s390/include/asm/ioctl.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/ioctl.h> | |||
diff --git a/arch/s390/include/asm/ioctls.h b/arch/s390/include/asm/ioctls.h new file mode 100644 index 000000000000..40e481b1b461 --- /dev/null +++ b/arch/s390/include/asm/ioctls.h | |||
@@ -0,0 +1,92 @@ | |||
1 | /* | ||
2 | * include/asm-s390/ioctls.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/ioctls.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef __ARCH_S390_IOCTLS_H__ | ||
10 | #define __ARCH_S390_IOCTLS_H__ | ||
11 | |||
12 | #include <asm/ioctl.h> | ||
13 | |||
14 | /* 0x54 is just a magic number to make these relatively unique ('T') */ | ||
15 | |||
16 | #define TCGETS 0x5401 | ||
17 | #define TCSETS 0x5402 | ||
18 | #define TCSETSW 0x5403 | ||
19 | #define TCSETSF 0x5404 | ||
20 | #define TCGETA 0x5405 | ||
21 | #define TCSETA 0x5406 | ||
22 | #define TCSETAW 0x5407 | ||
23 | #define TCSETAF 0x5408 | ||
24 | #define TCSBRK 0x5409 | ||
25 | #define TCXONC 0x540A | ||
26 | #define TCFLSH 0x540B | ||
27 | #define TIOCEXCL 0x540C | ||
28 | #define TIOCNXCL 0x540D | ||
29 | #define TIOCSCTTY 0x540E | ||
30 | #define TIOCGPGRP 0x540F | ||
31 | #define TIOCSPGRP 0x5410 | ||
32 | #define TIOCOUTQ 0x5411 | ||
33 | #define TIOCSTI 0x5412 | ||
34 | #define TIOCGWINSZ 0x5413 | ||
35 | #define TIOCSWINSZ 0x5414 | ||
36 | #define TIOCMGET 0x5415 | ||
37 | #define TIOCMBIS 0x5416 | ||
38 | #define TIOCMBIC 0x5417 | ||
39 | #define TIOCMSET 0x5418 | ||
40 | #define TIOCGSOFTCAR 0x5419 | ||
41 | #define TIOCSSOFTCAR 0x541A | ||
42 | #define FIONREAD 0x541B | ||
43 | #define TIOCINQ FIONREAD | ||
44 | #define TIOCLINUX 0x541C | ||
45 | #define TIOCCONS 0x541D | ||
46 | #define TIOCGSERIAL 0x541E | ||
47 | #define TIOCSSERIAL 0x541F | ||
48 | #define TIOCPKT 0x5420 | ||
49 | #define FIONBIO 0x5421 | ||
50 | #define TIOCNOTTY 0x5422 | ||
51 | #define TIOCSETD 0x5423 | ||
52 | #define TIOCGETD 0x5424 | ||
53 | #define TCSBRKP 0x5425 /* Needed for POSIX tcsendbreak() */ | ||
54 | #define TIOCSBRK 0x5427 /* BSD compatibility */ | ||
55 | #define TIOCCBRK 0x5428 /* BSD compatibility */ | ||
56 | #define TIOCGSID 0x5429 /* Return the session ID of FD */ | ||
57 | #define TCGETS2 _IOR('T',0x2A, struct termios2) | ||
58 | #define TCSETS2 _IOW('T',0x2B, struct termios2) | ||
59 | #define TCSETSW2 _IOW('T',0x2C, struct termios2) | ||
60 | #define TCSETSF2 _IOW('T',0x2D, struct termios2) | ||
61 | #define TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ | ||
62 | #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ | ||
63 | |||
64 | #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ | ||
65 | #define FIOCLEX 0x5451 | ||
66 | #define FIOASYNC 0x5452 | ||
67 | #define TIOCSERCONFIG 0x5453 | ||
68 | #define TIOCSERGWILD 0x5454 | ||
69 | #define TIOCSERSWILD 0x5455 | ||
70 | #define TIOCGLCKTRMIOS 0x5456 | ||
71 | #define TIOCSLCKTRMIOS 0x5457 | ||
72 | #define TIOCSERGSTRUCT 0x5458 /* For debugging only */ | ||
73 | #define TIOCSERGETLSR 0x5459 /* Get line status register */ | ||
74 | #define TIOCSERGETMULTI 0x545A /* Get multiport config */ | ||
75 | #define TIOCSERSETMULTI 0x545B /* Set multiport config */ | ||
76 | |||
77 | #define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ | ||
78 | #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ | ||
79 | #define FIOQSIZE 0x545E | ||
80 | |||
81 | /* Used for packet mode */ | ||
82 | #define TIOCPKT_DATA 0 | ||
83 | #define TIOCPKT_FLUSHREAD 1 | ||
84 | #define TIOCPKT_FLUSHWRITE 2 | ||
85 | #define TIOCPKT_STOP 4 | ||
86 | #define TIOCPKT_START 8 | ||
87 | #define TIOCPKT_NOSTOP 16 | ||
88 | #define TIOCPKT_DOSTOP 32 | ||
89 | |||
90 | #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ | ||
91 | |||
92 | #endif | ||
diff --git a/arch/s390/include/asm/ipcbuf.h b/arch/s390/include/asm/ipcbuf.h new file mode 100644 index 000000000000..37f293d12c8f --- /dev/null +++ b/arch/s390/include/asm/ipcbuf.h | |||
@@ -0,0 +1,31 @@ | |||
1 | #ifndef __S390_IPCBUF_H__ | ||
2 | #define __S390_IPCBUF_H__ | ||
3 | |||
4 | /* | ||
5 | * The user_ipc_perm structure for S/390 architecture. | ||
6 | * Note extra padding because this structure is passed back and forth | ||
7 | * between kernel and user space. | ||
8 | * | ||
9 | * Pad space is left for: | ||
10 | * - 32-bit mode_t and seq | ||
11 | * - 2 miscellaneous 32-bit values | ||
12 | */ | ||
13 | |||
14 | struct ipc64_perm | ||
15 | { | ||
16 | __kernel_key_t key; | ||
17 | __kernel_uid32_t uid; | ||
18 | __kernel_gid32_t gid; | ||
19 | __kernel_uid32_t cuid; | ||
20 | __kernel_gid32_t cgid; | ||
21 | __kernel_mode_t mode; | ||
22 | unsigned short __pad1; | ||
23 | unsigned short seq; | ||
24 | #ifndef __s390x__ | ||
25 | unsigned short __pad2; | ||
26 | #endif /* ! __s390x__ */ | ||
27 | unsigned long __unused1; | ||
28 | unsigned long __unused2; | ||
29 | }; | ||
30 | |||
31 | #endif /* __S390_IPCBUF_H__ */ | ||
diff --git a/arch/s390/include/asm/ipl.h b/arch/s390/include/asm/ipl.h new file mode 100644 index 000000000000..1171e6d144a3 --- /dev/null +++ b/arch/s390/include/asm/ipl.h | |||
@@ -0,0 +1,168 @@ | |||
1 | /* | ||
2 | * s390 (re)ipl support | ||
3 | * | ||
4 | * Copyright IBM Corp. 2007 | ||
5 | */ | ||
6 | |||
7 | #ifndef _ASM_S390_IPL_H | ||
8 | #define _ASM_S390_IPL_H | ||
9 | |||
10 | #include <asm/types.h> | ||
11 | #include <asm/cio.h> | ||
12 | #include <asm/setup.h> | ||
13 | |||
14 | #define IPL_PARMBLOCK_ORIGIN 0x2000 | ||
15 | |||
16 | #define IPL_PARM_BLK_FCP_LEN (sizeof(struct ipl_list_hdr) + \ | ||
17 | sizeof(struct ipl_block_fcp)) | ||
18 | |||
19 | #define IPL_PARM_BLK0_FCP_LEN (sizeof(struct ipl_block_fcp) + 8) | ||
20 | |||
21 | #define IPL_PARM_BLK_CCW_LEN (sizeof(struct ipl_list_hdr) + \ | ||
22 | sizeof(struct ipl_block_ccw)) | ||
23 | |||
24 | #define IPL_PARM_BLK0_CCW_LEN (sizeof(struct ipl_block_ccw) + 8) | ||
25 | |||
26 | #define IPL_MAX_SUPPORTED_VERSION (0) | ||
27 | |||
28 | #define IPL_PARMBLOCK_START ((struct ipl_parameter_block *) \ | ||
29 | IPL_PARMBLOCK_ORIGIN) | ||
30 | #define IPL_PARMBLOCK_SIZE (IPL_PARMBLOCK_START->hdr.len) | ||
31 | |||
32 | struct ipl_list_hdr { | ||
33 | u32 len; | ||
34 | u8 reserved1[3]; | ||
35 | u8 version; | ||
36 | u32 blk0_len; | ||
37 | u8 pbt; | ||
38 | u8 flags; | ||
39 | u16 reserved2; | ||
40 | } __attribute__((packed)); | ||
41 | |||
42 | struct ipl_block_fcp { | ||
43 | u8 reserved1[313-1]; | ||
44 | u8 opt; | ||
45 | u8 reserved2[3]; | ||
46 | u16 reserved3; | ||
47 | u16 devno; | ||
48 | u8 reserved4[4]; | ||
49 | u64 wwpn; | ||
50 | u64 lun; | ||
51 | u32 bootprog; | ||
52 | u8 reserved5[12]; | ||
53 | u64 br_lba; | ||
54 | u32 scp_data_len; | ||
55 | u8 reserved6[260]; | ||
56 | u8 scp_data[]; | ||
57 | } __attribute__((packed)); | ||
58 | |||
59 | #define DIAG308_VMPARM_SIZE 64 | ||
60 | |||
61 | struct ipl_block_ccw { | ||
62 | u8 load_parm[8]; | ||
63 | u8 reserved1[84]; | ||
64 | u8 reserved2[2]; | ||
65 | u16 devno; | ||
66 | u8 vm_flags; | ||
67 | u8 reserved3[3]; | ||
68 | u32 vm_parm_len; | ||
69 | u8 nss_name[8]; | ||
70 | u8 vm_parm[DIAG308_VMPARM_SIZE]; | ||
71 | u8 reserved4[8]; | ||
72 | } __attribute__((packed)); | ||
73 | |||
74 | struct ipl_parameter_block { | ||
75 | struct ipl_list_hdr hdr; | ||
76 | union { | ||
77 | struct ipl_block_fcp fcp; | ||
78 | struct ipl_block_ccw ccw; | ||
79 | } ipl_info; | ||
80 | } __attribute__((packed,aligned(4096))); | ||
81 | |||
82 | /* | ||
83 | * IPL validity flags | ||
84 | */ | ||
85 | extern u32 ipl_flags; | ||
86 | extern u32 dump_prefix_page; | ||
87 | extern unsigned int zfcpdump_prefix_array[]; | ||
88 | |||
89 | extern void do_reipl(void); | ||
90 | extern void do_halt(void); | ||
91 | extern void do_poff(void); | ||
92 | extern void ipl_save_parameters(void); | ||
93 | extern void ipl_update_parameters(void); | ||
94 | extern void get_ipl_vmparm(char *); | ||
95 | |||
96 | enum { | ||
97 | IPL_DEVNO_VALID = 1, | ||
98 | IPL_PARMBLOCK_VALID = 2, | ||
99 | IPL_NSS_VALID = 4, | ||
100 | }; | ||
101 | |||
102 | enum ipl_type { | ||
103 | IPL_TYPE_UNKNOWN = 1, | ||
104 | IPL_TYPE_CCW = 2, | ||
105 | IPL_TYPE_FCP = 4, | ||
106 | IPL_TYPE_FCP_DUMP = 8, | ||
107 | IPL_TYPE_NSS = 16, | ||
108 | }; | ||
109 | |||
110 | struct ipl_info | ||
111 | { | ||
112 | enum ipl_type type; | ||
113 | union { | ||
114 | struct { | ||
115 | struct ccw_dev_id dev_id; | ||
116 | } ccw; | ||
117 | struct { | ||
118 | struct ccw_dev_id dev_id; | ||
119 | u64 wwpn; | ||
120 | u64 lun; | ||
121 | } fcp; | ||
122 | struct { | ||
123 | char name[NSS_NAME_SIZE + 1]; | ||
124 | } nss; | ||
125 | } data; | ||
126 | }; | ||
127 | |||
128 | extern struct ipl_info ipl_info; | ||
129 | extern void setup_ipl(void); | ||
130 | |||
131 | /* | ||
132 | * DIAG 308 support | ||
133 | */ | ||
134 | enum diag308_subcode { | ||
135 | DIAG308_REL_HSA = 2, | ||
136 | DIAG308_IPL = 3, | ||
137 | DIAG308_DUMP = 4, | ||
138 | DIAG308_SET = 5, | ||
139 | DIAG308_STORE = 6, | ||
140 | }; | ||
141 | |||
142 | enum diag308_ipl_type { | ||
143 | DIAG308_IPL_TYPE_FCP = 0, | ||
144 | DIAG308_IPL_TYPE_CCW = 2, | ||
145 | }; | ||
146 | |||
147 | enum diag308_opt { | ||
148 | DIAG308_IPL_OPT_IPL = 0x10, | ||
149 | DIAG308_IPL_OPT_DUMP = 0x20, | ||
150 | }; | ||
151 | |||
152 | enum diag308_flags { | ||
153 | DIAG308_FLAGS_LP_VALID = 0x80, | ||
154 | }; | ||
155 | |||
156 | enum diag308_vm_flags { | ||
157 | DIAG308_VM_FLAGS_NSS_VALID = 0x80, | ||
158 | DIAG308_VM_FLAGS_VP_VALID = 0x40, | ||
159 | }; | ||
160 | |||
161 | enum diag308_rc { | ||
162 | DIAG308_RC_OK = 0x0001, | ||
163 | DIAG308_RC_NOCONFIG = 0x0102, | ||
164 | }; | ||
165 | |||
166 | extern int diag308(unsigned long subcode, void *addr); | ||
167 | |||
168 | #endif /* _ASM_S390_IPL_H */ | ||
diff --git a/arch/s390/include/asm/irq.h b/arch/s390/include/asm/irq.h new file mode 100644 index 000000000000..7da991a858f8 --- /dev/null +++ b/arch/s390/include/asm/irq.h | |||
@@ -0,0 +1,23 @@ | |||
1 | #ifndef _ASM_IRQ_H | ||
2 | #define _ASM_IRQ_H | ||
3 | |||
4 | #ifdef __KERNEL__ | ||
5 | #include <linux/hardirq.h> | ||
6 | |||
7 | /* | ||
8 | * the definition of irqs has changed in 2.5.46: | ||
9 | * NR_IRQS is no longer the number of i/o | ||
10 | * interrupts (65536), but rather the number | ||
11 | * of interrupt classes (2). | ||
12 | * Only external and i/o interrupts make much sense here (CH). | ||
13 | */ | ||
14 | |||
15 | enum interruption_class { | ||
16 | EXTERNAL_INTERRUPT, | ||
17 | IO_INTERRUPT, | ||
18 | |||
19 | NR_IRQS, | ||
20 | }; | ||
21 | |||
22 | #endif /* __KERNEL__ */ | ||
23 | #endif | ||
diff --git a/arch/s390/include/asm/irq_regs.h b/arch/s390/include/asm/irq_regs.h new file mode 100644 index 000000000000..3dd9c0b70270 --- /dev/null +++ b/arch/s390/include/asm/irq_regs.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/irq_regs.h> | |||
diff --git a/arch/s390/include/asm/irqflags.h b/arch/s390/include/asm/irqflags.h new file mode 100644 index 000000000000..3f26131120b7 --- /dev/null +++ b/arch/s390/include/asm/irqflags.h | |||
@@ -0,0 +1,106 @@ | |||
1 | /* | ||
2 | * include/asm-s390/irqflags.h | ||
3 | * | ||
4 | * Copyright (C) IBM Corp. 2006 | ||
5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #ifndef __ASM_IRQFLAGS_H | ||
9 | #define __ASM_IRQFLAGS_H | ||
10 | |||
11 | #ifdef __KERNEL__ | ||
12 | |||
13 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | ||
14 | |||
15 | /* store then or system mask. */ | ||
16 | #define __raw_local_irq_stosm(__or) \ | ||
17 | ({ \ | ||
18 | unsigned long __mask; \ | ||
19 | asm volatile( \ | ||
20 | " stosm %0,%1" \ | ||
21 | : "=Q" (__mask) : "i" (__or) : "memory"); \ | ||
22 | __mask; \ | ||
23 | }) | ||
24 | |||
25 | /* store then and system mask. */ | ||
26 | #define __raw_local_irq_stnsm(__and) \ | ||
27 | ({ \ | ||
28 | unsigned long __mask; \ | ||
29 | asm volatile( \ | ||
30 | " stnsm %0,%1" \ | ||
31 | : "=Q" (__mask) : "i" (__and) : "memory"); \ | ||
32 | __mask; \ | ||
33 | }) | ||
34 | |||
35 | /* set system mask. */ | ||
36 | #define __raw_local_irq_ssm(__mask) \ | ||
37 | ({ \ | ||
38 | asm volatile("ssm %0" : : "Q" (__mask) : "memory"); \ | ||
39 | }) | ||
40 | |||
41 | #else /* __GNUC__ */ | ||
42 | |||
43 | /* store then or system mask. */ | ||
44 | #define __raw_local_irq_stosm(__or) \ | ||
45 | ({ \ | ||
46 | unsigned long __mask; \ | ||
47 | asm volatile( \ | ||
48 | " stosm 0(%1),%2" \ | ||
49 | : "=m" (__mask) \ | ||
50 | : "a" (&__mask), "i" (__or) : "memory"); \ | ||
51 | __mask; \ | ||
52 | }) | ||
53 | |||
54 | /* store then and system mask. */ | ||
55 | #define __raw_local_irq_stnsm(__and) \ | ||
56 | ({ \ | ||
57 | unsigned long __mask; \ | ||
58 | asm volatile( \ | ||
59 | " stnsm 0(%1),%2" \ | ||
60 | : "=m" (__mask) \ | ||
61 | : "a" (&__mask), "i" (__and) : "memory"); \ | ||
62 | __mask; \ | ||
63 | }) | ||
64 | |||
65 | /* set system mask. */ | ||
66 | #define __raw_local_irq_ssm(__mask) \ | ||
67 | ({ \ | ||
68 | asm volatile( \ | ||
69 | " ssm 0(%0)" \ | ||
70 | : : "a" (&__mask), "m" (__mask) : "memory"); \ | ||
71 | }) | ||
72 | |||
73 | #endif /* __GNUC__ */ | ||
74 | |||
75 | /* interrupt control.. */ | ||
76 | static inline unsigned long raw_local_irq_enable(void) | ||
77 | { | ||
78 | return __raw_local_irq_stosm(0x03); | ||
79 | } | ||
80 | |||
81 | static inline unsigned long raw_local_irq_disable(void) | ||
82 | { | ||
83 | return __raw_local_irq_stnsm(0xfc); | ||
84 | } | ||
85 | |||
86 | #define raw_local_save_flags(x) \ | ||
87 | do { \ | ||
88 | typecheck(unsigned long, x); \ | ||
89 | (x) = __raw_local_irq_stosm(0x00); \ | ||
90 | } while (0) | ||
91 | |||
92 | static inline void raw_local_irq_restore(unsigned long flags) | ||
93 | { | ||
94 | __raw_local_irq_ssm(flags); | ||
95 | } | ||
96 | |||
97 | static inline int raw_irqs_disabled_flags(unsigned long flags) | ||
98 | { | ||
99 | return !(flags & (3UL << (BITS_PER_LONG - 8))); | ||
100 | } | ||
101 | |||
102 | /* For spinlocks etc */ | ||
103 | #define raw_local_irq_save(x) ((x) = raw_local_irq_disable()) | ||
104 | |||
105 | #endif /* __KERNEL__ */ | ||
106 | #endif /* __ASM_IRQFLAGS_H */ | ||
diff --git a/arch/s390/include/asm/isc.h b/arch/s390/include/asm/isc.h new file mode 100644 index 000000000000..34bb8916db4f --- /dev/null +++ b/arch/s390/include/asm/isc.h | |||
@@ -0,0 +1,25 @@ | |||
1 | #ifndef _ASM_S390_ISC_H | ||
2 | #define _ASM_S390_ISC_H | ||
3 | |||
4 | #include <linux/types.h> | ||
5 | |||
6 | /* | ||
7 | * I/O interruption subclasses used by drivers. | ||
8 | * Please add all used iscs here so that it is possible to distribute | ||
9 | * isc usage between drivers. | ||
10 | * Reminder: 0 is highest priority, 7 lowest. | ||
11 | */ | ||
12 | #define MAX_ISC 7 | ||
13 | |||
14 | /* Regular I/O interrupts. */ | ||
15 | #define IO_SCH_ISC 3 /* regular I/O subchannels */ | ||
16 | #define CONSOLE_ISC 1 /* console I/O subchannel */ | ||
17 | #define CHSC_SCH_ISC 7 /* CHSC subchannels */ | ||
18 | /* Adapter interrupts. */ | ||
19 | #define QDIO_AIRQ_ISC IO_SCH_ISC /* I/O subchannel in qdio mode */ | ||
20 | |||
21 | /* Functions for registration of I/O interruption subclasses */ | ||
22 | void isc_register(unsigned int isc); | ||
23 | void isc_unregister(unsigned int isc); | ||
24 | |||
25 | #endif /* _ASM_S390_ISC_H */ | ||
diff --git a/arch/s390/include/asm/itcw.h b/arch/s390/include/asm/itcw.h new file mode 100644 index 000000000000..a9bc5c36b32a --- /dev/null +++ b/arch/s390/include/asm/itcw.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * Functions for incremental construction of fcx enabled I/O control blocks. | ||
3 | * | ||
4 | * Copyright IBM Corp. 2008 | ||
5 | * Author(s): Peter Oberparleiter <peter.oberparleiter@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_S390_ITCW_H | ||
9 | #define _ASM_S390_ITCW_H _ASM_S390_ITCW_H | ||
10 | |||
11 | #include <linux/types.h> | ||
12 | #include <asm/fcx.h> | ||
13 | |||
14 | #define ITCW_OP_READ 0 | ||
15 | #define ITCW_OP_WRITE 1 | ||
16 | |||
17 | struct itcw; | ||
18 | |||
19 | struct tcw *itcw_get_tcw(struct itcw *itcw); | ||
20 | size_t itcw_calc_size(int intrg, int max_tidaws, int intrg_max_tidaws); | ||
21 | struct itcw *itcw_init(void *buffer, size_t size, int op, int intrg, | ||
22 | int max_tidaws, int intrg_max_tidaws); | ||
23 | struct dcw *itcw_add_dcw(struct itcw *itcw, u8 cmd, u8 flags, void *cd, | ||
24 | u8 cd_count, u32 count); | ||
25 | struct tidaw *itcw_add_tidaw(struct itcw *itcw, u8 flags, void *addr, | ||
26 | u32 count); | ||
27 | void itcw_set_data(struct itcw *itcw, void *addr, int use_tidal); | ||
28 | void itcw_finalize(struct itcw *itcw); | ||
29 | |||
30 | #endif /* _ASM_S390_ITCW_H */ | ||
diff --git a/arch/s390/include/asm/kdebug.h b/arch/s390/include/asm/kdebug.h new file mode 100644 index 000000000000..40db27cd6e60 --- /dev/null +++ b/arch/s390/include/asm/kdebug.h | |||
@@ -0,0 +1,27 @@ | |||
1 | #ifndef _S390_KDEBUG_H | ||
2 | #define _S390_KDEBUG_H | ||
3 | |||
4 | /* | ||
5 | * Feb 2006 Ported to s390 <grundym@us.ibm.com> | ||
6 | */ | ||
7 | |||
8 | struct pt_regs; | ||
9 | |||
10 | enum die_val { | ||
11 | DIE_OOPS = 1, | ||
12 | DIE_BPT, | ||
13 | DIE_SSTEP, | ||
14 | DIE_PANIC, | ||
15 | DIE_NMI, | ||
16 | DIE_DIE, | ||
17 | DIE_NMIWATCHDOG, | ||
18 | DIE_KERNELDEBUG, | ||
19 | DIE_TRAP, | ||
20 | DIE_GPF, | ||
21 | DIE_CALL, | ||
22 | DIE_NMI_IPI, | ||
23 | }; | ||
24 | |||
25 | extern void die(const char *, struct pt_regs *, long); | ||
26 | |||
27 | #endif | ||
diff --git a/arch/s390/include/asm/kexec.h b/arch/s390/include/asm/kexec.h new file mode 100644 index 000000000000..f219c6411e0b --- /dev/null +++ b/arch/s390/include/asm/kexec.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * include/asm-s390/kexec.h | ||
3 | * | ||
4 | * (C) Copyright IBM Corp. 2005 | ||
5 | * | ||
6 | * Author(s): Rolf Adelsberger <adelsberger@de.ibm.com> | ||
7 | * | ||
8 | */ | ||
9 | |||
10 | #ifndef _S390_KEXEC_H | ||
11 | #define _S390_KEXEC_H | ||
12 | |||
13 | #ifdef __KERNEL__ | ||
14 | #include <asm/page.h> | ||
15 | #endif | ||
16 | #include <asm/processor.h> | ||
17 | /* | ||
18 | * KEXEC_SOURCE_MEMORY_LIMIT maximum page get_free_page can return. | ||
19 | * I.e. Maximum page that is mapped directly into kernel memory, | ||
20 | * and kmap is not required. | ||
21 | */ | ||
22 | |||
23 | /* Maximum physical address we can use pages from */ | ||
24 | #define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) | ||
25 | |||
26 | /* Maximum address we can reach in physical address mode */ | ||
27 | #define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) | ||
28 | |||
29 | /* Maximum address we can use for the control pages */ | ||
30 | /* Not more than 2GB */ | ||
31 | #define KEXEC_CONTROL_MEMORY_LIMIT (1UL<<31) | ||
32 | |||
33 | /* Allocate one page for the pdp and the second for the code */ | ||
34 | #define KEXEC_CONTROL_CODE_SIZE 4096 | ||
35 | |||
36 | /* The native architecture */ | ||
37 | #define KEXEC_ARCH KEXEC_ARCH_S390 | ||
38 | |||
39 | /* Provide a dummy definition to avoid build failures. */ | ||
40 | static inline void crash_setup_regs(struct pt_regs *newregs, | ||
41 | struct pt_regs *oldregs) { } | ||
42 | |||
43 | #endif /*_S390_KEXEC_H */ | ||
diff --git a/arch/s390/include/asm/kmap_types.h b/arch/s390/include/asm/kmap_types.h new file mode 100644 index 000000000000..fd1574648223 --- /dev/null +++ b/arch/s390/include/asm/kmap_types.h | |||
@@ -0,0 +1,23 @@ | |||
1 | #ifdef __KERNEL__ | ||
2 | #ifndef _ASM_KMAP_TYPES_H | ||
3 | #define _ASM_KMAP_TYPES_H | ||
4 | |||
5 | enum km_type { | ||
6 | KM_BOUNCE_READ, | ||
7 | KM_SKB_SUNRPC_DATA, | ||
8 | KM_SKB_DATA_SOFTIRQ, | ||
9 | KM_USER0, | ||
10 | KM_USER1, | ||
11 | KM_BIO_SRC_IRQ, | ||
12 | KM_BIO_DST_IRQ, | ||
13 | KM_PTE0, | ||
14 | KM_PTE1, | ||
15 | KM_IRQ0, | ||
16 | KM_IRQ1, | ||
17 | KM_SOFTIRQ0, | ||
18 | KM_SOFTIRQ1, | ||
19 | KM_TYPE_NR | ||
20 | }; | ||
21 | |||
22 | #endif | ||
23 | #endif /* __KERNEL__ */ | ||
diff --git a/arch/s390/include/asm/kprobes.h b/arch/s390/include/asm/kprobes.h new file mode 100644 index 000000000000..330f68caffe4 --- /dev/null +++ b/arch/s390/include/asm/kprobes.h | |||
@@ -0,0 +1,103 @@ | |||
1 | #ifndef _ASM_S390_KPROBES_H | ||
2 | #define _ASM_S390_KPROBES_H | ||
3 | /* | ||
4 | * Kernel Probes (KProbes) | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License as published by | ||
8 | * the Free Software Foundation; either version 2 of the License, or | ||
9 | * (at your option) any later version. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. | ||
19 | * | ||
20 | * Copyright (C) IBM Corporation, 2002, 2006 | ||
21 | * | ||
22 | * 2002-Oct Created by Vamsi Krishna S <vamsi_krishna@in.ibm.com> Kernel | ||
23 | * Probes initial implementation ( includes suggestions from | ||
24 | * Rusty Russell). | ||
25 | * 2004-Nov Modified for PPC64 by Ananth N Mavinakayanahalli | ||
26 | * <ananth@in.ibm.com> | ||
27 | * 2005-Dec Used as a template for s390 by Mike Grundy | ||
28 | * <grundym@us.ibm.com> | ||
29 | */ | ||
30 | #include <linux/types.h> | ||
31 | #include <linux/ptrace.h> | ||
32 | #include <linux/percpu.h> | ||
33 | |||
34 | #define __ARCH_WANT_KPROBES_INSN_SLOT | ||
35 | struct pt_regs; | ||
36 | struct kprobe; | ||
37 | |||
38 | typedef u16 kprobe_opcode_t; | ||
39 | #define BREAKPOINT_INSTRUCTION 0x0002 | ||
40 | |||
41 | /* Maximum instruction size is 3 (16bit) halfwords: */ | ||
42 | #define MAX_INSN_SIZE 0x0003 | ||
43 | #define MAX_STACK_SIZE 64 | ||
44 | #define MIN_STACK_SIZE(ADDR) (((MAX_STACK_SIZE) < \ | ||
45 | (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) \ | ||
46 | ? (MAX_STACK_SIZE) \ | ||
47 | : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) | ||
48 | |||
49 | #define kretprobe_blacklist_size 0 | ||
50 | |||
51 | #define KPROBE_SWAP_INST 0x10 | ||
52 | |||
53 | #define FIXUP_PSW_NORMAL 0x08 | ||
54 | #define FIXUP_BRANCH_NOT_TAKEN 0x04 | ||
55 | #define FIXUP_RETURN_REGISTER 0x02 | ||
56 | #define FIXUP_NOT_REQUIRED 0x01 | ||
57 | |||
58 | /* Architecture specific copy of original instruction */ | ||
59 | struct arch_specific_insn { | ||
60 | /* copy of original instruction */ | ||
61 | kprobe_opcode_t *insn; | ||
62 | int fixup; | ||
63 | int ilen; | ||
64 | int reg; | ||
65 | }; | ||
66 | |||
67 | struct ins_replace_args { | ||
68 | kprobe_opcode_t *ptr; | ||
69 | kprobe_opcode_t old; | ||
70 | kprobe_opcode_t new; | ||
71 | }; | ||
72 | struct prev_kprobe { | ||
73 | struct kprobe *kp; | ||
74 | unsigned long status; | ||
75 | unsigned long saved_psw; | ||
76 | unsigned long kprobe_saved_imask; | ||
77 | unsigned long kprobe_saved_ctl[3]; | ||
78 | }; | ||
79 | |||
80 | /* per-cpu kprobe control block */ | ||
81 | struct kprobe_ctlblk { | ||
82 | unsigned long kprobe_status; | ||
83 | unsigned long kprobe_saved_imask; | ||
84 | unsigned long kprobe_saved_ctl[3]; | ||
85 | struct pt_regs jprobe_saved_regs; | ||
86 | unsigned long jprobe_saved_r14; | ||
87 | unsigned long jprobe_saved_r15; | ||
88 | struct prev_kprobe prev_kprobe; | ||
89 | kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; | ||
90 | }; | ||
91 | |||
92 | void arch_remove_kprobe(struct kprobe *p); | ||
93 | void kretprobe_trampoline(void); | ||
94 | int is_prohibited_opcode(kprobe_opcode_t *instruction); | ||
95 | void get_instruction_type(struct arch_specific_insn *ainsn); | ||
96 | |||
97 | int kprobe_fault_handler(struct pt_regs *regs, int trapnr); | ||
98 | int kprobe_exceptions_notify(struct notifier_block *self, | ||
99 | unsigned long val, void *data); | ||
100 | |||
101 | #define flush_insn_slot(p) do { } while (0) | ||
102 | |||
103 | #endif /* _ASM_S390_KPROBES_H */ | ||
diff --git a/arch/s390/include/asm/kvm.h b/arch/s390/include/asm/kvm.h new file mode 100644 index 000000000000..d74002f95794 --- /dev/null +++ b/arch/s390/include/asm/kvm.h | |||
@@ -0,0 +1,45 @@ | |||
1 | #ifndef __LINUX_KVM_S390_H | ||
2 | #define __LINUX_KVM_S390_H | ||
3 | |||
4 | /* | ||
5 | * asm-s390/kvm.h - KVM s390 specific structures and definitions | ||
6 | * | ||
7 | * Copyright IBM Corp. 2008 | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify | ||
10 | * it under the terms of the GNU General Public License (version 2 only) | ||
11 | * as published by the Free Software Foundation. | ||
12 | * | ||
13 | * Author(s): Carsten Otte <cotte@de.ibm.com> | ||
14 | * Christian Borntraeger <borntraeger@de.ibm.com> | ||
15 | */ | ||
16 | #include <asm/types.h> | ||
17 | |||
18 | /* for KVM_GET_IRQCHIP and KVM_SET_IRQCHIP */ | ||
19 | struct kvm_pic_state { | ||
20 | /* no PIC for s390 */ | ||
21 | }; | ||
22 | |||
23 | struct kvm_ioapic_state { | ||
24 | /* no IOAPIC for s390 */ | ||
25 | }; | ||
26 | |||
27 | /* for KVM_GET_REGS and KVM_SET_REGS */ | ||
28 | struct kvm_regs { | ||
29 | /* general purpose regs for s390 */ | ||
30 | __u64 gprs[16]; | ||
31 | }; | ||
32 | |||
33 | /* for KVM_GET_SREGS and KVM_SET_SREGS */ | ||
34 | struct kvm_sregs { | ||
35 | __u32 acrs[16]; | ||
36 | __u64 crs[16]; | ||
37 | }; | ||
38 | |||
39 | /* for KVM_GET_FPU and KVM_SET_FPU */ | ||
40 | struct kvm_fpu { | ||
41 | __u32 fpc; | ||
42 | __u64 fprs[16]; | ||
43 | }; | ||
44 | |||
45 | #endif | ||
diff --git a/arch/s390/include/asm/kvm_host.h b/arch/s390/include/asm/kvm_host.h new file mode 100644 index 000000000000..3c55e4107dcc --- /dev/null +++ b/arch/s390/include/asm/kvm_host.h | |||
@@ -0,0 +1,235 @@ | |||
1 | /* | ||
2 | * asm-s390/kvm_host.h - definition for kernel virtual machines on s390 | ||
3 | * | ||
4 | * Copyright IBM Corp. 2008 | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License (version 2 only) | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * Author(s): Carsten Otte <cotte@de.ibm.com> | ||
11 | */ | ||
12 | |||
13 | |||
14 | #ifndef ASM_KVM_HOST_H | ||
15 | #define ASM_KVM_HOST_H | ||
16 | #include <linux/kvm_host.h> | ||
17 | #include <asm/debug.h> | ||
18 | |||
19 | #define KVM_MAX_VCPUS 64 | ||
20 | #define KVM_MEMORY_SLOTS 32 | ||
21 | /* memory slots that does not exposed to userspace */ | ||
22 | #define KVM_PRIVATE_MEM_SLOTS 4 | ||
23 | |||
24 | struct kvm_guest_debug { | ||
25 | }; | ||
26 | |||
27 | struct sca_entry { | ||
28 | atomic_t scn; | ||
29 | __u64 reserved; | ||
30 | __u64 sda; | ||
31 | __u64 reserved2[2]; | ||
32 | } __attribute__((packed)); | ||
33 | |||
34 | |||
35 | struct sca_block { | ||
36 | __u64 ipte_control; | ||
37 | __u64 reserved[5]; | ||
38 | __u64 mcn; | ||
39 | __u64 reserved2; | ||
40 | struct sca_entry cpu[64]; | ||
41 | } __attribute__((packed)); | ||
42 | |||
43 | #define KVM_PAGES_PER_HPAGE 256 | ||
44 | |||
45 | #define CPUSTAT_HOST 0x80000000 | ||
46 | #define CPUSTAT_WAIT 0x10000000 | ||
47 | #define CPUSTAT_ECALL_PEND 0x08000000 | ||
48 | #define CPUSTAT_STOP_INT 0x04000000 | ||
49 | #define CPUSTAT_IO_INT 0x02000000 | ||
50 | #define CPUSTAT_EXT_INT 0x01000000 | ||
51 | #define CPUSTAT_RUNNING 0x00800000 | ||
52 | #define CPUSTAT_RETAINED 0x00400000 | ||
53 | #define CPUSTAT_TIMING_SUB 0x00020000 | ||
54 | #define CPUSTAT_SIE_SUB 0x00010000 | ||
55 | #define CPUSTAT_RRF 0x00008000 | ||
56 | #define CPUSTAT_SLSV 0x00004000 | ||
57 | #define CPUSTAT_SLSR 0x00002000 | ||
58 | #define CPUSTAT_ZARCH 0x00000800 | ||
59 | #define CPUSTAT_MCDS 0x00000100 | ||
60 | #define CPUSTAT_SM 0x00000080 | ||
61 | #define CPUSTAT_G 0x00000008 | ||
62 | #define CPUSTAT_J 0x00000002 | ||
63 | #define CPUSTAT_P 0x00000001 | ||
64 | |||
65 | struct kvm_s390_sie_block { | ||
66 | atomic_t cpuflags; /* 0x0000 */ | ||
67 | __u32 prefix; /* 0x0004 */ | ||
68 | __u8 reserved8[32]; /* 0x0008 */ | ||
69 | __u64 cputm; /* 0x0028 */ | ||
70 | __u64 ckc; /* 0x0030 */ | ||
71 | __u64 epoch; /* 0x0038 */ | ||
72 | __u8 reserved40[4]; /* 0x0040 */ | ||
73 | #define LCTL_CR0 0x8000 | ||
74 | __u16 lctl; /* 0x0044 */ | ||
75 | __s16 icpua; /* 0x0046 */ | ||
76 | __u32 ictl; /* 0x0048 */ | ||
77 | __u32 eca; /* 0x004c */ | ||
78 | __u8 icptcode; /* 0x0050 */ | ||
79 | __u8 reserved51; /* 0x0051 */ | ||
80 | __u16 ihcpu; /* 0x0052 */ | ||
81 | __u8 reserved54[2]; /* 0x0054 */ | ||
82 | __u16 ipa; /* 0x0056 */ | ||
83 | __u32 ipb; /* 0x0058 */ | ||
84 | __u32 scaoh; /* 0x005c */ | ||
85 | __u8 reserved60; /* 0x0060 */ | ||
86 | __u8 ecb; /* 0x0061 */ | ||
87 | __u8 reserved62[2]; /* 0x0062 */ | ||
88 | __u32 scaol; /* 0x0064 */ | ||
89 | __u8 reserved68[4]; /* 0x0068 */ | ||
90 | __u32 todpr; /* 0x006c */ | ||
91 | __u8 reserved70[16]; /* 0x0070 */ | ||
92 | __u64 gmsor; /* 0x0080 */ | ||
93 | __u64 gmslm; /* 0x0088 */ | ||
94 | psw_t gpsw; /* 0x0090 */ | ||
95 | __u64 gg14; /* 0x00a0 */ | ||
96 | __u64 gg15; /* 0x00a8 */ | ||
97 | __u8 reservedb0[30]; /* 0x00b0 */ | ||
98 | __u16 iprcc; /* 0x00ce */ | ||
99 | __u8 reservedd0[48]; /* 0x00d0 */ | ||
100 | __u64 gcr[16]; /* 0x0100 */ | ||
101 | __u64 gbea; /* 0x0180 */ | ||
102 | __u8 reserved188[120]; /* 0x0188 */ | ||
103 | } __attribute__((packed)); | ||
104 | |||
105 | struct kvm_vcpu_stat { | ||
106 | u32 exit_userspace; | ||
107 | u32 exit_null; | ||
108 | u32 exit_external_request; | ||
109 | u32 exit_external_interrupt; | ||
110 | u32 exit_stop_request; | ||
111 | u32 exit_validity; | ||
112 | u32 exit_instruction; | ||
113 | u32 instruction_lctl; | ||
114 | u32 instruction_lctlg; | ||
115 | u32 exit_program_interruption; | ||
116 | u32 exit_instr_and_program; | ||
117 | u32 deliver_emergency_signal; | ||
118 | u32 deliver_service_signal; | ||
119 | u32 deliver_virtio_interrupt; | ||
120 | u32 deliver_stop_signal; | ||
121 | u32 deliver_prefix_signal; | ||
122 | u32 deliver_restart_signal; | ||
123 | u32 deliver_program_int; | ||
124 | u32 exit_wait_state; | ||
125 | u32 instruction_stidp; | ||
126 | u32 instruction_spx; | ||
127 | u32 instruction_stpx; | ||
128 | u32 instruction_stap; | ||
129 | u32 instruction_storage_key; | ||
130 | u32 instruction_stsch; | ||
131 | u32 instruction_chsc; | ||
132 | u32 instruction_stsi; | ||
133 | u32 instruction_stfl; | ||
134 | u32 instruction_sigp_sense; | ||
135 | u32 instruction_sigp_emergency; | ||
136 | u32 instruction_sigp_stop; | ||
137 | u32 instruction_sigp_arch; | ||
138 | u32 instruction_sigp_prefix; | ||
139 | u32 instruction_sigp_restart; | ||
140 | u32 diagnose_44; | ||
141 | }; | ||
142 | |||
143 | struct kvm_s390_io_info { | ||
144 | __u16 subchannel_id; /* 0x0b8 */ | ||
145 | __u16 subchannel_nr; /* 0x0ba */ | ||
146 | __u32 io_int_parm; /* 0x0bc */ | ||
147 | __u32 io_int_word; /* 0x0c0 */ | ||
148 | }; | ||
149 | |||
150 | struct kvm_s390_ext_info { | ||
151 | __u32 ext_params; | ||
152 | __u64 ext_params2; | ||
153 | }; | ||
154 | |||
155 | #define PGM_OPERATION 0x01 | ||
156 | #define PGM_PRIVILEGED_OPERATION 0x02 | ||
157 | #define PGM_EXECUTE 0x03 | ||
158 | #define PGM_PROTECTION 0x04 | ||
159 | #define PGM_ADDRESSING 0x05 | ||
160 | #define PGM_SPECIFICATION 0x06 | ||
161 | #define PGM_DATA 0x07 | ||
162 | |||
163 | struct kvm_s390_pgm_info { | ||
164 | __u16 code; | ||
165 | }; | ||
166 | |||
167 | struct kvm_s390_prefix_info { | ||
168 | __u32 address; | ||
169 | }; | ||
170 | |||
171 | struct kvm_s390_interrupt_info { | ||
172 | struct list_head list; | ||
173 | u64 type; | ||
174 | union { | ||
175 | struct kvm_s390_io_info io; | ||
176 | struct kvm_s390_ext_info ext; | ||
177 | struct kvm_s390_pgm_info pgm; | ||
178 | struct kvm_s390_prefix_info prefix; | ||
179 | }; | ||
180 | }; | ||
181 | |||
182 | /* for local_interrupt.action_flags */ | ||
183 | #define ACTION_STORE_ON_STOP 1 | ||
184 | #define ACTION_STOP_ON_STOP 2 | ||
185 | |||
186 | struct kvm_s390_local_interrupt { | ||
187 | spinlock_t lock; | ||
188 | struct list_head list; | ||
189 | atomic_t active; | ||
190 | struct kvm_s390_float_interrupt *float_int; | ||
191 | int timer_due; /* event indicator for waitqueue below */ | ||
192 | wait_queue_head_t wq; | ||
193 | atomic_t *cpuflags; | ||
194 | unsigned int action_bits; | ||
195 | }; | ||
196 | |||
197 | struct kvm_s390_float_interrupt { | ||
198 | spinlock_t lock; | ||
199 | struct list_head list; | ||
200 | atomic_t active; | ||
201 | int next_rr_cpu; | ||
202 | unsigned long idle_mask [(64 + sizeof(long) - 1) / sizeof(long)]; | ||
203 | struct kvm_s390_local_interrupt *local_int[64]; | ||
204 | }; | ||
205 | |||
206 | |||
207 | struct kvm_vcpu_arch { | ||
208 | struct kvm_s390_sie_block *sie_block; | ||
209 | unsigned long guest_gprs[16]; | ||
210 | s390_fp_regs host_fpregs; | ||
211 | unsigned int host_acrs[NUM_ACRS]; | ||
212 | s390_fp_regs guest_fpregs; | ||
213 | unsigned int guest_acrs[NUM_ACRS]; | ||
214 | struct kvm_s390_local_interrupt local_int; | ||
215 | struct timer_list ckc_timer; | ||
216 | union { | ||
217 | cpuid_t cpu_id; | ||
218 | u64 stidp_data; | ||
219 | }; | ||
220 | }; | ||
221 | |||
222 | struct kvm_vm_stat { | ||
223 | u32 remote_tlb_flush; | ||
224 | }; | ||
225 | |||
226 | struct kvm_arch{ | ||
227 | unsigned long guest_origin; | ||
228 | unsigned long guest_memsize; | ||
229 | struct sca_block *sca; | ||
230 | debug_info_t *dbf; | ||
231 | struct kvm_s390_float_interrupt float_int; | ||
232 | }; | ||
233 | |||
234 | extern int sie64a(struct kvm_s390_sie_block *, unsigned long *); | ||
235 | #endif | ||
diff --git a/arch/s390/include/asm/kvm_para.h b/arch/s390/include/asm/kvm_para.h new file mode 100644 index 000000000000..2c503796b619 --- /dev/null +++ b/arch/s390/include/asm/kvm_para.h | |||
@@ -0,0 +1,150 @@ | |||
1 | /* | ||
2 | * asm-s390/kvm_para.h - definition for paravirtual devices on s390 | ||
3 | * | ||
4 | * Copyright IBM Corp. 2008 | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License (version 2 only) | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * Author(s): Christian Borntraeger <borntraeger@de.ibm.com> | ||
11 | */ | ||
12 | |||
13 | #ifndef __S390_KVM_PARA_H | ||
14 | #define __S390_KVM_PARA_H | ||
15 | |||
16 | /* | ||
17 | * Hypercalls for KVM on s390. The calling convention is similar to the | ||
18 | * s390 ABI, so we use R2-R6 for parameters 1-5. In addition we use R1 | ||
19 | * as hypercall number and R7 as parameter 6. The return value is | ||
20 | * written to R2. We use the diagnose instruction as hypercall. To avoid | ||
21 | * conflicts with existing diagnoses for LPAR and z/VM, we do not use | ||
22 | * the instruction encoded number, but specify the number in R1 and | ||
23 | * use 0x500 as KVM hypercall | ||
24 | * | ||
25 | * Copyright IBM Corp. 2007,2008 | ||
26 | * Author(s): Christian Borntraeger <borntraeger@de.ibm.com> | ||
27 | * | ||
28 | * This work is licensed under the terms of the GNU GPL, version 2. | ||
29 | */ | ||
30 | |||
31 | static inline long kvm_hypercall0(unsigned long nr) | ||
32 | { | ||
33 | register unsigned long __nr asm("1") = nr; | ||
34 | register long __rc asm("2"); | ||
35 | |||
36 | asm volatile ("diag 2,4,0x500\n" | ||
37 | : "=d" (__rc) : "d" (__nr): "memory", "cc"); | ||
38 | return __rc; | ||
39 | } | ||
40 | |||
41 | static inline long kvm_hypercall1(unsigned long nr, unsigned long p1) | ||
42 | { | ||
43 | register unsigned long __nr asm("1") = nr; | ||
44 | register unsigned long __p1 asm("2") = p1; | ||
45 | register long __rc asm("2"); | ||
46 | |||
47 | asm volatile ("diag 2,4,0x500\n" | ||
48 | : "=d" (__rc) : "d" (__nr), "0" (__p1) : "memory", "cc"); | ||
49 | return __rc; | ||
50 | } | ||
51 | |||
52 | static inline long kvm_hypercall2(unsigned long nr, unsigned long p1, | ||
53 | unsigned long p2) | ||
54 | { | ||
55 | register unsigned long __nr asm("1") = nr; | ||
56 | register unsigned long __p1 asm("2") = p1; | ||
57 | register unsigned long __p2 asm("3") = p2; | ||
58 | register long __rc asm("2"); | ||
59 | |||
60 | asm volatile ("diag 2,4,0x500\n" | ||
61 | : "=d" (__rc) : "d" (__nr), "0" (__p1), "d" (__p2) | ||
62 | : "memory", "cc"); | ||
63 | return __rc; | ||
64 | } | ||
65 | |||
66 | static inline long kvm_hypercall3(unsigned long nr, unsigned long p1, | ||
67 | unsigned long p2, unsigned long p3) | ||
68 | { | ||
69 | register unsigned long __nr asm("1") = nr; | ||
70 | register unsigned long __p1 asm("2") = p1; | ||
71 | register unsigned long __p2 asm("3") = p2; | ||
72 | register unsigned long __p3 asm("4") = p3; | ||
73 | register long __rc asm("2"); | ||
74 | |||
75 | asm volatile ("diag 2,4,0x500\n" | ||
76 | : "=d" (__rc) : "d" (__nr), "0" (__p1), "d" (__p2), | ||
77 | "d" (__p3) : "memory", "cc"); | ||
78 | return __rc; | ||
79 | } | ||
80 | |||
81 | |||
82 | static inline long kvm_hypercall4(unsigned long nr, unsigned long p1, | ||
83 | unsigned long p2, unsigned long p3, | ||
84 | unsigned long p4) | ||
85 | { | ||
86 | register unsigned long __nr asm("1") = nr; | ||
87 | register unsigned long __p1 asm("2") = p1; | ||
88 | register unsigned long __p2 asm("3") = p2; | ||
89 | register unsigned long __p3 asm("4") = p3; | ||
90 | register unsigned long __p4 asm("5") = p4; | ||
91 | register long __rc asm("2"); | ||
92 | |||
93 | asm volatile ("diag 2,4,0x500\n" | ||
94 | : "=d" (__rc) : "d" (__nr), "0" (__p1), "d" (__p2), | ||
95 | "d" (__p3), "d" (__p4) : "memory", "cc"); | ||
96 | return __rc; | ||
97 | } | ||
98 | |||
99 | static inline long kvm_hypercall5(unsigned long nr, unsigned long p1, | ||
100 | unsigned long p2, unsigned long p3, | ||
101 | unsigned long p4, unsigned long p5) | ||
102 | { | ||
103 | register unsigned long __nr asm("1") = nr; | ||
104 | register unsigned long __p1 asm("2") = p1; | ||
105 | register unsigned long __p2 asm("3") = p2; | ||
106 | register unsigned long __p3 asm("4") = p3; | ||
107 | register unsigned long __p4 asm("5") = p4; | ||
108 | register unsigned long __p5 asm("6") = p5; | ||
109 | register long __rc asm("2"); | ||
110 | |||
111 | asm volatile ("diag 2,4,0x500\n" | ||
112 | : "=d" (__rc) : "d" (__nr), "0" (__p1), "d" (__p2), | ||
113 | "d" (__p3), "d" (__p4), "d" (__p5) : "memory", "cc"); | ||
114 | return __rc; | ||
115 | } | ||
116 | |||
117 | static inline long kvm_hypercall6(unsigned long nr, unsigned long p1, | ||
118 | unsigned long p2, unsigned long p3, | ||
119 | unsigned long p4, unsigned long p5, | ||
120 | unsigned long p6) | ||
121 | { | ||
122 | register unsigned long __nr asm("1") = nr; | ||
123 | register unsigned long __p1 asm("2") = p1; | ||
124 | register unsigned long __p2 asm("3") = p2; | ||
125 | register unsigned long __p3 asm("4") = p3; | ||
126 | register unsigned long __p4 asm("5") = p4; | ||
127 | register unsigned long __p5 asm("6") = p5; | ||
128 | register unsigned long __p6 asm("7") = p6; | ||
129 | register long __rc asm("2"); | ||
130 | |||
131 | asm volatile ("diag 2,4,0x500\n" | ||
132 | : "=d" (__rc) : "d" (__nr), "0" (__p1), "d" (__p2), | ||
133 | "d" (__p3), "d" (__p4), "d" (__p5), "d" (__p6) | ||
134 | : "memory", "cc"); | ||
135 | return __rc; | ||
136 | } | ||
137 | |||
138 | /* kvm on s390 is always paravirtualization enabled */ | ||
139 | static inline int kvm_para_available(void) | ||
140 | { | ||
141 | return 1; | ||
142 | } | ||
143 | |||
144 | /* No feature bits are currently assigned for kvm on s390 */ | ||
145 | static inline unsigned int kvm_arch_para_features(void) | ||
146 | { | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | #endif /* __S390_KVM_PARA_H */ | ||
diff --git a/arch/s390/include/asm/kvm_virtio.h b/arch/s390/include/asm/kvm_virtio.h new file mode 100644 index 000000000000..146100224def --- /dev/null +++ b/arch/s390/include/asm/kvm_virtio.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * kvm_virtio.h - definition for virtio for kvm on s390 | ||
3 | * | ||
4 | * Copyright IBM Corp. 2008 | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License (version 2 only) | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * Author(s): Christian Borntraeger <borntraeger@de.ibm.com> | ||
11 | */ | ||
12 | |||
13 | #ifndef __KVM_S390_VIRTIO_H | ||
14 | #define __KVM_S390_VIRTIO_H | ||
15 | |||
16 | #include <linux/types.h> | ||
17 | |||
18 | struct kvm_device_desc { | ||
19 | /* The device type: console, network, disk etc. Type 0 terminates. */ | ||
20 | __u8 type; | ||
21 | /* The number of virtqueues (first in config array) */ | ||
22 | __u8 num_vq; | ||
23 | /* | ||
24 | * The number of bytes of feature bits. Multiply by 2: one for host | ||
25 | * features and one for guest acknowledgements. | ||
26 | */ | ||
27 | __u8 feature_len; | ||
28 | /* The number of bytes of the config array after virtqueues. */ | ||
29 | __u8 config_len; | ||
30 | /* A status byte, written by the Guest. */ | ||
31 | __u8 status; | ||
32 | __u8 config[0]; | ||
33 | }; | ||
34 | |||
35 | /* | ||
36 | * This is how we expect the device configuration field for a virtqueue | ||
37 | * to be laid out in config space. | ||
38 | */ | ||
39 | struct kvm_vqconfig { | ||
40 | /* The token returned with an interrupt. Set by the guest */ | ||
41 | __u64 token; | ||
42 | /* The address of the virtio ring */ | ||
43 | __u64 address; | ||
44 | /* The number of entries in the virtio_ring */ | ||
45 | __u16 num; | ||
46 | |||
47 | }; | ||
48 | |||
49 | #define KVM_S390_VIRTIO_NOTIFY 0 | ||
50 | #define KVM_S390_VIRTIO_RESET 1 | ||
51 | #define KVM_S390_VIRTIO_SET_STATUS 2 | ||
52 | |||
53 | #ifdef __KERNEL__ | ||
54 | /* early virtio console setup */ | ||
55 | #ifdef CONFIG_VIRTIO_CONSOLE | ||
56 | extern void s390_virtio_console_init(void); | ||
57 | #else | ||
58 | static inline void s390_virtio_console_init(void) | ||
59 | { | ||
60 | } | ||
61 | #endif /* CONFIG_VIRTIO_CONSOLE */ | ||
62 | #endif /* __KERNEL__ */ | ||
63 | #endif | ||
diff --git a/arch/s390/include/asm/linkage.h b/arch/s390/include/asm/linkage.h new file mode 100644 index 000000000000..291c2d01c44f --- /dev/null +++ b/arch/s390/include/asm/linkage.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef __ASM_LINKAGE_H | ||
2 | #define __ASM_LINKAGE_H | ||
3 | |||
4 | /* Nothing to see here... */ | ||
5 | |||
6 | #endif | ||
diff --git a/arch/s390/include/asm/local.h b/arch/s390/include/asm/local.h new file mode 100644 index 000000000000..c11c530f74d0 --- /dev/null +++ b/arch/s390/include/asm/local.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/local.h> | |||
diff --git a/arch/s390/include/asm/lowcore.h b/arch/s390/include/asm/lowcore.h new file mode 100644 index 000000000000..0bc51d52a899 --- /dev/null +++ b/arch/s390/include/asm/lowcore.h | |||
@@ -0,0 +1,433 @@ | |||
1 | /* | ||
2 | * include/asm-s390/lowcore.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Hartmut Penner (hp@de.ibm.com), | ||
7 | * Martin Schwidefsky (schwidefsky@de.ibm.com), | ||
8 | * Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) | ||
9 | */ | ||
10 | |||
11 | #ifndef _ASM_S390_LOWCORE_H | ||
12 | #define _ASM_S390_LOWCORE_H | ||
13 | |||
14 | #ifndef __s390x__ | ||
15 | #define __LC_EXT_OLD_PSW 0x018 | ||
16 | #define __LC_SVC_OLD_PSW 0x020 | ||
17 | #define __LC_PGM_OLD_PSW 0x028 | ||
18 | #define __LC_MCK_OLD_PSW 0x030 | ||
19 | #define __LC_IO_OLD_PSW 0x038 | ||
20 | #define __LC_EXT_NEW_PSW 0x058 | ||
21 | #define __LC_SVC_NEW_PSW 0x060 | ||
22 | #define __LC_PGM_NEW_PSW 0x068 | ||
23 | #define __LC_MCK_NEW_PSW 0x070 | ||
24 | #define __LC_IO_NEW_PSW 0x078 | ||
25 | #else /* !__s390x__ */ | ||
26 | #define __LC_EXT_OLD_PSW 0x0130 | ||
27 | #define __LC_SVC_OLD_PSW 0x0140 | ||
28 | #define __LC_PGM_OLD_PSW 0x0150 | ||
29 | #define __LC_MCK_OLD_PSW 0x0160 | ||
30 | #define __LC_IO_OLD_PSW 0x0170 | ||
31 | #define __LC_EXT_NEW_PSW 0x01b0 | ||
32 | #define __LC_SVC_NEW_PSW 0x01c0 | ||
33 | #define __LC_PGM_NEW_PSW 0x01d0 | ||
34 | #define __LC_MCK_NEW_PSW 0x01e0 | ||
35 | #define __LC_IO_NEW_PSW 0x01f0 | ||
36 | #endif /* !__s390x__ */ | ||
37 | |||
38 | #define __LC_IPL_PARMBLOCK_PTR 0x014 | ||
39 | #define __LC_EXT_PARAMS 0x080 | ||
40 | #define __LC_CPU_ADDRESS 0x084 | ||
41 | #define __LC_EXT_INT_CODE 0x086 | ||
42 | |||
43 | #define __LC_SVC_ILC 0x088 | ||
44 | #define __LC_SVC_INT_CODE 0x08A | ||
45 | #define __LC_PGM_ILC 0x08C | ||
46 | #define __LC_PGM_INT_CODE 0x08E | ||
47 | |||
48 | #define __LC_PER_ATMID 0x096 | ||
49 | #define __LC_PER_ADDRESS 0x098 | ||
50 | #define __LC_PER_ACCESS_ID 0x0A1 | ||
51 | #define __LC_AR_MODE_ID 0x0A3 | ||
52 | |||
53 | #define __LC_SUBCHANNEL_ID 0x0B8 | ||
54 | #define __LC_SUBCHANNEL_NR 0x0BA | ||
55 | #define __LC_IO_INT_PARM 0x0BC | ||
56 | #define __LC_IO_INT_WORD 0x0C0 | ||
57 | #define __LC_MCCK_CODE 0x0E8 | ||
58 | |||
59 | #define __LC_LAST_BREAK 0x110 | ||
60 | |||
61 | #define __LC_RETURN_PSW 0x200 | ||
62 | |||
63 | #define __LC_SAVE_AREA 0xC00 | ||
64 | |||
65 | #ifndef __s390x__ | ||
66 | #define __LC_IRB 0x208 | ||
67 | #define __LC_SYNC_ENTER_TIMER 0x248 | ||
68 | #define __LC_ASYNC_ENTER_TIMER 0x250 | ||
69 | #define __LC_EXIT_TIMER 0x258 | ||
70 | #define __LC_LAST_UPDATE_TIMER 0x260 | ||
71 | #define __LC_USER_TIMER 0x268 | ||
72 | #define __LC_SYSTEM_TIMER 0x270 | ||
73 | #define __LC_LAST_UPDATE_CLOCK 0x278 | ||
74 | #define __LC_STEAL_CLOCK 0x280 | ||
75 | #define __LC_RETURN_MCCK_PSW 0x288 | ||
76 | #define __LC_KERNEL_STACK 0xC40 | ||
77 | #define __LC_THREAD_INFO 0xC44 | ||
78 | #define __LC_ASYNC_STACK 0xC48 | ||
79 | #define __LC_KERNEL_ASCE 0xC4C | ||
80 | #define __LC_USER_ASCE 0xC50 | ||
81 | #define __LC_PANIC_STACK 0xC54 | ||
82 | #define __LC_CPUID 0xC60 | ||
83 | #define __LC_CPUADDR 0xC68 | ||
84 | #define __LC_IPLDEV 0xC7C | ||
85 | #define __LC_CURRENT 0xC90 | ||
86 | #define __LC_INT_CLOCK 0xC98 | ||
87 | #else /* __s390x__ */ | ||
88 | #define __LC_IRB 0x210 | ||
89 | #define __LC_SYNC_ENTER_TIMER 0x250 | ||
90 | #define __LC_ASYNC_ENTER_TIMER 0x258 | ||
91 | #define __LC_EXIT_TIMER 0x260 | ||
92 | #define __LC_LAST_UPDATE_TIMER 0x268 | ||
93 | #define __LC_USER_TIMER 0x270 | ||
94 | #define __LC_SYSTEM_TIMER 0x278 | ||
95 | #define __LC_LAST_UPDATE_CLOCK 0x280 | ||
96 | #define __LC_STEAL_CLOCK 0x288 | ||
97 | #define __LC_RETURN_MCCK_PSW 0x290 | ||
98 | #define __LC_KERNEL_STACK 0xD40 | ||
99 | #define __LC_THREAD_INFO 0xD48 | ||
100 | #define __LC_ASYNC_STACK 0xD50 | ||
101 | #define __LC_KERNEL_ASCE 0xD58 | ||
102 | #define __LC_USER_ASCE 0xD60 | ||
103 | #define __LC_PANIC_STACK 0xD68 | ||
104 | #define __LC_CPUID 0xD80 | ||
105 | #define __LC_CPUADDR 0xD88 | ||
106 | #define __LC_IPLDEV 0xDB8 | ||
107 | #define __LC_CURRENT 0xDD8 | ||
108 | #define __LC_INT_CLOCK 0xDE8 | ||
109 | #endif /* __s390x__ */ | ||
110 | |||
111 | |||
112 | #define __LC_PANIC_MAGIC 0xE00 | ||
113 | #ifndef __s390x__ | ||
114 | #define __LC_PFAULT_INTPARM 0x080 | ||
115 | #define __LC_CPU_TIMER_SAVE_AREA 0x0D8 | ||
116 | #define __LC_CLOCK_COMP_SAVE_AREA 0x0E0 | ||
117 | #define __LC_PSW_SAVE_AREA 0x100 | ||
118 | #define __LC_PREFIX_SAVE_AREA 0x108 | ||
119 | #define __LC_AREGS_SAVE_AREA 0x120 | ||
120 | #define __LC_FPREGS_SAVE_AREA 0x160 | ||
121 | #define __LC_GPREGS_SAVE_AREA 0x180 | ||
122 | #define __LC_CREGS_SAVE_AREA 0x1C0 | ||
123 | #else /* __s390x__ */ | ||
124 | #define __LC_PFAULT_INTPARM 0x11B8 | ||
125 | #define __LC_FPREGS_SAVE_AREA 0x1200 | ||
126 | #define __LC_GPREGS_SAVE_AREA 0x1280 | ||
127 | #define __LC_PSW_SAVE_AREA 0x1300 | ||
128 | #define __LC_PREFIX_SAVE_AREA 0x1318 | ||
129 | #define __LC_FP_CREG_SAVE_AREA 0x131C | ||
130 | #define __LC_TODREG_SAVE_AREA 0x1324 | ||
131 | #define __LC_CPU_TIMER_SAVE_AREA 0x1328 | ||
132 | #define __LC_CLOCK_COMP_SAVE_AREA 0x1331 | ||
133 | #define __LC_AREGS_SAVE_AREA 0x1340 | ||
134 | #define __LC_CREGS_SAVE_AREA 0x1380 | ||
135 | #endif /* __s390x__ */ | ||
136 | |||
137 | #ifndef __ASSEMBLY__ | ||
138 | |||
139 | #include <asm/processor.h> | ||
140 | #include <linux/types.h> | ||
141 | #include <asm/sigp.h> | ||
142 | |||
143 | void restart_int_handler(void); | ||
144 | void ext_int_handler(void); | ||
145 | void system_call(void); | ||
146 | void pgm_check_handler(void); | ||
147 | void mcck_int_handler(void); | ||
148 | void io_int_handler(void); | ||
149 | |||
150 | struct save_area_s390 { | ||
151 | u32 ext_save; | ||
152 | u64 timer; | ||
153 | u64 clk_cmp; | ||
154 | u8 pad1[24]; | ||
155 | u8 psw[8]; | ||
156 | u32 pref_reg; | ||
157 | u8 pad2[20]; | ||
158 | u32 acc_regs[16]; | ||
159 | u64 fp_regs[4]; | ||
160 | u32 gp_regs[16]; | ||
161 | u32 ctrl_regs[16]; | ||
162 | } __attribute__((packed)); | ||
163 | |||
164 | struct save_area_s390x { | ||
165 | u64 fp_regs[16]; | ||
166 | u64 gp_regs[16]; | ||
167 | u8 psw[16]; | ||
168 | u8 pad1[8]; | ||
169 | u32 pref_reg; | ||
170 | u32 fp_ctrl_reg; | ||
171 | u8 pad2[4]; | ||
172 | u32 tod_reg; | ||
173 | u64 timer; | ||
174 | u64 clk_cmp; | ||
175 | u8 pad3[8]; | ||
176 | u32 acc_regs[16]; | ||
177 | u64 ctrl_regs[16]; | ||
178 | } __attribute__((packed)); | ||
179 | |||
180 | union save_area { | ||
181 | struct save_area_s390 s390; | ||
182 | struct save_area_s390x s390x; | ||
183 | }; | ||
184 | |||
185 | #define SAVE_AREA_BASE_S390 0xd4 | ||
186 | #define SAVE_AREA_BASE_S390X 0x1200 | ||
187 | |||
188 | #ifndef __s390x__ | ||
189 | #define SAVE_AREA_SIZE sizeof(struct save_area_s390) | ||
190 | #define SAVE_AREA_BASE SAVE_AREA_BASE_S390 | ||
191 | #else | ||
192 | #define SAVE_AREA_SIZE sizeof(struct save_area_s390x) | ||
193 | #define SAVE_AREA_BASE SAVE_AREA_BASE_S390X | ||
194 | #endif | ||
195 | |||
196 | struct _lowcore | ||
197 | { | ||
198 | #ifndef __s390x__ | ||
199 | /* prefix area: defined by architecture */ | ||
200 | psw_t restart_psw; /* 0x000 */ | ||
201 | __u32 ccw2[4]; /* 0x008 */ | ||
202 | psw_t external_old_psw; /* 0x018 */ | ||
203 | psw_t svc_old_psw; /* 0x020 */ | ||
204 | psw_t program_old_psw; /* 0x028 */ | ||
205 | psw_t mcck_old_psw; /* 0x030 */ | ||
206 | psw_t io_old_psw; /* 0x038 */ | ||
207 | __u8 pad1[0x58-0x40]; /* 0x040 */ | ||
208 | psw_t external_new_psw; /* 0x058 */ | ||
209 | psw_t svc_new_psw; /* 0x060 */ | ||
210 | psw_t program_new_psw; /* 0x068 */ | ||
211 | psw_t mcck_new_psw; /* 0x070 */ | ||
212 | psw_t io_new_psw; /* 0x078 */ | ||
213 | __u32 ext_params; /* 0x080 */ | ||
214 | __u16 cpu_addr; /* 0x084 */ | ||
215 | __u16 ext_int_code; /* 0x086 */ | ||
216 | __u16 svc_ilc; /* 0x088 */ | ||
217 | __u16 svc_code; /* 0x08a */ | ||
218 | __u16 pgm_ilc; /* 0x08c */ | ||
219 | __u16 pgm_code; /* 0x08e */ | ||
220 | __u32 trans_exc_code; /* 0x090 */ | ||
221 | __u16 mon_class_num; /* 0x094 */ | ||
222 | __u16 per_perc_atmid; /* 0x096 */ | ||
223 | __u32 per_address; /* 0x098 */ | ||
224 | __u32 monitor_code; /* 0x09c */ | ||
225 | __u8 exc_access_id; /* 0x0a0 */ | ||
226 | __u8 per_access_id; /* 0x0a1 */ | ||
227 | __u8 pad2[0xB8-0xA2]; /* 0x0a2 */ | ||
228 | __u16 subchannel_id; /* 0x0b8 */ | ||
229 | __u16 subchannel_nr; /* 0x0ba */ | ||
230 | __u32 io_int_parm; /* 0x0bc */ | ||
231 | __u32 io_int_word; /* 0x0c0 */ | ||
232 | __u8 pad3[0xc8-0xc4]; /* 0x0c4 */ | ||
233 | __u32 stfl_fac_list; /* 0x0c8 */ | ||
234 | __u8 pad4[0xd4-0xcc]; /* 0x0cc */ | ||
235 | __u32 extended_save_area_addr; /* 0x0d4 */ | ||
236 | __u32 cpu_timer_save_area[2]; /* 0x0d8 */ | ||
237 | __u32 clock_comp_save_area[2]; /* 0x0e0 */ | ||
238 | __u32 mcck_interruption_code[2]; /* 0x0e8 */ | ||
239 | __u8 pad5[0xf4-0xf0]; /* 0x0f0 */ | ||
240 | __u32 external_damage_code; /* 0x0f4 */ | ||
241 | __u32 failing_storage_address; /* 0x0f8 */ | ||
242 | __u8 pad6[0x100-0xfc]; /* 0x0fc */ | ||
243 | __u32 st_status_fixed_logout[4];/* 0x100 */ | ||
244 | __u8 pad7[0x120-0x110]; /* 0x110 */ | ||
245 | __u32 access_regs_save_area[16];/* 0x120 */ | ||
246 | __u32 floating_pt_save_area[8]; /* 0x160 */ | ||
247 | __u32 gpregs_save_area[16]; /* 0x180 */ | ||
248 | __u32 cregs_save_area[16]; /* 0x1c0 */ | ||
249 | |||
250 | psw_t return_psw; /* 0x200 */ | ||
251 | __u8 irb[64]; /* 0x208 */ | ||
252 | __u64 sync_enter_timer; /* 0x248 */ | ||
253 | __u64 async_enter_timer; /* 0x250 */ | ||
254 | __u64 exit_timer; /* 0x258 */ | ||
255 | __u64 last_update_timer; /* 0x260 */ | ||
256 | __u64 user_timer; /* 0x268 */ | ||
257 | __u64 system_timer; /* 0x270 */ | ||
258 | __u64 last_update_clock; /* 0x278 */ | ||
259 | __u64 steal_clock; /* 0x280 */ | ||
260 | psw_t return_mcck_psw; /* 0x288 */ | ||
261 | __u8 pad8[0xc00-0x290]; /* 0x290 */ | ||
262 | |||
263 | /* System info area */ | ||
264 | __u32 save_area[16]; /* 0xc00 */ | ||
265 | __u32 kernel_stack; /* 0xc40 */ | ||
266 | __u32 thread_info; /* 0xc44 */ | ||
267 | __u32 async_stack; /* 0xc48 */ | ||
268 | __u32 kernel_asce; /* 0xc4c */ | ||
269 | __u32 user_asce; /* 0xc50 */ | ||
270 | __u32 panic_stack; /* 0xc54 */ | ||
271 | __u32 user_exec_asce; /* 0xc58 */ | ||
272 | __u8 pad10[0xc60-0xc5c]; /* 0xc5c */ | ||
273 | /* entry.S sensitive area start */ | ||
274 | struct cpuinfo_S390 cpu_data; /* 0xc60 */ | ||
275 | __u32 ipl_device; /* 0xc7c */ | ||
276 | /* entry.S sensitive area end */ | ||
277 | |||
278 | /* SMP info area: defined by DJB */ | ||
279 | __u64 clock_comparator; /* 0xc80 */ | ||
280 | __u32 ext_call_fast; /* 0xc88 */ | ||
281 | __u32 percpu_offset; /* 0xc8c */ | ||
282 | __u32 current_task; /* 0xc90 */ | ||
283 | __u32 softirq_pending; /* 0xc94 */ | ||
284 | __u64 int_clock; /* 0xc98 */ | ||
285 | __u8 pad11[0xe00-0xca0]; /* 0xca0 */ | ||
286 | |||
287 | /* 0xe00 is used as indicator for dump tools */ | ||
288 | /* whether the kernel died with panic() or not */ | ||
289 | __u32 panic_magic; /* 0xe00 */ | ||
290 | |||
291 | /* Align to the top 1k of prefix area */ | ||
292 | __u8 pad12[0x1000-0xe04]; /* 0xe04 */ | ||
293 | #else /* !__s390x__ */ | ||
294 | /* prefix area: defined by architecture */ | ||
295 | __u32 ccw1[2]; /* 0x000 */ | ||
296 | __u32 ccw2[4]; /* 0x008 */ | ||
297 | __u8 pad1[0x80-0x18]; /* 0x018 */ | ||
298 | __u32 ext_params; /* 0x080 */ | ||
299 | __u16 cpu_addr; /* 0x084 */ | ||
300 | __u16 ext_int_code; /* 0x086 */ | ||
301 | __u16 svc_ilc; /* 0x088 */ | ||
302 | __u16 svc_code; /* 0x08a */ | ||
303 | __u16 pgm_ilc; /* 0x08c */ | ||
304 | __u16 pgm_code; /* 0x08e */ | ||
305 | __u32 data_exc_code; /* 0x090 */ | ||
306 | __u16 mon_class_num; /* 0x094 */ | ||
307 | __u16 per_perc_atmid; /* 0x096 */ | ||
308 | addr_t per_address; /* 0x098 */ | ||
309 | __u8 exc_access_id; /* 0x0a0 */ | ||
310 | __u8 per_access_id; /* 0x0a1 */ | ||
311 | __u8 op_access_id; /* 0x0a2 */ | ||
312 | __u8 ar_access_id; /* 0x0a3 */ | ||
313 | __u8 pad2[0xA8-0xA4]; /* 0x0a4 */ | ||
314 | addr_t trans_exc_code; /* 0x0A0 */ | ||
315 | addr_t monitor_code; /* 0x09c */ | ||
316 | __u16 subchannel_id; /* 0x0b8 */ | ||
317 | __u16 subchannel_nr; /* 0x0ba */ | ||
318 | __u32 io_int_parm; /* 0x0bc */ | ||
319 | __u32 io_int_word; /* 0x0c0 */ | ||
320 | __u8 pad3[0xc8-0xc4]; /* 0x0c4 */ | ||
321 | __u32 stfl_fac_list; /* 0x0c8 */ | ||
322 | __u8 pad4[0xe8-0xcc]; /* 0x0cc */ | ||
323 | __u32 mcck_interruption_code[2]; /* 0x0e8 */ | ||
324 | __u8 pad5[0xf4-0xf0]; /* 0x0f0 */ | ||
325 | __u32 external_damage_code; /* 0x0f4 */ | ||
326 | addr_t failing_storage_address; /* 0x0f8 */ | ||
327 | __u8 pad6[0x120-0x100]; /* 0x100 */ | ||
328 | psw_t restart_old_psw; /* 0x120 */ | ||
329 | psw_t external_old_psw; /* 0x130 */ | ||
330 | psw_t svc_old_psw; /* 0x140 */ | ||
331 | psw_t program_old_psw; /* 0x150 */ | ||
332 | psw_t mcck_old_psw; /* 0x160 */ | ||
333 | psw_t io_old_psw; /* 0x170 */ | ||
334 | __u8 pad7[0x1a0-0x180]; /* 0x180 */ | ||
335 | psw_t restart_psw; /* 0x1a0 */ | ||
336 | psw_t external_new_psw; /* 0x1b0 */ | ||
337 | psw_t svc_new_psw; /* 0x1c0 */ | ||
338 | psw_t program_new_psw; /* 0x1d0 */ | ||
339 | psw_t mcck_new_psw; /* 0x1e0 */ | ||
340 | psw_t io_new_psw; /* 0x1f0 */ | ||
341 | psw_t return_psw; /* 0x200 */ | ||
342 | __u8 irb[64]; /* 0x210 */ | ||
343 | __u64 sync_enter_timer; /* 0x250 */ | ||
344 | __u64 async_enter_timer; /* 0x258 */ | ||
345 | __u64 exit_timer; /* 0x260 */ | ||
346 | __u64 last_update_timer; /* 0x268 */ | ||
347 | __u64 user_timer; /* 0x270 */ | ||
348 | __u64 system_timer; /* 0x278 */ | ||
349 | __u64 last_update_clock; /* 0x280 */ | ||
350 | __u64 steal_clock; /* 0x288 */ | ||
351 | psw_t return_mcck_psw; /* 0x290 */ | ||
352 | __u8 pad8[0xc00-0x2a0]; /* 0x2a0 */ | ||
353 | /* System info area */ | ||
354 | __u64 save_area[16]; /* 0xc00 */ | ||
355 | __u8 pad9[0xd40-0xc80]; /* 0xc80 */ | ||
356 | __u64 kernel_stack; /* 0xd40 */ | ||
357 | __u64 thread_info; /* 0xd48 */ | ||
358 | __u64 async_stack; /* 0xd50 */ | ||
359 | __u64 kernel_asce; /* 0xd58 */ | ||
360 | __u64 user_asce; /* 0xd60 */ | ||
361 | __u64 panic_stack; /* 0xd68 */ | ||
362 | __u64 user_exec_asce; /* 0xd70 */ | ||
363 | __u8 pad10[0xd80-0xd78]; /* 0xd78 */ | ||
364 | /* entry.S sensitive area start */ | ||
365 | struct cpuinfo_S390 cpu_data; /* 0xd80 */ | ||
366 | __u32 ipl_device; /* 0xdb8 */ | ||
367 | __u32 pad11; /* 0xdbc */ | ||
368 | /* entry.S sensitive area end */ | ||
369 | |||
370 | /* SMP info area: defined by DJB */ | ||
371 | __u64 clock_comparator; /* 0xdc0 */ | ||
372 | __u64 ext_call_fast; /* 0xdc8 */ | ||
373 | __u64 percpu_offset; /* 0xdd0 */ | ||
374 | __u64 current_task; /* 0xdd8 */ | ||
375 | __u32 softirq_pending; /* 0xde0 */ | ||
376 | __u32 pad_0x0de4; /* 0xde4 */ | ||
377 | __u64 int_clock; /* 0xde8 */ | ||
378 | __u8 pad12[0xe00-0xdf0]; /* 0xdf0 */ | ||
379 | |||
380 | /* 0xe00 is used as indicator for dump tools */ | ||
381 | /* whether the kernel died with panic() or not */ | ||
382 | __u32 panic_magic; /* 0xe00 */ | ||
383 | |||
384 | __u8 pad13[0x11b8-0xe04]; /* 0xe04 */ | ||
385 | |||
386 | /* 64 bit extparam used for pfault, diag 250 etc */ | ||
387 | __u64 ext_params2; /* 0x11B8 */ | ||
388 | |||
389 | __u8 pad14[0x1200-0x11C0]; /* 0x11C0 */ | ||
390 | |||
391 | /* System info area */ | ||
392 | |||
393 | __u64 floating_pt_save_area[16]; /* 0x1200 */ | ||
394 | __u64 gpregs_save_area[16]; /* 0x1280 */ | ||
395 | __u32 st_status_fixed_logout[4]; /* 0x1300 */ | ||
396 | __u8 pad15[0x1318-0x1310]; /* 0x1310 */ | ||
397 | __u32 prefixreg_save_area; /* 0x1318 */ | ||
398 | __u32 fpt_creg_save_area; /* 0x131c */ | ||
399 | __u8 pad16[0x1324-0x1320]; /* 0x1320 */ | ||
400 | __u32 tod_progreg_save_area; /* 0x1324 */ | ||
401 | __u32 cpu_timer_save_area[2]; /* 0x1328 */ | ||
402 | __u32 clock_comp_save_area[2]; /* 0x1330 */ | ||
403 | __u8 pad17[0x1340-0x1338]; /* 0x1338 */ | ||
404 | __u32 access_regs_save_area[16]; /* 0x1340 */ | ||
405 | __u64 cregs_save_area[16]; /* 0x1380 */ | ||
406 | |||
407 | /* align to the top of the prefix area */ | ||
408 | |||
409 | __u8 pad18[0x2000-0x1400]; /* 0x1400 */ | ||
410 | #endif /* !__s390x__ */ | ||
411 | } __attribute__((packed)); /* End structure*/ | ||
412 | |||
413 | #define S390_lowcore (*((struct _lowcore *) 0)) | ||
414 | extern struct _lowcore *lowcore_ptr[]; | ||
415 | |||
416 | static inline void set_prefix(__u32 address) | ||
417 | { | ||
418 | asm volatile("spx %0" : : "m" (address) : "memory"); | ||
419 | } | ||
420 | |||
421 | static inline __u32 store_prefix(void) | ||
422 | { | ||
423 | __u32 address; | ||
424 | |||
425 | asm volatile("stpx %0" : "=m" (address)); | ||
426 | return address; | ||
427 | } | ||
428 | |||
429 | #define __PANIC_MAGIC 0xDEADC0DE | ||
430 | |||
431 | #endif | ||
432 | |||
433 | #endif | ||
diff --git a/arch/s390/include/asm/mathemu.h b/arch/s390/include/asm/mathemu.h new file mode 100644 index 000000000000..e8dd1ba8edb0 --- /dev/null +++ b/arch/s390/include/asm/mathemu.h | |||
@@ -0,0 +1,29 @@ | |||
1 | /* | ||
2 | * arch/s390/kernel/mathemu.h | ||
3 | * IEEE floating point emulation. | ||
4 | * | ||
5 | * S390 version | ||
6 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
7 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
8 | */ | ||
9 | |||
10 | #ifndef __MATHEMU__ | ||
11 | #define __MATHEMU__ | ||
12 | |||
13 | extern int math_emu_b3(__u8 *, struct pt_regs *); | ||
14 | extern int math_emu_ed(__u8 *, struct pt_regs *); | ||
15 | extern int math_emu_ldr(__u8 *); | ||
16 | extern int math_emu_ler(__u8 *); | ||
17 | extern int math_emu_std(__u8 *, struct pt_regs *); | ||
18 | extern int math_emu_ld(__u8 *, struct pt_regs *); | ||
19 | extern int math_emu_ste(__u8 *, struct pt_regs *); | ||
20 | extern int math_emu_le(__u8 *, struct pt_regs *); | ||
21 | extern int math_emu_lfpc(__u8 *, struct pt_regs *); | ||
22 | extern int math_emu_stfpc(__u8 *, struct pt_regs *); | ||
23 | extern int math_emu_srnm(__u8 *, struct pt_regs *); | ||
24 | |||
25 | #endif /* __MATHEMU__ */ | ||
26 | |||
27 | |||
28 | |||
29 | |||
diff --git a/arch/s390/include/asm/mman.h b/arch/s390/include/asm/mman.h new file mode 100644 index 000000000000..7839767d837e --- /dev/null +++ b/arch/s390/include/asm/mman.h | |||
@@ -0,0 +1,25 @@ | |||
1 | /* | ||
2 | * include/asm-s390/mman.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/mman.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef __S390_MMAN_H__ | ||
10 | #define __S390_MMAN_H__ | ||
11 | |||
12 | #include <asm-generic/mman.h> | ||
13 | |||
14 | #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ | ||
15 | #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ | ||
16 | #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ | ||
17 | #define MAP_LOCKED 0x2000 /* pages are locked */ | ||
18 | #define MAP_NORESERVE 0x4000 /* don't check for reservations */ | ||
19 | #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ | ||
20 | #define MAP_NONBLOCK 0x10000 /* do not block on IO */ | ||
21 | |||
22 | #define MCL_CURRENT 1 /* lock all current mappings */ | ||
23 | #define MCL_FUTURE 2 /* lock all future mappings */ | ||
24 | |||
25 | #endif /* __S390_MMAN_H__ */ | ||
diff --git a/arch/s390/include/asm/mmu.h b/arch/s390/include/asm/mmu.h new file mode 100644 index 000000000000..5dd5e7b3476f --- /dev/null +++ b/arch/s390/include/asm/mmu.h | |||
@@ -0,0 +1,13 @@ | |||
1 | #ifndef __MMU_H | ||
2 | #define __MMU_H | ||
3 | |||
4 | typedef struct { | ||
5 | struct list_head crst_list; | ||
6 | struct list_head pgtable_list; | ||
7 | unsigned long asce_bits; | ||
8 | unsigned long asce_limit; | ||
9 | int noexec; | ||
10 | int pgstes; | ||
11 | } mm_context_t; | ||
12 | |||
13 | #endif | ||
diff --git a/arch/s390/include/asm/mmu_context.h b/arch/s390/include/asm/mmu_context.h new file mode 100644 index 000000000000..4c2fbf48c9c4 --- /dev/null +++ b/arch/s390/include/asm/mmu_context.h | |||
@@ -0,0 +1,77 @@ | |||
1 | /* | ||
2 | * include/asm-s390/mmu_context.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/mmu_context.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef __S390_MMU_CONTEXT_H | ||
10 | #define __S390_MMU_CONTEXT_H | ||
11 | |||
12 | #include <asm/pgalloc.h> | ||
13 | #include <asm/uaccess.h> | ||
14 | #include <asm-generic/mm_hooks.h> | ||
15 | |||
16 | static inline int init_new_context(struct task_struct *tsk, | ||
17 | struct mm_struct *mm) | ||
18 | { | ||
19 | mm->context.asce_bits = _ASCE_TABLE_LENGTH | _ASCE_USER_BITS; | ||
20 | #ifdef CONFIG_64BIT | ||
21 | mm->context.asce_bits |= _ASCE_TYPE_REGION3; | ||
22 | #endif | ||
23 | if (current->mm->context.pgstes) { | ||
24 | mm->context.noexec = 0; | ||
25 | mm->context.pgstes = 1; | ||
26 | } else { | ||
27 | mm->context.noexec = s390_noexec; | ||
28 | mm->context.pgstes = 0; | ||
29 | } | ||
30 | mm->context.asce_limit = STACK_TOP_MAX; | ||
31 | crst_table_init((unsigned long *) mm->pgd, pgd_entry_type(mm)); | ||
32 | return 0; | ||
33 | } | ||
34 | |||
35 | #define destroy_context(mm) do { } while (0) | ||
36 | |||
37 | #ifndef __s390x__ | ||
38 | #define LCTL_OPCODE "lctl" | ||
39 | #else | ||
40 | #define LCTL_OPCODE "lctlg" | ||
41 | #endif | ||
42 | |||
43 | static inline void update_mm(struct mm_struct *mm, struct task_struct *tsk) | ||
44 | { | ||
45 | pgd_t *pgd = mm->pgd; | ||
46 | |||
47 | S390_lowcore.user_asce = mm->context.asce_bits | __pa(pgd); | ||
48 | if (switch_amode) { | ||
49 | /* Load primary space page table origin. */ | ||
50 | pgd = mm->context.noexec ? get_shadow_table(pgd) : pgd; | ||
51 | S390_lowcore.user_exec_asce = mm->context.asce_bits | __pa(pgd); | ||
52 | asm volatile(LCTL_OPCODE" 1,1,%0\n" | ||
53 | : : "m" (S390_lowcore.user_exec_asce) ); | ||
54 | } else | ||
55 | /* Load home space page table origin. */ | ||
56 | asm volatile(LCTL_OPCODE" 13,13,%0" | ||
57 | : : "m" (S390_lowcore.user_asce) ); | ||
58 | set_fs(current->thread.mm_segment); | ||
59 | } | ||
60 | |||
61 | static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | ||
62 | struct task_struct *tsk) | ||
63 | { | ||
64 | cpu_set(smp_processor_id(), next->cpu_vm_mask); | ||
65 | update_mm(next, tsk); | ||
66 | } | ||
67 | |||
68 | #define enter_lazy_tlb(mm,tsk) do { } while (0) | ||
69 | #define deactivate_mm(tsk,mm) do { } while (0) | ||
70 | |||
71 | static inline void activate_mm(struct mm_struct *prev, | ||
72 | struct mm_struct *next) | ||
73 | { | ||
74 | switch_mm(prev, next, current); | ||
75 | } | ||
76 | |||
77 | #endif /* __S390_MMU_CONTEXT_H */ | ||
diff --git a/arch/s390/include/asm/module.h b/arch/s390/include/asm/module.h new file mode 100644 index 000000000000..1cc1c5af705a --- /dev/null +++ b/arch/s390/include/asm/module.h | |||
@@ -0,0 +1,46 @@ | |||
1 | #ifndef _ASM_S390_MODULE_H | ||
2 | #define _ASM_S390_MODULE_H | ||
3 | /* | ||
4 | * This file contains the s390 architecture specific module code. | ||
5 | */ | ||
6 | |||
7 | struct mod_arch_syminfo | ||
8 | { | ||
9 | unsigned long got_offset; | ||
10 | unsigned long plt_offset; | ||
11 | int got_initialized; | ||
12 | int plt_initialized; | ||
13 | }; | ||
14 | |||
15 | struct mod_arch_specific | ||
16 | { | ||
17 | /* Starting offset of got in the module core memory. */ | ||
18 | unsigned long got_offset; | ||
19 | /* Starting offset of plt in the module core memory. */ | ||
20 | unsigned long plt_offset; | ||
21 | /* Size of the got. */ | ||
22 | unsigned long got_size; | ||
23 | /* Size of the plt. */ | ||
24 | unsigned long plt_size; | ||
25 | /* Number of symbols in syminfo. */ | ||
26 | int nsyms; | ||
27 | /* Additional symbol information (got and plt offsets). */ | ||
28 | struct mod_arch_syminfo *syminfo; | ||
29 | }; | ||
30 | |||
31 | #ifdef __s390x__ | ||
32 | #define ElfW(x) Elf64_ ## x | ||
33 | #define ELFW(x) ELF64_ ## x | ||
34 | #else | ||
35 | #define ElfW(x) Elf32_ ## x | ||
36 | #define ELFW(x) ELF32_ ## x | ||
37 | #endif | ||
38 | |||
39 | #define Elf_Addr ElfW(Addr) | ||
40 | #define Elf_Rela ElfW(Rela) | ||
41 | #define Elf_Shdr ElfW(Shdr) | ||
42 | #define Elf_Sym ElfW(Sym) | ||
43 | #define Elf_Ehdr ElfW(Ehdr) | ||
44 | #define ELF_R_SYM ELFW(R_SYM) | ||
45 | #define ELF_R_TYPE ELFW(R_TYPE) | ||
46 | #endif /* _ASM_S390_MODULE_H */ | ||
diff --git a/arch/s390/include/asm/monwriter.h b/arch/s390/include/asm/monwriter.h new file mode 100644 index 000000000000..f0cbf96c52e6 --- /dev/null +++ b/arch/s390/include/asm/monwriter.h | |||
@@ -0,0 +1,33 @@ | |||
1 | /* | ||
2 | * include/asm-s390/monwriter.h | ||
3 | * | ||
4 | * Copyright (C) IBM Corp. 2006 | ||
5 | * Character device driver for writing z/VM APPLDATA monitor records | ||
6 | * Version 1.0 | ||
7 | * Author(s): Melissa Howland <melissah@us.ibm.com> | ||
8 | * | ||
9 | */ | ||
10 | |||
11 | #ifndef _ASM_390_MONWRITER_H | ||
12 | #define _ASM_390_MONWRITER_H | ||
13 | |||
14 | /* mon_function values */ | ||
15 | #define MONWRITE_START_INTERVAL 0x00 /* start interval recording */ | ||
16 | #define MONWRITE_STOP_INTERVAL 0x01 /* stop interval or config recording */ | ||
17 | #define MONWRITE_GEN_EVENT 0x02 /* generate event record */ | ||
18 | #define MONWRITE_START_CONFIG 0x03 /* start configuration recording */ | ||
19 | |||
20 | /* the header the app uses in its write() data */ | ||
21 | struct monwrite_hdr { | ||
22 | unsigned char mon_function; | ||
23 | unsigned short applid; | ||
24 | unsigned char record_num; | ||
25 | unsigned short version; | ||
26 | unsigned short release; | ||
27 | unsigned short mod_level; | ||
28 | unsigned short datalen; | ||
29 | unsigned char hdrlen; | ||
30 | |||
31 | } __attribute__((packed)); | ||
32 | |||
33 | #endif /* _ASM_390_MONWRITER_H */ | ||
diff --git a/arch/s390/include/asm/msgbuf.h b/arch/s390/include/asm/msgbuf.h new file mode 100644 index 000000000000..1bbdee927924 --- /dev/null +++ b/arch/s390/include/asm/msgbuf.h | |||
@@ -0,0 +1,37 @@ | |||
1 | #ifndef _S390_MSGBUF_H | ||
2 | #define _S390_MSGBUF_H | ||
3 | |||
4 | /* | ||
5 | * The msqid64_ds structure for S/390 architecture. | ||
6 | * Note extra padding because this structure is passed back and forth | ||
7 | * between kernel and user space. | ||
8 | * | ||
9 | * Pad space is left for: | ||
10 | * - 64-bit time_t to solve y2038 problem | ||
11 | * - 2 miscellaneous 32-bit values | ||
12 | */ | ||
13 | |||
14 | struct msqid64_ds { | ||
15 | struct ipc64_perm msg_perm; | ||
16 | __kernel_time_t msg_stime; /* last msgsnd time */ | ||
17 | #ifndef __s390x__ | ||
18 | unsigned long __unused1; | ||
19 | #endif /* ! __s390x__ */ | ||
20 | __kernel_time_t msg_rtime; /* last msgrcv time */ | ||
21 | #ifndef __s390x__ | ||
22 | unsigned long __unused2; | ||
23 | #endif /* ! __s390x__ */ | ||
24 | __kernel_time_t msg_ctime; /* last change time */ | ||
25 | #ifndef __s390x__ | ||
26 | unsigned long __unused3; | ||
27 | #endif /* ! __s390x__ */ | ||
28 | unsigned long msg_cbytes; /* current number of bytes on queue */ | ||
29 | unsigned long msg_qnum; /* number of messages in queue */ | ||
30 | unsigned long msg_qbytes; /* max number of bytes on queue */ | ||
31 | __kernel_pid_t msg_lspid; /* pid of last msgsnd */ | ||
32 | __kernel_pid_t msg_lrpid; /* last receive pid */ | ||
33 | unsigned long __unused4; | ||
34 | unsigned long __unused5; | ||
35 | }; | ||
36 | |||
37 | #endif /* _S390_MSGBUF_H */ | ||
diff --git a/arch/s390/include/asm/mutex.h b/arch/s390/include/asm/mutex.h new file mode 100644 index 000000000000..458c1f7fbc18 --- /dev/null +++ b/arch/s390/include/asm/mutex.h | |||
@@ -0,0 +1,9 @@ | |||
1 | /* | ||
2 | * Pull in the generic implementation for the mutex fastpath. | ||
3 | * | ||
4 | * TODO: implement optimized primitives instead, or leave the generic | ||
5 | * implementation in place, or pick the atomic_xchg() based generic | ||
6 | * implementation. (see asm-generic/mutex-xchg.h for details) | ||
7 | */ | ||
8 | |||
9 | #include <asm-generic/mutex-dec.h> | ||
diff --git a/arch/s390/include/asm/page.h b/arch/s390/include/asm/page.h new file mode 100644 index 000000000000..991ba939408c --- /dev/null +++ b/arch/s390/include/asm/page.h | |||
@@ -0,0 +1,155 @@ | |||
1 | /* | ||
2 | * include/asm-s390/page.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Hartmut Penner (hp@de.ibm.com) | ||
7 | */ | ||
8 | |||
9 | #ifndef _S390_PAGE_H | ||
10 | #define _S390_PAGE_H | ||
11 | |||
12 | #include <linux/const.h> | ||
13 | #include <asm/types.h> | ||
14 | |||
15 | /* PAGE_SHIFT determines the page size */ | ||
16 | #define PAGE_SHIFT 12 | ||
17 | #define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) | ||
18 | #define PAGE_MASK (~(PAGE_SIZE-1)) | ||
19 | #define PAGE_DEFAULT_ACC 0 | ||
20 | #define PAGE_DEFAULT_KEY (PAGE_DEFAULT_ACC << 4) | ||
21 | |||
22 | #define HPAGE_SHIFT 20 | ||
23 | #define HPAGE_SIZE (1UL << HPAGE_SHIFT) | ||
24 | #define HPAGE_MASK (~(HPAGE_SIZE - 1)) | ||
25 | #define HUGETLB_PAGE_ORDER (HPAGE_SHIFT - PAGE_SHIFT) | ||
26 | |||
27 | #define ARCH_HAS_SETCLEAR_HUGE_PTE | ||
28 | #define ARCH_HAS_HUGE_PTE_TYPE | ||
29 | #define ARCH_HAS_PREPARE_HUGEPAGE | ||
30 | #define ARCH_HAS_HUGEPAGE_CLEAR_FLUSH | ||
31 | |||
32 | #include <asm/setup.h> | ||
33 | #ifndef __ASSEMBLY__ | ||
34 | |||
35 | static inline void clear_page(void *page) | ||
36 | { | ||
37 | if (MACHINE_HAS_PFMF) { | ||
38 | asm volatile( | ||
39 | " .insn rre,0xb9af0000,%0,%1" | ||
40 | : : "d" (0x10000), "a" (page) : "memory", "cc"); | ||
41 | } else { | ||
42 | register unsigned long reg1 asm ("1") = 0; | ||
43 | register void *reg2 asm ("2") = page; | ||
44 | register unsigned long reg3 asm ("3") = 4096; | ||
45 | asm volatile( | ||
46 | " mvcl 2,0" | ||
47 | : "+d" (reg2), "+d" (reg3) : "d" (reg1) | ||
48 | : "memory", "cc"); | ||
49 | } | ||
50 | } | ||
51 | |||
52 | static inline void copy_page(void *to, void *from) | ||
53 | { | ||
54 | if (MACHINE_HAS_MVPG) { | ||
55 | register unsigned long reg0 asm ("0") = 0; | ||
56 | asm volatile( | ||
57 | " mvpg %0,%1" | ||
58 | : : "a" (to), "a" (from), "d" (reg0) | ||
59 | : "memory", "cc"); | ||
60 | } else | ||
61 | asm volatile( | ||
62 | " mvc 0(256,%0),0(%1)\n" | ||
63 | " mvc 256(256,%0),256(%1)\n" | ||
64 | " mvc 512(256,%0),512(%1)\n" | ||
65 | " mvc 768(256,%0),768(%1)\n" | ||
66 | " mvc 1024(256,%0),1024(%1)\n" | ||
67 | " mvc 1280(256,%0),1280(%1)\n" | ||
68 | " mvc 1536(256,%0),1536(%1)\n" | ||
69 | " mvc 1792(256,%0),1792(%1)\n" | ||
70 | " mvc 2048(256,%0),2048(%1)\n" | ||
71 | " mvc 2304(256,%0),2304(%1)\n" | ||
72 | " mvc 2560(256,%0),2560(%1)\n" | ||
73 | " mvc 2816(256,%0),2816(%1)\n" | ||
74 | " mvc 3072(256,%0),3072(%1)\n" | ||
75 | " mvc 3328(256,%0),3328(%1)\n" | ||
76 | " mvc 3584(256,%0),3584(%1)\n" | ||
77 | " mvc 3840(256,%0),3840(%1)\n" | ||
78 | : : "a" (to), "a" (from) : "memory"); | ||
79 | } | ||
80 | |||
81 | #define clear_user_page(page, vaddr, pg) clear_page(page) | ||
82 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) | ||
83 | |||
84 | #define __alloc_zeroed_user_highpage(movableflags, vma, vaddr) \ | ||
85 | alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO | movableflags, vma, vaddr) | ||
86 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE | ||
87 | |||
88 | /* | ||
89 | * These are used to make use of C type-checking.. | ||
90 | */ | ||
91 | |||
92 | typedef struct { unsigned long pgprot; } pgprot_t; | ||
93 | typedef struct { unsigned long pte; } pte_t; | ||
94 | typedef struct { unsigned long pmd; } pmd_t; | ||
95 | typedef struct { unsigned long pud; } pud_t; | ||
96 | typedef struct { unsigned long pgd; } pgd_t; | ||
97 | typedef pte_t *pgtable_t; | ||
98 | |||
99 | #define pgprot_val(x) ((x).pgprot) | ||
100 | #define pte_val(x) ((x).pte) | ||
101 | #define pmd_val(x) ((x).pmd) | ||
102 | #define pud_val(x) ((x).pud) | ||
103 | #define pgd_val(x) ((x).pgd) | ||
104 | |||
105 | #define __pte(x) ((pte_t) { (x) } ) | ||
106 | #define __pmd(x) ((pmd_t) { (x) } ) | ||
107 | #define __pgd(x) ((pgd_t) { (x) } ) | ||
108 | #define __pgprot(x) ((pgprot_t) { (x) } ) | ||
109 | |||
110 | /* default storage key used for all pages */ | ||
111 | extern unsigned int default_storage_key; | ||
112 | |||
113 | static inline void | ||
114 | page_set_storage_key(unsigned long addr, unsigned int skey) | ||
115 | { | ||
116 | asm volatile("sske %0,%1" : : "d" (skey), "a" (addr)); | ||
117 | } | ||
118 | |||
119 | static inline unsigned int | ||
120 | page_get_storage_key(unsigned long addr) | ||
121 | { | ||
122 | unsigned int skey; | ||
123 | |||
124 | asm volatile("iske %0,%1" : "=d" (skey) : "a" (addr), "0" (0)); | ||
125 | return skey; | ||
126 | } | ||
127 | |||
128 | #ifdef CONFIG_PAGE_STATES | ||
129 | |||
130 | struct page; | ||
131 | void arch_free_page(struct page *page, int order); | ||
132 | void arch_alloc_page(struct page *page, int order); | ||
133 | |||
134 | #define HAVE_ARCH_FREE_PAGE | ||
135 | #define HAVE_ARCH_ALLOC_PAGE | ||
136 | |||
137 | #endif | ||
138 | |||
139 | #endif /* !__ASSEMBLY__ */ | ||
140 | |||
141 | #define __PAGE_OFFSET 0x0UL | ||
142 | #define PAGE_OFFSET 0x0UL | ||
143 | #define __pa(x) (unsigned long)(x) | ||
144 | #define __va(x) (void *)(unsigned long)(x) | ||
145 | #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) | ||
146 | #define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) | ||
147 | #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) | ||
148 | |||
149 | #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | \ | ||
150 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | ||
151 | |||
152 | #include <asm-generic/memory_model.h> | ||
153 | #include <asm-generic/page.h> | ||
154 | |||
155 | #endif /* _S390_PAGE_H */ | ||
diff --git a/arch/s390/include/asm/param.h b/arch/s390/include/asm/param.h new file mode 100644 index 000000000000..34aaa4603347 --- /dev/null +++ b/arch/s390/include/asm/param.h | |||
@@ -0,0 +1,30 @@ | |||
1 | /* | ||
2 | * include/asm-s390/param.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/param.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef _ASMS390_PARAM_H | ||
10 | #define _ASMS390_PARAM_H | ||
11 | |||
12 | #ifdef __KERNEL__ | ||
13 | # define HZ CONFIG_HZ /* Internal kernel timer frequency */ | ||
14 | # define USER_HZ 100 /* .. some user interfaces are in "ticks" */ | ||
15 | # define CLOCKS_PER_SEC (USER_HZ) /* like times() */ | ||
16 | #endif | ||
17 | |||
18 | #ifndef HZ | ||
19 | #define HZ 100 | ||
20 | #endif | ||
21 | |||
22 | #define EXEC_PAGESIZE 4096 | ||
23 | |||
24 | #ifndef NOGROUP | ||
25 | #define NOGROUP (-1) | ||
26 | #endif | ||
27 | |||
28 | #define MAXHOSTNAMELEN 64 /* max length of hostname */ | ||
29 | |||
30 | #endif | ||
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h new file mode 100644 index 000000000000..42a145c9ddd6 --- /dev/null +++ b/arch/s390/include/asm/pci.h | |||
@@ -0,0 +1,10 @@ | |||
1 | #ifndef __ASM_S390_PCI_H | ||
2 | #define __ASM_S390_PCI_H | ||
3 | |||
4 | /* S/390 systems don't have a PCI bus. This file is just here because some stupid .c code | ||
5 | * includes it even if CONFIG_PCI is not set. | ||
6 | */ | ||
7 | #define PCI_DMA_BUS_IS_PHYS (0) | ||
8 | |||
9 | #endif /* __ASM_S390_PCI_H */ | ||
10 | |||
diff --git a/arch/s390/include/asm/percpu.h b/arch/s390/include/asm/percpu.h new file mode 100644 index 000000000000..408d60b4f75b --- /dev/null +++ b/arch/s390/include/asm/percpu.h | |||
@@ -0,0 +1,37 @@ | |||
1 | #ifndef __ARCH_S390_PERCPU__ | ||
2 | #define __ARCH_S390_PERCPU__ | ||
3 | |||
4 | #include <linux/compiler.h> | ||
5 | #include <asm/lowcore.h> | ||
6 | |||
7 | /* | ||
8 | * s390 uses its own implementation for per cpu data, the offset of | ||
9 | * the cpu local data area is cached in the cpu's lowcore memory. | ||
10 | * For 64 bit module code s390 forces the use of a GOT slot for the | ||
11 | * address of the per cpu variable. This is needed because the module | ||
12 | * may be more than 4G above the per cpu area. | ||
13 | */ | ||
14 | #if defined(__s390x__) && defined(MODULE) | ||
15 | |||
16 | #define SHIFT_PERCPU_PTR(ptr,offset) (({ \ | ||
17 | extern int simple_identifier_##var(void); \ | ||
18 | unsigned long *__ptr; \ | ||
19 | asm ( "larl %0, %1@GOTENT" \ | ||
20 | : "=a" (__ptr) : "X" (ptr) ); \ | ||
21 | (typeof(ptr))((*__ptr) + (offset)); })) | ||
22 | |||
23 | #else | ||
24 | |||
25 | #define SHIFT_PERCPU_PTR(ptr, offset) (({ \ | ||
26 | extern int simple_identifier_##var(void); \ | ||
27 | unsigned long __ptr; \ | ||
28 | asm ( "" : "=a" (__ptr) : "0" (ptr) ); \ | ||
29 | (typeof(ptr)) (__ptr + (offset)); })) | ||
30 | |||
31 | #endif | ||
32 | |||
33 | #define __my_cpu_offset S390_lowcore.percpu_offset | ||
34 | |||
35 | #include <asm-generic/percpu.h> | ||
36 | |||
37 | #endif /* __ARCH_S390_PERCPU__ */ | ||
diff --git a/arch/s390/include/asm/pgalloc.h b/arch/s390/include/asm/pgalloc.h new file mode 100644 index 000000000000..f5b2bf3d7c1d --- /dev/null +++ b/arch/s390/include/asm/pgalloc.h | |||
@@ -0,0 +1,174 @@ | |||
1 | /* | ||
2 | * include/asm-s390/pgalloc.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Hartmut Penner (hp@de.ibm.com) | ||
7 | * Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
8 | * | ||
9 | * Derived from "include/asm-i386/pgalloc.h" | ||
10 | * Copyright (C) 1994 Linus Torvalds | ||
11 | */ | ||
12 | |||
13 | #ifndef _S390_PGALLOC_H | ||
14 | #define _S390_PGALLOC_H | ||
15 | |||
16 | #include <linux/threads.h> | ||
17 | #include <linux/gfp.h> | ||
18 | #include <linux/mm.h> | ||
19 | |||
20 | #define check_pgt_cache() do {} while (0) | ||
21 | |||
22 | unsigned long *crst_table_alloc(struct mm_struct *, int); | ||
23 | void crst_table_free(struct mm_struct *, unsigned long *); | ||
24 | |||
25 | unsigned long *page_table_alloc(struct mm_struct *); | ||
26 | void page_table_free(struct mm_struct *, unsigned long *); | ||
27 | void disable_noexec(struct mm_struct *, struct task_struct *); | ||
28 | |||
29 | static inline void clear_table(unsigned long *s, unsigned long val, size_t n) | ||
30 | { | ||
31 | *s = val; | ||
32 | n = (n / 256) - 1; | ||
33 | asm volatile( | ||
34 | #ifdef CONFIG_64BIT | ||
35 | " mvc 8(248,%0),0(%0)\n" | ||
36 | #else | ||
37 | " mvc 4(252,%0),0(%0)\n" | ||
38 | #endif | ||
39 | "0: mvc 256(256,%0),0(%0)\n" | ||
40 | " la %0,256(%0)\n" | ||
41 | " brct %1,0b\n" | ||
42 | : "+a" (s), "+d" (n)); | ||
43 | } | ||
44 | |||
45 | static inline void crst_table_init(unsigned long *crst, unsigned long entry) | ||
46 | { | ||
47 | clear_table(crst, entry, sizeof(unsigned long)*2048); | ||
48 | crst = get_shadow_table(crst); | ||
49 | if (crst) | ||
50 | clear_table(crst, entry, sizeof(unsigned long)*2048); | ||
51 | } | ||
52 | |||
53 | #ifndef __s390x__ | ||
54 | |||
55 | static inline unsigned long pgd_entry_type(struct mm_struct *mm) | ||
56 | { | ||
57 | return _SEGMENT_ENTRY_EMPTY; | ||
58 | } | ||
59 | |||
60 | #define pud_alloc_one(mm,address) ({ BUG(); ((pud_t *)2); }) | ||
61 | #define pud_free(mm, x) do { } while (0) | ||
62 | |||
63 | #define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) | ||
64 | #define pmd_free(mm, x) do { } while (0) | ||
65 | |||
66 | #define pgd_populate(mm, pgd, pud) BUG() | ||
67 | #define pgd_populate_kernel(mm, pgd, pud) BUG() | ||
68 | |||
69 | #define pud_populate(mm, pud, pmd) BUG() | ||
70 | #define pud_populate_kernel(mm, pud, pmd) BUG() | ||
71 | |||
72 | #else /* __s390x__ */ | ||
73 | |||
74 | static inline unsigned long pgd_entry_type(struct mm_struct *mm) | ||
75 | { | ||
76 | if (mm->context.asce_limit <= (1UL << 31)) | ||
77 | return _SEGMENT_ENTRY_EMPTY; | ||
78 | if (mm->context.asce_limit <= (1UL << 42)) | ||
79 | return _REGION3_ENTRY_EMPTY; | ||
80 | return _REGION2_ENTRY_EMPTY; | ||
81 | } | ||
82 | |||
83 | int crst_table_upgrade(struct mm_struct *, unsigned long limit); | ||
84 | void crst_table_downgrade(struct mm_struct *, unsigned long limit); | ||
85 | |||
86 | static inline pud_t *pud_alloc_one(struct mm_struct *mm, unsigned long address) | ||
87 | { | ||
88 | unsigned long *table = crst_table_alloc(mm, mm->context.noexec); | ||
89 | if (table) | ||
90 | crst_table_init(table, _REGION3_ENTRY_EMPTY); | ||
91 | return (pud_t *) table; | ||
92 | } | ||
93 | #define pud_free(mm, pud) crst_table_free(mm, (unsigned long *) pud) | ||
94 | |||
95 | static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) | ||
96 | { | ||
97 | unsigned long *table = crst_table_alloc(mm, mm->context.noexec); | ||
98 | if (table) | ||
99 | crst_table_init(table, _SEGMENT_ENTRY_EMPTY); | ||
100 | return (pmd_t *) table; | ||
101 | } | ||
102 | #define pmd_free(mm, pmd) crst_table_free(mm, (unsigned long *) pmd) | ||
103 | |||
104 | static inline void pgd_populate_kernel(struct mm_struct *mm, | ||
105 | pgd_t *pgd, pud_t *pud) | ||
106 | { | ||
107 | pgd_val(*pgd) = _REGION2_ENTRY | __pa(pud); | ||
108 | } | ||
109 | |||
110 | static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pud_t *pud) | ||
111 | { | ||
112 | pgd_populate_kernel(mm, pgd, pud); | ||
113 | if (mm->context.noexec) { | ||
114 | pgd = get_shadow_table(pgd); | ||
115 | pud = get_shadow_table(pud); | ||
116 | pgd_populate_kernel(mm, pgd, pud); | ||
117 | } | ||
118 | } | ||
119 | |||
120 | static inline void pud_populate_kernel(struct mm_struct *mm, | ||
121 | pud_t *pud, pmd_t *pmd) | ||
122 | { | ||
123 | pud_val(*pud) = _REGION3_ENTRY | __pa(pmd); | ||
124 | } | ||
125 | |||
126 | static inline void pud_populate(struct mm_struct *mm, pud_t *pud, pmd_t *pmd) | ||
127 | { | ||
128 | pud_populate_kernel(mm, pud, pmd); | ||
129 | if (mm->context.noexec) { | ||
130 | pud = get_shadow_table(pud); | ||
131 | pmd = get_shadow_table(pmd); | ||
132 | pud_populate_kernel(mm, pud, pmd); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | #endif /* __s390x__ */ | ||
137 | |||
138 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) | ||
139 | { | ||
140 | INIT_LIST_HEAD(&mm->context.crst_list); | ||
141 | INIT_LIST_HEAD(&mm->context.pgtable_list); | ||
142 | return (pgd_t *) crst_table_alloc(mm, s390_noexec); | ||
143 | } | ||
144 | #define pgd_free(mm, pgd) crst_table_free(mm, (unsigned long *) pgd) | ||
145 | |||
146 | static inline void pmd_populate_kernel(struct mm_struct *mm, | ||
147 | pmd_t *pmd, pte_t *pte) | ||
148 | { | ||
149 | pmd_val(*pmd) = _SEGMENT_ENTRY + __pa(pte); | ||
150 | } | ||
151 | |||
152 | static inline void pmd_populate(struct mm_struct *mm, | ||
153 | pmd_t *pmd, pgtable_t pte) | ||
154 | { | ||
155 | pmd_populate_kernel(mm, pmd, pte); | ||
156 | if (mm->context.noexec) { | ||
157 | pmd = get_shadow_table(pmd); | ||
158 | pmd_populate_kernel(mm, pmd, pte + PTRS_PER_PTE); | ||
159 | } | ||
160 | } | ||
161 | |||
162 | #define pmd_pgtable(pmd) \ | ||
163 | (pgtable_t)(pmd_val(pmd) & -sizeof(pte_t)*PTRS_PER_PTE) | ||
164 | |||
165 | /* | ||
166 | * page table entry allocation/free routines. | ||
167 | */ | ||
168 | #define pte_alloc_one_kernel(mm, vmaddr) ((pte_t *) page_table_alloc(mm)) | ||
169 | #define pte_alloc_one(mm, vmaddr) ((pte_t *) page_table_alloc(mm)) | ||
170 | |||
171 | #define pte_free_kernel(mm, pte) page_table_free(mm, (unsigned long *) pte) | ||
172 | #define pte_free(mm, pte) page_table_free(mm, (unsigned long *) pte) | ||
173 | |||
174 | #endif /* _S390_PGALLOC_H */ | ||
diff --git a/arch/s390/include/asm/pgtable.h b/arch/s390/include/asm/pgtable.h new file mode 100644 index 000000000000..0bdb704ae051 --- /dev/null +++ b/arch/s390/include/asm/pgtable.h | |||
@@ -0,0 +1,1093 @@ | |||
1 | /* | ||
2 | * include/asm-s390/pgtable.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Hartmut Penner (hp@de.ibm.com) | ||
7 | * Ulrich Weigand (weigand@de.ibm.com) | ||
8 | * Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
9 | * | ||
10 | * Derived from "include/asm-i386/pgtable.h" | ||
11 | */ | ||
12 | |||
13 | #ifndef _ASM_S390_PGTABLE_H | ||
14 | #define _ASM_S390_PGTABLE_H | ||
15 | |||
16 | /* | ||
17 | * The Linux memory management assumes a three-level page table setup. For | ||
18 | * s390 31 bit we "fold" the mid level into the top-level page table, so | ||
19 | * that we physically have the same two-level page table as the s390 mmu | ||
20 | * expects in 31 bit mode. For s390 64 bit we use three of the five levels | ||
21 | * the hardware provides (region first and region second tables are not | ||
22 | * used). | ||
23 | * | ||
24 | * The "pgd_xxx()" functions are trivial for a folded two-level | ||
25 | * setup: the pgd is never bad, and a pmd always exists (as it's folded | ||
26 | * into the pgd entry) | ||
27 | * | ||
28 | * This file contains the functions and defines necessary to modify and use | ||
29 | * the S390 page table tree. | ||
30 | */ | ||
31 | #ifndef __ASSEMBLY__ | ||
32 | #include <linux/sched.h> | ||
33 | #include <linux/mm_types.h> | ||
34 | #include <asm/bitops.h> | ||
35 | #include <asm/bug.h> | ||
36 | #include <asm/processor.h> | ||
37 | |||
38 | extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096))); | ||
39 | extern void paging_init(void); | ||
40 | extern void vmem_map_init(void); | ||
41 | |||
42 | /* | ||
43 | * The S390 doesn't have any external MMU info: the kernel page | ||
44 | * tables contain all the necessary information. | ||
45 | */ | ||
46 | #define update_mmu_cache(vma, address, pte) do { } while (0) | ||
47 | |||
48 | /* | ||
49 | * ZERO_PAGE is a global shared page that is always zero: used | ||
50 | * for zero-mapped memory areas etc.. | ||
51 | */ | ||
52 | extern char empty_zero_page[PAGE_SIZE]; | ||
53 | #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) | ||
54 | #endif /* !__ASSEMBLY__ */ | ||
55 | |||
56 | /* | ||
57 | * PMD_SHIFT determines the size of the area a second-level page | ||
58 | * table can map | ||
59 | * PGDIR_SHIFT determines what a third-level page table entry can map | ||
60 | */ | ||
61 | #ifndef __s390x__ | ||
62 | # define PMD_SHIFT 20 | ||
63 | # define PUD_SHIFT 20 | ||
64 | # define PGDIR_SHIFT 20 | ||
65 | #else /* __s390x__ */ | ||
66 | # define PMD_SHIFT 20 | ||
67 | # define PUD_SHIFT 31 | ||
68 | # define PGDIR_SHIFT 42 | ||
69 | #endif /* __s390x__ */ | ||
70 | |||
71 | #define PMD_SIZE (1UL << PMD_SHIFT) | ||
72 | #define PMD_MASK (~(PMD_SIZE-1)) | ||
73 | #define PUD_SIZE (1UL << PUD_SHIFT) | ||
74 | #define PUD_MASK (~(PUD_SIZE-1)) | ||
75 | #define PGDIR_SIZE (1UL << PGDIR_SHIFT) | ||
76 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) | ||
77 | |||
78 | /* | ||
79 | * entries per page directory level: the S390 is two-level, so | ||
80 | * we don't really have any PMD directory physically. | ||
81 | * for S390 segment-table entries are combined to one PGD | ||
82 | * that leads to 1024 pte per pgd | ||
83 | */ | ||
84 | #define PTRS_PER_PTE 256 | ||
85 | #ifndef __s390x__ | ||
86 | #define PTRS_PER_PMD 1 | ||
87 | #define PTRS_PER_PUD 1 | ||
88 | #else /* __s390x__ */ | ||
89 | #define PTRS_PER_PMD 2048 | ||
90 | #define PTRS_PER_PUD 2048 | ||
91 | #endif /* __s390x__ */ | ||
92 | #define PTRS_PER_PGD 2048 | ||
93 | |||
94 | #define FIRST_USER_ADDRESS 0 | ||
95 | |||
96 | #define pte_ERROR(e) \ | ||
97 | printk("%s:%d: bad pte %p.\n", __FILE__, __LINE__, (void *) pte_val(e)) | ||
98 | #define pmd_ERROR(e) \ | ||
99 | printk("%s:%d: bad pmd %p.\n", __FILE__, __LINE__, (void *) pmd_val(e)) | ||
100 | #define pud_ERROR(e) \ | ||
101 | printk("%s:%d: bad pud %p.\n", __FILE__, __LINE__, (void *) pud_val(e)) | ||
102 | #define pgd_ERROR(e) \ | ||
103 | printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e)) | ||
104 | |||
105 | #ifndef __ASSEMBLY__ | ||
106 | /* | ||
107 | * The vmalloc area will always be on the topmost area of the kernel | ||
108 | * mapping. We reserve 96MB (31bit) / 1GB (64bit) for vmalloc, | ||
109 | * which should be enough for any sane case. | ||
110 | * By putting vmalloc at the top, we maximise the gap between physical | ||
111 | * memory and vmalloc to catch misplaced memory accesses. As a side | ||
112 | * effect, this also makes sure that 64 bit module code cannot be used | ||
113 | * as system call address. | ||
114 | */ | ||
115 | #ifndef __s390x__ | ||
116 | #define VMALLOC_START 0x78000000UL | ||
117 | #define VMALLOC_END 0x7e000000UL | ||
118 | #define VMEM_MAP_END 0x80000000UL | ||
119 | #else /* __s390x__ */ | ||
120 | #define VMALLOC_START 0x3e000000000UL | ||
121 | #define VMALLOC_END 0x3e040000000UL | ||
122 | #define VMEM_MAP_END 0x40000000000UL | ||
123 | #endif /* __s390x__ */ | ||
124 | |||
125 | /* | ||
126 | * VMEM_MAX_PHYS is the highest physical address that can be added to the 1:1 | ||
127 | * mapping. This needs to be calculated at compile time since the size of the | ||
128 | * VMEM_MAP is static but the size of struct page can change. | ||
129 | */ | ||
130 | #define VMEM_MAX_PAGES ((VMEM_MAP_END - VMALLOC_END) / sizeof(struct page)) | ||
131 | #define VMEM_MAX_PFN min(VMALLOC_START >> PAGE_SHIFT, VMEM_MAX_PAGES) | ||
132 | #define VMEM_MAX_PHYS ((VMEM_MAX_PFN << PAGE_SHIFT) & ~((16 << 20) - 1)) | ||
133 | #define vmemmap ((struct page *) VMALLOC_END) | ||
134 | |||
135 | /* | ||
136 | * A 31 bit pagetable entry of S390 has following format: | ||
137 | * | PFRA | | OS | | ||
138 | * 0 0IP0 | ||
139 | * 00000000001111111111222222222233 | ||
140 | * 01234567890123456789012345678901 | ||
141 | * | ||
142 | * I Page-Invalid Bit: Page is not available for address-translation | ||
143 | * P Page-Protection Bit: Store access not possible for page | ||
144 | * | ||
145 | * A 31 bit segmenttable entry of S390 has following format: | ||
146 | * | P-table origin | |PTL | ||
147 | * 0 IC | ||
148 | * 00000000001111111111222222222233 | ||
149 | * 01234567890123456789012345678901 | ||
150 | * | ||
151 | * I Segment-Invalid Bit: Segment is not available for address-translation | ||
152 | * C Common-Segment Bit: Segment is not private (PoP 3-30) | ||
153 | * PTL Page-Table-Length: Page-table length (PTL+1*16 entries -> up to 256) | ||
154 | * | ||
155 | * The 31 bit segmenttable origin of S390 has following format: | ||
156 | * | ||
157 | * |S-table origin | | STL | | ||
158 | * X **GPS | ||
159 | * 00000000001111111111222222222233 | ||
160 | * 01234567890123456789012345678901 | ||
161 | * | ||
162 | * X Space-Switch event: | ||
163 | * G Segment-Invalid Bit: * | ||
164 | * P Private-Space Bit: Segment is not private (PoP 3-30) | ||
165 | * S Storage-Alteration: | ||
166 | * STL Segment-Table-Length: Segment-table length (STL+1*16 entries -> up to 2048) | ||
167 | * | ||
168 | * A 64 bit pagetable entry of S390 has following format: | ||
169 | * | PFRA |0IP0| OS | | ||
170 | * 0000000000111111111122222222223333333333444444444455555555556666 | ||
171 | * 0123456789012345678901234567890123456789012345678901234567890123 | ||
172 | * | ||
173 | * I Page-Invalid Bit: Page is not available for address-translation | ||
174 | * P Page-Protection Bit: Store access not possible for page | ||
175 | * | ||
176 | * A 64 bit segmenttable entry of S390 has following format: | ||
177 | * | P-table origin | TT | ||
178 | * 0000000000111111111122222222223333333333444444444455555555556666 | ||
179 | * 0123456789012345678901234567890123456789012345678901234567890123 | ||
180 | * | ||
181 | * I Segment-Invalid Bit: Segment is not available for address-translation | ||
182 | * C Common-Segment Bit: Segment is not private (PoP 3-30) | ||
183 | * P Page-Protection Bit: Store access not possible for page | ||
184 | * TT Type 00 | ||
185 | * | ||
186 | * A 64 bit region table entry of S390 has following format: | ||
187 | * | S-table origin | TF TTTL | ||
188 | * 0000000000111111111122222222223333333333444444444455555555556666 | ||
189 | * 0123456789012345678901234567890123456789012345678901234567890123 | ||
190 | * | ||
191 | * I Segment-Invalid Bit: Segment is not available for address-translation | ||
192 | * TT Type 01 | ||
193 | * TF | ||
194 | * TL Table length | ||
195 | * | ||
196 | * The 64 bit regiontable origin of S390 has following format: | ||
197 | * | region table origon | DTTL | ||
198 | * 0000000000111111111122222222223333333333444444444455555555556666 | ||
199 | * 0123456789012345678901234567890123456789012345678901234567890123 | ||
200 | * | ||
201 | * X Space-Switch event: | ||
202 | * G Segment-Invalid Bit: | ||
203 | * P Private-Space Bit: | ||
204 | * S Storage-Alteration: | ||
205 | * R Real space | ||
206 | * TL Table-Length: | ||
207 | * | ||
208 | * A storage key has the following format: | ||
209 | * | ACC |F|R|C|0| | ||
210 | * 0 3 4 5 6 7 | ||
211 | * ACC: access key | ||
212 | * F : fetch protection bit | ||
213 | * R : referenced bit | ||
214 | * C : changed bit | ||
215 | */ | ||
216 | |||
217 | /* Hardware bits in the page table entry */ | ||
218 | #define _PAGE_RO 0x200 /* HW read-only bit */ | ||
219 | #define _PAGE_INVALID 0x400 /* HW invalid bit */ | ||
220 | |||
221 | /* Software bits in the page table entry */ | ||
222 | #define _PAGE_SWT 0x001 /* SW pte type bit t */ | ||
223 | #define _PAGE_SWX 0x002 /* SW pte type bit x */ | ||
224 | #define _PAGE_SPECIAL 0x004 /* SW associated with special page */ | ||
225 | #define __HAVE_ARCH_PTE_SPECIAL | ||
226 | |||
227 | /* Set of bits not changed in pte_modify */ | ||
228 | #define _PAGE_CHG_MASK (PAGE_MASK | _PAGE_SPECIAL) | ||
229 | |||
230 | /* Six different types of pages. */ | ||
231 | #define _PAGE_TYPE_EMPTY 0x400 | ||
232 | #define _PAGE_TYPE_NONE 0x401 | ||
233 | #define _PAGE_TYPE_SWAP 0x403 | ||
234 | #define _PAGE_TYPE_FILE 0x601 /* bit 0x002 is used for offset !! */ | ||
235 | #define _PAGE_TYPE_RO 0x200 | ||
236 | #define _PAGE_TYPE_RW 0x000 | ||
237 | #define _PAGE_TYPE_EX_RO 0x202 | ||
238 | #define _PAGE_TYPE_EX_RW 0x002 | ||
239 | |||
240 | /* | ||
241 | * Only four types for huge pages, using the invalid bit and protection bit | ||
242 | * of a segment table entry. | ||
243 | */ | ||
244 | #define _HPAGE_TYPE_EMPTY 0x020 /* _SEGMENT_ENTRY_INV */ | ||
245 | #define _HPAGE_TYPE_NONE 0x220 | ||
246 | #define _HPAGE_TYPE_RO 0x200 /* _SEGMENT_ENTRY_RO */ | ||
247 | #define _HPAGE_TYPE_RW 0x000 | ||
248 | |||
249 | /* | ||
250 | * PTE type bits are rather complicated. handle_pte_fault uses pte_present, | ||
251 | * pte_none and pte_file to find out the pte type WITHOUT holding the page | ||
252 | * table lock. ptep_clear_flush on the other hand uses ptep_clear_flush to | ||
253 | * invalidate a given pte. ipte sets the hw invalid bit and clears all tlbs | ||
254 | * for the page. The page table entry is set to _PAGE_TYPE_EMPTY afterwards. | ||
255 | * This change is done while holding the lock, but the intermediate step | ||
256 | * of a previously valid pte with the hw invalid bit set can be observed by | ||
257 | * handle_pte_fault. That makes it necessary that all valid pte types with | ||
258 | * the hw invalid bit set must be distinguishable from the four pte types | ||
259 | * empty, none, swap and file. | ||
260 | * | ||
261 | * irxt ipte irxt | ||
262 | * _PAGE_TYPE_EMPTY 1000 -> 1000 | ||
263 | * _PAGE_TYPE_NONE 1001 -> 1001 | ||
264 | * _PAGE_TYPE_SWAP 1011 -> 1011 | ||
265 | * _PAGE_TYPE_FILE 11?1 -> 11?1 | ||
266 | * _PAGE_TYPE_RO 0100 -> 1100 | ||
267 | * _PAGE_TYPE_RW 0000 -> 1000 | ||
268 | * _PAGE_TYPE_EX_RO 0110 -> 1110 | ||
269 | * _PAGE_TYPE_EX_RW 0010 -> 1010 | ||
270 | * | ||
271 | * pte_none is true for bits combinations 1000, 1010, 1100, 1110 | ||
272 | * pte_present is true for bits combinations 0000, 0010, 0100, 0110, 1001 | ||
273 | * pte_file is true for bits combinations 1101, 1111 | ||
274 | * swap pte is 1011 and 0001, 0011, 0101, 0111 are invalid. | ||
275 | */ | ||
276 | |||
277 | /* Page status table bits for virtualization */ | ||
278 | #define RCP_PCL_BIT 55 | ||
279 | #define RCP_HR_BIT 54 | ||
280 | #define RCP_HC_BIT 53 | ||
281 | #define RCP_GR_BIT 50 | ||
282 | #define RCP_GC_BIT 49 | ||
283 | |||
284 | #ifndef __s390x__ | ||
285 | |||
286 | /* Bits in the segment table address-space-control-element */ | ||
287 | #define _ASCE_SPACE_SWITCH 0x80000000UL /* space switch event */ | ||
288 | #define _ASCE_ORIGIN_MASK 0x7ffff000UL /* segment table origin */ | ||
289 | #define _ASCE_PRIVATE_SPACE 0x100 /* private space control */ | ||
290 | #define _ASCE_ALT_EVENT 0x80 /* storage alteration event control */ | ||
291 | #define _ASCE_TABLE_LENGTH 0x7f /* 128 x 64 entries = 8k */ | ||
292 | |||
293 | /* Bits in the segment table entry */ | ||
294 | #define _SEGMENT_ENTRY_ORIGIN 0x7fffffc0UL /* page table origin */ | ||
295 | #define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */ | ||
296 | #define _SEGMENT_ENTRY_COMMON 0x10 /* common segment bit */ | ||
297 | #define _SEGMENT_ENTRY_PTL 0x0f /* page table length */ | ||
298 | |||
299 | #define _SEGMENT_ENTRY (_SEGMENT_ENTRY_PTL) | ||
300 | #define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INV) | ||
301 | |||
302 | #else /* __s390x__ */ | ||
303 | |||
304 | /* Bits in the segment/region table address-space-control-element */ | ||
305 | #define _ASCE_ORIGIN ~0xfffUL/* segment table origin */ | ||
306 | #define _ASCE_PRIVATE_SPACE 0x100 /* private space control */ | ||
307 | #define _ASCE_ALT_EVENT 0x80 /* storage alteration event control */ | ||
308 | #define _ASCE_SPACE_SWITCH 0x40 /* space switch event */ | ||
309 | #define _ASCE_REAL_SPACE 0x20 /* real space control */ | ||
310 | #define _ASCE_TYPE_MASK 0x0c /* asce table type mask */ | ||
311 | #define _ASCE_TYPE_REGION1 0x0c /* region first table type */ | ||
312 | #define _ASCE_TYPE_REGION2 0x08 /* region second table type */ | ||
313 | #define _ASCE_TYPE_REGION3 0x04 /* region third table type */ | ||
314 | #define _ASCE_TYPE_SEGMENT 0x00 /* segment table type */ | ||
315 | #define _ASCE_TABLE_LENGTH 0x03 /* region table length */ | ||
316 | |||
317 | /* Bits in the region table entry */ | ||
318 | #define _REGION_ENTRY_ORIGIN ~0xfffUL/* region/segment table origin */ | ||
319 | #define _REGION_ENTRY_INV 0x20 /* invalid region table entry */ | ||
320 | #define _REGION_ENTRY_TYPE_MASK 0x0c /* region/segment table type mask */ | ||
321 | #define _REGION_ENTRY_TYPE_R1 0x0c /* region first table type */ | ||
322 | #define _REGION_ENTRY_TYPE_R2 0x08 /* region second table type */ | ||
323 | #define _REGION_ENTRY_TYPE_R3 0x04 /* region third table type */ | ||
324 | #define _REGION_ENTRY_LENGTH 0x03 /* region third length */ | ||
325 | |||
326 | #define _REGION1_ENTRY (_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_LENGTH) | ||
327 | #define _REGION1_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R1 | _REGION_ENTRY_INV) | ||
328 | #define _REGION2_ENTRY (_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_LENGTH) | ||
329 | #define _REGION2_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R2 | _REGION_ENTRY_INV) | ||
330 | #define _REGION3_ENTRY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_LENGTH) | ||
331 | #define _REGION3_ENTRY_EMPTY (_REGION_ENTRY_TYPE_R3 | _REGION_ENTRY_INV) | ||
332 | |||
333 | /* Bits in the segment table entry */ | ||
334 | #define _SEGMENT_ENTRY_ORIGIN ~0x7ffUL/* segment table origin */ | ||
335 | #define _SEGMENT_ENTRY_RO 0x200 /* page protection bit */ | ||
336 | #define _SEGMENT_ENTRY_INV 0x20 /* invalid segment table entry */ | ||
337 | |||
338 | #define _SEGMENT_ENTRY (0) | ||
339 | #define _SEGMENT_ENTRY_EMPTY (_SEGMENT_ENTRY_INV) | ||
340 | |||
341 | #define _SEGMENT_ENTRY_LARGE 0x400 /* STE-format control, large page */ | ||
342 | #define _SEGMENT_ENTRY_CO 0x100 /* change-recording override */ | ||
343 | |||
344 | #endif /* __s390x__ */ | ||
345 | |||
346 | /* | ||
347 | * A user page table pointer has the space-switch-event bit, the | ||
348 | * private-space-control bit and the storage-alteration-event-control | ||
349 | * bit set. A kernel page table pointer doesn't need them. | ||
350 | */ | ||
351 | #define _ASCE_USER_BITS (_ASCE_SPACE_SWITCH | _ASCE_PRIVATE_SPACE | \ | ||
352 | _ASCE_ALT_EVENT) | ||
353 | |||
354 | /* Bits int the storage key */ | ||
355 | #define _PAGE_CHANGED 0x02 /* HW changed bit */ | ||
356 | #define _PAGE_REFERENCED 0x04 /* HW referenced bit */ | ||
357 | |||
358 | /* | ||
359 | * Page protection definitions. | ||
360 | */ | ||
361 | #define PAGE_NONE __pgprot(_PAGE_TYPE_NONE) | ||
362 | #define PAGE_RO __pgprot(_PAGE_TYPE_RO) | ||
363 | #define PAGE_RW __pgprot(_PAGE_TYPE_RW) | ||
364 | #define PAGE_EX_RO __pgprot(_PAGE_TYPE_EX_RO) | ||
365 | #define PAGE_EX_RW __pgprot(_PAGE_TYPE_EX_RW) | ||
366 | |||
367 | #define PAGE_KERNEL PAGE_RW | ||
368 | #define PAGE_COPY PAGE_RO | ||
369 | |||
370 | /* | ||
371 | * Dependent on the EXEC_PROTECT option s390 can do execute protection. | ||
372 | * Write permission always implies read permission. In theory with a | ||
373 | * primary/secondary page table execute only can be implemented but | ||
374 | * it would cost an additional bit in the pte to distinguish all the | ||
375 | * different pte types. To avoid that execute permission currently | ||
376 | * implies read permission as well. | ||
377 | */ | ||
378 | /*xwr*/ | ||
379 | #define __P000 PAGE_NONE | ||
380 | #define __P001 PAGE_RO | ||
381 | #define __P010 PAGE_RO | ||
382 | #define __P011 PAGE_RO | ||
383 | #define __P100 PAGE_EX_RO | ||
384 | #define __P101 PAGE_EX_RO | ||
385 | #define __P110 PAGE_EX_RO | ||
386 | #define __P111 PAGE_EX_RO | ||
387 | |||
388 | #define __S000 PAGE_NONE | ||
389 | #define __S001 PAGE_RO | ||
390 | #define __S010 PAGE_RW | ||
391 | #define __S011 PAGE_RW | ||
392 | #define __S100 PAGE_EX_RO | ||
393 | #define __S101 PAGE_EX_RO | ||
394 | #define __S110 PAGE_EX_RW | ||
395 | #define __S111 PAGE_EX_RW | ||
396 | |||
397 | #ifndef __s390x__ | ||
398 | # define PxD_SHADOW_SHIFT 1 | ||
399 | #else /* __s390x__ */ | ||
400 | # define PxD_SHADOW_SHIFT 2 | ||
401 | #endif /* __s390x__ */ | ||
402 | |||
403 | static inline void *get_shadow_table(void *table) | ||
404 | { | ||
405 | unsigned long addr, offset; | ||
406 | struct page *page; | ||
407 | |||
408 | addr = (unsigned long) table; | ||
409 | offset = addr & ((PAGE_SIZE << PxD_SHADOW_SHIFT) - 1); | ||
410 | page = virt_to_page((void *)(addr ^ offset)); | ||
411 | return (void *)(addr_t)(page->index ? (page->index | offset) : 0UL); | ||
412 | } | ||
413 | |||
414 | /* | ||
415 | * Certain architectures need to do special things when PTEs | ||
416 | * within a page table are directly modified. Thus, the following | ||
417 | * hook is made available. | ||
418 | */ | ||
419 | static inline void set_pte_at(struct mm_struct *mm, unsigned long addr, | ||
420 | pte_t *ptep, pte_t entry) | ||
421 | { | ||
422 | *ptep = entry; | ||
423 | if (mm->context.noexec) { | ||
424 | if (!(pte_val(entry) & _PAGE_INVALID) && | ||
425 | (pte_val(entry) & _PAGE_SWX)) | ||
426 | pte_val(entry) |= _PAGE_RO; | ||
427 | else | ||
428 | pte_val(entry) = _PAGE_TYPE_EMPTY; | ||
429 | ptep[PTRS_PER_PTE] = entry; | ||
430 | } | ||
431 | } | ||
432 | |||
433 | /* | ||
434 | * pgd/pmd/pte query functions | ||
435 | */ | ||
436 | #ifndef __s390x__ | ||
437 | |||
438 | static inline int pgd_present(pgd_t pgd) { return 1; } | ||
439 | static inline int pgd_none(pgd_t pgd) { return 0; } | ||
440 | static inline int pgd_bad(pgd_t pgd) { return 0; } | ||
441 | |||
442 | static inline int pud_present(pud_t pud) { return 1; } | ||
443 | static inline int pud_none(pud_t pud) { return 0; } | ||
444 | static inline int pud_bad(pud_t pud) { return 0; } | ||
445 | |||
446 | #else /* __s390x__ */ | ||
447 | |||
448 | static inline int pgd_present(pgd_t pgd) | ||
449 | { | ||
450 | if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2) | ||
451 | return 1; | ||
452 | return (pgd_val(pgd) & _REGION_ENTRY_ORIGIN) != 0UL; | ||
453 | } | ||
454 | |||
455 | static inline int pgd_none(pgd_t pgd) | ||
456 | { | ||
457 | if ((pgd_val(pgd) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R2) | ||
458 | return 0; | ||
459 | return (pgd_val(pgd) & _REGION_ENTRY_INV) != 0UL; | ||
460 | } | ||
461 | |||
462 | static inline int pgd_bad(pgd_t pgd) | ||
463 | { | ||
464 | /* | ||
465 | * With dynamic page table levels the pgd can be a region table | ||
466 | * entry or a segment table entry. Check for the bit that are | ||
467 | * invalid for either table entry. | ||
468 | */ | ||
469 | unsigned long mask = | ||
470 | ~_SEGMENT_ENTRY_ORIGIN & ~_REGION_ENTRY_INV & | ||
471 | ~_REGION_ENTRY_TYPE_MASK & ~_REGION_ENTRY_LENGTH; | ||
472 | return (pgd_val(pgd) & mask) != 0; | ||
473 | } | ||
474 | |||
475 | static inline int pud_present(pud_t pud) | ||
476 | { | ||
477 | if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R3) | ||
478 | return 1; | ||
479 | return (pud_val(pud) & _REGION_ENTRY_ORIGIN) != 0UL; | ||
480 | } | ||
481 | |||
482 | static inline int pud_none(pud_t pud) | ||
483 | { | ||
484 | if ((pud_val(pud) & _REGION_ENTRY_TYPE_MASK) < _REGION_ENTRY_TYPE_R3) | ||
485 | return 0; | ||
486 | return (pud_val(pud) & _REGION_ENTRY_INV) != 0UL; | ||
487 | } | ||
488 | |||
489 | static inline int pud_bad(pud_t pud) | ||
490 | { | ||
491 | /* | ||
492 | * With dynamic page table levels the pud can be a region table | ||
493 | * entry or a segment table entry. Check for the bit that are | ||
494 | * invalid for either table entry. | ||
495 | */ | ||
496 | unsigned long mask = | ||
497 | ~_SEGMENT_ENTRY_ORIGIN & ~_REGION_ENTRY_INV & | ||
498 | ~_REGION_ENTRY_TYPE_MASK & ~_REGION_ENTRY_LENGTH; | ||
499 | return (pud_val(pud) & mask) != 0; | ||
500 | } | ||
501 | |||
502 | #endif /* __s390x__ */ | ||
503 | |||
504 | static inline int pmd_present(pmd_t pmd) | ||
505 | { | ||
506 | return (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) != 0UL; | ||
507 | } | ||
508 | |||
509 | static inline int pmd_none(pmd_t pmd) | ||
510 | { | ||
511 | return (pmd_val(pmd) & _SEGMENT_ENTRY_INV) != 0UL; | ||
512 | } | ||
513 | |||
514 | static inline int pmd_bad(pmd_t pmd) | ||
515 | { | ||
516 | unsigned long mask = ~_SEGMENT_ENTRY_ORIGIN & ~_SEGMENT_ENTRY_INV; | ||
517 | return (pmd_val(pmd) & mask) != _SEGMENT_ENTRY; | ||
518 | } | ||
519 | |||
520 | static inline int pte_none(pte_t pte) | ||
521 | { | ||
522 | return (pte_val(pte) & _PAGE_INVALID) && !(pte_val(pte) & _PAGE_SWT); | ||
523 | } | ||
524 | |||
525 | static inline int pte_present(pte_t pte) | ||
526 | { | ||
527 | unsigned long mask = _PAGE_RO | _PAGE_INVALID | _PAGE_SWT | _PAGE_SWX; | ||
528 | return (pte_val(pte) & mask) == _PAGE_TYPE_NONE || | ||
529 | (!(pte_val(pte) & _PAGE_INVALID) && | ||
530 | !(pte_val(pte) & _PAGE_SWT)); | ||
531 | } | ||
532 | |||
533 | static inline int pte_file(pte_t pte) | ||
534 | { | ||
535 | unsigned long mask = _PAGE_RO | _PAGE_INVALID | _PAGE_SWT; | ||
536 | return (pte_val(pte) & mask) == _PAGE_TYPE_FILE; | ||
537 | } | ||
538 | |||
539 | static inline int pte_special(pte_t pte) | ||
540 | { | ||
541 | return (pte_val(pte) & _PAGE_SPECIAL); | ||
542 | } | ||
543 | |||
544 | #define __HAVE_ARCH_PTE_SAME | ||
545 | #define pte_same(a,b) (pte_val(a) == pte_val(b)) | ||
546 | |||
547 | static inline void rcp_lock(pte_t *ptep) | ||
548 | { | ||
549 | #ifdef CONFIG_PGSTE | ||
550 | unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE); | ||
551 | preempt_disable(); | ||
552 | while (test_and_set_bit(RCP_PCL_BIT, pgste)) | ||
553 | ; | ||
554 | #endif | ||
555 | } | ||
556 | |||
557 | static inline void rcp_unlock(pte_t *ptep) | ||
558 | { | ||
559 | #ifdef CONFIG_PGSTE | ||
560 | unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE); | ||
561 | clear_bit(RCP_PCL_BIT, pgste); | ||
562 | preempt_enable(); | ||
563 | #endif | ||
564 | } | ||
565 | |||
566 | /* forward declaration for SetPageUptodate in page-flags.h*/ | ||
567 | static inline void page_clear_dirty(struct page *page); | ||
568 | #include <linux/page-flags.h> | ||
569 | |||
570 | static inline void ptep_rcp_copy(pte_t *ptep) | ||
571 | { | ||
572 | #ifdef CONFIG_PGSTE | ||
573 | struct page *page = virt_to_page(pte_val(*ptep)); | ||
574 | unsigned int skey; | ||
575 | unsigned long *pgste = (unsigned long *) (ptep + PTRS_PER_PTE); | ||
576 | |||
577 | skey = page_get_storage_key(page_to_phys(page)); | ||
578 | if (skey & _PAGE_CHANGED) | ||
579 | set_bit_simple(RCP_GC_BIT, pgste); | ||
580 | if (skey & _PAGE_REFERENCED) | ||
581 | set_bit_simple(RCP_GR_BIT, pgste); | ||
582 | if (test_and_clear_bit_simple(RCP_HC_BIT, pgste)) | ||
583 | SetPageDirty(page); | ||
584 | if (test_and_clear_bit_simple(RCP_HR_BIT, pgste)) | ||
585 | SetPageReferenced(page); | ||
586 | #endif | ||
587 | } | ||
588 | |||
589 | /* | ||
590 | * query functions pte_write/pte_dirty/pte_young only work if | ||
591 | * pte_present() is true. Undefined behaviour if not.. | ||
592 | */ | ||
593 | static inline int pte_write(pte_t pte) | ||
594 | { | ||
595 | return (pte_val(pte) & _PAGE_RO) == 0; | ||
596 | } | ||
597 | |||
598 | static inline int pte_dirty(pte_t pte) | ||
599 | { | ||
600 | /* A pte is neither clean nor dirty on s/390. The dirty bit | ||
601 | * is in the storage key. See page_test_and_clear_dirty for | ||
602 | * details. | ||
603 | */ | ||
604 | return 0; | ||
605 | } | ||
606 | |||
607 | static inline int pte_young(pte_t pte) | ||
608 | { | ||
609 | /* A pte is neither young nor old on s/390. The young bit | ||
610 | * is in the storage key. See page_test_and_clear_young for | ||
611 | * details. | ||
612 | */ | ||
613 | return 0; | ||
614 | } | ||
615 | |||
616 | /* | ||
617 | * pgd/pmd/pte modification functions | ||
618 | */ | ||
619 | |||
620 | #ifndef __s390x__ | ||
621 | |||
622 | #define pgd_clear(pgd) do { } while (0) | ||
623 | #define pud_clear(pud) do { } while (0) | ||
624 | |||
625 | #else /* __s390x__ */ | ||
626 | |||
627 | static inline void pgd_clear_kernel(pgd_t * pgd) | ||
628 | { | ||
629 | if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2) | ||
630 | pgd_val(*pgd) = _REGION2_ENTRY_EMPTY; | ||
631 | } | ||
632 | |||
633 | static inline void pgd_clear(pgd_t * pgd) | ||
634 | { | ||
635 | pgd_t *shadow = get_shadow_table(pgd); | ||
636 | |||
637 | pgd_clear_kernel(pgd); | ||
638 | if (shadow) | ||
639 | pgd_clear_kernel(shadow); | ||
640 | } | ||
641 | |||
642 | static inline void pud_clear_kernel(pud_t *pud) | ||
643 | { | ||
644 | if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) | ||
645 | pud_val(*pud) = _REGION3_ENTRY_EMPTY; | ||
646 | } | ||
647 | |||
648 | static inline void pud_clear(pud_t *pud) | ||
649 | { | ||
650 | pud_t *shadow = get_shadow_table(pud); | ||
651 | |||
652 | pud_clear_kernel(pud); | ||
653 | if (shadow) | ||
654 | pud_clear_kernel(shadow); | ||
655 | } | ||
656 | |||
657 | #endif /* __s390x__ */ | ||
658 | |||
659 | static inline void pmd_clear_kernel(pmd_t * pmdp) | ||
660 | { | ||
661 | pmd_val(*pmdp) = _SEGMENT_ENTRY_EMPTY; | ||
662 | } | ||
663 | |||
664 | static inline void pmd_clear(pmd_t *pmd) | ||
665 | { | ||
666 | pmd_t *shadow = get_shadow_table(pmd); | ||
667 | |||
668 | pmd_clear_kernel(pmd); | ||
669 | if (shadow) | ||
670 | pmd_clear_kernel(shadow); | ||
671 | } | ||
672 | |||
673 | static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | ||
674 | { | ||
675 | if (mm->context.pgstes) | ||
676 | ptep_rcp_copy(ptep); | ||
677 | pte_val(*ptep) = _PAGE_TYPE_EMPTY; | ||
678 | if (mm->context.noexec) | ||
679 | pte_val(ptep[PTRS_PER_PTE]) = _PAGE_TYPE_EMPTY; | ||
680 | } | ||
681 | |||
682 | /* | ||
683 | * The following pte modification functions only work if | ||
684 | * pte_present() is true. Undefined behaviour if not.. | ||
685 | */ | ||
686 | static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | ||
687 | { | ||
688 | pte_val(pte) &= _PAGE_CHG_MASK; | ||
689 | pte_val(pte) |= pgprot_val(newprot); | ||
690 | return pte; | ||
691 | } | ||
692 | |||
693 | static inline pte_t pte_wrprotect(pte_t pte) | ||
694 | { | ||
695 | /* Do not clobber _PAGE_TYPE_NONE pages! */ | ||
696 | if (!(pte_val(pte) & _PAGE_INVALID)) | ||
697 | pte_val(pte) |= _PAGE_RO; | ||
698 | return pte; | ||
699 | } | ||
700 | |||
701 | static inline pte_t pte_mkwrite(pte_t pte) | ||
702 | { | ||
703 | pte_val(pte) &= ~_PAGE_RO; | ||
704 | return pte; | ||
705 | } | ||
706 | |||
707 | static inline pte_t pte_mkclean(pte_t pte) | ||
708 | { | ||
709 | /* The only user of pte_mkclean is the fork() code. | ||
710 | We must *not* clear the *physical* page dirty bit | ||
711 | just because fork() wants to clear the dirty bit in | ||
712 | *one* of the page's mappings. So we just do nothing. */ | ||
713 | return pte; | ||
714 | } | ||
715 | |||
716 | static inline pte_t pte_mkdirty(pte_t pte) | ||
717 | { | ||
718 | /* We do not explicitly set the dirty bit because the | ||
719 | * sske instruction is slow. It is faster to let the | ||
720 | * next instruction set the dirty bit. | ||
721 | */ | ||
722 | return pte; | ||
723 | } | ||
724 | |||
725 | static inline pte_t pte_mkold(pte_t pte) | ||
726 | { | ||
727 | /* S/390 doesn't keep its dirty/referenced bit in the pte. | ||
728 | * There is no point in clearing the real referenced bit. | ||
729 | */ | ||
730 | return pte; | ||
731 | } | ||
732 | |||
733 | static inline pte_t pte_mkyoung(pte_t pte) | ||
734 | { | ||
735 | /* S/390 doesn't keep its dirty/referenced bit in the pte. | ||
736 | * There is no point in setting the real referenced bit. | ||
737 | */ | ||
738 | return pte; | ||
739 | } | ||
740 | |||
741 | static inline pte_t pte_mkspecial(pte_t pte) | ||
742 | { | ||
743 | pte_val(pte) |= _PAGE_SPECIAL; | ||
744 | return pte; | ||
745 | } | ||
746 | |||
747 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG | ||
748 | static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, | ||
749 | unsigned long addr, pte_t *ptep) | ||
750 | { | ||
751 | #ifdef CONFIG_PGSTE | ||
752 | unsigned long physpage; | ||
753 | int young; | ||
754 | unsigned long *pgste; | ||
755 | |||
756 | if (!vma->vm_mm->context.pgstes) | ||
757 | return 0; | ||
758 | physpage = pte_val(*ptep) & PAGE_MASK; | ||
759 | pgste = (unsigned long *) (ptep + PTRS_PER_PTE); | ||
760 | |||
761 | young = ((page_get_storage_key(physpage) & _PAGE_REFERENCED) != 0); | ||
762 | rcp_lock(ptep); | ||
763 | if (young) | ||
764 | set_bit_simple(RCP_GR_BIT, pgste); | ||
765 | young |= test_and_clear_bit_simple(RCP_HR_BIT, pgste); | ||
766 | rcp_unlock(ptep); | ||
767 | return young; | ||
768 | #endif | ||
769 | return 0; | ||
770 | } | ||
771 | |||
772 | #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH | ||
773 | static inline int ptep_clear_flush_young(struct vm_area_struct *vma, | ||
774 | unsigned long address, pte_t *ptep) | ||
775 | { | ||
776 | /* No need to flush TLB | ||
777 | * On s390 reference bits are in storage key and never in TLB | ||
778 | * With virtualization we handle the reference bit, without we | ||
779 | * we can simply return */ | ||
780 | #ifdef CONFIG_PGSTE | ||
781 | return ptep_test_and_clear_young(vma, address, ptep); | ||
782 | #endif | ||
783 | return 0; | ||
784 | } | ||
785 | |||
786 | static inline void __ptep_ipte(unsigned long address, pte_t *ptep) | ||
787 | { | ||
788 | if (!(pte_val(*ptep) & _PAGE_INVALID)) { | ||
789 | #ifndef __s390x__ | ||
790 | /* pto must point to the start of the segment table */ | ||
791 | pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00); | ||
792 | #else | ||
793 | /* ipte in zarch mode can do the math */ | ||
794 | pte_t *pto = ptep; | ||
795 | #endif | ||
796 | asm volatile( | ||
797 | " ipte %2,%3" | ||
798 | : "=m" (*ptep) : "m" (*ptep), | ||
799 | "a" (pto), "a" (address)); | ||
800 | } | ||
801 | } | ||
802 | |||
803 | static inline void ptep_invalidate(struct mm_struct *mm, | ||
804 | unsigned long address, pte_t *ptep) | ||
805 | { | ||
806 | if (mm->context.pgstes) { | ||
807 | rcp_lock(ptep); | ||
808 | __ptep_ipte(address, ptep); | ||
809 | ptep_rcp_copy(ptep); | ||
810 | pte_val(*ptep) = _PAGE_TYPE_EMPTY; | ||
811 | rcp_unlock(ptep); | ||
812 | return; | ||
813 | } | ||
814 | __ptep_ipte(address, ptep); | ||
815 | pte_val(*ptep) = _PAGE_TYPE_EMPTY; | ||
816 | if (mm->context.noexec) { | ||
817 | __ptep_ipte(address, ptep + PTRS_PER_PTE); | ||
818 | pte_val(*(ptep + PTRS_PER_PTE)) = _PAGE_TYPE_EMPTY; | ||
819 | } | ||
820 | } | ||
821 | |||
822 | /* | ||
823 | * This is hard to understand. ptep_get_and_clear and ptep_clear_flush | ||
824 | * both clear the TLB for the unmapped pte. The reason is that | ||
825 | * ptep_get_and_clear is used in common code (e.g. change_pte_range) | ||
826 | * to modify an active pte. The sequence is | ||
827 | * 1) ptep_get_and_clear | ||
828 | * 2) set_pte_at | ||
829 | * 3) flush_tlb_range | ||
830 | * On s390 the tlb needs to get flushed with the modification of the pte | ||
831 | * if the pte is active. The only way how this can be implemented is to | ||
832 | * have ptep_get_and_clear do the tlb flush. In exchange flush_tlb_range | ||
833 | * is a nop. | ||
834 | */ | ||
835 | #define __HAVE_ARCH_PTEP_GET_AND_CLEAR | ||
836 | #define ptep_get_and_clear(__mm, __address, __ptep) \ | ||
837 | ({ \ | ||
838 | pte_t __pte = *(__ptep); \ | ||
839 | if (atomic_read(&(__mm)->mm_users) > 1 || \ | ||
840 | (__mm) != current->active_mm) \ | ||
841 | ptep_invalidate(__mm, __address, __ptep); \ | ||
842 | else \ | ||
843 | pte_clear((__mm), (__address), (__ptep)); \ | ||
844 | __pte; \ | ||
845 | }) | ||
846 | |||
847 | #define __HAVE_ARCH_PTEP_CLEAR_FLUSH | ||
848 | static inline pte_t ptep_clear_flush(struct vm_area_struct *vma, | ||
849 | unsigned long address, pte_t *ptep) | ||
850 | { | ||
851 | pte_t pte = *ptep; | ||
852 | ptep_invalidate(vma->vm_mm, address, ptep); | ||
853 | return pte; | ||
854 | } | ||
855 | |||
856 | /* | ||
857 | * The batched pte unmap code uses ptep_get_and_clear_full to clear the | ||
858 | * ptes. Here an optimization is possible. tlb_gather_mmu flushes all | ||
859 | * tlbs of an mm if it can guarantee that the ptes of the mm_struct | ||
860 | * cannot be accessed while the batched unmap is running. In this case | ||
861 | * full==1 and a simple pte_clear is enough. See tlb.h. | ||
862 | */ | ||
863 | #define __HAVE_ARCH_PTEP_GET_AND_CLEAR_FULL | ||
864 | static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, | ||
865 | unsigned long addr, | ||
866 | pte_t *ptep, int full) | ||
867 | { | ||
868 | pte_t pte = *ptep; | ||
869 | |||
870 | if (full) | ||
871 | pte_clear(mm, addr, ptep); | ||
872 | else | ||
873 | ptep_invalidate(mm, addr, ptep); | ||
874 | return pte; | ||
875 | } | ||
876 | |||
877 | #define __HAVE_ARCH_PTEP_SET_WRPROTECT | ||
878 | #define ptep_set_wrprotect(__mm, __addr, __ptep) \ | ||
879 | ({ \ | ||
880 | pte_t __pte = *(__ptep); \ | ||
881 | if (pte_write(__pte)) { \ | ||
882 | if (atomic_read(&(__mm)->mm_users) > 1 || \ | ||
883 | (__mm) != current->active_mm) \ | ||
884 | ptep_invalidate(__mm, __addr, __ptep); \ | ||
885 | set_pte_at(__mm, __addr, __ptep, pte_wrprotect(__pte)); \ | ||
886 | } \ | ||
887 | }) | ||
888 | |||
889 | #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS | ||
890 | #define ptep_set_access_flags(__vma, __addr, __ptep, __entry, __dirty) \ | ||
891 | ({ \ | ||
892 | int __changed = !pte_same(*(__ptep), __entry); \ | ||
893 | if (__changed) { \ | ||
894 | ptep_invalidate((__vma)->vm_mm, __addr, __ptep); \ | ||
895 | set_pte_at((__vma)->vm_mm, __addr, __ptep, __entry); \ | ||
896 | } \ | ||
897 | __changed; \ | ||
898 | }) | ||
899 | |||
900 | /* | ||
901 | * Test and clear dirty bit in storage key. | ||
902 | * We can't clear the changed bit atomically. This is a potential | ||
903 | * race against modification of the referenced bit. This function | ||
904 | * should therefore only be called if it is not mapped in any | ||
905 | * address space. | ||
906 | */ | ||
907 | #define __HAVE_ARCH_PAGE_TEST_DIRTY | ||
908 | static inline int page_test_dirty(struct page *page) | ||
909 | { | ||
910 | return (page_get_storage_key(page_to_phys(page)) & _PAGE_CHANGED) != 0; | ||
911 | } | ||
912 | |||
913 | #define __HAVE_ARCH_PAGE_CLEAR_DIRTY | ||
914 | static inline void page_clear_dirty(struct page *page) | ||
915 | { | ||
916 | page_set_storage_key(page_to_phys(page), PAGE_DEFAULT_KEY); | ||
917 | } | ||
918 | |||
919 | /* | ||
920 | * Test and clear referenced bit in storage key. | ||
921 | */ | ||
922 | #define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG | ||
923 | static inline int page_test_and_clear_young(struct page *page) | ||
924 | { | ||
925 | unsigned long physpage = page_to_phys(page); | ||
926 | int ccode; | ||
927 | |||
928 | asm volatile( | ||
929 | " rrbe 0,%1\n" | ||
930 | " ipm %0\n" | ||
931 | " srl %0,28\n" | ||
932 | : "=d" (ccode) : "a" (physpage) : "cc" ); | ||
933 | return ccode & 2; | ||
934 | } | ||
935 | |||
936 | /* | ||
937 | * Conversion functions: convert a page and protection to a page entry, | ||
938 | * and a page entry and page directory to the page they refer to. | ||
939 | */ | ||
940 | static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) | ||
941 | { | ||
942 | pte_t __pte; | ||
943 | pte_val(__pte) = physpage + pgprot_val(pgprot); | ||
944 | return __pte; | ||
945 | } | ||
946 | |||
947 | static inline pte_t mk_pte(struct page *page, pgprot_t pgprot) | ||
948 | { | ||
949 | unsigned long physpage = page_to_phys(page); | ||
950 | |||
951 | return mk_pte_phys(physpage, pgprot); | ||
952 | } | ||
953 | |||
954 | #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) | ||
955 | #define pud_index(address) (((address) >> PUD_SHIFT) & (PTRS_PER_PUD-1)) | ||
956 | #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) | ||
957 | #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1)) | ||
958 | |||
959 | #define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) | ||
960 | #define pgd_offset_k(address) pgd_offset(&init_mm, address) | ||
961 | |||
962 | #ifndef __s390x__ | ||
963 | |||
964 | #define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) | ||
965 | #define pud_deref(pmd) ({ BUG(); 0UL; }) | ||
966 | #define pgd_deref(pmd) ({ BUG(); 0UL; }) | ||
967 | |||
968 | #define pud_offset(pgd, address) ((pud_t *) pgd) | ||
969 | #define pmd_offset(pud, address) ((pmd_t *) pud + pmd_index(address)) | ||
970 | |||
971 | #else /* __s390x__ */ | ||
972 | |||
973 | #define pmd_deref(pmd) (pmd_val(pmd) & _SEGMENT_ENTRY_ORIGIN) | ||
974 | #define pud_deref(pud) (pud_val(pud) & _REGION_ENTRY_ORIGIN) | ||
975 | #define pgd_deref(pgd) (pgd_val(pgd) & _REGION_ENTRY_ORIGIN) | ||
976 | |||
977 | static inline pud_t *pud_offset(pgd_t *pgd, unsigned long address) | ||
978 | { | ||
979 | pud_t *pud = (pud_t *) pgd; | ||
980 | if ((pgd_val(*pgd) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R2) | ||
981 | pud = (pud_t *) pgd_deref(*pgd); | ||
982 | return pud + pud_index(address); | ||
983 | } | ||
984 | |||
985 | static inline pmd_t *pmd_offset(pud_t *pud, unsigned long address) | ||
986 | { | ||
987 | pmd_t *pmd = (pmd_t *) pud; | ||
988 | if ((pud_val(*pud) & _REGION_ENTRY_TYPE_MASK) == _REGION_ENTRY_TYPE_R3) | ||
989 | pmd = (pmd_t *) pud_deref(*pud); | ||
990 | return pmd + pmd_index(address); | ||
991 | } | ||
992 | |||
993 | #endif /* __s390x__ */ | ||
994 | |||
995 | #define pfn_pte(pfn,pgprot) mk_pte_phys(__pa((pfn) << PAGE_SHIFT),(pgprot)) | ||
996 | #define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT) | ||
997 | #define pte_page(x) pfn_to_page(pte_pfn(x)) | ||
998 | |||
999 | #define pmd_page(pmd) pfn_to_page(pmd_val(pmd) >> PAGE_SHIFT) | ||
1000 | |||
1001 | /* Find an entry in the lowest level page table.. */ | ||
1002 | #define pte_offset(pmd, addr) ((pte_t *) pmd_deref(*(pmd)) + pte_index(addr)) | ||
1003 | #define pte_offset_kernel(pmd, address) pte_offset(pmd,address) | ||
1004 | #define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address) | ||
1005 | #define pte_offset_map_nested(pmd, address) pte_offset_kernel(pmd, address) | ||
1006 | #define pte_unmap(pte) do { } while (0) | ||
1007 | #define pte_unmap_nested(pte) do { } while (0) | ||
1008 | |||
1009 | /* | ||
1010 | * 31 bit swap entry format: | ||
1011 | * A page-table entry has some bits we have to treat in a special way. | ||
1012 | * Bits 0, 20 and bit 23 have to be zero, otherwise an specification | ||
1013 | * exception will occur instead of a page translation exception. The | ||
1014 | * specifiation exception has the bad habit not to store necessary | ||
1015 | * information in the lowcore. | ||
1016 | * Bit 21 and bit 22 are the page invalid bit and the page protection | ||
1017 | * bit. We set both to indicate a swapped page. | ||
1018 | * Bit 30 and 31 are used to distinguish the different page types. For | ||
1019 | * a swapped page these bits need to be zero. | ||
1020 | * This leaves the bits 1-19 and bits 24-29 to store type and offset. | ||
1021 | * We use the 5 bits from 25-29 for the type and the 20 bits from 1-19 | ||
1022 | * plus 24 for the offset. | ||
1023 | * 0| offset |0110|o|type |00| | ||
1024 | * 0 0000000001111111111 2222 2 22222 33 | ||
1025 | * 0 1234567890123456789 0123 4 56789 01 | ||
1026 | * | ||
1027 | * 64 bit swap entry format: | ||
1028 | * A page-table entry has some bits we have to treat in a special way. | ||
1029 | * Bits 52 and bit 55 have to be zero, otherwise an specification | ||
1030 | * exception will occur instead of a page translation exception. The | ||
1031 | * specifiation exception has the bad habit not to store necessary | ||
1032 | * information in the lowcore. | ||
1033 | * Bit 53 and bit 54 are the page invalid bit and the page protection | ||
1034 | * bit. We set both to indicate a swapped page. | ||
1035 | * Bit 62 and 63 are used to distinguish the different page types. For | ||
1036 | * a swapped page these bits need to be zero. | ||
1037 | * This leaves the bits 0-51 and bits 56-61 to store type and offset. | ||
1038 | * We use the 5 bits from 57-61 for the type and the 53 bits from 0-51 | ||
1039 | * plus 56 for the offset. | ||
1040 | * | offset |0110|o|type |00| | ||
1041 | * 0000000000111111111122222222223333333333444444444455 5555 5 55566 66 | ||
1042 | * 0123456789012345678901234567890123456789012345678901 2345 6 78901 23 | ||
1043 | */ | ||
1044 | #ifndef __s390x__ | ||
1045 | #define __SWP_OFFSET_MASK (~0UL >> 12) | ||
1046 | #else | ||
1047 | #define __SWP_OFFSET_MASK (~0UL >> 11) | ||
1048 | #endif | ||
1049 | static inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) | ||
1050 | { | ||
1051 | pte_t pte; | ||
1052 | offset &= __SWP_OFFSET_MASK; | ||
1053 | pte_val(pte) = _PAGE_TYPE_SWAP | ((type & 0x1f) << 2) | | ||
1054 | ((offset & 1UL) << 7) | ((offset & ~1UL) << 11); | ||
1055 | return pte; | ||
1056 | } | ||
1057 | |||
1058 | #define __swp_type(entry) (((entry).val >> 2) & 0x1f) | ||
1059 | #define __swp_offset(entry) (((entry).val >> 11) | (((entry).val >> 7) & 1)) | ||
1060 | #define __swp_entry(type,offset) ((swp_entry_t) { pte_val(mk_swap_pte((type),(offset))) }) | ||
1061 | |||
1062 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) | ||
1063 | #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) | ||
1064 | |||
1065 | #ifndef __s390x__ | ||
1066 | # define PTE_FILE_MAX_BITS 26 | ||
1067 | #else /* __s390x__ */ | ||
1068 | # define PTE_FILE_MAX_BITS 59 | ||
1069 | #endif /* __s390x__ */ | ||
1070 | |||
1071 | #define pte_to_pgoff(__pte) \ | ||
1072 | ((((__pte).pte >> 12) << 7) + (((__pte).pte >> 1) & 0x7f)) | ||
1073 | |||
1074 | #define pgoff_to_pte(__off) \ | ||
1075 | ((pte_t) { ((((__off) & 0x7f) << 1) + (((__off) >> 7) << 12)) \ | ||
1076 | | _PAGE_TYPE_FILE }) | ||
1077 | |||
1078 | #endif /* !__ASSEMBLY__ */ | ||
1079 | |||
1080 | #define kern_addr_valid(addr) (1) | ||
1081 | |||
1082 | extern int vmem_add_mapping(unsigned long start, unsigned long size); | ||
1083 | extern int vmem_remove_mapping(unsigned long start, unsigned long size); | ||
1084 | extern int s390_enable_sie(void); | ||
1085 | |||
1086 | /* | ||
1087 | * No page table caches to initialise | ||
1088 | */ | ||
1089 | #define pgtable_cache_init() do { } while (0) | ||
1090 | |||
1091 | #include <asm-generic/pgtable.h> | ||
1092 | |||
1093 | #endif /* _S390_PAGE_H */ | ||
diff --git a/arch/s390/include/asm/poll.h b/arch/s390/include/asm/poll.h new file mode 100644 index 000000000000..c98509d3149e --- /dev/null +++ b/arch/s390/include/asm/poll.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/poll.h> | |||
diff --git a/arch/s390/include/asm/posix_types.h b/arch/s390/include/asm/posix_types.h new file mode 100644 index 000000000000..397d93fba3a7 --- /dev/null +++ b/arch/s390/include/asm/posix_types.h | |||
@@ -0,0 +1,111 @@ | |||
1 | /* | ||
2 | * include/asm-s390/posix_types.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/posix_types.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef __ARCH_S390_POSIX_TYPES_H | ||
10 | #define __ARCH_S390_POSIX_TYPES_H | ||
11 | |||
12 | /* | ||
13 | * This file is generally used by user-level software, so you need to | ||
14 | * be a little careful about namespace pollution etc. Also, we cannot | ||
15 | * assume GCC is being used. | ||
16 | */ | ||
17 | |||
18 | typedef long __kernel_off_t; | ||
19 | typedef int __kernel_pid_t; | ||
20 | typedef unsigned long __kernel_size_t; | ||
21 | typedef long __kernel_time_t; | ||
22 | typedef long __kernel_suseconds_t; | ||
23 | typedef long __kernel_clock_t; | ||
24 | typedef int __kernel_timer_t; | ||
25 | typedef int __kernel_clockid_t; | ||
26 | typedef int __kernel_daddr_t; | ||
27 | typedef char * __kernel_caddr_t; | ||
28 | typedef unsigned short __kernel_uid16_t; | ||
29 | typedef unsigned short __kernel_gid16_t; | ||
30 | |||
31 | #ifdef __GNUC__ | ||
32 | typedef long long __kernel_loff_t; | ||
33 | #endif | ||
34 | |||
35 | #ifndef __s390x__ | ||
36 | |||
37 | typedef unsigned long __kernel_ino_t; | ||
38 | typedef unsigned short __kernel_mode_t; | ||
39 | typedef unsigned short __kernel_nlink_t; | ||
40 | typedef unsigned short __kernel_ipc_pid_t; | ||
41 | typedef unsigned short __kernel_uid_t; | ||
42 | typedef unsigned short __kernel_gid_t; | ||
43 | typedef int __kernel_ssize_t; | ||
44 | typedef int __kernel_ptrdiff_t; | ||
45 | typedef unsigned int __kernel_uid32_t; | ||
46 | typedef unsigned int __kernel_gid32_t; | ||
47 | typedef unsigned short __kernel_old_uid_t; | ||
48 | typedef unsigned short __kernel_old_gid_t; | ||
49 | typedef unsigned short __kernel_old_dev_t; | ||
50 | |||
51 | #else /* __s390x__ */ | ||
52 | |||
53 | typedef unsigned int __kernel_ino_t; | ||
54 | typedef unsigned int __kernel_mode_t; | ||
55 | typedef unsigned int __kernel_nlink_t; | ||
56 | typedef int __kernel_ipc_pid_t; | ||
57 | typedef unsigned int __kernel_uid_t; | ||
58 | typedef unsigned int __kernel_gid_t; | ||
59 | typedef long __kernel_ssize_t; | ||
60 | typedef long __kernel_ptrdiff_t; | ||
61 | typedef unsigned long __kernel_sigset_t; /* at least 32 bits */ | ||
62 | typedef __kernel_uid_t __kernel_old_uid_t; | ||
63 | typedef __kernel_gid_t __kernel_old_gid_t; | ||
64 | typedef __kernel_uid_t __kernel_uid32_t; | ||
65 | typedef __kernel_gid_t __kernel_gid32_t; | ||
66 | typedef unsigned short __kernel_old_dev_t; | ||
67 | |||
68 | #endif /* __s390x__ */ | ||
69 | |||
70 | typedef struct { | ||
71 | #if defined(__KERNEL__) || defined(__USE_ALL) | ||
72 | int val[2]; | ||
73 | #else /* !defined(__KERNEL__) && !defined(__USE_ALL)*/ | ||
74 | int __val[2]; | ||
75 | #endif /* !defined(__KERNEL__) && !defined(__USE_ALL)*/ | ||
76 | } __kernel_fsid_t; | ||
77 | |||
78 | |||
79 | #ifdef __KERNEL__ | ||
80 | |||
81 | #undef __FD_SET | ||
82 | static inline void __FD_SET(unsigned long fd, __kernel_fd_set *fdsetp) | ||
83 | { | ||
84 | unsigned long _tmp = fd / __NFDBITS; | ||
85 | unsigned long _rem = fd % __NFDBITS; | ||
86 | fdsetp->fds_bits[_tmp] |= (1UL<<_rem); | ||
87 | } | ||
88 | |||
89 | #undef __FD_CLR | ||
90 | static inline void __FD_CLR(unsigned long fd, __kernel_fd_set *fdsetp) | ||
91 | { | ||
92 | unsigned long _tmp = fd / __NFDBITS; | ||
93 | unsigned long _rem = fd % __NFDBITS; | ||
94 | fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem); | ||
95 | } | ||
96 | |||
97 | #undef __FD_ISSET | ||
98 | static inline int __FD_ISSET(unsigned long fd, const __kernel_fd_set *fdsetp) | ||
99 | { | ||
100 | unsigned long _tmp = fd / __NFDBITS; | ||
101 | unsigned long _rem = fd % __NFDBITS; | ||
102 | return (fdsetp->fds_bits[_tmp] & (1UL<<_rem)) != 0; | ||
103 | } | ||
104 | |||
105 | #undef __FD_ZERO | ||
106 | #define __FD_ZERO(fdsetp) \ | ||
107 | ((void) memset ((void *) (fdsetp), 0, sizeof (__kernel_fd_set))) | ||
108 | |||
109 | #endif /* __KERNEL__ */ | ||
110 | |||
111 | #endif | ||
diff --git a/arch/s390/include/asm/processor.h b/arch/s390/include/asm/processor.h new file mode 100644 index 000000000000..4af80af2a88f --- /dev/null +++ b/arch/s390/include/asm/processor.h | |||
@@ -0,0 +1,360 @@ | |||
1 | /* | ||
2 | * include/asm-s390/processor.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Hartmut Penner (hp@de.ibm.com), | ||
7 | * Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
8 | * | ||
9 | * Derived from "include/asm-i386/processor.h" | ||
10 | * Copyright (C) 1994, Linus Torvalds | ||
11 | */ | ||
12 | |||
13 | #ifndef __ASM_S390_PROCESSOR_H | ||
14 | #define __ASM_S390_PROCESSOR_H | ||
15 | |||
16 | #include <asm/ptrace.h> | ||
17 | |||
18 | #ifdef __KERNEL__ | ||
19 | /* | ||
20 | * Default implementation of macro that returns current | ||
21 | * instruction pointer ("program counter"). | ||
22 | */ | ||
23 | #define current_text_addr() ({ void *pc; asm("basr %0,0" : "=a" (pc)); pc; }) | ||
24 | |||
25 | /* | ||
26 | * CPU type and hardware bug flags. Kept separately for each CPU. | ||
27 | * Members of this structure are referenced in head.S, so think twice | ||
28 | * before touching them. [mj] | ||
29 | */ | ||
30 | |||
31 | typedef struct | ||
32 | { | ||
33 | unsigned int version : 8; | ||
34 | unsigned int ident : 24; | ||
35 | unsigned int machine : 16; | ||
36 | unsigned int unused : 16; | ||
37 | } __attribute__ ((packed)) cpuid_t; | ||
38 | |||
39 | static inline void get_cpu_id(cpuid_t *ptr) | ||
40 | { | ||
41 | asm volatile("stidp 0(%1)" : "=m" (*ptr) : "a" (ptr)); | ||
42 | } | ||
43 | |||
44 | struct cpuinfo_S390 | ||
45 | { | ||
46 | cpuid_t cpu_id; | ||
47 | __u16 cpu_addr; | ||
48 | __u16 cpu_nr; | ||
49 | unsigned long loops_per_jiffy; | ||
50 | unsigned long *pgd_quick; | ||
51 | #ifdef __s390x__ | ||
52 | unsigned long *pmd_quick; | ||
53 | #endif /* __s390x__ */ | ||
54 | unsigned long *pte_quick; | ||
55 | unsigned long pgtable_cache_sz; | ||
56 | }; | ||
57 | |||
58 | extern void s390_adjust_jiffies(void); | ||
59 | extern void print_cpu_info(struct cpuinfo_S390 *); | ||
60 | extern int get_cpu_capability(unsigned int *); | ||
61 | |||
62 | /* | ||
63 | * User space process size: 2GB for 31 bit, 4TB for 64 bit. | ||
64 | */ | ||
65 | #ifndef __s390x__ | ||
66 | |||
67 | #define TASK_SIZE (1UL << 31) | ||
68 | #define TASK_UNMAPPED_BASE (1UL << 30) | ||
69 | |||
70 | #else /* __s390x__ */ | ||
71 | |||
72 | #define TASK_SIZE_OF(tsk) (test_tsk_thread_flag(tsk,TIF_31BIT) ? \ | ||
73 | (1UL << 31) : (1UL << 53)) | ||
74 | #define TASK_UNMAPPED_BASE (test_thread_flag(TIF_31BIT) ? \ | ||
75 | (1UL << 30) : (1UL << 41)) | ||
76 | #define TASK_SIZE TASK_SIZE_OF(current) | ||
77 | |||
78 | #endif /* __s390x__ */ | ||
79 | |||
80 | #ifdef __KERNEL__ | ||
81 | |||
82 | #ifndef __s390x__ | ||
83 | #define STACK_TOP (1UL << 31) | ||
84 | #define STACK_TOP_MAX (1UL << 31) | ||
85 | #else /* __s390x__ */ | ||
86 | #define STACK_TOP (1UL << (test_thread_flag(TIF_31BIT) ? 31:42)) | ||
87 | #define STACK_TOP_MAX (1UL << 42) | ||
88 | #endif /* __s390x__ */ | ||
89 | |||
90 | |||
91 | #endif | ||
92 | |||
93 | #define HAVE_ARCH_PICK_MMAP_LAYOUT | ||
94 | |||
95 | typedef struct { | ||
96 | __u32 ar4; | ||
97 | } mm_segment_t; | ||
98 | |||
99 | /* | ||
100 | * Thread structure | ||
101 | */ | ||
102 | struct thread_struct { | ||
103 | s390_fp_regs fp_regs; | ||
104 | unsigned int acrs[NUM_ACRS]; | ||
105 | unsigned long ksp; /* kernel stack pointer */ | ||
106 | mm_segment_t mm_segment; | ||
107 | unsigned long prot_addr; /* address of protection-excep. */ | ||
108 | unsigned int trap_no; | ||
109 | per_struct per_info; | ||
110 | /* Used to give failing instruction back to user for ieee exceptions */ | ||
111 | unsigned long ieee_instruction_pointer; | ||
112 | /* pfault_wait is used to block the process on a pfault event */ | ||
113 | unsigned long pfault_wait; | ||
114 | }; | ||
115 | |||
116 | typedef struct thread_struct thread_struct; | ||
117 | |||
118 | /* | ||
119 | * Stack layout of a C stack frame. | ||
120 | */ | ||
121 | #ifndef __PACK_STACK | ||
122 | struct stack_frame { | ||
123 | unsigned long back_chain; | ||
124 | unsigned long empty1[5]; | ||
125 | unsigned long gprs[10]; | ||
126 | unsigned int empty2[8]; | ||
127 | }; | ||
128 | #else | ||
129 | struct stack_frame { | ||
130 | unsigned long empty1[5]; | ||
131 | unsigned int empty2[8]; | ||
132 | unsigned long gprs[10]; | ||
133 | unsigned long back_chain; | ||
134 | }; | ||
135 | #endif | ||
136 | |||
137 | #define ARCH_MIN_TASKALIGN 8 | ||
138 | |||
139 | #define INIT_THREAD { \ | ||
140 | .ksp = sizeof(init_stack) + (unsigned long) &init_stack, \ | ||
141 | } | ||
142 | |||
143 | /* | ||
144 | * Do necessary setup to start up a new thread. | ||
145 | */ | ||
146 | #define start_thread(regs, new_psw, new_stackp) do { \ | ||
147 | set_fs(USER_DS); \ | ||
148 | regs->psw.mask = psw_user_bits; \ | ||
149 | regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ | ||
150 | regs->gprs[15] = new_stackp; \ | ||
151 | } while (0) | ||
152 | |||
153 | #define start_thread31(regs, new_psw, new_stackp) do { \ | ||
154 | set_fs(USER_DS); \ | ||
155 | regs->psw.mask = psw_user32_bits; \ | ||
156 | regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ | ||
157 | regs->gprs[15] = new_stackp; \ | ||
158 | crst_table_downgrade(current->mm, 1UL << 31); \ | ||
159 | } while (0) | ||
160 | |||
161 | /* Forward declaration, a strange C thing */ | ||
162 | struct task_struct; | ||
163 | struct mm_struct; | ||
164 | struct seq_file; | ||
165 | |||
166 | /* Free all resources held by a thread. */ | ||
167 | extern void release_thread(struct task_struct *); | ||
168 | extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); | ||
169 | |||
170 | /* Prepare to copy thread state - unlazy all lazy status */ | ||
171 | #define prepare_to_copy(tsk) do { } while (0) | ||
172 | |||
173 | /* | ||
174 | * Return saved PC of a blocked thread. | ||
175 | */ | ||
176 | extern unsigned long thread_saved_pc(struct task_struct *t); | ||
177 | |||
178 | /* | ||
179 | * Print register of task into buffer. Used in fs/proc/array.c. | ||
180 | */ | ||
181 | extern void task_show_regs(struct seq_file *m, struct task_struct *task); | ||
182 | |||
183 | extern void show_code(struct pt_regs *regs); | ||
184 | |||
185 | unsigned long get_wchan(struct task_struct *p); | ||
186 | #define task_pt_regs(tsk) ((struct pt_regs *) \ | ||
187 | (task_stack_page(tsk) + THREAD_SIZE) - 1) | ||
188 | #define KSTK_EIP(tsk) (task_pt_regs(tsk)->psw.addr) | ||
189 | #define KSTK_ESP(tsk) (task_pt_regs(tsk)->gprs[15]) | ||
190 | |||
191 | /* | ||
192 | * Give up the time slice of the virtual PU. | ||
193 | */ | ||
194 | static inline void cpu_relax(void) | ||
195 | { | ||
196 | if (MACHINE_HAS_DIAG44) | ||
197 | asm volatile("diag 0,0,68"); | ||
198 | barrier(); | ||
199 | } | ||
200 | |||
201 | static inline void psw_set_key(unsigned int key) | ||
202 | { | ||
203 | asm volatile("spka 0(%0)" : : "d" (key)); | ||
204 | } | ||
205 | |||
206 | /* | ||
207 | * Set PSW to specified value. | ||
208 | */ | ||
209 | static inline void __load_psw(psw_t psw) | ||
210 | { | ||
211 | #ifndef __s390x__ | ||
212 | asm volatile("lpsw 0(%0)" : : "a" (&psw), "m" (psw) : "cc"); | ||
213 | #else | ||
214 | asm volatile("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc"); | ||
215 | #endif | ||
216 | } | ||
217 | |||
218 | /* | ||
219 | * Set PSW mask to specified value, while leaving the | ||
220 | * PSW addr pointing to the next instruction. | ||
221 | */ | ||
222 | |||
223 | static inline void __load_psw_mask (unsigned long mask) | ||
224 | { | ||
225 | unsigned long addr; | ||
226 | psw_t psw; | ||
227 | |||
228 | psw.mask = mask; | ||
229 | |||
230 | #ifndef __s390x__ | ||
231 | asm volatile( | ||
232 | " basr %0,0\n" | ||
233 | "0: ahi %0,1f-0b\n" | ||
234 | " st %0,4(%1)\n" | ||
235 | " lpsw 0(%1)\n" | ||
236 | "1:" | ||
237 | : "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc"); | ||
238 | #else /* __s390x__ */ | ||
239 | asm volatile( | ||
240 | " larl %0,1f\n" | ||
241 | " stg %0,8(%1)\n" | ||
242 | " lpswe 0(%1)\n" | ||
243 | "1:" | ||
244 | : "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc"); | ||
245 | #endif /* __s390x__ */ | ||
246 | } | ||
247 | |||
248 | /* | ||
249 | * Function to stop a processor until an interruption occurred | ||
250 | */ | ||
251 | static inline void enabled_wait(void) | ||
252 | { | ||
253 | __load_psw_mask(PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT | | ||
254 | PSW_MASK_MCHECK | PSW_MASK_WAIT | PSW_DEFAULT_KEY); | ||
255 | } | ||
256 | |||
257 | /* | ||
258 | * Function to drop a processor into disabled wait state | ||
259 | */ | ||
260 | |||
261 | static inline void disabled_wait(unsigned long code) | ||
262 | { | ||
263 | unsigned long ctl_buf; | ||
264 | psw_t dw_psw; | ||
265 | |||
266 | dw_psw.mask = PSW_BASE_BITS | PSW_MASK_WAIT; | ||
267 | dw_psw.addr = code; | ||
268 | /* | ||
269 | * Store status and then load disabled wait psw, | ||
270 | * the processor is dead afterwards | ||
271 | */ | ||
272 | #ifndef __s390x__ | ||
273 | asm volatile( | ||
274 | " stctl 0,0,0(%2)\n" | ||
275 | " ni 0(%2),0xef\n" /* switch off protection */ | ||
276 | " lctl 0,0,0(%2)\n" | ||
277 | " stpt 0xd8\n" /* store timer */ | ||
278 | " stckc 0xe0\n" /* store clock comparator */ | ||
279 | " stpx 0x108\n" /* store prefix register */ | ||
280 | " stam 0,15,0x120\n" /* store access registers */ | ||
281 | " std 0,0x160\n" /* store f0 */ | ||
282 | " std 2,0x168\n" /* store f2 */ | ||
283 | " std 4,0x170\n" /* store f4 */ | ||
284 | " std 6,0x178\n" /* store f6 */ | ||
285 | " stm 0,15,0x180\n" /* store general registers */ | ||
286 | " stctl 0,15,0x1c0\n" /* store control registers */ | ||
287 | " oi 0x1c0,0x10\n" /* fake protection bit */ | ||
288 | " lpsw 0(%1)" | ||
289 | : "=m" (ctl_buf) | ||
290 | : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc"); | ||
291 | #else /* __s390x__ */ | ||
292 | asm volatile( | ||
293 | " stctg 0,0,0(%2)\n" | ||
294 | " ni 4(%2),0xef\n" /* switch off protection */ | ||
295 | " lctlg 0,0,0(%2)\n" | ||
296 | " lghi 1,0x1000\n" | ||
297 | " stpt 0x328(1)\n" /* store timer */ | ||
298 | " stckc 0x330(1)\n" /* store clock comparator */ | ||
299 | " stpx 0x318(1)\n" /* store prefix register */ | ||
300 | " stam 0,15,0x340(1)\n"/* store access registers */ | ||
301 | " stfpc 0x31c(1)\n" /* store fpu control */ | ||
302 | " std 0,0x200(1)\n" /* store f0 */ | ||
303 | " std 1,0x208(1)\n" /* store f1 */ | ||
304 | " std 2,0x210(1)\n" /* store f2 */ | ||
305 | " std 3,0x218(1)\n" /* store f3 */ | ||
306 | " std 4,0x220(1)\n" /* store f4 */ | ||
307 | " std 5,0x228(1)\n" /* store f5 */ | ||
308 | " std 6,0x230(1)\n" /* store f6 */ | ||
309 | " std 7,0x238(1)\n" /* store f7 */ | ||
310 | " std 8,0x240(1)\n" /* store f8 */ | ||
311 | " std 9,0x248(1)\n" /* store f9 */ | ||
312 | " std 10,0x250(1)\n" /* store f10 */ | ||
313 | " std 11,0x258(1)\n" /* store f11 */ | ||
314 | " std 12,0x260(1)\n" /* store f12 */ | ||
315 | " std 13,0x268(1)\n" /* store f13 */ | ||
316 | " std 14,0x270(1)\n" /* store f14 */ | ||
317 | " std 15,0x278(1)\n" /* store f15 */ | ||
318 | " stmg 0,15,0x280(1)\n"/* store general registers */ | ||
319 | " stctg 0,15,0x380(1)\n"/* store control registers */ | ||
320 | " oi 0x384(1),0x10\n"/* fake protection bit */ | ||
321 | " lpswe 0(%1)" | ||
322 | : "=m" (ctl_buf) | ||
323 | : "a" (&dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc", "0"); | ||
324 | #endif /* __s390x__ */ | ||
325 | } | ||
326 | |||
327 | /* | ||
328 | * Basic Machine Check/Program Check Handler. | ||
329 | */ | ||
330 | |||
331 | extern void s390_base_mcck_handler(void); | ||
332 | extern void s390_base_pgm_handler(void); | ||
333 | extern void s390_base_ext_handler(void); | ||
334 | |||
335 | extern void (*s390_base_mcck_handler_fn)(void); | ||
336 | extern void (*s390_base_pgm_handler_fn)(void); | ||
337 | extern void (*s390_base_ext_handler_fn)(void); | ||
338 | |||
339 | #define ARCH_LOW_ADDRESS_LIMIT 0x7fffffffUL | ||
340 | |||
341 | #endif | ||
342 | |||
343 | /* | ||
344 | * Helper macro for exception table entries | ||
345 | */ | ||
346 | #ifndef __s390x__ | ||
347 | #define EX_TABLE(_fault,_target) \ | ||
348 | ".section __ex_table,\"a\"\n" \ | ||
349 | " .align 4\n" \ | ||
350 | " .long " #_fault "," #_target "\n" \ | ||
351 | ".previous\n" | ||
352 | #else | ||
353 | #define EX_TABLE(_fault,_target) \ | ||
354 | ".section __ex_table,\"a\"\n" \ | ||
355 | " .align 8\n" \ | ||
356 | " .quad " #_fault "," #_target "\n" \ | ||
357 | ".previous\n" | ||
358 | #endif | ||
359 | |||
360 | #endif /* __ASM_S390_PROCESSOR_H */ | ||
diff --git a/arch/s390/include/asm/ptrace.h b/arch/s390/include/asm/ptrace.h new file mode 100644 index 000000000000..af2c9ac28a07 --- /dev/null +++ b/arch/s390/include/asm/ptrace.h | |||
@@ -0,0 +1,499 @@ | |||
1 | /* | ||
2 | * include/asm-s390/ptrace.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com) | ||
7 | */ | ||
8 | |||
9 | #ifndef _S390_PTRACE_H | ||
10 | #define _S390_PTRACE_H | ||
11 | |||
12 | /* | ||
13 | * Offsets in the user_regs_struct. They are used for the ptrace | ||
14 | * system call and in entry.S | ||
15 | */ | ||
16 | #ifndef __s390x__ | ||
17 | |||
18 | #define PT_PSWMASK 0x00 | ||
19 | #define PT_PSWADDR 0x04 | ||
20 | #define PT_GPR0 0x08 | ||
21 | #define PT_GPR1 0x0C | ||
22 | #define PT_GPR2 0x10 | ||
23 | #define PT_GPR3 0x14 | ||
24 | #define PT_GPR4 0x18 | ||
25 | #define PT_GPR5 0x1C | ||
26 | #define PT_GPR6 0x20 | ||
27 | #define PT_GPR7 0x24 | ||
28 | #define PT_GPR8 0x28 | ||
29 | #define PT_GPR9 0x2C | ||
30 | #define PT_GPR10 0x30 | ||
31 | #define PT_GPR11 0x34 | ||
32 | #define PT_GPR12 0x38 | ||
33 | #define PT_GPR13 0x3C | ||
34 | #define PT_GPR14 0x40 | ||
35 | #define PT_GPR15 0x44 | ||
36 | #define PT_ACR0 0x48 | ||
37 | #define PT_ACR1 0x4C | ||
38 | #define PT_ACR2 0x50 | ||
39 | #define PT_ACR3 0x54 | ||
40 | #define PT_ACR4 0x58 | ||
41 | #define PT_ACR5 0x5C | ||
42 | #define PT_ACR6 0x60 | ||
43 | #define PT_ACR7 0x64 | ||
44 | #define PT_ACR8 0x68 | ||
45 | #define PT_ACR9 0x6C | ||
46 | #define PT_ACR10 0x70 | ||
47 | #define PT_ACR11 0x74 | ||
48 | #define PT_ACR12 0x78 | ||
49 | #define PT_ACR13 0x7C | ||
50 | #define PT_ACR14 0x80 | ||
51 | #define PT_ACR15 0x84 | ||
52 | #define PT_ORIGGPR2 0x88 | ||
53 | #define PT_FPC 0x90 | ||
54 | /* | ||
55 | * A nasty fact of life that the ptrace api | ||
56 | * only supports passing of longs. | ||
57 | */ | ||
58 | #define PT_FPR0_HI 0x98 | ||
59 | #define PT_FPR0_LO 0x9C | ||
60 | #define PT_FPR1_HI 0xA0 | ||
61 | #define PT_FPR1_LO 0xA4 | ||
62 | #define PT_FPR2_HI 0xA8 | ||
63 | #define PT_FPR2_LO 0xAC | ||
64 | #define PT_FPR3_HI 0xB0 | ||
65 | #define PT_FPR3_LO 0xB4 | ||
66 | #define PT_FPR4_HI 0xB8 | ||
67 | #define PT_FPR4_LO 0xBC | ||
68 | #define PT_FPR5_HI 0xC0 | ||
69 | #define PT_FPR5_LO 0xC4 | ||
70 | #define PT_FPR6_HI 0xC8 | ||
71 | #define PT_FPR6_LO 0xCC | ||
72 | #define PT_FPR7_HI 0xD0 | ||
73 | #define PT_FPR7_LO 0xD4 | ||
74 | #define PT_FPR8_HI 0xD8 | ||
75 | #define PT_FPR8_LO 0XDC | ||
76 | #define PT_FPR9_HI 0xE0 | ||
77 | #define PT_FPR9_LO 0xE4 | ||
78 | #define PT_FPR10_HI 0xE8 | ||
79 | #define PT_FPR10_LO 0xEC | ||
80 | #define PT_FPR11_HI 0xF0 | ||
81 | #define PT_FPR11_LO 0xF4 | ||
82 | #define PT_FPR12_HI 0xF8 | ||
83 | #define PT_FPR12_LO 0xFC | ||
84 | #define PT_FPR13_HI 0x100 | ||
85 | #define PT_FPR13_LO 0x104 | ||
86 | #define PT_FPR14_HI 0x108 | ||
87 | #define PT_FPR14_LO 0x10C | ||
88 | #define PT_FPR15_HI 0x110 | ||
89 | #define PT_FPR15_LO 0x114 | ||
90 | #define PT_CR_9 0x118 | ||
91 | #define PT_CR_10 0x11C | ||
92 | #define PT_CR_11 0x120 | ||
93 | #define PT_IEEE_IP 0x13C | ||
94 | #define PT_LASTOFF PT_IEEE_IP | ||
95 | #define PT_ENDREGS 0x140-1 | ||
96 | |||
97 | #define GPR_SIZE 4 | ||
98 | #define CR_SIZE 4 | ||
99 | |||
100 | #define STACK_FRAME_OVERHEAD 96 /* size of minimum stack frame */ | ||
101 | |||
102 | #else /* __s390x__ */ | ||
103 | |||
104 | #define PT_PSWMASK 0x00 | ||
105 | #define PT_PSWADDR 0x08 | ||
106 | #define PT_GPR0 0x10 | ||
107 | #define PT_GPR1 0x18 | ||
108 | #define PT_GPR2 0x20 | ||
109 | #define PT_GPR3 0x28 | ||
110 | #define PT_GPR4 0x30 | ||
111 | #define PT_GPR5 0x38 | ||
112 | #define PT_GPR6 0x40 | ||
113 | #define PT_GPR7 0x48 | ||
114 | #define PT_GPR8 0x50 | ||
115 | #define PT_GPR9 0x58 | ||
116 | #define PT_GPR10 0x60 | ||
117 | #define PT_GPR11 0x68 | ||
118 | #define PT_GPR12 0x70 | ||
119 | #define PT_GPR13 0x78 | ||
120 | #define PT_GPR14 0x80 | ||
121 | #define PT_GPR15 0x88 | ||
122 | #define PT_ACR0 0x90 | ||
123 | #define PT_ACR1 0x94 | ||
124 | #define PT_ACR2 0x98 | ||
125 | #define PT_ACR3 0x9C | ||
126 | #define PT_ACR4 0xA0 | ||
127 | #define PT_ACR5 0xA4 | ||
128 | #define PT_ACR6 0xA8 | ||
129 | #define PT_ACR7 0xAC | ||
130 | #define PT_ACR8 0xB0 | ||
131 | #define PT_ACR9 0xB4 | ||
132 | #define PT_ACR10 0xB8 | ||
133 | #define PT_ACR11 0xBC | ||
134 | #define PT_ACR12 0xC0 | ||
135 | #define PT_ACR13 0xC4 | ||
136 | #define PT_ACR14 0xC8 | ||
137 | #define PT_ACR15 0xCC | ||
138 | #define PT_ORIGGPR2 0xD0 | ||
139 | #define PT_FPC 0xD8 | ||
140 | #define PT_FPR0 0xE0 | ||
141 | #define PT_FPR1 0xE8 | ||
142 | #define PT_FPR2 0xF0 | ||
143 | #define PT_FPR3 0xF8 | ||
144 | #define PT_FPR4 0x100 | ||
145 | #define PT_FPR5 0x108 | ||
146 | #define PT_FPR6 0x110 | ||
147 | #define PT_FPR7 0x118 | ||
148 | #define PT_FPR8 0x120 | ||
149 | #define PT_FPR9 0x128 | ||
150 | #define PT_FPR10 0x130 | ||
151 | #define PT_FPR11 0x138 | ||
152 | #define PT_FPR12 0x140 | ||
153 | #define PT_FPR13 0x148 | ||
154 | #define PT_FPR14 0x150 | ||
155 | #define PT_FPR15 0x158 | ||
156 | #define PT_CR_9 0x160 | ||
157 | #define PT_CR_10 0x168 | ||
158 | #define PT_CR_11 0x170 | ||
159 | #define PT_IEEE_IP 0x1A8 | ||
160 | #define PT_LASTOFF PT_IEEE_IP | ||
161 | #define PT_ENDREGS 0x1B0-1 | ||
162 | |||
163 | #define GPR_SIZE 8 | ||
164 | #define CR_SIZE 8 | ||
165 | |||
166 | #define STACK_FRAME_OVERHEAD 160 /* size of minimum stack frame */ | ||
167 | |||
168 | #endif /* __s390x__ */ | ||
169 | |||
170 | #define NUM_GPRS 16 | ||
171 | #define NUM_FPRS 16 | ||
172 | #define NUM_CRS 16 | ||
173 | #define NUM_ACRS 16 | ||
174 | |||
175 | #define FPR_SIZE 8 | ||
176 | #define FPC_SIZE 4 | ||
177 | #define FPC_PAD_SIZE 4 /* gcc insists on aligning the fpregs */ | ||
178 | #define ACR_SIZE 4 | ||
179 | |||
180 | |||
181 | #define PTRACE_OLDSETOPTIONS 21 | ||
182 | |||
183 | #ifndef __ASSEMBLY__ | ||
184 | #include <linux/stddef.h> | ||
185 | #include <linux/types.h> | ||
186 | |||
187 | typedef union | ||
188 | { | ||
189 | float f; | ||
190 | double d; | ||
191 | __u64 ui; | ||
192 | struct | ||
193 | { | ||
194 | __u32 hi; | ||
195 | __u32 lo; | ||
196 | } fp; | ||
197 | } freg_t; | ||
198 | |||
199 | typedef struct | ||
200 | { | ||
201 | __u32 fpc; | ||
202 | freg_t fprs[NUM_FPRS]; | ||
203 | } s390_fp_regs; | ||
204 | |||
205 | #define FPC_EXCEPTION_MASK 0xF8000000 | ||
206 | #define FPC_FLAGS_MASK 0x00F80000 | ||
207 | #define FPC_DXC_MASK 0x0000FF00 | ||
208 | #define FPC_RM_MASK 0x00000003 | ||
209 | #define FPC_VALID_MASK 0xF8F8FF03 | ||
210 | |||
211 | /* this typedef defines how a Program Status Word looks like */ | ||
212 | typedef struct | ||
213 | { | ||
214 | unsigned long mask; | ||
215 | unsigned long addr; | ||
216 | } __attribute__ ((aligned(8))) psw_t; | ||
217 | |||
218 | typedef struct | ||
219 | { | ||
220 | __u32 mask; | ||
221 | __u32 addr; | ||
222 | } __attribute__ ((aligned(8))) psw_compat_t; | ||
223 | |||
224 | #ifndef __s390x__ | ||
225 | |||
226 | #define PSW_MASK_PER 0x40000000UL | ||
227 | #define PSW_MASK_DAT 0x04000000UL | ||
228 | #define PSW_MASK_IO 0x02000000UL | ||
229 | #define PSW_MASK_EXT 0x01000000UL | ||
230 | #define PSW_MASK_KEY 0x00F00000UL | ||
231 | #define PSW_MASK_MCHECK 0x00040000UL | ||
232 | #define PSW_MASK_WAIT 0x00020000UL | ||
233 | #define PSW_MASK_PSTATE 0x00010000UL | ||
234 | #define PSW_MASK_ASC 0x0000C000UL | ||
235 | #define PSW_MASK_CC 0x00003000UL | ||
236 | #define PSW_MASK_PM 0x00000F00UL | ||
237 | |||
238 | #define PSW_ADDR_AMODE 0x80000000UL | ||
239 | #define PSW_ADDR_INSN 0x7FFFFFFFUL | ||
240 | |||
241 | #define PSW_BASE_BITS 0x00080000UL | ||
242 | #define PSW_DEFAULT_KEY (((unsigned long) PAGE_DEFAULT_ACC) << 20) | ||
243 | |||
244 | #define PSW_ASC_PRIMARY 0x00000000UL | ||
245 | #define PSW_ASC_ACCREG 0x00004000UL | ||
246 | #define PSW_ASC_SECONDARY 0x00008000UL | ||
247 | #define PSW_ASC_HOME 0x0000C000UL | ||
248 | |||
249 | #else /* __s390x__ */ | ||
250 | |||
251 | #define PSW_MASK_PER 0x4000000000000000UL | ||
252 | #define PSW_MASK_DAT 0x0400000000000000UL | ||
253 | #define PSW_MASK_IO 0x0200000000000000UL | ||
254 | #define PSW_MASK_EXT 0x0100000000000000UL | ||
255 | #define PSW_MASK_KEY 0x00F0000000000000UL | ||
256 | #define PSW_MASK_MCHECK 0x0004000000000000UL | ||
257 | #define PSW_MASK_WAIT 0x0002000000000000UL | ||
258 | #define PSW_MASK_PSTATE 0x0001000000000000UL | ||
259 | #define PSW_MASK_ASC 0x0000C00000000000UL | ||
260 | #define PSW_MASK_CC 0x0000300000000000UL | ||
261 | #define PSW_MASK_PM 0x00000F0000000000UL | ||
262 | |||
263 | #define PSW_ADDR_AMODE 0x0000000000000000UL | ||
264 | #define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL | ||
265 | |||
266 | #define PSW_BASE_BITS 0x0000000180000000UL | ||
267 | #define PSW_BASE32_BITS 0x0000000080000000UL | ||
268 | #define PSW_DEFAULT_KEY (((unsigned long) PAGE_DEFAULT_ACC) << 52) | ||
269 | |||
270 | #define PSW_ASC_PRIMARY 0x0000000000000000UL | ||
271 | #define PSW_ASC_ACCREG 0x0000400000000000UL | ||
272 | #define PSW_ASC_SECONDARY 0x0000800000000000UL | ||
273 | #define PSW_ASC_HOME 0x0000C00000000000UL | ||
274 | |||
275 | extern long psw_user32_bits; | ||
276 | |||
277 | #endif /* __s390x__ */ | ||
278 | |||
279 | extern long psw_kernel_bits; | ||
280 | extern long psw_user_bits; | ||
281 | |||
282 | /* This macro merges a NEW PSW mask specified by the user into | ||
283 | the currently active PSW mask CURRENT, modifying only those | ||
284 | bits in CURRENT that the user may be allowed to change: this | ||
285 | is the condition code and the program mask bits. */ | ||
286 | #define PSW_MASK_MERGE(CURRENT,NEW) \ | ||
287 | (((CURRENT) & ~(PSW_MASK_CC|PSW_MASK_PM)) | \ | ||
288 | ((NEW) & (PSW_MASK_CC|PSW_MASK_PM))) | ||
289 | |||
290 | /* | ||
291 | * The s390_regs structure is used to define the elf_gregset_t. | ||
292 | */ | ||
293 | typedef struct | ||
294 | { | ||
295 | psw_t psw; | ||
296 | unsigned long gprs[NUM_GPRS]; | ||
297 | unsigned int acrs[NUM_ACRS]; | ||
298 | unsigned long orig_gpr2; | ||
299 | } s390_regs; | ||
300 | |||
301 | typedef struct | ||
302 | { | ||
303 | psw_compat_t psw; | ||
304 | __u32 gprs[NUM_GPRS]; | ||
305 | __u32 acrs[NUM_ACRS]; | ||
306 | __u32 orig_gpr2; | ||
307 | } s390_compat_regs; | ||
308 | |||
309 | |||
310 | #ifdef __KERNEL__ | ||
311 | #include <asm/setup.h> | ||
312 | #include <asm/page.h> | ||
313 | |||
314 | /* | ||
315 | * The pt_regs struct defines the way the registers are stored on | ||
316 | * the stack during a system call. | ||
317 | */ | ||
318 | struct pt_regs | ||
319 | { | ||
320 | unsigned long args[1]; | ||
321 | psw_t psw; | ||
322 | unsigned long gprs[NUM_GPRS]; | ||
323 | unsigned long orig_gpr2; | ||
324 | unsigned short ilc; | ||
325 | unsigned short trap; | ||
326 | }; | ||
327 | #endif | ||
328 | |||
329 | /* | ||
330 | * Now for the program event recording (trace) definitions. | ||
331 | */ | ||
332 | typedef struct | ||
333 | { | ||
334 | unsigned long cr[3]; | ||
335 | } per_cr_words; | ||
336 | |||
337 | #define PER_EM_MASK 0xE8000000UL | ||
338 | |||
339 | typedef struct | ||
340 | { | ||
341 | #ifdef __s390x__ | ||
342 | unsigned : 32; | ||
343 | #endif /* __s390x__ */ | ||
344 | unsigned em_branching : 1; | ||
345 | unsigned em_instruction_fetch : 1; | ||
346 | /* | ||
347 | * Switching on storage alteration automatically fixes | ||
348 | * the storage alteration event bit in the users std. | ||
349 | */ | ||
350 | unsigned em_storage_alteration : 1; | ||
351 | unsigned em_gpr_alt_unused : 1; | ||
352 | unsigned em_store_real_address : 1; | ||
353 | unsigned : 3; | ||
354 | unsigned branch_addr_ctl : 1; | ||
355 | unsigned : 1; | ||
356 | unsigned storage_alt_space_ctl : 1; | ||
357 | unsigned : 21; | ||
358 | unsigned long starting_addr; | ||
359 | unsigned long ending_addr; | ||
360 | } per_cr_bits; | ||
361 | |||
362 | typedef struct | ||
363 | { | ||
364 | unsigned short perc_atmid; | ||
365 | unsigned long address; | ||
366 | unsigned char access_id; | ||
367 | } per_lowcore_words; | ||
368 | |||
369 | typedef struct | ||
370 | { | ||
371 | unsigned perc_branching : 1; | ||
372 | unsigned perc_instruction_fetch : 1; | ||
373 | unsigned perc_storage_alteration : 1; | ||
374 | unsigned perc_gpr_alt_unused : 1; | ||
375 | unsigned perc_store_real_address : 1; | ||
376 | unsigned : 3; | ||
377 | unsigned atmid_psw_bit_31 : 1; | ||
378 | unsigned atmid_validity_bit : 1; | ||
379 | unsigned atmid_psw_bit_32 : 1; | ||
380 | unsigned atmid_psw_bit_5 : 1; | ||
381 | unsigned atmid_psw_bit_16 : 1; | ||
382 | unsigned atmid_psw_bit_17 : 1; | ||
383 | unsigned si : 2; | ||
384 | unsigned long address; | ||
385 | unsigned : 4; | ||
386 | unsigned access_id : 4; | ||
387 | } per_lowcore_bits; | ||
388 | |||
389 | typedef struct | ||
390 | { | ||
391 | union { | ||
392 | per_cr_words words; | ||
393 | per_cr_bits bits; | ||
394 | } control_regs; | ||
395 | /* | ||
396 | * Use these flags instead of setting em_instruction_fetch | ||
397 | * directly they are used so that single stepping can be | ||
398 | * switched on & off while not affecting other tracing | ||
399 | */ | ||
400 | unsigned single_step : 1; | ||
401 | unsigned instruction_fetch : 1; | ||
402 | unsigned : 30; | ||
403 | /* | ||
404 | * These addresses are copied into cr10 & cr11 if single | ||
405 | * stepping is switched off | ||
406 | */ | ||
407 | unsigned long starting_addr; | ||
408 | unsigned long ending_addr; | ||
409 | union { | ||
410 | per_lowcore_words words; | ||
411 | per_lowcore_bits bits; | ||
412 | } lowcore; | ||
413 | } per_struct; | ||
414 | |||
415 | typedef struct | ||
416 | { | ||
417 | unsigned int len; | ||
418 | unsigned long kernel_addr; | ||
419 | unsigned long process_addr; | ||
420 | } ptrace_area; | ||
421 | |||
422 | /* | ||
423 | * S/390 specific non posix ptrace requests. I chose unusual values so | ||
424 | * they are unlikely to clash with future ptrace definitions. | ||
425 | */ | ||
426 | #define PTRACE_PEEKUSR_AREA 0x5000 | ||
427 | #define PTRACE_POKEUSR_AREA 0x5001 | ||
428 | #define PTRACE_PEEKTEXT_AREA 0x5002 | ||
429 | #define PTRACE_PEEKDATA_AREA 0x5003 | ||
430 | #define PTRACE_POKETEXT_AREA 0x5004 | ||
431 | #define PTRACE_POKEDATA_AREA 0x5005 | ||
432 | |||
433 | /* | ||
434 | * PT_PROT definition is loosely based on hppa bsd definition in | ||
435 | * gdb/hppab-nat.c | ||
436 | */ | ||
437 | #define PTRACE_PROT 21 | ||
438 | |||
439 | typedef enum | ||
440 | { | ||
441 | ptprot_set_access_watchpoint, | ||
442 | ptprot_set_write_watchpoint, | ||
443 | ptprot_disable_watchpoint | ||
444 | } ptprot_flags; | ||
445 | |||
446 | typedef struct | ||
447 | { | ||
448 | unsigned long lowaddr; | ||
449 | unsigned long hiaddr; | ||
450 | ptprot_flags prot; | ||
451 | } ptprot_area; | ||
452 | |||
453 | /* Sequence of bytes for breakpoint illegal instruction. */ | ||
454 | #define S390_BREAKPOINT {0x0,0x1} | ||
455 | #define S390_BREAKPOINT_U16 ((__u16)0x0001) | ||
456 | #define S390_SYSCALL_OPCODE ((__u16)0x0a00) | ||
457 | #define S390_SYSCALL_SIZE 2 | ||
458 | |||
459 | /* | ||
460 | * The user_regs_struct defines the way the user registers are | ||
461 | * store on the stack for signal handling. | ||
462 | */ | ||
463 | struct user_regs_struct | ||
464 | { | ||
465 | psw_t psw; | ||
466 | unsigned long gprs[NUM_GPRS]; | ||
467 | unsigned int acrs[NUM_ACRS]; | ||
468 | unsigned long orig_gpr2; | ||
469 | s390_fp_regs fp_regs; | ||
470 | /* | ||
471 | * These per registers are in here so that gdb can modify them | ||
472 | * itself as there is no "official" ptrace interface for hardware | ||
473 | * watchpoints. This is the way intel does it. | ||
474 | */ | ||
475 | per_struct per_info; | ||
476 | unsigned long ieee_instruction_pointer; | ||
477 | /* Used to give failing instruction back to user for ieee exceptions */ | ||
478 | }; | ||
479 | |||
480 | #ifdef __KERNEL__ | ||
481 | /* | ||
482 | * These are defined as per linux/ptrace.h, which see. | ||
483 | */ | ||
484 | #define arch_has_single_step() (1) | ||
485 | struct task_struct; | ||
486 | extern void user_enable_single_step(struct task_struct *); | ||
487 | extern void user_disable_single_step(struct task_struct *); | ||
488 | |||
489 | #define __ARCH_WANT_COMPAT_SYS_PTRACE | ||
490 | |||
491 | #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) | ||
492 | #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) | ||
493 | #define regs_return_value(regs)((regs)->gprs[2]) | ||
494 | #define profile_pc(regs) instruction_pointer(regs) | ||
495 | extern void show_regs(struct pt_regs * regs); | ||
496 | #endif /* __KERNEL__ */ | ||
497 | #endif /* __ASSEMBLY__ */ | ||
498 | |||
499 | #endif /* _S390_PTRACE_H */ | ||
diff --git a/arch/s390/include/asm/qdio.h b/arch/s390/include/asm/qdio.h new file mode 100644 index 000000000000..6813772171f2 --- /dev/null +++ b/arch/s390/include/asm/qdio.h | |||
@@ -0,0 +1,382 @@ | |||
1 | /* | ||
2 | * linux/include/asm-s390/qdio.h | ||
3 | * | ||
4 | * Copyright 2000,2008 IBM Corp. | ||
5 | * Author(s): Utz Bacher <utz.bacher@de.ibm.com> | ||
6 | * Jan Glauber <jang@linux.vnet.ibm.com> | ||
7 | * | ||
8 | */ | ||
9 | #ifndef __QDIO_H__ | ||
10 | #define __QDIO_H__ | ||
11 | |||
12 | #include <linux/interrupt.h> | ||
13 | #include <asm/cio.h> | ||
14 | #include <asm/ccwdev.h> | ||
15 | |||
16 | #define QDIO_MAX_QUEUES_PER_IRQ 32 | ||
17 | #define QDIO_MAX_BUFFERS_PER_Q 128 | ||
18 | #define QDIO_MAX_BUFFERS_MASK (QDIO_MAX_BUFFERS_PER_Q - 1) | ||
19 | #define QDIO_MAX_ELEMENTS_PER_BUFFER 16 | ||
20 | #define QDIO_SBAL_SIZE 256 | ||
21 | |||
22 | #define QDIO_QETH_QFMT 0 | ||
23 | #define QDIO_ZFCP_QFMT 1 | ||
24 | #define QDIO_IQDIO_QFMT 2 | ||
25 | |||
26 | /** | ||
27 | * struct qdesfmt0 - queue descriptor, format 0 | ||
28 | * @sliba: storage list information block address | ||
29 | * @sla: storage list address | ||
30 | * @slsba: storage list state block address | ||
31 | * @akey: access key for DLIB | ||
32 | * @bkey: access key for SL | ||
33 | * @ckey: access key for SBALs | ||
34 | * @dkey: access key for SLSB | ||
35 | */ | ||
36 | struct qdesfmt0 { | ||
37 | u64 sliba; | ||
38 | u64 sla; | ||
39 | u64 slsba; | ||
40 | u32 : 32; | ||
41 | u32 akey : 4; | ||
42 | u32 bkey : 4; | ||
43 | u32 ckey : 4; | ||
44 | u32 dkey : 4; | ||
45 | u32 : 16; | ||
46 | } __attribute__ ((packed)); | ||
47 | |||
48 | /** | ||
49 | * struct qdr - queue description record (QDR) | ||
50 | * @qfmt: queue format | ||
51 | * @pfmt: implementation dependent parameter format | ||
52 | * @ac: adapter characteristics | ||
53 | * @iqdcnt: input queue descriptor count | ||
54 | * @oqdcnt: output queue descriptor count | ||
55 | * @iqdsz: inpout queue descriptor size | ||
56 | * @oqdsz: output queue descriptor size | ||
57 | * @qiba: queue information block address | ||
58 | * @qkey: queue information block key | ||
59 | * @qdf0: queue descriptions | ||
60 | */ | ||
61 | struct qdr { | ||
62 | u32 qfmt : 8; | ||
63 | u32 pfmt : 8; | ||
64 | u32 : 8; | ||
65 | u32 ac : 8; | ||
66 | u32 : 8; | ||
67 | u32 iqdcnt : 8; | ||
68 | u32 : 8; | ||
69 | u32 oqdcnt : 8; | ||
70 | u32 : 8; | ||
71 | u32 iqdsz : 8; | ||
72 | u32 : 8; | ||
73 | u32 oqdsz : 8; | ||
74 | /* private: */ | ||
75 | u32 res[9]; | ||
76 | /* public: */ | ||
77 | u64 qiba; | ||
78 | u32 : 32; | ||
79 | u32 qkey : 4; | ||
80 | u32 : 28; | ||
81 | struct qdesfmt0 qdf0[126]; | ||
82 | } __attribute__ ((packed, aligned(4096))); | ||
83 | |||
84 | #define QIB_AC_OUTBOUND_PCI_SUPPORTED 0x40 | ||
85 | #define QIB_RFLAGS_ENABLE_QEBSM 0x80 | ||
86 | |||
87 | /** | ||
88 | * struct qib - queue information block (QIB) | ||
89 | * @qfmt: queue format | ||
90 | * @pfmt: implementation dependent parameter format | ||
91 | * @rflags: QEBSM | ||
92 | * @ac: adapter characteristics | ||
93 | * @isliba: absolute address of first input SLIB | ||
94 | * @osliba: absolute address of first output SLIB | ||
95 | * @ebcnam: adapter identifier in EBCDIC | ||
96 | * @parm: implementation dependent parameters | ||
97 | */ | ||
98 | struct qib { | ||
99 | u32 qfmt : 8; | ||
100 | u32 pfmt : 8; | ||
101 | u32 rflags : 8; | ||
102 | u32 ac : 8; | ||
103 | u32 : 32; | ||
104 | u64 isliba; | ||
105 | u64 osliba; | ||
106 | u32 : 32; | ||
107 | u32 : 32; | ||
108 | u8 ebcnam[8]; | ||
109 | /* private: */ | ||
110 | u8 res[88]; | ||
111 | /* public: */ | ||
112 | u8 parm[QDIO_MAX_BUFFERS_PER_Q]; | ||
113 | } __attribute__ ((packed, aligned(256))); | ||
114 | |||
115 | /** | ||
116 | * struct slibe - storage list information block element (SLIBE) | ||
117 | * @parms: implementation dependent parameters | ||
118 | */ | ||
119 | struct slibe { | ||
120 | u64 parms; | ||
121 | }; | ||
122 | |||
123 | /** | ||
124 | * struct slib - storage list information block (SLIB) | ||
125 | * @nsliba: next SLIB address (if any) | ||
126 | * @sla: SL address | ||
127 | * @slsba: SLSB address | ||
128 | * @slibe: SLIB elements | ||
129 | */ | ||
130 | struct slib { | ||
131 | u64 nsliba; | ||
132 | u64 sla; | ||
133 | u64 slsba; | ||
134 | /* private: */ | ||
135 | u8 res[1000]; | ||
136 | /* public: */ | ||
137 | struct slibe slibe[QDIO_MAX_BUFFERS_PER_Q]; | ||
138 | } __attribute__ ((packed, aligned(2048))); | ||
139 | |||
140 | /** | ||
141 | * struct sbal_flags - storage block address list flags | ||
142 | * @last: last entry | ||
143 | * @cont: contiguous storage | ||
144 | * @frag: fragmentation | ||
145 | */ | ||
146 | struct sbal_flags { | ||
147 | u8 : 1; | ||
148 | u8 last : 1; | ||
149 | u8 cont : 1; | ||
150 | u8 : 1; | ||
151 | u8 frag : 2; | ||
152 | u8 : 2; | ||
153 | } __attribute__ ((packed)); | ||
154 | |||
155 | #define SBAL_FLAGS_FIRST_FRAG 0x04000000UL | ||
156 | #define SBAL_FLAGS_MIDDLE_FRAG 0x08000000UL | ||
157 | #define SBAL_FLAGS_LAST_FRAG 0x0c000000UL | ||
158 | #define SBAL_FLAGS_LAST_ENTRY 0x40000000UL | ||
159 | #define SBAL_FLAGS_CONTIGUOUS 0x20000000UL | ||
160 | |||
161 | #define SBAL_FLAGS0_DATA_CONTINUATION 0x20UL | ||
162 | |||
163 | /* Awesome OpenFCP extensions */ | ||
164 | #define SBAL_FLAGS0_TYPE_STATUS 0x00UL | ||
165 | #define SBAL_FLAGS0_TYPE_WRITE 0x08UL | ||
166 | #define SBAL_FLAGS0_TYPE_READ 0x10UL | ||
167 | #define SBAL_FLAGS0_TYPE_WRITE_READ 0x18UL | ||
168 | #define SBAL_FLAGS0_MORE_SBALS 0x04UL | ||
169 | #define SBAL_FLAGS0_COMMAND 0x02UL | ||
170 | #define SBAL_FLAGS0_LAST_SBAL 0x00UL | ||
171 | #define SBAL_FLAGS0_ONLY_SBAL SBAL_FLAGS0_COMMAND | ||
172 | #define SBAL_FLAGS0_MIDDLE_SBAL SBAL_FLAGS0_MORE_SBALS | ||
173 | #define SBAL_FLAGS0_FIRST_SBAL SBAL_FLAGS0_MORE_SBALS | SBAL_FLAGS0_COMMAND | ||
174 | #define SBAL_FLAGS0_PCI 0x40 | ||
175 | |||
176 | /** | ||
177 | * struct sbal_sbalf_0 - sbal flags for sbale 0 | ||
178 | * @pci: PCI indicator | ||
179 | * @cont: data continuation | ||
180 | * @sbtype: storage-block type (FCP) | ||
181 | */ | ||
182 | struct sbal_sbalf_0 { | ||
183 | u8 : 1; | ||
184 | u8 pci : 1; | ||
185 | u8 cont : 1; | ||
186 | u8 sbtype : 2; | ||
187 | u8 : 3; | ||
188 | } __attribute__ ((packed)); | ||
189 | |||
190 | /** | ||
191 | * struct sbal_sbalf_1 - sbal flags for sbale 1 | ||
192 | * @key: storage key | ||
193 | */ | ||
194 | struct sbal_sbalf_1 { | ||
195 | u8 : 4; | ||
196 | u8 key : 4; | ||
197 | } __attribute__ ((packed)); | ||
198 | |||
199 | /** | ||
200 | * struct sbal_sbalf_14 - sbal flags for sbale 14 | ||
201 | * @erridx: error index | ||
202 | */ | ||
203 | struct sbal_sbalf_14 { | ||
204 | u8 : 4; | ||
205 | u8 erridx : 4; | ||
206 | } __attribute__ ((packed)); | ||
207 | |||
208 | /** | ||
209 | * struct sbal_sbalf_15 - sbal flags for sbale 15 | ||
210 | * @reason: reason for error state | ||
211 | */ | ||
212 | struct sbal_sbalf_15 { | ||
213 | u8 reason; | ||
214 | } __attribute__ ((packed)); | ||
215 | |||
216 | /** | ||
217 | * union sbal_sbalf - storage block address list flags | ||
218 | * @i0: sbalf0 | ||
219 | * @i1: sbalf1 | ||
220 | * @i14: sbalf14 | ||
221 | * @i15: sblaf15 | ||
222 | * @value: raw value | ||
223 | */ | ||
224 | union sbal_sbalf { | ||
225 | struct sbal_sbalf_0 i0; | ||
226 | struct sbal_sbalf_1 i1; | ||
227 | struct sbal_sbalf_14 i14; | ||
228 | struct sbal_sbalf_15 i15; | ||
229 | u8 value; | ||
230 | }; | ||
231 | |||
232 | /** | ||
233 | * struct qdio_buffer_element - SBAL entry | ||
234 | * @flags: flags | ||
235 | * @length: length | ||
236 | * @addr: address | ||
237 | */ | ||
238 | struct qdio_buffer_element { | ||
239 | u32 flags; | ||
240 | u32 length; | ||
241 | #ifdef CONFIG_32BIT | ||
242 | /* private: */ | ||
243 | void *reserved; | ||
244 | /* public: */ | ||
245 | #endif | ||
246 | void *addr; | ||
247 | } __attribute__ ((packed, aligned(16))); | ||
248 | |||
249 | /** | ||
250 | * struct qdio_buffer - storage block address list (SBAL) | ||
251 | * @element: SBAL entries | ||
252 | */ | ||
253 | struct qdio_buffer { | ||
254 | struct qdio_buffer_element element[QDIO_MAX_ELEMENTS_PER_BUFFER]; | ||
255 | } __attribute__ ((packed, aligned(256))); | ||
256 | |||
257 | /** | ||
258 | * struct sl_element - storage list entry | ||
259 | * @sbal: absolute SBAL address | ||
260 | */ | ||
261 | struct sl_element { | ||
262 | #ifdef CONFIG_32BIT | ||
263 | /* private: */ | ||
264 | unsigned long reserved; | ||
265 | /* public: */ | ||
266 | #endif | ||
267 | unsigned long sbal; | ||
268 | } __attribute__ ((packed)); | ||
269 | |||
270 | /** | ||
271 | * struct sl - storage list (SL) | ||
272 | * @element: SL entries | ||
273 | */ | ||
274 | struct sl { | ||
275 | struct sl_element element[QDIO_MAX_BUFFERS_PER_Q]; | ||
276 | } __attribute__ ((packed, aligned(1024))); | ||
277 | |||
278 | /** | ||
279 | * struct slsb - storage list state block (SLSB) | ||
280 | * @val: state per buffer | ||
281 | */ | ||
282 | struct slsb { | ||
283 | u8 val[QDIO_MAX_BUFFERS_PER_Q]; | ||
284 | } __attribute__ ((packed, aligned(256))); | ||
285 | |||
286 | struct qdio_ssqd_desc { | ||
287 | u8 flags; | ||
288 | u8:8; | ||
289 | u16 sch; | ||
290 | u8 qfmt; | ||
291 | u8 parm; | ||
292 | u8 qdioac1; | ||
293 | u8 sch_class; | ||
294 | u8 pcnt; | ||
295 | u8 icnt; | ||
296 | u8:8; | ||
297 | u8 ocnt; | ||
298 | u8:8; | ||
299 | u8 mbccnt; | ||
300 | u16 qdioac2; | ||
301 | u64 sch_token; | ||
302 | u64:64; | ||
303 | } __attribute__ ((packed)); | ||
304 | |||
305 | /* params are: ccw_device, qdio_error, queue_number, | ||
306 | first element processed, number of elements processed, int_parm */ | ||
307 | typedef void qdio_handler_t(struct ccw_device *, unsigned int, int, | ||
308 | int, int, unsigned long); | ||
309 | |||
310 | /* qdio errors reported to the upper-layer program */ | ||
311 | #define QDIO_ERROR_SIGA_ACCESS_EXCEPTION 0x10 | ||
312 | #define QDIO_ERROR_SIGA_BUSY 0x20 | ||
313 | #define QDIO_ERROR_ACTIVATE_CHECK_CONDITION 0x40 | ||
314 | #define QDIO_ERROR_SLSB_STATE 0x80 | ||
315 | |||
316 | /* for qdio_initialize */ | ||
317 | #define QDIO_INBOUND_0COPY_SBALS 0x01 | ||
318 | #define QDIO_OUTBOUND_0COPY_SBALS 0x02 | ||
319 | #define QDIO_USE_OUTBOUND_PCIS 0x04 | ||
320 | |||
321 | /* for qdio_cleanup */ | ||
322 | #define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01 | ||
323 | #define QDIO_FLAG_CLEANUP_USING_HALT 0x02 | ||
324 | |||
325 | /** | ||
326 | * struct qdio_initialize - qdio initalization data | ||
327 | * @cdev: associated ccw device | ||
328 | * @q_format: queue format | ||
329 | * @adapter_name: name for the adapter | ||
330 | * @qib_param_field_format: format for qib_parm_field | ||
331 | * @qib_param_field: pointer to 128 bytes or NULL, if no param field | ||
332 | * @input_slib_elements: pointer to no_input_qs * 128 words of data or NULL | ||
333 | * @output_slib_elements: pointer to no_output_qs * 128 words of data or NULL | ||
334 | * @no_input_qs: number of input queues | ||
335 | * @no_output_qs: number of output queues | ||
336 | * @input_handler: handler to be called for input queues | ||
337 | * @output_handler: handler to be called for output queues | ||
338 | * @int_parm: interruption parameter | ||
339 | * @flags: initialization flags | ||
340 | * @input_sbal_addr_array: address of no_input_qs * 128 pointers | ||
341 | * @output_sbal_addr_array: address of no_output_qs * 128 pointers | ||
342 | */ | ||
343 | struct qdio_initialize { | ||
344 | struct ccw_device *cdev; | ||
345 | unsigned char q_format; | ||
346 | unsigned char adapter_name[8]; | ||
347 | unsigned int qib_param_field_format; | ||
348 | unsigned char *qib_param_field; | ||
349 | unsigned long *input_slib_elements; | ||
350 | unsigned long *output_slib_elements; | ||
351 | unsigned int no_input_qs; | ||
352 | unsigned int no_output_qs; | ||
353 | qdio_handler_t *input_handler; | ||
354 | qdio_handler_t *output_handler; | ||
355 | unsigned long int_parm; | ||
356 | unsigned long flags; | ||
357 | void **input_sbal_addr_array; | ||
358 | void **output_sbal_addr_array; | ||
359 | }; | ||
360 | |||
361 | #define QDIO_STATE_INACTIVE 0x00000002 /* after qdio_cleanup */ | ||
362 | #define QDIO_STATE_ESTABLISHED 0x00000004 /* after qdio_establish */ | ||
363 | #define QDIO_STATE_ACTIVE 0x00000008 /* after qdio_activate */ | ||
364 | #define QDIO_STATE_STOPPED 0x00000010 /* after queues went down */ | ||
365 | |||
366 | #define QDIO_FLAG_SYNC_INPUT 0x01 | ||
367 | #define QDIO_FLAG_SYNC_OUTPUT 0x02 | ||
368 | #define QDIO_FLAG_PCI_OUT 0x10 | ||
369 | |||
370 | extern int qdio_initialize(struct qdio_initialize *init_data); | ||
371 | extern int qdio_allocate(struct qdio_initialize *init_data); | ||
372 | extern int qdio_establish(struct qdio_initialize *init_data); | ||
373 | extern int qdio_activate(struct ccw_device *); | ||
374 | |||
375 | extern int do_QDIO(struct ccw_device*, unsigned int flags, | ||
376 | int q_nr, int qidx, int count); | ||
377 | extern int qdio_cleanup(struct ccw_device*, int how); | ||
378 | extern int qdio_shutdown(struct ccw_device*, int how); | ||
379 | extern int qdio_free(struct ccw_device *); | ||
380 | extern struct qdio_ssqd_desc *qdio_get_ssqd_desc(struct ccw_device *cdev); | ||
381 | |||
382 | #endif /* __QDIO_H__ */ | ||
diff --git a/arch/s390/include/asm/qeth.h b/arch/s390/include/asm/qeth.h new file mode 100644 index 000000000000..930d378ef75a --- /dev/null +++ b/arch/s390/include/asm/qeth.h | |||
@@ -0,0 +1,78 @@ | |||
1 | /* | ||
2 | * include/asm-s390/qeth.h | ||
3 | * | ||
4 | * ioctl definitions for qeth driver | ||
5 | * | ||
6 | * Copyright (C) 2004 IBM Corporation | ||
7 | * | ||
8 | * Author(s): Thomas Spatzier <tspat@de.ibm.com> | ||
9 | * | ||
10 | */ | ||
11 | #ifndef __ASM_S390_QETH_IOCTL_H__ | ||
12 | #define __ASM_S390_QETH_IOCTL_H__ | ||
13 | #include <linux/ioctl.h> | ||
14 | |||
15 | #define SIOC_QETH_ARP_SET_NO_ENTRIES (SIOCDEVPRIVATE) | ||
16 | #define SIOC_QETH_ARP_QUERY_INFO (SIOCDEVPRIVATE + 1) | ||
17 | #define SIOC_QETH_ARP_ADD_ENTRY (SIOCDEVPRIVATE + 2) | ||
18 | #define SIOC_QETH_ARP_REMOVE_ENTRY (SIOCDEVPRIVATE + 3) | ||
19 | #define SIOC_QETH_ARP_FLUSH_CACHE (SIOCDEVPRIVATE + 4) | ||
20 | #define SIOC_QETH_ADP_SET_SNMP_CONTROL (SIOCDEVPRIVATE + 5) | ||
21 | #define SIOC_QETH_GET_CARD_TYPE (SIOCDEVPRIVATE + 6) | ||
22 | |||
23 | struct qeth_arp_cache_entry { | ||
24 | __u8 macaddr[6]; | ||
25 | __u8 reserved1[2]; | ||
26 | __u8 ipaddr[16]; /* for both IPv4 and IPv6 */ | ||
27 | __u8 reserved2[32]; | ||
28 | } __attribute__ ((packed)); | ||
29 | |||
30 | struct qeth_arp_qi_entry7 { | ||
31 | __u8 media_specific[32]; | ||
32 | __u8 macaddr_type; | ||
33 | __u8 ipaddr_type; | ||
34 | __u8 macaddr[6]; | ||
35 | __u8 ipaddr[4]; | ||
36 | } __attribute__((packed)); | ||
37 | |||
38 | struct qeth_arp_qi_entry7_short { | ||
39 | __u8 macaddr_type; | ||
40 | __u8 ipaddr_type; | ||
41 | __u8 macaddr[6]; | ||
42 | __u8 ipaddr[4]; | ||
43 | } __attribute__((packed)); | ||
44 | |||
45 | struct qeth_arp_qi_entry5 { | ||
46 | __u8 media_specific[32]; | ||
47 | __u8 macaddr_type; | ||
48 | __u8 ipaddr_type; | ||
49 | __u8 ipaddr[4]; | ||
50 | } __attribute__((packed)); | ||
51 | |||
52 | struct qeth_arp_qi_entry5_short { | ||
53 | __u8 macaddr_type; | ||
54 | __u8 ipaddr_type; | ||
55 | __u8 ipaddr[4]; | ||
56 | } __attribute__((packed)); | ||
57 | |||
58 | /* | ||
59 | * can be set by user if no "media specific information" is wanted | ||
60 | * -> saves a lot of space in user space buffer | ||
61 | */ | ||
62 | #define QETH_QARP_STRIP_ENTRIES 0x8000 | ||
63 | #define QETH_QARP_REQUEST_MASK 0x00ff | ||
64 | |||
65 | /* data sent to user space as result of query arp ioctl */ | ||
66 | #define QETH_QARP_USER_DATA_SIZE 20000 | ||
67 | #define QETH_QARP_MASK_OFFSET 4 | ||
68 | #define QETH_QARP_ENTRIES_OFFSET 6 | ||
69 | struct qeth_arp_query_user_data { | ||
70 | union { | ||
71 | __u32 data_len; /* set by user space program */ | ||
72 | __u32 no_entries; /* set by kernel */ | ||
73 | } u; | ||
74 | __u16 mask_bits; | ||
75 | char *entries; | ||
76 | } __attribute__((packed)); | ||
77 | |||
78 | #endif /* __ASM_S390_QETH_IOCTL_H__ */ | ||
diff --git a/arch/s390/include/asm/reset.h b/arch/s390/include/asm/reset.h new file mode 100644 index 000000000000..f584f4a52581 --- /dev/null +++ b/arch/s390/include/asm/reset.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * include/asm-s390/reset.h | ||
3 | * | ||
4 | * Copyright IBM Corp. 2006 | ||
5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_S390_RESET_H | ||
9 | #define _ASM_S390_RESET_H | ||
10 | |||
11 | #include <linux/list.h> | ||
12 | |||
13 | struct reset_call { | ||
14 | struct list_head list; | ||
15 | void (*fn)(void); | ||
16 | }; | ||
17 | |||
18 | extern void register_reset_call(struct reset_call *reset); | ||
19 | extern void unregister_reset_call(struct reset_call *reset); | ||
20 | extern void s390_reset_system(void); | ||
21 | #endif /* _ASM_S390_RESET_H */ | ||
diff --git a/arch/s390/include/asm/resource.h b/arch/s390/include/asm/resource.h new file mode 100644 index 000000000000..366c01de04f2 --- /dev/null +++ b/arch/s390/include/asm/resource.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * include/asm-s390/resource.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/resources.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef _S390_RESOURCE_H | ||
10 | #define _S390_RESOURCE_H | ||
11 | |||
12 | #include <asm-generic/resource.h> | ||
13 | |||
14 | #endif | ||
15 | |||
diff --git a/arch/s390/include/asm/rwsem.h b/arch/s390/include/asm/rwsem.h new file mode 100644 index 000000000000..9d2a17971805 --- /dev/null +++ b/arch/s390/include/asm/rwsem.h | |||
@@ -0,0 +1,387 @@ | |||
1 | #ifndef _S390_RWSEM_H | ||
2 | #define _S390_RWSEM_H | ||
3 | |||
4 | /* | ||
5 | * include/asm-s390/rwsem.h | ||
6 | * | ||
7 | * S390 version | ||
8 | * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
9 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
10 | * | ||
11 | * Based on asm-alpha/semaphore.h and asm-i386/rwsem.h | ||
12 | */ | ||
13 | |||
14 | /* | ||
15 | * | ||
16 | * The MSW of the count is the negated number of active writers and waiting | ||
17 | * lockers, and the LSW is the total number of active locks | ||
18 | * | ||
19 | * The lock count is initialized to 0 (no active and no waiting lockers). | ||
20 | * | ||
21 | * When a writer subtracts WRITE_BIAS, it'll get 0xffff0001 for the case of an | ||
22 | * uncontended lock. This can be determined because XADD returns the old value. | ||
23 | * Readers increment by 1 and see a positive value when uncontended, negative | ||
24 | * if there are writers (and maybe) readers waiting (in which case it goes to | ||
25 | * sleep). | ||
26 | * | ||
27 | * The value of WAITING_BIAS supports up to 32766 waiting processes. This can | ||
28 | * be extended to 65534 by manually checking the whole MSW rather than relying | ||
29 | * on the S flag. | ||
30 | * | ||
31 | * The value of ACTIVE_BIAS supports up to 65535 active processes. | ||
32 | * | ||
33 | * This should be totally fair - if anything is waiting, a process that wants a | ||
34 | * lock will go to the back of the queue. When the currently active lock is | ||
35 | * released, if there's a writer at the front of the queue, then that and only | ||
36 | * that will be woken up; if there's a bunch of consequtive readers at the | ||
37 | * front, then they'll all be woken up, but no other readers will be. | ||
38 | */ | ||
39 | |||
40 | #ifndef _LINUX_RWSEM_H | ||
41 | #error "please don't include asm/rwsem.h directly, use linux/rwsem.h instead" | ||
42 | #endif | ||
43 | |||
44 | #ifdef __KERNEL__ | ||
45 | |||
46 | #include <linux/list.h> | ||
47 | #include <linux/spinlock.h> | ||
48 | |||
49 | struct rwsem_waiter; | ||
50 | |||
51 | extern struct rw_semaphore *rwsem_down_read_failed(struct rw_semaphore *); | ||
52 | extern struct rw_semaphore *rwsem_down_write_failed(struct rw_semaphore *); | ||
53 | extern struct rw_semaphore *rwsem_wake(struct rw_semaphore *); | ||
54 | extern struct rw_semaphore *rwsem_downgrade_wake(struct rw_semaphore *); | ||
55 | extern struct rw_semaphore *rwsem_downgrade_write(struct rw_semaphore *); | ||
56 | |||
57 | /* | ||
58 | * the semaphore definition | ||
59 | */ | ||
60 | struct rw_semaphore { | ||
61 | signed long count; | ||
62 | spinlock_t wait_lock; | ||
63 | struct list_head wait_list; | ||
64 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
65 | struct lockdep_map dep_map; | ||
66 | #endif | ||
67 | }; | ||
68 | |||
69 | #ifndef __s390x__ | ||
70 | #define RWSEM_UNLOCKED_VALUE 0x00000000 | ||
71 | #define RWSEM_ACTIVE_BIAS 0x00000001 | ||
72 | #define RWSEM_ACTIVE_MASK 0x0000ffff | ||
73 | #define RWSEM_WAITING_BIAS (-0x00010000) | ||
74 | #else /* __s390x__ */ | ||
75 | #define RWSEM_UNLOCKED_VALUE 0x0000000000000000L | ||
76 | #define RWSEM_ACTIVE_BIAS 0x0000000000000001L | ||
77 | #define RWSEM_ACTIVE_MASK 0x00000000ffffffffL | ||
78 | #define RWSEM_WAITING_BIAS (-0x0000000100000000L) | ||
79 | #endif /* __s390x__ */ | ||
80 | #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS | ||
81 | #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) | ||
82 | |||
83 | /* | ||
84 | * initialisation | ||
85 | */ | ||
86 | |||
87 | #ifdef CONFIG_DEBUG_LOCK_ALLOC | ||
88 | # define __RWSEM_DEP_MAP_INIT(lockname) , .dep_map = { .name = #lockname } | ||
89 | #else | ||
90 | # define __RWSEM_DEP_MAP_INIT(lockname) | ||
91 | #endif | ||
92 | |||
93 | #define __RWSEM_INITIALIZER(name) \ | ||
94 | { RWSEM_UNLOCKED_VALUE, __SPIN_LOCK_UNLOCKED((name).wait.lock), \ | ||
95 | LIST_HEAD_INIT((name).wait_list) __RWSEM_DEP_MAP_INIT(name) } | ||
96 | |||
97 | #define DECLARE_RWSEM(name) \ | ||
98 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) | ||
99 | |||
100 | static inline void init_rwsem(struct rw_semaphore *sem) | ||
101 | { | ||
102 | sem->count = RWSEM_UNLOCKED_VALUE; | ||
103 | spin_lock_init(&sem->wait_lock); | ||
104 | INIT_LIST_HEAD(&sem->wait_list); | ||
105 | } | ||
106 | |||
107 | extern void __init_rwsem(struct rw_semaphore *sem, const char *name, | ||
108 | struct lock_class_key *key); | ||
109 | |||
110 | #define init_rwsem(sem) \ | ||
111 | do { \ | ||
112 | static struct lock_class_key __key; \ | ||
113 | \ | ||
114 | __init_rwsem((sem), #sem, &__key); \ | ||
115 | } while (0) | ||
116 | |||
117 | |||
118 | /* | ||
119 | * lock for reading | ||
120 | */ | ||
121 | static inline void __down_read(struct rw_semaphore *sem) | ||
122 | { | ||
123 | signed long old, new; | ||
124 | |||
125 | asm volatile( | ||
126 | #ifndef __s390x__ | ||
127 | " l %0,0(%3)\n" | ||
128 | "0: lr %1,%0\n" | ||
129 | " ahi %1,%5\n" | ||
130 | " cs %0,%1,0(%3)\n" | ||
131 | " jl 0b" | ||
132 | #else /* __s390x__ */ | ||
133 | " lg %0,0(%3)\n" | ||
134 | "0: lgr %1,%0\n" | ||
135 | " aghi %1,%5\n" | ||
136 | " csg %0,%1,0(%3)\n" | ||
137 | " jl 0b" | ||
138 | #endif /* __s390x__ */ | ||
139 | : "=&d" (old), "=&d" (new), "=m" (sem->count) | ||
140 | : "a" (&sem->count), "m" (sem->count), | ||
141 | "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory"); | ||
142 | if (old < 0) | ||
143 | rwsem_down_read_failed(sem); | ||
144 | } | ||
145 | |||
146 | /* | ||
147 | * trylock for reading -- returns 1 if successful, 0 if contention | ||
148 | */ | ||
149 | static inline int __down_read_trylock(struct rw_semaphore *sem) | ||
150 | { | ||
151 | signed long old, new; | ||
152 | |||
153 | asm volatile( | ||
154 | #ifndef __s390x__ | ||
155 | " l %0,0(%3)\n" | ||
156 | "0: ltr %1,%0\n" | ||
157 | " jm 1f\n" | ||
158 | " ahi %1,%5\n" | ||
159 | " cs %0,%1,0(%3)\n" | ||
160 | " jl 0b\n" | ||
161 | "1:" | ||
162 | #else /* __s390x__ */ | ||
163 | " lg %0,0(%3)\n" | ||
164 | "0: ltgr %1,%0\n" | ||
165 | " jm 1f\n" | ||
166 | " aghi %1,%5\n" | ||
167 | " csg %0,%1,0(%3)\n" | ||
168 | " jl 0b\n" | ||
169 | "1:" | ||
170 | #endif /* __s390x__ */ | ||
171 | : "=&d" (old), "=&d" (new), "=m" (sem->count) | ||
172 | : "a" (&sem->count), "m" (sem->count), | ||
173 | "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory"); | ||
174 | return old >= 0 ? 1 : 0; | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * lock for writing | ||
179 | */ | ||
180 | static inline void __down_write_nested(struct rw_semaphore *sem, int subclass) | ||
181 | { | ||
182 | signed long old, new, tmp; | ||
183 | |||
184 | tmp = RWSEM_ACTIVE_WRITE_BIAS; | ||
185 | asm volatile( | ||
186 | #ifndef __s390x__ | ||
187 | " l %0,0(%3)\n" | ||
188 | "0: lr %1,%0\n" | ||
189 | " a %1,%5\n" | ||
190 | " cs %0,%1,0(%3)\n" | ||
191 | " jl 0b" | ||
192 | #else /* __s390x__ */ | ||
193 | " lg %0,0(%3)\n" | ||
194 | "0: lgr %1,%0\n" | ||
195 | " ag %1,%5\n" | ||
196 | " csg %0,%1,0(%3)\n" | ||
197 | " jl 0b" | ||
198 | #endif /* __s390x__ */ | ||
199 | : "=&d" (old), "=&d" (new), "=m" (sem->count) | ||
200 | : "a" (&sem->count), "m" (sem->count), "m" (tmp) | ||
201 | : "cc", "memory"); | ||
202 | if (old != 0) | ||
203 | rwsem_down_write_failed(sem); | ||
204 | } | ||
205 | |||
206 | static inline void __down_write(struct rw_semaphore *sem) | ||
207 | { | ||
208 | __down_write_nested(sem, 0); | ||
209 | } | ||
210 | |||
211 | /* | ||
212 | * trylock for writing -- returns 1 if successful, 0 if contention | ||
213 | */ | ||
214 | static inline int __down_write_trylock(struct rw_semaphore *sem) | ||
215 | { | ||
216 | signed long old; | ||
217 | |||
218 | asm volatile( | ||
219 | #ifndef __s390x__ | ||
220 | " l %0,0(%2)\n" | ||
221 | "0: ltr %0,%0\n" | ||
222 | " jnz 1f\n" | ||
223 | " cs %0,%4,0(%2)\n" | ||
224 | " jl 0b\n" | ||
225 | #else /* __s390x__ */ | ||
226 | " lg %0,0(%2)\n" | ||
227 | "0: ltgr %0,%0\n" | ||
228 | " jnz 1f\n" | ||
229 | " csg %0,%4,0(%2)\n" | ||
230 | " jl 0b\n" | ||
231 | #endif /* __s390x__ */ | ||
232 | "1:" | ||
233 | : "=&d" (old), "=m" (sem->count) | ||
234 | : "a" (&sem->count), "m" (sem->count), | ||
235 | "d" (RWSEM_ACTIVE_WRITE_BIAS) : "cc", "memory"); | ||
236 | return (old == RWSEM_UNLOCKED_VALUE) ? 1 : 0; | ||
237 | } | ||
238 | |||
239 | /* | ||
240 | * unlock after reading | ||
241 | */ | ||
242 | static inline void __up_read(struct rw_semaphore *sem) | ||
243 | { | ||
244 | signed long old, new; | ||
245 | |||
246 | asm volatile( | ||
247 | #ifndef __s390x__ | ||
248 | " l %0,0(%3)\n" | ||
249 | "0: lr %1,%0\n" | ||
250 | " ahi %1,%5\n" | ||
251 | " cs %0,%1,0(%3)\n" | ||
252 | " jl 0b" | ||
253 | #else /* __s390x__ */ | ||
254 | " lg %0,0(%3)\n" | ||
255 | "0: lgr %1,%0\n" | ||
256 | " aghi %1,%5\n" | ||
257 | " csg %0,%1,0(%3)\n" | ||
258 | " jl 0b" | ||
259 | #endif /* __s390x__ */ | ||
260 | : "=&d" (old), "=&d" (new), "=m" (sem->count) | ||
261 | : "a" (&sem->count), "m" (sem->count), | ||
262 | "i" (-RWSEM_ACTIVE_READ_BIAS) | ||
263 | : "cc", "memory"); | ||
264 | if (new < 0) | ||
265 | if ((new & RWSEM_ACTIVE_MASK) == 0) | ||
266 | rwsem_wake(sem); | ||
267 | } | ||
268 | |||
269 | /* | ||
270 | * unlock after writing | ||
271 | */ | ||
272 | static inline void __up_write(struct rw_semaphore *sem) | ||
273 | { | ||
274 | signed long old, new, tmp; | ||
275 | |||
276 | tmp = -RWSEM_ACTIVE_WRITE_BIAS; | ||
277 | asm volatile( | ||
278 | #ifndef __s390x__ | ||
279 | " l %0,0(%3)\n" | ||
280 | "0: lr %1,%0\n" | ||
281 | " a %1,%5\n" | ||
282 | " cs %0,%1,0(%3)\n" | ||
283 | " jl 0b" | ||
284 | #else /* __s390x__ */ | ||
285 | " lg %0,0(%3)\n" | ||
286 | "0: lgr %1,%0\n" | ||
287 | " ag %1,%5\n" | ||
288 | " csg %0,%1,0(%3)\n" | ||
289 | " jl 0b" | ||
290 | #endif /* __s390x__ */ | ||
291 | : "=&d" (old), "=&d" (new), "=m" (sem->count) | ||
292 | : "a" (&sem->count), "m" (sem->count), "m" (tmp) | ||
293 | : "cc", "memory"); | ||
294 | if (new < 0) | ||
295 | if ((new & RWSEM_ACTIVE_MASK) == 0) | ||
296 | rwsem_wake(sem); | ||
297 | } | ||
298 | |||
299 | /* | ||
300 | * downgrade write lock to read lock | ||
301 | */ | ||
302 | static inline void __downgrade_write(struct rw_semaphore *sem) | ||
303 | { | ||
304 | signed long old, new, tmp; | ||
305 | |||
306 | tmp = -RWSEM_WAITING_BIAS; | ||
307 | asm volatile( | ||
308 | #ifndef __s390x__ | ||
309 | " l %0,0(%3)\n" | ||
310 | "0: lr %1,%0\n" | ||
311 | " a %1,%5\n" | ||
312 | " cs %0,%1,0(%3)\n" | ||
313 | " jl 0b" | ||
314 | #else /* __s390x__ */ | ||
315 | " lg %0,0(%3)\n" | ||
316 | "0: lgr %1,%0\n" | ||
317 | " ag %1,%5\n" | ||
318 | " csg %0,%1,0(%3)\n" | ||
319 | " jl 0b" | ||
320 | #endif /* __s390x__ */ | ||
321 | : "=&d" (old), "=&d" (new), "=m" (sem->count) | ||
322 | : "a" (&sem->count), "m" (sem->count), "m" (tmp) | ||
323 | : "cc", "memory"); | ||
324 | if (new > 1) | ||
325 | rwsem_downgrade_wake(sem); | ||
326 | } | ||
327 | |||
328 | /* | ||
329 | * implement atomic add functionality | ||
330 | */ | ||
331 | static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) | ||
332 | { | ||
333 | signed long old, new; | ||
334 | |||
335 | asm volatile( | ||
336 | #ifndef __s390x__ | ||
337 | " l %0,0(%3)\n" | ||
338 | "0: lr %1,%0\n" | ||
339 | " ar %1,%5\n" | ||
340 | " cs %0,%1,0(%3)\n" | ||
341 | " jl 0b" | ||
342 | #else /* __s390x__ */ | ||
343 | " lg %0,0(%3)\n" | ||
344 | "0: lgr %1,%0\n" | ||
345 | " agr %1,%5\n" | ||
346 | " csg %0,%1,0(%3)\n" | ||
347 | " jl 0b" | ||
348 | #endif /* __s390x__ */ | ||
349 | : "=&d" (old), "=&d" (new), "=m" (sem->count) | ||
350 | : "a" (&sem->count), "m" (sem->count), "d" (delta) | ||
351 | : "cc", "memory"); | ||
352 | } | ||
353 | |||
354 | /* | ||
355 | * implement exchange and add functionality | ||
356 | */ | ||
357 | static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) | ||
358 | { | ||
359 | signed long old, new; | ||
360 | |||
361 | asm volatile( | ||
362 | #ifndef __s390x__ | ||
363 | " l %0,0(%3)\n" | ||
364 | "0: lr %1,%0\n" | ||
365 | " ar %1,%5\n" | ||
366 | " cs %0,%1,0(%3)\n" | ||
367 | " jl 0b" | ||
368 | #else /* __s390x__ */ | ||
369 | " lg %0,0(%3)\n" | ||
370 | "0: lgr %1,%0\n" | ||
371 | " agr %1,%5\n" | ||
372 | " csg %0,%1,0(%3)\n" | ||
373 | " jl 0b" | ||
374 | #endif /* __s390x__ */ | ||
375 | : "=&d" (old), "=&d" (new), "=m" (sem->count) | ||
376 | : "a" (&sem->count), "m" (sem->count), "d" (delta) | ||
377 | : "cc", "memory"); | ||
378 | return new; | ||
379 | } | ||
380 | |||
381 | static inline int rwsem_is_locked(struct rw_semaphore *sem) | ||
382 | { | ||
383 | return (sem->count != 0); | ||
384 | } | ||
385 | |||
386 | #endif /* __KERNEL__ */ | ||
387 | #endif /* _S390_RWSEM_H */ | ||
diff --git a/arch/s390/include/asm/s390_ext.h b/arch/s390/include/asm/s390_ext.h new file mode 100644 index 000000000000..2afc060266a2 --- /dev/null +++ b/arch/s390/include/asm/s390_ext.h | |||
@@ -0,0 +1,32 @@ | |||
1 | #ifndef _S390_EXTINT_H | ||
2 | #define _S390_EXTINT_H | ||
3 | |||
4 | /* | ||
5 | * include/asm-s390/s390_ext.h | ||
6 | * | ||
7 | * S390 version | ||
8 | * Copyright IBM Corp. 1999,2007 | ||
9 | * Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com), | ||
10 | * Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
11 | */ | ||
12 | |||
13 | #include <linux/types.h> | ||
14 | |||
15 | typedef void (*ext_int_handler_t)(__u16 code); | ||
16 | |||
17 | typedef struct ext_int_info_t { | ||
18 | struct ext_int_info_t *next; | ||
19 | ext_int_handler_t handler; | ||
20 | __u16 code; | ||
21 | } ext_int_info_t; | ||
22 | |||
23 | extern ext_int_info_t *ext_int_hash[]; | ||
24 | |||
25 | int register_external_interrupt(__u16 code, ext_int_handler_t handler); | ||
26 | int register_early_external_interrupt(__u16 code, ext_int_handler_t handler, | ||
27 | ext_int_info_t *info); | ||
28 | int unregister_external_interrupt(__u16 code, ext_int_handler_t handler); | ||
29 | int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler, | ||
30 | ext_int_info_t *info); | ||
31 | |||
32 | #endif | ||
diff --git a/arch/s390/include/asm/s390_rdev.h b/arch/s390/include/asm/s390_rdev.h new file mode 100644 index 000000000000..6fa20442a48c --- /dev/null +++ b/arch/s390/include/asm/s390_rdev.h | |||
@@ -0,0 +1,15 @@ | |||
1 | /* | ||
2 | * include/asm-s390/ccwdev.h | ||
3 | * | ||
4 | * Copyright (C) 2002,2005 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
5 | * Author(s): Cornelia Huck <cornelia.huck@de.ibm.com> | ||
6 | * Carsten Otte <cotte@de.ibm.com> | ||
7 | * | ||
8 | * Interface for s390 root device | ||
9 | */ | ||
10 | |||
11 | #ifndef _S390_RDEV_H_ | ||
12 | #define _S390_RDEV_H_ | ||
13 | extern struct device *s390_root_dev_register(const char *); | ||
14 | extern void s390_root_dev_unregister(struct device *); | ||
15 | #endif /* _S390_RDEV_H_ */ | ||
diff --git a/arch/s390/include/asm/scatterlist.h b/arch/s390/include/asm/scatterlist.h new file mode 100644 index 000000000000..29ec8e28c8df --- /dev/null +++ b/arch/s390/include/asm/scatterlist.h | |||
@@ -0,0 +1,19 @@ | |||
1 | #ifndef _ASMS390_SCATTERLIST_H | ||
2 | #define _ASMS390_SCATTERLIST_H | ||
3 | |||
4 | struct scatterlist { | ||
5 | #ifdef CONFIG_DEBUG_SG | ||
6 | unsigned long sg_magic; | ||
7 | #endif | ||
8 | unsigned long page_link; | ||
9 | unsigned int offset; | ||
10 | unsigned int length; | ||
11 | }; | ||
12 | |||
13 | #ifdef __s390x__ | ||
14 | #define ISA_DMA_THRESHOLD (0xffffffffffffffffUL) | ||
15 | #else | ||
16 | #define ISA_DMA_THRESHOLD (0xffffffffUL) | ||
17 | #endif | ||
18 | |||
19 | #endif /* _ASMS390X_SCATTERLIST_H */ | ||
diff --git a/arch/s390/include/asm/schid.h b/arch/s390/include/asm/schid.h new file mode 100644 index 000000000000..825503cf3dc2 --- /dev/null +++ b/arch/s390/include/asm/schid.h | |||
@@ -0,0 +1,32 @@ | |||
1 | #ifndef ASM_SCHID_H | ||
2 | #define ASM_SCHID_H | ||
3 | |||
4 | struct subchannel_id { | ||
5 | __u32 cssid : 8; | ||
6 | __u32 : 4; | ||
7 | __u32 m : 1; | ||
8 | __u32 ssid : 2; | ||
9 | __u32 one : 1; | ||
10 | __u32 sch_no : 16; | ||
11 | } __attribute__ ((packed, aligned(4))); | ||
12 | |||
13 | #ifdef __KERNEL__ | ||
14 | #include <linux/string.h> | ||
15 | |||
16 | /* Helper function for sane state of pre-allocated subchannel_id. */ | ||
17 | static inline void | ||
18 | init_subchannel_id(struct subchannel_id *schid) | ||
19 | { | ||
20 | memset(schid, 0, sizeof(struct subchannel_id)); | ||
21 | schid->one = 1; | ||
22 | } | ||
23 | |||
24 | static inline int | ||
25 | schid_equal(struct subchannel_id *schid1, struct subchannel_id *schid2) | ||
26 | { | ||
27 | return !memcmp(schid1, schid2, sizeof(struct subchannel_id)); | ||
28 | } | ||
29 | |||
30 | #endif /* __KERNEL__ */ | ||
31 | |||
32 | #endif /* ASM_SCHID_H */ | ||
diff --git a/arch/s390/include/asm/sclp.h b/arch/s390/include/asm/sclp.h new file mode 100644 index 000000000000..fed7bee650a0 --- /dev/null +++ b/arch/s390/include/asm/sclp.h | |||
@@ -0,0 +1,58 @@ | |||
1 | /* | ||
2 | * include/asm-s390/sclp.h | ||
3 | * | ||
4 | * Copyright IBM Corp. 2007 | ||
5 | * Author(s): Heiko Carstens <heiko.carstens@de.ibm.com> | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_S390_SCLP_H | ||
9 | #define _ASM_S390_SCLP_H | ||
10 | |||
11 | #include <linux/types.h> | ||
12 | #include <asm/chpid.h> | ||
13 | |||
14 | #define SCLP_CHP_INFO_MASK_SIZE 32 | ||
15 | |||
16 | struct sclp_chp_info { | ||
17 | u8 recognized[SCLP_CHP_INFO_MASK_SIZE]; | ||
18 | u8 standby[SCLP_CHP_INFO_MASK_SIZE]; | ||
19 | u8 configured[SCLP_CHP_INFO_MASK_SIZE]; | ||
20 | }; | ||
21 | |||
22 | #define LOADPARM_LEN 8 | ||
23 | |||
24 | struct sclp_ipl_info { | ||
25 | int is_valid; | ||
26 | int has_dump; | ||
27 | char loadparm[LOADPARM_LEN]; | ||
28 | }; | ||
29 | |||
30 | struct sclp_cpu_entry { | ||
31 | u8 address; | ||
32 | u8 reserved0[13]; | ||
33 | u8 type; | ||
34 | u8 reserved1; | ||
35 | } __attribute__((packed)); | ||
36 | |||
37 | struct sclp_cpu_info { | ||
38 | unsigned int configured; | ||
39 | unsigned int standby; | ||
40 | unsigned int combined; | ||
41 | int has_cpu_type; | ||
42 | struct sclp_cpu_entry cpu[255]; | ||
43 | }; | ||
44 | |||
45 | int sclp_get_cpu_info(struct sclp_cpu_info *info); | ||
46 | int sclp_cpu_configure(u8 cpu); | ||
47 | int sclp_cpu_deconfigure(u8 cpu); | ||
48 | void sclp_facilities_detect(void); | ||
49 | unsigned long long sclp_get_rnmax(void); | ||
50 | unsigned long long sclp_get_rzm(void); | ||
51 | int sclp_sdias_blk_count(void); | ||
52 | int sclp_sdias_copy(void *dest, int blk_num, int nr_blks); | ||
53 | int sclp_chp_configure(struct chp_id chpid); | ||
54 | int sclp_chp_deconfigure(struct chp_id chpid); | ||
55 | int sclp_chp_read_info(struct sclp_chp_info *info); | ||
56 | void sclp_get_ipl_info(struct sclp_ipl_info *info); | ||
57 | |||
58 | #endif /* _ASM_S390_SCLP_H */ | ||
diff --git a/arch/s390/include/asm/sections.h b/arch/s390/include/asm/sections.h new file mode 100644 index 000000000000..fbd9116eb17b --- /dev/null +++ b/arch/s390/include/asm/sections.h | |||
@@ -0,0 +1,8 @@ | |||
1 | #ifndef _S390_SECTIONS_H | ||
2 | #define _S390_SECTIONS_H | ||
3 | |||
4 | #include <asm-generic/sections.h> | ||
5 | |||
6 | extern char _eshared[], _ehead[]; | ||
7 | |||
8 | #endif | ||
diff --git a/arch/s390/include/asm/segment.h b/arch/s390/include/asm/segment.h new file mode 100644 index 000000000000..8bfce3475b1c --- /dev/null +++ b/arch/s390/include/asm/segment.h | |||
@@ -0,0 +1,4 @@ | |||
1 | #ifndef _ASM_SEGMENT_H | ||
2 | #define _ASM_SEGMENT_H | ||
3 | |||
4 | #endif | ||
diff --git a/arch/s390/include/asm/sembuf.h b/arch/s390/include/asm/sembuf.h new file mode 100644 index 000000000000..32626b0cac4b --- /dev/null +++ b/arch/s390/include/asm/sembuf.h | |||
@@ -0,0 +1,29 @@ | |||
1 | #ifndef _S390_SEMBUF_H | ||
2 | #define _S390_SEMBUF_H | ||
3 | |||
4 | /* | ||
5 | * The semid64_ds structure for S/390 architecture. | ||
6 | * Note extra padding because this structure is passed back and forth | ||
7 | * between kernel and user space. | ||
8 | * | ||
9 | * Pad space is left for: | ||
10 | * - 64-bit time_t to solve y2038 problem (for !__s390x__) | ||
11 | * - 2 miscellaneous 32-bit values | ||
12 | */ | ||
13 | |||
14 | struct semid64_ds { | ||
15 | struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ | ||
16 | __kernel_time_t sem_otime; /* last semop time */ | ||
17 | #ifndef __s390x__ | ||
18 | unsigned long __unused1; | ||
19 | #endif /* ! __s390x__ */ | ||
20 | __kernel_time_t sem_ctime; /* last change time */ | ||
21 | #ifndef __s390x__ | ||
22 | unsigned long __unused2; | ||
23 | #endif /* ! __s390x__ */ | ||
24 | unsigned long sem_nsems; /* no. of semaphores in array */ | ||
25 | unsigned long __unused3; | ||
26 | unsigned long __unused4; | ||
27 | }; | ||
28 | |||
29 | #endif /* _S390_SEMBUF_H */ | ||
diff --git a/arch/s390/include/asm/setup.h b/arch/s390/include/asm/setup.h new file mode 100644 index 000000000000..2bd9faeb3919 --- /dev/null +++ b/arch/s390/include/asm/setup.h | |||
@@ -0,0 +1,140 @@ | |||
1 | /* | ||
2 | * include/asm-s390/setup.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright IBM Corp. 1999,2006 | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_S390_SETUP_H | ||
9 | #define _ASM_S390_SETUP_H | ||
10 | |||
11 | #define COMMAND_LINE_SIZE 1024 | ||
12 | |||
13 | #define ARCH_COMMAND_LINE_SIZE 896 | ||
14 | |||
15 | #ifdef __KERNEL__ | ||
16 | |||
17 | #include <asm/types.h> | ||
18 | |||
19 | #define PARMAREA 0x10400 | ||
20 | #define MEMORY_CHUNKS 256 | ||
21 | |||
22 | #ifndef __ASSEMBLY__ | ||
23 | |||
24 | #ifndef __s390x__ | ||
25 | #define IPL_DEVICE (*(unsigned long *) (0x10404)) | ||
26 | #define INITRD_START (*(unsigned long *) (0x1040C)) | ||
27 | #define INITRD_SIZE (*(unsigned long *) (0x10414)) | ||
28 | #else /* __s390x__ */ | ||
29 | #define IPL_DEVICE (*(unsigned long *) (0x10400)) | ||
30 | #define INITRD_START (*(unsigned long *) (0x10408)) | ||
31 | #define INITRD_SIZE (*(unsigned long *) (0x10410)) | ||
32 | #endif /* __s390x__ */ | ||
33 | #define COMMAND_LINE ((char *) (0x10480)) | ||
34 | |||
35 | #define CHUNK_READ_WRITE 0 | ||
36 | #define CHUNK_READ_ONLY 1 | ||
37 | |||
38 | struct mem_chunk { | ||
39 | unsigned long addr; | ||
40 | unsigned long size; | ||
41 | int type; | ||
42 | }; | ||
43 | |||
44 | extern struct mem_chunk memory_chunk[]; | ||
45 | extern unsigned long real_memory_size; | ||
46 | |||
47 | void detect_memory_layout(struct mem_chunk chunk[]); | ||
48 | |||
49 | #ifdef CONFIG_S390_SWITCH_AMODE | ||
50 | extern unsigned int switch_amode; | ||
51 | #else | ||
52 | #define switch_amode (0) | ||
53 | #endif | ||
54 | |||
55 | #ifdef CONFIG_S390_EXEC_PROTECT | ||
56 | extern unsigned int s390_noexec; | ||
57 | #else | ||
58 | #define s390_noexec (0) | ||
59 | #endif | ||
60 | |||
61 | /* | ||
62 | * Machine features detected in head.S | ||
63 | */ | ||
64 | extern unsigned long machine_flags; | ||
65 | |||
66 | #define MACHINE_FLAG_VM (1UL << 0) | ||
67 | #define MACHINE_FLAG_IEEE (1UL << 1) | ||
68 | #define MACHINE_FLAG_CSP (1UL << 3) | ||
69 | #define MACHINE_FLAG_MVPG (1UL << 4) | ||
70 | #define MACHINE_FLAG_DIAG44 (1UL << 5) | ||
71 | #define MACHINE_FLAG_IDTE (1UL << 6) | ||
72 | #define MACHINE_FLAG_DIAG9C (1UL << 7) | ||
73 | #define MACHINE_FLAG_MVCOS (1UL << 8) | ||
74 | #define MACHINE_FLAG_KVM (1UL << 9) | ||
75 | #define MACHINE_FLAG_HPAGE (1UL << 10) | ||
76 | #define MACHINE_FLAG_PFMF (1UL << 11) | ||
77 | |||
78 | #define MACHINE_IS_VM (machine_flags & MACHINE_FLAG_VM) | ||
79 | #define MACHINE_IS_KVM (machine_flags & MACHINE_FLAG_KVM) | ||
80 | #define MACHINE_HAS_DIAG9C (machine_flags & MACHINE_FLAG_DIAG9C) | ||
81 | |||
82 | #ifndef __s390x__ | ||
83 | #define MACHINE_HAS_IEEE (machine_flags & MACHINE_FLAG_IEEE) | ||
84 | #define MACHINE_HAS_CSP (machine_flags & MACHINE_FLAG_CSP) | ||
85 | #define MACHINE_HAS_IDTE (0) | ||
86 | #define MACHINE_HAS_DIAG44 (1) | ||
87 | #define MACHINE_HAS_MVPG (machine_flags & MACHINE_FLAG_MVPG) | ||
88 | #define MACHINE_HAS_MVCOS (0) | ||
89 | #define MACHINE_HAS_HPAGE (0) | ||
90 | #define MACHINE_HAS_PFMF (0) | ||
91 | #else /* __s390x__ */ | ||
92 | #define MACHINE_HAS_IEEE (1) | ||
93 | #define MACHINE_HAS_CSP (1) | ||
94 | #define MACHINE_HAS_IDTE (machine_flags & MACHINE_FLAG_IDTE) | ||
95 | #define MACHINE_HAS_DIAG44 (machine_flags & MACHINE_FLAG_DIAG44) | ||
96 | #define MACHINE_HAS_MVPG (1) | ||
97 | #define MACHINE_HAS_MVCOS (machine_flags & MACHINE_FLAG_MVCOS) | ||
98 | #define MACHINE_HAS_HPAGE (machine_flags & MACHINE_FLAG_HPAGE) | ||
99 | #define MACHINE_HAS_PFMF (machine_flags & MACHINE_FLAG_PFMF) | ||
100 | #endif /* __s390x__ */ | ||
101 | |||
102 | #define ZFCPDUMP_HSA_SIZE (32UL<<20) | ||
103 | |||
104 | /* | ||
105 | * Console mode. Override with conmode= | ||
106 | */ | ||
107 | extern unsigned int console_mode; | ||
108 | extern unsigned int console_devno; | ||
109 | extern unsigned int console_irq; | ||
110 | |||
111 | extern char vmhalt_cmd[]; | ||
112 | extern char vmpoff_cmd[]; | ||
113 | |||
114 | #define CONSOLE_IS_UNDEFINED (console_mode == 0) | ||
115 | #define CONSOLE_IS_SCLP (console_mode == 1) | ||
116 | #define CONSOLE_IS_3215 (console_mode == 2) | ||
117 | #define CONSOLE_IS_3270 (console_mode == 3) | ||
118 | #define SET_CONSOLE_SCLP do { console_mode = 1; } while (0) | ||
119 | #define SET_CONSOLE_3215 do { console_mode = 2; } while (0) | ||
120 | #define SET_CONSOLE_3270 do { console_mode = 3; } while (0) | ||
121 | |||
122 | #define NSS_NAME_SIZE 8 | ||
123 | extern char kernel_nss_name[]; | ||
124 | |||
125 | #else /* __ASSEMBLY__ */ | ||
126 | |||
127 | #ifndef __s390x__ | ||
128 | #define IPL_DEVICE 0x10404 | ||
129 | #define INITRD_START 0x1040C | ||
130 | #define INITRD_SIZE 0x10414 | ||
131 | #else /* __s390x__ */ | ||
132 | #define IPL_DEVICE 0x10400 | ||
133 | #define INITRD_START 0x10408 | ||
134 | #define INITRD_SIZE 0x10410 | ||
135 | #endif /* __s390x__ */ | ||
136 | #define COMMAND_LINE 0x10480 | ||
137 | |||
138 | #endif /* __ASSEMBLY__ */ | ||
139 | #endif /* __KERNEL__ */ | ||
140 | #endif /* _ASM_S390_SETUP_H */ | ||
diff --git a/arch/s390/include/asm/sfp-machine.h b/arch/s390/include/asm/sfp-machine.h new file mode 100644 index 000000000000..4e16aede4b06 --- /dev/null +++ b/arch/s390/include/asm/sfp-machine.h | |||
@@ -0,0 +1,142 @@ | |||
1 | /* Machine-dependent software floating-point definitions. | ||
2 | S/390 kernel version. | ||
3 | Copyright (C) 1997,1998,1999 Free Software Foundation, Inc. | ||
4 | This file is part of the GNU C Library. | ||
5 | Contributed by Richard Henderson (rth@cygnus.com), | ||
6 | Jakub Jelinek (jj@ultra.linux.cz), | ||
7 | David S. Miller (davem@redhat.com) and | ||
8 | Peter Maydell (pmaydell@chiark.greenend.org.uk). | ||
9 | |||
10 | The GNU C Library is free software; you can redistribute it and/or | ||
11 | modify it under the terms of the GNU Library General Public License as | ||
12 | published by the Free Software Foundation; either version 2 of the | ||
13 | License, or (at your option) any later version. | ||
14 | |||
15 | The GNU C Library is distributed in the hope that it will be useful, | ||
16 | but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
17 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
18 | Library General Public License for more details. | ||
19 | |||
20 | You should have received a copy of the GNU Library General Public | ||
21 | License along with the GNU C Library; see the file COPYING.LIB. If | ||
22 | not, write to the Free Software Foundation, Inc., | ||
23 | 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ | ||
24 | |||
25 | #ifndef _SFP_MACHINE_H | ||
26 | #define _SFP_MACHINE_H | ||
27 | |||
28 | |||
29 | #define _FP_W_TYPE_SIZE 32 | ||
30 | #define _FP_W_TYPE unsigned int | ||
31 | #define _FP_WS_TYPE signed int | ||
32 | #define _FP_I_TYPE int | ||
33 | |||
34 | #define _FP_MUL_MEAT_S(R,X,Y) \ | ||
35 | _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm) | ||
36 | #define _FP_MUL_MEAT_D(R,X,Y) \ | ||
37 | _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) | ||
38 | #define _FP_MUL_MEAT_Q(R,X,Y) \ | ||
39 | _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) | ||
40 | |||
41 | #define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y) | ||
42 | #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y) | ||
43 | #define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y) | ||
44 | |||
45 | #define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1) | ||
46 | #define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1 | ||
47 | #define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1 | ||
48 | #define _FP_NANSIGN_S 0 | ||
49 | #define _FP_NANSIGN_D 0 | ||
50 | #define _FP_NANSIGN_Q 0 | ||
51 | |||
52 | #define _FP_KEEPNANFRACP 1 | ||
53 | |||
54 | /* | ||
55 | * If one NaN is signaling and the other is not, | ||
56 | * we choose that one, otherwise we choose X. | ||
57 | */ | ||
58 | #define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ | ||
59 | do { \ | ||
60 | if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \ | ||
61 | && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \ | ||
62 | { \ | ||
63 | R##_s = Y##_s; \ | ||
64 | _FP_FRAC_COPY_##wc(R,Y); \ | ||
65 | } \ | ||
66 | else \ | ||
67 | { \ | ||
68 | R##_s = X##_s; \ | ||
69 | _FP_FRAC_COPY_##wc(R,X); \ | ||
70 | } \ | ||
71 | R##_c = FP_CLS_NAN; \ | ||
72 | } while (0) | ||
73 | |||
74 | /* Some assembly to speed things up. */ | ||
75 | #define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) ({ \ | ||
76 | unsigned int __r2 = (x2) + (y2); \ | ||
77 | unsigned int __r1 = (x1); \ | ||
78 | unsigned int __r0 = (x0); \ | ||
79 | asm volatile( \ | ||
80 | " alr %2,%3\n" \ | ||
81 | " brc 12,0f\n" \ | ||
82 | " lhi 0,1\n" \ | ||
83 | " alr %1,0\n" \ | ||
84 | " brc 12,0f\n" \ | ||
85 | " alr %0,0\n" \ | ||
86 | "0:" \ | ||
87 | : "+&d" (__r2), "+&d" (__r1), "+&d" (__r0) \ | ||
88 | : "d" (y0), "i" (1) : "cc", "0" ); \ | ||
89 | asm volatile( \ | ||
90 | " alr %1,%2\n" \ | ||
91 | " brc 12,0f\n" \ | ||
92 | " ahi %0,1\n" \ | ||
93 | "0:" \ | ||
94 | : "+&d" (__r2), "+&d" (__r1) \ | ||
95 | : "d" (y1) : "cc"); \ | ||
96 | (r2) = __r2; \ | ||
97 | (r1) = __r1; \ | ||
98 | (r0) = __r0; \ | ||
99 | }) | ||
100 | |||
101 | #define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) ({ \ | ||
102 | unsigned int __r2 = (x2) - (y2); \ | ||
103 | unsigned int __r1 = (x1); \ | ||
104 | unsigned int __r0 = (x0); \ | ||
105 | asm volatile( \ | ||
106 | " slr %2,%3\n" \ | ||
107 | " brc 3,0f\n" \ | ||
108 | " lhi 0,1\n" \ | ||
109 | " slr %1,0\n" \ | ||
110 | " brc 3,0f\n" \ | ||
111 | " slr %0,0\n" \ | ||
112 | "0:" \ | ||
113 | : "+&d" (__r2), "+&d" (__r1), "+&d" (__r0) \ | ||
114 | : "d" (y0) : "cc", "0"); \ | ||
115 | asm volatile( \ | ||
116 | " slr %1,%2\n" \ | ||
117 | " brc 3,0f\n" \ | ||
118 | " ahi %0,-1\n" \ | ||
119 | "0:" \ | ||
120 | : "+&d" (__r2), "+&d" (__r1) \ | ||
121 | : "d" (y1) : "cc"); \ | ||
122 | (r2) = __r2; \ | ||
123 | (r1) = __r1; \ | ||
124 | (r0) = __r0; \ | ||
125 | }) | ||
126 | |||
127 | #define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) __FP_FRAC_SUB_3(x2,x1,x0,x2,x1,x0,y2,y1,y0) | ||
128 | |||
129 | /* Obtain the current rounding mode. */ | ||
130 | #define FP_ROUNDMODE mode | ||
131 | |||
132 | /* Exception flags. */ | ||
133 | #define FP_EX_INVALID 0x800000 | ||
134 | #define FP_EX_DIVZERO 0x400000 | ||
135 | #define FP_EX_OVERFLOW 0x200000 | ||
136 | #define FP_EX_UNDERFLOW 0x100000 | ||
137 | #define FP_EX_INEXACT 0x080000 | ||
138 | |||
139 | /* We write the results always */ | ||
140 | #define FP_INHIBIT_RESULTS 0 | ||
141 | |||
142 | #endif | ||
diff --git a/arch/s390/include/asm/sfp-util.h b/arch/s390/include/asm/sfp-util.h new file mode 100644 index 000000000000..0addc6466d95 --- /dev/null +++ b/arch/s390/include/asm/sfp-util.h | |||
@@ -0,0 +1,77 @@ | |||
1 | #include <linux/kernel.h> | ||
2 | #include <linux/sched.h> | ||
3 | #include <linux/types.h> | ||
4 | #include <asm/byteorder.h> | ||
5 | |||
6 | #define add_ssaaaa(sh, sl, ah, al, bh, bl) ({ \ | ||
7 | unsigned int __sh = (ah); \ | ||
8 | unsigned int __sl = (al); \ | ||
9 | asm volatile( \ | ||
10 | " alr %1,%3\n" \ | ||
11 | " brc 12,0f\n" \ | ||
12 | " ahi %0,1\n" \ | ||
13 | "0: alr %0,%2" \ | ||
14 | : "+&d" (__sh), "+d" (__sl) \ | ||
15 | : "d" (bh), "d" (bl) : "cc"); \ | ||
16 | (sh) = __sh; \ | ||
17 | (sl) = __sl; \ | ||
18 | }) | ||
19 | |||
20 | #define sub_ddmmss(sh, sl, ah, al, bh, bl) ({ \ | ||
21 | unsigned int __sh = (ah); \ | ||
22 | unsigned int __sl = (al); \ | ||
23 | asm volatile( \ | ||
24 | " slr %1,%3\n" \ | ||
25 | " brc 3,0f\n" \ | ||
26 | " ahi %0,-1\n" \ | ||
27 | "0: slr %0,%2" \ | ||
28 | : "+&d" (__sh), "+d" (__sl) \ | ||
29 | : "d" (bh), "d" (bl) : "cc"); \ | ||
30 | (sh) = __sh; \ | ||
31 | (sl) = __sl; \ | ||
32 | }) | ||
33 | |||
34 | /* a umul b = a mul b + (a>=2<<31) ? b<<32:0 + (b>=2<<31) ? a<<32:0 */ | ||
35 | #define umul_ppmm(wh, wl, u, v) ({ \ | ||
36 | unsigned int __wh = u; \ | ||
37 | unsigned int __wl = v; \ | ||
38 | asm volatile( \ | ||
39 | " ltr 1,%0\n" \ | ||
40 | " mr 0,%1\n" \ | ||
41 | " jnm 0f\n" \ | ||
42 | " alr 0,%1\n" \ | ||
43 | "0: ltr %1,%1\n" \ | ||
44 | " jnm 1f\n" \ | ||
45 | " alr 0,%0\n" \ | ||
46 | "1: lr %0,0\n" \ | ||
47 | " lr %1,1\n" \ | ||
48 | : "+d" (__wh), "+d" (__wl) \ | ||
49 | : : "0", "1", "cc"); \ | ||
50 | wh = __wh; \ | ||
51 | wl = __wl; \ | ||
52 | }) | ||
53 | |||
54 | #ifdef __s390x__ | ||
55 | #define udiv_qrnnd(q, r, n1, n0, d) \ | ||
56 | do { unsigned long __n; \ | ||
57 | unsigned int __r, __d; \ | ||
58 | __n = ((unsigned long)(n1) << 32) + n0; \ | ||
59 | __d = (d); \ | ||
60 | (q) = __n / __d; \ | ||
61 | (r) = __n % __d; \ | ||
62 | } while (0) | ||
63 | #else | ||
64 | #define udiv_qrnnd(q, r, n1, n0, d) \ | ||
65 | do { unsigned int __r; \ | ||
66 | (q) = __udiv_qrnnd (&__r, (n1), (n0), (d)); \ | ||
67 | (r) = __r; \ | ||
68 | } while (0) | ||
69 | extern unsigned long __udiv_qrnnd (unsigned int *, unsigned int, | ||
70 | unsigned int , unsigned int); | ||
71 | #endif | ||
72 | |||
73 | #define UDIV_NEEDS_NORMALIZATION 0 | ||
74 | |||
75 | #define abort() return 0 | ||
76 | |||
77 | #define __BYTE_ORDER __BIG_ENDIAN | ||
diff --git a/arch/s390/include/asm/shmbuf.h b/arch/s390/include/asm/shmbuf.h new file mode 100644 index 000000000000..eed2e280ce37 --- /dev/null +++ b/arch/s390/include/asm/shmbuf.h | |||
@@ -0,0 +1,48 @@ | |||
1 | #ifndef _S390_SHMBUF_H | ||
2 | #define _S390_SHMBUF_H | ||
3 | |||
4 | /* | ||
5 | * The shmid64_ds structure for S/390 architecture. | ||
6 | * Note extra padding because this structure is passed back and forth | ||
7 | * between kernel and user space. | ||
8 | * | ||
9 | * Pad space is left for: | ||
10 | * - 64-bit time_t to solve y2038 problem (for !__s390x__) | ||
11 | * - 2 miscellaneous 32-bit values | ||
12 | */ | ||
13 | |||
14 | struct shmid64_ds { | ||
15 | struct ipc64_perm shm_perm; /* operation perms */ | ||
16 | size_t shm_segsz; /* size of segment (bytes) */ | ||
17 | __kernel_time_t shm_atime; /* last attach time */ | ||
18 | #ifndef __s390x__ | ||
19 | unsigned long __unused1; | ||
20 | #endif /* ! __s390x__ */ | ||
21 | __kernel_time_t shm_dtime; /* last detach time */ | ||
22 | #ifndef __s390x__ | ||
23 | unsigned long __unused2; | ||
24 | #endif /* ! __s390x__ */ | ||
25 | __kernel_time_t shm_ctime; /* last change time */ | ||
26 | #ifndef __s390x__ | ||
27 | unsigned long __unused3; | ||
28 | #endif /* ! __s390x__ */ | ||
29 | __kernel_pid_t shm_cpid; /* pid of creator */ | ||
30 | __kernel_pid_t shm_lpid; /* pid of last operator */ | ||
31 | unsigned long shm_nattch; /* no. of current attaches */ | ||
32 | unsigned long __unused4; | ||
33 | unsigned long __unused5; | ||
34 | }; | ||
35 | |||
36 | struct shminfo64 { | ||
37 | unsigned long shmmax; | ||
38 | unsigned long shmmin; | ||
39 | unsigned long shmmni; | ||
40 | unsigned long shmseg; | ||
41 | unsigned long shmall; | ||
42 | unsigned long __unused1; | ||
43 | unsigned long __unused2; | ||
44 | unsigned long __unused3; | ||
45 | unsigned long __unused4; | ||
46 | }; | ||
47 | |||
48 | #endif /* _S390_SHMBUF_H */ | ||
diff --git a/arch/s390/include/asm/shmparam.h b/arch/s390/include/asm/shmparam.h new file mode 100644 index 000000000000..c2e0c0508e73 --- /dev/null +++ b/arch/s390/include/asm/shmparam.h | |||
@@ -0,0 +1,13 @@ | |||
1 | /* | ||
2 | * include/asm-s390/shmparam.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/shmparam.h" | ||
7 | */ | ||
8 | #ifndef _ASM_S390_SHMPARAM_H | ||
9 | #define _ASM_S390_SHMPARAM_H | ||
10 | |||
11 | #define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ | ||
12 | |||
13 | #endif /* _ASM_S390_SHMPARAM_H */ | ||
diff --git a/arch/s390/include/asm/sigcontext.h b/arch/s390/include/asm/sigcontext.h new file mode 100644 index 000000000000..aeb6e0b13329 --- /dev/null +++ b/arch/s390/include/asm/sigcontext.h | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * include/asm-s390/sigcontext.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_S390_SIGCONTEXT_H | ||
9 | #define _ASM_S390_SIGCONTEXT_H | ||
10 | |||
11 | #include <linux/compiler.h> | ||
12 | |||
13 | #define __NUM_GPRS 16 | ||
14 | #define __NUM_FPRS 16 | ||
15 | #define __NUM_ACRS 16 | ||
16 | |||
17 | #ifndef __s390x__ | ||
18 | |||
19 | /* Has to be at least _NSIG_WORDS from asm/signal.h */ | ||
20 | #define _SIGCONTEXT_NSIG 64 | ||
21 | #define _SIGCONTEXT_NSIG_BPW 32 | ||
22 | /* Size of stack frame allocated when calling signal handler. */ | ||
23 | #define __SIGNAL_FRAMESIZE 96 | ||
24 | |||
25 | #else /* __s390x__ */ | ||
26 | |||
27 | /* Has to be at least _NSIG_WORDS from asm/signal.h */ | ||
28 | #define _SIGCONTEXT_NSIG 64 | ||
29 | #define _SIGCONTEXT_NSIG_BPW 64 | ||
30 | /* Size of stack frame allocated when calling signal handler. */ | ||
31 | #define __SIGNAL_FRAMESIZE 160 | ||
32 | |||
33 | #endif /* __s390x__ */ | ||
34 | |||
35 | #define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW) | ||
36 | #define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS) | ||
37 | |||
38 | typedef struct | ||
39 | { | ||
40 | unsigned long mask; | ||
41 | unsigned long addr; | ||
42 | } __attribute__ ((aligned(8))) _psw_t; | ||
43 | |||
44 | typedef struct | ||
45 | { | ||
46 | _psw_t psw; | ||
47 | unsigned long gprs[__NUM_GPRS]; | ||
48 | unsigned int acrs[__NUM_ACRS]; | ||
49 | } _s390_regs_common; | ||
50 | |||
51 | typedef struct | ||
52 | { | ||
53 | unsigned int fpc; | ||
54 | double fprs[__NUM_FPRS]; | ||
55 | } _s390_fp_regs; | ||
56 | |||
57 | typedef struct | ||
58 | { | ||
59 | _s390_regs_common regs; | ||
60 | _s390_fp_regs fpregs; | ||
61 | } _sigregs; | ||
62 | |||
63 | struct sigcontext | ||
64 | { | ||
65 | unsigned long oldmask[_SIGCONTEXT_NSIG_WORDS]; | ||
66 | _sigregs __user *sregs; | ||
67 | }; | ||
68 | |||
69 | |||
70 | #endif | ||
71 | |||
diff --git a/arch/s390/include/asm/siginfo.h b/arch/s390/include/asm/siginfo.h new file mode 100644 index 000000000000..e0ff1ab054be --- /dev/null +++ b/arch/s390/include/asm/siginfo.h | |||
@@ -0,0 +1,18 @@ | |||
1 | /* | ||
2 | * include/asm-s390/siginfo.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/siginfo.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef _S390_SIGINFO_H | ||
10 | #define _S390_SIGINFO_H | ||
11 | |||
12 | #ifdef __s390x__ | ||
13 | #define __ARCH_SI_PREAMBLE_SIZE (4 * sizeof(int)) | ||
14 | #endif | ||
15 | |||
16 | #include <asm-generic/siginfo.h> | ||
17 | |||
18 | #endif | ||
diff --git a/arch/s390/include/asm/signal.h b/arch/s390/include/asm/signal.h new file mode 100644 index 000000000000..f6cfddb278cb --- /dev/null +++ b/arch/s390/include/asm/signal.h | |||
@@ -0,0 +1,172 @@ | |||
1 | /* | ||
2 | * include/asm-s390/signal.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/signal.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef _ASMS390_SIGNAL_H | ||
10 | #define _ASMS390_SIGNAL_H | ||
11 | |||
12 | #include <linux/types.h> | ||
13 | #include <linux/time.h> | ||
14 | |||
15 | /* Avoid too many header ordering problems. */ | ||
16 | struct siginfo; | ||
17 | struct pt_regs; | ||
18 | |||
19 | #ifdef __KERNEL__ | ||
20 | /* Most things should be clean enough to redefine this at will, if care | ||
21 | is taken to make libc match. */ | ||
22 | #include <asm/sigcontext.h> | ||
23 | #define _NSIG _SIGCONTEXT_NSIG | ||
24 | #define _NSIG_BPW _SIGCONTEXT_NSIG_BPW | ||
25 | #define _NSIG_WORDS _SIGCONTEXT_NSIG_WORDS | ||
26 | |||
27 | typedef unsigned long old_sigset_t; /* at least 32 bits */ | ||
28 | |||
29 | typedef struct { | ||
30 | unsigned long sig[_NSIG_WORDS]; | ||
31 | } sigset_t; | ||
32 | |||
33 | #else | ||
34 | /* Here we must cater to libcs that poke about in kernel headers. */ | ||
35 | |||
36 | #define NSIG 32 | ||
37 | typedef unsigned long sigset_t; | ||
38 | |||
39 | #endif /* __KERNEL__ */ | ||
40 | |||
41 | #define SIGHUP 1 | ||
42 | #define SIGINT 2 | ||
43 | #define SIGQUIT 3 | ||
44 | #define SIGILL 4 | ||
45 | #define SIGTRAP 5 | ||
46 | #define SIGABRT 6 | ||
47 | #define SIGIOT 6 | ||
48 | #define SIGBUS 7 | ||
49 | #define SIGFPE 8 | ||
50 | #define SIGKILL 9 | ||
51 | #define SIGUSR1 10 | ||
52 | #define SIGSEGV 11 | ||
53 | #define SIGUSR2 12 | ||
54 | #define SIGPIPE 13 | ||
55 | #define SIGALRM 14 | ||
56 | #define SIGTERM 15 | ||
57 | #define SIGSTKFLT 16 | ||
58 | #define SIGCHLD 17 | ||
59 | #define SIGCONT 18 | ||
60 | #define SIGSTOP 19 | ||
61 | #define SIGTSTP 20 | ||
62 | #define SIGTTIN 21 | ||
63 | #define SIGTTOU 22 | ||
64 | #define SIGURG 23 | ||
65 | #define SIGXCPU 24 | ||
66 | #define SIGXFSZ 25 | ||
67 | #define SIGVTALRM 26 | ||
68 | #define SIGPROF 27 | ||
69 | #define SIGWINCH 28 | ||
70 | #define SIGIO 29 | ||
71 | #define SIGPOLL SIGIO | ||
72 | /* | ||
73 | #define SIGLOST 29 | ||
74 | */ | ||
75 | #define SIGPWR 30 | ||
76 | #define SIGSYS 31 | ||
77 | #define SIGUNUSED 31 | ||
78 | |||
79 | /* These should not be considered constants from userland. */ | ||
80 | #define SIGRTMIN 32 | ||
81 | #define SIGRTMAX _NSIG | ||
82 | |||
83 | /* | ||
84 | * SA_FLAGS values: | ||
85 | * | ||
86 | * SA_ONSTACK indicates that a registered stack_t will be used. | ||
87 | * SA_RESTART flag to get restarting signals (which were the default long ago) | ||
88 | * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. | ||
89 | * SA_RESETHAND clears the handler when the signal is delivered. | ||
90 | * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. | ||
91 | * SA_NODEFER prevents the current signal from being masked in the handler. | ||
92 | * | ||
93 | * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single | ||
94 | * Unix names RESETHAND and NODEFER respectively. | ||
95 | */ | ||
96 | #define SA_NOCLDSTOP 0x00000001 | ||
97 | #define SA_NOCLDWAIT 0x00000002 | ||
98 | #define SA_SIGINFO 0x00000004 | ||
99 | #define SA_ONSTACK 0x08000000 | ||
100 | #define SA_RESTART 0x10000000 | ||
101 | #define SA_NODEFER 0x40000000 | ||
102 | #define SA_RESETHAND 0x80000000 | ||
103 | |||
104 | #define SA_NOMASK SA_NODEFER | ||
105 | #define SA_ONESHOT SA_RESETHAND | ||
106 | |||
107 | #define SA_RESTORER 0x04000000 | ||
108 | |||
109 | /* | ||
110 | * sigaltstack controls | ||
111 | */ | ||
112 | #define SS_ONSTACK 1 | ||
113 | #define SS_DISABLE 2 | ||
114 | |||
115 | #define MINSIGSTKSZ 2048 | ||
116 | #define SIGSTKSZ 8192 | ||
117 | |||
118 | #include <asm-generic/signal.h> | ||
119 | |||
120 | #ifdef __KERNEL__ | ||
121 | struct old_sigaction { | ||
122 | __sighandler_t sa_handler; | ||
123 | old_sigset_t sa_mask; | ||
124 | unsigned long sa_flags; | ||
125 | void (*sa_restorer)(void); | ||
126 | }; | ||
127 | |||
128 | struct sigaction { | ||
129 | __sighandler_t sa_handler; | ||
130 | unsigned long sa_flags; | ||
131 | void (*sa_restorer)(void); | ||
132 | sigset_t sa_mask; /* mask last for extensibility */ | ||
133 | }; | ||
134 | |||
135 | struct k_sigaction { | ||
136 | struct sigaction sa; | ||
137 | }; | ||
138 | |||
139 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) | ||
140 | |||
141 | #else | ||
142 | /* Here we must cater to libcs that poke about in kernel headers. */ | ||
143 | |||
144 | struct sigaction { | ||
145 | union { | ||
146 | __sighandler_t _sa_handler; | ||
147 | void (*_sa_sigaction)(int, struct siginfo *, void *); | ||
148 | } _u; | ||
149 | #ifndef __s390x__ /* lovely */ | ||
150 | sigset_t sa_mask; | ||
151 | unsigned long sa_flags; | ||
152 | void (*sa_restorer)(void); | ||
153 | #else /* __s390x__ */ | ||
154 | unsigned long sa_flags; | ||
155 | void (*sa_restorer)(void); | ||
156 | sigset_t sa_mask; | ||
157 | #endif /* __s390x__ */ | ||
158 | }; | ||
159 | |||
160 | #define sa_handler _u._sa_handler | ||
161 | #define sa_sigaction _u._sa_sigaction | ||
162 | |||
163 | #endif /* __KERNEL__ */ | ||
164 | |||
165 | typedef struct sigaltstack { | ||
166 | void __user *ss_sp; | ||
167 | int ss_flags; | ||
168 | size_t ss_size; | ||
169 | } stack_t; | ||
170 | |||
171 | |||
172 | #endif | ||
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h new file mode 100644 index 000000000000..e16d56f8dfe1 --- /dev/null +++ b/arch/s390/include/asm/sigp.h | |||
@@ -0,0 +1,126 @@ | |||
1 | /* | ||
2 | * include/asm-s390/sigp.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), | ||
7 | * Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
8 | * Heiko Carstens (heiko.carstens@de.ibm.com) | ||
9 | * | ||
10 | * sigp.h by D.J. Barrow (c) IBM 1999 | ||
11 | * contains routines / structures for signalling other S/390 processors in an | ||
12 | * SMP configuration. | ||
13 | */ | ||
14 | |||
15 | #ifndef __SIGP__ | ||
16 | #define __SIGP__ | ||
17 | |||
18 | #include <asm/ptrace.h> | ||
19 | #include <asm/atomic.h> | ||
20 | |||
21 | /* get real cpu address from logical cpu number */ | ||
22 | extern volatile int __cpu_logical_map[]; | ||
23 | |||
24 | typedef enum | ||
25 | { | ||
26 | sigp_unassigned=0x0, | ||
27 | sigp_sense, | ||
28 | sigp_external_call, | ||
29 | sigp_emergency_signal, | ||
30 | sigp_start, | ||
31 | sigp_stop, | ||
32 | sigp_restart, | ||
33 | sigp_unassigned1, | ||
34 | sigp_unassigned2, | ||
35 | sigp_stop_and_store_status, | ||
36 | sigp_unassigned3, | ||
37 | sigp_initial_cpu_reset, | ||
38 | sigp_cpu_reset, | ||
39 | sigp_set_prefix, | ||
40 | sigp_store_status_at_address, | ||
41 | sigp_store_extended_status_at_address | ||
42 | } sigp_order_code; | ||
43 | |||
44 | typedef __u32 sigp_status_word; | ||
45 | |||
46 | typedef enum | ||
47 | { | ||
48 | sigp_order_code_accepted=0, | ||
49 | sigp_status_stored, | ||
50 | sigp_busy, | ||
51 | sigp_not_operational | ||
52 | } sigp_ccode; | ||
53 | |||
54 | |||
55 | /* | ||
56 | * Definitions for the external call | ||
57 | */ | ||
58 | |||
59 | /* 'Bit' signals, asynchronous */ | ||
60 | typedef enum | ||
61 | { | ||
62 | ec_schedule=0, | ||
63 | ec_call_function, | ||
64 | ec_bit_last | ||
65 | } ec_bit_sig; | ||
66 | |||
67 | /* | ||
68 | * Signal processor | ||
69 | */ | ||
70 | static inline sigp_ccode | ||
71 | signal_processor(__u16 cpu_addr, sigp_order_code order_code) | ||
72 | { | ||
73 | register unsigned long reg1 asm ("1") = 0; | ||
74 | sigp_ccode ccode; | ||
75 | |||
76 | asm volatile( | ||
77 | " sigp %1,%2,0(%3)\n" | ||
78 | " ipm %0\n" | ||
79 | " srl %0,28\n" | ||
80 | : "=d" (ccode) | ||
81 | : "d" (reg1), "d" (__cpu_logical_map[cpu_addr]), | ||
82 | "a" (order_code) : "cc" , "memory"); | ||
83 | return ccode; | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * Signal processor with parameter | ||
88 | */ | ||
89 | static inline sigp_ccode | ||
90 | signal_processor_p(__u32 parameter, __u16 cpu_addr, sigp_order_code order_code) | ||
91 | { | ||
92 | register unsigned int reg1 asm ("1") = parameter; | ||
93 | sigp_ccode ccode; | ||
94 | |||
95 | asm volatile( | ||
96 | " sigp %1,%2,0(%3)\n" | ||
97 | " ipm %0\n" | ||
98 | " srl %0,28\n" | ||
99 | : "=d" (ccode) | ||
100 | : "d" (reg1), "d" (__cpu_logical_map[cpu_addr]), | ||
101 | "a" (order_code) : "cc" , "memory"); | ||
102 | return ccode; | ||
103 | } | ||
104 | |||
105 | /* | ||
106 | * Signal processor with parameter and return status | ||
107 | */ | ||
108 | static inline sigp_ccode | ||
109 | signal_processor_ps(__u32 *statusptr, __u32 parameter, __u16 cpu_addr, | ||
110 | sigp_order_code order_code) | ||
111 | { | ||
112 | register unsigned int reg1 asm ("1") = parameter; | ||
113 | sigp_ccode ccode; | ||
114 | |||
115 | asm volatile( | ||
116 | " sigp %1,%2,0(%3)\n" | ||
117 | " ipm %0\n" | ||
118 | " srl %0,28\n" | ||
119 | : "=d" (ccode), "+d" (reg1) | ||
120 | : "d" (__cpu_logical_map[cpu_addr]), "a" (order_code) | ||
121 | : "cc" , "memory"); | ||
122 | *statusptr = reg1; | ||
123 | return ccode; | ||
124 | } | ||
125 | |||
126 | #endif /* __SIGP__ */ | ||
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h new file mode 100644 index 000000000000..ae89cf2478fc --- /dev/null +++ b/arch/s390/include/asm/smp.h | |||
@@ -0,0 +1,116 @@ | |||
1 | /* | ||
2 | * include/asm-s390/smp.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Denis Joseph Barrow (djbarrow@de.ibm.com,barrow_dj@yahoo.com), | ||
7 | * Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
8 | * Heiko Carstens (heiko.carstens@de.ibm.com) | ||
9 | */ | ||
10 | #ifndef __ASM_SMP_H | ||
11 | #define __ASM_SMP_H | ||
12 | |||
13 | #include <linux/threads.h> | ||
14 | #include <linux/cpumask.h> | ||
15 | #include <linux/bitops.h> | ||
16 | |||
17 | #if defined(__KERNEL__) && defined(CONFIG_SMP) && !defined(__ASSEMBLY__) | ||
18 | |||
19 | #include <asm/lowcore.h> | ||
20 | #include <asm/sigp.h> | ||
21 | #include <asm/ptrace.h> | ||
22 | #include <asm/system.h> | ||
23 | |||
24 | /* | ||
25 | s390 specific smp.c headers | ||
26 | */ | ||
27 | typedef struct | ||
28 | { | ||
29 | int intresting; | ||
30 | sigp_ccode ccode; | ||
31 | __u32 status; | ||
32 | __u16 cpu; | ||
33 | } sigp_info; | ||
34 | |||
35 | extern void machine_restart_smp(char *); | ||
36 | extern void machine_halt_smp(void); | ||
37 | extern void machine_power_off_smp(void); | ||
38 | |||
39 | #define NO_PROC_ID 0xFF /* No processor magic marker */ | ||
40 | |||
41 | /* | ||
42 | * This magic constant controls our willingness to transfer | ||
43 | * a process across CPUs. Such a transfer incurs misses on the L1 | ||
44 | * cache, and on a P6 or P5 with multiple L2 caches L2 hits. My | ||
45 | * gut feeling is this will vary by board in value. For a board | ||
46 | * with separate L2 cache it probably depends also on the RSS, and | ||
47 | * for a board with shared L2 cache it ought to decay fast as other | ||
48 | * processes are run. | ||
49 | */ | ||
50 | |||
51 | #define PROC_CHANGE_PENALTY 20 /* Schedule penalty */ | ||
52 | |||
53 | #define raw_smp_processor_id() (S390_lowcore.cpu_data.cpu_nr) | ||
54 | |||
55 | static inline __u16 hard_smp_processor_id(void) | ||
56 | { | ||
57 | return stap(); | ||
58 | } | ||
59 | |||
60 | /* | ||
61 | * returns 1 if cpu is in stopped/check stopped state or not operational | ||
62 | * returns 0 otherwise | ||
63 | */ | ||
64 | static inline int | ||
65 | smp_cpu_not_running(int cpu) | ||
66 | { | ||
67 | __u32 status; | ||
68 | |||
69 | switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { | ||
70 | case sigp_order_code_accepted: | ||
71 | case sigp_status_stored: | ||
72 | /* Check for stopped and check stop state */ | ||
73 | if (status & 0x50) | ||
74 | return 1; | ||
75 | break; | ||
76 | case sigp_not_operational: | ||
77 | return 1; | ||
78 | default: | ||
79 | break; | ||
80 | } | ||
81 | return 0; | ||
82 | } | ||
83 | |||
84 | #define cpu_logical_map(cpu) (cpu) | ||
85 | |||
86 | extern int __cpu_disable (void); | ||
87 | extern void __cpu_die (unsigned int cpu); | ||
88 | extern void cpu_die (void) __attribute__ ((noreturn)); | ||
89 | extern int __cpu_up (unsigned int cpu); | ||
90 | |||
91 | extern struct mutex smp_cpu_state_mutex; | ||
92 | extern int smp_cpu_polarization[]; | ||
93 | |||
94 | extern int smp_call_function_mask(cpumask_t mask, void (*func)(void *), | ||
95 | void *info, int wait); | ||
96 | #endif | ||
97 | |||
98 | #ifndef CONFIG_SMP | ||
99 | static inline void smp_send_stop(void) | ||
100 | { | ||
101 | /* Disable all interrupts/machine checks */ | ||
102 | __load_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK); | ||
103 | } | ||
104 | |||
105 | #define hard_smp_processor_id() 0 | ||
106 | #define smp_cpu_not_running(cpu) 1 | ||
107 | #endif | ||
108 | |||
109 | #ifdef CONFIG_HOTPLUG_CPU | ||
110 | extern int smp_rescan_cpus(void); | ||
111 | #else | ||
112 | static inline int smp_rescan_cpus(void) { return 0; } | ||
113 | #endif | ||
114 | |||
115 | extern union save_area *zfcpdump_save_areas[NR_CPUS + 1]; | ||
116 | #endif | ||
diff --git a/arch/s390/include/asm/socket.h b/arch/s390/include/asm/socket.h new file mode 100644 index 000000000000..c786ab623b2d --- /dev/null +++ b/arch/s390/include/asm/socket.h | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * include/asm-s390/socket.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/socket.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef _ASM_SOCKET_H | ||
10 | #define _ASM_SOCKET_H | ||
11 | |||
12 | #include <asm/sockios.h> | ||
13 | |||
14 | /* For setsockopt(2) */ | ||
15 | #define SOL_SOCKET 1 | ||
16 | |||
17 | #define SO_DEBUG 1 | ||
18 | #define SO_REUSEADDR 2 | ||
19 | #define SO_TYPE 3 | ||
20 | #define SO_ERROR 4 | ||
21 | #define SO_DONTROUTE 5 | ||
22 | #define SO_BROADCAST 6 | ||
23 | #define SO_SNDBUF 7 | ||
24 | #define SO_RCVBUF 8 | ||
25 | #define SO_SNDBUFFORCE 32 | ||
26 | #define SO_RCVBUFFORCE 33 | ||
27 | #define SO_KEEPALIVE 9 | ||
28 | #define SO_OOBINLINE 10 | ||
29 | #define SO_NO_CHECK 11 | ||
30 | #define SO_PRIORITY 12 | ||
31 | #define SO_LINGER 13 | ||
32 | #define SO_BSDCOMPAT 14 | ||
33 | /* To add :#define SO_REUSEPORT 15 */ | ||
34 | #define SO_PASSCRED 16 | ||
35 | #define SO_PEERCRED 17 | ||
36 | #define SO_RCVLOWAT 18 | ||
37 | #define SO_SNDLOWAT 19 | ||
38 | #define SO_RCVTIMEO 20 | ||
39 | #define SO_SNDTIMEO 21 | ||
40 | |||
41 | /* Security levels - as per NRL IPv6 - don't actually do anything */ | ||
42 | #define SO_SECURITY_AUTHENTICATION 22 | ||
43 | #define SO_SECURITY_ENCRYPTION_TRANSPORT 23 | ||
44 | #define SO_SECURITY_ENCRYPTION_NETWORK 24 | ||
45 | |||
46 | #define SO_BINDTODEVICE 25 | ||
47 | |||
48 | /* Socket filtering */ | ||
49 | #define SO_ATTACH_FILTER 26 | ||
50 | #define SO_DETACH_FILTER 27 | ||
51 | |||
52 | #define SO_PEERNAME 28 | ||
53 | #define SO_TIMESTAMP 29 | ||
54 | #define SCM_TIMESTAMP SO_TIMESTAMP | ||
55 | |||
56 | #define SO_ACCEPTCONN 30 | ||
57 | |||
58 | #define SO_PEERSEC 31 | ||
59 | #define SO_PASSSEC 34 | ||
60 | #define SO_TIMESTAMPNS 35 | ||
61 | #define SCM_TIMESTAMPNS SO_TIMESTAMPNS | ||
62 | |||
63 | #define SO_MARK 36 | ||
64 | |||
65 | #endif /* _ASM_SOCKET_H */ | ||
diff --git a/arch/s390/include/asm/sockios.h b/arch/s390/include/asm/sockios.h new file mode 100644 index 000000000000..f4fc16c7da59 --- /dev/null +++ b/arch/s390/include/asm/sockios.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * include/asm-s390/sockios.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/sockios.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef __ARCH_S390_SOCKIOS__ | ||
10 | #define __ARCH_S390_SOCKIOS__ | ||
11 | |||
12 | /* Socket-level I/O control calls. */ | ||
13 | #define FIOSETOWN 0x8901 | ||
14 | #define SIOCSPGRP 0x8902 | ||
15 | #define FIOGETOWN 0x8903 | ||
16 | #define SIOCGPGRP 0x8904 | ||
17 | #define SIOCATMARK 0x8905 | ||
18 | #define SIOCGSTAMP 0x8906 /* Get stamp (timeval) */ | ||
19 | #define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ | ||
20 | |||
21 | #endif | ||
diff --git a/arch/s390/include/asm/sparsemem.h b/arch/s390/include/asm/sparsemem.h new file mode 100644 index 000000000000..545d219e6a2d --- /dev/null +++ b/arch/s390/include/asm/sparsemem.h | |||
@@ -0,0 +1,18 @@ | |||
1 | #ifndef _ASM_S390_SPARSEMEM_H | ||
2 | #define _ASM_S390_SPARSEMEM_H | ||
3 | |||
4 | #ifdef CONFIG_64BIT | ||
5 | |||
6 | #define SECTION_SIZE_BITS 28 | ||
7 | #define MAX_PHYSADDR_BITS 42 | ||
8 | #define MAX_PHYSMEM_BITS 42 | ||
9 | |||
10 | #else | ||
11 | |||
12 | #define SECTION_SIZE_BITS 25 | ||
13 | #define MAX_PHYSADDR_BITS 31 | ||
14 | #define MAX_PHYSMEM_BITS 31 | ||
15 | |||
16 | #endif /* CONFIG_64BIT */ | ||
17 | |||
18 | #endif /* _ASM_S390_SPARSEMEM_H */ | ||
diff --git a/arch/s390/include/asm/spinlock.h b/arch/s390/include/asm/spinlock.h new file mode 100644 index 000000000000..df84ae96915f --- /dev/null +++ b/arch/s390/include/asm/spinlock.h | |||
@@ -0,0 +1,178 @@ | |||
1 | /* | ||
2 | * include/asm-s390/spinlock.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
7 | * | ||
8 | * Derived from "include/asm-i386/spinlock.h" | ||
9 | */ | ||
10 | |||
11 | #ifndef __ASM_SPINLOCK_H | ||
12 | #define __ASM_SPINLOCK_H | ||
13 | |||
14 | #include <linux/smp.h> | ||
15 | |||
16 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | ||
17 | |||
18 | static inline int | ||
19 | _raw_compare_and_swap(volatile unsigned int *lock, | ||
20 | unsigned int old, unsigned int new) | ||
21 | { | ||
22 | asm volatile( | ||
23 | " cs %0,%3,%1" | ||
24 | : "=d" (old), "=Q" (*lock) | ||
25 | : "0" (old), "d" (new), "Q" (*lock) | ||
26 | : "cc", "memory" ); | ||
27 | return old; | ||
28 | } | ||
29 | |||
30 | #else /* __GNUC__ */ | ||
31 | |||
32 | static inline int | ||
33 | _raw_compare_and_swap(volatile unsigned int *lock, | ||
34 | unsigned int old, unsigned int new) | ||
35 | { | ||
36 | asm volatile( | ||
37 | " cs %0,%3,0(%4)" | ||
38 | : "=d" (old), "=m" (*lock) | ||
39 | : "0" (old), "d" (new), "a" (lock), "m" (*lock) | ||
40 | : "cc", "memory" ); | ||
41 | return old; | ||
42 | } | ||
43 | |||
44 | #endif /* __GNUC__ */ | ||
45 | |||
46 | /* | ||
47 | * Simple spin lock operations. There are two variants, one clears IRQ's | ||
48 | * on the local processor, one does not. | ||
49 | * | ||
50 | * We make no fairness assumptions. They have a cost. | ||
51 | * | ||
52 | * (the type definitions are in asm/spinlock_types.h) | ||
53 | */ | ||
54 | |||
55 | #define __raw_spin_is_locked(x) ((x)->owner_cpu != 0) | ||
56 | #define __raw_spin_unlock_wait(lock) \ | ||
57 | do { while (__raw_spin_is_locked(lock)) \ | ||
58 | _raw_spin_relax(lock); } while (0) | ||
59 | |||
60 | extern void _raw_spin_lock_wait(raw_spinlock_t *); | ||
61 | extern void _raw_spin_lock_wait_flags(raw_spinlock_t *, unsigned long flags); | ||
62 | extern int _raw_spin_trylock_retry(raw_spinlock_t *); | ||
63 | extern void _raw_spin_relax(raw_spinlock_t *lock); | ||
64 | |||
65 | static inline void __raw_spin_lock(raw_spinlock_t *lp) | ||
66 | { | ||
67 | int old; | ||
68 | |||
69 | old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); | ||
70 | if (likely(old == 0)) | ||
71 | return; | ||
72 | _raw_spin_lock_wait(lp); | ||
73 | } | ||
74 | |||
75 | static inline void __raw_spin_lock_flags(raw_spinlock_t *lp, | ||
76 | unsigned long flags) | ||
77 | { | ||
78 | int old; | ||
79 | |||
80 | old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); | ||
81 | if (likely(old == 0)) | ||
82 | return; | ||
83 | _raw_spin_lock_wait_flags(lp, flags); | ||
84 | } | ||
85 | |||
86 | static inline int __raw_spin_trylock(raw_spinlock_t *lp) | ||
87 | { | ||
88 | int old; | ||
89 | |||
90 | old = _raw_compare_and_swap(&lp->owner_cpu, 0, ~smp_processor_id()); | ||
91 | if (likely(old == 0)) | ||
92 | return 1; | ||
93 | return _raw_spin_trylock_retry(lp); | ||
94 | } | ||
95 | |||
96 | static inline void __raw_spin_unlock(raw_spinlock_t *lp) | ||
97 | { | ||
98 | _raw_compare_and_swap(&lp->owner_cpu, lp->owner_cpu, 0); | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * Read-write spinlocks, allowing multiple readers | ||
103 | * but only one writer. | ||
104 | * | ||
105 | * NOTE! it is quite common to have readers in interrupts | ||
106 | * but no interrupt writers. For those circumstances we | ||
107 | * can "mix" irq-safe locks - any writer needs to get a | ||
108 | * irq-safe write-lock, but readers can get non-irqsafe | ||
109 | * read-locks. | ||
110 | */ | ||
111 | |||
112 | /** | ||
113 | * read_can_lock - would read_trylock() succeed? | ||
114 | * @lock: the rwlock in question. | ||
115 | */ | ||
116 | #define __raw_read_can_lock(x) ((int)(x)->lock >= 0) | ||
117 | |||
118 | /** | ||
119 | * write_can_lock - would write_trylock() succeed? | ||
120 | * @lock: the rwlock in question. | ||
121 | */ | ||
122 | #define __raw_write_can_lock(x) ((x)->lock == 0) | ||
123 | |||
124 | extern void _raw_read_lock_wait(raw_rwlock_t *lp); | ||
125 | extern int _raw_read_trylock_retry(raw_rwlock_t *lp); | ||
126 | extern void _raw_write_lock_wait(raw_rwlock_t *lp); | ||
127 | extern int _raw_write_trylock_retry(raw_rwlock_t *lp); | ||
128 | |||
129 | static inline void __raw_read_lock(raw_rwlock_t *rw) | ||
130 | { | ||
131 | unsigned int old; | ||
132 | old = rw->lock & 0x7fffffffU; | ||
133 | if (_raw_compare_and_swap(&rw->lock, old, old + 1) != old) | ||
134 | _raw_read_lock_wait(rw); | ||
135 | } | ||
136 | |||
137 | static inline void __raw_read_unlock(raw_rwlock_t *rw) | ||
138 | { | ||
139 | unsigned int old, cmp; | ||
140 | |||
141 | old = rw->lock; | ||
142 | do { | ||
143 | cmp = old; | ||
144 | old = _raw_compare_and_swap(&rw->lock, old, old - 1); | ||
145 | } while (cmp != old); | ||
146 | } | ||
147 | |||
148 | static inline void __raw_write_lock(raw_rwlock_t *rw) | ||
149 | { | ||
150 | if (unlikely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) != 0)) | ||
151 | _raw_write_lock_wait(rw); | ||
152 | } | ||
153 | |||
154 | static inline void __raw_write_unlock(raw_rwlock_t *rw) | ||
155 | { | ||
156 | _raw_compare_and_swap(&rw->lock, 0x80000000, 0); | ||
157 | } | ||
158 | |||
159 | static inline int __raw_read_trylock(raw_rwlock_t *rw) | ||
160 | { | ||
161 | unsigned int old; | ||
162 | old = rw->lock & 0x7fffffffU; | ||
163 | if (likely(_raw_compare_and_swap(&rw->lock, old, old + 1) == old)) | ||
164 | return 1; | ||
165 | return _raw_read_trylock_retry(rw); | ||
166 | } | ||
167 | |||
168 | static inline int __raw_write_trylock(raw_rwlock_t *rw) | ||
169 | { | ||
170 | if (likely(_raw_compare_and_swap(&rw->lock, 0, 0x80000000) == 0)) | ||
171 | return 1; | ||
172 | return _raw_write_trylock_retry(rw); | ||
173 | } | ||
174 | |||
175 | #define _raw_read_relax(lock) cpu_relax() | ||
176 | #define _raw_write_relax(lock) cpu_relax() | ||
177 | |||
178 | #endif /* __ASM_SPINLOCK_H */ | ||
diff --git a/arch/s390/include/asm/spinlock_types.h b/arch/s390/include/asm/spinlock_types.h new file mode 100644 index 000000000000..654abc40de04 --- /dev/null +++ b/arch/s390/include/asm/spinlock_types.h | |||
@@ -0,0 +1,20 @@ | |||
1 | #ifndef __ASM_SPINLOCK_TYPES_H | ||
2 | #define __ASM_SPINLOCK_TYPES_H | ||
3 | |||
4 | #ifndef __LINUX_SPINLOCK_TYPES_H | ||
5 | # error "please don't include this file directly" | ||
6 | #endif | ||
7 | |||
8 | typedef struct { | ||
9 | volatile unsigned int owner_cpu; | ||
10 | } __attribute__ ((aligned (4))) raw_spinlock_t; | ||
11 | |||
12 | #define __RAW_SPIN_LOCK_UNLOCKED { 0 } | ||
13 | |||
14 | typedef struct { | ||
15 | volatile unsigned int lock; | ||
16 | } raw_rwlock_t; | ||
17 | |||
18 | #define __RAW_RW_LOCK_UNLOCKED { 0 } | ||
19 | |||
20 | #endif | ||
diff --git a/arch/s390/include/asm/stat.h b/arch/s390/include/asm/stat.h new file mode 100644 index 000000000000..d92959eebb65 --- /dev/null +++ b/arch/s390/include/asm/stat.h | |||
@@ -0,0 +1,105 @@ | |||
1 | /* | ||
2 | * include/asm-s390/stat.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/stat.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef _S390_STAT_H | ||
10 | #define _S390_STAT_H | ||
11 | |||
12 | #ifndef __s390x__ | ||
13 | struct __old_kernel_stat { | ||
14 | unsigned short st_dev; | ||
15 | unsigned short st_ino; | ||
16 | unsigned short st_mode; | ||
17 | unsigned short st_nlink; | ||
18 | unsigned short st_uid; | ||
19 | unsigned short st_gid; | ||
20 | unsigned short st_rdev; | ||
21 | unsigned long st_size; | ||
22 | unsigned long st_atime; | ||
23 | unsigned long st_mtime; | ||
24 | unsigned long st_ctime; | ||
25 | }; | ||
26 | |||
27 | struct stat { | ||
28 | unsigned short st_dev; | ||
29 | unsigned short __pad1; | ||
30 | unsigned long st_ino; | ||
31 | unsigned short st_mode; | ||
32 | unsigned short st_nlink; | ||
33 | unsigned short st_uid; | ||
34 | unsigned short st_gid; | ||
35 | unsigned short st_rdev; | ||
36 | unsigned short __pad2; | ||
37 | unsigned long st_size; | ||
38 | unsigned long st_blksize; | ||
39 | unsigned long st_blocks; | ||
40 | unsigned long st_atime; | ||
41 | unsigned long st_atime_nsec; | ||
42 | unsigned long st_mtime; | ||
43 | unsigned long st_mtime_nsec; | ||
44 | unsigned long st_ctime; | ||
45 | unsigned long st_ctime_nsec; | ||
46 | unsigned long __unused4; | ||
47 | unsigned long __unused5; | ||
48 | }; | ||
49 | |||
50 | /* This matches struct stat64 in glibc2.1, hence the absolutely | ||
51 | * insane amounts of padding around dev_t's. | ||
52 | */ | ||
53 | struct stat64 { | ||
54 | unsigned long long st_dev; | ||
55 | unsigned int __pad1; | ||
56 | #define STAT64_HAS_BROKEN_ST_INO 1 | ||
57 | unsigned long __st_ino; | ||
58 | unsigned int st_mode; | ||
59 | unsigned int st_nlink; | ||
60 | unsigned long st_uid; | ||
61 | unsigned long st_gid; | ||
62 | unsigned long long st_rdev; | ||
63 | unsigned int __pad3; | ||
64 | long long st_size; | ||
65 | unsigned long st_blksize; | ||
66 | unsigned char __pad4[4]; | ||
67 | unsigned long __pad5; /* future possible st_blocks high bits */ | ||
68 | unsigned long st_blocks; /* Number 512-byte blocks allocated. */ | ||
69 | unsigned long st_atime; | ||
70 | unsigned long st_atime_nsec; | ||
71 | unsigned long st_mtime; | ||
72 | unsigned long st_mtime_nsec; | ||
73 | unsigned long st_ctime; | ||
74 | unsigned long st_ctime_nsec; /* will be high 32 bits of ctime someday */ | ||
75 | unsigned long long st_ino; | ||
76 | }; | ||
77 | |||
78 | #else /* __s390x__ */ | ||
79 | |||
80 | struct stat { | ||
81 | unsigned long st_dev; | ||
82 | unsigned long st_ino; | ||
83 | unsigned long st_nlink; | ||
84 | unsigned int st_mode; | ||
85 | unsigned int st_uid; | ||
86 | unsigned int st_gid; | ||
87 | unsigned int __pad1; | ||
88 | unsigned long st_rdev; | ||
89 | unsigned long st_size; | ||
90 | unsigned long st_atime; | ||
91 | unsigned long st_atime_nsec; | ||
92 | unsigned long st_mtime; | ||
93 | unsigned long st_mtime_nsec; | ||
94 | unsigned long st_ctime; | ||
95 | unsigned long st_ctime_nsec; | ||
96 | unsigned long st_blksize; | ||
97 | long st_blocks; | ||
98 | unsigned long __unused[3]; | ||
99 | }; | ||
100 | |||
101 | #endif /* __s390x__ */ | ||
102 | |||
103 | #define STAT_HAVE_NSEC 1 | ||
104 | |||
105 | #endif | ||
diff --git a/arch/s390/include/asm/statfs.h b/arch/s390/include/asm/statfs.h new file mode 100644 index 000000000000..099a45579190 --- /dev/null +++ b/arch/s390/include/asm/statfs.h | |||
@@ -0,0 +1,71 @@ | |||
1 | /* | ||
2 | * include/asm-s390/statfs.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/statfs.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef _S390_STATFS_H | ||
10 | #define _S390_STATFS_H | ||
11 | |||
12 | #ifndef __s390x__ | ||
13 | #include <asm-generic/statfs.h> | ||
14 | #else | ||
15 | |||
16 | #ifndef __KERNEL_STRICT_NAMES | ||
17 | |||
18 | #include <linux/types.h> | ||
19 | |||
20 | typedef __kernel_fsid_t fsid_t; | ||
21 | |||
22 | #endif | ||
23 | |||
24 | /* | ||
25 | * This is ugly -- we're already 64-bit clean, so just duplicate the | ||
26 | * definitions. | ||
27 | */ | ||
28 | struct statfs { | ||
29 | int f_type; | ||
30 | int f_bsize; | ||
31 | long f_blocks; | ||
32 | long f_bfree; | ||
33 | long f_bavail; | ||
34 | long f_files; | ||
35 | long f_ffree; | ||
36 | __kernel_fsid_t f_fsid; | ||
37 | int f_namelen; | ||
38 | int f_frsize; | ||
39 | int f_spare[5]; | ||
40 | }; | ||
41 | |||
42 | struct statfs64 { | ||
43 | int f_type; | ||
44 | int f_bsize; | ||
45 | long f_blocks; | ||
46 | long f_bfree; | ||
47 | long f_bavail; | ||
48 | long f_files; | ||
49 | long f_ffree; | ||
50 | __kernel_fsid_t f_fsid; | ||
51 | int f_namelen; | ||
52 | int f_frsize; | ||
53 | int f_spare[5]; | ||
54 | }; | ||
55 | |||
56 | struct compat_statfs64 { | ||
57 | __u32 f_type; | ||
58 | __u32 f_bsize; | ||
59 | __u64 f_blocks; | ||
60 | __u64 f_bfree; | ||
61 | __u64 f_bavail; | ||
62 | __u64 f_files; | ||
63 | __u64 f_ffree; | ||
64 | __kernel_fsid_t f_fsid; | ||
65 | __u32 f_namelen; | ||
66 | __u32 f_frsize; | ||
67 | __u32 f_spare[5]; | ||
68 | }; | ||
69 | |||
70 | #endif /* __s390x__ */ | ||
71 | #endif | ||
diff --git a/arch/s390/include/asm/string.h b/arch/s390/include/asm/string.h new file mode 100644 index 000000000000..d074673a6d9b --- /dev/null +++ b/arch/s390/include/asm/string.h | |||
@@ -0,0 +1,143 @@ | |||
1 | /* | ||
2 | * include/asm-s390/string.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | ||
7 | */ | ||
8 | |||
9 | #ifndef _S390_STRING_H_ | ||
10 | #define _S390_STRING_H_ | ||
11 | |||
12 | #ifdef __KERNEL__ | ||
13 | |||
14 | #ifndef _LINUX_TYPES_H | ||
15 | #include <linux/types.h> | ||
16 | #endif | ||
17 | |||
18 | #define __HAVE_ARCH_MEMCHR /* inline & arch function */ | ||
19 | #define __HAVE_ARCH_MEMCMP /* arch function */ | ||
20 | #define __HAVE_ARCH_MEMCPY /* gcc builtin & arch function */ | ||
21 | #define __HAVE_ARCH_MEMSCAN /* inline & arch function */ | ||
22 | #define __HAVE_ARCH_MEMSET /* gcc builtin & arch function */ | ||
23 | #define __HAVE_ARCH_STRCAT /* inline & arch function */ | ||
24 | #define __HAVE_ARCH_STRCMP /* arch function */ | ||
25 | #define __HAVE_ARCH_STRCPY /* inline & arch function */ | ||
26 | #define __HAVE_ARCH_STRLCAT /* arch function */ | ||
27 | #define __HAVE_ARCH_STRLCPY /* arch function */ | ||
28 | #define __HAVE_ARCH_STRLEN /* inline & arch function */ | ||
29 | #define __HAVE_ARCH_STRNCAT /* arch function */ | ||
30 | #define __HAVE_ARCH_STRNCPY /* arch function */ | ||
31 | #define __HAVE_ARCH_STRNLEN /* inline & arch function */ | ||
32 | #define __HAVE_ARCH_STRRCHR /* arch function */ | ||
33 | #define __HAVE_ARCH_STRSTR /* arch function */ | ||
34 | |||
35 | /* Prototypes for non-inlined arch strings functions. */ | ||
36 | extern int memcmp(const void *, const void *, size_t); | ||
37 | extern void *memcpy(void *, const void *, size_t); | ||
38 | extern void *memset(void *, int, size_t); | ||
39 | extern int strcmp(const char *,const char *); | ||
40 | extern size_t strlcat(char *, const char *, size_t); | ||
41 | extern size_t strlcpy(char *, const char *, size_t); | ||
42 | extern char *strncat(char *, const char *, size_t); | ||
43 | extern char *strncpy(char *, const char *, size_t); | ||
44 | extern char *strrchr(const char *, int); | ||
45 | extern char *strstr(const char *, const char *); | ||
46 | |||
47 | #undef __HAVE_ARCH_MEMMOVE | ||
48 | #undef __HAVE_ARCH_STRCHR | ||
49 | #undef __HAVE_ARCH_STRNCHR | ||
50 | #undef __HAVE_ARCH_STRNCMP | ||
51 | #undef __HAVE_ARCH_STRNICMP | ||
52 | #undef __HAVE_ARCH_STRPBRK | ||
53 | #undef __HAVE_ARCH_STRSEP | ||
54 | #undef __HAVE_ARCH_STRSPN | ||
55 | |||
56 | #if !defined(IN_ARCH_STRING_C) | ||
57 | |||
58 | static inline void *memchr(const void * s, int c, size_t n) | ||
59 | { | ||
60 | register int r0 asm("0") = (char) c; | ||
61 | const void *ret = s + n; | ||
62 | |||
63 | asm volatile( | ||
64 | "0: srst %0,%1\n" | ||
65 | " jo 0b\n" | ||
66 | " jl 1f\n" | ||
67 | " la %0,0\n" | ||
68 | "1:" | ||
69 | : "+a" (ret), "+&a" (s) : "d" (r0) : "cc"); | ||
70 | return (void *) ret; | ||
71 | } | ||
72 | |||
73 | static inline void *memscan(void *s, int c, size_t n) | ||
74 | { | ||
75 | register int r0 asm("0") = (char) c; | ||
76 | const void *ret = s + n; | ||
77 | |||
78 | asm volatile( | ||
79 | "0: srst %0,%1\n" | ||
80 | " jo 0b\n" | ||
81 | : "+a" (ret), "+&a" (s) : "d" (r0) : "cc"); | ||
82 | return (void *) ret; | ||
83 | } | ||
84 | |||
85 | static inline char *strcat(char *dst, const char *src) | ||
86 | { | ||
87 | register int r0 asm("0") = 0; | ||
88 | unsigned long dummy; | ||
89 | char *ret = dst; | ||
90 | |||
91 | asm volatile( | ||
92 | "0: srst %0,%1\n" | ||
93 | " jo 0b\n" | ||
94 | "1: mvst %0,%2\n" | ||
95 | " jo 1b" | ||
96 | : "=&a" (dummy), "+a" (dst), "+a" (src) | ||
97 | : "d" (r0), "0" (0) : "cc", "memory" ); | ||
98 | return ret; | ||
99 | } | ||
100 | |||
101 | static inline char *strcpy(char *dst, const char *src) | ||
102 | { | ||
103 | register int r0 asm("0") = 0; | ||
104 | char *ret = dst; | ||
105 | |||
106 | asm volatile( | ||
107 | "0: mvst %0,%1\n" | ||
108 | " jo 0b" | ||
109 | : "+&a" (dst), "+&a" (src) : "d" (r0) | ||
110 | : "cc", "memory"); | ||
111 | return ret; | ||
112 | } | ||
113 | |||
114 | static inline size_t strlen(const char *s) | ||
115 | { | ||
116 | register unsigned long r0 asm("0") = 0; | ||
117 | const char *tmp = s; | ||
118 | |||
119 | asm volatile( | ||
120 | "0: srst %0,%1\n" | ||
121 | " jo 0b" | ||
122 | : "+d" (r0), "+a" (tmp) : : "cc"); | ||
123 | return r0 - (unsigned long) s; | ||
124 | } | ||
125 | |||
126 | static inline size_t strnlen(const char * s, size_t n) | ||
127 | { | ||
128 | register int r0 asm("0") = 0; | ||
129 | const char *tmp = s; | ||
130 | const char *end = s + n; | ||
131 | |||
132 | asm volatile( | ||
133 | "0: srst %0,%1\n" | ||
134 | " jo 0b" | ||
135 | : "+a" (end), "+a" (tmp) : "d" (r0) : "cc"); | ||
136 | return end - s; | ||
137 | } | ||
138 | |||
139 | #endif /* !IN_ARCH_STRING_C */ | ||
140 | |||
141 | #endif /* __KERNEL__ */ | ||
142 | |||
143 | #endif /* __S390_STRING_H_ */ | ||
diff --git a/arch/s390/include/asm/suspend.h b/arch/s390/include/asm/suspend.h new file mode 100644 index 000000000000..1f34580e67a7 --- /dev/null +++ b/arch/s390/include/asm/suspend.h | |||
@@ -0,0 +1,5 @@ | |||
1 | #ifndef __ASM_S390_SUSPEND_H | ||
2 | #define __ASM_S390_SUSPEND_H | ||
3 | |||
4 | #endif | ||
5 | |||
diff --git a/arch/s390/include/asm/sysinfo.h b/arch/s390/include/asm/sysinfo.h new file mode 100644 index 000000000000..79d01343f8b0 --- /dev/null +++ b/arch/s390/include/asm/sysinfo.h | |||
@@ -0,0 +1,121 @@ | |||
1 | /* | ||
2 | * definition for store system information stsi | ||
3 | * | ||
4 | * Copyright IBM Corp. 2001,2008 | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify | ||
7 | * it under the terms of the GNU General Public License (version 2 only) | ||
8 | * as published by the Free Software Foundation. | ||
9 | * | ||
10 | * Author(s): Ulrich Weigand <weigand@de.ibm.com> | ||
11 | * Christian Borntraeger <borntraeger@de.ibm.com> | ||
12 | */ | ||
13 | |||
14 | #ifndef __ASM_S390_SYSINFO_H | ||
15 | #define __ASM_S390_SYSINFO_H | ||
16 | |||
17 | struct sysinfo_1_1_1 { | ||
18 | char reserved_0[32]; | ||
19 | char manufacturer[16]; | ||
20 | char type[4]; | ||
21 | char reserved_1[12]; | ||
22 | char model_capacity[16]; | ||
23 | char sequence[16]; | ||
24 | char plant[4]; | ||
25 | char model[16]; | ||
26 | char model_perm_cap[16]; | ||
27 | char model_temp_cap[16]; | ||
28 | char model_cap_rating[4]; | ||
29 | char model_perm_cap_rating[4]; | ||
30 | char model_temp_cap_rating[4]; | ||
31 | }; | ||
32 | |||
33 | struct sysinfo_1_2_1 { | ||
34 | char reserved_0[80]; | ||
35 | char sequence[16]; | ||
36 | char plant[4]; | ||
37 | char reserved_1[2]; | ||
38 | unsigned short cpu_address; | ||
39 | }; | ||
40 | |||
41 | struct sysinfo_1_2_2 { | ||
42 | char format; | ||
43 | char reserved_0[1]; | ||
44 | unsigned short acc_offset; | ||
45 | char reserved_1[24]; | ||
46 | unsigned int secondary_capability; | ||
47 | unsigned int capability; | ||
48 | unsigned short cpus_total; | ||
49 | unsigned short cpus_configured; | ||
50 | unsigned short cpus_standby; | ||
51 | unsigned short cpus_reserved; | ||
52 | unsigned short adjustment[0]; | ||
53 | }; | ||
54 | |||
55 | struct sysinfo_1_2_2_extension { | ||
56 | unsigned int alt_capability; | ||
57 | unsigned short alt_adjustment[0]; | ||
58 | }; | ||
59 | |||
60 | struct sysinfo_2_2_1 { | ||
61 | char reserved_0[80]; | ||
62 | char sequence[16]; | ||
63 | char plant[4]; | ||
64 | unsigned short cpu_id; | ||
65 | unsigned short cpu_address; | ||
66 | }; | ||
67 | |||
68 | struct sysinfo_2_2_2 { | ||
69 | char reserved_0[32]; | ||
70 | unsigned short lpar_number; | ||
71 | char reserved_1; | ||
72 | unsigned char characteristics; | ||
73 | unsigned short cpus_total; | ||
74 | unsigned short cpus_configured; | ||
75 | unsigned short cpus_standby; | ||
76 | unsigned short cpus_reserved; | ||
77 | char name[8]; | ||
78 | unsigned int caf; | ||
79 | char reserved_2[16]; | ||
80 | unsigned short cpus_dedicated; | ||
81 | unsigned short cpus_shared; | ||
82 | }; | ||
83 | |||
84 | #define LPAR_CHAR_DEDICATED (1 << 7) | ||
85 | #define LPAR_CHAR_SHARED (1 << 6) | ||
86 | #define LPAR_CHAR_LIMITED (1 << 5) | ||
87 | |||
88 | struct sysinfo_3_2_2 { | ||
89 | char reserved_0[31]; | ||
90 | unsigned char count; | ||
91 | struct { | ||
92 | char reserved_0[4]; | ||
93 | unsigned short cpus_total; | ||
94 | unsigned short cpus_configured; | ||
95 | unsigned short cpus_standby; | ||
96 | unsigned short cpus_reserved; | ||
97 | char name[8]; | ||
98 | unsigned int caf; | ||
99 | char cpi[16]; | ||
100 | char reserved_1[24]; | ||
101 | |||
102 | } vm[8]; | ||
103 | }; | ||
104 | |||
105 | static inline int stsi(void *sysinfo, int fc, int sel1, int sel2) | ||
106 | { | ||
107 | register int r0 asm("0") = (fc << 28) | sel1; | ||
108 | register int r1 asm("1") = sel2; | ||
109 | |||
110 | asm volatile( | ||
111 | " stsi 0(%2)\n" | ||
112 | "0: jz 2f\n" | ||
113 | "1: lhi %0,%3\n" | ||
114 | "2:\n" | ||
115 | EX_TABLE(0b, 1b) | ||
116 | : "+d" (r0) : "d" (r1), "a" (sysinfo), "K" (-ENOSYS) | ||
117 | : "cc", "memory"); | ||
118 | return r0; | ||
119 | } | ||
120 | |||
121 | #endif /* __ASM_S390_SYSINFO_H */ | ||
diff --git a/arch/s390/include/asm/system.h b/arch/s390/include/asm/system.h new file mode 100644 index 000000000000..819e7d99ca0c --- /dev/null +++ b/arch/s390/include/asm/system.h | |||
@@ -0,0 +1,462 @@ | |||
1 | /* | ||
2 | * include/asm-s390/system.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | ||
7 | * | ||
8 | * Derived from "include/asm-i386/system.h" | ||
9 | */ | ||
10 | |||
11 | #ifndef __ASM_SYSTEM_H | ||
12 | #define __ASM_SYSTEM_H | ||
13 | |||
14 | #include <linux/kernel.h> | ||
15 | #include <asm/types.h> | ||
16 | #include <asm/ptrace.h> | ||
17 | #include <asm/setup.h> | ||
18 | #include <asm/processor.h> | ||
19 | #include <asm/lowcore.h> | ||
20 | |||
21 | #ifdef __KERNEL__ | ||
22 | |||
23 | struct task_struct; | ||
24 | |||
25 | extern struct task_struct *__switch_to(void *, void *); | ||
26 | |||
27 | static inline void save_fp_regs(s390_fp_regs *fpregs) | ||
28 | { | ||
29 | asm volatile( | ||
30 | " std 0,8(%1)\n" | ||
31 | " std 2,24(%1)\n" | ||
32 | " std 4,40(%1)\n" | ||
33 | " std 6,56(%1)" | ||
34 | : "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory"); | ||
35 | if (!MACHINE_HAS_IEEE) | ||
36 | return; | ||
37 | asm volatile( | ||
38 | " stfpc 0(%1)\n" | ||
39 | " std 1,16(%1)\n" | ||
40 | " std 3,32(%1)\n" | ||
41 | " std 5,48(%1)\n" | ||
42 | " std 7,64(%1)\n" | ||
43 | " std 8,72(%1)\n" | ||
44 | " std 9,80(%1)\n" | ||
45 | " std 10,88(%1)\n" | ||
46 | " std 11,96(%1)\n" | ||
47 | " std 12,104(%1)\n" | ||
48 | " std 13,112(%1)\n" | ||
49 | " std 14,120(%1)\n" | ||
50 | " std 15,128(%1)\n" | ||
51 | : "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory"); | ||
52 | } | ||
53 | |||
54 | static inline void restore_fp_regs(s390_fp_regs *fpregs) | ||
55 | { | ||
56 | asm volatile( | ||
57 | " ld 0,8(%0)\n" | ||
58 | " ld 2,24(%0)\n" | ||
59 | " ld 4,40(%0)\n" | ||
60 | " ld 6,56(%0)" | ||
61 | : : "a" (fpregs), "m" (*fpregs)); | ||
62 | if (!MACHINE_HAS_IEEE) | ||
63 | return; | ||
64 | asm volatile( | ||
65 | " lfpc 0(%0)\n" | ||
66 | " ld 1,16(%0)\n" | ||
67 | " ld 3,32(%0)\n" | ||
68 | " ld 5,48(%0)\n" | ||
69 | " ld 7,64(%0)\n" | ||
70 | " ld 8,72(%0)\n" | ||
71 | " ld 9,80(%0)\n" | ||
72 | " ld 10,88(%0)\n" | ||
73 | " ld 11,96(%0)\n" | ||
74 | " ld 12,104(%0)\n" | ||
75 | " ld 13,112(%0)\n" | ||
76 | " ld 14,120(%0)\n" | ||
77 | " ld 15,128(%0)\n" | ||
78 | : : "a" (fpregs), "m" (*fpregs)); | ||
79 | } | ||
80 | |||
81 | static inline void save_access_regs(unsigned int *acrs) | ||
82 | { | ||
83 | asm volatile("stam 0,15,0(%0)" : : "a" (acrs) : "memory"); | ||
84 | } | ||
85 | |||
86 | static inline void restore_access_regs(unsigned int *acrs) | ||
87 | { | ||
88 | asm volatile("lam 0,15,0(%0)" : : "a" (acrs)); | ||
89 | } | ||
90 | |||
91 | #define switch_to(prev,next,last) do { \ | ||
92 | if (prev == next) \ | ||
93 | break; \ | ||
94 | save_fp_regs(&prev->thread.fp_regs); \ | ||
95 | restore_fp_regs(&next->thread.fp_regs); \ | ||
96 | save_access_regs(&prev->thread.acrs[0]); \ | ||
97 | restore_access_regs(&next->thread.acrs[0]); \ | ||
98 | prev = __switch_to(prev,next); \ | ||
99 | } while (0) | ||
100 | |||
101 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | ||
102 | extern void account_vtime(struct task_struct *); | ||
103 | extern void account_tick_vtime(struct task_struct *); | ||
104 | extern void account_system_vtime(struct task_struct *); | ||
105 | #else | ||
106 | #define account_vtime(x) do { /* empty */ } while (0) | ||
107 | #endif | ||
108 | |||
109 | #ifdef CONFIG_PFAULT | ||
110 | extern void pfault_irq_init(void); | ||
111 | extern int pfault_init(void); | ||
112 | extern void pfault_fini(void); | ||
113 | #else /* CONFIG_PFAULT */ | ||
114 | #define pfault_irq_init() do { } while (0) | ||
115 | #define pfault_init() ({-1;}) | ||
116 | #define pfault_fini() do { } while (0) | ||
117 | #endif /* CONFIG_PFAULT */ | ||
118 | |||
119 | #ifdef CONFIG_PAGE_STATES | ||
120 | extern void cmma_init(void); | ||
121 | #else | ||
122 | static inline void cmma_init(void) { } | ||
123 | #endif | ||
124 | |||
125 | #define finish_arch_switch(prev) do { \ | ||
126 | set_fs(current->thread.mm_segment); \ | ||
127 | account_vtime(prev); \ | ||
128 | } while (0) | ||
129 | |||
130 | #define nop() asm volatile("nop") | ||
131 | |||
132 | #define xchg(ptr,x) \ | ||
133 | ({ \ | ||
134 | __typeof__(*(ptr)) __ret; \ | ||
135 | __ret = (__typeof__(*(ptr))) \ | ||
136 | __xchg((unsigned long)(x), (void *)(ptr),sizeof(*(ptr))); \ | ||
137 | __ret; \ | ||
138 | }) | ||
139 | |||
140 | extern void __xchg_called_with_bad_pointer(void); | ||
141 | |||
142 | static inline unsigned long __xchg(unsigned long x, void * ptr, int size) | ||
143 | { | ||
144 | unsigned long addr, old; | ||
145 | int shift; | ||
146 | |||
147 | switch (size) { | ||
148 | case 1: | ||
149 | addr = (unsigned long) ptr; | ||
150 | shift = (3 ^ (addr & 3)) << 3; | ||
151 | addr ^= addr & 3; | ||
152 | asm volatile( | ||
153 | " l %0,0(%4)\n" | ||
154 | "0: lr 0,%0\n" | ||
155 | " nr 0,%3\n" | ||
156 | " or 0,%2\n" | ||
157 | " cs %0,0,0(%4)\n" | ||
158 | " jl 0b\n" | ||
159 | : "=&d" (old), "=m" (*(int *) addr) | ||
160 | : "d" (x << shift), "d" (~(255 << shift)), "a" (addr), | ||
161 | "m" (*(int *) addr) : "memory", "cc", "0"); | ||
162 | return old >> shift; | ||
163 | case 2: | ||
164 | addr = (unsigned long) ptr; | ||
165 | shift = (2 ^ (addr & 2)) << 3; | ||
166 | addr ^= addr & 2; | ||
167 | asm volatile( | ||
168 | " l %0,0(%4)\n" | ||
169 | "0: lr 0,%0\n" | ||
170 | " nr 0,%3\n" | ||
171 | " or 0,%2\n" | ||
172 | " cs %0,0,0(%4)\n" | ||
173 | " jl 0b\n" | ||
174 | : "=&d" (old), "=m" (*(int *) addr) | ||
175 | : "d" (x << shift), "d" (~(65535 << shift)), "a" (addr), | ||
176 | "m" (*(int *) addr) : "memory", "cc", "0"); | ||
177 | return old >> shift; | ||
178 | case 4: | ||
179 | asm volatile( | ||
180 | " l %0,0(%3)\n" | ||
181 | "0: cs %0,%2,0(%3)\n" | ||
182 | " jl 0b\n" | ||
183 | : "=&d" (old), "=m" (*(int *) ptr) | ||
184 | : "d" (x), "a" (ptr), "m" (*(int *) ptr) | ||
185 | : "memory", "cc"); | ||
186 | return old; | ||
187 | #ifdef __s390x__ | ||
188 | case 8: | ||
189 | asm volatile( | ||
190 | " lg %0,0(%3)\n" | ||
191 | "0: csg %0,%2,0(%3)\n" | ||
192 | " jl 0b\n" | ||
193 | : "=&d" (old), "=m" (*(long *) ptr) | ||
194 | : "d" (x), "a" (ptr), "m" (*(long *) ptr) | ||
195 | : "memory", "cc"); | ||
196 | return old; | ||
197 | #endif /* __s390x__ */ | ||
198 | } | ||
199 | __xchg_called_with_bad_pointer(); | ||
200 | return x; | ||
201 | } | ||
202 | |||
203 | /* | ||
204 | * Atomic compare and exchange. Compare OLD with MEM, if identical, | ||
205 | * store NEW in MEM. Return the initial value in MEM. Success is | ||
206 | * indicated by comparing RETURN with OLD. | ||
207 | */ | ||
208 | |||
209 | #define __HAVE_ARCH_CMPXCHG 1 | ||
210 | |||
211 | #define cmpxchg(ptr, o, n) \ | ||
212 | ((__typeof__(*(ptr)))__cmpxchg((ptr), (unsigned long)(o), \ | ||
213 | (unsigned long)(n), sizeof(*(ptr)))) | ||
214 | |||
215 | extern void __cmpxchg_called_with_bad_pointer(void); | ||
216 | |||
217 | static inline unsigned long | ||
218 | __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) | ||
219 | { | ||
220 | unsigned long addr, prev, tmp; | ||
221 | int shift; | ||
222 | |||
223 | switch (size) { | ||
224 | case 1: | ||
225 | addr = (unsigned long) ptr; | ||
226 | shift = (3 ^ (addr & 3)) << 3; | ||
227 | addr ^= addr & 3; | ||
228 | asm volatile( | ||
229 | " l %0,0(%4)\n" | ||
230 | "0: nr %0,%5\n" | ||
231 | " lr %1,%0\n" | ||
232 | " or %0,%2\n" | ||
233 | " or %1,%3\n" | ||
234 | " cs %0,%1,0(%4)\n" | ||
235 | " jnl 1f\n" | ||
236 | " xr %1,%0\n" | ||
237 | " nr %1,%5\n" | ||
238 | " jnz 0b\n" | ||
239 | "1:" | ||
240 | : "=&d" (prev), "=&d" (tmp) | ||
241 | : "d" (old << shift), "d" (new << shift), "a" (ptr), | ||
242 | "d" (~(255 << shift)) | ||
243 | : "memory", "cc"); | ||
244 | return prev >> shift; | ||
245 | case 2: | ||
246 | addr = (unsigned long) ptr; | ||
247 | shift = (2 ^ (addr & 2)) << 3; | ||
248 | addr ^= addr & 2; | ||
249 | asm volatile( | ||
250 | " l %0,0(%4)\n" | ||
251 | "0: nr %0,%5\n" | ||
252 | " lr %1,%0\n" | ||
253 | " or %0,%2\n" | ||
254 | " or %1,%3\n" | ||
255 | " cs %0,%1,0(%4)\n" | ||
256 | " jnl 1f\n" | ||
257 | " xr %1,%0\n" | ||
258 | " nr %1,%5\n" | ||
259 | " jnz 0b\n" | ||
260 | "1:" | ||
261 | : "=&d" (prev), "=&d" (tmp) | ||
262 | : "d" (old << shift), "d" (new << shift), "a" (ptr), | ||
263 | "d" (~(65535 << shift)) | ||
264 | : "memory", "cc"); | ||
265 | return prev >> shift; | ||
266 | case 4: | ||
267 | asm volatile( | ||
268 | " cs %0,%2,0(%3)\n" | ||
269 | : "=&d" (prev) : "0" (old), "d" (new), "a" (ptr) | ||
270 | : "memory", "cc"); | ||
271 | return prev; | ||
272 | #ifdef __s390x__ | ||
273 | case 8: | ||
274 | asm volatile( | ||
275 | " csg %0,%2,0(%3)\n" | ||
276 | : "=&d" (prev) : "0" (old), "d" (new), "a" (ptr) | ||
277 | : "memory", "cc"); | ||
278 | return prev; | ||
279 | #endif /* __s390x__ */ | ||
280 | } | ||
281 | __cmpxchg_called_with_bad_pointer(); | ||
282 | return old; | ||
283 | } | ||
284 | |||
285 | /* | ||
286 | * Force strict CPU ordering. | ||
287 | * And yes, this is required on UP too when we're talking | ||
288 | * to devices. | ||
289 | * | ||
290 | * This is very similar to the ppc eieio/sync instruction in that is | ||
291 | * does a checkpoint syncronisation & makes sure that | ||
292 | * all memory ops have completed wrt other CPU's ( see 7-15 POP DJB ). | ||
293 | */ | ||
294 | |||
295 | #define eieio() asm volatile("bcr 15,0" : : : "memory") | ||
296 | #define SYNC_OTHER_CORES(x) eieio() | ||
297 | #define mb() eieio() | ||
298 | #define rmb() eieio() | ||
299 | #define wmb() eieio() | ||
300 | #define read_barrier_depends() do { } while(0) | ||
301 | #define smp_mb() mb() | ||
302 | #define smp_rmb() rmb() | ||
303 | #define smp_wmb() wmb() | ||
304 | #define smp_read_barrier_depends() read_barrier_depends() | ||
305 | #define smp_mb__before_clear_bit() smp_mb() | ||
306 | #define smp_mb__after_clear_bit() smp_mb() | ||
307 | |||
308 | |||
309 | #define set_mb(var, value) do { var = value; mb(); } while (0) | ||
310 | |||
311 | #ifdef __s390x__ | ||
312 | |||
313 | #define __ctl_load(array, low, high) ({ \ | ||
314 | typedef struct { char _[sizeof(array)]; } addrtype; \ | ||
315 | asm volatile( \ | ||
316 | " lctlg %1,%2,0(%0)\n" \ | ||
317 | : : "a" (&array), "i" (low), "i" (high), \ | ||
318 | "m" (*(addrtype *)(&array))); \ | ||
319 | }) | ||
320 | |||
321 | #define __ctl_store(array, low, high) ({ \ | ||
322 | typedef struct { char _[sizeof(array)]; } addrtype; \ | ||
323 | asm volatile( \ | ||
324 | " stctg %2,%3,0(%1)\n" \ | ||
325 | : "=m" (*(addrtype *)(&array)) \ | ||
326 | : "a" (&array), "i" (low), "i" (high)); \ | ||
327 | }) | ||
328 | |||
329 | #else /* __s390x__ */ | ||
330 | |||
331 | #define __ctl_load(array, low, high) ({ \ | ||
332 | typedef struct { char _[sizeof(array)]; } addrtype; \ | ||
333 | asm volatile( \ | ||
334 | " lctl %1,%2,0(%0)\n" \ | ||
335 | : : "a" (&array), "i" (low), "i" (high), \ | ||
336 | "m" (*(addrtype *)(&array))); \ | ||
337 | }) | ||
338 | |||
339 | #define __ctl_store(array, low, high) ({ \ | ||
340 | typedef struct { char _[sizeof(array)]; } addrtype; \ | ||
341 | asm volatile( \ | ||
342 | " stctl %2,%3,0(%1)\n" \ | ||
343 | : "=m" (*(addrtype *)(&array)) \ | ||
344 | : "a" (&array), "i" (low), "i" (high)); \ | ||
345 | }) | ||
346 | |||
347 | #endif /* __s390x__ */ | ||
348 | |||
349 | #define __ctl_set_bit(cr, bit) ({ \ | ||
350 | unsigned long __dummy; \ | ||
351 | __ctl_store(__dummy, cr, cr); \ | ||
352 | __dummy |= 1UL << (bit); \ | ||
353 | __ctl_load(__dummy, cr, cr); \ | ||
354 | }) | ||
355 | |||
356 | #define __ctl_clear_bit(cr, bit) ({ \ | ||
357 | unsigned long __dummy; \ | ||
358 | __ctl_store(__dummy, cr, cr); \ | ||
359 | __dummy &= ~(1UL << (bit)); \ | ||
360 | __ctl_load(__dummy, cr, cr); \ | ||
361 | }) | ||
362 | |||
363 | #include <linux/irqflags.h> | ||
364 | |||
365 | #include <asm-generic/cmpxchg-local.h> | ||
366 | |||
367 | static inline unsigned long __cmpxchg_local(volatile void *ptr, | ||
368 | unsigned long old, | ||
369 | unsigned long new, int size) | ||
370 | { | ||
371 | switch (size) { | ||
372 | case 1: | ||
373 | case 2: | ||
374 | case 4: | ||
375 | #ifdef __s390x__ | ||
376 | case 8: | ||
377 | #endif | ||
378 | return __cmpxchg(ptr, old, new, size); | ||
379 | default: | ||
380 | return __cmpxchg_local_generic(ptr, old, new, size); | ||
381 | } | ||
382 | |||
383 | return old; | ||
384 | } | ||
385 | |||
386 | /* | ||
387 | * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make | ||
388 | * them available. | ||
389 | */ | ||
390 | #define cmpxchg_local(ptr, o, n) \ | ||
391 | ((__typeof__(*(ptr)))__cmpxchg_local((ptr), (unsigned long)(o), \ | ||
392 | (unsigned long)(n), sizeof(*(ptr)))) | ||
393 | #ifdef __s390x__ | ||
394 | #define cmpxchg64_local(ptr, o, n) \ | ||
395 | ({ \ | ||
396 | BUILD_BUG_ON(sizeof(*(ptr)) != 8); \ | ||
397 | cmpxchg_local((ptr), (o), (n)); \ | ||
398 | }) | ||
399 | #else | ||
400 | #define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n)) | ||
401 | #endif | ||
402 | |||
403 | /* | ||
404 | * Use to set psw mask except for the first byte which | ||
405 | * won't be changed by this function. | ||
406 | */ | ||
407 | static inline void | ||
408 | __set_psw_mask(unsigned long mask) | ||
409 | { | ||
410 | __load_psw_mask(mask | (__raw_local_irq_stosm(0x00) & ~(-1UL >> 8))); | ||
411 | } | ||
412 | |||
413 | #define local_mcck_enable() __set_psw_mask(psw_kernel_bits) | ||
414 | #define local_mcck_disable() __set_psw_mask(psw_kernel_bits & ~PSW_MASK_MCHECK) | ||
415 | |||
416 | int stfle(unsigned long long *list, int doublewords); | ||
417 | |||
418 | #ifdef CONFIG_SMP | ||
419 | |||
420 | extern void smp_ctl_set_bit(int cr, int bit); | ||
421 | extern void smp_ctl_clear_bit(int cr, int bit); | ||
422 | #define ctl_set_bit(cr, bit) smp_ctl_set_bit(cr, bit) | ||
423 | #define ctl_clear_bit(cr, bit) smp_ctl_clear_bit(cr, bit) | ||
424 | |||
425 | #else | ||
426 | |||
427 | #define ctl_set_bit(cr, bit) __ctl_set_bit(cr, bit) | ||
428 | #define ctl_clear_bit(cr, bit) __ctl_clear_bit(cr, bit) | ||
429 | |||
430 | #endif /* CONFIG_SMP */ | ||
431 | |||
432 | static inline unsigned int stfl(void) | ||
433 | { | ||
434 | asm volatile( | ||
435 | " .insn s,0xb2b10000,0(0)\n" /* stfl */ | ||
436 | "0:\n" | ||
437 | EX_TABLE(0b,0b)); | ||
438 | return S390_lowcore.stfl_fac_list; | ||
439 | } | ||
440 | |||
441 | static inline unsigned short stap(void) | ||
442 | { | ||
443 | unsigned short cpu_address; | ||
444 | |||
445 | asm volatile("stap %0" : "=m" (cpu_address)); | ||
446 | return cpu_address; | ||
447 | } | ||
448 | |||
449 | extern void (*_machine_restart)(char *command); | ||
450 | extern void (*_machine_halt)(void); | ||
451 | extern void (*_machine_power_off)(void); | ||
452 | |||
453 | #define arch_align_stack(x) (x) | ||
454 | |||
455 | #ifdef CONFIG_TRACE_IRQFLAGS | ||
456 | extern psw_t sysc_restore_trace_psw; | ||
457 | extern psw_t io_restore_trace_psw; | ||
458 | #endif | ||
459 | |||
460 | #endif /* __KERNEL__ */ | ||
461 | |||
462 | #endif | ||
diff --git a/arch/s390/include/asm/tape390.h b/arch/s390/include/asm/tape390.h new file mode 100644 index 000000000000..884fba48f1ff --- /dev/null +++ b/arch/s390/include/asm/tape390.h | |||
@@ -0,0 +1,103 @@ | |||
1 | /************************************************************************* | ||
2 | * | ||
3 | * tape390.h | ||
4 | * enables user programs to display messages and control encryption | ||
5 | * on s390 tape devices | ||
6 | * | ||
7 | * Copyright IBM Corp. 2001,2006 | ||
8 | * Author(s): Michael Holzheu <holzheu@de.ibm.com> | ||
9 | * | ||
10 | *************************************************************************/ | ||
11 | |||
12 | #ifndef _TAPE390_H | ||
13 | #define _TAPE390_H | ||
14 | |||
15 | #define TAPE390_DISPLAY _IOW('d', 1, struct display_struct) | ||
16 | |||
17 | /* | ||
18 | * The TAPE390_DISPLAY ioctl calls the Load Display command | ||
19 | * which transfers 17 bytes of data from the channel to the subsystem: | ||
20 | * - 1 format control byte, and | ||
21 | * - two 8-byte messages | ||
22 | * | ||
23 | * Format control byte: | ||
24 | * 0-2: New Message Overlay | ||
25 | * 3: Alternate Messages | ||
26 | * 4: Blink Message | ||
27 | * 5: Display Low/High Message | ||
28 | * 6: Reserved | ||
29 | * 7: Automatic Load Request | ||
30 | * | ||
31 | */ | ||
32 | |||
33 | typedef struct display_struct { | ||
34 | char cntrl; | ||
35 | char message1[8]; | ||
36 | char message2[8]; | ||
37 | } display_struct; | ||
38 | |||
39 | /* | ||
40 | * Tape encryption support | ||
41 | */ | ||
42 | |||
43 | struct tape390_crypt_info { | ||
44 | char capability; | ||
45 | char status; | ||
46 | char medium_status; | ||
47 | } __attribute__ ((packed)); | ||
48 | |||
49 | |||
50 | /* Macros for "capable" field */ | ||
51 | #define TAPE390_CRYPT_SUPPORTED_MASK 0x01 | ||
52 | #define TAPE390_CRYPT_SUPPORTED(x) \ | ||
53 | ((x.capability & TAPE390_CRYPT_SUPPORTED_MASK)) | ||
54 | |||
55 | /* Macros for "status" field */ | ||
56 | #define TAPE390_CRYPT_ON_MASK 0x01 | ||
57 | #define TAPE390_CRYPT_ON(x) (((x.status) & TAPE390_CRYPT_ON_MASK)) | ||
58 | |||
59 | /* Macros for "medium status" field */ | ||
60 | #define TAPE390_MEDIUM_LOADED_MASK 0x01 | ||
61 | #define TAPE390_MEDIUM_ENCRYPTED_MASK 0x02 | ||
62 | #define TAPE390_MEDIUM_ENCRYPTED(x) \ | ||
63 | (((x.medium_status) & TAPE390_MEDIUM_ENCRYPTED_MASK)) | ||
64 | #define TAPE390_MEDIUM_LOADED(x) \ | ||
65 | (((x.medium_status) & TAPE390_MEDIUM_LOADED_MASK)) | ||
66 | |||
67 | /* | ||
68 | * The TAPE390_CRYPT_SET ioctl is used to switch on/off encryption. | ||
69 | * The "encryption_capable" and "tape_status" fields are ignored for this ioctl! | ||
70 | */ | ||
71 | #define TAPE390_CRYPT_SET _IOW('d', 2, struct tape390_crypt_info) | ||
72 | |||
73 | /* | ||
74 | * The TAPE390_CRYPT_QUERY ioctl is used to query the encryption state. | ||
75 | */ | ||
76 | #define TAPE390_CRYPT_QUERY _IOR('d', 3, struct tape390_crypt_info) | ||
77 | |||
78 | /* Values for "kekl1/2_type" and "kekl1/2_type_on_tape" fields */ | ||
79 | #define TAPE390_KEKL_TYPE_NONE 0 | ||
80 | #define TAPE390_KEKL_TYPE_LABEL 1 | ||
81 | #define TAPE390_KEKL_TYPE_HASH 2 | ||
82 | |||
83 | struct tape390_kekl { | ||
84 | unsigned char type; | ||
85 | unsigned char type_on_tape; | ||
86 | char label[65]; | ||
87 | } __attribute__ ((packed)); | ||
88 | |||
89 | struct tape390_kekl_pair { | ||
90 | struct tape390_kekl kekl[2]; | ||
91 | } __attribute__ ((packed)); | ||
92 | |||
93 | /* | ||
94 | * The TAPE390_KEKL_SET ioctl is used to set Key Encrypting Key labels. | ||
95 | */ | ||
96 | #define TAPE390_KEKL_SET _IOW('d', 4, struct tape390_kekl_pair) | ||
97 | |||
98 | /* | ||
99 | * The TAPE390_KEKL_QUERY ioctl is used to query Key Encrypting Key labels. | ||
100 | */ | ||
101 | #define TAPE390_KEKL_QUERY _IOR('d', 5, struct tape390_kekl_pair) | ||
102 | |||
103 | #endif | ||
diff --git a/arch/s390/include/asm/termbits.h b/arch/s390/include/asm/termbits.h new file mode 100644 index 000000000000..58731853d529 --- /dev/null +++ b/arch/s390/include/asm/termbits.h | |||
@@ -0,0 +1,206 @@ | |||
1 | /* | ||
2 | * include/asm-s390/termbits.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/termbits.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef __ARCH_S390_TERMBITS_H__ | ||
10 | #define __ARCH_S390_TERMBITS_H__ | ||
11 | |||
12 | #include <linux/posix_types.h> | ||
13 | |||
14 | typedef unsigned char cc_t; | ||
15 | typedef unsigned int speed_t; | ||
16 | typedef unsigned int tcflag_t; | ||
17 | |||
18 | #define NCCS 19 | ||
19 | struct termios { | ||
20 | tcflag_t c_iflag; /* input mode flags */ | ||
21 | tcflag_t c_oflag; /* output mode flags */ | ||
22 | tcflag_t c_cflag; /* control mode flags */ | ||
23 | tcflag_t c_lflag; /* local mode flags */ | ||
24 | cc_t c_line; /* line discipline */ | ||
25 | cc_t c_cc[NCCS]; /* control characters */ | ||
26 | }; | ||
27 | |||
28 | struct termios2 { | ||
29 | tcflag_t c_iflag; /* input mode flags */ | ||
30 | tcflag_t c_oflag; /* output mode flags */ | ||
31 | tcflag_t c_cflag; /* control mode flags */ | ||
32 | tcflag_t c_lflag; /* local mode flags */ | ||
33 | cc_t c_line; /* line discipline */ | ||
34 | cc_t c_cc[NCCS]; /* control characters */ | ||
35 | speed_t c_ispeed; /* input speed */ | ||
36 | speed_t c_ospeed; /* output speed */ | ||
37 | }; | ||
38 | |||
39 | struct ktermios { | ||
40 | tcflag_t c_iflag; /* input mode flags */ | ||
41 | tcflag_t c_oflag; /* output mode flags */ | ||
42 | tcflag_t c_cflag; /* control mode flags */ | ||
43 | tcflag_t c_lflag; /* local mode flags */ | ||
44 | cc_t c_line; /* line discipline */ | ||
45 | cc_t c_cc[NCCS]; /* control characters */ | ||
46 | speed_t c_ispeed; /* input speed */ | ||
47 | speed_t c_ospeed; /* output speed */ | ||
48 | }; | ||
49 | |||
50 | /* c_cc characters */ | ||
51 | #define VINTR 0 | ||
52 | #define VQUIT 1 | ||
53 | #define VERASE 2 | ||
54 | #define VKILL 3 | ||
55 | #define VEOF 4 | ||
56 | #define VTIME 5 | ||
57 | #define VMIN 6 | ||
58 | #define VSWTC 7 | ||
59 | #define VSTART 8 | ||
60 | #define VSTOP 9 | ||
61 | #define VSUSP 10 | ||
62 | #define VEOL 11 | ||
63 | #define VREPRINT 12 | ||
64 | #define VDISCARD 13 | ||
65 | #define VWERASE 14 | ||
66 | #define VLNEXT 15 | ||
67 | #define VEOL2 16 | ||
68 | |||
69 | /* c_iflag bits */ | ||
70 | #define IGNBRK 0000001 | ||
71 | #define BRKINT 0000002 | ||
72 | #define IGNPAR 0000004 | ||
73 | #define PARMRK 0000010 | ||
74 | #define INPCK 0000020 | ||
75 | #define ISTRIP 0000040 | ||
76 | #define INLCR 0000100 | ||
77 | #define IGNCR 0000200 | ||
78 | #define ICRNL 0000400 | ||
79 | #define IUCLC 0001000 | ||
80 | #define IXON 0002000 | ||
81 | #define IXANY 0004000 | ||
82 | #define IXOFF 0010000 | ||
83 | #define IMAXBEL 0020000 | ||
84 | #define IUTF8 0040000 | ||
85 | |||
86 | /* c_oflag bits */ | ||
87 | #define OPOST 0000001 | ||
88 | #define OLCUC 0000002 | ||
89 | #define ONLCR 0000004 | ||
90 | #define OCRNL 0000010 | ||
91 | #define ONOCR 0000020 | ||
92 | #define ONLRET 0000040 | ||
93 | #define OFILL 0000100 | ||
94 | #define OFDEL 0000200 | ||
95 | #define NLDLY 0000400 | ||
96 | #define NL0 0000000 | ||
97 | #define NL1 0000400 | ||
98 | #define CRDLY 0003000 | ||
99 | #define CR0 0000000 | ||
100 | #define CR1 0001000 | ||
101 | #define CR2 0002000 | ||
102 | #define CR3 0003000 | ||
103 | #define TABDLY 0014000 | ||
104 | #define TAB0 0000000 | ||
105 | #define TAB1 0004000 | ||
106 | #define TAB2 0010000 | ||
107 | #define TAB3 0014000 | ||
108 | #define XTABS 0014000 | ||
109 | #define BSDLY 0020000 | ||
110 | #define BS0 0000000 | ||
111 | #define BS1 0020000 | ||
112 | #define VTDLY 0040000 | ||
113 | #define VT0 0000000 | ||
114 | #define VT1 0040000 | ||
115 | #define FFDLY 0100000 | ||
116 | #define FF0 0000000 | ||
117 | #define FF1 0100000 | ||
118 | |||
119 | /* c_cflag bit meaning */ | ||
120 | #define CBAUD 0010017 | ||
121 | #define B0 0000000 /* hang up */ | ||
122 | #define B50 0000001 | ||
123 | #define B75 0000002 | ||
124 | #define B110 0000003 | ||
125 | #define B134 0000004 | ||
126 | #define B150 0000005 | ||
127 | #define B200 0000006 | ||
128 | #define B300 0000007 | ||
129 | #define B600 0000010 | ||
130 | #define B1200 0000011 | ||
131 | #define B1800 0000012 | ||
132 | #define B2400 0000013 | ||
133 | #define B4800 0000014 | ||
134 | #define B9600 0000015 | ||
135 | #define B19200 0000016 | ||
136 | #define B38400 0000017 | ||
137 | #define EXTA B19200 | ||
138 | #define EXTB B38400 | ||
139 | #define CSIZE 0000060 | ||
140 | #define CS5 0000000 | ||
141 | #define CS6 0000020 | ||
142 | #define CS7 0000040 | ||
143 | #define CS8 0000060 | ||
144 | #define CSTOPB 0000100 | ||
145 | #define CREAD 0000200 | ||
146 | #define PARENB 0000400 | ||
147 | #define PARODD 0001000 | ||
148 | #define HUPCL 0002000 | ||
149 | #define CLOCAL 0004000 | ||
150 | #define CBAUDEX 0010000 | ||
151 | #define BOTHER 0010000 | ||
152 | #define B57600 0010001 | ||
153 | #define B115200 0010002 | ||
154 | #define B230400 0010003 | ||
155 | #define B460800 0010004 | ||
156 | #define B500000 0010005 | ||
157 | #define B576000 0010006 | ||
158 | #define B921600 0010007 | ||
159 | #define B1000000 0010010 | ||
160 | #define B1152000 0010011 | ||
161 | #define B1500000 0010012 | ||
162 | #define B2000000 0010013 | ||
163 | #define B2500000 0010014 | ||
164 | #define B3000000 0010015 | ||
165 | #define B3500000 0010016 | ||
166 | #define B4000000 0010017 | ||
167 | #define CIBAUD 002003600000 /* input baud rate */ | ||
168 | #define CMSPAR 010000000000 /* mark or space (stick) parity */ | ||
169 | #define CRTSCTS 020000000000 /* flow control */ | ||
170 | |||
171 | #define IBSHIFT 16 /* Shift from CBAUD to CIBAUD */ | ||
172 | |||
173 | /* c_lflag bits */ | ||
174 | #define ISIG 0000001 | ||
175 | #define ICANON 0000002 | ||
176 | #define XCASE 0000004 | ||
177 | #define ECHO 0000010 | ||
178 | #define ECHOE 0000020 | ||
179 | #define ECHOK 0000040 | ||
180 | #define ECHONL 0000100 | ||
181 | #define NOFLSH 0000200 | ||
182 | #define TOSTOP 0000400 | ||
183 | #define ECHOCTL 0001000 | ||
184 | #define ECHOPRT 0002000 | ||
185 | #define ECHOKE 0004000 | ||
186 | #define FLUSHO 0010000 | ||
187 | #define PENDIN 0040000 | ||
188 | #define IEXTEN 0100000 | ||
189 | |||
190 | /* tcflow() and TCXONC use these */ | ||
191 | #define TCOOFF 0 | ||
192 | #define TCOON 1 | ||
193 | #define TCIOFF 2 | ||
194 | #define TCION 3 | ||
195 | |||
196 | /* tcflush() and TCFLSH use these */ | ||
197 | #define TCIFLUSH 0 | ||
198 | #define TCOFLUSH 1 | ||
199 | #define TCIOFLUSH 2 | ||
200 | |||
201 | /* tcsetattr uses these */ | ||
202 | #define TCSANOW 0 | ||
203 | #define TCSADRAIN 1 | ||
204 | #define TCSAFLUSH 2 | ||
205 | |||
206 | #endif | ||
diff --git a/arch/s390/include/asm/termios.h b/arch/s390/include/asm/termios.h new file mode 100644 index 000000000000..67f66278f533 --- /dev/null +++ b/arch/s390/include/asm/termios.h | |||
@@ -0,0 +1,67 @@ | |||
1 | /* | ||
2 | * include/asm-s390/termios.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/termios.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef _S390_TERMIOS_H | ||
10 | #define _S390_TERMIOS_H | ||
11 | |||
12 | #include <asm/termbits.h> | ||
13 | #include <asm/ioctls.h> | ||
14 | |||
15 | struct winsize { | ||
16 | unsigned short ws_row; | ||
17 | unsigned short ws_col; | ||
18 | unsigned short ws_xpixel; | ||
19 | unsigned short ws_ypixel; | ||
20 | }; | ||
21 | |||
22 | #define NCC 8 | ||
23 | struct termio { | ||
24 | unsigned short c_iflag; /* input mode flags */ | ||
25 | unsigned short c_oflag; /* output mode flags */ | ||
26 | unsigned short c_cflag; /* control mode flags */ | ||
27 | unsigned short c_lflag; /* local mode flags */ | ||
28 | unsigned char c_line; /* line discipline */ | ||
29 | unsigned char c_cc[NCC]; /* control characters */ | ||
30 | }; | ||
31 | |||
32 | /* modem lines */ | ||
33 | #define TIOCM_LE 0x001 | ||
34 | #define TIOCM_DTR 0x002 | ||
35 | #define TIOCM_RTS 0x004 | ||
36 | #define TIOCM_ST 0x008 | ||
37 | #define TIOCM_SR 0x010 | ||
38 | #define TIOCM_CTS 0x020 | ||
39 | #define TIOCM_CAR 0x040 | ||
40 | #define TIOCM_RNG 0x080 | ||
41 | #define TIOCM_DSR 0x100 | ||
42 | #define TIOCM_CD TIOCM_CAR | ||
43 | #define TIOCM_RI TIOCM_RNG | ||
44 | #define TIOCM_OUT1 0x2000 | ||
45 | #define TIOCM_OUT2 0x4000 | ||
46 | #define TIOCM_LOOP 0x8000 | ||
47 | |||
48 | /* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ | ||
49 | |||
50 | #ifdef __KERNEL__ | ||
51 | |||
52 | /* intr=^C quit=^\ erase=del kill=^U | ||
53 | eof=^D vtime=\0 vmin=\1 sxtc=\0 | ||
54 | start=^Q stop=^S susp=^Z eol=\0 | ||
55 | reprint=^R discard=^U werase=^W lnext=^V | ||
56 | eol2=\0 | ||
57 | */ | ||
58 | #define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" | ||
59 | |||
60 | #define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios2)) | ||
61 | #define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios2)) | ||
62 | |||
63 | #include <asm-generic/termios.h> | ||
64 | |||
65 | #endif /* __KERNEL__ */ | ||
66 | |||
67 | #endif /* _S390_TERMIOS_H */ | ||
diff --git a/arch/s390/include/asm/thread_info.h b/arch/s390/include/asm/thread_info.h new file mode 100644 index 000000000000..91a8f93ad355 --- /dev/null +++ b/arch/s390/include/asm/thread_info.h | |||
@@ -0,0 +1,118 @@ | |||
1 | /* | ||
2 | * include/asm-s390/thread_info.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) IBM Corp. 2002,2006 | ||
6 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
7 | */ | ||
8 | |||
9 | #ifndef _ASM_THREAD_INFO_H | ||
10 | #define _ASM_THREAD_INFO_H | ||
11 | |||
12 | #ifdef __KERNEL__ | ||
13 | |||
14 | /* | ||
15 | * Size of kernel stack for each process | ||
16 | */ | ||
17 | #ifndef __s390x__ | ||
18 | #ifndef __SMALL_STACK | ||
19 | #define THREAD_ORDER 1 | ||
20 | #define ASYNC_ORDER 1 | ||
21 | #else | ||
22 | #define THREAD_ORDER 0 | ||
23 | #define ASYNC_ORDER 0 | ||
24 | #endif | ||
25 | #else /* __s390x__ */ | ||
26 | #ifndef __SMALL_STACK | ||
27 | #define THREAD_ORDER 2 | ||
28 | #define ASYNC_ORDER 2 | ||
29 | #else | ||
30 | #define THREAD_ORDER 1 | ||
31 | #define ASYNC_ORDER 1 | ||
32 | #endif | ||
33 | #endif /* __s390x__ */ | ||
34 | |||
35 | #define THREAD_SIZE (PAGE_SIZE << THREAD_ORDER) | ||
36 | #define ASYNC_SIZE (PAGE_SIZE << ASYNC_ORDER) | ||
37 | |||
38 | #ifndef __ASSEMBLY__ | ||
39 | #include <asm/processor.h> | ||
40 | #include <asm/lowcore.h> | ||
41 | |||
42 | /* | ||
43 | * low level task data that entry.S needs immediate access to | ||
44 | * - this struct should fit entirely inside of one cache line | ||
45 | * - this struct shares the supervisor stack pages | ||
46 | * - if the contents of this structure are changed, the assembly constants must also be changed | ||
47 | */ | ||
48 | struct thread_info { | ||
49 | struct task_struct *task; /* main task structure */ | ||
50 | struct exec_domain *exec_domain; /* execution domain */ | ||
51 | unsigned long flags; /* low level flags */ | ||
52 | unsigned int cpu; /* current CPU */ | ||
53 | int preempt_count; /* 0 => preemptable, <0 => BUG */ | ||
54 | struct restart_block restart_block; | ||
55 | }; | ||
56 | |||
57 | /* | ||
58 | * macros/functions for gaining access to the thread information structure | ||
59 | */ | ||
60 | #define INIT_THREAD_INFO(tsk) \ | ||
61 | { \ | ||
62 | .task = &tsk, \ | ||
63 | .exec_domain = &default_exec_domain, \ | ||
64 | .flags = 0, \ | ||
65 | .cpu = 0, \ | ||
66 | .preempt_count = 1, \ | ||
67 | .restart_block = { \ | ||
68 | .fn = do_no_restart_syscall, \ | ||
69 | }, \ | ||
70 | } | ||
71 | |||
72 | #define init_thread_info (init_thread_union.thread_info) | ||
73 | #define init_stack (init_thread_union.stack) | ||
74 | |||
75 | /* how to get the thread information struct from C */ | ||
76 | static inline struct thread_info *current_thread_info(void) | ||
77 | { | ||
78 | return (struct thread_info *)((*(unsigned long *) __LC_KERNEL_STACK)-THREAD_SIZE); | ||
79 | } | ||
80 | |||
81 | #define THREAD_SIZE_ORDER THREAD_ORDER | ||
82 | |||
83 | #endif | ||
84 | |||
85 | /* | ||
86 | * thread information flags bit numbers | ||
87 | */ | ||
88 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ | ||
89 | #define TIF_SIGPENDING 2 /* signal pending */ | ||
90 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ | ||
91 | #define TIF_RESTART_SVC 4 /* restart svc with new svc number */ | ||
92 | #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ | ||
93 | #define TIF_SINGLE_STEP 6 /* deliver sigtrap on return to user */ | ||
94 | #define TIF_MCCK_PENDING 7 /* machine check handling is pending */ | ||
95 | #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ | ||
96 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling | ||
97 | TIF_NEED_RESCHED */ | ||
98 | #define TIF_31BIT 18 /* 32bit process */ | ||
99 | #define TIF_MEMDIE 19 | ||
100 | #define TIF_RESTORE_SIGMASK 20 /* restore signal mask in do_signal() */ | ||
101 | |||
102 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | ||
103 | #define _TIF_RESTORE_SIGMASK (1<<TIF_RESTORE_SIGMASK) | ||
104 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) | ||
105 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) | ||
106 | #define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC) | ||
107 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) | ||
108 | #define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP) | ||
109 | #define _TIF_MCCK_PENDING (1<<TIF_MCCK_PENDING) | ||
110 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) | ||
111 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | ||
112 | #define _TIF_31BIT (1<<TIF_31BIT) | ||
113 | |||
114 | #endif /* __KERNEL__ */ | ||
115 | |||
116 | #define PREEMPT_ACTIVE 0x4000000 | ||
117 | |||
118 | #endif /* _ASM_THREAD_INFO_H */ | ||
diff --git a/arch/s390/include/asm/timer.h b/arch/s390/include/asm/timer.h new file mode 100644 index 000000000000..d98d79e35cd6 --- /dev/null +++ b/arch/s390/include/asm/timer.h | |||
@@ -0,0 +1,65 @@ | |||
1 | /* | ||
2 | * include/asm-s390/timer.h | ||
3 | * | ||
4 | * (C) Copyright IBM Corp. 2003,2006 | ||
5 | * Virtual CPU timer | ||
6 | * | ||
7 | * Author: Jan Glauber (jang@de.ibm.com) | ||
8 | */ | ||
9 | |||
10 | #ifndef _ASM_S390_TIMER_H | ||
11 | #define _ASM_S390_TIMER_H | ||
12 | |||
13 | #ifdef __KERNEL__ | ||
14 | |||
15 | #include <linux/timer.h> | ||
16 | |||
17 | #define VTIMER_MAX_SLICE (0x7ffffffffffff000LL) | ||
18 | |||
19 | struct vtimer_list { | ||
20 | struct list_head entry; | ||
21 | |||
22 | int cpu; | ||
23 | __u64 expires; | ||
24 | __u64 interval; | ||
25 | |||
26 | spinlock_t lock; | ||
27 | unsigned long magic; | ||
28 | |||
29 | void (*function)(unsigned long); | ||
30 | unsigned long data; | ||
31 | }; | ||
32 | |||
33 | /* the offset value will wrap after ca. 71 years */ | ||
34 | struct vtimer_queue { | ||
35 | struct list_head list; | ||
36 | spinlock_t lock; | ||
37 | __u64 to_expire; /* current event expire time */ | ||
38 | __u64 offset; /* list offset to zero */ | ||
39 | __u64 idle; /* temp var for idle */ | ||
40 | }; | ||
41 | |||
42 | extern void init_virt_timer(struct vtimer_list *timer); | ||
43 | extern void add_virt_timer(void *new); | ||
44 | extern void add_virt_timer_periodic(void *new); | ||
45 | extern int mod_virt_timer(struct vtimer_list *timer, __u64 expires); | ||
46 | extern int del_virt_timer(struct vtimer_list *timer); | ||
47 | |||
48 | extern void init_cpu_vtimer(void); | ||
49 | extern void vtime_init(void); | ||
50 | |||
51 | #ifdef CONFIG_VIRT_TIMER | ||
52 | |||
53 | extern void vtime_start_cpu_timer(void); | ||
54 | extern void vtime_stop_cpu_timer(void); | ||
55 | |||
56 | #else | ||
57 | |||
58 | static inline void vtime_start_cpu_timer(void) { } | ||
59 | static inline void vtime_stop_cpu_timer(void) { } | ||
60 | |||
61 | #endif /* CONFIG_VIRT_TIMER */ | ||
62 | |||
63 | #endif /* __KERNEL__ */ | ||
64 | |||
65 | #endif /* _ASM_S390_TIMER_H */ | ||
diff --git a/arch/s390/include/asm/timex.h b/arch/s390/include/asm/timex.h new file mode 100644 index 000000000000..d744c3d62de5 --- /dev/null +++ b/arch/s390/include/asm/timex.h | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | * include/asm-s390/timex.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * | ||
7 | * Derived from "include/asm-i386/timex.h" | ||
8 | * Copyright (C) 1992, Linus Torvalds | ||
9 | */ | ||
10 | |||
11 | #ifndef _ASM_S390_TIMEX_H | ||
12 | #define _ASM_S390_TIMEX_H | ||
13 | |||
14 | /* Inline functions for clock register access. */ | ||
15 | static inline int set_clock(__u64 time) | ||
16 | { | ||
17 | int cc; | ||
18 | |||
19 | asm volatile( | ||
20 | " sck 0(%2)\n" | ||
21 | " ipm %0\n" | ||
22 | " srl %0,28\n" | ||
23 | : "=d" (cc) : "m" (time), "a" (&time) : "cc"); | ||
24 | return cc; | ||
25 | } | ||
26 | |||
27 | static inline int store_clock(__u64 *time) | ||
28 | { | ||
29 | int cc; | ||
30 | |||
31 | asm volatile( | ||
32 | " stck 0(%2)\n" | ||
33 | " ipm %0\n" | ||
34 | " srl %0,28\n" | ||
35 | : "=d" (cc), "=m" (*time) : "a" (time) : "cc"); | ||
36 | return cc; | ||
37 | } | ||
38 | |||
39 | static inline void set_clock_comparator(__u64 time) | ||
40 | { | ||
41 | asm volatile("sckc 0(%1)" : : "m" (time), "a" (&time)); | ||
42 | } | ||
43 | |||
44 | static inline void store_clock_comparator(__u64 *time) | ||
45 | { | ||
46 | asm volatile("stckc 0(%1)" : "=m" (*time) : "a" (time)); | ||
47 | } | ||
48 | |||
49 | #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ | ||
50 | |||
51 | typedef unsigned long long cycles_t; | ||
52 | |||
53 | static inline unsigned long long get_clock (void) | ||
54 | { | ||
55 | unsigned long long clk; | ||
56 | |||
57 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | ||
58 | asm volatile("stck %0" : "=Q" (clk) : : "cc"); | ||
59 | #else /* __GNUC__ */ | ||
60 | asm volatile("stck 0(%1)" : "=m" (clk) : "a" (&clk) : "cc"); | ||
61 | #endif /* __GNUC__ */ | ||
62 | return clk; | ||
63 | } | ||
64 | |||
65 | static inline unsigned long long get_clock_xt(void) | ||
66 | { | ||
67 | unsigned char clk[16]; | ||
68 | |||
69 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | ||
70 | asm volatile("stcke %0" : "=Q" (clk) : : "cc"); | ||
71 | #else /* __GNUC__ */ | ||
72 | asm volatile("stcke 0(%1)" : "=m" (clk) | ||
73 | : "a" (clk) : "cc"); | ||
74 | #endif /* __GNUC__ */ | ||
75 | |||
76 | return *((unsigned long long *)&clk[1]); | ||
77 | } | ||
78 | |||
79 | static inline cycles_t get_cycles(void) | ||
80 | { | ||
81 | return (cycles_t) get_clock() >> 2; | ||
82 | } | ||
83 | |||
84 | int get_sync_clock(unsigned long long *clock); | ||
85 | void init_cpu_timer(void); | ||
86 | unsigned long long monotonic_clock(void); | ||
87 | |||
88 | #endif | ||
diff --git a/arch/s390/include/asm/tlb.h b/arch/s390/include/asm/tlb.h new file mode 100644 index 000000000000..3d8a96d39d9d --- /dev/null +++ b/arch/s390/include/asm/tlb.h | |||
@@ -0,0 +1,156 @@ | |||
1 | #ifndef _S390_TLB_H | ||
2 | #define _S390_TLB_H | ||
3 | |||
4 | /* | ||
5 | * TLB flushing on s390 is complicated. The following requirement | ||
6 | * from the principles of operation is the most arduous: | ||
7 | * | ||
8 | * "A valid table entry must not be changed while it is attached | ||
9 | * to any CPU and may be used for translation by that CPU except to | ||
10 | * (1) invalidate the entry by using INVALIDATE PAGE TABLE ENTRY, | ||
11 | * or INVALIDATE DAT TABLE ENTRY, (2) alter bits 56-63 of a page | ||
12 | * table entry, or (3) make a change by means of a COMPARE AND SWAP | ||
13 | * AND PURGE instruction that purges the TLB." | ||
14 | * | ||
15 | * The modification of a pte of an active mm struct therefore is | ||
16 | * a two step process: i) invalidate the pte, ii) store the new pte. | ||
17 | * This is true for the page protection bit as well. | ||
18 | * The only possible optimization is to flush at the beginning of | ||
19 | * a tlb_gather_mmu cycle if the mm_struct is currently not in use. | ||
20 | * | ||
21 | * Pages used for the page tables is a different story. FIXME: more | ||
22 | */ | ||
23 | |||
24 | #include <linux/mm.h> | ||
25 | #include <linux/swap.h> | ||
26 | #include <asm/processor.h> | ||
27 | #include <asm/pgalloc.h> | ||
28 | #include <asm/smp.h> | ||
29 | #include <asm/tlbflush.h> | ||
30 | |||
31 | #ifndef CONFIG_SMP | ||
32 | #define TLB_NR_PTRS 1 | ||
33 | #else | ||
34 | #define TLB_NR_PTRS 508 | ||
35 | #endif | ||
36 | |||
37 | struct mmu_gather { | ||
38 | struct mm_struct *mm; | ||
39 | unsigned int fullmm; | ||
40 | unsigned int nr_ptes; | ||
41 | unsigned int nr_pxds; | ||
42 | void *array[TLB_NR_PTRS]; | ||
43 | }; | ||
44 | |||
45 | DECLARE_PER_CPU(struct mmu_gather, mmu_gathers); | ||
46 | |||
47 | static inline struct mmu_gather *tlb_gather_mmu(struct mm_struct *mm, | ||
48 | unsigned int full_mm_flush) | ||
49 | { | ||
50 | struct mmu_gather *tlb = &get_cpu_var(mmu_gathers); | ||
51 | |||
52 | tlb->mm = mm; | ||
53 | tlb->fullmm = full_mm_flush || (num_online_cpus() == 1) || | ||
54 | (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm); | ||
55 | tlb->nr_ptes = 0; | ||
56 | tlb->nr_pxds = TLB_NR_PTRS; | ||
57 | if (tlb->fullmm) | ||
58 | __tlb_flush_mm(mm); | ||
59 | return tlb; | ||
60 | } | ||
61 | |||
62 | static inline void tlb_flush_mmu(struct mmu_gather *tlb, | ||
63 | unsigned long start, unsigned long end) | ||
64 | { | ||
65 | if (!tlb->fullmm && (tlb->nr_ptes > 0 || tlb->nr_pxds < TLB_NR_PTRS)) | ||
66 | __tlb_flush_mm(tlb->mm); | ||
67 | while (tlb->nr_ptes > 0) | ||
68 | pte_free(tlb->mm, tlb->array[--tlb->nr_ptes]); | ||
69 | while (tlb->nr_pxds < TLB_NR_PTRS) | ||
70 | /* pgd_free frees the pointer as region or segment table */ | ||
71 | pgd_free(tlb->mm, tlb->array[tlb->nr_pxds++]); | ||
72 | } | ||
73 | |||
74 | static inline void tlb_finish_mmu(struct mmu_gather *tlb, | ||
75 | unsigned long start, unsigned long end) | ||
76 | { | ||
77 | tlb_flush_mmu(tlb, start, end); | ||
78 | |||
79 | /* keep the page table cache within bounds */ | ||
80 | check_pgt_cache(); | ||
81 | |||
82 | put_cpu_var(mmu_gathers); | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * Release the page cache reference for a pte removed by | ||
87 | * tlb_ptep_clear_flush. In both flush modes the tlb fo a page cache page | ||
88 | * has already been freed, so just do free_page_and_swap_cache. | ||
89 | */ | ||
90 | static inline void tlb_remove_page(struct mmu_gather *tlb, struct page *page) | ||
91 | { | ||
92 | free_page_and_swap_cache(page); | ||
93 | } | ||
94 | |||
95 | /* | ||
96 | * pte_free_tlb frees a pte table and clears the CRSTE for the | ||
97 | * page table from the tlb. | ||
98 | */ | ||
99 | static inline void pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte) | ||
100 | { | ||
101 | if (!tlb->fullmm) { | ||
102 | tlb->array[tlb->nr_ptes++] = pte; | ||
103 | if (tlb->nr_ptes >= tlb->nr_pxds) | ||
104 | tlb_flush_mmu(tlb, 0, 0); | ||
105 | } else | ||
106 | pte_free(tlb->mm, pte); | ||
107 | } | ||
108 | |||
109 | /* | ||
110 | * pmd_free_tlb frees a pmd table and clears the CRSTE for the | ||
111 | * segment table entry from the tlb. | ||
112 | * If the mm uses a two level page table the single pmd is freed | ||
113 | * as the pgd. pmd_free_tlb checks the asce_limit against 2GB | ||
114 | * to avoid the double free of the pmd in this case. | ||
115 | */ | ||
116 | static inline void pmd_free_tlb(struct mmu_gather *tlb, pmd_t *pmd) | ||
117 | { | ||
118 | #ifdef __s390x__ | ||
119 | if (tlb->mm->context.asce_limit <= (1UL << 31)) | ||
120 | return; | ||
121 | if (!tlb->fullmm) { | ||
122 | tlb->array[--tlb->nr_pxds] = pmd; | ||
123 | if (tlb->nr_ptes >= tlb->nr_pxds) | ||
124 | tlb_flush_mmu(tlb, 0, 0); | ||
125 | } else | ||
126 | pmd_free(tlb->mm, pmd); | ||
127 | #endif | ||
128 | } | ||
129 | |||
130 | /* | ||
131 | * pud_free_tlb frees a pud table and clears the CRSTE for the | ||
132 | * region third table entry from the tlb. | ||
133 | * If the mm uses a three level page table the single pud is freed | ||
134 | * as the pgd. pud_free_tlb checks the asce_limit against 4TB | ||
135 | * to avoid the double free of the pud in this case. | ||
136 | */ | ||
137 | static inline void pud_free_tlb(struct mmu_gather *tlb, pud_t *pud) | ||
138 | { | ||
139 | #ifdef __s390x__ | ||
140 | if (tlb->mm->context.asce_limit <= (1UL << 42)) | ||
141 | return; | ||
142 | if (!tlb->fullmm) { | ||
143 | tlb->array[--tlb->nr_pxds] = pud; | ||
144 | if (tlb->nr_ptes >= tlb->nr_pxds) | ||
145 | tlb_flush_mmu(tlb, 0, 0); | ||
146 | } else | ||
147 | pud_free(tlb->mm, pud); | ||
148 | #endif | ||
149 | } | ||
150 | |||
151 | #define tlb_start_vma(tlb, vma) do { } while (0) | ||
152 | #define tlb_end_vma(tlb, vma) do { } while (0) | ||
153 | #define tlb_remove_tlb_entry(tlb, ptep, addr) do { } while (0) | ||
154 | #define tlb_migrate_finish(mm) do { } while (0) | ||
155 | |||
156 | #endif /* _S390_TLB_H */ | ||
diff --git a/arch/s390/include/asm/tlbflush.h b/arch/s390/include/asm/tlbflush.h new file mode 100644 index 000000000000..d60394b9745e --- /dev/null +++ b/arch/s390/include/asm/tlbflush.h | |||
@@ -0,0 +1,140 @@ | |||
1 | #ifndef _S390_TLBFLUSH_H | ||
2 | #define _S390_TLBFLUSH_H | ||
3 | |||
4 | #include <linux/mm.h> | ||
5 | #include <linux/sched.h> | ||
6 | #include <asm/processor.h> | ||
7 | #include <asm/pgalloc.h> | ||
8 | |||
9 | /* | ||
10 | * Flush all tlb entries on the local cpu. | ||
11 | */ | ||
12 | static inline void __tlb_flush_local(void) | ||
13 | { | ||
14 | asm volatile("ptlb" : : : "memory"); | ||
15 | } | ||
16 | |||
17 | #ifdef CONFIG_SMP | ||
18 | /* | ||
19 | * Flush all tlb entries on all cpus. | ||
20 | */ | ||
21 | void smp_ptlb_all(void); | ||
22 | |||
23 | static inline void __tlb_flush_global(void) | ||
24 | { | ||
25 | register unsigned long reg2 asm("2"); | ||
26 | register unsigned long reg3 asm("3"); | ||
27 | register unsigned long reg4 asm("4"); | ||
28 | long dummy; | ||
29 | |||
30 | #ifndef __s390x__ | ||
31 | if (!MACHINE_HAS_CSP) { | ||
32 | smp_ptlb_all(); | ||
33 | return; | ||
34 | } | ||
35 | #endif /* __s390x__ */ | ||
36 | |||
37 | dummy = 0; | ||
38 | reg2 = reg3 = 0; | ||
39 | reg4 = ((unsigned long) &dummy) + 1; | ||
40 | asm volatile( | ||
41 | " csp %0,%2" | ||
42 | : : "d" (reg2), "d" (reg3), "d" (reg4), "m" (dummy) : "cc" ); | ||
43 | } | ||
44 | |||
45 | static inline void __tlb_flush_full(struct mm_struct *mm) | ||
46 | { | ||
47 | cpumask_t local_cpumask; | ||
48 | |||
49 | preempt_disable(); | ||
50 | /* | ||
51 | * If the process only ran on the local cpu, do a local flush. | ||
52 | */ | ||
53 | local_cpumask = cpumask_of_cpu(smp_processor_id()); | ||
54 | if (cpus_equal(mm->cpu_vm_mask, local_cpumask)) | ||
55 | __tlb_flush_local(); | ||
56 | else | ||
57 | __tlb_flush_global(); | ||
58 | preempt_enable(); | ||
59 | } | ||
60 | #else | ||
61 | #define __tlb_flush_full(mm) __tlb_flush_local() | ||
62 | #endif | ||
63 | |||
64 | /* | ||
65 | * Flush all tlb entries of a page table on all cpus. | ||
66 | */ | ||
67 | static inline void __tlb_flush_idte(unsigned long asce) | ||
68 | { | ||
69 | asm volatile( | ||
70 | " .insn rrf,0xb98e0000,0,%0,%1,0" | ||
71 | : : "a" (2048), "a" (asce) : "cc" ); | ||
72 | } | ||
73 | |||
74 | static inline void __tlb_flush_mm(struct mm_struct * mm) | ||
75 | { | ||
76 | if (unlikely(cpus_empty(mm->cpu_vm_mask))) | ||
77 | return; | ||
78 | /* | ||
79 | * If the machine has IDTE we prefer to do a per mm flush | ||
80 | * on all cpus instead of doing a local flush if the mm | ||
81 | * only ran on the local cpu. | ||
82 | */ | ||
83 | if (MACHINE_HAS_IDTE) { | ||
84 | if (mm->context.noexec) | ||
85 | __tlb_flush_idte((unsigned long) | ||
86 | get_shadow_table(mm->pgd) | | ||
87 | mm->context.asce_bits); | ||
88 | __tlb_flush_idte((unsigned long) mm->pgd | | ||
89 | mm->context.asce_bits); | ||
90 | return; | ||
91 | } | ||
92 | __tlb_flush_full(mm); | ||
93 | } | ||
94 | |||
95 | static inline void __tlb_flush_mm_cond(struct mm_struct * mm) | ||
96 | { | ||
97 | if (atomic_read(&mm->mm_users) <= 1 && mm == current->active_mm) | ||
98 | __tlb_flush_mm(mm); | ||
99 | } | ||
100 | |||
101 | /* | ||
102 | * TLB flushing: | ||
103 | * flush_tlb() - flushes the current mm struct TLBs | ||
104 | * flush_tlb_all() - flushes all processes TLBs | ||
105 | * flush_tlb_mm(mm) - flushes the specified mm context TLB's | ||
106 | * flush_tlb_page(vma, vmaddr) - flushes one page | ||
107 | * flush_tlb_range(vma, start, end) - flushes a range of pages | ||
108 | * flush_tlb_kernel_range(start, end) - flushes a range of kernel pages | ||
109 | */ | ||
110 | |||
111 | /* | ||
112 | * flush_tlb_mm goes together with ptep_set_wrprotect for the | ||
113 | * copy_page_range operation and flush_tlb_range is related to | ||
114 | * ptep_get_and_clear for change_protection. ptep_set_wrprotect and | ||
115 | * ptep_get_and_clear do not flush the TLBs directly if the mm has | ||
116 | * only one user. At the end of the update the flush_tlb_mm and | ||
117 | * flush_tlb_range functions need to do the flush. | ||
118 | */ | ||
119 | #define flush_tlb() do { } while (0) | ||
120 | #define flush_tlb_all() do { } while (0) | ||
121 | #define flush_tlb_page(vma, addr) do { } while (0) | ||
122 | |||
123 | static inline void flush_tlb_mm(struct mm_struct *mm) | ||
124 | { | ||
125 | __tlb_flush_mm_cond(mm); | ||
126 | } | ||
127 | |||
128 | static inline void flush_tlb_range(struct vm_area_struct *vma, | ||
129 | unsigned long start, unsigned long end) | ||
130 | { | ||
131 | __tlb_flush_mm_cond(vma->vm_mm); | ||
132 | } | ||
133 | |||
134 | static inline void flush_tlb_kernel_range(unsigned long start, | ||
135 | unsigned long end) | ||
136 | { | ||
137 | __tlb_flush_mm(&init_mm); | ||
138 | } | ||
139 | |||
140 | #endif /* _S390_TLBFLUSH_H */ | ||
diff --git a/arch/s390/include/asm/todclk.h b/arch/s390/include/asm/todclk.h new file mode 100644 index 000000000000..c7f62055488a --- /dev/null +++ b/arch/s390/include/asm/todclk.h | |||
@@ -0,0 +1,23 @@ | |||
1 | /* | ||
2 | * File...........: linux/include/asm/todclk.h | ||
3 | * Author(s)......: Holger Smolinski <Holger.Smolinski@de.ibm.com> | ||
4 | * Bugreports.to..: <Linux390@de.ibm.com> | ||
5 | * (C) IBM Corporation, IBM Deutschland Entwicklung GmbH, 1999,2000 | ||
6 | * | ||
7 | * History of changes (starts July 2000) | ||
8 | */ | ||
9 | |||
10 | #ifndef __ASM_TODCLK_H | ||
11 | #define __ASM_TODCLK_H | ||
12 | |||
13 | #ifdef __KERNEL__ | ||
14 | |||
15 | #define TOD_uSEC (0x1000ULL) | ||
16 | #define TOD_mSEC (1000 * TOD_uSEC) | ||
17 | #define TOD_SEC (1000 * TOD_mSEC) | ||
18 | #define TOD_MIN (60 * TOD_SEC) | ||
19 | #define TOD_HOUR (60 * TOD_MIN) | ||
20 | |||
21 | #endif | ||
22 | |||
23 | #endif | ||
diff --git a/arch/s390/include/asm/topology.h b/arch/s390/include/asm/topology.h new file mode 100644 index 000000000000..d96c91643458 --- /dev/null +++ b/arch/s390/include/asm/topology.h | |||
@@ -0,0 +1,33 @@ | |||
1 | #ifndef _ASM_S390_TOPOLOGY_H | ||
2 | #define _ASM_S390_TOPOLOGY_H | ||
3 | |||
4 | #include <linux/cpumask.h> | ||
5 | |||
6 | #define mc_capable() (1) | ||
7 | |||
8 | cpumask_t cpu_coregroup_map(unsigned int cpu); | ||
9 | |||
10 | extern cpumask_t cpu_core_map[NR_CPUS]; | ||
11 | |||
12 | #define topology_core_siblings(cpu) (cpu_core_map[cpu]) | ||
13 | |||
14 | int topology_set_cpu_management(int fc); | ||
15 | void topology_schedule_update(void); | ||
16 | |||
17 | #define POLARIZATION_UNKNWN (-1) | ||
18 | #define POLARIZATION_HRZ (0) | ||
19 | #define POLARIZATION_VL (1) | ||
20 | #define POLARIZATION_VM (2) | ||
21 | #define POLARIZATION_VH (3) | ||
22 | |||
23 | #ifdef CONFIG_SMP | ||
24 | void s390_init_cpu_topology(void); | ||
25 | #else | ||
26 | static inline void s390_init_cpu_topology(void) | ||
27 | { | ||
28 | }; | ||
29 | #endif | ||
30 | |||
31 | #include <asm-generic/topology.h> | ||
32 | |||
33 | #endif /* _ASM_S390_TOPOLOGY_H */ | ||
diff --git a/arch/s390/include/asm/types.h b/arch/s390/include/asm/types.h new file mode 100644 index 000000000000..41c547656130 --- /dev/null +++ b/arch/s390/include/asm/types.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /* | ||
2 | * include/asm-s390/types.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/types.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef _S390_TYPES_H | ||
10 | #define _S390_TYPES_H | ||
11 | |||
12 | #ifndef __s390x__ | ||
13 | # include <asm-generic/int-ll64.h> | ||
14 | #else | ||
15 | # include <asm-generic/int-l64.h> | ||
16 | #endif | ||
17 | |||
18 | #ifndef __ASSEMBLY__ | ||
19 | |||
20 | typedef unsigned short umode_t; | ||
21 | |||
22 | /* A address type so that arithmetic can be done on it & it can be upgraded to | ||
23 | 64 bit when necessary | ||
24 | */ | ||
25 | typedef unsigned long addr_t; | ||
26 | typedef __signed__ long saddr_t; | ||
27 | |||
28 | #endif /* __ASSEMBLY__ */ | ||
29 | |||
30 | /* | ||
31 | * These aren't exported outside the kernel to avoid name space clashes | ||
32 | */ | ||
33 | #ifdef __KERNEL__ | ||
34 | |||
35 | #ifndef __s390x__ | ||
36 | #define BITS_PER_LONG 32 | ||
37 | #else | ||
38 | #define BITS_PER_LONG 64 | ||
39 | #endif | ||
40 | |||
41 | #ifndef __ASSEMBLY__ | ||
42 | |||
43 | typedef u64 dma64_addr_t; | ||
44 | #ifdef __s390x__ | ||
45 | /* DMA addresses come in 32-bit and 64-bit flavours. */ | ||
46 | typedef u64 dma_addr_t; | ||
47 | #else | ||
48 | typedef u32 dma_addr_t; | ||
49 | #endif | ||
50 | |||
51 | #ifndef __s390x__ | ||
52 | typedef union { | ||
53 | unsigned long long pair; | ||
54 | struct { | ||
55 | unsigned long even; | ||
56 | unsigned long odd; | ||
57 | } subreg; | ||
58 | } register_pair; | ||
59 | |||
60 | #endif /* ! __s390x__ */ | ||
61 | #endif /* __ASSEMBLY__ */ | ||
62 | #endif /* __KERNEL__ */ | ||
63 | #endif /* _S390_TYPES_H */ | ||
diff --git a/arch/s390/include/asm/uaccess.h b/arch/s390/include/asm/uaccess.h new file mode 100644 index 000000000000..0235970278f0 --- /dev/null +++ b/arch/s390/include/asm/uaccess.h | |||
@@ -0,0 +1,363 @@ | |||
1 | /* | ||
2 | * include/asm-s390/uaccess.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * Author(s): Hartmut Penner (hp@de.ibm.com), | ||
7 | * Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
8 | * | ||
9 | * Derived from "include/asm-i386/uaccess.h" | ||
10 | */ | ||
11 | #ifndef __S390_UACCESS_H | ||
12 | #define __S390_UACCESS_H | ||
13 | |||
14 | /* | ||
15 | * User space memory access functions | ||
16 | */ | ||
17 | #include <linux/sched.h> | ||
18 | #include <linux/errno.h> | ||
19 | |||
20 | #define VERIFY_READ 0 | ||
21 | #define VERIFY_WRITE 1 | ||
22 | |||
23 | |||
24 | /* | ||
25 | * The fs value determines whether argument validity checking should be | ||
26 | * performed or not. If get_fs() == USER_DS, checking is performed, with | ||
27 | * get_fs() == KERNEL_DS, checking is bypassed. | ||
28 | * | ||
29 | * For historical reasons, these macros are grossly misnamed. | ||
30 | */ | ||
31 | |||
32 | #define MAKE_MM_SEG(a) ((mm_segment_t) { (a) }) | ||
33 | |||
34 | |||
35 | #define KERNEL_DS MAKE_MM_SEG(0) | ||
36 | #define USER_DS MAKE_MM_SEG(1) | ||
37 | |||
38 | #define get_ds() (KERNEL_DS) | ||
39 | #define get_fs() (current->thread.mm_segment) | ||
40 | |||
41 | #define set_fs(x) \ | ||
42 | ({ \ | ||
43 | unsigned long __pto; \ | ||
44 | current->thread.mm_segment = (x); \ | ||
45 | __pto = current->thread.mm_segment.ar4 ? \ | ||
46 | S390_lowcore.user_asce : S390_lowcore.kernel_asce; \ | ||
47 | __ctl_load(__pto, 7, 7); \ | ||
48 | }) | ||
49 | |||
50 | #define segment_eq(a,b) ((a).ar4 == (b).ar4) | ||
51 | |||
52 | |||
53 | static inline int __access_ok(const void __user *addr, unsigned long size) | ||
54 | { | ||
55 | return 1; | ||
56 | } | ||
57 | #define access_ok(type,addr,size) __access_ok(addr,size) | ||
58 | |||
59 | /* | ||
60 | * The exception table consists of pairs of addresses: the first is the | ||
61 | * address of an instruction that is allowed to fault, and the second is | ||
62 | * the address at which the program should continue. No registers are | ||
63 | * modified, so it is entirely up to the continuation code to figure out | ||
64 | * what to do. | ||
65 | * | ||
66 | * All the routines below use bits of fixup code that are out of line | ||
67 | * with the main instruction path. This means when everything is well, | ||
68 | * we don't even have to jump over them. Further, they do not intrude | ||
69 | * on our cache or tlb entries. | ||
70 | */ | ||
71 | |||
72 | struct exception_table_entry | ||
73 | { | ||
74 | unsigned long insn, fixup; | ||
75 | }; | ||
76 | |||
77 | struct uaccess_ops { | ||
78 | size_t (*copy_from_user)(size_t, const void __user *, void *); | ||
79 | size_t (*copy_from_user_small)(size_t, const void __user *, void *); | ||
80 | size_t (*copy_to_user)(size_t, void __user *, const void *); | ||
81 | size_t (*copy_to_user_small)(size_t, void __user *, const void *); | ||
82 | size_t (*copy_in_user)(size_t, void __user *, const void __user *); | ||
83 | size_t (*clear_user)(size_t, void __user *); | ||
84 | size_t (*strnlen_user)(size_t, const char __user *); | ||
85 | size_t (*strncpy_from_user)(size_t, const char __user *, char *); | ||
86 | int (*futex_atomic_op)(int op, int __user *, int oparg, int *old); | ||
87 | int (*futex_atomic_cmpxchg)(int __user *, int old, int new); | ||
88 | }; | ||
89 | |||
90 | extern struct uaccess_ops uaccess; | ||
91 | extern struct uaccess_ops uaccess_std; | ||
92 | extern struct uaccess_ops uaccess_mvcos; | ||
93 | extern struct uaccess_ops uaccess_mvcos_switch; | ||
94 | extern struct uaccess_ops uaccess_pt; | ||
95 | |||
96 | static inline int __put_user_fn(size_t size, void __user *ptr, void *x) | ||
97 | { | ||
98 | size = uaccess.copy_to_user_small(size, ptr, x); | ||
99 | return size ? -EFAULT : size; | ||
100 | } | ||
101 | |||
102 | static inline int __get_user_fn(size_t size, const void __user *ptr, void *x) | ||
103 | { | ||
104 | size = uaccess.copy_from_user_small(size, ptr, x); | ||
105 | return size ? -EFAULT : size; | ||
106 | } | ||
107 | |||
108 | /* | ||
109 | * These are the main single-value transfer routines. They automatically | ||
110 | * use the right size if we just have the right pointer type. | ||
111 | */ | ||
112 | #define __put_user(x, ptr) \ | ||
113 | ({ \ | ||
114 | __typeof__(*(ptr)) __x = (x); \ | ||
115 | int __pu_err = -EFAULT; \ | ||
116 | __chk_user_ptr(ptr); \ | ||
117 | switch (sizeof (*(ptr))) { \ | ||
118 | case 1: \ | ||
119 | case 2: \ | ||
120 | case 4: \ | ||
121 | case 8: \ | ||
122 | __pu_err = __put_user_fn(sizeof (*(ptr)), \ | ||
123 | ptr, &__x); \ | ||
124 | break; \ | ||
125 | default: \ | ||
126 | __put_user_bad(); \ | ||
127 | break; \ | ||
128 | } \ | ||
129 | __pu_err; \ | ||
130 | }) | ||
131 | |||
132 | #define put_user(x, ptr) \ | ||
133 | ({ \ | ||
134 | might_sleep(); \ | ||
135 | __put_user(x, ptr); \ | ||
136 | }) | ||
137 | |||
138 | |||
139 | extern int __put_user_bad(void) __attribute__((noreturn)); | ||
140 | |||
141 | #define __get_user(x, ptr) \ | ||
142 | ({ \ | ||
143 | int __gu_err = -EFAULT; \ | ||
144 | __chk_user_ptr(ptr); \ | ||
145 | switch (sizeof(*(ptr))) { \ | ||
146 | case 1: { \ | ||
147 | unsigned char __x; \ | ||
148 | __gu_err = __get_user_fn(sizeof (*(ptr)), \ | ||
149 | ptr, &__x); \ | ||
150 | (x) = *(__force __typeof__(*(ptr)) *) &__x; \ | ||
151 | break; \ | ||
152 | }; \ | ||
153 | case 2: { \ | ||
154 | unsigned short __x; \ | ||
155 | __gu_err = __get_user_fn(sizeof (*(ptr)), \ | ||
156 | ptr, &__x); \ | ||
157 | (x) = *(__force __typeof__(*(ptr)) *) &__x; \ | ||
158 | break; \ | ||
159 | }; \ | ||
160 | case 4: { \ | ||
161 | unsigned int __x; \ | ||
162 | __gu_err = __get_user_fn(sizeof (*(ptr)), \ | ||
163 | ptr, &__x); \ | ||
164 | (x) = *(__force __typeof__(*(ptr)) *) &__x; \ | ||
165 | break; \ | ||
166 | }; \ | ||
167 | case 8: { \ | ||
168 | unsigned long long __x; \ | ||
169 | __gu_err = __get_user_fn(sizeof (*(ptr)), \ | ||
170 | ptr, &__x); \ | ||
171 | (x) = *(__force __typeof__(*(ptr)) *) &__x; \ | ||
172 | break; \ | ||
173 | }; \ | ||
174 | default: \ | ||
175 | __get_user_bad(); \ | ||
176 | break; \ | ||
177 | } \ | ||
178 | __gu_err; \ | ||
179 | }) | ||
180 | |||
181 | #define get_user(x, ptr) \ | ||
182 | ({ \ | ||
183 | might_sleep(); \ | ||
184 | __get_user(x, ptr); \ | ||
185 | }) | ||
186 | |||
187 | extern int __get_user_bad(void) __attribute__((noreturn)); | ||
188 | |||
189 | #define __put_user_unaligned __put_user | ||
190 | #define __get_user_unaligned __get_user | ||
191 | |||
192 | /** | ||
193 | * __copy_to_user: - Copy a block of data into user space, with less checking. | ||
194 | * @to: Destination address, in user space. | ||
195 | * @from: Source address, in kernel space. | ||
196 | * @n: Number of bytes to copy. | ||
197 | * | ||
198 | * Context: User context only. This function may sleep. | ||
199 | * | ||
200 | * Copy data from kernel space to user space. Caller must check | ||
201 | * the specified block with access_ok() before calling this function. | ||
202 | * | ||
203 | * Returns number of bytes that could not be copied. | ||
204 | * On success, this will be zero. | ||
205 | */ | ||
206 | static inline unsigned long __must_check | ||
207 | __copy_to_user(void __user *to, const void *from, unsigned long n) | ||
208 | { | ||
209 | if (__builtin_constant_p(n) && (n <= 256)) | ||
210 | return uaccess.copy_to_user_small(n, to, from); | ||
211 | else | ||
212 | return uaccess.copy_to_user(n, to, from); | ||
213 | } | ||
214 | |||
215 | #define __copy_to_user_inatomic __copy_to_user | ||
216 | #define __copy_from_user_inatomic __copy_from_user | ||
217 | |||
218 | /** | ||
219 | * copy_to_user: - Copy a block of data into user space. | ||
220 | * @to: Destination address, in user space. | ||
221 | * @from: Source address, in kernel space. | ||
222 | * @n: Number of bytes to copy. | ||
223 | * | ||
224 | * Context: User context only. This function may sleep. | ||
225 | * | ||
226 | * Copy data from kernel space to user space. | ||
227 | * | ||
228 | * Returns number of bytes that could not be copied. | ||
229 | * On success, this will be zero. | ||
230 | */ | ||
231 | static inline unsigned long __must_check | ||
232 | copy_to_user(void __user *to, const void *from, unsigned long n) | ||
233 | { | ||
234 | might_sleep(); | ||
235 | if (access_ok(VERIFY_WRITE, to, n)) | ||
236 | n = __copy_to_user(to, from, n); | ||
237 | return n; | ||
238 | } | ||
239 | |||
240 | /** | ||
241 | * __copy_from_user: - Copy a block of data from user space, with less checking. | ||
242 | * @to: Destination address, in kernel space. | ||
243 | * @from: Source address, in user space. | ||
244 | * @n: Number of bytes to copy. | ||
245 | * | ||
246 | * Context: User context only. This function may sleep. | ||
247 | * | ||
248 | * Copy data from user space to kernel space. Caller must check | ||
249 | * the specified block with access_ok() before calling this function. | ||
250 | * | ||
251 | * Returns number of bytes that could not be copied. | ||
252 | * On success, this will be zero. | ||
253 | * | ||
254 | * If some data could not be copied, this function will pad the copied | ||
255 | * data to the requested size using zero bytes. | ||
256 | */ | ||
257 | static inline unsigned long __must_check | ||
258 | __copy_from_user(void *to, const void __user *from, unsigned long n) | ||
259 | { | ||
260 | if (__builtin_constant_p(n) && (n <= 256)) | ||
261 | return uaccess.copy_from_user_small(n, from, to); | ||
262 | else | ||
263 | return uaccess.copy_from_user(n, from, to); | ||
264 | } | ||
265 | |||
266 | /** | ||
267 | * copy_from_user: - Copy a block of data from user space. | ||
268 | * @to: Destination address, in kernel space. | ||
269 | * @from: Source address, in user space. | ||
270 | * @n: Number of bytes to copy. | ||
271 | * | ||
272 | * Context: User context only. This function may sleep. | ||
273 | * | ||
274 | * Copy data from user space to kernel space. | ||
275 | * | ||
276 | * Returns number of bytes that could not be copied. | ||
277 | * On success, this will be zero. | ||
278 | * | ||
279 | * If some data could not be copied, this function will pad the copied | ||
280 | * data to the requested size using zero bytes. | ||
281 | */ | ||
282 | static inline unsigned long __must_check | ||
283 | copy_from_user(void *to, const void __user *from, unsigned long n) | ||
284 | { | ||
285 | might_sleep(); | ||
286 | if (access_ok(VERIFY_READ, from, n)) | ||
287 | n = __copy_from_user(to, from, n); | ||
288 | else | ||
289 | memset(to, 0, n); | ||
290 | return n; | ||
291 | } | ||
292 | |||
293 | static inline unsigned long __must_check | ||
294 | __copy_in_user(void __user *to, const void __user *from, unsigned long n) | ||
295 | { | ||
296 | return uaccess.copy_in_user(n, to, from); | ||
297 | } | ||
298 | |||
299 | static inline unsigned long __must_check | ||
300 | copy_in_user(void __user *to, const void __user *from, unsigned long n) | ||
301 | { | ||
302 | might_sleep(); | ||
303 | if (__access_ok(from,n) && __access_ok(to,n)) | ||
304 | n = __copy_in_user(to, from, n); | ||
305 | return n; | ||
306 | } | ||
307 | |||
308 | /* | ||
309 | * Copy a null terminated string from userspace. | ||
310 | */ | ||
311 | static inline long __must_check | ||
312 | strncpy_from_user(char *dst, const char __user *src, long count) | ||
313 | { | ||
314 | long res = -EFAULT; | ||
315 | might_sleep(); | ||
316 | if (access_ok(VERIFY_READ, src, 1)) | ||
317 | res = uaccess.strncpy_from_user(count, src, dst); | ||
318 | return res; | ||
319 | } | ||
320 | |||
321 | static inline unsigned long | ||
322 | strnlen_user(const char __user * src, unsigned long n) | ||
323 | { | ||
324 | might_sleep(); | ||
325 | return uaccess.strnlen_user(n, src); | ||
326 | } | ||
327 | |||
328 | /** | ||
329 | * strlen_user: - Get the size of a string in user space. | ||
330 | * @str: The string to measure. | ||
331 | * | ||
332 | * Context: User context only. This function may sleep. | ||
333 | * | ||
334 | * Get the size of a NUL-terminated string in user space. | ||
335 | * | ||
336 | * Returns the size of the string INCLUDING the terminating NUL. | ||
337 | * On exception, returns 0. | ||
338 | * | ||
339 | * If there is a limit on the length of a valid string, you may wish to | ||
340 | * consider using strnlen_user() instead. | ||
341 | */ | ||
342 | #define strlen_user(str) strnlen_user(str, ~0UL) | ||
343 | |||
344 | /* | ||
345 | * Zero Userspace | ||
346 | */ | ||
347 | |||
348 | static inline unsigned long __must_check | ||
349 | __clear_user(void __user *to, unsigned long n) | ||
350 | { | ||
351 | return uaccess.clear_user(n, to); | ||
352 | } | ||
353 | |||
354 | static inline unsigned long __must_check | ||
355 | clear_user(void __user *to, unsigned long n) | ||
356 | { | ||
357 | might_sleep(); | ||
358 | if (access_ok(VERIFY_WRITE, to, n)) | ||
359 | n = uaccess.clear_user(n, to); | ||
360 | return n; | ||
361 | } | ||
362 | |||
363 | #endif /* __S390_UACCESS_H */ | ||
diff --git a/arch/s390/include/asm/ucontext.h b/arch/s390/include/asm/ucontext.h new file mode 100644 index 000000000000..d69bec0b03f5 --- /dev/null +++ b/arch/s390/include/asm/ucontext.h | |||
@@ -0,0 +1,20 @@ | |||
1 | /* | ||
2 | * include/asm-s390/ucontext.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/ucontext.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef _ASM_S390_UCONTEXT_H | ||
10 | #define _ASM_S390_UCONTEXT_H | ||
11 | |||
12 | struct ucontext { | ||
13 | unsigned long uc_flags; | ||
14 | struct ucontext *uc_link; | ||
15 | stack_t uc_stack; | ||
16 | _sigregs uc_mcontext; | ||
17 | sigset_t uc_sigmask; /* mask last for extensibility */ | ||
18 | }; | ||
19 | |||
20 | #endif /* !_ASM_S390_UCONTEXT_H */ | ||
diff --git a/arch/s390/include/asm/unaligned.h b/arch/s390/include/asm/unaligned.h new file mode 100644 index 000000000000..da9627afe5d8 --- /dev/null +++ b/arch/s390/include/asm/unaligned.h | |||
@@ -0,0 +1,13 @@ | |||
1 | #ifndef _ASM_S390_UNALIGNED_H | ||
2 | #define _ASM_S390_UNALIGNED_H | ||
3 | |||
4 | /* | ||
5 | * The S390 can do unaligned accesses itself. | ||
6 | */ | ||
7 | #include <linux/unaligned/access_ok.h> | ||
8 | #include <linux/unaligned/generic.h> | ||
9 | |||
10 | #define get_unaligned __get_unaligned_be | ||
11 | #define put_unaligned __put_unaligned_be | ||
12 | |||
13 | #endif /* _ASM_S390_UNALIGNED_H */ | ||
diff --git a/arch/s390/include/asm/unistd.h b/arch/s390/include/asm/unistd.h new file mode 100644 index 000000000000..c8ad350d1444 --- /dev/null +++ b/arch/s390/include/asm/unistd.h | |||
@@ -0,0 +1,411 @@ | |||
1 | /* | ||
2 | * include/asm-s390/unistd.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/unistd.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef _ASM_S390_UNISTD_H_ | ||
10 | #define _ASM_S390_UNISTD_H_ | ||
11 | |||
12 | /* | ||
13 | * This file contains the system call numbers. | ||
14 | */ | ||
15 | |||
16 | #define __NR_exit 1 | ||
17 | #define __NR_fork 2 | ||
18 | #define __NR_read 3 | ||
19 | #define __NR_write 4 | ||
20 | #define __NR_open 5 | ||
21 | #define __NR_close 6 | ||
22 | #define __NR_restart_syscall 7 | ||
23 | #define __NR_creat 8 | ||
24 | #define __NR_link 9 | ||
25 | #define __NR_unlink 10 | ||
26 | #define __NR_execve 11 | ||
27 | #define __NR_chdir 12 | ||
28 | #define __NR_mknod 14 | ||
29 | #define __NR_chmod 15 | ||
30 | #define __NR_lseek 19 | ||
31 | #define __NR_getpid 20 | ||
32 | #define __NR_mount 21 | ||
33 | #define __NR_umount 22 | ||
34 | #define __NR_ptrace 26 | ||
35 | #define __NR_alarm 27 | ||
36 | #define __NR_pause 29 | ||
37 | #define __NR_utime 30 | ||
38 | #define __NR_access 33 | ||
39 | #define __NR_nice 34 | ||
40 | #define __NR_sync 36 | ||
41 | #define __NR_kill 37 | ||
42 | #define __NR_rename 38 | ||
43 | #define __NR_mkdir 39 | ||
44 | #define __NR_rmdir 40 | ||
45 | #define __NR_dup 41 | ||
46 | #define __NR_pipe 42 | ||
47 | #define __NR_times 43 | ||
48 | #define __NR_brk 45 | ||
49 | #define __NR_signal 48 | ||
50 | #define __NR_acct 51 | ||
51 | #define __NR_umount2 52 | ||
52 | #define __NR_ioctl 54 | ||
53 | #define __NR_fcntl 55 | ||
54 | #define __NR_setpgid 57 | ||
55 | #define __NR_umask 60 | ||
56 | #define __NR_chroot 61 | ||
57 | #define __NR_ustat 62 | ||
58 | #define __NR_dup2 63 | ||
59 | #define __NR_getppid 64 | ||
60 | #define __NR_getpgrp 65 | ||
61 | #define __NR_setsid 66 | ||
62 | #define __NR_sigaction 67 | ||
63 | #define __NR_sigsuspend 72 | ||
64 | #define __NR_sigpending 73 | ||
65 | #define __NR_sethostname 74 | ||
66 | #define __NR_setrlimit 75 | ||
67 | #define __NR_getrusage 77 | ||
68 | #define __NR_gettimeofday 78 | ||
69 | #define __NR_settimeofday 79 | ||
70 | #define __NR_symlink 83 | ||
71 | #define __NR_readlink 85 | ||
72 | #define __NR_uselib 86 | ||
73 | #define __NR_swapon 87 | ||
74 | #define __NR_reboot 88 | ||
75 | #define __NR_readdir 89 | ||
76 | #define __NR_mmap 90 | ||
77 | #define __NR_munmap 91 | ||
78 | #define __NR_truncate 92 | ||
79 | #define __NR_ftruncate 93 | ||
80 | #define __NR_fchmod 94 | ||
81 | #define __NR_getpriority 96 | ||
82 | #define __NR_setpriority 97 | ||
83 | #define __NR_statfs 99 | ||
84 | #define __NR_fstatfs 100 | ||
85 | #define __NR_socketcall 102 | ||
86 | #define __NR_syslog 103 | ||
87 | #define __NR_setitimer 104 | ||
88 | #define __NR_getitimer 105 | ||
89 | #define __NR_stat 106 | ||
90 | #define __NR_lstat 107 | ||
91 | #define __NR_fstat 108 | ||
92 | #define __NR_lookup_dcookie 110 | ||
93 | #define __NR_vhangup 111 | ||
94 | #define __NR_idle 112 | ||
95 | #define __NR_wait4 114 | ||
96 | #define __NR_swapoff 115 | ||
97 | #define __NR_sysinfo 116 | ||
98 | #define __NR_ipc 117 | ||
99 | #define __NR_fsync 118 | ||
100 | #define __NR_sigreturn 119 | ||
101 | #define __NR_clone 120 | ||
102 | #define __NR_setdomainname 121 | ||
103 | #define __NR_uname 122 | ||
104 | #define __NR_adjtimex 124 | ||
105 | #define __NR_mprotect 125 | ||
106 | #define __NR_sigprocmask 126 | ||
107 | #define __NR_create_module 127 | ||
108 | #define __NR_init_module 128 | ||
109 | #define __NR_delete_module 129 | ||
110 | #define __NR_get_kernel_syms 130 | ||
111 | #define __NR_quotactl 131 | ||
112 | #define __NR_getpgid 132 | ||
113 | #define __NR_fchdir 133 | ||
114 | #define __NR_bdflush 134 | ||
115 | #define __NR_sysfs 135 | ||
116 | #define __NR_personality 136 | ||
117 | #define __NR_afs_syscall 137 /* Syscall for Andrew File System */ | ||
118 | #define __NR_getdents 141 | ||
119 | #define __NR_flock 143 | ||
120 | #define __NR_msync 144 | ||
121 | #define __NR_readv 145 | ||
122 | #define __NR_writev 146 | ||
123 | #define __NR_getsid 147 | ||
124 | #define __NR_fdatasync 148 | ||
125 | #define __NR__sysctl 149 | ||
126 | #define __NR_mlock 150 | ||
127 | #define __NR_munlock 151 | ||
128 | #define __NR_mlockall 152 | ||
129 | #define __NR_munlockall 153 | ||
130 | #define __NR_sched_setparam 154 | ||
131 | #define __NR_sched_getparam 155 | ||
132 | #define __NR_sched_setscheduler 156 | ||
133 | #define __NR_sched_getscheduler 157 | ||
134 | #define __NR_sched_yield 158 | ||
135 | #define __NR_sched_get_priority_max 159 | ||
136 | #define __NR_sched_get_priority_min 160 | ||
137 | #define __NR_sched_rr_get_interval 161 | ||
138 | #define __NR_nanosleep 162 | ||
139 | #define __NR_mremap 163 | ||
140 | #define __NR_query_module 167 | ||
141 | #define __NR_poll 168 | ||
142 | #define __NR_nfsservctl 169 | ||
143 | #define __NR_prctl 172 | ||
144 | #define __NR_rt_sigreturn 173 | ||
145 | #define __NR_rt_sigaction 174 | ||
146 | #define __NR_rt_sigprocmask 175 | ||
147 | #define __NR_rt_sigpending 176 | ||
148 | #define __NR_rt_sigtimedwait 177 | ||
149 | #define __NR_rt_sigqueueinfo 178 | ||
150 | #define __NR_rt_sigsuspend 179 | ||
151 | #define __NR_pread64 180 | ||
152 | #define __NR_pwrite64 181 | ||
153 | #define __NR_getcwd 183 | ||
154 | #define __NR_capget 184 | ||
155 | #define __NR_capset 185 | ||
156 | #define __NR_sigaltstack 186 | ||
157 | #define __NR_sendfile 187 | ||
158 | #define __NR_getpmsg 188 | ||
159 | #define __NR_putpmsg 189 | ||
160 | #define __NR_vfork 190 | ||
161 | #define __NR_pivot_root 217 | ||
162 | #define __NR_mincore 218 | ||
163 | #define __NR_madvise 219 | ||
164 | #define __NR_getdents64 220 | ||
165 | #define __NR_readahead 222 | ||
166 | #define __NR_setxattr 224 | ||
167 | #define __NR_lsetxattr 225 | ||
168 | #define __NR_fsetxattr 226 | ||
169 | #define __NR_getxattr 227 | ||
170 | #define __NR_lgetxattr 228 | ||
171 | #define __NR_fgetxattr 229 | ||
172 | #define __NR_listxattr 230 | ||
173 | #define __NR_llistxattr 231 | ||
174 | #define __NR_flistxattr 232 | ||
175 | #define __NR_removexattr 233 | ||
176 | #define __NR_lremovexattr 234 | ||
177 | #define __NR_fremovexattr 235 | ||
178 | #define __NR_gettid 236 | ||
179 | #define __NR_tkill 237 | ||
180 | #define __NR_futex 238 | ||
181 | #define __NR_sched_setaffinity 239 | ||
182 | #define __NR_sched_getaffinity 240 | ||
183 | #define __NR_tgkill 241 | ||
184 | /* Number 242 is reserved for tux */ | ||
185 | #define __NR_io_setup 243 | ||
186 | #define __NR_io_destroy 244 | ||
187 | #define __NR_io_getevents 245 | ||
188 | #define __NR_io_submit 246 | ||
189 | #define __NR_io_cancel 247 | ||
190 | #define __NR_exit_group 248 | ||
191 | #define __NR_epoll_create 249 | ||
192 | #define __NR_epoll_ctl 250 | ||
193 | #define __NR_epoll_wait 251 | ||
194 | #define __NR_set_tid_address 252 | ||
195 | #define __NR_fadvise64 253 | ||
196 | #define __NR_timer_create 254 | ||
197 | #define __NR_timer_settime (__NR_timer_create+1) | ||
198 | #define __NR_timer_gettime (__NR_timer_create+2) | ||
199 | #define __NR_timer_getoverrun (__NR_timer_create+3) | ||
200 | #define __NR_timer_delete (__NR_timer_create+4) | ||
201 | #define __NR_clock_settime (__NR_timer_create+5) | ||
202 | #define __NR_clock_gettime (__NR_timer_create+6) | ||
203 | #define __NR_clock_getres (__NR_timer_create+7) | ||
204 | #define __NR_clock_nanosleep (__NR_timer_create+8) | ||
205 | /* Number 263 is reserved for vserver */ | ||
206 | #define __NR_statfs64 265 | ||
207 | #define __NR_fstatfs64 266 | ||
208 | #define __NR_remap_file_pages 267 | ||
209 | /* Number 268 is reserved for new sys_mbind */ | ||
210 | /* Number 269 is reserved for new sys_get_mempolicy */ | ||
211 | /* Number 270 is reserved for new sys_set_mempolicy */ | ||
212 | #define __NR_mq_open 271 | ||
213 | #define __NR_mq_unlink 272 | ||
214 | #define __NR_mq_timedsend 273 | ||
215 | #define __NR_mq_timedreceive 274 | ||
216 | #define __NR_mq_notify 275 | ||
217 | #define __NR_mq_getsetattr 276 | ||
218 | #define __NR_kexec_load 277 | ||
219 | #define __NR_add_key 278 | ||
220 | #define __NR_request_key 279 | ||
221 | #define __NR_keyctl 280 | ||
222 | #define __NR_waitid 281 | ||
223 | #define __NR_ioprio_set 282 | ||
224 | #define __NR_ioprio_get 283 | ||
225 | #define __NR_inotify_init 284 | ||
226 | #define __NR_inotify_add_watch 285 | ||
227 | #define __NR_inotify_rm_watch 286 | ||
228 | /* Number 287 is reserved for new sys_migrate_pages */ | ||
229 | #define __NR_openat 288 | ||
230 | #define __NR_mkdirat 289 | ||
231 | #define __NR_mknodat 290 | ||
232 | #define __NR_fchownat 291 | ||
233 | #define __NR_futimesat 292 | ||
234 | #define __NR_unlinkat 294 | ||
235 | #define __NR_renameat 295 | ||
236 | #define __NR_linkat 296 | ||
237 | #define __NR_symlinkat 297 | ||
238 | #define __NR_readlinkat 298 | ||
239 | #define __NR_fchmodat 299 | ||
240 | #define __NR_faccessat 300 | ||
241 | #define __NR_pselect6 301 | ||
242 | #define __NR_ppoll 302 | ||
243 | #define __NR_unshare 303 | ||
244 | #define __NR_set_robust_list 304 | ||
245 | #define __NR_get_robust_list 305 | ||
246 | #define __NR_splice 306 | ||
247 | #define __NR_sync_file_range 307 | ||
248 | #define __NR_tee 308 | ||
249 | #define __NR_vmsplice 309 | ||
250 | /* Number 310 is reserved for new sys_move_pages */ | ||
251 | #define __NR_getcpu 311 | ||
252 | #define __NR_epoll_pwait 312 | ||
253 | #define __NR_utimes 313 | ||
254 | #define __NR_fallocate 314 | ||
255 | #define __NR_utimensat 315 | ||
256 | #define __NR_signalfd 316 | ||
257 | #define __NR_timerfd 317 | ||
258 | #define __NR_eventfd 318 | ||
259 | #define __NR_timerfd_create 319 | ||
260 | #define __NR_timerfd_settime 320 | ||
261 | #define __NR_timerfd_gettime 321 | ||
262 | #define __NR_signalfd4 322 | ||
263 | #define __NR_eventfd2 323 | ||
264 | #define __NR_inotify_init1 324 | ||
265 | #define __NR_pipe2 325 | ||
266 | #define __NR_dup3 326 | ||
267 | #define __NR_epoll_create1 327 | ||
268 | #define NR_syscalls 328 | ||
269 | |||
270 | /* | ||
271 | * There are some system calls that are not present on 64 bit, some | ||
272 | * have a different name although they do the same (e.g. __NR_chown32 | ||
273 | * is __NR_chown on 64 bit). | ||
274 | */ | ||
275 | #ifndef __s390x__ | ||
276 | |||
277 | #define __NR_time 13 | ||
278 | #define __NR_lchown 16 | ||
279 | #define __NR_setuid 23 | ||
280 | #define __NR_getuid 24 | ||
281 | #define __NR_stime 25 | ||
282 | #define __NR_setgid 46 | ||
283 | #define __NR_getgid 47 | ||
284 | #define __NR_geteuid 49 | ||
285 | #define __NR_getegid 50 | ||
286 | #define __NR_setreuid 70 | ||
287 | #define __NR_setregid 71 | ||
288 | #define __NR_getrlimit 76 | ||
289 | #define __NR_getgroups 80 | ||
290 | #define __NR_setgroups 81 | ||
291 | #define __NR_fchown 95 | ||
292 | #define __NR_ioperm 101 | ||
293 | #define __NR_setfsuid 138 | ||
294 | #define __NR_setfsgid 139 | ||
295 | #define __NR__llseek 140 | ||
296 | #define __NR__newselect 142 | ||
297 | #define __NR_setresuid 164 | ||
298 | #define __NR_getresuid 165 | ||
299 | #define __NR_setresgid 170 | ||
300 | #define __NR_getresgid 171 | ||
301 | #define __NR_chown 182 | ||
302 | #define __NR_ugetrlimit 191 /* SuS compliant getrlimit */ | ||
303 | #define __NR_mmap2 192 | ||
304 | #define __NR_truncate64 193 | ||
305 | #define __NR_ftruncate64 194 | ||
306 | #define __NR_stat64 195 | ||
307 | #define __NR_lstat64 196 | ||
308 | #define __NR_fstat64 197 | ||
309 | #define __NR_lchown32 198 | ||
310 | #define __NR_getuid32 199 | ||
311 | #define __NR_getgid32 200 | ||
312 | #define __NR_geteuid32 201 | ||
313 | #define __NR_getegid32 202 | ||
314 | #define __NR_setreuid32 203 | ||
315 | #define __NR_setregid32 204 | ||
316 | #define __NR_getgroups32 205 | ||
317 | #define __NR_setgroups32 206 | ||
318 | #define __NR_fchown32 207 | ||
319 | #define __NR_setresuid32 208 | ||
320 | #define __NR_getresuid32 209 | ||
321 | #define __NR_setresgid32 210 | ||
322 | #define __NR_getresgid32 211 | ||
323 | #define __NR_chown32 212 | ||
324 | #define __NR_setuid32 213 | ||
325 | #define __NR_setgid32 214 | ||
326 | #define __NR_setfsuid32 215 | ||
327 | #define __NR_setfsgid32 216 | ||
328 | #define __NR_fcntl64 221 | ||
329 | #define __NR_sendfile64 223 | ||
330 | #define __NR_fadvise64_64 264 | ||
331 | #define __NR_fstatat64 293 | ||
332 | |||
333 | #else | ||
334 | |||
335 | #define __NR_select 142 | ||
336 | #define __NR_getrlimit 191 /* SuS compliant getrlimit */ | ||
337 | #define __NR_lchown 198 | ||
338 | #define __NR_getuid 199 | ||
339 | #define __NR_getgid 200 | ||
340 | #define __NR_geteuid 201 | ||
341 | #define __NR_getegid 202 | ||
342 | #define __NR_setreuid 203 | ||
343 | #define __NR_setregid 204 | ||
344 | #define __NR_getgroups 205 | ||
345 | #define __NR_setgroups 206 | ||
346 | #define __NR_fchown 207 | ||
347 | #define __NR_setresuid 208 | ||
348 | #define __NR_getresuid 209 | ||
349 | #define __NR_setresgid 210 | ||
350 | #define __NR_getresgid 211 | ||
351 | #define __NR_chown 212 | ||
352 | #define __NR_setuid 213 | ||
353 | #define __NR_setgid 214 | ||
354 | #define __NR_setfsuid 215 | ||
355 | #define __NR_setfsgid 216 | ||
356 | #define __NR_newfstatat 293 | ||
357 | |||
358 | #endif | ||
359 | |||
360 | #ifdef __KERNEL__ | ||
361 | |||
362 | #ifndef CONFIG_64BIT | ||
363 | #define __IGNORE_select | ||
364 | #else | ||
365 | #define __IGNORE_time | ||
366 | #endif | ||
367 | |||
368 | /* Ignore NUMA system calls. Not wired up on s390. */ | ||
369 | #define __IGNORE_mbind | ||
370 | #define __IGNORE_get_mempolicy | ||
371 | #define __IGNORE_set_mempolicy | ||
372 | #define __IGNORE_migrate_pages | ||
373 | #define __IGNORE_move_pages | ||
374 | |||
375 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
376 | #define __ARCH_WANT_OLD_READDIR | ||
377 | #define __ARCH_WANT_SYS_ALARM | ||
378 | #define __ARCH_WANT_SYS_GETHOSTNAME | ||
379 | #define __ARCH_WANT_SYS_PAUSE | ||
380 | #define __ARCH_WANT_SYS_SIGNAL | ||
381 | #define __ARCH_WANT_SYS_UTIME | ||
382 | #define __ARCH_WANT_SYS_SOCKETCALL | ||
383 | #define __ARCH_WANT_SYS_FADVISE64 | ||
384 | #define __ARCH_WANT_SYS_GETPGRP | ||
385 | #define __ARCH_WANT_SYS_LLSEEK | ||
386 | #define __ARCH_WANT_SYS_NICE | ||
387 | #define __ARCH_WANT_SYS_OLD_GETRLIMIT | ||
388 | #define __ARCH_WANT_SYS_OLDUMOUNT | ||
389 | #define __ARCH_WANT_SYS_SIGPENDING | ||
390 | #define __ARCH_WANT_SYS_SIGPROCMASK | ||
391 | #define __ARCH_WANT_SYS_RT_SIGACTION | ||
392 | #define __ARCH_WANT_SYS_RT_SIGSUSPEND | ||
393 | # ifndef CONFIG_64BIT | ||
394 | # define __ARCH_WANT_STAT64 | ||
395 | # define __ARCH_WANT_SYS_TIME | ||
396 | # endif | ||
397 | # ifdef CONFIG_COMPAT | ||
398 | # define __ARCH_WANT_COMPAT_SYS_TIME | ||
399 | # define __ARCH_WANT_COMPAT_SYS_RT_SIGSUSPEND | ||
400 | # endif | ||
401 | |||
402 | /* | ||
403 | * "Conditional" syscalls | ||
404 | * | ||
405 | * What we want is __attribute__((weak,alias("sys_ni_syscall"))), | ||
406 | * but it doesn't work on all toolchains, so we just do it by hand | ||
407 | */ | ||
408 | #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") | ||
409 | |||
410 | #endif /* __KERNEL__ */ | ||
411 | #endif /* _ASM_S390_UNISTD_H_ */ | ||
diff --git a/arch/s390/include/asm/user.h b/arch/s390/include/asm/user.h new file mode 100644 index 000000000000..1b050e35fdc6 --- /dev/null +++ b/arch/s390/include/asm/user.h | |||
@@ -0,0 +1,76 @@ | |||
1 | /* | ||
2 | * include/asm-s390/user.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/usr.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef _S390_USER_H | ||
10 | #define _S390_USER_H | ||
11 | |||
12 | #include <asm/page.h> | ||
13 | #include <asm/ptrace.h> | ||
14 | /* Core file format: The core file is written in such a way that gdb | ||
15 | can understand it and provide useful information to the user (under | ||
16 | linux we use the 'trad-core' bfd). There are quite a number of | ||
17 | obstacles to being able to view the contents of the floating point | ||
18 | registers, and until these are solved you will not be able to view the | ||
19 | contents of them. Actually, you can read in the core file and look at | ||
20 | the contents of the user struct to find out what the floating point | ||
21 | registers contain. | ||
22 | The actual file contents are as follows: | ||
23 | UPAGE: 1 page consisting of a user struct that tells gdb what is present | ||
24 | in the file. Directly after this is a copy of the task_struct, which | ||
25 | is currently not used by gdb, but it may come in useful at some point. | ||
26 | All of the registers are stored as part of the upage. The upage should | ||
27 | always be only one page. | ||
28 | DATA: The data area is stored. We use current->end_text to | ||
29 | current->brk to pick up all of the user variables, plus any memory | ||
30 | that may have been malloced. No attempt is made to determine if a page | ||
31 | is demand-zero or if a page is totally unused, we just cover the entire | ||
32 | range. All of the addresses are rounded in such a way that an integral | ||
33 | number of pages is written. | ||
34 | STACK: We need the stack information in order to get a meaningful | ||
35 | backtrace. We need to write the data from (esp) to | ||
36 | current->start_stack, so we round each of these off in order to be able | ||
37 | to write an integer number of pages. | ||
38 | The minimum core file size is 3 pages, or 12288 bytes. | ||
39 | */ | ||
40 | |||
41 | |||
42 | /* | ||
43 | * This is the old layout of "struct pt_regs", and | ||
44 | * is still the layout used by user mode (the new | ||
45 | * pt_regs doesn't have all registers as the kernel | ||
46 | * doesn't use the extra segment registers) | ||
47 | */ | ||
48 | |||
49 | /* When the kernel dumps core, it starts by dumping the user struct - | ||
50 | this will be used by gdb to figure out where the data and stack segments | ||
51 | are within the file, and what virtual addresses to use. */ | ||
52 | struct user { | ||
53 | /* We start with the registers, to mimic the way that "memory" is returned | ||
54 | from the ptrace(3,...) function. */ | ||
55 | struct user_regs_struct regs; /* Where the registers are actually stored */ | ||
56 | /* The rest of this junk is to help gdb figure out what goes where */ | ||
57 | unsigned long int u_tsize; /* Text segment size (pages). */ | ||
58 | unsigned long int u_dsize; /* Data segment size (pages). */ | ||
59 | unsigned long int u_ssize; /* Stack segment size (pages). */ | ||
60 | unsigned long start_code; /* Starting virtual address of text. */ | ||
61 | unsigned long start_stack; /* Starting virtual address of stack area. | ||
62 | This is actually the bottom of the stack, | ||
63 | the top of the stack is always found in the | ||
64 | esp register. */ | ||
65 | long int signal; /* Signal that caused the core dump. */ | ||
66 | unsigned long u_ar0; /* Used by gdb to help find the values for */ | ||
67 | /* the registers. */ | ||
68 | unsigned long magic; /* To uniquely identify a core file */ | ||
69 | char u_comm[32]; /* User command that was responsible */ | ||
70 | }; | ||
71 | #define NBPG PAGE_SIZE | ||
72 | #define UPAGES 1 | ||
73 | #define HOST_TEXT_START_ADDR (u.start_code) | ||
74 | #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) | ||
75 | |||
76 | #endif /* _S390_USER_H */ | ||
diff --git a/arch/s390/include/asm/vtoc.h b/arch/s390/include/asm/vtoc.h new file mode 100644 index 000000000000..3a5267d90d29 --- /dev/null +++ b/arch/s390/include/asm/vtoc.h | |||
@@ -0,0 +1,203 @@ | |||
1 | /* | ||
2 | * include/asm-s390/vtoc.h | ||
3 | * | ||
4 | * This file contains volume label definitions for DASD devices. | ||
5 | * | ||
6 | * (C) Copyright IBM Corp. 2005 | ||
7 | * | ||
8 | * Author(s): Volker Sameske <sameske@de.ibm.com> | ||
9 | * | ||
10 | */ | ||
11 | |||
12 | #ifndef _ASM_S390_VTOC_H | ||
13 | #define _ASM_S390_VTOC_H | ||
14 | |||
15 | #include <linux/types.h> | ||
16 | |||
17 | struct vtoc_ttr | ||
18 | { | ||
19 | __u16 tt; | ||
20 | __u8 r; | ||
21 | } __attribute__ ((packed)); | ||
22 | |||
23 | struct vtoc_cchhb | ||
24 | { | ||
25 | __u16 cc; | ||
26 | __u16 hh; | ||
27 | __u8 b; | ||
28 | } __attribute__ ((packed)); | ||
29 | |||
30 | struct vtoc_cchh | ||
31 | { | ||
32 | __u16 cc; | ||
33 | __u16 hh; | ||
34 | } __attribute__ ((packed)); | ||
35 | |||
36 | struct vtoc_labeldate | ||
37 | { | ||
38 | __u8 year; | ||
39 | __u16 day; | ||
40 | } __attribute__ ((packed)); | ||
41 | |||
42 | struct vtoc_volume_label | ||
43 | { | ||
44 | char volkey[4]; /* volume key = volume label */ | ||
45 | char vollbl[4]; /* volume label */ | ||
46 | char volid[6]; /* volume identifier */ | ||
47 | __u8 security; /* security byte */ | ||
48 | struct vtoc_cchhb vtoc; /* VTOC address */ | ||
49 | char res1[5]; /* reserved */ | ||
50 | char cisize[4]; /* CI-size for FBA,... */ | ||
51 | /* ...blanks for CKD */ | ||
52 | char blkperci[4]; /* no of blocks per CI (FBA), blanks for CKD */ | ||
53 | char labperci[4]; /* no of labels per CI (FBA), blanks for CKD */ | ||
54 | char res2[4]; /* reserved */ | ||
55 | char lvtoc[14]; /* owner code for LVTOC */ | ||
56 | char res3[29]; /* reserved */ | ||
57 | } __attribute__ ((packed)); | ||
58 | |||
59 | struct vtoc_extent | ||
60 | { | ||
61 | __u8 typeind; /* extent type indicator */ | ||
62 | __u8 seqno; /* extent sequence number */ | ||
63 | struct vtoc_cchh llimit; /* starting point of this extent */ | ||
64 | struct vtoc_cchh ulimit; /* ending point of this extent */ | ||
65 | } __attribute__ ((packed)); | ||
66 | |||
67 | struct vtoc_dev_const | ||
68 | { | ||
69 | __u16 DS4DSCYL; /* number of logical cyls */ | ||
70 | __u16 DS4DSTRK; /* number of tracks in a logical cylinder */ | ||
71 | __u16 DS4DEVTK; /* device track length */ | ||
72 | __u8 DS4DEVI; /* non-last keyed record overhead */ | ||
73 | __u8 DS4DEVL; /* last keyed record overhead */ | ||
74 | __u8 DS4DEVK; /* non-keyed record overhead differential */ | ||
75 | __u8 DS4DEVFG; /* flag byte */ | ||
76 | __u16 DS4DEVTL; /* device tolerance */ | ||
77 | __u8 DS4DEVDT; /* number of DSCB's per track */ | ||
78 | __u8 DS4DEVDB; /* number of directory blocks per track */ | ||
79 | } __attribute__ ((packed)); | ||
80 | |||
81 | struct vtoc_format1_label | ||
82 | { | ||
83 | char DS1DSNAM[44]; /* data set name */ | ||
84 | __u8 DS1FMTID; /* format identifier */ | ||
85 | char DS1DSSN[6]; /* data set serial number */ | ||
86 | __u16 DS1VOLSQ; /* volume sequence number */ | ||
87 | struct vtoc_labeldate DS1CREDT; /* creation date: ydd */ | ||
88 | struct vtoc_labeldate DS1EXPDT; /* expiration date */ | ||
89 | __u8 DS1NOEPV; /* number of extents on volume */ | ||
90 | __u8 DS1NOBDB; /* no. of bytes used in last direction blk */ | ||
91 | __u8 DS1FLAG1; /* flag 1 */ | ||
92 | char DS1SYSCD[13]; /* system code */ | ||
93 | struct vtoc_labeldate DS1REFD; /* date last referenced */ | ||
94 | __u8 DS1SMSFG; /* system managed storage indicators */ | ||
95 | __u8 DS1SCXTF; /* sec. space extension flag byte */ | ||
96 | __u16 DS1SCXTV; /* secondary space extension value */ | ||
97 | __u8 DS1DSRG1; /* data set organisation byte 1 */ | ||
98 | __u8 DS1DSRG2; /* data set organisation byte 2 */ | ||
99 | __u8 DS1RECFM; /* record format */ | ||
100 | __u8 DS1OPTCD; /* option code */ | ||
101 | __u16 DS1BLKL; /* block length */ | ||
102 | __u16 DS1LRECL; /* record length */ | ||
103 | __u8 DS1KEYL; /* key length */ | ||
104 | __u16 DS1RKP; /* relative key position */ | ||
105 | __u8 DS1DSIND; /* data set indicators */ | ||
106 | __u8 DS1SCAL1; /* secondary allocation flag byte */ | ||
107 | char DS1SCAL3[3]; /* secondary allocation quantity */ | ||
108 | struct vtoc_ttr DS1LSTAR; /* last used track and block on track */ | ||
109 | __u16 DS1TRBAL; /* space remaining on last used track */ | ||
110 | __u16 res1; /* reserved */ | ||
111 | struct vtoc_extent DS1EXT1; /* first extent description */ | ||
112 | struct vtoc_extent DS1EXT2; /* second extent description */ | ||
113 | struct vtoc_extent DS1EXT3; /* third extent description */ | ||
114 | struct vtoc_cchhb DS1PTRDS; /* possible pointer to f2 or f3 DSCB */ | ||
115 | } __attribute__ ((packed)); | ||
116 | |||
117 | struct vtoc_format4_label | ||
118 | { | ||
119 | char DS4KEYCD[44]; /* key code for VTOC labels: 44 times 0x04 */ | ||
120 | __u8 DS4IDFMT; /* format identifier */ | ||
121 | struct vtoc_cchhb DS4HPCHR; /* highest address of a format 1 DSCB */ | ||
122 | __u16 DS4DSREC; /* number of available DSCB's */ | ||
123 | struct vtoc_cchh DS4HCCHH; /* CCHH of next available alternate track */ | ||
124 | __u16 DS4NOATK; /* number of remaining alternate tracks */ | ||
125 | __u8 DS4VTOCI; /* VTOC indicators */ | ||
126 | __u8 DS4NOEXT; /* number of extents in VTOC */ | ||
127 | __u8 DS4SMSFG; /* system managed storage indicators */ | ||
128 | __u8 DS4DEVAC; /* number of alternate cylinders. | ||
129 | * Subtract from first two bytes of | ||
130 | * DS4DEVSZ to get number of usable | ||
131 | * cylinders. can be zero. valid | ||
132 | * only if DS4DEVAV on. */ | ||
133 | struct vtoc_dev_const DS4DEVCT; /* device constants */ | ||
134 | char DS4AMTIM[8]; /* VSAM time stamp */ | ||
135 | char DS4AMCAT[3]; /* VSAM catalog indicator */ | ||
136 | char DS4R2TIM[8]; /* VSAM volume/catalog match time stamp */ | ||
137 | char res1[5]; /* reserved */ | ||
138 | char DS4F6PTR[5]; /* pointer to first format 6 DSCB */ | ||
139 | struct vtoc_extent DS4VTOCE; /* VTOC extent description */ | ||
140 | char res2[10]; /* reserved */ | ||
141 | __u8 DS4EFLVL; /* extended free-space management level */ | ||
142 | struct vtoc_cchhb DS4EFPTR; /* pointer to extended free-space info */ | ||
143 | char res3[9]; /* reserved */ | ||
144 | } __attribute__ ((packed)); | ||
145 | |||
146 | struct vtoc_ds5ext | ||
147 | { | ||
148 | __u16 t; /* RTA of the first track of free extent */ | ||
149 | __u16 fc; /* number of whole cylinders in free ext. */ | ||
150 | __u8 ft; /* number of remaining free tracks */ | ||
151 | } __attribute__ ((packed)); | ||
152 | |||
153 | struct vtoc_format5_label | ||
154 | { | ||
155 | char DS5KEYID[4]; /* key identifier */ | ||
156 | struct vtoc_ds5ext DS5AVEXT; /* first available (free-space) extent. */ | ||
157 | struct vtoc_ds5ext DS5EXTAV[7]; /* seven available extents */ | ||
158 | __u8 DS5FMTID; /* format identifier */ | ||
159 | struct vtoc_ds5ext DS5MAVET[18]; /* eighteen available extents */ | ||
160 | struct vtoc_cchhb DS5PTRDS; /* pointer to next format5 DSCB */ | ||
161 | } __attribute__ ((packed)); | ||
162 | |||
163 | struct vtoc_ds7ext | ||
164 | { | ||
165 | __u32 a; /* starting RTA value */ | ||
166 | __u32 b; /* ending RTA value + 1 */ | ||
167 | } __attribute__ ((packed)); | ||
168 | |||
169 | struct vtoc_format7_label | ||
170 | { | ||
171 | char DS7KEYID[4]; /* key identifier */ | ||
172 | struct vtoc_ds7ext DS7EXTNT[5]; /* space for 5 extent descriptions */ | ||
173 | __u8 DS7FMTID; /* format identifier */ | ||
174 | struct vtoc_ds7ext DS7ADEXT[11]; /* space for 11 extent descriptions */ | ||
175 | char res1[2]; /* reserved */ | ||
176 | struct vtoc_cchhb DS7PTRDS; /* pointer to next FMT7 DSCB */ | ||
177 | } __attribute__ ((packed)); | ||
178 | |||
179 | struct vtoc_cms_label { | ||
180 | __u8 label_id[4]; /* Label identifier */ | ||
181 | __u8 vol_id[6]; /* Volid */ | ||
182 | __u16 version_id; /* Version identifier */ | ||
183 | __u32 block_size; /* Disk block size */ | ||
184 | __u32 origin_ptr; /* Disk origin pointer */ | ||
185 | __u32 usable_count; /* Number of usable cylinders/blocks */ | ||
186 | __u32 formatted_count; /* Maximum number of formatted cylinders/ | ||
187 | * blocks */ | ||
188 | __u32 block_count; /* Disk size in CMS blocks */ | ||
189 | __u32 used_count; /* Number of CMS blocks in use */ | ||
190 | __u32 fst_size; /* File Status Table (FST) size */ | ||
191 | __u32 fst_count; /* Number of FSTs per CMS block */ | ||
192 | __u8 format_date[6]; /* Disk FORMAT date */ | ||
193 | __u8 reserved1[2]; | ||
194 | __u32 disk_offset; /* Disk offset when reserved*/ | ||
195 | __u32 map_block; /* Allocation Map Block with next hole */ | ||
196 | __u32 hblk_disp; /* Displacement into HBLK data of next hole */ | ||
197 | __u32 user_disp; /* Displacement into user part of Allocation | ||
198 | * map */ | ||
199 | __u8 reserved2[4]; | ||
200 | __u8 segment_name[8]; /* Name of shared segment */ | ||
201 | } __attribute__ ((packed)); | ||
202 | |||
203 | #endif /* _ASM_S390_VTOC_H */ | ||
diff --git a/arch/s390/include/asm/xor.h b/arch/s390/include/asm/xor.h new file mode 100644 index 000000000000..c82eb12a5b18 --- /dev/null +++ b/arch/s390/include/asm/xor.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/xor.h> | |||
diff --git a/arch/s390/include/asm/zcrypt.h b/arch/s390/include/asm/zcrypt.h new file mode 100644 index 000000000000..00d3bbd44117 --- /dev/null +++ b/arch/s390/include/asm/zcrypt.h | |||
@@ -0,0 +1,276 @@ | |||
1 | /* | ||
2 | * include/asm-s390/zcrypt.h | ||
3 | * | ||
4 | * zcrypt 2.1.0 (user-visible header) | ||
5 | * | ||
6 | * Copyright (C) 2001, 2006 IBM Corporation | ||
7 | * Author(s): Robert Burroughs | ||
8 | * Eric Rossman (edrossma@us.ibm.com) | ||
9 | * | ||
10 | * Hotplug & misc device support: Jochen Roehrig (roehrig@de.ibm.com) | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or modify | ||
13 | * it under the terms of the GNU General Public License as published by | ||
14 | * the Free Software Foundation; either version 2, or (at your option) | ||
15 | * any later version. | ||
16 | * | ||
17 | * This program is distributed in the hope that it will be useful, | ||
18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
20 | * GNU General Public License for more details. | ||
21 | * | ||
22 | * You should have received a copy of the GNU General Public License | ||
23 | * along with this program; if not, write to the Free Software | ||
24 | * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. | ||
25 | */ | ||
26 | |||
27 | #ifndef __ASM_S390_ZCRYPT_H | ||
28 | #define __ASM_S390_ZCRYPT_H | ||
29 | |||
30 | #define ZCRYPT_VERSION 2 | ||
31 | #define ZCRYPT_RELEASE 1 | ||
32 | #define ZCRYPT_VARIANT 1 | ||
33 | |||
34 | #include <linux/ioctl.h> | ||
35 | #include <linux/compiler.h> | ||
36 | |||
37 | /** | ||
38 | * struct ica_rsa_modexpo | ||
39 | * | ||
40 | * Requirements: | ||
41 | * - outputdatalength is at least as large as inputdatalength. | ||
42 | * - All key parts are right justified in their fields, padded on | ||
43 | * the left with zeroes. | ||
44 | * - length(b_key) = inputdatalength | ||
45 | * - length(n_modulus) = inputdatalength | ||
46 | */ | ||
47 | struct ica_rsa_modexpo { | ||
48 | char __user * inputdata; | ||
49 | unsigned int inputdatalength; | ||
50 | char __user * outputdata; | ||
51 | unsigned int outputdatalength; | ||
52 | char __user * b_key; | ||
53 | char __user * n_modulus; | ||
54 | }; | ||
55 | |||
56 | /** | ||
57 | * struct ica_rsa_modexpo_crt | ||
58 | * | ||
59 | * Requirements: | ||
60 | * - inputdatalength is even. | ||
61 | * - outputdatalength is at least as large as inputdatalength. | ||
62 | * - All key parts are right justified in their fields, padded on | ||
63 | * the left with zeroes. | ||
64 | * - length(bp_key) = inputdatalength/2 + 8 | ||
65 | * - length(bq_key) = inputdatalength/2 | ||
66 | * - length(np_key) = inputdatalength/2 + 8 | ||
67 | * - length(nq_key) = inputdatalength/2 | ||
68 | * - length(u_mult_inv) = inputdatalength/2 + 8 | ||
69 | */ | ||
70 | struct ica_rsa_modexpo_crt { | ||
71 | char __user * inputdata; | ||
72 | unsigned int inputdatalength; | ||
73 | char __user * outputdata; | ||
74 | unsigned int outputdatalength; | ||
75 | char __user * bp_key; | ||
76 | char __user * bq_key; | ||
77 | char __user * np_prime; | ||
78 | char __user * nq_prime; | ||
79 | char __user * u_mult_inv; | ||
80 | }; | ||
81 | |||
82 | /** | ||
83 | * CPRBX | ||
84 | * Note that all shorts and ints are big-endian. | ||
85 | * All pointer fields are 16 bytes long, and mean nothing. | ||
86 | * | ||
87 | * A request CPRB is followed by a request_parameter_block. | ||
88 | * | ||
89 | * The request (or reply) parameter block is organized thus: | ||
90 | * function code | ||
91 | * VUD block | ||
92 | * key block | ||
93 | */ | ||
94 | struct CPRBX { | ||
95 | unsigned short cprb_len; /* CPRB length 220 */ | ||
96 | unsigned char cprb_ver_id; /* CPRB version id. 0x02 */ | ||
97 | unsigned char pad_000[3]; /* Alignment pad bytes */ | ||
98 | unsigned char func_id[2]; /* function id 0x5432 */ | ||
99 | unsigned char cprb_flags[4]; /* Flags */ | ||
100 | unsigned int req_parml; /* request parameter buffer len */ | ||
101 | unsigned int req_datal; /* request data buffer */ | ||
102 | unsigned int rpl_msgbl; /* reply message block length */ | ||
103 | unsigned int rpld_parml; /* replied parameter block len */ | ||
104 | unsigned int rpl_datal; /* reply data block len */ | ||
105 | unsigned int rpld_datal; /* replied data block len */ | ||
106 | unsigned int req_extbl; /* request extension block len */ | ||
107 | unsigned char pad_001[4]; /* reserved */ | ||
108 | unsigned int rpld_extbl; /* replied extension block len */ | ||
109 | unsigned char padx000[16 - sizeof (char *)]; | ||
110 | unsigned char * req_parmb; /* request parm block 'address' */ | ||
111 | unsigned char padx001[16 - sizeof (char *)]; | ||
112 | unsigned char * req_datab; /* request data block 'address' */ | ||
113 | unsigned char padx002[16 - sizeof (char *)]; | ||
114 | unsigned char * rpl_parmb; /* reply parm block 'address' */ | ||
115 | unsigned char padx003[16 - sizeof (char *)]; | ||
116 | unsigned char * rpl_datab; /* reply data block 'address' */ | ||
117 | unsigned char padx004[16 - sizeof (char *)]; | ||
118 | unsigned char * req_extb; /* request extension block 'addr'*/ | ||
119 | unsigned char padx005[16 - sizeof (char *)]; | ||
120 | unsigned char * rpl_extb; /* reply extension block 'address'*/ | ||
121 | unsigned short ccp_rtcode; /* server return code */ | ||
122 | unsigned short ccp_rscode; /* server reason code */ | ||
123 | unsigned int mac_data_len; /* Mac Data Length */ | ||
124 | unsigned char logon_id[8]; /* Logon Identifier */ | ||
125 | unsigned char mac_value[8]; /* Mac Value */ | ||
126 | unsigned char mac_content_flgs;/* Mac content flag byte */ | ||
127 | unsigned char pad_002; /* Alignment */ | ||
128 | unsigned short domain; /* Domain */ | ||
129 | unsigned char usage_domain[4];/* Usage domain */ | ||
130 | unsigned char cntrl_domain[4];/* Control domain */ | ||
131 | unsigned char S390enf_mask[4];/* S/390 enforcement mask */ | ||
132 | unsigned char pad_004[36]; /* reserved */ | ||
133 | } __attribute__((packed)); | ||
134 | |||
135 | /** | ||
136 | * xcRB | ||
137 | */ | ||
138 | struct ica_xcRB { | ||
139 | unsigned short agent_ID; | ||
140 | unsigned int user_defined; | ||
141 | unsigned short request_ID; | ||
142 | unsigned int request_control_blk_length; | ||
143 | unsigned char padding1[16 - sizeof (char *)]; | ||
144 | char __user * request_control_blk_addr; | ||
145 | unsigned int request_data_length; | ||
146 | char padding2[16 - sizeof (char *)]; | ||
147 | char __user * request_data_address; | ||
148 | unsigned int reply_control_blk_length; | ||
149 | char padding3[16 - sizeof (char *)]; | ||
150 | char __user * reply_control_blk_addr; | ||
151 | unsigned int reply_data_length; | ||
152 | char padding4[16 - sizeof (char *)]; | ||
153 | char __user * reply_data_addr; | ||
154 | unsigned short priority_window; | ||
155 | unsigned int status; | ||
156 | } __attribute__((packed)); | ||
157 | #define AUTOSELECT ((unsigned int)0xFFFFFFFF) | ||
158 | |||
159 | #define ZCRYPT_IOCTL_MAGIC 'z' | ||
160 | |||
161 | /** | ||
162 | * Interface notes: | ||
163 | * | ||
164 | * The ioctl()s which are implemented (along with relevant details) | ||
165 | * are: | ||
166 | * | ||
167 | * ICARSAMODEXPO | ||
168 | * Perform an RSA operation using a Modulus-Exponent pair | ||
169 | * This takes an ica_rsa_modexpo struct as its arg. | ||
170 | * | ||
171 | * NOTE: please refer to the comments preceding this structure | ||
172 | * for the implementation details for the contents of the | ||
173 | * block | ||
174 | * | ||
175 | * ICARSACRT | ||
176 | * Perform an RSA operation using a Chinese-Remainder Theorem key | ||
177 | * This takes an ica_rsa_modexpo_crt struct as its arg. | ||
178 | * | ||
179 | * NOTE: please refer to the comments preceding this structure | ||
180 | * for the implementation details for the contents of the | ||
181 | * block | ||
182 | * | ||
183 | * ZSECSENDCPRB | ||
184 | * Send an arbitrary CPRB to a crypto card. | ||
185 | * | ||
186 | * Z90STAT_STATUS_MASK | ||
187 | * Return an 64 element array of unsigned chars for the status of | ||
188 | * all devices. | ||
189 | * 0x01: PCICA | ||
190 | * 0x02: PCICC | ||
191 | * 0x03: PCIXCC_MCL2 | ||
192 | * 0x04: PCIXCC_MCL3 | ||
193 | * 0x05: CEX2C | ||
194 | * 0x06: CEX2A | ||
195 | * 0x0d: device is disabled via the proc filesystem | ||
196 | * | ||
197 | * Z90STAT_QDEPTH_MASK | ||
198 | * Return an 64 element array of unsigned chars for the queue | ||
199 | * depth of all devices. | ||
200 | * | ||
201 | * Z90STAT_PERDEV_REQCNT | ||
202 | * Return an 64 element array of unsigned integers for the number | ||
203 | * of successfully completed requests per device since the device | ||
204 | * was detected and made available. | ||
205 | * | ||
206 | * Z90STAT_REQUESTQ_COUNT | ||
207 | * Return an integer count of the number of entries waiting to be | ||
208 | * sent to a device. | ||
209 | * | ||
210 | * Z90STAT_PENDINGQ_COUNT | ||
211 | * Return an integer count of the number of entries sent to all | ||
212 | * devices awaiting the reply. | ||
213 | * | ||
214 | * Z90STAT_TOTALOPEN_COUNT | ||
215 | * Return an integer count of the number of open file handles. | ||
216 | * | ||
217 | * Z90STAT_DOMAIN_INDEX | ||
218 | * Return the integer value of the Cryptographic Domain. | ||
219 | * | ||
220 | * The following ioctls are deprecated and should be no longer used: | ||
221 | * | ||
222 | * Z90STAT_TOTALCOUNT | ||
223 | * Return an integer count of all device types together. | ||
224 | * | ||
225 | * Z90STAT_PCICACOUNT | ||
226 | * Return an integer count of all PCICAs. | ||
227 | * | ||
228 | * Z90STAT_PCICCCOUNT | ||
229 | * Return an integer count of all PCICCs. | ||
230 | * | ||
231 | * Z90STAT_PCIXCCMCL2COUNT | ||
232 | * Return an integer count of all MCL2 PCIXCCs. | ||
233 | * | ||
234 | * Z90STAT_PCIXCCMCL3COUNT | ||
235 | * Return an integer count of all MCL3 PCIXCCs. | ||
236 | * | ||
237 | * Z90STAT_CEX2CCOUNT | ||
238 | * Return an integer count of all CEX2Cs. | ||
239 | * | ||
240 | * Z90STAT_CEX2ACOUNT | ||
241 | * Return an integer count of all CEX2As. | ||
242 | * | ||
243 | * ICAZ90STATUS | ||
244 | * Return some device driver status in a ica_z90_status struct | ||
245 | * This takes an ica_z90_status struct as its arg. | ||
246 | * | ||
247 | * Z90STAT_PCIXCCCOUNT | ||
248 | * Return an integer count of all PCIXCCs (MCL2 + MCL3). | ||
249 | * This is DEPRECATED now that MCL3 PCIXCCs are treated differently from | ||
250 | * MCL2 PCIXCCs. | ||
251 | */ | ||
252 | |||
253 | /** | ||
254 | * Supported ioctl calls | ||
255 | */ | ||
256 | #define ICARSAMODEXPO _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x05, 0) | ||
257 | #define ICARSACRT _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x06, 0) | ||
258 | #define ZSECSENDCPRB _IOC(_IOC_READ|_IOC_WRITE, ZCRYPT_IOCTL_MAGIC, 0x81, 0) | ||
259 | |||
260 | /* New status calls */ | ||
261 | #define Z90STAT_TOTALCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x40, int) | ||
262 | #define Z90STAT_PCICACOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x41, int) | ||
263 | #define Z90STAT_PCICCCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x42, int) | ||
264 | #define Z90STAT_PCIXCCMCL2COUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x4b, int) | ||
265 | #define Z90STAT_PCIXCCMCL3COUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x4c, int) | ||
266 | #define Z90STAT_CEX2CCOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x4d, int) | ||
267 | #define Z90STAT_CEX2ACOUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x4e, int) | ||
268 | #define Z90STAT_REQUESTQ_COUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x44, int) | ||
269 | #define Z90STAT_PENDINGQ_COUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x45, int) | ||
270 | #define Z90STAT_TOTALOPEN_COUNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x46, int) | ||
271 | #define Z90STAT_DOMAIN_INDEX _IOR(ZCRYPT_IOCTL_MAGIC, 0x47, int) | ||
272 | #define Z90STAT_STATUS_MASK _IOR(ZCRYPT_IOCTL_MAGIC, 0x48, char[64]) | ||
273 | #define Z90STAT_QDEPTH_MASK _IOR(ZCRYPT_IOCTL_MAGIC, 0x49, char[64]) | ||
274 | #define Z90STAT_PERDEV_REQCNT _IOR(ZCRYPT_IOCTL_MAGIC, 0x4a, int[64]) | ||
275 | |||
276 | #endif /* __ASM_S390_ZCRYPT_H */ | ||