diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /include/asm-s390 |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'include/asm-s390')
102 files changed, 12928 insertions, 0 deletions
diff --git a/include/asm-s390/a.out.h b/include/asm-s390/a.out.h new file mode 100644 index 000000000000..72adee6ef338 --- /dev/null +++ b/include/asm-s390/a.out.h | |||
@@ -0,0 +1,38 @@ | |||
1 | /* | ||
2 | * include/asm-s390/a.out.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * | ||
7 | * Derived from "include/asm-i386/a.out.h" | ||
8 | * Copyright (C) 1992, Linus Torvalds | ||
9 | * | ||
10 | * I don't think we'll ever need a.out ... | ||
11 | */ | ||
12 | |||
13 | #ifndef __S390_A_OUT_H__ | ||
14 | #define __S390_A_OUT_H__ | ||
15 | |||
16 | struct exec | ||
17 | { | ||
18 | unsigned long a_info; /* Use macros N_MAGIC, etc for access */ | ||
19 | unsigned a_text; /* length of text, in bytes */ | ||
20 | unsigned a_data; /* length of data, in bytes */ | ||
21 | unsigned a_bss; /* length of uninitialized data area for file, in bytes */ | ||
22 | unsigned a_syms; /* length of symbol table data in file, in bytes */ | ||
23 | unsigned a_entry; /* start address */ | ||
24 | unsigned a_trsize; /* length of relocation info for text, in bytes */ | ||
25 | unsigned a_drsize; /* length of relocation info for data, in bytes */ | ||
26 | }; | ||
27 | |||
28 | #define N_TRSIZE(a) ((a).a_trsize) | ||
29 | #define N_DRSIZE(a) ((a).a_drsize) | ||
30 | #define N_SYMSIZE(a) ((a).a_syms) | ||
31 | |||
32 | #ifdef __KERNEL__ | ||
33 | |||
34 | #define STACK_TOP TASK_SIZE | ||
35 | |||
36 | #endif | ||
37 | |||
38 | #endif /* __A_OUT_GNU_H__ */ | ||
diff --git a/include/asm-s390/atomic.h b/include/asm-s390/atomic.h new file mode 100644 index 000000000000..d5a05cf47168 --- /dev/null +++ b/include/asm-s390/atomic.h | |||
@@ -0,0 +1,207 @@ | |||
1 | #ifndef __ARCH_S390_ATOMIC__ | ||
2 | #define __ARCH_S390_ATOMIC__ | ||
3 | |||
4 | /* | ||
5 | * include/asm-s390/atomic.h | ||
6 | * | ||
7 | * S390 version | ||
8 | * Copyright (C) 1999-2003 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
9 | * Author(s): Martin Schwidefsky (schwidefsky@de.ibm.com), | ||
10 | * Denis Joseph Barrow, | ||
11 | * Arnd Bergmann (arndb@de.ibm.com) | ||
12 | * | ||
13 | * Derived from "include/asm-i386/bitops.h" | ||
14 | * Copyright (C) 1992, Linus Torvalds | ||
15 | * | ||
16 | */ | ||
17 | |||
18 | /* | ||
19 | * Atomic operations that C can't guarantee us. Useful for | ||
20 | * resource counting etc.. | ||
21 | * S390 uses 'Compare And Swap' for atomicity in SMP enviroment | ||
22 | */ | ||
23 | |||
24 | typedef struct { | ||
25 | volatile int counter; | ||
26 | } __attribute__ ((aligned (4))) atomic_t; | ||
27 | #define ATOMIC_INIT(i) { (i) } | ||
28 | |||
29 | #ifdef __KERNEL__ | ||
30 | |||
31 | #define __CS_LOOP(ptr, op_val, op_string) ({ \ | ||
32 | typeof(ptr->counter) old_val, new_val; \ | ||
33 | __asm__ __volatile__(" l %0,0(%3)\n" \ | ||
34 | "0: lr %1,%0\n" \ | ||
35 | op_string " %1,%4\n" \ | ||
36 | " cs %0,%1,0(%3)\n" \ | ||
37 | " jl 0b" \ | ||
38 | : "=&d" (old_val), "=&d" (new_val), \ | ||
39 | "=m" (((atomic_t *)(ptr))->counter) \ | ||
40 | : "a" (ptr), "d" (op_val), \ | ||
41 | "m" (((atomic_t *)(ptr))->counter) \ | ||
42 | : "cc", "memory" ); \ | ||
43 | new_val; \ | ||
44 | }) | ||
45 | #define atomic_read(v) ((v)->counter) | ||
46 | #define atomic_set(v,i) (((v)->counter) = (i)) | ||
47 | |||
48 | static __inline__ void atomic_add(int i, atomic_t * v) | ||
49 | { | ||
50 | __CS_LOOP(v, i, "ar"); | ||
51 | } | ||
52 | static __inline__ int atomic_add_return(int i, atomic_t * v) | ||
53 | { | ||
54 | return __CS_LOOP(v, i, "ar"); | ||
55 | } | ||
56 | static __inline__ int atomic_add_negative(int i, atomic_t * v) | ||
57 | { | ||
58 | return __CS_LOOP(v, i, "ar") < 0; | ||
59 | } | ||
60 | static __inline__ void atomic_sub(int i, atomic_t * v) | ||
61 | { | ||
62 | __CS_LOOP(v, i, "sr"); | ||
63 | } | ||
64 | static __inline__ int atomic_sub_return(int i, atomic_t * v) | ||
65 | { | ||
66 | return __CS_LOOP(v, i, "sr"); | ||
67 | } | ||
68 | static __inline__ void atomic_inc(volatile atomic_t * v) | ||
69 | { | ||
70 | __CS_LOOP(v, 1, "ar"); | ||
71 | } | ||
72 | static __inline__ int atomic_inc_return(volatile atomic_t * v) | ||
73 | { | ||
74 | return __CS_LOOP(v, 1, "ar"); | ||
75 | } | ||
76 | |||
77 | static __inline__ int atomic_inc_and_test(volatile atomic_t * v) | ||
78 | { | ||
79 | return __CS_LOOP(v, 1, "ar") == 0; | ||
80 | } | ||
81 | static __inline__ void atomic_dec(volatile atomic_t * v) | ||
82 | { | ||
83 | __CS_LOOP(v, 1, "sr"); | ||
84 | } | ||
85 | static __inline__ int atomic_dec_return(volatile atomic_t * v) | ||
86 | { | ||
87 | return __CS_LOOP(v, 1, "sr"); | ||
88 | } | ||
89 | static __inline__ int atomic_dec_and_test(volatile atomic_t * v) | ||
90 | { | ||
91 | return __CS_LOOP(v, 1, "sr") == 0; | ||
92 | } | ||
93 | static __inline__ void atomic_clear_mask(unsigned long mask, atomic_t * v) | ||
94 | { | ||
95 | __CS_LOOP(v, ~mask, "nr"); | ||
96 | } | ||
97 | static __inline__ void atomic_set_mask(unsigned long mask, atomic_t * v) | ||
98 | { | ||
99 | __CS_LOOP(v, mask, "or"); | ||
100 | } | ||
101 | #undef __CS_LOOP | ||
102 | |||
103 | #ifdef __s390x__ | ||
104 | typedef struct { | ||
105 | volatile long long counter; | ||
106 | } __attribute__ ((aligned (8))) atomic64_t; | ||
107 | #define ATOMIC64_INIT(i) { (i) } | ||
108 | |||
109 | #define __CSG_LOOP(ptr, op_val, op_string) ({ \ | ||
110 | typeof(ptr->counter) old_val, new_val; \ | ||
111 | __asm__ __volatile__(" lg %0,0(%3)\n" \ | ||
112 | "0: lgr %1,%0\n" \ | ||
113 | op_string " %1,%4\n" \ | ||
114 | " csg %0,%1,0(%3)\n" \ | ||
115 | " jl 0b" \ | ||
116 | : "=&d" (old_val), "=&d" (new_val), \ | ||
117 | "=m" (((atomic_t *)(ptr))->counter) \ | ||
118 | : "a" (ptr), "d" (op_val), \ | ||
119 | "m" (((atomic_t *)(ptr))->counter) \ | ||
120 | : "cc", "memory" ); \ | ||
121 | new_val; \ | ||
122 | }) | ||
123 | #define atomic64_read(v) ((v)->counter) | ||
124 | #define atomic64_set(v,i) (((v)->counter) = (i)) | ||
125 | |||
126 | static __inline__ void atomic64_add(int i, atomic64_t * v) | ||
127 | { | ||
128 | __CSG_LOOP(v, i, "agr"); | ||
129 | } | ||
130 | static __inline__ long long atomic64_add_return(int i, atomic64_t * v) | ||
131 | { | ||
132 | return __CSG_LOOP(v, i, "agr"); | ||
133 | } | ||
134 | static __inline__ long long atomic64_add_negative(int i, atomic64_t * v) | ||
135 | { | ||
136 | return __CSG_LOOP(v, i, "agr") < 0; | ||
137 | } | ||
138 | static __inline__ void atomic64_sub(int i, atomic64_t * v) | ||
139 | { | ||
140 | __CSG_LOOP(v, i, "sgr"); | ||
141 | } | ||
142 | static __inline__ void atomic64_inc(volatile atomic64_t * v) | ||
143 | { | ||
144 | __CSG_LOOP(v, 1, "agr"); | ||
145 | } | ||
146 | static __inline__ long long atomic64_inc_return(volatile atomic64_t * v) | ||
147 | { | ||
148 | return __CSG_LOOP(v, 1, "agr"); | ||
149 | } | ||
150 | static __inline__ long long atomic64_inc_and_test(volatile atomic64_t * v) | ||
151 | { | ||
152 | return __CSG_LOOP(v, 1, "agr") == 0; | ||
153 | } | ||
154 | static __inline__ void atomic64_dec(volatile atomic64_t * v) | ||
155 | { | ||
156 | __CSG_LOOP(v, 1, "sgr"); | ||
157 | } | ||
158 | static __inline__ long long atomic64_dec_return(volatile atomic64_t * v) | ||
159 | { | ||
160 | return __CSG_LOOP(v, 1, "sgr"); | ||
161 | } | ||
162 | static __inline__ long long atomic64_dec_and_test(volatile atomic64_t * v) | ||
163 | { | ||
164 | return __CSG_LOOP(v, 1, "sgr") == 0; | ||
165 | } | ||
166 | static __inline__ void atomic64_clear_mask(unsigned long mask, atomic64_t * v) | ||
167 | { | ||
168 | __CSG_LOOP(v, ~mask, "ngr"); | ||
169 | } | ||
170 | static __inline__ void atomic64_set_mask(unsigned long mask, atomic64_t * v) | ||
171 | { | ||
172 | __CSG_LOOP(v, mask, "ogr"); | ||
173 | } | ||
174 | |||
175 | #undef __CSG_LOOP | ||
176 | #endif | ||
177 | |||
178 | /* | ||
179 | returns 0 if expected_oldval==value in *v ( swap was successful ) | ||
180 | returns 1 if unsuccessful. | ||
181 | |||
182 | This is non-portable, use bitops or spinlocks instead! | ||
183 | */ | ||
184 | static __inline__ int | ||
185 | atomic_compare_and_swap(int expected_oldval,int new_val,atomic_t *v) | ||
186 | { | ||
187 | int retval; | ||
188 | |||
189 | __asm__ __volatile__( | ||
190 | " lr %0,%3\n" | ||
191 | " cs %0,%4,0(%2)\n" | ||
192 | " ipm %0\n" | ||
193 | " srl %0,28\n" | ||
194 | "0:" | ||
195 | : "=&d" (retval), "=m" (v->counter) | ||
196 | : "a" (v), "d" (expected_oldval) , "d" (new_val), | ||
197 | "m" (v->counter) : "cc", "memory" ); | ||
198 | return retval; | ||
199 | } | ||
200 | |||
201 | #define smp_mb__before_atomic_dec() smp_mb() | ||
202 | #define smp_mb__after_atomic_dec() smp_mb() | ||
203 | #define smp_mb__before_atomic_inc() smp_mb() | ||
204 | #define smp_mb__after_atomic_inc() smp_mb() | ||
205 | |||
206 | #endif /* __KERNEL__ */ | ||
207 | #endif /* __ARCH_S390_ATOMIC__ */ | ||
diff --git a/include/asm-s390/bitops.h b/include/asm-s390/bitops.h new file mode 100644 index 000000000000..16bb08499c7f --- /dev/null +++ b/include/asm-s390/bitops.h | |||
@@ -0,0 +1,1188 @@ | |||
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 | #include <linux/config.h> | ||
16 | #include <linux/compiler.h> | ||
17 | |||
18 | /* | ||
19 | * 32 bit bitops format: | ||
20 | * bit 0 is the LSB of *addr; bit 31 is the MSB of *addr; | ||
21 | * bit 32 is the LSB of *(addr+4). That combined with the | ||
22 | * big endian byte order on S390 give the following bit | ||
23 | * order in memory: | ||
24 | * 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 \ | ||
25 | * 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 | ||
26 | * after that follows the next long with bit numbers | ||
27 | * 3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 | ||
28 | * 2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20 | ||
29 | * The reason for this bit ordering is the fact that | ||
30 | * in the architecture independent code bits operations | ||
31 | * of the form "flags |= (1 << bitnr)" are used INTERMIXED | ||
32 | * with operation of the form "set_bit(bitnr, flags)". | ||
33 | * | ||
34 | * 64 bit bitops format: | ||
35 | * bit 0 is the LSB of *addr; bit 63 is the MSB of *addr; | ||
36 | * bit 64 is the LSB of *(addr+8). That combined with the | ||
37 | * big endian byte order on S390 give the following bit | ||
38 | * order in memory: | ||
39 | * 3f 3e 3d 3c 3b 3a 39 38 37 36 35 34 33 32 31 30 | ||
40 | * 2f 2e 2d 2c 2b 2a 29 28 27 26 25 24 23 22 21 20 | ||
41 | * 1f 1e 1d 1c 1b 1a 19 18 17 16 15 14 13 12 11 10 | ||
42 | * 0f 0e 0d 0c 0b 0a 09 08 07 06 05 04 03 02 01 00 | ||
43 | * after that follows the next long with bit numbers | ||
44 | * 7f 7e 7d 7c 7b 7a 79 78 77 76 75 74 73 72 71 70 | ||
45 | * 6f 6e 6d 6c 6b 6a 69 68 67 66 65 64 63 62 61 60 | ||
46 | * 5f 5e 5d 5c 5b 5a 59 58 57 56 55 54 53 52 51 50 | ||
47 | * 4f 4e 4d 4c 4b 4a 49 48 47 46 45 44 43 42 41 40 | ||
48 | * The reason for this bit ordering is the fact that | ||
49 | * in the architecture independent code bits operations | ||
50 | * of the form "flags |= (1 << bitnr)" are used INTERMIXED | ||
51 | * with operation of the form "set_bit(bitnr, flags)". | ||
52 | */ | ||
53 | |||
54 | /* set ALIGN_CS to 1 if the SMP safe bit operations should | ||
55 | * align the address to 4 byte boundary. It seems to work | ||
56 | * without the alignment. | ||
57 | */ | ||
58 | #ifdef __KERNEL__ | ||
59 | #define ALIGN_CS 0 | ||
60 | #else | ||
61 | #define ALIGN_CS 1 | ||
62 | #ifndef CONFIG_SMP | ||
63 | #error "bitops won't work without CONFIG_SMP" | ||
64 | #endif | ||
65 | #endif | ||
66 | |||
67 | /* bitmap tables from arch/S390/kernel/bitmap.S */ | ||
68 | extern const char _oi_bitmap[]; | ||
69 | extern const char _ni_bitmap[]; | ||
70 | extern const char _zb_findmap[]; | ||
71 | extern const char _sb_findmap[]; | ||
72 | |||
73 | #ifndef __s390x__ | ||
74 | |||
75 | #define __BITOPS_ALIGN 3 | ||
76 | #define __BITOPS_WORDSIZE 32 | ||
77 | #define __BITOPS_OR "or" | ||
78 | #define __BITOPS_AND "nr" | ||
79 | #define __BITOPS_XOR "xr" | ||
80 | |||
81 | #define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ | ||
82 | __asm__ __volatile__(" l %0,0(%4)\n" \ | ||
83 | "0: lr %1,%0\n" \ | ||
84 | __op_string " %1,%3\n" \ | ||
85 | " cs %0,%1,0(%4)\n" \ | ||
86 | " jl 0b" \ | ||
87 | : "=&d" (__old), "=&d" (__new), \ | ||
88 | "=m" (*(unsigned long *) __addr) \ | ||
89 | : "d" (__val), "a" (__addr), \ | ||
90 | "m" (*(unsigned long *) __addr) : "cc" ); | ||
91 | |||
92 | #else /* __s390x__ */ | ||
93 | |||
94 | #define __BITOPS_ALIGN 7 | ||
95 | #define __BITOPS_WORDSIZE 64 | ||
96 | #define __BITOPS_OR "ogr" | ||
97 | #define __BITOPS_AND "ngr" | ||
98 | #define __BITOPS_XOR "xgr" | ||
99 | |||
100 | #define __BITOPS_LOOP(__old, __new, __addr, __val, __op_string) \ | ||
101 | __asm__ __volatile__(" lg %0,0(%4)\n" \ | ||
102 | "0: lgr %1,%0\n" \ | ||
103 | __op_string " %1,%3\n" \ | ||
104 | " csg %0,%1,0(%4)\n" \ | ||
105 | " jl 0b" \ | ||
106 | : "=&d" (__old), "=&d" (__new), \ | ||
107 | "=m" (*(unsigned long *) __addr) \ | ||
108 | : "d" (__val), "a" (__addr), \ | ||
109 | "m" (*(unsigned long *) __addr) : "cc" ); | ||
110 | |||
111 | #endif /* __s390x__ */ | ||
112 | |||
113 | #define __BITOPS_WORDS(bits) (((bits)+__BITOPS_WORDSIZE-1)/__BITOPS_WORDSIZE) | ||
114 | #define __BITOPS_BARRIER() __asm__ __volatile__ ( "" : : : "memory" ) | ||
115 | |||
116 | #ifdef CONFIG_SMP | ||
117 | /* | ||
118 | * SMP safe set_bit routine based on compare and swap (CS) | ||
119 | */ | ||
120 | static inline void set_bit_cs(unsigned long nr, volatile unsigned long *ptr) | ||
121 | { | ||
122 | unsigned long addr, old, new, mask; | ||
123 | |||
124 | addr = (unsigned long) ptr; | ||
125 | #if ALIGN_CS == 1 | ||
126 | nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */ | ||
127 | addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */ | ||
128 | #endif | ||
129 | /* calculate address for CS */ | ||
130 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | ||
131 | /* make OR mask */ | ||
132 | mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); | ||
133 | /* Do the atomic update. */ | ||
134 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR); | ||
135 | } | ||
136 | |||
137 | /* | ||
138 | * SMP safe clear_bit routine based on compare and swap (CS) | ||
139 | */ | ||
140 | static inline void clear_bit_cs(unsigned long nr, volatile unsigned long *ptr) | ||
141 | { | ||
142 | unsigned long addr, old, new, mask; | ||
143 | |||
144 | addr = (unsigned long) ptr; | ||
145 | #if ALIGN_CS == 1 | ||
146 | nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */ | ||
147 | addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */ | ||
148 | #endif | ||
149 | /* calculate address for CS */ | ||
150 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | ||
151 | /* make AND mask */ | ||
152 | mask = ~(1UL << (nr & (__BITOPS_WORDSIZE - 1))); | ||
153 | /* Do the atomic update. */ | ||
154 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND); | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * SMP safe change_bit routine based on compare and swap (CS) | ||
159 | */ | ||
160 | static inline void change_bit_cs(unsigned long nr, volatile unsigned long *ptr) | ||
161 | { | ||
162 | unsigned long addr, old, new, mask; | ||
163 | |||
164 | addr = (unsigned long) ptr; | ||
165 | #if ALIGN_CS == 1 | ||
166 | nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */ | ||
167 | addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */ | ||
168 | #endif | ||
169 | /* calculate address for CS */ | ||
170 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | ||
171 | /* make XOR mask */ | ||
172 | mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); | ||
173 | /* Do the atomic update. */ | ||
174 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR); | ||
175 | } | ||
176 | |||
177 | /* | ||
178 | * SMP safe test_and_set_bit routine based on compare and swap (CS) | ||
179 | */ | ||
180 | static inline int | ||
181 | test_and_set_bit_cs(unsigned long nr, volatile unsigned long *ptr) | ||
182 | { | ||
183 | unsigned long addr, old, new, mask; | ||
184 | |||
185 | addr = (unsigned long) ptr; | ||
186 | #if ALIGN_CS == 1 | ||
187 | nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */ | ||
188 | addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */ | ||
189 | #endif | ||
190 | /* calculate address for CS */ | ||
191 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | ||
192 | /* make OR/test mask */ | ||
193 | mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); | ||
194 | /* Do the atomic update. */ | ||
195 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_OR); | ||
196 | __BITOPS_BARRIER(); | ||
197 | return (old & mask) != 0; | ||
198 | } | ||
199 | |||
200 | /* | ||
201 | * SMP safe test_and_clear_bit routine based on compare and swap (CS) | ||
202 | */ | ||
203 | static inline int | ||
204 | test_and_clear_bit_cs(unsigned long nr, volatile unsigned long *ptr) | ||
205 | { | ||
206 | unsigned long addr, old, new, mask; | ||
207 | |||
208 | addr = (unsigned long) ptr; | ||
209 | #if ALIGN_CS == 1 | ||
210 | nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */ | ||
211 | addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */ | ||
212 | #endif | ||
213 | /* calculate address for CS */ | ||
214 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | ||
215 | /* make AND/test mask */ | ||
216 | mask = ~(1UL << (nr & (__BITOPS_WORDSIZE - 1))); | ||
217 | /* Do the atomic update. */ | ||
218 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_AND); | ||
219 | __BITOPS_BARRIER(); | ||
220 | return (old ^ new) != 0; | ||
221 | } | ||
222 | |||
223 | /* | ||
224 | * SMP safe test_and_change_bit routine based on compare and swap (CS) | ||
225 | */ | ||
226 | static inline int | ||
227 | test_and_change_bit_cs(unsigned long nr, volatile unsigned long *ptr) | ||
228 | { | ||
229 | unsigned long addr, old, new, mask; | ||
230 | |||
231 | addr = (unsigned long) ptr; | ||
232 | #if ALIGN_CS == 1 | ||
233 | nr += (addr & __BITOPS_ALIGN) << 3; /* add alignment to bit number */ | ||
234 | addr ^= addr & __BITOPS_ALIGN; /* align address to 8 */ | ||
235 | #endif | ||
236 | /* calculate address for CS */ | ||
237 | addr += (nr ^ (nr & (__BITOPS_WORDSIZE - 1))) >> 3; | ||
238 | /* make XOR/test mask */ | ||
239 | mask = 1UL << (nr & (__BITOPS_WORDSIZE - 1)); | ||
240 | /* Do the atomic update. */ | ||
241 | __BITOPS_LOOP(old, new, addr, mask, __BITOPS_XOR); | ||
242 | __BITOPS_BARRIER(); | ||
243 | return (old & mask) != 0; | ||
244 | } | ||
245 | #endif /* CONFIG_SMP */ | ||
246 | |||
247 | /* | ||
248 | * fast, non-SMP set_bit routine | ||
249 | */ | ||
250 | static inline void __set_bit(unsigned long nr, volatile unsigned long *ptr) | ||
251 | { | ||
252 | unsigned long addr; | ||
253 | |||
254 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
255 | asm volatile("oc 0(1,%1),0(%2)" | ||
256 | : "=m" (*(char *) addr) | ||
257 | : "a" (addr), "a" (_oi_bitmap + (nr & 7)), | ||
258 | "m" (*(char *) addr) : "cc" ); | ||
259 | } | ||
260 | |||
261 | static inline void | ||
262 | __constant_set_bit(const unsigned long nr, volatile unsigned long *ptr) | ||
263 | { | ||
264 | unsigned long addr; | ||
265 | |||
266 | addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
267 | switch (nr&7) { | ||
268 | case 0: | ||
269 | asm volatile ("oi 0(%1),0x01" : "=m" (*(char *) addr) | ||
270 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
271 | break; | ||
272 | case 1: | ||
273 | asm volatile ("oi 0(%1),0x02" : "=m" (*(char *) addr) | ||
274 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
275 | break; | ||
276 | case 2: | ||
277 | asm volatile ("oi 0(%1),0x04" : "=m" (*(char *) addr) | ||
278 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
279 | break; | ||
280 | case 3: | ||
281 | asm volatile ("oi 0(%1),0x08" : "=m" (*(char *) addr) | ||
282 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
283 | break; | ||
284 | case 4: | ||
285 | asm volatile ("oi 0(%1),0x10" : "=m" (*(char *) addr) | ||
286 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
287 | break; | ||
288 | case 5: | ||
289 | asm volatile ("oi 0(%1),0x20" : "=m" (*(char *) addr) | ||
290 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
291 | break; | ||
292 | case 6: | ||
293 | asm volatile ("oi 0(%1),0x40" : "=m" (*(char *) addr) | ||
294 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
295 | break; | ||
296 | case 7: | ||
297 | asm volatile ("oi 0(%1),0x80" : "=m" (*(char *) addr) | ||
298 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
299 | break; | ||
300 | } | ||
301 | } | ||
302 | |||
303 | #define set_bit_simple(nr,addr) \ | ||
304 | (__builtin_constant_p((nr)) ? \ | ||
305 | __constant_set_bit((nr),(addr)) : \ | ||
306 | __set_bit((nr),(addr)) ) | ||
307 | |||
308 | /* | ||
309 | * fast, non-SMP clear_bit routine | ||
310 | */ | ||
311 | static inline void | ||
312 | __clear_bit(unsigned long nr, volatile unsigned long *ptr) | ||
313 | { | ||
314 | unsigned long addr; | ||
315 | |||
316 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
317 | asm volatile("nc 0(1,%1),0(%2)" | ||
318 | : "=m" (*(char *) addr) | ||
319 | : "a" (addr), "a" (_ni_bitmap + (nr & 7)), | ||
320 | "m" (*(char *) addr) : "cc" ); | ||
321 | } | ||
322 | |||
323 | static inline void | ||
324 | __constant_clear_bit(const unsigned long nr, volatile unsigned long *ptr) | ||
325 | { | ||
326 | unsigned long addr; | ||
327 | |||
328 | addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
329 | switch (nr&7) { | ||
330 | case 0: | ||
331 | asm volatile ("ni 0(%1),0xFE" : "=m" (*(char *) addr) | ||
332 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
333 | break; | ||
334 | case 1: | ||
335 | asm volatile ("ni 0(%1),0xFD": "=m" (*(char *) addr) | ||
336 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
337 | break; | ||
338 | case 2: | ||
339 | asm volatile ("ni 0(%1),0xFB" : "=m" (*(char *) addr) | ||
340 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
341 | break; | ||
342 | case 3: | ||
343 | asm volatile ("ni 0(%1),0xF7" : "=m" (*(char *) addr) | ||
344 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
345 | break; | ||
346 | case 4: | ||
347 | asm volatile ("ni 0(%1),0xEF" : "=m" (*(char *) addr) | ||
348 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
349 | break; | ||
350 | case 5: | ||
351 | asm volatile ("ni 0(%1),0xDF" : "=m" (*(char *) addr) | ||
352 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
353 | break; | ||
354 | case 6: | ||
355 | asm volatile ("ni 0(%1),0xBF" : "=m" (*(char *) addr) | ||
356 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
357 | break; | ||
358 | case 7: | ||
359 | asm volatile ("ni 0(%1),0x7F" : "=m" (*(char *) addr) | ||
360 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
361 | break; | ||
362 | } | ||
363 | } | ||
364 | |||
365 | #define clear_bit_simple(nr,addr) \ | ||
366 | (__builtin_constant_p((nr)) ? \ | ||
367 | __constant_clear_bit((nr),(addr)) : \ | ||
368 | __clear_bit((nr),(addr)) ) | ||
369 | |||
370 | /* | ||
371 | * fast, non-SMP change_bit routine | ||
372 | */ | ||
373 | static inline void __change_bit(unsigned long nr, volatile unsigned long *ptr) | ||
374 | { | ||
375 | unsigned long addr; | ||
376 | |||
377 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
378 | asm volatile("xc 0(1,%1),0(%2)" | ||
379 | : "=m" (*(char *) addr) | ||
380 | : "a" (addr), "a" (_oi_bitmap + (nr & 7)), | ||
381 | "m" (*(char *) addr) : "cc" ); | ||
382 | } | ||
383 | |||
384 | static inline void | ||
385 | __constant_change_bit(const unsigned long nr, volatile unsigned long *ptr) | ||
386 | { | ||
387 | unsigned long addr; | ||
388 | |||
389 | addr = ((unsigned long) ptr) + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
390 | switch (nr&7) { | ||
391 | case 0: | ||
392 | asm volatile ("xi 0(%1),0x01" : "=m" (*(char *) addr) | ||
393 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
394 | break; | ||
395 | case 1: | ||
396 | asm volatile ("xi 0(%1),0x02" : "=m" (*(char *) addr) | ||
397 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
398 | break; | ||
399 | case 2: | ||
400 | asm volatile ("xi 0(%1),0x04" : "=m" (*(char *) addr) | ||
401 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
402 | break; | ||
403 | case 3: | ||
404 | asm volatile ("xi 0(%1),0x08" : "=m" (*(char *) addr) | ||
405 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
406 | break; | ||
407 | case 4: | ||
408 | asm volatile ("xi 0(%1),0x10" : "=m" (*(char *) addr) | ||
409 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
410 | break; | ||
411 | case 5: | ||
412 | asm volatile ("xi 0(%1),0x20" : "=m" (*(char *) addr) | ||
413 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
414 | break; | ||
415 | case 6: | ||
416 | asm volatile ("xi 0(%1),0x40" : "=m" (*(char *) addr) | ||
417 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
418 | break; | ||
419 | case 7: | ||
420 | asm volatile ("xi 0(%1),0x80" : "=m" (*(char *) addr) | ||
421 | : "a" (addr), "m" (*(char *) addr) : "cc" ); | ||
422 | break; | ||
423 | } | ||
424 | } | ||
425 | |||
426 | #define change_bit_simple(nr,addr) \ | ||
427 | (__builtin_constant_p((nr)) ? \ | ||
428 | __constant_change_bit((nr),(addr)) : \ | ||
429 | __change_bit((nr),(addr)) ) | ||
430 | |||
431 | /* | ||
432 | * fast, non-SMP test_and_set_bit routine | ||
433 | */ | ||
434 | static inline int | ||
435 | test_and_set_bit_simple(unsigned long nr, volatile unsigned long *ptr) | ||
436 | { | ||
437 | unsigned long addr; | ||
438 | unsigned char ch; | ||
439 | |||
440 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
441 | ch = *(unsigned char *) addr; | ||
442 | asm volatile("oc 0(1,%1),0(%2)" | ||
443 | : "=m" (*(char *) addr) | ||
444 | : "a" (addr), "a" (_oi_bitmap + (nr & 7)), | ||
445 | "m" (*(char *) addr) : "cc", "memory" ); | ||
446 | return (ch >> (nr & 7)) & 1; | ||
447 | } | ||
448 | #define __test_and_set_bit(X,Y) test_and_set_bit_simple(X,Y) | ||
449 | |||
450 | /* | ||
451 | * fast, non-SMP test_and_clear_bit routine | ||
452 | */ | ||
453 | static inline int | ||
454 | test_and_clear_bit_simple(unsigned long nr, volatile unsigned long *ptr) | ||
455 | { | ||
456 | unsigned long addr; | ||
457 | unsigned char ch; | ||
458 | |||
459 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
460 | ch = *(unsigned char *) addr; | ||
461 | asm volatile("nc 0(1,%1),0(%2)" | ||
462 | : "=m" (*(char *) addr) | ||
463 | : "a" (addr), "a" (_ni_bitmap + (nr & 7)), | ||
464 | "m" (*(char *) addr) : "cc", "memory" ); | ||
465 | return (ch >> (nr & 7)) & 1; | ||
466 | } | ||
467 | #define __test_and_clear_bit(X,Y) test_and_clear_bit_simple(X,Y) | ||
468 | |||
469 | /* | ||
470 | * fast, non-SMP test_and_change_bit routine | ||
471 | */ | ||
472 | static inline int | ||
473 | test_and_change_bit_simple(unsigned long nr, volatile unsigned long *ptr) | ||
474 | { | ||
475 | unsigned long addr; | ||
476 | unsigned char ch; | ||
477 | |||
478 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
479 | ch = *(unsigned char *) addr; | ||
480 | asm volatile("xc 0(1,%1),0(%2)" | ||
481 | : "=m" (*(char *) addr) | ||
482 | : "a" (addr), "a" (_oi_bitmap + (nr & 7)), | ||
483 | "m" (*(char *) addr) : "cc", "memory" ); | ||
484 | return (ch >> (nr & 7)) & 1; | ||
485 | } | ||
486 | #define __test_and_change_bit(X,Y) test_and_change_bit_simple(X,Y) | ||
487 | |||
488 | #ifdef CONFIG_SMP | ||
489 | #define set_bit set_bit_cs | ||
490 | #define clear_bit clear_bit_cs | ||
491 | #define change_bit change_bit_cs | ||
492 | #define test_and_set_bit test_and_set_bit_cs | ||
493 | #define test_and_clear_bit test_and_clear_bit_cs | ||
494 | #define test_and_change_bit test_and_change_bit_cs | ||
495 | #else | ||
496 | #define set_bit set_bit_simple | ||
497 | #define clear_bit clear_bit_simple | ||
498 | #define change_bit change_bit_simple | ||
499 | #define test_and_set_bit test_and_set_bit_simple | ||
500 | #define test_and_clear_bit test_and_clear_bit_simple | ||
501 | #define test_and_change_bit test_and_change_bit_simple | ||
502 | #endif | ||
503 | |||
504 | |||
505 | /* | ||
506 | * This routine doesn't need to be atomic. | ||
507 | */ | ||
508 | |||
509 | static inline int __test_bit(unsigned long nr, const volatile unsigned long *ptr) | ||
510 | { | ||
511 | unsigned long addr; | ||
512 | unsigned char ch; | ||
513 | |||
514 | addr = (unsigned long) ptr + ((nr ^ (__BITOPS_WORDSIZE - 8)) >> 3); | ||
515 | ch = *(volatile unsigned char *) addr; | ||
516 | return (ch >> (nr & 7)) & 1; | ||
517 | } | ||
518 | |||
519 | static inline int | ||
520 | __constant_test_bit(unsigned long nr, const volatile unsigned long *addr) { | ||
521 | return (((volatile char *) addr) | ||
522 | [(nr^(__BITOPS_WORDSIZE-8))>>3] & (1<<(nr&7))); | ||
523 | } | ||
524 | |||
525 | #define test_bit(nr,addr) \ | ||
526 | (__builtin_constant_p((nr)) ? \ | ||
527 | __constant_test_bit((nr),(addr)) : \ | ||
528 | __test_bit((nr),(addr)) ) | ||
529 | |||
530 | #ifndef __s390x__ | ||
531 | |||
532 | /* | ||
533 | * Find-bit routines.. | ||
534 | */ | ||
535 | static inline int | ||
536 | find_first_zero_bit(const unsigned long * addr, unsigned int size) | ||
537 | { | ||
538 | typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; | ||
539 | unsigned long cmp, count; | ||
540 | unsigned int res; | ||
541 | |||
542 | if (!size) | ||
543 | return 0; | ||
544 | __asm__(" lhi %1,-1\n" | ||
545 | " lr %2,%3\n" | ||
546 | " slr %0,%0\n" | ||
547 | " ahi %2,31\n" | ||
548 | " srl %2,5\n" | ||
549 | "0: c %1,0(%0,%4)\n" | ||
550 | " jne 1f\n" | ||
551 | " ahi %0,4\n" | ||
552 | " brct %2,0b\n" | ||
553 | " lr %0,%3\n" | ||
554 | " j 4f\n" | ||
555 | "1: l %2,0(%0,%4)\n" | ||
556 | " sll %0,3\n" | ||
557 | " lhi %1,0xff\n" | ||
558 | " tml %2,0xffff\n" | ||
559 | " jno 2f\n" | ||
560 | " ahi %0,16\n" | ||
561 | " srl %2,16\n" | ||
562 | "2: tml %2,0x00ff\n" | ||
563 | " jno 3f\n" | ||
564 | " ahi %0,8\n" | ||
565 | " srl %2,8\n" | ||
566 | "3: nr %2,%1\n" | ||
567 | " ic %2,0(%2,%5)\n" | ||
568 | " alr %0,%2\n" | ||
569 | "4:" | ||
570 | : "=&a" (res), "=&d" (cmp), "=&a" (count) | ||
571 | : "a" (size), "a" (addr), "a" (&_zb_findmap), | ||
572 | "m" (*(addrtype *) addr) : "cc" ); | ||
573 | return (res < size) ? res : size; | ||
574 | } | ||
575 | |||
576 | static inline int | ||
577 | find_first_bit(const unsigned long * addr, unsigned int size) | ||
578 | { | ||
579 | typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; | ||
580 | unsigned long cmp, count; | ||
581 | unsigned int res; | ||
582 | |||
583 | if (!size) | ||
584 | return 0; | ||
585 | __asm__(" slr %1,%1\n" | ||
586 | " lr %2,%3\n" | ||
587 | " slr %0,%0\n" | ||
588 | " ahi %2,31\n" | ||
589 | " srl %2,5\n" | ||
590 | "0: c %1,0(%0,%4)\n" | ||
591 | " jne 1f\n" | ||
592 | " ahi %0,4\n" | ||
593 | " brct %2,0b\n" | ||
594 | " lr %0,%3\n" | ||
595 | " j 4f\n" | ||
596 | "1: l %2,0(%0,%4)\n" | ||
597 | " sll %0,3\n" | ||
598 | " lhi %1,0xff\n" | ||
599 | " tml %2,0xffff\n" | ||
600 | " jnz 2f\n" | ||
601 | " ahi %0,16\n" | ||
602 | " srl %2,16\n" | ||
603 | "2: tml %2,0x00ff\n" | ||
604 | " jnz 3f\n" | ||
605 | " ahi %0,8\n" | ||
606 | " srl %2,8\n" | ||
607 | "3: nr %2,%1\n" | ||
608 | " ic %2,0(%2,%5)\n" | ||
609 | " alr %0,%2\n" | ||
610 | "4:" | ||
611 | : "=&a" (res), "=&d" (cmp), "=&a" (count) | ||
612 | : "a" (size), "a" (addr), "a" (&_sb_findmap), | ||
613 | "m" (*(addrtype *) addr) : "cc" ); | ||
614 | return (res < size) ? res : size; | ||
615 | } | ||
616 | |||
617 | static inline int | ||
618 | find_next_zero_bit (const unsigned long * addr, int size, int offset) | ||
619 | { | ||
620 | unsigned long * p = ((unsigned long *) addr) + (offset >> 5); | ||
621 | unsigned long bitvec, reg; | ||
622 | int set, bit = offset & 31, res; | ||
623 | |||
624 | if (bit) { | ||
625 | /* | ||
626 | * Look for zero in first word | ||
627 | */ | ||
628 | bitvec = (*p) >> bit; | ||
629 | __asm__(" slr %0,%0\n" | ||
630 | " lhi %2,0xff\n" | ||
631 | " tml %1,0xffff\n" | ||
632 | " jno 0f\n" | ||
633 | " ahi %0,16\n" | ||
634 | " srl %1,16\n" | ||
635 | "0: tml %1,0x00ff\n" | ||
636 | " jno 1f\n" | ||
637 | " ahi %0,8\n" | ||
638 | " srl %1,8\n" | ||
639 | "1: nr %1,%2\n" | ||
640 | " ic %1,0(%1,%3)\n" | ||
641 | " alr %0,%1" | ||
642 | : "=&d" (set), "+a" (bitvec), "=&d" (reg) | ||
643 | : "a" (&_zb_findmap) : "cc" ); | ||
644 | if (set < (32 - bit)) | ||
645 | return set + offset; | ||
646 | offset += 32 - bit; | ||
647 | p++; | ||
648 | } | ||
649 | /* | ||
650 | * No zero yet, search remaining full words for a zero | ||
651 | */ | ||
652 | res = find_first_zero_bit (p, size - 32 * (p - (unsigned long *) addr)); | ||
653 | return (offset + res); | ||
654 | } | ||
655 | |||
656 | static inline int | ||
657 | find_next_bit (const unsigned long * addr, int size, int offset) | ||
658 | { | ||
659 | unsigned long * p = ((unsigned long *) addr) + (offset >> 5); | ||
660 | unsigned long bitvec, reg; | ||
661 | int set, bit = offset & 31, res; | ||
662 | |||
663 | if (bit) { | ||
664 | /* | ||
665 | * Look for set bit in first word | ||
666 | */ | ||
667 | bitvec = (*p) >> bit; | ||
668 | __asm__(" slr %0,%0\n" | ||
669 | " lhi %2,0xff\n" | ||
670 | " tml %1,0xffff\n" | ||
671 | " jnz 0f\n" | ||
672 | " ahi %0,16\n" | ||
673 | " srl %1,16\n" | ||
674 | "0: tml %1,0x00ff\n" | ||
675 | " jnz 1f\n" | ||
676 | " ahi %0,8\n" | ||
677 | " srl %1,8\n" | ||
678 | "1: nr %1,%2\n" | ||
679 | " ic %1,0(%1,%3)\n" | ||
680 | " alr %0,%1" | ||
681 | : "=&d" (set), "+a" (bitvec), "=&d" (reg) | ||
682 | : "a" (&_sb_findmap) : "cc" ); | ||
683 | if (set < (32 - bit)) | ||
684 | return set + offset; | ||
685 | offset += 32 - bit; | ||
686 | p++; | ||
687 | } | ||
688 | /* | ||
689 | * No set bit yet, search remaining full words for a bit | ||
690 | */ | ||
691 | res = find_first_bit (p, size - 32 * (p - (unsigned long *) addr)); | ||
692 | return (offset + res); | ||
693 | } | ||
694 | |||
695 | #else /* __s390x__ */ | ||
696 | |||
697 | /* | ||
698 | * Find-bit routines.. | ||
699 | */ | ||
700 | static inline unsigned long | ||
701 | find_first_zero_bit(const unsigned long * addr, unsigned long size) | ||
702 | { | ||
703 | typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; | ||
704 | unsigned long res, cmp, count; | ||
705 | |||
706 | if (!size) | ||
707 | return 0; | ||
708 | __asm__(" lghi %1,-1\n" | ||
709 | " lgr %2,%3\n" | ||
710 | " slgr %0,%0\n" | ||
711 | " aghi %2,63\n" | ||
712 | " srlg %2,%2,6\n" | ||
713 | "0: cg %1,0(%0,%4)\n" | ||
714 | " jne 1f\n" | ||
715 | " aghi %0,8\n" | ||
716 | " brct %2,0b\n" | ||
717 | " lgr %0,%3\n" | ||
718 | " j 5f\n" | ||
719 | "1: lg %2,0(%0,%4)\n" | ||
720 | " sllg %0,%0,3\n" | ||
721 | " clr %2,%1\n" | ||
722 | " jne 2f\n" | ||
723 | " aghi %0,32\n" | ||
724 | " srlg %2,%2,32\n" | ||
725 | "2: lghi %1,0xff\n" | ||
726 | " tmll %2,0xffff\n" | ||
727 | " jno 3f\n" | ||
728 | " aghi %0,16\n" | ||
729 | " srl %2,16\n" | ||
730 | "3: tmll %2,0x00ff\n" | ||
731 | " jno 4f\n" | ||
732 | " aghi %0,8\n" | ||
733 | " srl %2,8\n" | ||
734 | "4: ngr %2,%1\n" | ||
735 | " ic %2,0(%2,%5)\n" | ||
736 | " algr %0,%2\n" | ||
737 | "5:" | ||
738 | : "=&a" (res), "=&d" (cmp), "=&a" (count) | ||
739 | : "a" (size), "a" (addr), "a" (&_zb_findmap), | ||
740 | "m" (*(addrtype *) addr) : "cc" ); | ||
741 | return (res < size) ? res : size; | ||
742 | } | ||
743 | |||
744 | static inline unsigned long | ||
745 | find_first_bit(const unsigned long * addr, unsigned long size) | ||
746 | { | ||
747 | typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; | ||
748 | unsigned long res, cmp, count; | ||
749 | |||
750 | if (!size) | ||
751 | return 0; | ||
752 | __asm__(" slgr %1,%1\n" | ||
753 | " lgr %2,%3\n" | ||
754 | " slgr %0,%0\n" | ||
755 | " aghi %2,63\n" | ||
756 | " srlg %2,%2,6\n" | ||
757 | "0: cg %1,0(%0,%4)\n" | ||
758 | " jne 1f\n" | ||
759 | " aghi %0,8\n" | ||
760 | " brct %2,0b\n" | ||
761 | " lgr %0,%3\n" | ||
762 | " j 5f\n" | ||
763 | "1: lg %2,0(%0,%4)\n" | ||
764 | " sllg %0,%0,3\n" | ||
765 | " clr %2,%1\n" | ||
766 | " jne 2f\n" | ||
767 | " aghi %0,32\n" | ||
768 | " srlg %2,%2,32\n" | ||
769 | "2: lghi %1,0xff\n" | ||
770 | " tmll %2,0xffff\n" | ||
771 | " jnz 3f\n" | ||
772 | " aghi %0,16\n" | ||
773 | " srl %2,16\n" | ||
774 | "3: tmll %2,0x00ff\n" | ||
775 | " jnz 4f\n" | ||
776 | " aghi %0,8\n" | ||
777 | " srl %2,8\n" | ||
778 | "4: ngr %2,%1\n" | ||
779 | " ic %2,0(%2,%5)\n" | ||
780 | " algr %0,%2\n" | ||
781 | "5:" | ||
782 | : "=&a" (res), "=&d" (cmp), "=&a" (count) | ||
783 | : "a" (size), "a" (addr), "a" (&_sb_findmap), | ||
784 | "m" (*(addrtype *) addr) : "cc" ); | ||
785 | return (res < size) ? res : size; | ||
786 | } | ||
787 | |||
788 | static inline unsigned long | ||
789 | find_next_zero_bit (const unsigned long * addr, unsigned long size, unsigned long offset) | ||
790 | { | ||
791 | unsigned long * p = ((unsigned long *) addr) + (offset >> 6); | ||
792 | unsigned long bitvec, reg; | ||
793 | unsigned long set, bit = offset & 63, res; | ||
794 | |||
795 | if (bit) { | ||
796 | /* | ||
797 | * Look for zero in first word | ||
798 | */ | ||
799 | bitvec = (*p) >> bit; | ||
800 | __asm__(" lhi %2,-1\n" | ||
801 | " slgr %0,%0\n" | ||
802 | " clr %1,%2\n" | ||
803 | " jne 0f\n" | ||
804 | " aghi %0,32\n" | ||
805 | " srlg %1,%1,32\n" | ||
806 | "0: lghi %2,0xff\n" | ||
807 | " tmll %1,0xffff\n" | ||
808 | " jno 1f\n" | ||
809 | " aghi %0,16\n" | ||
810 | " srlg %1,%1,16\n" | ||
811 | "1: tmll %1,0x00ff\n" | ||
812 | " jno 2f\n" | ||
813 | " aghi %0,8\n" | ||
814 | " srlg %1,%1,8\n" | ||
815 | "2: ngr %1,%2\n" | ||
816 | " ic %1,0(%1,%3)\n" | ||
817 | " algr %0,%1" | ||
818 | : "=&d" (set), "+a" (bitvec), "=&d" (reg) | ||
819 | : "a" (&_zb_findmap) : "cc" ); | ||
820 | if (set < (64 - bit)) | ||
821 | return set + offset; | ||
822 | offset += 64 - bit; | ||
823 | p++; | ||
824 | } | ||
825 | /* | ||
826 | * No zero yet, search remaining full words for a zero | ||
827 | */ | ||
828 | res = find_first_zero_bit (p, size - 64 * (p - (unsigned long *) addr)); | ||
829 | return (offset + res); | ||
830 | } | ||
831 | |||
832 | static inline unsigned long | ||
833 | find_next_bit (const unsigned long * addr, unsigned long size, unsigned long offset) | ||
834 | { | ||
835 | unsigned long * p = ((unsigned long *) addr) + (offset >> 6); | ||
836 | unsigned long bitvec, reg; | ||
837 | unsigned long set, bit = offset & 63, res; | ||
838 | |||
839 | if (bit) { | ||
840 | /* | ||
841 | * Look for zero in first word | ||
842 | */ | ||
843 | bitvec = (*p) >> bit; | ||
844 | __asm__(" slgr %0,%0\n" | ||
845 | " ltr %1,%1\n" | ||
846 | " jnz 0f\n" | ||
847 | " aghi %0,32\n" | ||
848 | " srlg %1,%1,32\n" | ||
849 | "0: lghi %2,0xff\n" | ||
850 | " tmll %1,0xffff\n" | ||
851 | " jnz 1f\n" | ||
852 | " aghi %0,16\n" | ||
853 | " srlg %1,%1,16\n" | ||
854 | "1: tmll %1,0x00ff\n" | ||
855 | " jnz 2f\n" | ||
856 | " aghi %0,8\n" | ||
857 | " srlg %1,%1,8\n" | ||
858 | "2: ngr %1,%2\n" | ||
859 | " ic %1,0(%1,%3)\n" | ||
860 | " algr %0,%1" | ||
861 | : "=&d" (set), "+a" (bitvec), "=&d" (reg) | ||
862 | : "a" (&_sb_findmap) : "cc" ); | ||
863 | if (set < (64 - bit)) | ||
864 | return set + offset; | ||
865 | offset += 64 - bit; | ||
866 | p++; | ||
867 | } | ||
868 | /* | ||
869 | * No set bit yet, search remaining full words for a bit | ||
870 | */ | ||
871 | res = find_first_bit (p, size - 64 * (p - (unsigned long *) addr)); | ||
872 | return (offset + res); | ||
873 | } | ||
874 | |||
875 | #endif /* __s390x__ */ | ||
876 | |||
877 | /* | ||
878 | * ffz = Find First Zero in word. Undefined if no zero exists, | ||
879 | * so code should check against ~0UL first.. | ||
880 | */ | ||
881 | static inline unsigned long ffz(unsigned long word) | ||
882 | { | ||
883 | unsigned long bit = 0; | ||
884 | |||
885 | #ifdef __s390x__ | ||
886 | if (likely((word & 0xffffffff) == 0xffffffff)) { | ||
887 | word >>= 32; | ||
888 | bit += 32; | ||
889 | } | ||
890 | #endif | ||
891 | if (likely((word & 0xffff) == 0xffff)) { | ||
892 | word >>= 16; | ||
893 | bit += 16; | ||
894 | } | ||
895 | if (likely((word & 0xff) == 0xff)) { | ||
896 | word >>= 8; | ||
897 | bit += 8; | ||
898 | } | ||
899 | return bit + _zb_findmap[word & 0xff]; | ||
900 | } | ||
901 | |||
902 | /* | ||
903 | * __ffs = find first bit in word. Undefined if no bit exists, | ||
904 | * so code should check against 0UL first.. | ||
905 | */ | ||
906 | static inline unsigned long __ffs (unsigned long word) | ||
907 | { | ||
908 | unsigned long bit = 0; | ||
909 | |||
910 | #ifdef __s390x__ | ||
911 | if (likely((word & 0xffffffff) == 0)) { | ||
912 | word >>= 32; | ||
913 | bit += 32; | ||
914 | } | ||
915 | #endif | ||
916 | if (likely((word & 0xffff) == 0)) { | ||
917 | word >>= 16; | ||
918 | bit += 16; | ||
919 | } | ||
920 | if (likely((word & 0xff) == 0)) { | ||
921 | word >>= 8; | ||
922 | bit += 8; | ||
923 | } | ||
924 | return bit + _sb_findmap[word & 0xff]; | ||
925 | } | ||
926 | |||
927 | /* | ||
928 | * Every architecture must define this function. It's the fastest | ||
929 | * way of searching a 140-bit bitmap where the first 100 bits are | ||
930 | * unlikely to be set. It's guaranteed that at least one of the 140 | ||
931 | * bits is cleared. | ||
932 | */ | ||
933 | static inline int sched_find_first_bit(unsigned long *b) | ||
934 | { | ||
935 | return find_first_bit(b, 140); | ||
936 | } | ||
937 | |||
938 | /* | ||
939 | * ffs: find first bit set. This is defined the same way as | ||
940 | * the libc and compiler builtin ffs routines, therefore | ||
941 | * differs in spirit from the above ffz (man ffs). | ||
942 | */ | ||
943 | #define ffs(x) generic_ffs(x) | ||
944 | |||
945 | /* | ||
946 | * fls: find last bit set. | ||
947 | */ | ||
948 | #define fls(x) generic_fls(x) | ||
949 | |||
950 | /* | ||
951 | * hweightN: returns the hamming weight (i.e. the number | ||
952 | * of bits set) of a N-bit word | ||
953 | */ | ||
954 | #define hweight64(x) \ | ||
955 | ({ \ | ||
956 | unsigned long __x = (x); \ | ||
957 | unsigned int __w; \ | ||
958 | __w = generic_hweight32((unsigned int) __x); \ | ||
959 | __w += generic_hweight32((unsigned int) (__x>>32)); \ | ||
960 | __w; \ | ||
961 | }) | ||
962 | #define hweight32(x) generic_hweight32(x) | ||
963 | #define hweight16(x) generic_hweight16(x) | ||
964 | #define hweight8(x) generic_hweight8(x) | ||
965 | |||
966 | |||
967 | #ifdef __KERNEL__ | ||
968 | |||
969 | /* | ||
970 | * ATTENTION: intel byte ordering convention for ext2 and minix !! | ||
971 | * bit 0 is the LSB of addr; bit 31 is the MSB of addr; | ||
972 | * bit 32 is the LSB of (addr+4). | ||
973 | * That combined with the little endian byte order of Intel gives the | ||
974 | * following bit order in memory: | ||
975 | * 07 06 05 04 03 02 01 00 15 14 13 12 11 10 09 08 \ | ||
976 | * 23 22 21 20 19 18 17 16 31 30 29 28 27 26 25 24 | ||
977 | */ | ||
978 | |||
979 | #define ext2_set_bit(nr, addr) \ | ||
980 | test_and_set_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) | ||
981 | #define ext2_set_bit_atomic(lock, nr, addr) \ | ||
982 | test_and_set_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) | ||
983 | #define ext2_clear_bit(nr, addr) \ | ||
984 | test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) | ||
985 | #define ext2_clear_bit_atomic(lock, nr, addr) \ | ||
986 | test_and_clear_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) | ||
987 | #define ext2_test_bit(nr, addr) \ | ||
988 | test_bit((nr)^(__BITOPS_WORDSIZE - 8), (unsigned long *)addr) | ||
989 | |||
990 | #ifndef __s390x__ | ||
991 | |||
992 | static inline int | ||
993 | ext2_find_first_zero_bit(void *vaddr, unsigned int size) | ||
994 | { | ||
995 | typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; | ||
996 | unsigned long cmp, count; | ||
997 | unsigned int res; | ||
998 | |||
999 | if (!size) | ||
1000 | return 0; | ||
1001 | __asm__(" lhi %1,-1\n" | ||
1002 | " lr %2,%3\n" | ||
1003 | " ahi %2,31\n" | ||
1004 | " srl %2,5\n" | ||
1005 | " slr %0,%0\n" | ||
1006 | "0: cl %1,0(%0,%4)\n" | ||
1007 | " jne 1f\n" | ||
1008 | " ahi %0,4\n" | ||
1009 | " brct %2,0b\n" | ||
1010 | " lr %0,%3\n" | ||
1011 | " j 4f\n" | ||
1012 | "1: l %2,0(%0,%4)\n" | ||
1013 | " sll %0,3\n" | ||
1014 | " ahi %0,24\n" | ||
1015 | " lhi %1,0xff\n" | ||
1016 | " tmh %2,0xffff\n" | ||
1017 | " jo 2f\n" | ||
1018 | " ahi %0,-16\n" | ||
1019 | " srl %2,16\n" | ||
1020 | "2: tml %2,0xff00\n" | ||
1021 | " jo 3f\n" | ||
1022 | " ahi %0,-8\n" | ||
1023 | " srl %2,8\n" | ||
1024 | "3: nr %2,%1\n" | ||
1025 | " ic %2,0(%2,%5)\n" | ||
1026 | " alr %0,%2\n" | ||
1027 | "4:" | ||
1028 | : "=&a" (res), "=&d" (cmp), "=&a" (count) | ||
1029 | : "a" (size), "a" (vaddr), "a" (&_zb_findmap), | ||
1030 | "m" (*(addrtype *) vaddr) : "cc" ); | ||
1031 | return (res < size) ? res : size; | ||
1032 | } | ||
1033 | |||
1034 | static inline int | ||
1035 | ext2_find_next_zero_bit(void *vaddr, unsigned int size, unsigned offset) | ||
1036 | { | ||
1037 | unsigned long *addr = vaddr; | ||
1038 | unsigned long *p = addr + (offset >> 5); | ||
1039 | unsigned long word, reg; | ||
1040 | unsigned int bit = offset & 31UL, res; | ||
1041 | |||
1042 | if (offset >= size) | ||
1043 | return size; | ||
1044 | |||
1045 | if (bit) { | ||
1046 | __asm__(" ic %0,0(%1)\n" | ||
1047 | " icm %0,2,1(%1)\n" | ||
1048 | " icm %0,4,2(%1)\n" | ||
1049 | " icm %0,8,3(%1)" | ||
1050 | : "=&a" (word) : "a" (p) : "cc" ); | ||
1051 | word >>= bit; | ||
1052 | res = bit; | ||
1053 | /* Look for zero in first longword */ | ||
1054 | __asm__(" lhi %2,0xff\n" | ||
1055 | " tml %1,0xffff\n" | ||
1056 | " jno 0f\n" | ||
1057 | " ahi %0,16\n" | ||
1058 | " srl %1,16\n" | ||
1059 | "0: tml %1,0x00ff\n" | ||
1060 | " jno 1f\n" | ||
1061 | " ahi %0,8\n" | ||
1062 | " srl %1,8\n" | ||
1063 | "1: nr %1,%2\n" | ||
1064 | " ic %1,0(%1,%3)\n" | ||
1065 | " alr %0,%1" | ||
1066 | : "+&d" (res), "+&a" (word), "=&d" (reg) | ||
1067 | : "a" (&_zb_findmap) : "cc" ); | ||
1068 | if (res < 32) | ||
1069 | return (p - addr)*32 + res; | ||
1070 | p++; | ||
1071 | } | ||
1072 | /* No zero yet, search remaining full bytes for a zero */ | ||
1073 | res = ext2_find_first_zero_bit (p, size - 32 * (p - addr)); | ||
1074 | return (p - addr) * 32 + res; | ||
1075 | } | ||
1076 | |||
1077 | #else /* __s390x__ */ | ||
1078 | |||
1079 | static inline unsigned long | ||
1080 | ext2_find_first_zero_bit(void *vaddr, unsigned long size) | ||
1081 | { | ||
1082 | typedef struct { long _[__BITOPS_WORDS(size)]; } addrtype; | ||
1083 | unsigned long res, cmp, count; | ||
1084 | |||
1085 | if (!size) | ||
1086 | return 0; | ||
1087 | __asm__(" lghi %1,-1\n" | ||
1088 | " lgr %2,%3\n" | ||
1089 | " aghi %2,63\n" | ||
1090 | " srlg %2,%2,6\n" | ||
1091 | " slgr %0,%0\n" | ||
1092 | "0: clg %1,0(%0,%4)\n" | ||
1093 | " jne 1f\n" | ||
1094 | " aghi %0,8\n" | ||
1095 | " brct %2,0b\n" | ||
1096 | " lgr %0,%3\n" | ||
1097 | " j 5f\n" | ||
1098 | "1: cl %1,0(%0,%4)\n" | ||
1099 | " jne 2f\n" | ||
1100 | " aghi %0,4\n" | ||
1101 | "2: l %2,0(%0,%4)\n" | ||
1102 | " sllg %0,%0,3\n" | ||
1103 | " aghi %0,24\n" | ||
1104 | " lghi %1,0xff\n" | ||
1105 | " tmlh %2,0xffff\n" | ||
1106 | " jo 3f\n" | ||
1107 | " aghi %0,-16\n" | ||
1108 | " srl %2,16\n" | ||
1109 | "3: tmll %2,0xff00\n" | ||
1110 | " jo 4f\n" | ||
1111 | " aghi %0,-8\n" | ||
1112 | " srl %2,8\n" | ||
1113 | "4: ngr %2,%1\n" | ||
1114 | " ic %2,0(%2,%5)\n" | ||
1115 | " algr %0,%2\n" | ||
1116 | "5:" | ||
1117 | : "=&a" (res), "=&d" (cmp), "=&a" (count) | ||
1118 | : "a" (size), "a" (vaddr), "a" (&_zb_findmap), | ||
1119 | "m" (*(addrtype *) vaddr) : "cc" ); | ||
1120 | return (res < size) ? res : size; | ||
1121 | } | ||
1122 | |||
1123 | static inline unsigned long | ||
1124 | ext2_find_next_zero_bit(void *vaddr, unsigned long size, unsigned long offset) | ||
1125 | { | ||
1126 | unsigned long *addr = vaddr; | ||
1127 | unsigned long *p = addr + (offset >> 6); | ||
1128 | unsigned long word, reg; | ||
1129 | unsigned long bit = offset & 63UL, res; | ||
1130 | |||
1131 | if (offset >= size) | ||
1132 | return size; | ||
1133 | |||
1134 | if (bit) { | ||
1135 | __asm__(" lrvg %0,%1" /* load reversed, neat instruction */ | ||
1136 | : "=a" (word) : "m" (*p) ); | ||
1137 | word >>= bit; | ||
1138 | res = bit; | ||
1139 | /* Look for zero in first 8 byte word */ | ||
1140 | __asm__(" lghi %2,0xff\n" | ||
1141 | " tmll %1,0xffff\n" | ||
1142 | " jno 2f\n" | ||
1143 | " ahi %0,16\n" | ||
1144 | " srlg %1,%1,16\n" | ||
1145 | "0: tmll %1,0xffff\n" | ||
1146 | " jno 2f\n" | ||
1147 | " ahi %0,16\n" | ||
1148 | " srlg %1,%1,16\n" | ||
1149 | "1: tmll %1,0xffff\n" | ||
1150 | " jno 2f\n" | ||
1151 | " ahi %0,16\n" | ||
1152 | " srl %1,16\n" | ||
1153 | "2: tmll %1,0x00ff\n" | ||
1154 | " jno 3f\n" | ||
1155 | " ahi %0,8\n" | ||
1156 | " srl %1,8\n" | ||
1157 | "3: ngr %1,%2\n" | ||
1158 | " ic %1,0(%1,%3)\n" | ||
1159 | " alr %0,%1" | ||
1160 | : "+&d" (res), "+a" (word), "=&d" (reg) | ||
1161 | : "a" (&_zb_findmap) : "cc" ); | ||
1162 | if (res < 64) | ||
1163 | return (p - addr)*64 + res; | ||
1164 | p++; | ||
1165 | } | ||
1166 | /* No zero yet, search remaining full bytes for a zero */ | ||
1167 | res = ext2_find_first_zero_bit (p, size - 64 * (p - addr)); | ||
1168 | return (p - addr) * 64 + res; | ||
1169 | } | ||
1170 | |||
1171 | #endif /* __s390x__ */ | ||
1172 | |||
1173 | /* Bitmap functions for the minix filesystem. */ | ||
1174 | /* FIXME !!! */ | ||
1175 | #define minix_test_and_set_bit(nr,addr) \ | ||
1176 | test_and_set_bit(nr,(unsigned long *)addr) | ||
1177 | #define minix_set_bit(nr,addr) \ | ||
1178 | set_bit(nr,(unsigned long *)addr) | ||
1179 | #define minix_test_and_clear_bit(nr,addr) \ | ||
1180 | test_and_clear_bit(nr,(unsigned long *)addr) | ||
1181 | #define minix_test_bit(nr,addr) \ | ||
1182 | test_bit(nr,(unsigned long *)addr) | ||
1183 | #define minix_find_first_zero_bit(addr,size) \ | ||
1184 | find_first_zero_bit(addr,size) | ||
1185 | |||
1186 | #endif /* __KERNEL__ */ | ||
1187 | |||
1188 | #endif /* _S390_BITOPS_H */ | ||
diff --git a/include/asm-s390/bug.h b/include/asm-s390/bug.h new file mode 100644 index 000000000000..2b8d6d4dffcf --- /dev/null +++ b/include/asm-s390/bug.h | |||
@@ -0,0 +1,14 @@ | |||
1 | #ifndef _S390_BUG_H | ||
2 | #define _S390_BUG_H | ||
3 | |||
4 | #include <linux/kernel.h> | ||
5 | |||
6 | #define BUG() do { \ | ||
7 | printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); \ | ||
8 | __asm__ __volatile__(".long 0"); \ | ||
9 | } while (0) | ||
10 | |||
11 | #define HAVE_ARCH_BUG | ||
12 | #include <asm-generic/bug.h> | ||
13 | |||
14 | #endif | ||
diff --git a/include/asm-s390/bugs.h b/include/asm-s390/bugs.h new file mode 100644 index 000000000000..2c3659621314 --- /dev/null +++ b/include/asm-s390/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 void __init check_bugs(void) | ||
20 | { | ||
21 | /* s390 has no bugs ... */ | ||
22 | } | ||
diff --git a/include/asm-s390/byteorder.h b/include/asm-s390/byteorder.h new file mode 100644 index 000000000000..2cc35a0e188e --- /dev/null +++ b/include/asm-s390/byteorder.h | |||
@@ -0,0 +1,131 @@ | |||
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__ ( | ||
22 | " lrvg %0,%1" | ||
23 | : "=d" (result) : "m" (*x) ); | ||
24 | return result; | ||
25 | } | ||
26 | |||
27 | static __inline__ __u64 ___arch__swab64(__u64 x) | ||
28 | { | ||
29 | __u64 result; | ||
30 | |||
31 | __asm__ __volatile__ ( | ||
32 | " lrvgr %0,%1" | ||
33 | : "=d" (result) : "d" (x) ); | ||
34 | return result; | ||
35 | } | ||
36 | |||
37 | static __inline__ void ___arch__swab64s(__u64 *x) | ||
38 | { | ||
39 | *x = ___arch__swab64p(x); | ||
40 | } | ||
41 | #endif /* __s390x__ */ | ||
42 | |||
43 | static __inline__ __u32 ___arch__swab32p(const __u32 *x) | ||
44 | { | ||
45 | __u32 result; | ||
46 | |||
47 | __asm__ __volatile__ ( | ||
48 | #ifndef __s390x__ | ||
49 | " icm %0,8,3(%1)\n" | ||
50 | " icm %0,4,2(%1)\n" | ||
51 | " icm %0,2,1(%1)\n" | ||
52 | " ic %0,0(%1)" | ||
53 | : "=&d" (result) : "a" (x), "m" (*x) : "cc" ); | ||
54 | #else /* __s390x__ */ | ||
55 | " lrv %0,%1" | ||
56 | : "=d" (result) : "m" (*x) ); | ||
57 | #endif /* __s390x__ */ | ||
58 | return result; | ||
59 | } | ||
60 | |||
61 | static __inline__ __u32 ___arch__swab32(__u32 x) | ||
62 | { | ||
63 | #ifndef __s390x__ | ||
64 | return ___arch__swab32p(&x); | ||
65 | #else /* __s390x__ */ | ||
66 | __u32 result; | ||
67 | |||
68 | __asm__ __volatile__ ( | ||
69 | " lrvr %0,%1" | ||
70 | : "=d" (result) : "d" (x) ); | ||
71 | return result; | ||
72 | #endif /* __s390x__ */ | ||
73 | } | ||
74 | |||
75 | static __inline__ void ___arch__swab32s(__u32 *x) | ||
76 | { | ||
77 | *x = ___arch__swab32p(x); | ||
78 | } | ||
79 | |||
80 | static __inline__ __u16 ___arch__swab16p(const __u16 *x) | ||
81 | { | ||
82 | __u16 result; | ||
83 | |||
84 | __asm__ __volatile__ ( | ||
85 | #ifndef __s390x__ | ||
86 | " icm %0,2,1(%1)\n" | ||
87 | " ic %0,0(%1)\n" | ||
88 | : "=&d" (result) : "a" (x), "m" (*x) : "cc" ); | ||
89 | #else /* __s390x__ */ | ||
90 | " lrvh %0,%1" | ||
91 | : "=d" (result) : "m" (*x) ); | ||
92 | #endif /* __s390x__ */ | ||
93 | return result; | ||
94 | } | ||
95 | |||
96 | static __inline__ __u16 ___arch__swab16(__u16 x) | ||
97 | { | ||
98 | return ___arch__swab16p(&x); | ||
99 | } | ||
100 | |||
101 | static __inline__ void ___arch__swab16s(__u16 *x) | ||
102 | { | ||
103 | *x = ___arch__swab16p(x); | ||
104 | } | ||
105 | |||
106 | #ifdef __s390x__ | ||
107 | #define __arch__swab64(x) ___arch__swab64(x) | ||
108 | #define __arch__swab64p(x) ___arch__swab64p(x) | ||
109 | #define __arch__swab64s(x) ___arch__swab64s(x) | ||
110 | #endif /* __s390x__ */ | ||
111 | #define __arch__swab32(x) ___arch__swab32(x) | ||
112 | #define __arch__swab16(x) ___arch__swab16(x) | ||
113 | #define __arch__swab32p(x) ___arch__swab32p(x) | ||
114 | #define __arch__swab16p(x) ___arch__swab16p(x) | ||
115 | #define __arch__swab32s(x) ___arch__swab32s(x) | ||
116 | #define __arch__swab16s(x) ___arch__swab16s(x) | ||
117 | |||
118 | #ifndef __s390x__ | ||
119 | #if !defined(__STRICT_ANSI__) || defined(__KERNEL__) | ||
120 | # define __BYTEORDER_HAS_U64__ | ||
121 | # define __SWAB_64_THRU_32__ | ||
122 | #endif | ||
123 | #else /* __s390x__ */ | ||
124 | #define __BYTEORDER_HAS_U64__ | ||
125 | #endif /* __s390x__ */ | ||
126 | |||
127 | #endif /* __GNUC__ */ | ||
128 | |||
129 | #include <linux/byteorder/big_endian.h> | ||
130 | |||
131 | #endif /* _S390_BYTEORDER_H */ | ||
diff --git a/include/asm-s390/cache.h b/include/asm-s390/cache.h new file mode 100644 index 000000000000..29845378b206 --- /dev/null +++ b/include/asm-s390/cache.h | |||
@@ -0,0 +1,20 @@ | |||
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 | #define L1_CACHE_SHIFT_MAX 8 /* largest L1 which this arch supports */ | ||
17 | |||
18 | #define ARCH_KMALLOC_MINALIGN 8 | ||
19 | |||
20 | #endif | ||
diff --git a/include/asm-s390/cacheflush.h b/include/asm-s390/cacheflush.h new file mode 100644 index 000000000000..e399a8ba2ed7 --- /dev/null +++ b/include/asm-s390/cacheflush.h | |||
@@ -0,0 +1,26 @@ | |||
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_range(vma, start, end) do { } while (0) | ||
11 | #define flush_cache_page(vma, vmaddr, pfn) do { } while (0) | ||
12 | #define flush_dcache_page(page) do { } while (0) | ||
13 | #define flush_dcache_mmap_lock(mapping) do { } while (0) | ||
14 | #define flush_dcache_mmap_unlock(mapping) do { } while (0) | ||
15 | #define flush_icache_range(start, end) do { } while (0) | ||
16 | #define flush_icache_page(vma,pg) do { } while (0) | ||
17 | #define flush_icache_user_range(vma,pg,adr,len) do { } while (0) | ||
18 | #define flush_cache_vmap(start, end) do { } while (0) | ||
19 | #define flush_cache_vunmap(start, end) do { } while (0) | ||
20 | |||
21 | #define copy_to_user_page(vma, page, vaddr, dst, src, len) \ | ||
22 | memcpy(dst, src, len) | ||
23 | #define copy_from_user_page(vma, page, vaddr, dst, src, len) \ | ||
24 | memcpy(dst, src, len) | ||
25 | |||
26 | #endif /* _S390_CACHEFLUSH_H */ | ||
diff --git a/include/asm-s390/ccwdev.h b/include/asm-s390/ccwdev.h new file mode 100644 index 000000000000..3eb231af5d51 --- /dev/null +++ b/include/asm-s390/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 | |||
16 | /* structs from asm/cio.h */ | ||
17 | struct irb; | ||
18 | struct ccw1; | ||
19 | |||
20 | /* simplified initializers for struct ccw_device: | ||
21 | * CCW_DEVICE and CCW_DEVICE_DEVTYPE initialize one | ||
22 | * entry in your MODULE_DEVICE_TABLE and set the match_flag correctly */ | ||
23 | #define CCW_DEVICE(cu, cum) \ | ||
24 | .cu_type=(cu), .cu_model=(cum), \ | ||
25 | .match_flags=(CCW_DEVICE_ID_MATCH_CU_TYPE \ | ||
26 | | (cum ? CCW_DEVICE_ID_MATCH_CU_MODEL : 0)) | ||
27 | |||
28 | #define CCW_DEVICE_DEVTYPE(cu, cum, dev, devm) \ | ||
29 | .cu_type=(cu), .cu_model=(cum), .dev_type=(dev), .dev_model=(devm),\ | ||
30 | .match_flags=CCW_DEVICE_ID_MATCH_CU_TYPE \ | ||
31 | | ((cum) ? CCW_DEVICE_ID_MATCH_CU_MODEL : 0) \ | ||
32 | | CCW_DEVICE_ID_MATCH_DEVICE_TYPE \ | ||
33 | | ((devm) ? CCW_DEVICE_ID_MATCH_DEVICE_MODEL : 0) | ||
34 | |||
35 | /* scan through an array of device ids and return the first | ||
36 | * entry that matches the device. | ||
37 | * | ||
38 | * the array must end with an entry containing zero match_flags | ||
39 | */ | ||
40 | static inline const struct ccw_device_id * | ||
41 | ccw_device_id_match(const struct ccw_device_id *array, | ||
42 | const struct ccw_device_id *match) | ||
43 | { | ||
44 | const struct ccw_device_id *id = array; | ||
45 | |||
46 | for (id = array; id->match_flags; id++) { | ||
47 | if ((id->match_flags & CCW_DEVICE_ID_MATCH_CU_TYPE) | ||
48 | && (id->cu_type != match->cu_type)) | ||
49 | continue; | ||
50 | |||
51 | if ((id->match_flags & CCW_DEVICE_ID_MATCH_CU_MODEL) | ||
52 | && (id->cu_model != match->cu_model)) | ||
53 | continue; | ||
54 | |||
55 | if ((id->match_flags & CCW_DEVICE_ID_MATCH_DEVICE_TYPE) | ||
56 | && (id->dev_type != match->dev_type)) | ||
57 | continue; | ||
58 | |||
59 | if ((id->match_flags & CCW_DEVICE_ID_MATCH_DEVICE_MODEL) | ||
60 | && (id->dev_model != match->dev_model)) | ||
61 | continue; | ||
62 | |||
63 | return id; | ||
64 | } | ||
65 | |||
66 | return 0; | ||
67 | } | ||
68 | |||
69 | /* The struct ccw device is our replacement for the globally accessible | ||
70 | * ioinfo array. ioinfo will mutate into a subchannel device later. | ||
71 | * | ||
72 | * Reference: Documentation/s390/driver-model.txt */ | ||
73 | struct ccw_device { | ||
74 | spinlock_t *ccwlock; | ||
75 | struct ccw_device_private *private; /* cio private information */ | ||
76 | struct ccw_device_id id; /* id of this device, driver_info is | ||
77 | set by ccw_find_driver */ | ||
78 | struct ccw_driver *drv; /* */ | ||
79 | struct device dev; /* */ | ||
80 | int online; | ||
81 | /* This is sick, but a driver can have different interrupt handlers | ||
82 | for different ccw_devices (multi-subchannel drivers)... */ | ||
83 | void (*handler) (struct ccw_device *, unsigned long, struct irb *); | ||
84 | }; | ||
85 | |||
86 | |||
87 | /* Each ccw driver registers with the ccw root bus */ | ||
88 | struct ccw_driver { | ||
89 | struct module *owner; /* for automatic MOD_INC_USE_COUNT */ | ||
90 | struct ccw_device_id *ids; /* probe driver with these devs */ | ||
91 | int (*probe) (struct ccw_device *); /* ask driver to probe dev */ | ||
92 | void (*remove) (struct ccw_device *); | ||
93 | /* device is no longer available */ | ||
94 | int (*set_online) (struct ccw_device *); | ||
95 | int (*set_offline) (struct ccw_device *); | ||
96 | int (*notify) (struct ccw_device *, int); | ||
97 | struct device_driver driver; /* higher level structure, don't init | ||
98 | this from your driver */ | ||
99 | char *name; | ||
100 | }; | ||
101 | |||
102 | extern struct ccw_device *get_ccwdev_by_busid(struct ccw_driver *cdrv, | ||
103 | const char *bus_id); | ||
104 | |||
105 | /* devices drivers call these during module load and unload. | ||
106 | * When a driver is registered, its probe method is called | ||
107 | * when new devices for its type pop up */ | ||
108 | extern int ccw_driver_register (struct ccw_driver *driver); | ||
109 | extern void ccw_driver_unregister (struct ccw_driver *driver); | ||
110 | |||
111 | struct ccw1; | ||
112 | |||
113 | extern int ccw_device_set_options(struct ccw_device *, unsigned long); | ||
114 | |||
115 | /* Allow for i/o completion notification after primary interrupt status. */ | ||
116 | #define CCWDEV_EARLY_NOTIFICATION 0x0001 | ||
117 | /* Report all interrupt conditions. */ | ||
118 | #define CCWDEV_REPORT_ALL 0x0002 | ||
119 | /* Try to perform path grouping. */ | ||
120 | #define CCWDEV_DO_PATHGROUP 0x0004 | ||
121 | /* Allow forced onlining of boxed devices. */ | ||
122 | #define CCWDEV_ALLOW_FORCE 0x0008 | ||
123 | |||
124 | /* | ||
125 | * ccw_device_start() | ||
126 | * | ||
127 | * Start a S/390 channel program. When the interrupt arrives, the | ||
128 | * IRQ handler is called, either immediately, delayed (dev-end missing, | ||
129 | * or sense required) or never (no IRQ handler registered). | ||
130 | * Depending on the action taken, ccw_device_start() returns: | ||
131 | * 0 - Success | ||
132 | * -EBUSY - Device busy, or status pending | ||
133 | * -ENODEV - Device not operational | ||
134 | * -EINVAL - Device invalid for operation | ||
135 | */ | ||
136 | extern int ccw_device_start(struct ccw_device *, struct ccw1 *, | ||
137 | unsigned long, __u8, unsigned long); | ||
138 | /* | ||
139 | * ccw_device_start_timeout() | ||
140 | * | ||
141 | * This function notifies the device driver if the channel program has not | ||
142 | * completed during the specified time. If a timeout occurs, the channel | ||
143 | * program is terminated via xsch(), hsch() or csch(). | ||
144 | */ | ||
145 | extern int ccw_device_start_timeout(struct ccw_device *, struct ccw1 *, | ||
146 | unsigned long, __u8, unsigned long, int); | ||
147 | /* | ||
148 | * ccw_device_start_key() | ||
149 | * ccw_device_start_key_timeout() | ||
150 | * | ||
151 | * Same as ccw_device_start() and ccw_device_start_timeout(), except a | ||
152 | * storage key != default key can be provided for the I/O. | ||
153 | */ | ||
154 | extern int ccw_device_start_key(struct ccw_device *, struct ccw1 *, | ||
155 | unsigned long, __u8, __u8, unsigned long); | ||
156 | extern int ccw_device_start_timeout_key(struct ccw_device *, struct ccw1 *, | ||
157 | unsigned long, __u8, __u8, | ||
158 | unsigned long, int); | ||
159 | |||
160 | |||
161 | extern int ccw_device_resume(struct ccw_device *); | ||
162 | extern int ccw_device_halt(struct ccw_device *, unsigned long); | ||
163 | extern int ccw_device_clear(struct ccw_device *, unsigned long); | ||
164 | |||
165 | extern int read_dev_chars(struct ccw_device *cdev, void **buffer, int length); | ||
166 | extern int read_conf_data(struct ccw_device *cdev, void **buffer, int *length); | ||
167 | extern int read_conf_data_lpm(struct ccw_device *cdev, void **buffer, | ||
168 | int *length, __u8 lpm); | ||
169 | |||
170 | extern int ccw_device_set_online(struct ccw_device *cdev); | ||
171 | extern int ccw_device_set_offline(struct ccw_device *cdev); | ||
172 | |||
173 | |||
174 | extern struct ciw *ccw_device_get_ciw(struct ccw_device *, __u32 cmd); | ||
175 | extern __u8 ccw_device_get_path_mask(struct ccw_device *); | ||
176 | |||
177 | #define get_ccwdev_lock(x) (x)->ccwlock | ||
178 | |||
179 | #define to_ccwdev(n) container_of(n, struct ccw_device, dev) | ||
180 | #define to_ccwdrv(n) container_of(n, struct ccw_driver, driver) | ||
181 | |||
182 | extern struct ccw_device *ccw_device_probe_console(void); | ||
183 | |||
184 | // FIXME: these have to go | ||
185 | extern int _ccw_device_get_device_number(struct ccw_device *); | ||
186 | extern int _ccw_device_get_subchannel_number(struct ccw_device *); | ||
187 | |||
188 | extern struct device *s390_root_dev_register(const char *); | ||
189 | extern void s390_root_dev_unregister(struct device *); | ||
190 | |||
191 | extern void *ccw_device_get_chp_desc(struct ccw_device *, int); | ||
192 | #endif /* _S390_CCWDEV_H_ */ | ||
diff --git a/include/asm-s390/ccwgroup.h b/include/asm-s390/ccwgroup.h new file mode 100644 index 000000000000..d2f9c0d53a97 --- /dev/null +++ b/include/asm-s390/ccwgroup.h | |||
@@ -0,0 +1,45 @@ | |||
1 | #ifndef S390_CCWGROUP_H | ||
2 | #define S390_CCWGROUP_H | ||
3 | |||
4 | struct ccw_device; | ||
5 | struct ccw_driver; | ||
6 | |||
7 | struct ccwgroup_device { | ||
8 | unsigned long creator_id; /* unique number of the driver */ | ||
9 | enum { | ||
10 | CCWGROUP_OFFLINE, | ||
11 | CCWGROUP_ONLINE, | ||
12 | } state; | ||
13 | atomic_t onoff; | ||
14 | unsigned int count; /* number of attached slave devices */ | ||
15 | struct device dev; /* master device */ | ||
16 | struct ccw_device *cdev[0]; /* variable number, allocate as needed */ | ||
17 | }; | ||
18 | |||
19 | struct ccwgroup_driver { | ||
20 | struct module *owner; | ||
21 | char *name; | ||
22 | int max_slaves; | ||
23 | unsigned long driver_id; | ||
24 | |||
25 | int (*probe) (struct ccwgroup_device *); | ||
26 | void (*remove) (struct ccwgroup_device *); | ||
27 | int (*set_online) (struct ccwgroup_device *); | ||
28 | int (*set_offline) (struct ccwgroup_device *); | ||
29 | |||
30 | struct device_driver driver; /* this driver */ | ||
31 | }; | ||
32 | |||
33 | extern int ccwgroup_driver_register (struct ccwgroup_driver *cdriver); | ||
34 | extern void ccwgroup_driver_unregister (struct ccwgroup_driver *cdriver); | ||
35 | extern int ccwgroup_create (struct device *root, | ||
36 | unsigned int creator_id, | ||
37 | struct ccw_driver *gdrv, | ||
38 | int argc, char *argv[]); | ||
39 | |||
40 | extern int ccwgroup_probe_ccwdev(struct ccw_device *cdev); | ||
41 | extern void ccwgroup_remove_ccwdev(struct ccw_device *cdev); | ||
42 | |||
43 | #define to_ccwgroupdev(x) container_of((x), struct ccwgroup_device, dev) | ||
44 | #define to_ccwgroupdrv(x) container_of((x), struct ccwgroup_driver, driver) | ||
45 | #endif | ||
diff --git a/include/asm-s390/checksum.h b/include/asm-s390/checksum.h new file mode 100644 index 000000000000..471f2af2b16a --- /dev/null +++ b/include/asm-s390/checksum.h | |||
@@ -0,0 +1,264 @@ | |||
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 unsigned int | ||
31 | csum_partial(const unsigned char * buff, int len, unsigned int sum) | ||
32 | { | ||
33 | /* | ||
34 | * Experiments with ethernet and slip connections show that buf | ||
35 | * is aligned on either a 2-byte or 4-byte boundary. | ||
36 | */ | ||
37 | #ifndef __s390x__ | ||
38 | register_pair rp; | ||
39 | |||
40 | rp.subreg.even = (unsigned long) buff; | ||
41 | rp.subreg.odd = (unsigned long) len; | ||
42 | __asm__ __volatile__ ( | ||
43 | "0: cksm %0,%1\n" /* do checksum on longs */ | ||
44 | " jo 0b\n" | ||
45 | : "+&d" (sum), "+&a" (rp) : : "cc", "memory" ); | ||
46 | #else /* __s390x__ */ | ||
47 | __asm__ __volatile__ ( | ||
48 | " lgr 2,%1\n" /* address in gpr 2 */ | ||
49 | " lgfr 3,%2\n" /* length in gpr 3 */ | ||
50 | "0: cksm %0,2\n" /* do checksum on longs */ | ||
51 | " jo 0b\n" | ||
52 | : "+&d" (sum) | ||
53 | : "d" (buff), "d" (len) | ||
54 | : "cc", "memory", "2", "3" ); | ||
55 | #endif /* __s390x__ */ | ||
56 | return sum; | ||
57 | } | ||
58 | |||
59 | /* | ||
60 | * csum_partial as an inline function | ||
61 | */ | ||
62 | static inline unsigned int | ||
63 | csum_partial_inline(const unsigned char * buff, int len, unsigned int sum) | ||
64 | { | ||
65 | #ifndef __s390x__ | ||
66 | register_pair rp; | ||
67 | |||
68 | rp.subreg.even = (unsigned long) buff; | ||
69 | rp.subreg.odd = (unsigned long) len; | ||
70 | __asm__ __volatile__ ( | ||
71 | "0: cksm %0,%1\n" /* do checksum on longs */ | ||
72 | " jo 0b\n" | ||
73 | : "+&d" (sum), "+&a" (rp) : : "cc", "memory" ); | ||
74 | #else /* __s390x__ */ | ||
75 | __asm__ __volatile__ ( | ||
76 | " lgr 2,%1\n" /* address in gpr 2 */ | ||
77 | " lgfr 3,%2\n" /* length in gpr 3 */ | ||
78 | "0: cksm %0,2\n" /* do checksum on longs */ | ||
79 | " jo 0b\n" | ||
80 | : "+&d" (sum) | ||
81 | : "d" (buff), "d" (len) | ||
82 | : "cc", "memory", "2", "3" ); | ||
83 | #endif /* __s390x__ */ | ||
84 | return sum; | ||
85 | } | ||
86 | |||
87 | /* | ||
88 | * the same as csum_partial_copy, but copies from user space. | ||
89 | * | ||
90 | * here even more important to align src and dst on a 32-bit (or even | ||
91 | * better 64-bit) boundary | ||
92 | * | ||
93 | * Copy from userspace and compute checksum. If we catch an exception | ||
94 | * then zero the rest of the buffer. | ||
95 | */ | ||
96 | static inline unsigned int | ||
97 | csum_partial_copy_from_user(const char __user *src, char *dst, | ||
98 | int len, unsigned int sum, | ||
99 | int *err_ptr) | ||
100 | { | ||
101 | int missing; | ||
102 | |||
103 | missing = copy_from_user(dst, src, len); | ||
104 | if (missing) { | ||
105 | memset(dst + len - missing, 0, missing); | ||
106 | *err_ptr = -EFAULT; | ||
107 | } | ||
108 | |||
109 | return csum_partial(dst, len, sum); | ||
110 | } | ||
111 | |||
112 | |||
113 | static inline unsigned int | ||
114 | csum_partial_copy_nocheck (const char *src, char *dst, int len, unsigned int sum) | ||
115 | { | ||
116 | memcpy(dst,src,len); | ||
117 | return csum_partial_inline(dst, len, sum); | ||
118 | } | ||
119 | |||
120 | /* | ||
121 | * Fold a partial checksum without adding pseudo headers | ||
122 | */ | ||
123 | static inline unsigned short | ||
124 | csum_fold(unsigned int sum) | ||
125 | { | ||
126 | #ifndef __s390x__ | ||
127 | register_pair rp; | ||
128 | |||
129 | __asm__ __volatile__ ( | ||
130 | " slr %N1,%N1\n" /* %0 = H L */ | ||
131 | " lr %1,%0\n" /* %0 = H L, %1 = H L 0 0 */ | ||
132 | " srdl %1,16\n" /* %0 = H L, %1 = 0 H L 0 */ | ||
133 | " alr %1,%N1\n" /* %0 = H L, %1 = L H L 0 */ | ||
134 | " alr %0,%1\n" /* %0 = H+L+C L+H */ | ||
135 | " srl %0,16\n" /* %0 = H+L+C */ | ||
136 | : "+&d" (sum), "=d" (rp) : : "cc" ); | ||
137 | #else /* __s390x__ */ | ||
138 | __asm__ __volatile__ ( | ||
139 | " sr 3,3\n" /* %0 = H*65536 + L */ | ||
140 | " lr 2,%0\n" /* %0 = H L, R2/R3 = H L / 0 0 */ | ||
141 | " srdl 2,16\n" /* %0 = H L, R2/R3 = 0 H / L 0 */ | ||
142 | " alr 2,3\n" /* %0 = H L, R2/R3 = L H / L 0 */ | ||
143 | " alr %0,2\n" /* %0 = H+L+C L+H */ | ||
144 | " srl %0,16\n" /* %0 = H+L+C */ | ||
145 | : "+&d" (sum) : : "cc", "2", "3"); | ||
146 | #endif /* __s390x__ */ | ||
147 | return ((unsigned short) ~sum); | ||
148 | } | ||
149 | |||
150 | /* | ||
151 | * This is a version of ip_compute_csum() optimized for IP headers, | ||
152 | * which always checksum on 4 octet boundaries. | ||
153 | * | ||
154 | */ | ||
155 | static inline unsigned short | ||
156 | ip_fast_csum(unsigned char *iph, unsigned int ihl) | ||
157 | { | ||
158 | unsigned long sum; | ||
159 | #ifndef __s390x__ | ||
160 | register_pair rp; | ||
161 | |||
162 | rp.subreg.even = (unsigned long) iph; | ||
163 | rp.subreg.odd = (unsigned long) ihl*4; | ||
164 | __asm__ __volatile__ ( | ||
165 | " sr %0,%0\n" /* set sum to zero */ | ||
166 | "0: cksm %0,%1\n" /* do checksum on longs */ | ||
167 | " jo 0b\n" | ||
168 | : "=&d" (sum), "+&a" (rp) : : "cc", "memory" ); | ||
169 | #else /* __s390x__ */ | ||
170 | __asm__ __volatile__ ( | ||
171 | " slgr %0,%0\n" /* set sum to zero */ | ||
172 | " lgr 2,%1\n" /* address in gpr 2 */ | ||
173 | " lgfr 3,%2\n" /* length in gpr 3 */ | ||
174 | "0: cksm %0,2\n" /* do checksum on ints */ | ||
175 | " jo 0b\n" | ||
176 | : "=&d" (sum) | ||
177 | : "d" (iph), "d" (ihl*4) | ||
178 | : "cc", "memory", "2", "3" ); | ||
179 | #endif /* __s390x__ */ | ||
180 | return csum_fold(sum); | ||
181 | } | ||
182 | |||
183 | /* | ||
184 | * computes the checksum of the TCP/UDP pseudo-header | ||
185 | * returns a 32-bit checksum | ||
186 | */ | ||
187 | static inline unsigned int | ||
188 | csum_tcpudp_nofold(unsigned long saddr, unsigned long daddr, | ||
189 | unsigned short len, unsigned short proto, | ||
190 | unsigned int sum) | ||
191 | { | ||
192 | #ifndef __s390x__ | ||
193 | __asm__ __volatile__ ( | ||
194 | " alr %0,%1\n" /* sum += saddr */ | ||
195 | " brc 12,0f\n" | ||
196 | " ahi %0,1\n" /* add carry */ | ||
197 | "0:" | ||
198 | : "+&d" (sum) : "d" (saddr) : "cc" ); | ||
199 | __asm__ __volatile__ ( | ||
200 | " alr %0,%1\n" /* sum += daddr */ | ||
201 | " brc 12,1f\n" | ||
202 | " ahi %0,1\n" /* add carry */ | ||
203 | "1:" | ||
204 | : "+&d" (sum) : "d" (daddr) : "cc" ); | ||
205 | __asm__ __volatile__ ( | ||
206 | " alr %0,%1\n" /* sum += (len<<16) + (proto<<8) */ | ||
207 | " brc 12,2f\n" | ||
208 | " ahi %0,1\n" /* add carry */ | ||
209 | "2:" | ||
210 | : "+&d" (sum) | ||
211 | : "d" (((unsigned int) len<<16) + (unsigned int) proto) | ||
212 | : "cc" ); | ||
213 | #else /* __s390x__ */ | ||
214 | __asm__ __volatile__ ( | ||
215 | " lgfr %0,%0\n" | ||
216 | " algr %0,%1\n" /* sum += saddr */ | ||
217 | " brc 12,0f\n" | ||
218 | " aghi %0,1\n" /* add carry */ | ||
219 | "0: algr %0,%2\n" /* sum += daddr */ | ||
220 | " brc 12,1f\n" | ||
221 | " aghi %0,1\n" /* add carry */ | ||
222 | "1: algfr %0,%3\n" /* sum += (len<<16) + proto */ | ||
223 | " brc 12,2f\n" | ||
224 | " aghi %0,1\n" /* add carry */ | ||
225 | "2: srlg 0,%0,32\n" | ||
226 | " alr %0,0\n" /* fold to 32 bits */ | ||
227 | " brc 12,3f\n" | ||
228 | " ahi %0,1\n" /* add carry */ | ||
229 | "3: llgfr %0,%0" | ||
230 | : "+&d" (sum) | ||
231 | : "d" (saddr), "d" (daddr), | ||
232 | "d" (((unsigned int) len<<16) + (unsigned int) proto) | ||
233 | : "cc", "0" ); | ||
234 | #endif /* __s390x__ */ | ||
235 | return sum; | ||
236 | } | ||
237 | |||
238 | /* | ||
239 | * computes the checksum of the TCP/UDP pseudo-header | ||
240 | * returns a 16-bit checksum, already complemented | ||
241 | */ | ||
242 | |||
243 | static inline unsigned short int | ||
244 | csum_tcpudp_magic(unsigned long saddr, unsigned long daddr, | ||
245 | unsigned short len, unsigned short proto, | ||
246 | unsigned int sum) | ||
247 | { | ||
248 | return csum_fold(csum_tcpudp_nofold(saddr,daddr,len,proto,sum)); | ||
249 | } | ||
250 | |||
251 | /* | ||
252 | * this routine is used for miscellaneous IP-like checksums, mainly | ||
253 | * in icmp.c | ||
254 | */ | ||
255 | |||
256 | static inline unsigned short | ||
257 | ip_compute_csum(unsigned char * buff, int len) | ||
258 | { | ||
259 | return csum_fold(csum_partial(buff, len, 0)); | ||
260 | } | ||
261 | |||
262 | #endif /* _S390_CHECKSUM_H */ | ||
263 | |||
264 | |||
diff --git a/include/asm-s390/cio.h b/include/asm-s390/cio.h new file mode 100644 index 000000000000..089cf567c317 --- /dev/null +++ b/include/asm-s390/cio.h | |||
@@ -0,0 +1,281 @@ | |||
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 | |||
17 | /* | ||
18 | * subchannel status word | ||
19 | */ | ||
20 | struct scsw { | ||
21 | __u32 key : 4; /* subchannel key */ | ||
22 | __u32 sctl : 1; /* suspend control */ | ||
23 | __u32 eswf : 1; /* ESW format */ | ||
24 | __u32 cc : 2; /* deferred condition code */ | ||
25 | __u32 fmt : 1; /* format */ | ||
26 | __u32 pfch : 1; /* prefetch */ | ||
27 | __u32 isic : 1; /* initial-status interruption control */ | ||
28 | __u32 alcc : 1; /* address-limit checking control */ | ||
29 | __u32 ssi : 1; /* supress-suspended interruption */ | ||
30 | __u32 zcc : 1; /* zero condition code */ | ||
31 | __u32 ectl : 1; /* extended control */ | ||
32 | __u32 pno : 1; /* path not operational */ | ||
33 | __u32 res : 1; /* reserved */ | ||
34 | __u32 fctl : 3; /* function control */ | ||
35 | __u32 actl : 7; /* activity control */ | ||
36 | __u32 stctl : 5; /* status control */ | ||
37 | __u32 cpa; /* channel program address */ | ||
38 | __u32 dstat : 8; /* device status */ | ||
39 | __u32 cstat : 8; /* subchannel status */ | ||
40 | __u32 count : 16; /* residual count */ | ||
41 | } __attribute__ ((packed)); | ||
42 | |||
43 | #define SCSW_FCTL_CLEAR_FUNC 0x1 | ||
44 | #define SCSW_FCTL_HALT_FUNC 0x2 | ||
45 | #define SCSW_FCTL_START_FUNC 0x4 | ||
46 | |||
47 | #define SCSW_ACTL_SUSPENDED 0x1 | ||
48 | #define SCSW_ACTL_DEVACT 0x2 | ||
49 | #define SCSW_ACTL_SCHACT 0x4 | ||
50 | #define SCSW_ACTL_CLEAR_PEND 0x8 | ||
51 | #define SCSW_ACTL_HALT_PEND 0x10 | ||
52 | #define SCSW_ACTL_START_PEND 0x20 | ||
53 | #define SCSW_ACTL_RESUME_PEND 0x40 | ||
54 | |||
55 | #define SCSW_STCTL_STATUS_PEND 0x1 | ||
56 | #define SCSW_STCTL_SEC_STATUS 0x2 | ||
57 | #define SCSW_STCTL_PRIM_STATUS 0x4 | ||
58 | #define SCSW_STCTL_INTER_STATUS 0x8 | ||
59 | #define SCSW_STCTL_ALERT_STATUS 0x10 | ||
60 | |||
61 | #define DEV_STAT_ATTENTION 0x80 | ||
62 | #define DEV_STAT_STAT_MOD 0x40 | ||
63 | #define DEV_STAT_CU_END 0x20 | ||
64 | #define DEV_STAT_BUSY 0x10 | ||
65 | #define DEV_STAT_CHN_END 0x08 | ||
66 | #define DEV_STAT_DEV_END 0x04 | ||
67 | #define DEV_STAT_UNIT_CHECK 0x02 | ||
68 | #define DEV_STAT_UNIT_EXCEP 0x01 | ||
69 | |||
70 | #define SCHN_STAT_PCI 0x80 | ||
71 | #define SCHN_STAT_INCORR_LEN 0x40 | ||
72 | #define SCHN_STAT_PROG_CHECK 0x20 | ||
73 | #define SCHN_STAT_PROT_CHECK 0x10 | ||
74 | #define SCHN_STAT_CHN_DATA_CHK 0x08 | ||
75 | #define SCHN_STAT_CHN_CTRL_CHK 0x04 | ||
76 | #define SCHN_STAT_INTF_CTRL_CHK 0x02 | ||
77 | #define SCHN_STAT_CHAIN_CHECK 0x01 | ||
78 | |||
79 | /* | ||
80 | * architectured values for first sense byte | ||
81 | */ | ||
82 | #define SNS0_CMD_REJECT 0x80 | ||
83 | #define SNS_CMD_REJECT SNS0_CMD_REJEC | ||
84 | #define SNS0_INTERVENTION_REQ 0x40 | ||
85 | #define SNS0_BUS_OUT_CHECK 0x20 | ||
86 | #define SNS0_EQUIPMENT_CHECK 0x10 | ||
87 | #define SNS0_DATA_CHECK 0x08 | ||
88 | #define SNS0_OVERRUN 0x04 | ||
89 | #define SNS0_INCOMPL_DOMAIN 0x01 | ||
90 | |||
91 | /* | ||
92 | * architectured values for second sense byte | ||
93 | */ | ||
94 | #define SNS1_PERM_ERR 0x80 | ||
95 | #define SNS1_INV_TRACK_FORMAT 0x40 | ||
96 | #define SNS1_EOC 0x20 | ||
97 | #define SNS1_MESSAGE_TO_OPER 0x10 | ||
98 | #define SNS1_NO_REC_FOUND 0x08 | ||
99 | #define SNS1_FILE_PROTECTED 0x04 | ||
100 | #define SNS1_WRITE_INHIBITED 0x02 | ||
101 | #define SNS1_INPRECISE_END 0x01 | ||
102 | |||
103 | /* | ||
104 | * architectured values for third sense byte | ||
105 | */ | ||
106 | #define SNS2_REQ_INH_WRITE 0x80 | ||
107 | #define SNS2_CORRECTABLE 0x40 | ||
108 | #define SNS2_FIRST_LOG_ERR 0x20 | ||
109 | #define SNS2_ENV_DATA_PRESENT 0x10 | ||
110 | #define SNS2_INPRECISE_END 0x04 | ||
111 | |||
112 | struct ccw1 { | ||
113 | __u8 cmd_code; /* command code */ | ||
114 | __u8 flags; /* flags, like IDA addressing, etc. */ | ||
115 | __u16 count; /* byte count */ | ||
116 | __u32 cda; /* data address */ | ||
117 | } __attribute__ ((packed,aligned(8))); | ||
118 | |||
119 | #define CCW_FLAG_DC 0x80 | ||
120 | #define CCW_FLAG_CC 0x40 | ||
121 | #define CCW_FLAG_SLI 0x20 | ||
122 | #define CCW_FLAG_SKIP 0x10 | ||
123 | #define CCW_FLAG_PCI 0x08 | ||
124 | #define CCW_FLAG_IDA 0x04 | ||
125 | #define CCW_FLAG_SUSPEND 0x02 | ||
126 | |||
127 | #define CCW_CMD_READ_IPL 0x02 | ||
128 | #define CCW_CMD_NOOP 0x03 | ||
129 | #define CCW_CMD_BASIC_SENSE 0x04 | ||
130 | #define CCW_CMD_TIC 0x08 | ||
131 | #define CCW_CMD_STLCK 0x14 | ||
132 | #define CCW_CMD_SENSE_PGID 0x34 | ||
133 | #define CCW_CMD_SUSPEND_RECONN 0x5B | ||
134 | #define CCW_CMD_RDC 0x64 | ||
135 | #define CCW_CMD_RELEASE 0x94 | ||
136 | #define CCW_CMD_SET_PGID 0xAF | ||
137 | #define CCW_CMD_SENSE_ID 0xE4 | ||
138 | #define CCW_CMD_DCTL 0xF3 | ||
139 | |||
140 | #define SENSE_MAX_COUNT 0x20 | ||
141 | |||
142 | struct erw { | ||
143 | __u32 res0 : 3; /* reserved */ | ||
144 | __u32 auth : 1; /* Authorization check */ | ||
145 | __u32 pvrf : 1; /* path-verification-required flag */ | ||
146 | __u32 cpt : 1; /* channel-path timeout */ | ||
147 | __u32 fsavf : 1; /* Failing storage address validity flag */ | ||
148 | __u32 cons : 1; /* concurrent-sense */ | ||
149 | __u32 scavf : 1; /* Secondary ccw address validity flag */ | ||
150 | __u32 fsaf : 1; /* Failing storage address format */ | ||
151 | __u32 scnt : 6; /* sense count if cons == 1 */ | ||
152 | __u32 res16 : 16; /* reserved */ | ||
153 | } __attribute__ ((packed)); | ||
154 | |||
155 | /* | ||
156 | * subchannel logout area | ||
157 | */ | ||
158 | struct sublog { | ||
159 | __u32 res0 : 1; /* reserved */ | ||
160 | __u32 esf : 7; /* extended status flags */ | ||
161 | __u32 lpum : 8; /* last path used mask */ | ||
162 | __u32 arep : 1; /* ancillary report */ | ||
163 | __u32 fvf : 5; /* field-validity flags */ | ||
164 | __u32 sacc : 2; /* storage access code */ | ||
165 | __u32 termc : 2; /* termination code */ | ||
166 | __u32 devsc : 1; /* device-status check */ | ||
167 | __u32 serr : 1; /* secondary error */ | ||
168 | __u32 ioerr : 1; /* i/o-error alert */ | ||
169 | __u32 seqc : 3; /* sequence code */ | ||
170 | } __attribute__ ((packed)); | ||
171 | |||
172 | /* | ||
173 | * Format 0 Extended Status Word (ESW) | ||
174 | */ | ||
175 | struct esw0 { | ||
176 | struct sublog sublog; /* subchannel logout */ | ||
177 | struct erw erw; /* extended report word */ | ||
178 | __u32 faddr[2]; /* failing storage address */ | ||
179 | __u32 saddr; /* secondary ccw address */ | ||
180 | } __attribute__ ((packed)); | ||
181 | |||
182 | /* | ||
183 | * Format 1 Extended Status Word (ESW) | ||
184 | */ | ||
185 | struct esw1 { | ||
186 | __u8 zero0; /* reserved zeros */ | ||
187 | __u8 lpum; /* last path used mask */ | ||
188 | __u16 zero16; /* reserved zeros */ | ||
189 | struct erw erw; /* extended report word */ | ||
190 | __u32 zeros[3]; /* 2 fullwords of zeros */ | ||
191 | } __attribute__ ((packed)); | ||
192 | |||
193 | /* | ||
194 | * Format 2 Extended Status Word (ESW) | ||
195 | */ | ||
196 | struct esw2 { | ||
197 | __u8 zero0; /* reserved zeros */ | ||
198 | __u8 lpum; /* last path used mask */ | ||
199 | __u16 dcti; /* device-connect-time interval */ | ||
200 | struct erw erw; /* extended report word */ | ||
201 | __u32 zeros[3]; /* 2 fullwords of zeros */ | ||
202 | } __attribute__ ((packed)); | ||
203 | |||
204 | /* | ||
205 | * Format 3 Extended Status Word (ESW) | ||
206 | */ | ||
207 | struct esw3 { | ||
208 | __u8 zero0; /* reserved zeros */ | ||
209 | __u8 lpum; /* last path used mask */ | ||
210 | __u16 res; /* reserved */ | ||
211 | struct erw erw; /* extended report word */ | ||
212 | __u32 zeros[3]; /* 2 fullwords of zeros */ | ||
213 | } __attribute__ ((packed)); | ||
214 | |||
215 | /* | ||
216 | * interruption response block | ||
217 | */ | ||
218 | struct irb { | ||
219 | struct scsw scsw; /* subchannel status word */ | ||
220 | union { /* extended status word, 4 formats */ | ||
221 | struct esw0 esw0; | ||
222 | struct esw1 esw1; | ||
223 | struct esw2 esw2; | ||
224 | struct esw3 esw3; | ||
225 | } esw; | ||
226 | __u8 ecw[32]; /* extended control word */ | ||
227 | } __attribute__ ((packed,aligned(4))); | ||
228 | |||
229 | /* | ||
230 | * command information word (CIW) layout | ||
231 | */ | ||
232 | struct ciw { | ||
233 | __u32 et : 2; /* entry type */ | ||
234 | __u32 reserved : 2; /* reserved */ | ||
235 | __u32 ct : 4; /* command type */ | ||
236 | __u32 cmd : 8; /* command */ | ||
237 | __u32 count : 16; /* coun */ | ||
238 | } __attribute__ ((packed)); | ||
239 | |||
240 | #define CIW_TYPE_RCD 0x0 /* read configuration data */ | ||
241 | #define CIW_TYPE_SII 0x1 /* set interface identifier */ | ||
242 | #define CIW_TYPE_RNI 0x2 /* read node identifier */ | ||
243 | |||
244 | /* | ||
245 | * Flags used as input parameters for do_IO() | ||
246 | */ | ||
247 | #define DOIO_ALLOW_SUSPEND 0x0001 /* allow for channel prog. suspend */ | ||
248 | #define DOIO_DENY_PREFETCH 0x0002 /* don't allow for CCW prefetch */ | ||
249 | #define DOIO_SUPPRESS_INTER 0x0004 /* suppress intermediate inter. */ | ||
250 | /* ... for suspended CCWs */ | ||
251 | /* Device or subchannel gone. */ | ||
252 | #define CIO_GONE 0x0001 | ||
253 | /* No path to device. */ | ||
254 | #define CIO_NO_PATH 0x0002 | ||
255 | /* Device has appeared. */ | ||
256 | #define CIO_OPER 0x0004 | ||
257 | /* Sick revalidation of device. */ | ||
258 | #define CIO_REVALIDATE 0x0008 | ||
259 | |||
260 | struct diag210 { | ||
261 | __u16 vrdcdvno : 16; /* device number (input) */ | ||
262 | __u16 vrdclen : 16; /* data block length (input) */ | ||
263 | __u32 vrdcvcla : 8; /* virtual device class (output) */ | ||
264 | __u32 vrdcvtyp : 8; /* virtual device type (output) */ | ||
265 | __u32 vrdcvsta : 8; /* virtual device status (output) */ | ||
266 | __u32 vrdcvfla : 8; /* virtual device flags (output) */ | ||
267 | __u32 vrdcrccl : 8; /* real device class (output) */ | ||
268 | __u32 vrdccrty : 8; /* real device type (output) */ | ||
269 | __u32 vrdccrmd : 8; /* real device model (output) */ | ||
270 | __u32 vrdccrft : 8; /* real device feature (output) */ | ||
271 | } __attribute__ ((packed,aligned(4))); | ||
272 | |||
273 | extern int diag210(struct diag210 *addr); | ||
274 | |||
275 | extern void wait_cons_dev(void); | ||
276 | |||
277 | extern void clear_all_subchannels(void); | ||
278 | |||
279 | #endif | ||
280 | |||
281 | #endif | ||
diff --git a/include/asm-s390/cmb.h b/include/asm-s390/cmb.h new file mode 100644 index 000000000000..1bfe2bd630b5 --- /dev/null +++ b/include/asm-s390/cmb.h | |||
@@ -0,0 +1,98 @@ | |||
1 | #ifndef S390_CMB_H | ||
2 | #define S390_CMB_H | ||
3 | /** | ||
4 | * struct cmbdata -- channel measurement block data for user space | ||
5 | * | ||
6 | * @size: size of the stored data | ||
7 | * @ssch_rsch_count: XXX | ||
8 | * @sample_count: | ||
9 | * @device_connect_time: | ||
10 | * @function_pending_time: | ||
11 | * @device_disconnect_time: | ||
12 | * @control_unit_queuing_time: | ||
13 | * @device_active_only_time: | ||
14 | * @device_busy_time: | ||
15 | * @initial_command_response_time: | ||
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 results 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 | /* reset channel measurement block */ | ||
48 | #define BIODASDRESETCMB _IO(DASD_IOCTL_LETTER,34) | ||
49 | /* read channel measurement data */ | ||
50 | #define BIODASDREADCMB _IOWR(DASD_IOCTL_LETTER,32,u64) | ||
51 | /* read channel measurement data */ | ||
52 | #define BIODASDREADALLCMB _IOWR(DASD_IOCTL_LETTER,33,struct cmbdata) | ||
53 | |||
54 | #ifdef __KERNEL__ | ||
55 | |||
56 | /** | ||
57 | * enable_cmf() - switch on the channel measurement for a specific device | ||
58 | * @cdev: The ccw device to be enabled | ||
59 | * returns 0 for success or a negative error value. | ||
60 | * | ||
61 | * Context: | ||
62 | * non-atomic | ||
63 | **/ | ||
64 | extern int enable_cmf(struct ccw_device *cdev); | ||
65 | |||
66 | /** | ||
67 | * disable_cmf() - switch off the channel measurement for a specific device | ||
68 | * @cdev: The ccw device to be disabled | ||
69 | * returns 0 for success or a negative error value. | ||
70 | * | ||
71 | * Context: | ||
72 | * non-atomic | ||
73 | **/ | ||
74 | extern int disable_cmf(struct ccw_device *cdev); | ||
75 | |||
76 | /** | ||
77 | * cmf_read() - read one value from the current channel measurement block | ||
78 | * @cmf: the channel to be read | ||
79 | * @index: the name of the value that is read | ||
80 | * | ||
81 | * Context: | ||
82 | * any | ||
83 | **/ | ||
84 | |||
85 | extern u64 cmf_read(struct ccw_device *cdev, int index); | ||
86 | /** | ||
87 | * cmf_readall() - read one value from the current channel measurement block | ||
88 | * @cmf: the channel to be read | ||
89 | * @data: a pointer to a data block that will be filled | ||
90 | * | ||
91 | * Context: | ||
92 | * any | ||
93 | **/ | ||
94 | extern int cmf_readall(struct ccw_device *cdev, struct cmbdata*data); | ||
95 | extern void cmf_reset(struct ccw_device *cdev); | ||
96 | |||
97 | #endif /* __KERNEL__ */ | ||
98 | #endif /* S390_CMB_H */ | ||
diff --git a/include/asm-s390/compat.h b/include/asm-s390/compat.h new file mode 100644 index 000000000000..7f8f544eb262 --- /dev/null +++ b/include/asm-s390/compat.h | |||
@@ -0,0 +1,198 @@ | |||
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 COMPAT_USER_HZ 100 | ||
10 | |||
11 | typedef u32 compat_size_t; | ||
12 | typedef s32 compat_ssize_t; | ||
13 | typedef s32 compat_time_t; | ||
14 | typedef s32 compat_clock_t; | ||
15 | typedef s32 compat_pid_t; | ||
16 | typedef u16 compat_uid_t; | ||
17 | typedef u16 compat_gid_t; | ||
18 | typedef u32 compat_uid32_t; | ||
19 | typedef u32 compat_gid32_t; | ||
20 | typedef u16 compat_mode_t; | ||
21 | typedef u32 compat_ino_t; | ||
22 | typedef u16 compat_dev_t; | ||
23 | typedef s32 compat_off_t; | ||
24 | typedef s64 compat_loff_t; | ||
25 | typedef u16 compat_nlink_t; | ||
26 | typedef u16 compat_ipc_pid_t; | ||
27 | typedef s32 compat_daddr_t; | ||
28 | typedef u32 compat_caddr_t; | ||
29 | typedef __kernel_fsid_t compat_fsid_t; | ||
30 | typedef s32 compat_key_t; | ||
31 | typedef s32 compat_timer_t; | ||
32 | |||
33 | typedef s32 compat_int_t; | ||
34 | typedef s32 compat_long_t; | ||
35 | typedef u32 compat_uint_t; | ||
36 | typedef u32 compat_ulong_t; | ||
37 | |||
38 | struct compat_timespec { | ||
39 | compat_time_t tv_sec; | ||
40 | s32 tv_nsec; | ||
41 | }; | ||
42 | |||
43 | struct compat_timeval { | ||
44 | compat_time_t tv_sec; | ||
45 | s32 tv_usec; | ||
46 | }; | ||
47 | |||
48 | struct compat_stat { | ||
49 | compat_dev_t st_dev; | ||
50 | u16 __pad1; | ||
51 | compat_ino_t st_ino; | ||
52 | compat_mode_t st_mode; | ||
53 | compat_nlink_t st_nlink; | ||
54 | compat_uid_t st_uid; | ||
55 | compat_gid_t st_gid; | ||
56 | compat_dev_t st_rdev; | ||
57 | u16 __pad2; | ||
58 | u32 st_size; | ||
59 | u32 st_blksize; | ||
60 | u32 st_blocks; | ||
61 | u32 st_atime; | ||
62 | u32 st_atime_nsec; | ||
63 | u32 st_mtime; | ||
64 | u32 st_mtime_nsec; | ||
65 | u32 st_ctime; | ||
66 | u32 st_ctime_nsec; | ||
67 | u32 __unused4; | ||
68 | u32 __unused5; | ||
69 | }; | ||
70 | |||
71 | struct compat_flock { | ||
72 | short l_type; | ||
73 | short l_whence; | ||
74 | compat_off_t l_start; | ||
75 | compat_off_t l_len; | ||
76 | compat_pid_t l_pid; | ||
77 | }; | ||
78 | |||
79 | #define F_GETLK64 12 | ||
80 | #define F_SETLK64 13 | ||
81 | #define F_SETLKW64 14 | ||
82 | |||
83 | struct compat_flock64 { | ||
84 | short l_type; | ||
85 | short l_whence; | ||
86 | compat_loff_t l_start; | ||
87 | compat_loff_t l_len; | ||
88 | compat_pid_t l_pid; | ||
89 | }; | ||
90 | |||
91 | struct compat_statfs { | ||
92 | s32 f_type; | ||
93 | s32 f_bsize; | ||
94 | s32 f_blocks; | ||
95 | s32 f_bfree; | ||
96 | s32 f_bavail; | ||
97 | s32 f_files; | ||
98 | s32 f_ffree; | ||
99 | compat_fsid_t f_fsid; | ||
100 | s32 f_namelen; | ||
101 | s32 f_frsize; | ||
102 | s32 f_spare[6]; | ||
103 | }; | ||
104 | |||
105 | #define COMPAT_RLIM_OLD_INFINITY 0x7fffffff | ||
106 | #define COMPAT_RLIM_INFINITY 0xffffffff | ||
107 | |||
108 | typedef u32 compat_old_sigset_t; /* at least 32 bits */ | ||
109 | |||
110 | #define _COMPAT_NSIG 64 | ||
111 | #define _COMPAT_NSIG_BPW 32 | ||
112 | |||
113 | typedef u32 compat_sigset_word; | ||
114 | |||
115 | #define COMPAT_OFF_T_MAX 0x7fffffff | ||
116 | #define COMPAT_LOFF_T_MAX 0x7fffffffffffffffL | ||
117 | |||
118 | /* | ||
119 | * A pointer passed in from user mode. This should not | ||
120 | * be used for syscall parameters, just declare them | ||
121 | * as pointers because the syscall entry code will have | ||
122 | * appropriately comverted them already. | ||
123 | */ | ||
124 | typedef u32 compat_uptr_t; | ||
125 | |||
126 | static inline void __user *compat_ptr(compat_uptr_t uptr) | ||
127 | { | ||
128 | return (void __user *)(unsigned long)(uptr & 0x7fffffffUL); | ||
129 | } | ||
130 | |||
131 | static inline void __user *compat_alloc_user_space(long len) | ||
132 | { | ||
133 | unsigned long stack; | ||
134 | |||
135 | stack = KSTK_ESP(current); | ||
136 | if (test_thread_flag(TIF_31BIT)) | ||
137 | stack &= 0x7fffffffUL; | ||
138 | return (void __user *) (stack - len); | ||
139 | } | ||
140 | |||
141 | struct compat_ipc64_perm { | ||
142 | compat_key_t key; | ||
143 | compat_uid32_t uid; | ||
144 | compat_gid32_t gid; | ||
145 | compat_uid32_t cuid; | ||
146 | compat_gid32_t cgid; | ||
147 | compat_mode_t mode; | ||
148 | unsigned short __pad1; | ||
149 | unsigned short seq; | ||
150 | unsigned short __pad2; | ||
151 | unsigned int __unused1; | ||
152 | unsigned int __unused2; | ||
153 | }; | ||
154 | |||
155 | struct compat_semid64_ds { | ||
156 | struct compat_ipc64_perm sem_perm; | ||
157 | compat_time_t sem_otime; | ||
158 | compat_ulong_t __pad1; | ||
159 | compat_time_t sem_ctime; | ||
160 | compat_ulong_t __pad2; | ||
161 | compat_ulong_t sem_nsems; | ||
162 | compat_ulong_t __unused1; | ||
163 | compat_ulong_t __unused2; | ||
164 | }; | ||
165 | |||
166 | struct compat_msqid64_ds { | ||
167 | struct compat_ipc64_perm msg_perm; | ||
168 | compat_time_t msg_stime; | ||
169 | compat_ulong_t __pad1; | ||
170 | compat_time_t msg_rtime; | ||
171 | compat_ulong_t __pad2; | ||
172 | compat_time_t msg_ctime; | ||
173 | compat_ulong_t __pad3; | ||
174 | compat_ulong_t msg_cbytes; | ||
175 | compat_ulong_t msg_qnum; | ||
176 | compat_ulong_t msg_qbytes; | ||
177 | compat_pid_t msg_lspid; | ||
178 | compat_pid_t msg_lrpid; | ||
179 | compat_ulong_t __unused1; | ||
180 | compat_ulong_t __unused2; | ||
181 | }; | ||
182 | |||
183 | struct compat_shmid64_ds { | ||
184 | struct compat_ipc64_perm shm_perm; | ||
185 | compat_size_t shm_segsz; | ||
186 | compat_time_t shm_atime; | ||
187 | compat_ulong_t __pad1; | ||
188 | compat_time_t shm_dtime; | ||
189 | compat_ulong_t __pad2; | ||
190 | compat_time_t shm_ctime; | ||
191 | compat_ulong_t __pad3; | ||
192 | compat_pid_t shm_cpid; | ||
193 | compat_pid_t shm_lpid; | ||
194 | compat_ulong_t shm_nattch; | ||
195 | compat_ulong_t __unused1; | ||
196 | compat_ulong_t __unused2; | ||
197 | }; | ||
198 | #endif /* _ASM_S390X_COMPAT_H */ | ||
diff --git a/include/asm-s390/cpcmd.h b/include/asm-s390/cpcmd.h new file mode 100644 index 000000000000..1d33c5da083e --- /dev/null +++ b/include/asm-s390/cpcmd.h | |||
@@ -0,0 +1,24 @@ | |||
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 __CPCMD__ | ||
11 | #define __CPCMD__ | ||
12 | |||
13 | /* | ||
14 | * the caller of __cpcmd has to ensure that the response buffer is below 2 GB | ||
15 | */ | ||
16 | extern void __cpcmd(char *cmd, char *response, int rlen); | ||
17 | |||
18 | #ifndef __s390x__ | ||
19 | #define cpcmd __cpcmd | ||
20 | #else | ||
21 | extern void cpcmd(char *cmd, char *response, int rlen); | ||
22 | #endif /*__s390x__*/ | ||
23 | |||
24 | #endif | ||
diff --git a/include/asm-s390/cputime.h b/include/asm-s390/cputime.h new file mode 100644 index 000000000000..4b3ef7cad115 --- /dev/null +++ b/include/asm-s390/cputime.h | |||
@@ -0,0 +1,176 @@ | |||
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 jiffies_to_cputime(__hz) ((cputime_t)(__hz) * (1000000 / HZ)) | ||
58 | |||
59 | #define cputime64_zero (0ULL) | ||
60 | #define cputime64_add(__a, __b) ((__a) + (__b)) | ||
61 | #define cputime_to_cputime64(__ct) (__ct) | ||
62 | |||
63 | static inline u64 | ||
64 | cputime64_to_jiffies64(cputime64_t cputime) | ||
65 | { | ||
66 | do_div(cputime, 1000000 / HZ); | ||
67 | return cputime; | ||
68 | } | ||
69 | |||
70 | /* | ||
71 | * Convert cputime to milliseconds and back. | ||
72 | */ | ||
73 | static inline unsigned int | ||
74 | cputime_to_msecs(const cputime_t cputime) | ||
75 | { | ||
76 | return __div(cputime, 1000); | ||
77 | } | ||
78 | |||
79 | static inline cputime_t | ||
80 | msecs_to_cputime(const unsigned int m) | ||
81 | { | ||
82 | return (cputime_t) m * 1000; | ||
83 | } | ||
84 | |||
85 | /* | ||
86 | * Convert cputime to milliseconds and back. | ||
87 | */ | ||
88 | static inline unsigned int | ||
89 | cputime_to_secs(const cputime_t cputime) | ||
90 | { | ||
91 | return __div(cputime, 1000000); | ||
92 | } | ||
93 | |||
94 | static inline cputime_t | ||
95 | secs_to_cputime(const unsigned int s) | ||
96 | { | ||
97 | return (cputime_t) s * 1000000; | ||
98 | } | ||
99 | |||
100 | /* | ||
101 | * Convert cputime to timespec and back. | ||
102 | */ | ||
103 | static inline cputime_t | ||
104 | timespec_to_cputime(const struct timespec *value) | ||
105 | { | ||
106 | return value->tv_nsec / 1000 + (u64) value->tv_sec * 1000000; | ||
107 | } | ||
108 | |||
109 | static inline void | ||
110 | cputime_to_timespec(const cputime_t cputime, struct timespec *value) | ||
111 | { | ||
112 | #ifndef __s390x__ | ||
113 | register_pair rp; | ||
114 | |||
115 | rp.pair = cputime >> 1; | ||
116 | asm ("dr %0,%1" : "+d" (rp) : "d" (1000000 >> 1)); | ||
117 | value->tv_nsec = rp.subreg.even * 1000; | ||
118 | value->tv_sec = rp.subreg.odd; | ||
119 | #else | ||
120 | value->tv_nsec = (cputime % 1000000) * 1000; | ||
121 | value->tv_sec = cputime / 1000000; | ||
122 | #endif | ||
123 | } | ||
124 | |||
125 | /* | ||
126 | * Convert cputime to timeval and back. | ||
127 | * Since cputime and timeval have the same resolution (microseconds) | ||
128 | * this is easy. | ||
129 | */ | ||
130 | static inline cputime_t | ||
131 | timeval_to_cputime(const struct timeval *value) | ||
132 | { | ||
133 | return value->tv_usec + (u64) value->tv_sec * 1000000; | ||
134 | } | ||
135 | |||
136 | static inline void | ||
137 | cputime_to_timeval(const cputime_t cputime, struct timeval *value) | ||
138 | { | ||
139 | #ifndef __s390x__ | ||
140 | register_pair rp; | ||
141 | |||
142 | rp.pair = cputime >> 1; | ||
143 | asm ("dr %0,%1" : "+d" (rp) : "d" (1000000 >> 1)); | ||
144 | value->tv_usec = rp.subreg.even; | ||
145 | value->tv_sec = rp.subreg.odd; | ||
146 | #else | ||
147 | value->tv_usec = cputime % 1000000; | ||
148 | value->tv_sec = cputime / 1000000; | ||
149 | #endif | ||
150 | } | ||
151 | |||
152 | /* | ||
153 | * Convert cputime to clock and back. | ||
154 | */ | ||
155 | static inline clock_t | ||
156 | cputime_to_clock_t(cputime_t cputime) | ||
157 | { | ||
158 | return __div(cputime, 1000000 / USER_HZ); | ||
159 | } | ||
160 | |||
161 | static inline cputime_t | ||
162 | clock_t_to_cputime(unsigned long x) | ||
163 | { | ||
164 | return (cputime_t) x * (1000000 / USER_HZ); | ||
165 | } | ||
166 | |||
167 | /* | ||
168 | * Convert cputime64 to clock. | ||
169 | */ | ||
170 | static inline clock_t | ||
171 | cputime64_to_clock_t(cputime64_t cputime) | ||
172 | { | ||
173 | return __div(cputime, 1000000 / USER_HZ); | ||
174 | } | ||
175 | |||
176 | #endif /* _S390_CPUTIME_H */ | ||
diff --git a/include/asm-s390/current.h b/include/asm-s390/current.h new file mode 100644 index 000000000000..83cf36cde2da --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/dasd.h b/include/asm-s390/dasd.h new file mode 100644 index 000000000000..77b10d6adabd --- /dev/null +++ b/include/asm-s390/dasd.h | |||
@@ -0,0 +1,268 @@ | |||
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 | * $Revision: 1.6 $ | ||
12 | * | ||
13 | */ | ||
14 | |||
15 | #ifndef DASD_H | ||
16 | #define DASD_H | ||
17 | #include <linux/ioctl.h> | ||
18 | |||
19 | #define DASD_IOCTL_LETTER 'D' | ||
20 | |||
21 | #define DASD_API_VERSION 6 | ||
22 | |||
23 | /* | ||
24 | * struct dasd_information2_t | ||
25 | * represents any data about the device, which is visible to userspace. | ||
26 | * including foramt and featueres. | ||
27 | */ | ||
28 | typedef struct dasd_information2_t { | ||
29 | unsigned int devno; /* S/390 devno */ | ||
30 | unsigned int real_devno; /* for aliases */ | ||
31 | unsigned int schid; /* S/390 subchannel identifier */ | ||
32 | unsigned int cu_type : 16; /* from SenseID */ | ||
33 | unsigned int cu_model : 8; /* from SenseID */ | ||
34 | unsigned int dev_type : 16; /* from SenseID */ | ||
35 | unsigned int dev_model : 8; /* from SenseID */ | ||
36 | unsigned int open_count; | ||
37 | unsigned int req_queue_len; | ||
38 | unsigned int chanq_len; /* length of chanq */ | ||
39 | char type[4]; /* from discipline.name, 'none' for unknown */ | ||
40 | unsigned int status; /* current device level */ | ||
41 | unsigned int label_block; /* where to find the VOLSER */ | ||
42 | unsigned int FBA_layout; /* fixed block size (like AIXVOL) */ | ||
43 | unsigned int characteristics_size; | ||
44 | unsigned int confdata_size; | ||
45 | char characteristics[64]; /* from read_device_characteristics */ | ||
46 | char configuration_data[256]; /* from read_configuration_data */ | ||
47 | unsigned int format; /* format info like formatted/cdl/ldl/... */ | ||
48 | unsigned int features; /* dasd features like 'ro',... */ | ||
49 | unsigned int reserved0; /* reserved for further use ,... */ | ||
50 | unsigned int reserved1; /* reserved for further use ,... */ | ||
51 | unsigned int reserved2; /* reserved for further use ,... */ | ||
52 | unsigned int reserved3; /* reserved for further use ,... */ | ||
53 | unsigned int reserved4; /* reserved for further use ,... */ | ||
54 | unsigned int reserved5; /* reserved for further use ,... */ | ||
55 | unsigned int reserved6; /* reserved for further use ,... */ | ||
56 | unsigned int reserved7; /* reserved for further use ,... */ | ||
57 | } dasd_information2_t; | ||
58 | |||
59 | /* | ||
60 | * values to be used for dasd_information_t.format | ||
61 | * 0x00: NOT formatted | ||
62 | * 0x01: Linux disc layout | ||
63 | * 0x02: Common disc layout | ||
64 | */ | ||
65 | #define DASD_FORMAT_NONE 0 | ||
66 | #define DASD_FORMAT_LDL 1 | ||
67 | #define DASD_FORMAT_CDL 2 | ||
68 | /* | ||
69 | * values to be used for dasd_information_t.features | ||
70 | * 0x00: default features | ||
71 | * 0x01: readonly (ro) | ||
72 | * 0x02: use diag discipline (diag) | ||
73 | */ | ||
74 | #define DASD_FEATURE_DEFAULT 0 | ||
75 | #define DASD_FEATURE_READONLY 1 | ||
76 | #define DASD_FEATURE_USEDIAG 2 | ||
77 | |||
78 | #define DASD_PARTN_BITS 2 | ||
79 | |||
80 | /* | ||
81 | * struct dasd_information_t | ||
82 | * represents any data about the data, which is visible to userspace | ||
83 | */ | ||
84 | typedef struct dasd_information_t { | ||
85 | unsigned int devno; /* S/390 devno */ | ||
86 | unsigned int real_devno; /* for aliases */ | ||
87 | unsigned int schid; /* S/390 subchannel identifier */ | ||
88 | unsigned int cu_type : 16; /* from SenseID */ | ||
89 | unsigned int cu_model : 8; /* from SenseID */ | ||
90 | unsigned int dev_type : 16; /* from SenseID */ | ||
91 | unsigned int dev_model : 8; /* from SenseID */ | ||
92 | unsigned int open_count; | ||
93 | unsigned int req_queue_len; | ||
94 | unsigned int chanq_len; /* length of chanq */ | ||
95 | char type[4]; /* from discipline.name, 'none' for unknown */ | ||
96 | unsigned int status; /* current device level */ | ||
97 | unsigned int label_block; /* where to find the VOLSER */ | ||
98 | unsigned int FBA_layout; /* fixed block size (like AIXVOL) */ | ||
99 | unsigned int characteristics_size; | ||
100 | unsigned int confdata_size; | ||
101 | char characteristics[64]; /* from read_device_characteristics */ | ||
102 | char configuration_data[256]; /* from read_configuration_data */ | ||
103 | } dasd_information_t; | ||
104 | |||
105 | /* | ||
106 | * Read Subsystem Data - Perfomance Statistics | ||
107 | */ | ||
108 | typedef struct dasd_rssd_perf_stats_t { | ||
109 | unsigned char invalid:1; | ||
110 | unsigned char format:3; | ||
111 | unsigned char data_format:4; | ||
112 | unsigned char unit_address; | ||
113 | unsigned short device_status; | ||
114 | unsigned int nr_read_normal; | ||
115 | unsigned int nr_read_normal_hits; | ||
116 | unsigned int nr_write_normal; | ||
117 | unsigned int nr_write_fast_normal_hits; | ||
118 | unsigned int nr_read_seq; | ||
119 | unsigned int nr_read_seq_hits; | ||
120 | unsigned int nr_write_seq; | ||
121 | unsigned int nr_write_fast_seq_hits; | ||
122 | unsigned int nr_read_cache; | ||
123 | unsigned int nr_read_cache_hits; | ||
124 | unsigned int nr_write_cache; | ||
125 | unsigned int nr_write_fast_cache_hits; | ||
126 | unsigned int nr_inhibit_cache; | ||
127 | unsigned int nr_bybass_cache; | ||
128 | unsigned int nr_seq_dasd_to_cache; | ||
129 | unsigned int nr_dasd_to_cache; | ||
130 | unsigned int nr_cache_to_dasd; | ||
131 | unsigned int nr_delayed_fast_write; | ||
132 | unsigned int nr_normal_fast_write; | ||
133 | unsigned int nr_seq_fast_write; | ||
134 | unsigned int nr_cache_miss; | ||
135 | unsigned char status2; | ||
136 | unsigned int nr_quick_write_promotes; | ||
137 | unsigned char reserved; | ||
138 | unsigned short ssid; | ||
139 | unsigned char reseved2[96]; | ||
140 | } __attribute__((packed)) dasd_rssd_perf_stats_t; | ||
141 | |||
142 | /* | ||
143 | * struct profile_info_t | ||
144 | * holds the profinling information | ||
145 | */ | ||
146 | typedef struct dasd_profile_info_t { | ||
147 | unsigned int dasd_io_reqs; /* number of requests processed at all */ | ||
148 | unsigned int dasd_io_sects; /* number of sectors processed at all */ | ||
149 | unsigned int dasd_io_secs[32]; /* histogram of request's sizes */ | ||
150 | unsigned int dasd_io_times[32]; /* histogram of requests's times */ | ||
151 | unsigned int dasd_io_timps[32]; /* histogram of requests's times per sector */ | ||
152 | unsigned int dasd_io_time1[32]; /* histogram of time from build to start */ | ||
153 | unsigned int dasd_io_time2[32]; /* histogram of time from start to irq */ | ||
154 | unsigned int dasd_io_time2ps[32]; /* histogram of time from start to irq */ | ||
155 | unsigned int dasd_io_time3[32]; /* histogram of time from irq to end */ | ||
156 | unsigned int dasd_io_nr_req[32]; /* histogram of # of requests in chanq */ | ||
157 | } dasd_profile_info_t; | ||
158 | |||
159 | /* | ||
160 | * struct format_data_t | ||
161 | * represents all data necessary to format a dasd | ||
162 | */ | ||
163 | typedef struct format_data_t { | ||
164 | int start_unit; /* from track */ | ||
165 | int stop_unit; /* to track */ | ||
166 | int blksize; /* sectorsize */ | ||
167 | int intensity; | ||
168 | } format_data_t; | ||
169 | |||
170 | /* | ||
171 | * values to be used for format_data_t.intensity | ||
172 | * 0/8: normal format | ||
173 | * 1/9: also write record zero | ||
174 | * 3/11: also write home address | ||
175 | * 4/12: invalidate track | ||
176 | */ | ||
177 | #define DASD_FMT_INT_FMT_R0 1 /* write record zero */ | ||
178 | #define DASD_FMT_INT_FMT_HA 2 /* write home address, also set FMT_R0 ! */ | ||
179 | #define DASD_FMT_INT_INVAL 4 /* invalidate tracks */ | ||
180 | #define DASD_FMT_INT_COMPAT 8 /* use OS/390 compatible disk layout */ | ||
181 | |||
182 | |||
183 | /* | ||
184 | * struct attrib_data_t | ||
185 | * represents the operation (cache) bits for the device. | ||
186 | * Used in DE to influence caching of the DASD. | ||
187 | */ | ||
188 | typedef struct attrib_data_t { | ||
189 | unsigned char operation:3; /* cache operation mode */ | ||
190 | unsigned char reserved:5; /* cache operation mode */ | ||
191 | __u16 nr_cyl; /* no of cyliners for read ahaed */ | ||
192 | __u8 reserved2[29]; /* for future use */ | ||
193 | } __attribute__ ((packed)) attrib_data_t; | ||
194 | |||
195 | /* definition of operation (cache) bits within attributes of DE */ | ||
196 | #define DASD_NORMAL_CACHE 0x0 | ||
197 | #define DASD_BYPASS_CACHE 0x1 | ||
198 | #define DASD_INHIBIT_LOAD 0x2 | ||
199 | #define DASD_SEQ_ACCESS 0x3 | ||
200 | #define DASD_SEQ_PRESTAGE 0x4 | ||
201 | #define DASD_REC_ACCESS 0x5 | ||
202 | |||
203 | |||
204 | /******************************************************************************** | ||
205 | * SECTION: Definition of IOCTLs | ||
206 | * | ||
207 | * Here ist how the ioctl-nr should be used: | ||
208 | * 0 - 31 DASD driver itself | ||
209 | * 32 - 239 still open | ||
210 | * 240 - 255 reserved for EMC | ||
211 | *******************************************************************************/ | ||
212 | |||
213 | /* Disable the volume (for Linux) */ | ||
214 | #define BIODASDDISABLE _IO(DASD_IOCTL_LETTER,0) | ||
215 | /* Enable the volume (for Linux) */ | ||
216 | #define BIODASDENABLE _IO(DASD_IOCTL_LETTER,1) | ||
217 | /* Issue a reserve/release command, rsp. */ | ||
218 | #define BIODASDRSRV _IO(DASD_IOCTL_LETTER,2) /* reserve */ | ||
219 | #define BIODASDRLSE _IO(DASD_IOCTL_LETTER,3) /* release */ | ||
220 | #define BIODASDSLCK _IO(DASD_IOCTL_LETTER,4) /* steal lock */ | ||
221 | /* reset profiling information of a device */ | ||
222 | #define BIODASDPRRST _IO(DASD_IOCTL_LETTER,5) | ||
223 | /* Quiesce IO on device */ | ||
224 | #define BIODASDQUIESCE _IO(DASD_IOCTL_LETTER,6) | ||
225 | /* Resume IO on device */ | ||
226 | #define BIODASDRESUME _IO(DASD_IOCTL_LETTER,7) | ||
227 | |||
228 | |||
229 | /* retrieve API version number */ | ||
230 | #define DASDAPIVER _IOR(DASD_IOCTL_LETTER,0,int) | ||
231 | /* Get information on a dasd device */ | ||
232 | #define BIODASDINFO _IOR(DASD_IOCTL_LETTER,1,dasd_information_t) | ||
233 | /* retrieve profiling information of a device */ | ||
234 | #define BIODASDPRRD _IOR(DASD_IOCTL_LETTER,2,dasd_profile_info_t) | ||
235 | /* Get information on a dasd device (enhanced) */ | ||
236 | #define BIODASDINFO2 _IOR(DASD_IOCTL_LETTER,3,dasd_information2_t) | ||
237 | /* Performance Statistics Read */ | ||
238 | #define BIODASDPSRD _IOR(DASD_IOCTL_LETTER,4,dasd_rssd_perf_stats_t) | ||
239 | /* Get Attributes (cache operations) */ | ||
240 | #define BIODASDGATTR _IOR(DASD_IOCTL_LETTER,5,attrib_data_t) | ||
241 | |||
242 | |||
243 | /* #define BIODASDFORMAT _IOW(IOCTL_LETTER,0,format_data_t) , deprecated */ | ||
244 | #define BIODASDFMT _IOW(DASD_IOCTL_LETTER,1,format_data_t) | ||
245 | /* Set Attributes (cache operations) */ | ||
246 | #define BIODASDSATTR _IOW(DASD_IOCTL_LETTER,2,attrib_data_t) | ||
247 | |||
248 | |||
249 | #endif /* DASD_H */ | ||
250 | |||
251 | /* | ||
252 | * Overrides for Emacs so that we follow Linus's tabbing style. | ||
253 | * Emacs will notice this stuff at the end of the file and automatically | ||
254 | * adjust the settings for this buffer only. This must remain at the end | ||
255 | * of the file. | ||
256 | * --------------------------------------------------------------------------- | ||
257 | * Local variables: | ||
258 | * c-indent-level: 4 | ||
259 | * c-brace-imaginary-offset: 0 | ||
260 | * c-brace-offset: -4 | ||
261 | * c-argdecl-indent: 4 | ||
262 | * c-label-offset: -4 | ||
263 | * c-continued-statement-offset: 4 | ||
264 | * c-continued-brace-offset: 0 | ||
265 | * indent-tabs-mode: nil | ||
266 | * tab-width: 8 | ||
267 | * End: | ||
268 | */ | ||
diff --git a/include/asm-s390/debug.h b/include/asm-s390/debug.h new file mode 100644 index 000000000000..28ef2354b1b2 --- /dev/null +++ b/include/asm-s390/debug.h | |||
@@ -0,0 +1,249 @@ | |||
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/string.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 1 /* version of debug feature */ | ||
35 | |||
36 | #ifdef __KERNEL__ | ||
37 | #include <linux/spinlock.h> | ||
38 | #include <linux/kernel.h> | ||
39 | #include <linux/time.h> | ||
40 | #include <linux/proc_fs.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_PROCF_LEN 16 /* max length for a proc 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 | #define STCK(x) asm volatile ("STCK 0(%1)" : "=m" (x) : "a" (&(x)) : "cc") | ||
55 | |||
56 | typedef struct __debug_entry debug_entry_t; | ||
57 | |||
58 | struct debug_view; | ||
59 | |||
60 | typedef struct debug_info { | ||
61 | struct debug_info* next; | ||
62 | struct debug_info* prev; | ||
63 | atomic_t ref_count; | ||
64 | spinlock_t lock; | ||
65 | int level; | ||
66 | int nr_areas; | ||
67 | int page_order; | ||
68 | int buf_size; | ||
69 | int entry_size; | ||
70 | debug_entry_t** areas; | ||
71 | int active_area; | ||
72 | int *active_entry; | ||
73 | struct proc_dir_entry* proc_root_entry; | ||
74 | struct proc_dir_entry* proc_entries[DEBUG_MAX_VIEWS]; | ||
75 | struct debug_view* views[DEBUG_MAX_VIEWS]; | ||
76 | char name[DEBUG_MAX_PROCF_LEN]; | ||
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_PROCF_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(char* name, int pages_index, int nr_areas, | ||
124 | int buf_size); | ||
125 | |||
126 | void debug_unregister(debug_info_t* id); | ||
127 | |||
128 | void debug_set_level(debug_info_t* id, int new_level); | ||
129 | |||
130 | void debug_stop_all(void); | ||
131 | |||
132 | extern inline debug_entry_t* | ||
133 | debug_event(debug_info_t* id, int level, void* data, int length) | ||
134 | { | ||
135 | if ((!id) || (level > id->level)) return NULL; | ||
136 | return debug_event_common(id,level,data,length); | ||
137 | } | ||
138 | |||
139 | extern inline debug_entry_t* | ||
140 | debug_int_event(debug_info_t* id, int level, unsigned int tag) | ||
141 | { | ||
142 | unsigned int t=tag; | ||
143 | if ((!id) || (level > id->level)) return NULL; | ||
144 | return debug_event_common(id,level,&t,sizeof(unsigned int)); | ||
145 | } | ||
146 | |||
147 | extern inline debug_entry_t * | ||
148 | debug_long_event (debug_info_t* id, int level, unsigned long tag) | ||
149 | { | ||
150 | unsigned long t=tag; | ||
151 | if ((!id) || (level > id->level)) return NULL; | ||
152 | return debug_event_common(id,level,&t,sizeof(unsigned long)); | ||
153 | } | ||
154 | |||
155 | extern inline debug_entry_t* | ||
156 | debug_text_event(debug_info_t* id, int level, const char* txt) | ||
157 | { | ||
158 | if ((!id) || (level > id->level)) return NULL; | ||
159 | return debug_event_common(id,level,txt,strlen(txt)); | ||
160 | } | ||
161 | |||
162 | extern debug_entry_t * | ||
163 | debug_sprintf_event(debug_info_t* id,int level,char *string,...) | ||
164 | __attribute__ ((format(printf, 3, 4))); | ||
165 | |||
166 | |||
167 | extern inline debug_entry_t* | ||
168 | debug_exception(debug_info_t* id, int level, void* data, int length) | ||
169 | { | ||
170 | if ((!id) || (level > id->level)) return NULL; | ||
171 | return debug_exception_common(id,level,data,length); | ||
172 | } | ||
173 | |||
174 | extern inline debug_entry_t* | ||
175 | debug_int_exception(debug_info_t* id, int level, unsigned int tag) | ||
176 | { | ||
177 | unsigned int t=tag; | ||
178 | if ((!id) || (level > id->level)) return NULL; | ||
179 | return debug_exception_common(id,level,&t,sizeof(unsigned int)); | ||
180 | } | ||
181 | |||
182 | extern inline debug_entry_t * | ||
183 | debug_long_exception (debug_info_t* id, int level, unsigned long tag) | ||
184 | { | ||
185 | unsigned long t=tag; | ||
186 | if ((!id) || (level > id->level)) return NULL; | ||
187 | return debug_exception_common(id,level,&t,sizeof(unsigned long)); | ||
188 | } | ||
189 | |||
190 | extern inline debug_entry_t* | ||
191 | debug_text_exception(debug_info_t* id, int level, const char* txt) | ||
192 | { | ||
193 | if ((!id) || (level > id->level)) return NULL; | ||
194 | return debug_exception_common(id,level,txt,strlen(txt)); | ||
195 | } | ||
196 | |||
197 | |||
198 | extern debug_entry_t * | ||
199 | debug_sprintf_exception(debug_info_t* id,int level,char *string,...) | ||
200 | __attribute__ ((format(printf, 3, 4))); | ||
201 | |||
202 | int debug_register_view(debug_info_t* id, struct debug_view* view); | ||
203 | int debug_unregister_view(debug_info_t* id, struct debug_view* view); | ||
204 | |||
205 | /* | ||
206 | define the debug levels: | ||
207 | - 0 No debugging output to console or syslog | ||
208 | - 1 Log internal errors to syslog, ignore check conditions | ||
209 | - 2 Log internal errors and check conditions to syslog | ||
210 | - 3 Log internal errors to console, log check conditions to syslog | ||
211 | - 4 Log internal errors and check conditions to console | ||
212 | - 5 panic on internal errors, log check conditions to console | ||
213 | - 6 panic on both, internal errors and check conditions | ||
214 | */ | ||
215 | |||
216 | #ifndef DEBUG_LEVEL | ||
217 | #define DEBUG_LEVEL 4 | ||
218 | #endif | ||
219 | |||
220 | #define INTERNAL_ERRMSG(x,y...) "E" __FILE__ "%d: " x, __LINE__, y | ||
221 | #define INTERNAL_WRNMSG(x,y...) "W" __FILE__ "%d: " x, __LINE__, y | ||
222 | #define INTERNAL_INFMSG(x,y...) "I" __FILE__ "%d: " x, __LINE__, y | ||
223 | #define INTERNAL_DEBMSG(x,y...) "D" __FILE__ "%d: " x, __LINE__, y | ||
224 | |||
225 | #if DEBUG_LEVEL > 0 | ||
226 | #define PRINT_DEBUG(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | ||
227 | #define PRINT_INFO(x...) printk ( KERN_INFO PRINTK_HEADER x ) | ||
228 | #define PRINT_WARN(x...) printk ( KERN_WARNING PRINTK_HEADER x ) | ||
229 | #define PRINT_ERR(x...) printk ( KERN_ERR PRINTK_HEADER x ) | ||
230 | #define PRINT_FATAL(x...) panic ( PRINTK_HEADER x ) | ||
231 | #else | ||
232 | #define PRINT_DEBUG(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | ||
233 | #define PRINT_INFO(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | ||
234 | #define PRINT_WARN(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | ||
235 | #define PRINT_ERR(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | ||
236 | #define PRINT_FATAL(x...) printk ( KERN_DEBUG PRINTK_HEADER x ) | ||
237 | #endif /* DASD_DEBUG */ | ||
238 | |||
239 | #undef DEBUG_MALLOC | ||
240 | #ifdef DEBUG_MALLOC | ||
241 | void *b; | ||
242 | #define kmalloc(x...) (PRINT_INFO(" kmalloc %p\n",b=kmalloc(x)),b) | ||
243 | #define kfree(x) PRINT_INFO(" kfree %p\n",x);kfree(x) | ||
244 | #define get_zeroed_page(x...) (PRINT_INFO(" gfp %p\n",b=get_zeroed_page(x)),b) | ||
245 | #define __get_free_pages(x...) (PRINT_INFO(" gfps %p\n",b=__get_free_pages(x)),b) | ||
246 | #endif /* DEBUG_MALLOC */ | ||
247 | |||
248 | #endif /* __KERNEL__ */ | ||
249 | #endif /* DEBUG_H */ | ||
diff --git a/include/asm-s390/delay.h b/include/asm-s390/delay.h new file mode 100644 index 000000000000..78357314c450 --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/div64.h b/include/asm-s390/div64.h new file mode 100644 index 000000000000..af098dc3cf59 --- /dev/null +++ b/include/asm-s390/div64.h | |||
@@ -0,0 +1,49 @@ | |||
1 | #ifndef __S390_DIV64 | ||
2 | #define __S390_DIV64 | ||
3 | |||
4 | #ifndef __s390x__ | ||
5 | |||
6 | /* for do_div "base" needs to be smaller than 2^31-1 */ | ||
7 | #define do_div(n, base) ({ \ | ||
8 | unsigned long long __n = (n); \ | ||
9 | unsigned long __r; \ | ||
10 | \ | ||
11 | asm (" slr 0,0\n" \ | ||
12 | " l 1,%1\n" \ | ||
13 | " srdl 0,1\n" \ | ||
14 | " dr 0,%2\n" \ | ||
15 | " alr 1,1\n" \ | ||
16 | " alr 0,0\n" \ | ||
17 | " lhi 2,1\n" \ | ||
18 | " n 2,%1\n" \ | ||
19 | " alr 0,2\n" \ | ||
20 | " clr 0,%2\n" \ | ||
21 | " jl 0f\n" \ | ||
22 | " slr 0,%2\n" \ | ||
23 | " ahi 1,1\n" \ | ||
24 | "0: st 1,%1\n" \ | ||
25 | " l 1,4+%1\n" \ | ||
26 | " srdl 0,1\n" \ | ||
27 | " dr 0,%2\n" \ | ||
28 | " alr 1,1\n" \ | ||
29 | " alr 0,0\n" \ | ||
30 | " lhi 2,1\n" \ | ||
31 | " n 2,4+%1\n" \ | ||
32 | " alr 0,2\n" \ | ||
33 | " clr 0,%2\n" \ | ||
34 | " jl 1f\n" \ | ||
35 | " slr 0,%2\n" \ | ||
36 | " ahi 1,1\n" \ | ||
37 | "1: st 1,4+%1\n" \ | ||
38 | " lr %0,0" \ | ||
39 | : "=d" (__r), "=m" (__n) \ | ||
40 | : "d" (base), "m" (__n) : "0", "1", "2", "cc" ); \ | ||
41 | (n) = (__n); \ | ||
42 | __r; \ | ||
43 | }) | ||
44 | |||
45 | #else /* __s390x__ */ | ||
46 | #include <asm-generic/div64.h> | ||
47 | #endif /* __s390x__ */ | ||
48 | |||
49 | #endif | ||
diff --git a/include/asm-s390/dma-mapping.h b/include/asm-s390/dma-mapping.h new file mode 100644 index 000000000000..09bb7b04f967 --- /dev/null +++ b/include/asm-s390/dma-mapping.h | |||
@@ -0,0 +1,14 @@ | |||
1 | /* | ||
2 | * include/asm-s390/dma-mapping.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * This file exists so that #include <dma-mapping.h> doesn't break anything. | ||
7 | */ | ||
8 | |||
9 | #ifndef _ASM_DMA_MAPPING_H | ||
10 | #define _ASM_DMA_MAPPING_H | ||
11 | |||
12 | #include <asm-generic/dma-mapping-broken.h> | ||
13 | |||
14 | #endif /* _ASM_DMA_MAPPING_H */ | ||
diff --git a/include/asm-s390/dma.h b/include/asm-s390/dma.h new file mode 100644 index 000000000000..02720c449cd8 --- /dev/null +++ b/include/asm-s390/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) | ||
15 | |||
16 | #endif /* _ASM_DMA_H */ | ||
diff --git a/include/asm-s390/ebcdic.h b/include/asm-s390/ebcdic.h new file mode 100644 index 000000000000..20e81e885821 --- /dev/null +++ b/include/asm-s390/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[]; /* ASCII -> EBCDIC 500 conversion table */ | ||
18 | extern __u8 _ebcasc_500[]; /* EBCDIC 500 -> ASCII conversion table */ | ||
19 | extern __u8 _ascebc[]; /* ASCII -> EBCDIC conversion table */ | ||
20 | extern __u8 _ebcasc[]; /* EBCDIC -> ASCII conversion table */ | ||
21 | extern __u8 _ebc_tolower[]; /* EBCDIC -> lowercase */ | ||
22 | extern __u8 _ebc_toupper[]; /* EBCDIC -> uppercase */ | ||
23 | |||
24 | extern __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/include/asm-s390/elf.h b/include/asm-s390/elf.h new file mode 100644 index 000000000000..3b8bd46832a1 --- /dev/null +++ b/include/asm-s390/elf.h | |||
@@ -0,0 +1,215 @@ | |||
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 | * ELF register definitions.. | ||
97 | */ | ||
98 | |||
99 | #include <asm/ptrace.h> | ||
100 | #include <asm/user.h> | ||
101 | #include <asm/system.h> /* for save_access_regs */ | ||
102 | |||
103 | |||
104 | typedef s390_fp_regs elf_fpregset_t; | ||
105 | typedef s390_regs elf_gregset_t; | ||
106 | |||
107 | /* | ||
108 | * These are used to set parameters in the core dumps. | ||
109 | */ | ||
110 | #ifndef __s390x__ | ||
111 | #define ELF_CLASS ELFCLASS32 | ||
112 | #else /* __s390x__ */ | ||
113 | #define ELF_CLASS ELFCLASS64 | ||
114 | #endif /* __s390x__ */ | ||
115 | #define ELF_DATA ELFDATA2MSB | ||
116 | #define ELF_ARCH EM_S390 | ||
117 | |||
118 | /* | ||
119 | * This is used to ensure we don't load something for the wrong architecture. | ||
120 | */ | ||
121 | #define elf_check_arch(x) \ | ||
122 | (((x)->e_machine == EM_S390 || (x)->e_machine == EM_S390_OLD) \ | ||
123 | && (x)->e_ident[EI_CLASS] == ELF_CLASS) | ||
124 | |||
125 | /* For SVR4/S390 the function pointer to be registered with `atexit` is | ||
126 | passed in R14. */ | ||
127 | #define ELF_PLAT_INIT(_r, load_addr) \ | ||
128 | do { \ | ||
129 | _r->gprs[14] = 0; \ | ||
130 | } while (0) | ||
131 | |||
132 | #define USE_ELF_CORE_DUMP | ||
133 | #define ELF_EXEC_PAGESIZE 4096 | ||
134 | |||
135 | /* This is the location that an ET_DYN program is loaded if exec'ed. Typical | ||
136 | use of this is to invoke "./ld.so someprog" to test out a new version of | ||
137 | the loader. We need to make sure that it is out of the way of the program | ||
138 | that it will "exec", and that there is sufficient room for the brk. */ | ||
139 | |||
140 | #ifndef __s390x__ | ||
141 | #define ELF_ET_DYN_BASE ((TASK_SIZE & 0x80000000) \ | ||
142 | ? TASK_SIZE / 3 * 2 \ | ||
143 | : 2 * TASK_SIZE / 3) | ||
144 | #else /* __s390x__ */ | ||
145 | #define ELF_ET_DYN_BASE (TASK_SIZE / 3 * 2) | ||
146 | #endif /* __s390x__ */ | ||
147 | |||
148 | /* Wow, the "main" arch needs arch dependent functions too.. :) */ | ||
149 | |||
150 | /* regs is struct pt_regs, pr_reg is elf_gregset_t (which is | ||
151 | now struct_user_regs, they are different) */ | ||
152 | |||
153 | static inline int dump_regs(struct pt_regs *ptregs, elf_gregset_t *regs) | ||
154 | { | ||
155 | memcpy(®s->psw, &ptregs->psw, sizeof(regs->psw)+sizeof(regs->gprs)); | ||
156 | save_access_regs(regs->acrs); | ||
157 | regs->orig_gpr2 = ptregs->orig_gpr2; | ||
158 | return 1; | ||
159 | } | ||
160 | |||
161 | #define ELF_CORE_COPY_REGS(pr_reg, regs) dump_regs(regs, &pr_reg); | ||
162 | |||
163 | static inline int dump_task_regs(struct task_struct *tsk, elf_gregset_t *regs) | ||
164 | { | ||
165 | struct pt_regs *ptregs = __KSTK_PTREGS(tsk); | ||
166 | memcpy(®s->psw, &ptregs->psw, sizeof(regs->psw)+sizeof(regs->gprs)); | ||
167 | memcpy(regs->acrs, tsk->thread.acrs, sizeof(regs->acrs)); | ||
168 | regs->orig_gpr2 = ptregs->orig_gpr2; | ||
169 | return 1; | ||
170 | } | ||
171 | |||
172 | #define ELF_CORE_COPY_TASK_REGS(tsk, regs) dump_task_regs(tsk, regs) | ||
173 | |||
174 | static inline int dump_task_fpu(struct task_struct *tsk, elf_fpregset_t *fpregs) | ||
175 | { | ||
176 | if (tsk == current) | ||
177 | save_fp_regs(fpregs); | ||
178 | else | ||
179 | memcpy(fpregs, &tsk->thread.fp_regs, sizeof(elf_fpregset_t)); | ||
180 | return 1; | ||
181 | } | ||
182 | |||
183 | #define ELF_CORE_COPY_FPREGS(tsk, fpregs) dump_task_fpu(tsk, fpregs) | ||
184 | |||
185 | |||
186 | /* This yields a mask that user programs can use to figure out what | ||
187 | instruction set this CPU supports. */ | ||
188 | |||
189 | #define ELF_HWCAP (0) | ||
190 | |||
191 | /* This yields a string that ld.so will use to load implementation | ||
192 | specific libraries for optimization. This is more specific in | ||
193 | intent than poking at uname or /proc/cpuinfo. | ||
194 | |||
195 | For the moment, we have only optimizations for the Intel generations, | ||
196 | but that could change... */ | ||
197 | |||
198 | #define ELF_PLATFORM (NULL) | ||
199 | |||
200 | #ifdef __KERNEL__ | ||
201 | #ifndef __s390x__ | ||
202 | #define SET_PERSONALITY(ex, ibcs2) set_personality((ibcs2)?PER_SVR4:PER_LINUX) | ||
203 | #else /* __s390x__ */ | ||
204 | #define SET_PERSONALITY(ex, ibcs2) \ | ||
205 | do { \ | ||
206 | if (ibcs2) \ | ||
207 | set_personality(PER_SVR4); \ | ||
208 | else if (current->personality != PER_LINUX32) \ | ||
209 | set_personality(PER_LINUX); \ | ||
210 | clear_thread_flag(TIF_31BIT); \ | ||
211 | } while (0) | ||
212 | #endif /* __s390x__ */ | ||
213 | #endif | ||
214 | |||
215 | #endif | ||
diff --git a/include/asm-s390/errno.h b/include/asm-s390/errno.h new file mode 100644 index 000000000000..e41d5b37c4d6 --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/extmem.h b/include/asm-s390/extmem.h new file mode 100644 index 000000000000..c8802c934b74 --- /dev/null +++ b/include/asm-s390/extmem.h | |||
@@ -0,0 +1,32 @@ | |||
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 | extern int segment_load (char *name,int segtype,unsigned long *addr,unsigned long *length); | ||
26 | extern void segment_unload(char *name); | ||
27 | extern void segment_save(char *name); | ||
28 | extern int segment_type (char* name); | ||
29 | extern int segment_modify_shared (char *name, int do_nonshared); | ||
30 | |||
31 | #endif | ||
32 | #endif | ||
diff --git a/include/asm-s390/fcntl.h b/include/asm-s390/fcntl.h new file mode 100644 index 000000000000..48f692b45732 --- /dev/null +++ b/include/asm-s390/fcntl.h | |||
@@ -0,0 +1,97 @@ | |||
1 | /* | ||
2 | * include/asm-s390/fcntl.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/fcntl.h" | ||
7 | */ | ||
8 | #ifndef _S390_FCNTL_H | ||
9 | #define _S390_FCNTL_H | ||
10 | |||
11 | /* open/fcntl - O_SYNC is only implemented on blocks devices and on files | ||
12 | located on an ext2 file system */ | ||
13 | #define O_ACCMODE 0003 | ||
14 | #define O_RDONLY 00 | ||
15 | #define O_WRONLY 01 | ||
16 | #define O_RDWR 02 | ||
17 | #define O_CREAT 0100 /* not fcntl */ | ||
18 | #define O_EXCL 0200 /* not fcntl */ | ||
19 | #define O_NOCTTY 0400 /* not fcntl */ | ||
20 | #define O_TRUNC 01000 /* not fcntl */ | ||
21 | #define O_APPEND 02000 | ||
22 | #define O_NONBLOCK 04000 | ||
23 | #define O_NDELAY O_NONBLOCK | ||
24 | #define O_SYNC 010000 | ||
25 | #define FASYNC 020000 /* fcntl, for BSD compatibility */ | ||
26 | #define O_DIRECT 040000 /* direct disk access hint */ | ||
27 | #define O_LARGEFILE 0100000 | ||
28 | #define O_DIRECTORY 0200000 /* must be a directory */ | ||
29 | #define O_NOFOLLOW 0400000 /* don't follow links */ | ||
30 | #define O_NOATIME 01000000 | ||
31 | |||
32 | #define F_DUPFD 0 /* dup */ | ||
33 | #define F_GETFD 1 /* get close_on_exec */ | ||
34 | #define F_SETFD 2 /* set/clear close_on_exec */ | ||
35 | #define F_GETFL 3 /* get file->f_flags */ | ||
36 | #define F_SETFL 4 /* set file->f_flags */ | ||
37 | #define F_GETLK 5 | ||
38 | #define F_SETLK 6 | ||
39 | #define F_SETLKW 7 | ||
40 | |||
41 | #define F_SETOWN 8 /* for sockets. */ | ||
42 | #define F_GETOWN 9 /* for sockets. */ | ||
43 | #define F_SETSIG 10 /* for sockets. */ | ||
44 | #define F_GETSIG 11 /* for sockets. */ | ||
45 | |||
46 | #ifndef __s390x__ | ||
47 | #define F_GETLK64 12 /* using 'struct flock64' */ | ||
48 | #define F_SETLK64 13 | ||
49 | #define F_SETLKW64 14 | ||
50 | #endif /* ! __s390x__ */ | ||
51 | |||
52 | /* for F_[GET|SET]FL */ | ||
53 | #define FD_CLOEXEC 1 /* actually anything with low bit set goes */ | ||
54 | |||
55 | /* for posix fcntl() and lockf() */ | ||
56 | #define F_RDLCK 0 | ||
57 | #define F_WRLCK 1 | ||
58 | #define F_UNLCK 2 | ||
59 | |||
60 | /* for old implementation of bsd flock () */ | ||
61 | #define F_EXLCK 4 /* or 3 */ | ||
62 | #define F_SHLCK 8 /* or 4 */ | ||
63 | |||
64 | /* for leases */ | ||
65 | #define F_INPROGRESS 16 | ||
66 | |||
67 | /* operations for bsd flock(), also used by the kernel implementation */ | ||
68 | #define LOCK_SH 1 /* shared lock */ | ||
69 | #define LOCK_EX 2 /* exclusive lock */ | ||
70 | #define LOCK_NB 4 /* or'd with one of the above to prevent | ||
71 | blocking */ | ||
72 | #define LOCK_UN 8 /* remove lock */ | ||
73 | |||
74 | #define LOCK_MAND 32 /* This is a mandatory flock */ | ||
75 | #define LOCK_READ 64 /* ... Which allows concurrent read operations */ | ||
76 | #define LOCK_WRITE 128 /* ... Which allows concurrent write operations */ | ||
77 | #define LOCK_RW 192 /* ... Which allows concurrent read & write ops */ | ||
78 | |||
79 | struct flock { | ||
80 | short l_type; | ||
81 | short l_whence; | ||
82 | off_t l_start; | ||
83 | off_t l_len; | ||
84 | pid_t l_pid; | ||
85 | }; | ||
86 | |||
87 | #ifndef __s390x__ | ||
88 | struct flock64 { | ||
89 | short l_type; | ||
90 | short l_whence; | ||
91 | loff_t l_start; | ||
92 | loff_t l_len; | ||
93 | pid_t l_pid; | ||
94 | }; | ||
95 | #endif | ||
96 | #define F_LINUX_SPECIFIC_BASE 1024 | ||
97 | #endif | ||
diff --git a/include/asm-s390/hardirq.h b/include/asm-s390/hardirq.h new file mode 100644 index 000000000000..6792c559a124 --- /dev/null +++ b/include/asm-s390/hardirq.h | |||
@@ -0,0 +1,38 @@ | |||
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/config.h> | ||
16 | #include <linux/threads.h> | ||
17 | #include <linux/sched.h> | ||
18 | #include <linux/cache.h> | ||
19 | #include <linux/interrupt.h> | ||
20 | #include <asm/lowcore.h> | ||
21 | |||
22 | /* irq_cpustat_t is unused currently, but could be converted | ||
23 | * into a percpu variable instead of storing softirq_pending | ||
24 | * on the lowcore */ | ||
25 | typedef struct { | ||
26 | unsigned int __softirq_pending; | ||
27 | } irq_cpustat_t; | ||
28 | |||
29 | #define local_softirq_pending() (S390_lowcore.softirq_pending) | ||
30 | |||
31 | #define __ARCH_IRQ_STAT | ||
32 | #define __ARCH_HAS_DO_SOFTIRQ | ||
33 | |||
34 | #define HARDIRQ_BITS 8 | ||
35 | |||
36 | extern void account_ticks(struct pt_regs *); | ||
37 | |||
38 | #endif /* __ASM_HARDIRQ_H */ | ||
diff --git a/include/asm-s390/idals.h b/include/asm-s390/idals.h new file mode 100644 index 000000000000..8038858b86bb --- /dev/null +++ b/include/asm-s390/idals.h | |||
@@ -0,0 +1,257 @@ | |||
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/config.h> | ||
17 | #include <linux/errno.h> | ||
18 | #include <linux/err.h> | ||
19 | #include <linux/types.h> | ||
20 | #include <linux/slab.h> | ||
21 | #include <asm/cio.h> | ||
22 | #include <asm/uaccess.h> | ||
23 | |||
24 | #ifdef __s390x__ | ||
25 | #define IDA_SIZE_LOG 12 /* 11 for 2k , 12 for 4k */ | ||
26 | #else | ||
27 | #define IDA_SIZE_LOG 11 /* 11 for 2k , 12 for 4k */ | ||
28 | #endif | ||
29 | #define IDA_BLOCK_SIZE (1L<<IDA_SIZE_LOG) | ||
30 | |||
31 | /* | ||
32 | * Test if an address/length pair needs an idal list. | ||
33 | */ | ||
34 | static inline int | ||
35 | idal_is_needed(void *vaddr, unsigned int length) | ||
36 | { | ||
37 | #ifdef __s390x__ | ||
38 | return ((__pa(vaddr) + length - 1) >> 31) != 0; | ||
39 | #else | ||
40 | return 0; | ||
41 | #endif | ||
42 | } | ||
43 | |||
44 | |||
45 | /* | ||
46 | * Return the number of idal words needed for an address/length pair. | ||
47 | */ | ||
48 | static inline unsigned int | ||
49 | idal_nr_words(void *vaddr, unsigned int length) | ||
50 | { | ||
51 | #ifdef __s390x__ | ||
52 | if (idal_is_needed(vaddr, length)) | ||
53 | return ((__pa(vaddr) & (IDA_BLOCK_SIZE-1)) + length + | ||
54 | (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG; | ||
55 | #endif | ||
56 | return 0; | ||
57 | } | ||
58 | |||
59 | /* | ||
60 | * Create the list of idal words for an address/length pair. | ||
61 | */ | ||
62 | static inline unsigned long * | ||
63 | idal_create_words(unsigned long *idaws, void *vaddr, unsigned int length) | ||
64 | { | ||
65 | #ifdef __s390x__ | ||
66 | unsigned long paddr; | ||
67 | unsigned int cidaw; | ||
68 | |||
69 | paddr = __pa(vaddr); | ||
70 | cidaw = ((paddr & (IDA_BLOCK_SIZE-1)) + length + | ||
71 | (IDA_BLOCK_SIZE-1)) >> IDA_SIZE_LOG; | ||
72 | *idaws++ = paddr; | ||
73 | paddr &= -IDA_BLOCK_SIZE; | ||
74 | while (--cidaw > 0) { | ||
75 | paddr += IDA_BLOCK_SIZE; | ||
76 | *idaws++ = paddr; | ||
77 | } | ||
78 | #endif | ||
79 | return idaws; | ||
80 | } | ||
81 | |||
82 | /* | ||
83 | * Sets the address of the data in CCW. | ||
84 | * If necessary it allocates an IDAL and sets the appropriate flags. | ||
85 | */ | ||
86 | static inline int | ||
87 | set_normalized_cda(struct ccw1 * ccw, void *vaddr) | ||
88 | { | ||
89 | #ifdef __s390x__ | ||
90 | unsigned int nridaws; | ||
91 | unsigned long *idal; | ||
92 | |||
93 | if (ccw->flags & CCW_FLAG_IDA) | ||
94 | return -EINVAL; | ||
95 | nridaws = idal_nr_words(vaddr, ccw->count); | ||
96 | if (nridaws > 0) { | ||
97 | idal = kmalloc(nridaws * sizeof(unsigned long), | ||
98 | GFP_ATOMIC | GFP_DMA ); | ||
99 | if (idal == NULL) | ||
100 | return -ENOMEM; | ||
101 | idal_create_words(idal, vaddr, ccw->count); | ||
102 | ccw->flags |= CCW_FLAG_IDA; | ||
103 | vaddr = idal; | ||
104 | } | ||
105 | #endif | ||
106 | ccw->cda = (__u32)(unsigned long) vaddr; | ||
107 | return 0; | ||
108 | } | ||
109 | |||
110 | /* | ||
111 | * Releases any allocated IDAL related to the CCW. | ||
112 | */ | ||
113 | static inline void | ||
114 | clear_normalized_cda(struct ccw1 * ccw) | ||
115 | { | ||
116 | #ifdef __s390x__ | ||
117 | if (ccw->flags & CCW_FLAG_IDA) { | ||
118 | kfree((void *)(unsigned long) ccw->cda); | ||
119 | ccw->flags &= ~CCW_FLAG_IDA; | ||
120 | } | ||
121 | #endif | ||
122 | ccw->cda = 0; | ||
123 | } | ||
124 | |||
125 | /* | ||
126 | * Idal buffer extension | ||
127 | */ | ||
128 | struct idal_buffer { | ||
129 | size_t size; | ||
130 | size_t page_order; | ||
131 | void *data[0]; | ||
132 | }; | ||
133 | |||
134 | /* | ||
135 | * Allocate an idal buffer | ||
136 | */ | ||
137 | static inline struct idal_buffer * | ||
138 | idal_buffer_alloc(size_t size, int page_order) | ||
139 | { | ||
140 | struct idal_buffer *ib; | ||
141 | int nr_chunks, nr_ptrs, i; | ||
142 | |||
143 | nr_ptrs = (size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_LOG; | ||
144 | nr_chunks = (4096 << page_order) >> IDA_SIZE_LOG; | ||
145 | ib = kmalloc(sizeof(struct idal_buffer) + nr_ptrs*sizeof(void *), | ||
146 | GFP_DMA | GFP_KERNEL); | ||
147 | if (ib == NULL) | ||
148 | return ERR_PTR(-ENOMEM); | ||
149 | ib->size = size; | ||
150 | ib->page_order = page_order; | ||
151 | for (i = 0; i < nr_ptrs; i++) { | ||
152 | if ((i & (nr_chunks - 1)) != 0) { | ||
153 | ib->data[i] = ib->data[i-1] + IDA_BLOCK_SIZE; | ||
154 | continue; | ||
155 | } | ||
156 | ib->data[i] = (void *) | ||
157 | __get_free_pages(GFP_KERNEL, page_order); | ||
158 | if (ib->data[i] != NULL) | ||
159 | continue; | ||
160 | // Not enough memory | ||
161 | while (i >= nr_chunks) { | ||
162 | i -= nr_chunks; | ||
163 | free_pages((unsigned long) ib->data[i], | ||
164 | ib->page_order); | ||
165 | } | ||
166 | kfree(ib); | ||
167 | return ERR_PTR(-ENOMEM); | ||
168 | } | ||
169 | return ib; | ||
170 | } | ||
171 | |||
172 | /* | ||
173 | * Free an idal buffer. | ||
174 | */ | ||
175 | static inline void | ||
176 | idal_buffer_free(struct idal_buffer *ib) | ||
177 | { | ||
178 | int nr_chunks, nr_ptrs, i; | ||
179 | |||
180 | nr_ptrs = (ib->size + IDA_BLOCK_SIZE - 1) >> IDA_SIZE_LOG; | ||
181 | nr_chunks = (4096 << ib->page_order) >> IDA_SIZE_LOG; | ||
182 | for (i = 0; i < nr_ptrs; i += nr_chunks) | ||
183 | free_pages((unsigned long) ib->data[i], ib->page_order); | ||
184 | kfree(ib); | ||
185 | } | ||
186 | |||
187 | /* | ||
188 | * Test if a idal list is really needed. | ||
189 | */ | ||
190 | static inline int | ||
191 | __idal_buffer_is_needed(struct idal_buffer *ib) | ||
192 | { | ||
193 | #ifdef __s390x__ | ||
194 | return ib->size > (4096ul << ib->page_order) || | ||
195 | idal_is_needed(ib->data[0], ib->size); | ||
196 | #else | ||
197 | return ib->size > (4096ul << ib->page_order); | ||
198 | #endif | ||
199 | } | ||
200 | |||
201 | /* | ||
202 | * Set channel data address to idal buffer. | ||
203 | */ | ||
204 | static inline void | ||
205 | idal_buffer_set_cda(struct idal_buffer *ib, struct ccw1 *ccw) | ||
206 | { | ||
207 | if (__idal_buffer_is_needed(ib)) { | ||
208 | // setup idals; | ||
209 | ccw->cda = (u32)(addr_t) ib->data; | ||
210 | ccw->flags |= CCW_FLAG_IDA; | ||
211 | } else | ||
212 | // we do not need idals - use direct addressing | ||
213 | ccw->cda = (u32)(addr_t) ib->data[0]; | ||
214 | ccw->count = ib->size; | ||
215 | } | ||
216 | |||
217 | /* | ||
218 | * Copy count bytes from an idal buffer to user memory | ||
219 | */ | ||
220 | static inline size_t | ||
221 | idal_buffer_to_user(struct idal_buffer *ib, void __user *to, size_t count) | ||
222 | { | ||
223 | size_t left; | ||
224 | int i; | ||
225 | |||
226 | BUG_ON(count > ib->size); | ||
227 | for (i = 0; count > IDA_BLOCK_SIZE; i++) { | ||
228 | left = copy_to_user(to, ib->data[i], IDA_BLOCK_SIZE); | ||
229 | if (left) | ||
230 | return left + count - IDA_BLOCK_SIZE; | ||
231 | to = (void __user *) to + IDA_BLOCK_SIZE; | ||
232 | count -= IDA_BLOCK_SIZE; | ||
233 | } | ||
234 | return copy_to_user(to, ib->data[i], count); | ||
235 | } | ||
236 | |||
237 | /* | ||
238 | * Copy count bytes from user memory to an idal buffer | ||
239 | */ | ||
240 | static inline size_t | ||
241 | idal_buffer_from_user(struct idal_buffer *ib, const void __user *from, size_t count) | ||
242 | { | ||
243 | size_t left; | ||
244 | int i; | ||
245 | |||
246 | BUG_ON(count > ib->size); | ||
247 | for (i = 0; count > IDA_BLOCK_SIZE; i++) { | ||
248 | left = copy_from_user(ib->data[i], from, IDA_BLOCK_SIZE); | ||
249 | if (left) | ||
250 | return left + count - IDA_BLOCK_SIZE; | ||
251 | from = (void __user *) from + IDA_BLOCK_SIZE; | ||
252 | count -= IDA_BLOCK_SIZE; | ||
253 | } | ||
254 | return copy_from_user(ib->data[i], from, count); | ||
255 | } | ||
256 | |||
257 | #endif | ||
diff --git a/include/asm-s390/io.h b/include/asm-s390/io.h new file mode 100644 index 000000000000..8188fdc9884f --- /dev/null +++ b/include/asm-s390/io.h | |||
@@ -0,0 +1,123 @@ | |||
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 <linux/vmalloc.h> | ||
17 | #include <asm/page.h> | ||
18 | |||
19 | #define IO_SPACE_LIMIT 0xffffffff | ||
20 | |||
21 | #define __io_virt(x) ((void *)(PAGE_OFFSET | (unsigned long)(x))) | ||
22 | |||
23 | /* | ||
24 | * Change virtual addresses to physical addresses and vv. | ||
25 | * These are pretty trivial | ||
26 | */ | ||
27 | extern inline unsigned long virt_to_phys(volatile void * address) | ||
28 | { | ||
29 | unsigned long real_address; | ||
30 | __asm__ ( | ||
31 | #ifndef __s390x__ | ||
32 | " lra %0,0(%1)\n" | ||
33 | " jz 0f\n" | ||
34 | " sr %0,%0\n" | ||
35 | #else /* __s390x__ */ | ||
36 | " lrag %0,0(%1)\n" | ||
37 | " jz 0f\n" | ||
38 | " slgr %0,%0\n" | ||
39 | #endif /* __s390x__ */ | ||
40 | "0:" | ||
41 | : "=a" (real_address) : "a" (address) : "cc" ); | ||
42 | return real_address; | ||
43 | } | ||
44 | |||
45 | extern inline void * phys_to_virt(unsigned long address) | ||
46 | { | ||
47 | return __io_virt(address); | ||
48 | } | ||
49 | |||
50 | /* | ||
51 | * Change "struct page" to physical address. | ||
52 | */ | ||
53 | #define page_to_phys(page) ((page - mem_map) << PAGE_SHIFT) | ||
54 | |||
55 | extern void * __ioremap(unsigned long offset, unsigned long size, unsigned long flags); | ||
56 | |||
57 | extern inline void * ioremap (unsigned long offset, unsigned long size) | ||
58 | { | ||
59 | return __ioremap(offset, size, 0); | ||
60 | } | ||
61 | |||
62 | /* | ||
63 | * This one maps high address device memory and turns off caching for that area. | ||
64 | * it's useful if some control registers are in such an area and write combining | ||
65 | * or read caching is not desirable: | ||
66 | */ | ||
67 | extern inline void * ioremap_nocache (unsigned long offset, unsigned long size) | ||
68 | { | ||
69 | return __ioremap(offset, size, 0); | ||
70 | } | ||
71 | |||
72 | extern void iounmap(void *addr); | ||
73 | |||
74 | /* | ||
75 | * IO bus memory addresses are also 1:1 with the physical address | ||
76 | */ | ||
77 | #define virt_to_bus virt_to_phys | ||
78 | #define bus_to_virt phys_to_virt | ||
79 | |||
80 | /* | ||
81 | * readX/writeX() are used to access memory mapped devices. On some | ||
82 | * architectures the memory mapped IO stuff needs to be accessed | ||
83 | * differently. | ||
84 | */ | ||
85 | |||
86 | #define readb(addr) (*(volatile unsigned char *) __io_virt(addr)) | ||
87 | #define readw(addr) (*(volatile unsigned short *) __io_virt(addr)) | ||
88 | #define readl(addr) (*(volatile unsigned int *) __io_virt(addr)) | ||
89 | |||
90 | #define readb_relaxed(addr) readb(addr) | ||
91 | #define readw_relaxed(addr) readw(addr) | ||
92 | #define readl_relaxed(addr) readl(addr) | ||
93 | |||
94 | #define writeb(b,addr) (*(volatile unsigned char *) __io_virt(addr) = (b)) | ||
95 | #define writew(b,addr) (*(volatile unsigned short *) __io_virt(addr) = (b)) | ||
96 | #define writel(b,addr) (*(volatile unsigned int *) __io_virt(addr) = (b)) | ||
97 | |||
98 | #define memset_io(a,b,c) memset(__io_virt(a),(b),(c)) | ||
99 | #define memcpy_fromio(a,b,c) memcpy((a),__io_virt(b),(c)) | ||
100 | #define memcpy_toio(a,b,c) memcpy(__io_virt(a),(b),(c)) | ||
101 | |||
102 | #define inb_p(addr) readb(addr) | ||
103 | #define inb(addr) readb(addr) | ||
104 | |||
105 | #define outb(x,addr) ((void) writeb(x,addr)) | ||
106 | #define outb_p(x,addr) outb(x,addr) | ||
107 | |||
108 | #define mmiowb() | ||
109 | |||
110 | /* | ||
111 | * Convert a physical pointer to a virtual kernel pointer for /dev/mem | ||
112 | * access | ||
113 | */ | ||
114 | #define xlate_dev_mem_ptr(p) __va(p) | ||
115 | |||
116 | /* | ||
117 | * Convert a virtual cached pointer to an uncached pointer | ||
118 | */ | ||
119 | #define xlate_dev_kmem_ptr(p) p | ||
120 | |||
121 | #endif /* __KERNEL__ */ | ||
122 | |||
123 | #endif | ||
diff --git a/include/asm-s390/ioctl.h b/include/asm-s390/ioctl.h new file mode 100644 index 000000000000..df7394345ac4 --- /dev/null +++ b/include/asm-s390/ioctl.h | |||
@@ -0,0 +1,88 @@ | |||
1 | /* | ||
2 | * include/asm-s390/ioctl.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/ioctl.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef _S390_IOCTL_H | ||
10 | #define _S390_IOCTL_H | ||
11 | |||
12 | /* ioctl command encoding: 32 bits total, command in lower 16 bits, | ||
13 | * size of the parameter structure in the lower 14 bits of the | ||
14 | * upper 16 bits. | ||
15 | * Encoding the size of the parameter structure in the ioctl request | ||
16 | * is useful for catching programs compiled with old versions | ||
17 | * and to avoid overwriting user space outside the user buffer area. | ||
18 | * The highest 2 bits are reserved for indicating the ``access mode''. | ||
19 | * NOTE: This limits the max parameter size to 16kB -1 ! | ||
20 | */ | ||
21 | |||
22 | /* | ||
23 | * The following is for compatibility across the various Linux | ||
24 | * platforms. The i386 ioctl numbering scheme doesn't really enforce | ||
25 | * a type field. De facto, however, the top 8 bits of the lower 16 | ||
26 | * bits are indeed used as a type field, so we might just as well make | ||
27 | * this explicit here. Please be sure to use the decoding macros | ||
28 | * below from now on. | ||
29 | */ | ||
30 | #define _IOC_NRBITS 8 | ||
31 | #define _IOC_TYPEBITS 8 | ||
32 | #define _IOC_SIZEBITS 14 | ||
33 | #define _IOC_DIRBITS 2 | ||
34 | |||
35 | #define _IOC_NRMASK ((1 << _IOC_NRBITS)-1) | ||
36 | #define _IOC_TYPEMASK ((1 << _IOC_TYPEBITS)-1) | ||
37 | #define _IOC_SIZEMASK ((1 << _IOC_SIZEBITS)-1) | ||
38 | #define _IOC_DIRMASK ((1 << _IOC_DIRBITS)-1) | ||
39 | |||
40 | #define _IOC_NRSHIFT 0 | ||
41 | #define _IOC_TYPESHIFT (_IOC_NRSHIFT+_IOC_NRBITS) | ||
42 | #define _IOC_SIZESHIFT (_IOC_TYPESHIFT+_IOC_TYPEBITS) | ||
43 | #define _IOC_DIRSHIFT (_IOC_SIZESHIFT+_IOC_SIZEBITS) | ||
44 | |||
45 | /* | ||
46 | * Direction bits. | ||
47 | */ | ||
48 | #define _IOC_NONE 0U | ||
49 | #define _IOC_WRITE 1U | ||
50 | #define _IOC_READ 2U | ||
51 | |||
52 | #define _IOC(dir,type,nr,size) \ | ||
53 | (((dir) << _IOC_DIRSHIFT) | \ | ||
54 | ((type) << _IOC_TYPESHIFT) | \ | ||
55 | ((nr) << _IOC_NRSHIFT) | \ | ||
56 | ((size) << _IOC_SIZESHIFT)) | ||
57 | |||
58 | /* provoke compile error for invalid uses of size argument */ | ||
59 | extern unsigned long __invalid_size_argument_for_IOC; | ||
60 | #define _IOC_TYPECHECK(t) \ | ||
61 | ((sizeof(t) == sizeof(t[1]) && \ | ||
62 | sizeof(t) < (1 << _IOC_SIZEBITS)) ? \ | ||
63 | sizeof(t) : __invalid_size_argument_for_IOC) | ||
64 | |||
65 | /* used to create numbers */ | ||
66 | #define _IO(type,nr) _IOC(_IOC_NONE,(type),(nr),0) | ||
67 | #define _IOR(type,nr,size) _IOC(_IOC_READ,(type),(nr),(_IOC_TYPECHECK(size))) | ||
68 | #define _IOW(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) | ||
69 | #define _IOWR(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),(_IOC_TYPECHECK(size))) | ||
70 | #define _IOR_BAD(type,nr,size) _IOC(_IOC_READ,(type),(nr),sizeof(size)) | ||
71 | #define _IOW_BAD(type,nr,size) _IOC(_IOC_WRITE,(type),(nr),sizeof(size)) | ||
72 | #define _IOWR_BAD(type,nr,size) _IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size)) | ||
73 | |||
74 | /* used to decode ioctl numbers.. */ | ||
75 | #define _IOC_DIR(nr) (((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK) | ||
76 | #define _IOC_TYPE(nr) (((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK) | ||
77 | #define _IOC_NR(nr) (((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK) | ||
78 | #define _IOC_SIZE(nr) (((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK) | ||
79 | |||
80 | /* ...and for the drivers/sound files... */ | ||
81 | |||
82 | #define IOC_IN (_IOC_WRITE << _IOC_DIRSHIFT) | ||
83 | #define IOC_OUT (_IOC_READ << _IOC_DIRSHIFT) | ||
84 | #define IOC_INOUT ((_IOC_WRITE|_IOC_READ) << _IOC_DIRSHIFT) | ||
85 | #define IOCSIZE_MASK (_IOC_SIZEMASK << _IOC_SIZESHIFT) | ||
86 | #define IOCSIZE_SHIFT (_IOC_SIZESHIFT) | ||
87 | |||
88 | #endif /* _S390_IOCTL_H */ | ||
diff --git a/include/asm-s390/ioctls.h b/include/asm-s390/ioctls.h new file mode 100644 index 000000000000..07e19b2dd73f --- /dev/null +++ b/include/asm-s390/ioctls.h | |||
@@ -0,0 +1,88 @@ | |||
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 TIOCGPTN _IOR('T',0x30, unsigned int) /* Get Pty Number (of pty-mux device) */ | ||
58 | #define TIOCSPTLCK _IOW('T',0x31, int) /* Lock/unlock Pty */ | ||
59 | |||
60 | #define FIONCLEX 0x5450 /* these numbers need to be adjusted. */ | ||
61 | #define FIOCLEX 0x5451 | ||
62 | #define FIOASYNC 0x5452 | ||
63 | #define TIOCSERCONFIG 0x5453 | ||
64 | #define TIOCSERGWILD 0x5454 | ||
65 | #define TIOCSERSWILD 0x5455 | ||
66 | #define TIOCGLCKTRMIOS 0x5456 | ||
67 | #define TIOCSLCKTRMIOS 0x5457 | ||
68 | #define TIOCSERGSTRUCT 0x5458 /* For debugging only */ | ||
69 | #define TIOCSERGETLSR 0x5459 /* Get line status register */ | ||
70 | #define TIOCSERGETMULTI 0x545A /* Get multiport config */ | ||
71 | #define TIOCSERSETMULTI 0x545B /* Set multiport config */ | ||
72 | |||
73 | #define TIOCMIWAIT 0x545C /* wait for a change on serial input line(s) */ | ||
74 | #define TIOCGICOUNT 0x545D /* read serial port inline interrupt counts */ | ||
75 | #define FIOQSIZE 0x545E | ||
76 | |||
77 | /* Used for packet mode */ | ||
78 | #define TIOCPKT_DATA 0 | ||
79 | #define TIOCPKT_FLUSHREAD 1 | ||
80 | #define TIOCPKT_FLUSHWRITE 2 | ||
81 | #define TIOCPKT_STOP 4 | ||
82 | #define TIOCPKT_START 8 | ||
83 | #define TIOCPKT_NOSTOP 16 | ||
84 | #define TIOCPKT_DOSTOP 32 | ||
85 | |||
86 | #define TIOCSER_TEMT 0x01 /* Transmitter physically empty */ | ||
87 | |||
88 | #endif | ||
diff --git a/include/asm-s390/ipc.h b/include/asm-s390/ipc.h new file mode 100644 index 000000000000..a46e3d9c2a3f --- /dev/null +++ b/include/asm-s390/ipc.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/ipc.h> | |||
diff --git a/include/asm-s390/ipcbuf.h b/include/asm-s390/ipcbuf.h new file mode 100644 index 000000000000..37f293d12c8f --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/irq.h b/include/asm-s390/irq.h new file mode 100644 index 000000000000..916a1aa0b073 --- /dev/null +++ b/include/asm-s390/irq.h | |||
@@ -0,0 +1,30 @@ | |||
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 | #define touch_nmi_watchdog() do { } while(0) | ||
23 | |||
24 | struct irqaction; | ||
25 | struct pt_regs; | ||
26 | int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *); | ||
27 | |||
28 | #endif /* __KERNEL__ */ | ||
29 | #endif | ||
30 | |||
diff --git a/include/asm-s390/kmap_types.h b/include/asm-s390/kmap_types.h new file mode 100644 index 000000000000..fd1574648223 --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/linkage.h b/include/asm-s390/linkage.h new file mode 100644 index 000000000000..291c2d01c44f --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/local.h b/include/asm-s390/local.h new file mode 100644 index 000000000000..cf8189009c30 --- /dev/null +++ b/include/asm-s390/local.h | |||
@@ -0,0 +1,59 @@ | |||
1 | #ifndef _ASM_LOCAL_H | ||
2 | #define _ASM_LOCAL_H | ||
3 | |||
4 | #include <linux/config.h> | ||
5 | #include <linux/percpu.h> | ||
6 | #include <asm/atomic.h> | ||
7 | |||
8 | #ifndef __s390x__ | ||
9 | |||
10 | typedef atomic_t local_t; | ||
11 | |||
12 | #define LOCAL_INIT(i) ATOMIC_INIT(i) | ||
13 | #define local_read(v) atomic_read(v) | ||
14 | #define local_set(v,i) atomic_set(v,i) | ||
15 | |||
16 | #define local_inc(v) atomic_inc(v) | ||
17 | #define local_dec(v) atomic_dec(v) | ||
18 | #define local_add(i, v) atomic_add(i, v) | ||
19 | #define local_sub(i, v) atomic_sub(i, v) | ||
20 | |||
21 | #else | ||
22 | |||
23 | typedef atomic64_t local_t; | ||
24 | |||
25 | #define LOCAL_INIT(i) ATOMIC64_INIT(i) | ||
26 | #define local_read(v) atomic64_read(v) | ||
27 | #define local_set(v,i) atomic64_set(v,i) | ||
28 | |||
29 | #define local_inc(v) atomic64_inc(v) | ||
30 | #define local_dec(v) atomic64_dec(v) | ||
31 | #define local_add(i, v) atomic64_add(i, v) | ||
32 | #define local_sub(i, v) atomic64_sub(i, v) | ||
33 | |||
34 | #endif | ||
35 | |||
36 | #define __local_inc(v) ((v)->counter++) | ||
37 | #define __local_dec(v) ((v)->counter--) | ||
38 | #define __local_add(i,v) ((v)->counter+=(i)) | ||
39 | #define __local_sub(i,v) ((v)->counter-=(i)) | ||
40 | |||
41 | /* | ||
42 | * Use these for per-cpu local_t variables: on some archs they are | ||
43 | * much more efficient than these naive implementations. Note they take | ||
44 | * a variable, not an address. | ||
45 | */ | ||
46 | #define cpu_local_read(v) local_read(&__get_cpu_var(v)) | ||
47 | #define cpu_local_set(v, i) local_set(&__get_cpu_var(v), (i)) | ||
48 | |||
49 | #define cpu_local_inc(v) local_inc(&__get_cpu_var(v)) | ||
50 | #define cpu_local_dec(v) local_dec(&__get_cpu_var(v)) | ||
51 | #define cpu_local_add(i, v) local_add((i), &__get_cpu_var(v)) | ||
52 | #define cpu_local_sub(i, v) local_sub((i), &__get_cpu_var(v)) | ||
53 | |||
54 | #define __cpu_local_inc(v) __local_inc(&__get_cpu_var(v)) | ||
55 | #define __cpu_local_dec(v) __local_dec(&__get_cpu_var(v)) | ||
56 | #define __cpu_local_add(i, v) __local_add((i), &__get_cpu_var(v)) | ||
57 | #define __cpu_local_sub(i, v) __local_sub((i), &__get_cpu_var(v)) | ||
58 | |||
59 | #endif /* _ASM_LOCAL_H */ | ||
diff --git a/include/asm-s390/lowcore.h b/include/asm-s390/lowcore.h new file mode 100644 index 000000000000..df5172fc589d --- /dev/null +++ b/include/asm-s390/lowcore.h | |||
@@ -0,0 +1,351 @@ | |||
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_EXT_PARAMS 0x080 | ||
39 | #define __LC_CPU_ADDRESS 0x084 | ||
40 | #define __LC_EXT_INT_CODE 0x086 | ||
41 | |||
42 | #define __LC_SVC_ILC 0x088 | ||
43 | #define __LC_SVC_INT_CODE 0x08A | ||
44 | #define __LC_PGM_ILC 0x08C | ||
45 | #define __LC_PGM_INT_CODE 0x08E | ||
46 | |||
47 | #define __LC_PER_ATMID 0x096 | ||
48 | #define __LC_PER_ADDRESS 0x098 | ||
49 | #define __LC_PER_ACCESS_ID 0x0A1 | ||
50 | |||
51 | #define __LC_SUBCHANNEL_ID 0x0B8 | ||
52 | #define __LC_SUBCHANNEL_NR 0x0BA | ||
53 | #define __LC_IO_INT_PARM 0x0BC | ||
54 | #define __LC_IO_INT_WORD 0x0C0 | ||
55 | #define __LC_MCCK_CODE 0x0E8 | ||
56 | |||
57 | #define __LC_RETURN_PSW 0x200 | ||
58 | |||
59 | #define __LC_SAVE_AREA 0xC00 | ||
60 | |||
61 | #ifndef __s390x__ | ||
62 | #define __LC_IRB 0x208 | ||
63 | #define __LC_SYNC_ENTER_TIMER 0x248 | ||
64 | #define __LC_ASYNC_ENTER_TIMER 0x250 | ||
65 | #define __LC_EXIT_TIMER 0x258 | ||
66 | #define __LC_LAST_UPDATE_TIMER 0x260 | ||
67 | #define __LC_USER_TIMER 0x268 | ||
68 | #define __LC_SYSTEM_TIMER 0x270 | ||
69 | #define __LC_LAST_UPDATE_CLOCK 0x278 | ||
70 | #define __LC_STEAL_CLOCK 0x280 | ||
71 | #define __LC_KERNEL_STACK 0xC40 | ||
72 | #define __LC_THREAD_INFO 0xC44 | ||
73 | #define __LC_ASYNC_STACK 0xC48 | ||
74 | #define __LC_KERNEL_ASCE 0xC4C | ||
75 | #define __LC_USER_ASCE 0xC50 | ||
76 | #define __LC_PANIC_STACK 0xC54 | ||
77 | #define __LC_CPUID 0xC60 | ||
78 | #define __LC_CPUADDR 0xC68 | ||
79 | #define __LC_IPLDEV 0xC7C | ||
80 | #define __LC_JIFFY_TIMER 0xC80 | ||
81 | #define __LC_CURRENT 0xC90 | ||
82 | #define __LC_INT_CLOCK 0xC98 | ||
83 | #else /* __s390x__ */ | ||
84 | #define __LC_IRB 0x210 | ||
85 | #define __LC_SYNC_ENTER_TIMER 0x250 | ||
86 | #define __LC_ASYNC_ENTER_TIMER 0x258 | ||
87 | #define __LC_EXIT_TIMER 0x260 | ||
88 | #define __LC_LAST_UPDATE_TIMER 0x268 | ||
89 | #define __LC_USER_TIMER 0x270 | ||
90 | #define __LC_SYSTEM_TIMER 0x278 | ||
91 | #define __LC_LAST_UPDATE_CLOCK 0x280 | ||
92 | #define __LC_STEAL_CLOCK 0x288 | ||
93 | #define __LC_DIAG44_OPCODE 0x290 | ||
94 | #define __LC_KERNEL_STACK 0xD40 | ||
95 | #define __LC_THREAD_INFO 0xD48 | ||
96 | #define __LC_ASYNC_STACK 0xD50 | ||
97 | #define __LC_KERNEL_ASCE 0xD58 | ||
98 | #define __LC_USER_ASCE 0xD60 | ||
99 | #define __LC_PANIC_STACK 0xD68 | ||
100 | #define __LC_CPUID 0xD90 | ||
101 | #define __LC_CPUADDR 0xD98 | ||
102 | #define __LC_IPLDEV 0xDB8 | ||
103 | #define __LC_JIFFY_TIMER 0xDC0 | ||
104 | #define __LC_CURRENT 0xDD8 | ||
105 | #define __LC_INT_CLOCK 0xDE8 | ||
106 | #endif /* __s390x__ */ | ||
107 | |||
108 | #define __LC_PANIC_MAGIC 0xE00 | ||
109 | |||
110 | #ifndef __s390x__ | ||
111 | #define __LC_PFAULT_INTPARM 0x080 | ||
112 | #define __LC_AREGS_SAVE_AREA 0x120 | ||
113 | #define __LC_CREGS_SAVE_AREA 0x1C0 | ||
114 | #else /* __s390x__ */ | ||
115 | #define __LC_PFAULT_INTPARM 0x11B8 | ||
116 | #define __LC_AREGS_SAVE_AREA 0x1340 | ||
117 | #define __LC_CREGS_SAVE_AREA 0x1380 | ||
118 | #endif /* __s390x__ */ | ||
119 | |||
120 | #ifndef __ASSEMBLY__ | ||
121 | |||
122 | #include <linux/config.h> | ||
123 | #include <asm/processor.h> | ||
124 | #include <linux/types.h> | ||
125 | #include <asm/sigp.h> | ||
126 | |||
127 | void restart_int_handler(void); | ||
128 | void ext_int_handler(void); | ||
129 | void system_call(void); | ||
130 | void pgm_check_handler(void); | ||
131 | void mcck_int_handler(void); | ||
132 | void io_int_handler(void); | ||
133 | |||
134 | struct _lowcore | ||
135 | { | ||
136 | #ifndef __s390x__ | ||
137 | /* prefix area: defined by architecture */ | ||
138 | psw_t restart_psw; /* 0x000 */ | ||
139 | __u32 ccw2[4]; /* 0x008 */ | ||
140 | psw_t external_old_psw; /* 0x018 */ | ||
141 | psw_t svc_old_psw; /* 0x020 */ | ||
142 | psw_t program_old_psw; /* 0x028 */ | ||
143 | psw_t mcck_old_psw; /* 0x030 */ | ||
144 | psw_t io_old_psw; /* 0x038 */ | ||
145 | __u8 pad1[0x58-0x40]; /* 0x040 */ | ||
146 | psw_t external_new_psw; /* 0x058 */ | ||
147 | psw_t svc_new_psw; /* 0x060 */ | ||
148 | psw_t program_new_psw; /* 0x068 */ | ||
149 | psw_t mcck_new_psw; /* 0x070 */ | ||
150 | psw_t io_new_psw; /* 0x078 */ | ||
151 | __u32 ext_params; /* 0x080 */ | ||
152 | __u16 cpu_addr; /* 0x084 */ | ||
153 | __u16 ext_int_code; /* 0x086 */ | ||
154 | __u16 svc_ilc; /* 0x088 */ | ||
155 | __u16 svc_code; /* 0x08a */ | ||
156 | __u16 pgm_ilc; /* 0x08c */ | ||
157 | __u16 pgm_code; /* 0x08e */ | ||
158 | __u32 trans_exc_code; /* 0x090 */ | ||
159 | __u16 mon_class_num; /* 0x094 */ | ||
160 | __u16 per_perc_atmid; /* 0x096 */ | ||
161 | __u32 per_address; /* 0x098 */ | ||
162 | __u32 monitor_code; /* 0x09c */ | ||
163 | __u8 exc_access_id; /* 0x0a0 */ | ||
164 | __u8 per_access_id; /* 0x0a1 */ | ||
165 | __u8 pad2[0xB8-0xA2]; /* 0x0a2 */ | ||
166 | __u16 subchannel_id; /* 0x0b8 */ | ||
167 | __u16 subchannel_nr; /* 0x0ba */ | ||
168 | __u32 io_int_parm; /* 0x0bc */ | ||
169 | __u32 io_int_word; /* 0x0c0 */ | ||
170 | __u8 pad3[0xD8-0xC4]; /* 0x0c4 */ | ||
171 | __u32 cpu_timer_save_area[2]; /* 0x0d8 */ | ||
172 | __u32 clock_comp_save_area[2]; /* 0x0e0 */ | ||
173 | __u32 mcck_interruption_code[2]; /* 0x0e8 */ | ||
174 | __u8 pad4[0xf4-0xf0]; /* 0x0f0 */ | ||
175 | __u32 external_damage_code; /* 0x0f4 */ | ||
176 | __u32 failing_storage_address; /* 0x0f8 */ | ||
177 | __u8 pad5[0x100-0xfc]; /* 0x0fc */ | ||
178 | __u32 st_status_fixed_logout[4];/* 0x100 */ | ||
179 | __u8 pad6[0x120-0x110]; /* 0x110 */ | ||
180 | __u32 access_regs_save_area[16];/* 0x120 */ | ||
181 | __u32 floating_pt_save_area[8]; /* 0x160 */ | ||
182 | __u32 gpregs_save_area[16]; /* 0x180 */ | ||
183 | __u32 cregs_save_area[16]; /* 0x1c0 */ | ||
184 | |||
185 | psw_t return_psw; /* 0x200 */ | ||
186 | __u8 irb[64]; /* 0x208 */ | ||
187 | __u64 sync_enter_timer; /* 0x248 */ | ||
188 | __u64 async_enter_timer; /* 0x250 */ | ||
189 | __u64 exit_timer; /* 0x258 */ | ||
190 | __u64 last_update_timer; /* 0x260 */ | ||
191 | __u64 user_timer; /* 0x268 */ | ||
192 | __u64 system_timer; /* 0x270 */ | ||
193 | __u64 last_update_clock; /* 0x278 */ | ||
194 | __u64 steal_clock; /* 0x280 */ | ||
195 | __u8 pad8[0xc00-0x288]; /* 0x288 */ | ||
196 | |||
197 | /* System info area */ | ||
198 | __u32 save_area[16]; /* 0xc00 */ | ||
199 | __u32 kernel_stack; /* 0xc40 */ | ||
200 | __u32 thread_info; /* 0xc44 */ | ||
201 | __u32 async_stack; /* 0xc48 */ | ||
202 | __u32 kernel_asce; /* 0xc4c */ | ||
203 | __u32 user_asce; /* 0xc50 */ | ||
204 | __u32 panic_stack; /* 0xc54 */ | ||
205 | __u8 pad10[0xc60-0xc58]; /* 0xc58 */ | ||
206 | /* entry.S sensitive area start */ | ||
207 | struct cpuinfo_S390 cpu_data; /* 0xc60 */ | ||
208 | __u32 ipl_device; /* 0xc7c */ | ||
209 | /* entry.S sensitive area end */ | ||
210 | |||
211 | /* SMP info area: defined by DJB */ | ||
212 | __u64 jiffy_timer; /* 0xc80 */ | ||
213 | __u32 ext_call_fast; /* 0xc88 */ | ||
214 | __u32 percpu_offset; /* 0xc8c */ | ||
215 | __u32 current_task; /* 0xc90 */ | ||
216 | __u32 softirq_pending; /* 0xc94 */ | ||
217 | __u64 int_clock; /* 0xc98 */ | ||
218 | __u8 pad11[0xe00-0xca0]; /* 0xca0 */ | ||
219 | |||
220 | /* 0xe00 is used as indicator for dump tools */ | ||
221 | /* whether the kernel died with panic() or not */ | ||
222 | __u32 panic_magic; /* 0xe00 */ | ||
223 | |||
224 | /* Align to the top 1k of prefix area */ | ||
225 | __u8 pad12[0x1000-0xe04]; /* 0xe04 */ | ||
226 | #else /* !__s390x__ */ | ||
227 | /* prefix area: defined by architecture */ | ||
228 | __u32 ccw1[2]; /* 0x000 */ | ||
229 | __u32 ccw2[4]; /* 0x008 */ | ||
230 | __u8 pad1[0x80-0x18]; /* 0x018 */ | ||
231 | __u32 ext_params; /* 0x080 */ | ||
232 | __u16 cpu_addr; /* 0x084 */ | ||
233 | __u16 ext_int_code; /* 0x086 */ | ||
234 | __u16 svc_ilc; /* 0x088 */ | ||
235 | __u16 svc_code; /* 0x08a */ | ||
236 | __u16 pgm_ilc; /* 0x08c */ | ||
237 | __u16 pgm_code; /* 0x08e */ | ||
238 | __u32 data_exc_code; /* 0x090 */ | ||
239 | __u16 mon_class_num; /* 0x094 */ | ||
240 | __u16 per_perc_atmid; /* 0x096 */ | ||
241 | addr_t per_address; /* 0x098 */ | ||
242 | __u8 exc_access_id; /* 0x0a0 */ | ||
243 | __u8 per_access_id; /* 0x0a1 */ | ||
244 | __u8 op_access_id; /* 0x0a2 */ | ||
245 | __u8 ar_access_id; /* 0x0a3 */ | ||
246 | __u8 pad2[0xA8-0xA4]; /* 0x0a4 */ | ||
247 | addr_t trans_exc_code; /* 0x0A0 */ | ||
248 | addr_t monitor_code; /* 0x09c */ | ||
249 | __u16 subchannel_id; /* 0x0b8 */ | ||
250 | __u16 subchannel_nr; /* 0x0ba */ | ||
251 | __u32 io_int_parm; /* 0x0bc */ | ||
252 | __u32 io_int_word; /* 0x0c0 */ | ||
253 | __u8 pad3[0xc8-0xc4]; /* 0x0c4 */ | ||
254 | __u32 stfl_fac_list; /* 0x0c8 */ | ||
255 | __u8 pad4[0xe8-0xcc]; /* 0x0cc */ | ||
256 | __u32 mcck_interruption_code[2]; /* 0x0e8 */ | ||
257 | __u8 pad5[0xf4-0xf0]; /* 0x0f0 */ | ||
258 | __u32 external_damage_code; /* 0x0f4 */ | ||
259 | addr_t failing_storage_address; /* 0x0f8 */ | ||
260 | __u8 pad6[0x120-0x100]; /* 0x100 */ | ||
261 | psw_t restart_old_psw; /* 0x120 */ | ||
262 | psw_t external_old_psw; /* 0x130 */ | ||
263 | psw_t svc_old_psw; /* 0x140 */ | ||
264 | psw_t program_old_psw; /* 0x150 */ | ||
265 | psw_t mcck_old_psw; /* 0x160 */ | ||
266 | psw_t io_old_psw; /* 0x170 */ | ||
267 | __u8 pad7[0x1a0-0x180]; /* 0x180 */ | ||
268 | psw_t restart_psw; /* 0x1a0 */ | ||
269 | psw_t external_new_psw; /* 0x1b0 */ | ||
270 | psw_t svc_new_psw; /* 0x1c0 */ | ||
271 | psw_t program_new_psw; /* 0x1d0 */ | ||
272 | psw_t mcck_new_psw; /* 0x1e0 */ | ||
273 | psw_t io_new_psw; /* 0x1f0 */ | ||
274 | psw_t return_psw; /* 0x200 */ | ||
275 | __u8 irb[64]; /* 0x210 */ | ||
276 | __u64 sync_enter_timer; /* 0x250 */ | ||
277 | __u64 async_enter_timer; /* 0x258 */ | ||
278 | __u64 exit_timer; /* 0x260 */ | ||
279 | __u64 last_update_timer; /* 0x268 */ | ||
280 | __u64 user_timer; /* 0x270 */ | ||
281 | __u64 system_timer; /* 0x278 */ | ||
282 | __u64 last_update_clock; /* 0x280 */ | ||
283 | __u64 steal_clock; /* 0x288 */ | ||
284 | __u32 diag44_opcode; /* 0x290 */ | ||
285 | __u8 pad8[0xc00-0x294]; /* 0x294 */ | ||
286 | /* System info area */ | ||
287 | __u64 save_area[16]; /* 0xc00 */ | ||
288 | __u8 pad9[0xd40-0xc80]; /* 0xc80 */ | ||
289 | __u64 kernel_stack; /* 0xd40 */ | ||
290 | __u64 thread_info; /* 0xd48 */ | ||
291 | __u64 async_stack; /* 0xd50 */ | ||
292 | __u64 kernel_asce; /* 0xd58 */ | ||
293 | __u64 user_asce; /* 0xd60 */ | ||
294 | __u64 panic_stack; /* 0xd68 */ | ||
295 | __u8 pad10[0xd80-0xd70]; /* 0xd70 */ | ||
296 | /* entry.S sensitive area start */ | ||
297 | struct cpuinfo_S390 cpu_data; /* 0xd80 */ | ||
298 | __u32 ipl_device; /* 0xdb8 */ | ||
299 | __u32 pad11; /* 0xdbc */ | ||
300 | /* entry.S sensitive area end */ | ||
301 | |||
302 | /* SMP info area: defined by DJB */ | ||
303 | __u64 jiffy_timer; /* 0xdc0 */ | ||
304 | __u64 ext_call_fast; /* 0xdc8 */ | ||
305 | __u64 percpu_offset; /* 0xdd0 */ | ||
306 | __u64 current_task; /* 0xdd8 */ | ||
307 | __u64 softirq_pending; /* 0xde0 */ | ||
308 | __u64 int_clock; /* 0xde8 */ | ||
309 | __u8 pad12[0xe00-0xdf0]; /* 0xdf0 */ | ||
310 | |||
311 | /* 0xe00 is used as indicator for dump tools */ | ||
312 | /* whether the kernel died with panic() or not */ | ||
313 | __u32 panic_magic; /* 0xe00 */ | ||
314 | |||
315 | __u8 pad13[0x1200-0xe04]; /* 0xe04 */ | ||
316 | |||
317 | /* System info area */ | ||
318 | |||
319 | __u64 floating_pt_save_area[16]; /* 0x1200 */ | ||
320 | __u64 gpregs_save_area[16]; /* 0x1280 */ | ||
321 | __u32 st_status_fixed_logout[4]; /* 0x1300 */ | ||
322 | __u8 pad14[0x1318-0x1310]; /* 0x1310 */ | ||
323 | __u32 prefixreg_save_area; /* 0x1318 */ | ||
324 | __u32 fpt_creg_save_area; /* 0x131c */ | ||
325 | __u8 pad15[0x1324-0x1320]; /* 0x1320 */ | ||
326 | __u32 tod_progreg_save_area; /* 0x1324 */ | ||
327 | __u32 cpu_timer_save_area[2]; /* 0x1328 */ | ||
328 | __u32 clock_comp_save_area[2]; /* 0x1330 */ | ||
329 | __u8 pad16[0x1340-0x1338]; /* 0x1338 */ | ||
330 | __u32 access_regs_save_area[16]; /* 0x1340 */ | ||
331 | __u64 cregs_save_area[16]; /* 0x1380 */ | ||
332 | |||
333 | /* align to the top of the prefix area */ | ||
334 | |||
335 | __u8 pad17[0x2000-0x1400]; /* 0x1400 */ | ||
336 | #endif /* !__s390x__ */ | ||
337 | } __attribute__((packed)); /* End structure*/ | ||
338 | |||
339 | #define S390_lowcore (*((struct _lowcore *) 0)) | ||
340 | extern struct _lowcore *lowcore_ptr[]; | ||
341 | |||
342 | extern __inline__ void set_prefix(__u32 address) | ||
343 | { | ||
344 | __asm__ __volatile__ ("spx %0" : : "m" (address) : "memory" ); | ||
345 | } | ||
346 | |||
347 | #define __PANIC_MAGIC 0xDEADC0DE | ||
348 | |||
349 | #endif | ||
350 | |||
351 | #endif | ||
diff --git a/include/asm-s390/mathemu.h b/include/asm-s390/mathemu.h new file mode 100644 index 000000000000..e8dd1ba8edb0 --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/mman.h b/include/asm-s390/mman.h new file mode 100644 index 000000000000..ea86bd12204f --- /dev/null +++ b/include/asm-s390/mman.h | |||
@@ -0,0 +1,51 @@ | |||
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 | #define PROT_READ 0x1 /* page can be read */ | ||
13 | #define PROT_WRITE 0x2 /* page can be written */ | ||
14 | #define PROT_EXEC 0x4 /* page can be executed */ | ||
15 | #define PROT_SEM 0x8 /* page may be used for atomic ops */ | ||
16 | #define PROT_NONE 0x0 /* page can not be accessed */ | ||
17 | #define PROT_GROWSDOWN 0x01000000 /* mprotect flag: extend change to start of growsdown vma */ | ||
18 | #define PROT_GROWSUP 0x02000000 /* mprotect flag: extend change to end of growsup vma */ | ||
19 | |||
20 | #define MAP_SHARED 0x01 /* Share changes */ | ||
21 | #define MAP_PRIVATE 0x02 /* Changes are private */ | ||
22 | #define MAP_TYPE 0x0f /* Mask for type of mapping */ | ||
23 | #define MAP_FIXED 0x10 /* Interpret addr exactly */ | ||
24 | #define MAP_ANONYMOUS 0x20 /* don't use a file */ | ||
25 | |||
26 | #define MAP_GROWSDOWN 0x0100 /* stack-like segment */ | ||
27 | #define MAP_DENYWRITE 0x0800 /* ETXTBSY */ | ||
28 | #define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ | ||
29 | #define MAP_LOCKED 0x2000 /* pages are locked */ | ||
30 | #define MAP_NORESERVE 0x4000 /* don't check for reservations */ | ||
31 | #define MAP_POPULATE 0x8000 /* populate (prefault) pagetables */ | ||
32 | #define MAP_NONBLOCK 0x10000 /* do not block on IO */ | ||
33 | |||
34 | #define MS_ASYNC 1 /* sync memory asynchronously */ | ||
35 | #define MS_INVALIDATE 2 /* invalidate the caches */ | ||
36 | #define MS_SYNC 4 /* synchronous memory sync */ | ||
37 | |||
38 | #define MCL_CURRENT 1 /* lock all current mappings */ | ||
39 | #define MCL_FUTURE 2 /* lock all future mappings */ | ||
40 | |||
41 | #define MADV_NORMAL 0x0 /* default page-in behavior */ | ||
42 | #define MADV_RANDOM 0x1 /* page-in minimum required */ | ||
43 | #define MADV_SEQUENTIAL 0x2 /* read-ahead aggressively */ | ||
44 | #define MADV_WILLNEED 0x3 /* pre-fault pages */ | ||
45 | #define MADV_DONTNEED 0x4 /* discard these pages */ | ||
46 | |||
47 | /* compatibility flags */ | ||
48 | #define MAP_ANON MAP_ANONYMOUS | ||
49 | #define MAP_FILE 0 | ||
50 | |||
51 | #endif /* __S390_MMAN_H__ */ | ||
diff --git a/include/asm-s390/mmu.h b/include/asm-s390/mmu.h new file mode 100644 index 000000000000..ccd36d26615a --- /dev/null +++ b/include/asm-s390/mmu.h | |||
@@ -0,0 +1,7 @@ | |||
1 | #ifndef __MMU_H | ||
2 | #define __MMU_H | ||
3 | |||
4 | /* Default "unsigned long" context */ | ||
5 | typedef unsigned long mm_context_t; | ||
6 | |||
7 | #endif | ||
diff --git a/include/asm-s390/mmu_context.h b/include/asm-s390/mmu_context.h new file mode 100644 index 000000000000..3a3bb3f2dad5 --- /dev/null +++ b/include/asm-s390/mmu_context.h | |||
@@ -0,0 +1,54 @@ | |||
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 | /* | ||
13 | * get a new mmu context.. S390 don't know about contexts. | ||
14 | */ | ||
15 | #define init_new_context(tsk,mm) 0 | ||
16 | |||
17 | #define destroy_context(mm) do { } while (0) | ||
18 | |||
19 | static inline void enter_lazy_tlb(struct mm_struct *mm, | ||
20 | struct task_struct *tsk) | ||
21 | { | ||
22 | } | ||
23 | |||
24 | static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, | ||
25 | struct task_struct *tsk) | ||
26 | { | ||
27 | if (prev != next) { | ||
28 | #ifndef __s390x__ | ||
29 | S390_lowcore.user_asce = (__pa(next->pgd)&PAGE_MASK) | | ||
30 | (_SEGMENT_TABLE|USER_STD_MASK); | ||
31 | /* Load home space page table origin. */ | ||
32 | asm volatile("lctl 13,13,%0" | ||
33 | : : "m" (S390_lowcore.user_asce) ); | ||
34 | #else /* __s390x__ */ | ||
35 | S390_lowcore.user_asce = (__pa(next->pgd) & PAGE_MASK) | | ||
36 | (_REGION_TABLE|USER_STD_MASK); | ||
37 | /* Load home space page table origin. */ | ||
38 | asm volatile("lctlg 13,13,%0" | ||
39 | : : "m" (S390_lowcore.user_asce) ); | ||
40 | #endif /* __s390x__ */ | ||
41 | } | ||
42 | cpu_set(smp_processor_id(), next->cpu_vm_mask); | ||
43 | } | ||
44 | |||
45 | #define deactivate_mm(tsk,mm) do { } while (0) | ||
46 | |||
47 | extern inline void activate_mm(struct mm_struct *prev, | ||
48 | struct mm_struct *next) | ||
49 | { | ||
50 | switch_mm(prev, next, current); | ||
51 | set_fs(current->thread.mm_segment); | ||
52 | } | ||
53 | |||
54 | #endif | ||
diff --git a/include/asm-s390/module.h b/include/asm-s390/module.h new file mode 100644 index 000000000000..1cc1c5af705a --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/msgbuf.h b/include/asm-s390/msgbuf.h new file mode 100644 index 000000000000..1bbdee927924 --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/namei.h b/include/asm-s390/namei.h new file mode 100644 index 000000000000..3e286bdde4b0 --- /dev/null +++ b/include/asm-s390/namei.h | |||
@@ -0,0 +1,21 @@ | |||
1 | /* | ||
2 | * include/asm-s390/namei.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/namei.h" | ||
7 | * | ||
8 | * Included from linux/fs/namei.c | ||
9 | */ | ||
10 | |||
11 | #ifndef __S390_NAMEI_H | ||
12 | #define __S390_NAMEI_H | ||
13 | |||
14 | /* This dummy routine maybe changed to something useful | ||
15 | * for /usr/gnemul/ emulation stuff. | ||
16 | * Look at asm-sparc/namei.h for details. | ||
17 | */ | ||
18 | |||
19 | #define __emul_prefix() NULL | ||
20 | |||
21 | #endif /* __S390_NAMEI_H */ | ||
diff --git a/include/asm-s390/page.h b/include/asm-s390/page.h new file mode 100644 index 000000000000..614e2a93c703 --- /dev/null +++ b/include/asm-s390/page.h | |||
@@ -0,0 +1,208 @@ | |||
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 <asm/setup.h> | ||
13 | #include <asm/types.h> | ||
14 | |||
15 | /* PAGE_SHIFT determines the page size */ | ||
16 | #define PAGE_SHIFT 12 | ||
17 | #define PAGE_SIZE (1UL << PAGE_SHIFT) | ||
18 | #define PAGE_MASK (~(PAGE_SIZE-1)) | ||
19 | |||
20 | #ifdef __KERNEL__ | ||
21 | #ifndef __ASSEMBLY__ | ||
22 | |||
23 | #ifndef __s390x__ | ||
24 | |||
25 | static inline void clear_page(void *page) | ||
26 | { | ||
27 | register_pair rp; | ||
28 | |||
29 | rp.subreg.even = (unsigned long) page; | ||
30 | rp.subreg.odd = (unsigned long) 4096; | ||
31 | asm volatile (" slr 1,1\n" | ||
32 | " mvcl %0,0" | ||
33 | : "+&a" (rp) : : "memory", "cc", "1" ); | ||
34 | } | ||
35 | |||
36 | static inline void copy_page(void *to, void *from) | ||
37 | { | ||
38 | if (MACHINE_HAS_MVPG) | ||
39 | asm volatile (" sr 0,0\n" | ||
40 | " mvpg %0,%1" | ||
41 | : : "a" ((void *)(to)), "a" ((void *)(from)) | ||
42 | : "memory", "cc", "0" ); | ||
43 | else | ||
44 | asm volatile (" mvc 0(256,%0),0(%1)\n" | ||
45 | " mvc 256(256,%0),256(%1)\n" | ||
46 | " mvc 512(256,%0),512(%1)\n" | ||
47 | " mvc 768(256,%0),768(%1)\n" | ||
48 | " mvc 1024(256,%0),1024(%1)\n" | ||
49 | " mvc 1280(256,%0),1280(%1)\n" | ||
50 | " mvc 1536(256,%0),1536(%1)\n" | ||
51 | " mvc 1792(256,%0),1792(%1)\n" | ||
52 | " mvc 2048(256,%0),2048(%1)\n" | ||
53 | " mvc 2304(256,%0),2304(%1)\n" | ||
54 | " mvc 2560(256,%0),2560(%1)\n" | ||
55 | " mvc 2816(256,%0),2816(%1)\n" | ||
56 | " mvc 3072(256,%0),3072(%1)\n" | ||
57 | " mvc 3328(256,%0),3328(%1)\n" | ||
58 | " mvc 3584(256,%0),3584(%1)\n" | ||
59 | " mvc 3840(256,%0),3840(%1)\n" | ||
60 | : : "a"((void *)(to)),"a"((void *)(from)) | ||
61 | : "memory" ); | ||
62 | } | ||
63 | |||
64 | #else /* __s390x__ */ | ||
65 | |||
66 | static inline void clear_page(void *page) | ||
67 | { | ||
68 | asm volatile (" lgr 2,%0\n" | ||
69 | " lghi 3,4096\n" | ||
70 | " slgr 1,1\n" | ||
71 | " mvcl 2,0" | ||
72 | : : "a" ((void *) (page)) | ||
73 | : "memory", "cc", "1", "2", "3" ); | ||
74 | } | ||
75 | |||
76 | static inline void copy_page(void *to, void *from) | ||
77 | { | ||
78 | if (MACHINE_HAS_MVPG) | ||
79 | asm volatile (" sgr 0,0\n" | ||
80 | " mvpg %0,%1" | ||
81 | : : "a" ((void *)(to)), "a" ((void *)(from)) | ||
82 | : "memory", "cc", "0" ); | ||
83 | else | ||
84 | asm volatile (" mvc 0(256,%0),0(%1)\n" | ||
85 | " mvc 256(256,%0),256(%1)\n" | ||
86 | " mvc 512(256,%0),512(%1)\n" | ||
87 | " mvc 768(256,%0),768(%1)\n" | ||
88 | " mvc 1024(256,%0),1024(%1)\n" | ||
89 | " mvc 1280(256,%0),1280(%1)\n" | ||
90 | " mvc 1536(256,%0),1536(%1)\n" | ||
91 | " mvc 1792(256,%0),1792(%1)\n" | ||
92 | " mvc 2048(256,%0),2048(%1)\n" | ||
93 | " mvc 2304(256,%0),2304(%1)\n" | ||
94 | " mvc 2560(256,%0),2560(%1)\n" | ||
95 | " mvc 2816(256,%0),2816(%1)\n" | ||
96 | " mvc 3072(256,%0),3072(%1)\n" | ||
97 | " mvc 3328(256,%0),3328(%1)\n" | ||
98 | " mvc 3584(256,%0),3584(%1)\n" | ||
99 | " mvc 3840(256,%0),3840(%1)\n" | ||
100 | : : "a"((void *)(to)),"a"((void *)(from)) | ||
101 | : "memory" ); | ||
102 | } | ||
103 | |||
104 | #endif /* __s390x__ */ | ||
105 | |||
106 | #define clear_user_page(page, vaddr, pg) clear_page(page) | ||
107 | #define copy_user_page(to, from, vaddr, pg) copy_page(to, from) | ||
108 | |||
109 | #define alloc_zeroed_user_highpage(vma, vaddr) alloc_page_vma(GFP_HIGHUSER | __GFP_ZERO, vma, vaddr) | ||
110 | #define __HAVE_ARCH_ALLOC_ZEROED_USER_HIGHPAGE | ||
111 | |||
112 | /* Pure 2^n version of get_order */ | ||
113 | extern __inline__ int get_order(unsigned long size) | ||
114 | { | ||
115 | int order; | ||
116 | |||
117 | size = (size-1) >> (PAGE_SHIFT-1); | ||
118 | order = -1; | ||
119 | do { | ||
120 | size >>= 1; | ||
121 | order++; | ||
122 | } while (size); | ||
123 | return order; | ||
124 | } | ||
125 | |||
126 | /* | ||
127 | * These are used to make use of C type-checking.. | ||
128 | */ | ||
129 | |||
130 | typedef struct { unsigned long pgprot; } pgprot_t; | ||
131 | typedef struct { unsigned long pte; } pte_t; | ||
132 | |||
133 | #define pte_val(x) ((x).pte) | ||
134 | #define pgprot_val(x) ((x).pgprot) | ||
135 | |||
136 | #ifndef __s390x__ | ||
137 | |||
138 | typedef struct { unsigned long pmd; } pmd_t; | ||
139 | typedef struct { | ||
140 | unsigned long pgd0; | ||
141 | unsigned long pgd1; | ||
142 | unsigned long pgd2; | ||
143 | unsigned long pgd3; | ||
144 | } pgd_t; | ||
145 | |||
146 | #define pmd_val(x) ((x).pmd) | ||
147 | #define pgd_val(x) ((x).pgd0) | ||
148 | |||
149 | #else /* __s390x__ */ | ||
150 | |||
151 | typedef struct { | ||
152 | unsigned long pmd0; | ||
153 | unsigned long pmd1; | ||
154 | } pmd_t; | ||
155 | typedef struct { unsigned long pgd; } pgd_t; | ||
156 | |||
157 | #define pmd_val(x) ((x).pmd0) | ||
158 | #define pmd_val1(x) ((x).pmd1) | ||
159 | #define pgd_val(x) ((x).pgd) | ||
160 | |||
161 | #endif /* __s390x__ */ | ||
162 | |||
163 | #define __pte(x) ((pte_t) { (x) } ) | ||
164 | #define __pmd(x) ((pmd_t) { (x) } ) | ||
165 | #define __pgd(x) ((pgd_t) { (x) } ) | ||
166 | #define __pgprot(x) ((pgprot_t) { (x) } ) | ||
167 | |||
168 | /* default storage key used for all pages */ | ||
169 | extern unsigned int default_storage_key; | ||
170 | |||
171 | static inline void | ||
172 | page_set_storage_key(unsigned long addr, unsigned int skey) | ||
173 | { | ||
174 | asm volatile ( "sske %0,%1" : : "d" (skey), "a" (addr) ); | ||
175 | } | ||
176 | |||
177 | static inline unsigned int | ||
178 | page_get_storage_key(unsigned long addr) | ||
179 | { | ||
180 | unsigned int skey; | ||
181 | |||
182 | asm volatile ( "iske %0,%1" : "=d" (skey) : "a" (addr), "0" (0) ); | ||
183 | |||
184 | return skey; | ||
185 | } | ||
186 | |||
187 | #endif /* !__ASSEMBLY__ */ | ||
188 | |||
189 | /* to align the pointer to the (next) page boundary */ | ||
190 | #define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) | ||
191 | |||
192 | #define __PAGE_OFFSET 0x0UL | ||
193 | #define PAGE_OFFSET 0x0UL | ||
194 | #define __pa(x) (unsigned long)(x) | ||
195 | #define __va(x) (void *)(unsigned long)(x) | ||
196 | #define pfn_to_page(pfn) (mem_map + (pfn)) | ||
197 | #define page_to_pfn(page) ((unsigned long)((page) - mem_map)) | ||
198 | #define virt_to_page(kaddr) pfn_to_page(__pa(kaddr) >> PAGE_SHIFT) | ||
199 | |||
200 | #define pfn_valid(pfn) ((pfn) < max_mapnr) | ||
201 | #define virt_addr_valid(kaddr) pfn_valid(__pa(kaddr) >> PAGE_SHIFT) | ||
202 | |||
203 | #define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ | ||
204 | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) | ||
205 | |||
206 | #endif /* __KERNEL__ */ | ||
207 | |||
208 | #endif /* _S390_PAGE_H */ | ||
diff --git a/include/asm-s390/param.h b/include/asm-s390/param.h new file mode 100644 index 000000000000..085a7e229b23 --- /dev/null +++ b/include/asm-s390/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 100 /* 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/include/asm-s390/pci.h b/include/asm-s390/pci.h new file mode 100644 index 000000000000..42a145c9ddd6 --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/percpu.h b/include/asm-s390/percpu.h new file mode 100644 index 000000000000..123fcaca295e --- /dev/null +++ b/include/asm-s390/percpu.h | |||
@@ -0,0 +1,70 @@ | |||
1 | #ifndef __ARCH_S390_PERCPU__ | ||
2 | #define __ARCH_S390_PERCPU__ | ||
3 | |||
4 | #include <linux/compiler.h> | ||
5 | #include <asm/lowcore.h> | ||
6 | |||
7 | #define __GENERIC_PER_CPU | ||
8 | |||
9 | /* | ||
10 | * s390 uses its own implementation for per cpu data, the offset of | ||
11 | * the cpu local data area is cached in the cpu's lowcore memory. | ||
12 | * For 64 bit module code s390 forces the use of a GOT slot for the | ||
13 | * address of the per cpu variable. This is needed because the module | ||
14 | * may be more than 4G above the per cpu area. | ||
15 | */ | ||
16 | #if defined(__s390x__) && defined(MODULE) | ||
17 | |||
18 | #define __reloc_hide(var,offset) \ | ||
19 | (*({ unsigned long *__ptr; \ | ||
20 | asm ( "larl %0,per_cpu__"#var"@GOTENT" \ | ||
21 | : "=a" (__ptr) : "X" (per_cpu__##var) ); \ | ||
22 | (typeof(&per_cpu__##var))((*__ptr) + (offset)); })) | ||
23 | |||
24 | #else | ||
25 | |||
26 | #define __reloc_hide(var, offset) \ | ||
27 | (*({ unsigned long __ptr; \ | ||
28 | asm ( "" : "=a" (__ptr) : "0" (&per_cpu__##var) ); \ | ||
29 | (typeof(&per_cpu__##var)) (__ptr + (offset)); })) | ||
30 | |||
31 | #endif | ||
32 | |||
33 | #ifdef CONFIG_SMP | ||
34 | |||
35 | extern unsigned long __per_cpu_offset[NR_CPUS]; | ||
36 | |||
37 | /* Separate out the type, so (int[3], foo) works. */ | ||
38 | #define DEFINE_PER_CPU(type, name) \ | ||
39 | __attribute__((__section__(".data.percpu"))) \ | ||
40 | __typeof__(type) per_cpu__##name | ||
41 | |||
42 | #define __get_cpu_var(var) __reloc_hide(var,S390_lowcore.percpu_offset) | ||
43 | #define per_cpu(var,cpu) __reloc_hide(var,__per_cpu_offset[cpu]) | ||
44 | |||
45 | /* A macro to avoid #include hell... */ | ||
46 | #define percpu_modcopy(pcpudst, src, size) \ | ||
47 | do { \ | ||
48 | unsigned int __i; \ | ||
49 | for (__i = 0; __i < NR_CPUS; __i++) \ | ||
50 | if (cpu_possible(__i)) \ | ||
51 | memcpy((pcpudst)+__per_cpu_offset[__i], \ | ||
52 | (src), (size)); \ | ||
53 | } while (0) | ||
54 | |||
55 | #else /* ! SMP */ | ||
56 | |||
57 | #define DEFINE_PER_CPU(type, name) \ | ||
58 | __typeof__(type) per_cpu__##name | ||
59 | |||
60 | #define __get_cpu_var(var) __reloc_hide(var,0) | ||
61 | #define per_cpu(var,cpu) __reloc_hide(var,0) | ||
62 | |||
63 | #endif /* SMP */ | ||
64 | |||
65 | #define DECLARE_PER_CPU(type, name) extern __typeof__(type) per_cpu__##name | ||
66 | |||
67 | #define EXPORT_PER_CPU_SYMBOL(var) EXPORT_SYMBOL(per_cpu__##var) | ||
68 | #define EXPORT_PER_CPU_SYMBOL_GPL(var) EXPORT_SYMBOL_GPL(per_cpu__##var) | ||
69 | |||
70 | #endif /* __ARCH_S390_PERCPU__ */ | ||
diff --git a/include/asm-s390/pgalloc.h b/include/asm-s390/pgalloc.h new file mode 100644 index 000000000000..3417dd71ab43 --- /dev/null +++ b/include/asm-s390/pgalloc.h | |||
@@ -0,0 +1,168 @@ | |||
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/config.h> | ||
17 | #include <linux/threads.h> | ||
18 | #include <linux/gfp.h> | ||
19 | #include <linux/mm.h> | ||
20 | |||
21 | #define check_pgt_cache() do {} while (0) | ||
22 | |||
23 | extern void diag10(unsigned long addr); | ||
24 | |||
25 | /* | ||
26 | * Allocate and free page tables. The xxx_kernel() versions are | ||
27 | * used to allocate a kernel page table - this turns on ASN bits | ||
28 | * if any. | ||
29 | */ | ||
30 | |||
31 | static inline pgd_t *pgd_alloc(struct mm_struct *mm) | ||
32 | { | ||
33 | pgd_t *pgd; | ||
34 | int i; | ||
35 | |||
36 | #ifndef __s390x__ | ||
37 | pgd = (pgd_t *) __get_free_pages(GFP_KERNEL,1); | ||
38 | if (pgd != NULL) | ||
39 | for (i = 0; i < USER_PTRS_PER_PGD; i++) | ||
40 | pmd_clear(pmd_offset(pgd + i, i*PGDIR_SIZE)); | ||
41 | #else /* __s390x__ */ | ||
42 | pgd = (pgd_t *) __get_free_pages(GFP_KERNEL,2); | ||
43 | if (pgd != NULL) | ||
44 | for (i = 0; i < PTRS_PER_PGD; i++) | ||
45 | pgd_clear(pgd + i); | ||
46 | #endif /* __s390x__ */ | ||
47 | return pgd; | ||
48 | } | ||
49 | |||
50 | static inline void pgd_free(pgd_t *pgd) | ||
51 | { | ||
52 | #ifndef __s390x__ | ||
53 | free_pages((unsigned long) pgd, 1); | ||
54 | #else /* __s390x__ */ | ||
55 | free_pages((unsigned long) pgd, 2); | ||
56 | #endif /* __s390x__ */ | ||
57 | } | ||
58 | |||
59 | #ifndef __s390x__ | ||
60 | /* | ||
61 | * page middle directory allocation/free routines. | ||
62 | * We use pmd cache only on s390x, so these are dummy routines. This | ||
63 | * code never triggers because the pgd will always be present. | ||
64 | */ | ||
65 | #define pmd_alloc_one(mm,address) ({ BUG(); ((pmd_t *)2); }) | ||
66 | #define pmd_free(x) do { } while (0) | ||
67 | #define __pmd_free_tlb(tlb,x) do { } while (0) | ||
68 | #define pgd_populate(mm, pmd, pte) BUG() | ||
69 | #else /* __s390x__ */ | ||
70 | static inline pmd_t * pmd_alloc_one(struct mm_struct *mm, unsigned long vmaddr) | ||
71 | { | ||
72 | pmd_t *pmd; | ||
73 | int i; | ||
74 | |||
75 | pmd = (pmd_t *) __get_free_pages(GFP_KERNEL, 2); | ||
76 | if (pmd != NULL) { | ||
77 | for (i=0; i < PTRS_PER_PMD; i++) | ||
78 | pmd_clear(pmd+i); | ||
79 | } | ||
80 | return pmd; | ||
81 | } | ||
82 | |||
83 | static inline void pmd_free (pmd_t *pmd) | ||
84 | { | ||
85 | free_pages((unsigned long) pmd, 2); | ||
86 | } | ||
87 | |||
88 | #define __pmd_free_tlb(tlb,pmd) \ | ||
89 | do { \ | ||
90 | tlb_flush_mmu(tlb, 0, 0); \ | ||
91 | pmd_free(pmd); \ | ||
92 | } while (0) | ||
93 | |||
94 | static inline void pgd_populate(struct mm_struct *mm, pgd_t *pgd, pmd_t *pmd) | ||
95 | { | ||
96 | pgd_val(*pgd) = _PGD_ENTRY | __pa(pmd); | ||
97 | } | ||
98 | |||
99 | #endif /* __s390x__ */ | ||
100 | |||
101 | static inline void | ||
102 | pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmd, pte_t *pte) | ||
103 | { | ||
104 | #ifndef __s390x__ | ||
105 | pmd_val(pmd[0]) = _PAGE_TABLE + __pa(pte); | ||
106 | pmd_val(pmd[1]) = _PAGE_TABLE + __pa(pte+256); | ||
107 | pmd_val(pmd[2]) = _PAGE_TABLE + __pa(pte+512); | ||
108 | pmd_val(pmd[3]) = _PAGE_TABLE + __pa(pte+768); | ||
109 | #else /* __s390x__ */ | ||
110 | pmd_val(*pmd) = _PMD_ENTRY + __pa(pte); | ||
111 | pmd_val1(*pmd) = _PMD_ENTRY + __pa(pte+256); | ||
112 | #endif /* __s390x__ */ | ||
113 | } | ||
114 | |||
115 | static inline void | ||
116 | pmd_populate(struct mm_struct *mm, pmd_t *pmd, struct page *page) | ||
117 | { | ||
118 | pmd_populate_kernel(mm, pmd, (pte_t *)((page-mem_map) << PAGE_SHIFT)); | ||
119 | } | ||
120 | |||
121 | /* | ||
122 | * page table entry allocation/free routines. | ||
123 | */ | ||
124 | static inline pte_t * | ||
125 | pte_alloc_one_kernel(struct mm_struct *mm, unsigned long vmaddr) | ||
126 | { | ||
127 | pte_t *pte; | ||
128 | int i; | ||
129 | |||
130 | pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT); | ||
131 | if (pte != NULL) { | ||
132 | for (i=0; i < PTRS_PER_PTE; i++) { | ||
133 | pte_clear(mm, vmaddr, pte+i); | ||
134 | vmaddr += PAGE_SIZE; | ||
135 | } | ||
136 | } | ||
137 | return pte; | ||
138 | } | ||
139 | |||
140 | static inline struct page * | ||
141 | pte_alloc_one(struct mm_struct *mm, unsigned long vmaddr) | ||
142 | { | ||
143 | pte_t *pte = pte_alloc_one_kernel(mm, vmaddr); | ||
144 | if (pte) | ||
145 | return virt_to_page(pte); | ||
146 | return 0; | ||
147 | } | ||
148 | |||
149 | static inline void pte_free_kernel(pte_t *pte) | ||
150 | { | ||
151 | free_page((unsigned long) pte); | ||
152 | } | ||
153 | |||
154 | static inline void pte_free(struct page *pte) | ||
155 | { | ||
156 | __free_page(pte); | ||
157 | } | ||
158 | |||
159 | #define __pte_free_tlb(tlb,pte) tlb_remove_page(tlb,pte) | ||
160 | |||
161 | /* | ||
162 | * This establishes kernel virtual mappings (e.g., as a result of a | ||
163 | * vmalloc call). Since s390-esame uses a separate kernel page table, | ||
164 | * there is nothing to do here... :) | ||
165 | */ | ||
166 | #define set_pgdir(addr,entry) do { } while(0) | ||
167 | |||
168 | #endif /* _S390_PGALLOC_H */ | ||
diff --git a/include/asm-s390/pgtable.h b/include/asm-s390/pgtable.h new file mode 100644 index 000000000000..1633cb75f057 --- /dev/null +++ b/include/asm-s390/pgtable.h | |||
@@ -0,0 +1,813 @@ | |||
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 | #include <asm-generic/4level-fixup.h> | ||
17 | |||
18 | /* | ||
19 | * The Linux memory management assumes a three-level page table setup. For | ||
20 | * s390 31 bit we "fold" the mid level into the top-level page table, so | ||
21 | * that we physically have the same two-level page table as the s390 mmu | ||
22 | * expects in 31 bit mode. For s390 64 bit we use three of the five levels | ||
23 | * the hardware provides (region first and region second tables are not | ||
24 | * used). | ||
25 | * | ||
26 | * The "pgd_xxx()" functions are trivial for a folded two-level | ||
27 | * setup: the pgd is never bad, and a pmd always exists (as it's folded | ||
28 | * into the pgd entry) | ||
29 | * | ||
30 | * This file contains the functions and defines necessary to modify and use | ||
31 | * the S390 page table tree. | ||
32 | */ | ||
33 | #ifndef __ASSEMBLY__ | ||
34 | #include <asm/bug.h> | ||
35 | #include <asm/processor.h> | ||
36 | #include <linux/threads.h> | ||
37 | |||
38 | struct vm_area_struct; /* forward declaration (include/linux/mm.h) */ | ||
39 | |||
40 | extern pgd_t swapper_pg_dir[] __attribute__ ((aligned (4096))); | ||
41 | extern void paging_init(void); | ||
42 | |||
43 | /* | ||
44 | * The S390 doesn't have any external MMU info: the kernel page | ||
45 | * tables contain all the necessary information. | ||
46 | */ | ||
47 | #define update_mmu_cache(vma, address, pte) do { } while (0) | ||
48 | |||
49 | /* | ||
50 | * ZERO_PAGE is a global shared page that is always zero: used | ||
51 | * for zero-mapped memory areas etc.. | ||
52 | */ | ||
53 | extern char empty_zero_page[PAGE_SIZE]; | ||
54 | #define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page)) | ||
55 | #endif /* !__ASSEMBLY__ */ | ||
56 | |||
57 | /* | ||
58 | * PMD_SHIFT determines the size of the area a second-level page | ||
59 | * table can map | ||
60 | * PGDIR_SHIFT determines what a third-level page table entry can map | ||
61 | */ | ||
62 | #ifndef __s390x__ | ||
63 | # define PMD_SHIFT 22 | ||
64 | # define PGDIR_SHIFT 22 | ||
65 | #else /* __s390x__ */ | ||
66 | # define PMD_SHIFT 21 | ||
67 | # define PGDIR_SHIFT 31 | ||
68 | #endif /* __s390x__ */ | ||
69 | |||
70 | #define PMD_SIZE (1UL << PMD_SHIFT) | ||
71 | #define PMD_MASK (~(PMD_SIZE-1)) | ||
72 | #define PGDIR_SIZE (1UL << PGDIR_SHIFT) | ||
73 | #define PGDIR_MASK (~(PGDIR_SIZE-1)) | ||
74 | |||
75 | /* | ||
76 | * entries per page directory level: the S390 is two-level, so | ||
77 | * we don't really have any PMD directory physically. | ||
78 | * for S390 segment-table entries are combined to one PGD | ||
79 | * that leads to 1024 pte per pgd | ||
80 | */ | ||
81 | #ifndef __s390x__ | ||
82 | # define PTRS_PER_PTE 1024 | ||
83 | # define PTRS_PER_PMD 1 | ||
84 | # define PTRS_PER_PGD 512 | ||
85 | #else /* __s390x__ */ | ||
86 | # define PTRS_PER_PTE 512 | ||
87 | # define PTRS_PER_PMD 1024 | ||
88 | # define PTRS_PER_PGD 2048 | ||
89 | #endif /* __s390x__ */ | ||
90 | |||
91 | /* | ||
92 | * pgd entries used up by user/kernel: | ||
93 | */ | ||
94 | #ifndef __s390x__ | ||
95 | # define USER_PTRS_PER_PGD 512 | ||
96 | # define USER_PGD_PTRS 512 | ||
97 | # define KERNEL_PGD_PTRS 512 | ||
98 | # define FIRST_USER_PGD_NR 0 | ||
99 | #else /* __s390x__ */ | ||
100 | # define USER_PTRS_PER_PGD 2048 | ||
101 | # define USER_PGD_PTRS 2048 | ||
102 | # define KERNEL_PGD_PTRS 2048 | ||
103 | # define FIRST_USER_PGD_NR 0 | ||
104 | #endif /* __s390x__ */ | ||
105 | |||
106 | #define pte_ERROR(e) \ | ||
107 | printk("%s:%d: bad pte %p.\n", __FILE__, __LINE__, (void *) pte_val(e)) | ||
108 | #define pmd_ERROR(e) \ | ||
109 | printk("%s:%d: bad pmd %p.\n", __FILE__, __LINE__, (void *) pmd_val(e)) | ||
110 | #define pgd_ERROR(e) \ | ||
111 | printk("%s:%d: bad pgd %p.\n", __FILE__, __LINE__, (void *) pgd_val(e)) | ||
112 | |||
113 | #ifndef __ASSEMBLY__ | ||
114 | /* | ||
115 | * Just any arbitrary offset to the start of the vmalloc VM area: the | ||
116 | * current 8MB value just means that there will be a 8MB "hole" after the | ||
117 | * physical memory until the kernel virtual memory starts. That means that | ||
118 | * any out-of-bounds memory accesses will hopefully be caught. | ||
119 | * The vmalloc() routines leaves a hole of 4kB between each vmalloced | ||
120 | * area for the same reason. ;) | ||
121 | */ | ||
122 | #define VMALLOC_OFFSET (8*1024*1024) | ||
123 | #define VMALLOC_START (((unsigned long) high_memory + VMALLOC_OFFSET) \ | ||
124 | & ~(VMALLOC_OFFSET-1)) | ||
125 | #ifndef __s390x__ | ||
126 | # define VMALLOC_END (0x7fffffffL) | ||
127 | #else /* __s390x__ */ | ||
128 | # define VMALLOC_END (0x40000000000L) | ||
129 | #endif /* __s390x__ */ | ||
130 | |||
131 | |||
132 | /* | ||
133 | * A 31 bit pagetable entry of S390 has following format: | ||
134 | * | PFRA | | OS | | ||
135 | * 0 0IP0 | ||
136 | * 00000000001111111111222222222233 | ||
137 | * 01234567890123456789012345678901 | ||
138 | * | ||
139 | * I Page-Invalid Bit: Page is not available for address-translation | ||
140 | * P Page-Protection Bit: Store access not possible for page | ||
141 | * | ||
142 | * A 31 bit segmenttable entry of S390 has following format: | ||
143 | * | P-table origin | |PTL | ||
144 | * 0 IC | ||
145 | * 00000000001111111111222222222233 | ||
146 | * 01234567890123456789012345678901 | ||
147 | * | ||
148 | * I Segment-Invalid Bit: Segment is not available for address-translation | ||
149 | * C Common-Segment Bit: Segment is not private (PoP 3-30) | ||
150 | * PTL Page-Table-Length: Page-table length (PTL+1*16 entries -> up to 256) | ||
151 | * | ||
152 | * The 31 bit segmenttable origin of S390 has following format: | ||
153 | * | ||
154 | * |S-table origin | | STL | | ||
155 | * X **GPS | ||
156 | * 00000000001111111111222222222233 | ||
157 | * 01234567890123456789012345678901 | ||
158 | * | ||
159 | * X Space-Switch event: | ||
160 | * G Segment-Invalid Bit: * | ||
161 | * P Private-Space Bit: Segment is not private (PoP 3-30) | ||
162 | * S Storage-Alteration: | ||
163 | * STL Segment-Table-Length: Segment-table length (STL+1*16 entries -> up to 2048) | ||
164 | * | ||
165 | * A 64 bit pagetable entry of S390 has following format: | ||
166 | * | PFRA |0IP0| OS | | ||
167 | * 0000000000111111111122222222223333333333444444444455555555556666 | ||
168 | * 0123456789012345678901234567890123456789012345678901234567890123 | ||
169 | * | ||
170 | * I Page-Invalid Bit: Page is not available for address-translation | ||
171 | * P Page-Protection Bit: Store access not possible for page | ||
172 | * | ||
173 | * A 64 bit segmenttable entry of S390 has following format: | ||
174 | * | P-table origin | TT | ||
175 | * 0000000000111111111122222222223333333333444444444455555555556666 | ||
176 | * 0123456789012345678901234567890123456789012345678901234567890123 | ||
177 | * | ||
178 | * I Segment-Invalid Bit: Segment is not available for address-translation | ||
179 | * C Common-Segment Bit: Segment is not private (PoP 3-30) | ||
180 | * P Page-Protection Bit: Store access not possible for page | ||
181 | * TT Type 00 | ||
182 | * | ||
183 | * A 64 bit region table entry of S390 has following format: | ||
184 | * | S-table origin | TF TTTL | ||
185 | * 0000000000111111111122222222223333333333444444444455555555556666 | ||
186 | * 0123456789012345678901234567890123456789012345678901234567890123 | ||
187 | * | ||
188 | * I Segment-Invalid Bit: Segment is not available for address-translation | ||
189 | * TT Type 01 | ||
190 | * TF | ||
191 | * TL Table lenght | ||
192 | * | ||
193 | * The 64 bit regiontable origin of S390 has following format: | ||
194 | * | region table origon | DTTL | ||
195 | * 0000000000111111111122222222223333333333444444444455555555556666 | ||
196 | * 0123456789012345678901234567890123456789012345678901234567890123 | ||
197 | * | ||
198 | * X Space-Switch event: | ||
199 | * G Segment-Invalid Bit: | ||
200 | * P Private-Space Bit: | ||
201 | * S Storage-Alteration: | ||
202 | * R Real space | ||
203 | * TL Table-Length: | ||
204 | * | ||
205 | * A storage key has the following format: | ||
206 | * | ACC |F|R|C|0| | ||
207 | * 0 3 4 5 6 7 | ||
208 | * ACC: access key | ||
209 | * F : fetch protection bit | ||
210 | * R : referenced bit | ||
211 | * C : changed bit | ||
212 | */ | ||
213 | |||
214 | /* Hardware bits in the page table entry */ | ||
215 | #define _PAGE_RO 0x200 /* HW read-only */ | ||
216 | #define _PAGE_INVALID 0x400 /* HW invalid */ | ||
217 | |||
218 | /* Mask and four different kinds of invalid pages. */ | ||
219 | #define _PAGE_INVALID_MASK 0x601 | ||
220 | #define _PAGE_INVALID_EMPTY 0x400 | ||
221 | #define _PAGE_INVALID_NONE 0x401 | ||
222 | #define _PAGE_INVALID_SWAP 0x600 | ||
223 | #define _PAGE_INVALID_FILE 0x601 | ||
224 | |||
225 | #ifndef __s390x__ | ||
226 | |||
227 | /* Bits in the segment table entry */ | ||
228 | #define _PAGE_TABLE_LEN 0xf /* only full page-tables */ | ||
229 | #define _PAGE_TABLE_COM 0x10 /* common page-table */ | ||
230 | #define _PAGE_TABLE_INV 0x20 /* invalid page-table */ | ||
231 | #define _SEG_PRESENT 0x001 /* Software (overlap with PTL) */ | ||
232 | |||
233 | /* Bits int the storage key */ | ||
234 | #define _PAGE_CHANGED 0x02 /* HW changed bit */ | ||
235 | #define _PAGE_REFERENCED 0x04 /* HW referenced bit */ | ||
236 | |||
237 | #define _USER_SEG_TABLE_LEN 0x7f /* user-segment-table up to 2 GB */ | ||
238 | #define _KERNEL_SEG_TABLE_LEN 0x7f /* kernel-segment-table up to 2 GB */ | ||
239 | |||
240 | /* | ||
241 | * User and Kernel pagetables are identical | ||
242 | */ | ||
243 | #define _PAGE_TABLE _PAGE_TABLE_LEN | ||
244 | #define _KERNPG_TABLE _PAGE_TABLE_LEN | ||
245 | |||
246 | /* | ||
247 | * The Kernel segment-tables includes the User segment-table | ||
248 | */ | ||
249 | |||
250 | #define _SEGMENT_TABLE (_USER_SEG_TABLE_LEN|0x80000000|0x100) | ||
251 | #define _KERNSEG_TABLE _KERNEL_SEG_TABLE_LEN | ||
252 | |||
253 | #define USER_STD_MASK 0x00000080UL | ||
254 | |||
255 | #else /* __s390x__ */ | ||
256 | |||
257 | /* Bits in the segment table entry */ | ||
258 | #define _PMD_ENTRY_INV 0x20 /* invalid segment table entry */ | ||
259 | #define _PMD_ENTRY 0x00 | ||
260 | |||
261 | /* Bits in the region third table entry */ | ||
262 | #define _PGD_ENTRY_INV 0x20 /* invalid region table entry */ | ||
263 | #define _PGD_ENTRY 0x07 | ||
264 | |||
265 | /* | ||
266 | * User and kernel page directory | ||
267 | */ | ||
268 | #define _REGION_THIRD 0x4 | ||
269 | #define _REGION_THIRD_LEN 0x3 | ||
270 | #define _REGION_TABLE (_REGION_THIRD|_REGION_THIRD_LEN|0x40|0x100) | ||
271 | #define _KERN_REGION_TABLE (_REGION_THIRD|_REGION_THIRD_LEN) | ||
272 | |||
273 | #define USER_STD_MASK 0x0000000000000080UL | ||
274 | |||
275 | /* Bits in the storage key */ | ||
276 | #define _PAGE_CHANGED 0x02 /* HW changed bit */ | ||
277 | #define _PAGE_REFERENCED 0x04 /* HW referenced bit */ | ||
278 | |||
279 | #endif /* __s390x__ */ | ||
280 | |||
281 | /* | ||
282 | * No mapping available | ||
283 | */ | ||
284 | #define PAGE_NONE_SHARED __pgprot(_PAGE_INVALID_NONE) | ||
285 | #define PAGE_NONE_PRIVATE __pgprot(_PAGE_INVALID_NONE) | ||
286 | #define PAGE_RO_SHARED __pgprot(_PAGE_RO) | ||
287 | #define PAGE_RO_PRIVATE __pgprot(_PAGE_RO) | ||
288 | #define PAGE_COPY __pgprot(_PAGE_RO) | ||
289 | #define PAGE_SHARED __pgprot(0) | ||
290 | #define PAGE_KERNEL __pgprot(0) | ||
291 | |||
292 | /* | ||
293 | * The S390 can't do page protection for execute, and considers that the | ||
294 | * same are read. Also, write permissions imply read permissions. This is | ||
295 | * the closest we can get.. | ||
296 | */ | ||
297 | /*xwr*/ | ||
298 | #define __P000 PAGE_NONE_PRIVATE | ||
299 | #define __P001 PAGE_RO_PRIVATE | ||
300 | #define __P010 PAGE_COPY | ||
301 | #define __P011 PAGE_COPY | ||
302 | #define __P100 PAGE_RO_PRIVATE | ||
303 | #define __P101 PAGE_RO_PRIVATE | ||
304 | #define __P110 PAGE_COPY | ||
305 | #define __P111 PAGE_COPY | ||
306 | |||
307 | #define __S000 PAGE_NONE_SHARED | ||
308 | #define __S001 PAGE_RO_SHARED | ||
309 | #define __S010 PAGE_SHARED | ||
310 | #define __S011 PAGE_SHARED | ||
311 | #define __S100 PAGE_RO_SHARED | ||
312 | #define __S101 PAGE_RO_SHARED | ||
313 | #define __S110 PAGE_SHARED | ||
314 | #define __S111 PAGE_SHARED | ||
315 | |||
316 | /* | ||
317 | * Certain architectures need to do special things when PTEs | ||
318 | * within a page table are directly modified. Thus, the following | ||
319 | * hook is made available. | ||
320 | */ | ||
321 | extern inline void set_pte(pte_t *pteptr, pte_t pteval) | ||
322 | { | ||
323 | *pteptr = pteval; | ||
324 | } | ||
325 | #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) | ||
326 | |||
327 | /* | ||
328 | * pgd/pmd/pte query functions | ||
329 | */ | ||
330 | #ifndef __s390x__ | ||
331 | |||
332 | extern inline int pgd_present(pgd_t pgd) { return 1; } | ||
333 | extern inline int pgd_none(pgd_t pgd) { return 0; } | ||
334 | extern inline int pgd_bad(pgd_t pgd) { return 0; } | ||
335 | |||
336 | extern inline int pmd_present(pmd_t pmd) { return pmd_val(pmd) & _SEG_PRESENT; } | ||
337 | extern inline int pmd_none(pmd_t pmd) { return pmd_val(pmd) & _PAGE_TABLE_INV; } | ||
338 | extern inline int pmd_bad(pmd_t pmd) | ||
339 | { | ||
340 | return (pmd_val(pmd) & (~PAGE_MASK & ~_PAGE_TABLE_INV)) != _PAGE_TABLE; | ||
341 | } | ||
342 | |||
343 | #else /* __s390x__ */ | ||
344 | |||
345 | extern inline int pgd_present(pgd_t pgd) | ||
346 | { | ||
347 | return (pgd_val(pgd) & ~PAGE_MASK) == _PGD_ENTRY; | ||
348 | } | ||
349 | |||
350 | extern inline int pgd_none(pgd_t pgd) | ||
351 | { | ||
352 | return pgd_val(pgd) & _PGD_ENTRY_INV; | ||
353 | } | ||
354 | |||
355 | extern inline int pgd_bad(pgd_t pgd) | ||
356 | { | ||
357 | return (pgd_val(pgd) & (~PAGE_MASK & ~_PGD_ENTRY_INV)) != _PGD_ENTRY; | ||
358 | } | ||
359 | |||
360 | extern inline int pmd_present(pmd_t pmd) | ||
361 | { | ||
362 | return (pmd_val(pmd) & ~PAGE_MASK) == _PMD_ENTRY; | ||
363 | } | ||
364 | |||
365 | extern inline int pmd_none(pmd_t pmd) | ||
366 | { | ||
367 | return pmd_val(pmd) & _PMD_ENTRY_INV; | ||
368 | } | ||
369 | |||
370 | extern inline int pmd_bad(pmd_t pmd) | ||
371 | { | ||
372 | return (pmd_val(pmd) & (~PAGE_MASK & ~_PMD_ENTRY_INV)) != _PMD_ENTRY; | ||
373 | } | ||
374 | |||
375 | #endif /* __s390x__ */ | ||
376 | |||
377 | extern inline int pte_none(pte_t pte) | ||
378 | { | ||
379 | return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_EMPTY; | ||
380 | } | ||
381 | |||
382 | extern inline int pte_present(pte_t pte) | ||
383 | { | ||
384 | return !(pte_val(pte) & _PAGE_INVALID) || | ||
385 | (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_NONE; | ||
386 | } | ||
387 | |||
388 | extern inline int pte_file(pte_t pte) | ||
389 | { | ||
390 | return (pte_val(pte) & _PAGE_INVALID_MASK) == _PAGE_INVALID_FILE; | ||
391 | } | ||
392 | |||
393 | #define pte_same(a,b) (pte_val(a) == pte_val(b)) | ||
394 | |||
395 | /* | ||
396 | * query functions pte_write/pte_dirty/pte_young only work if | ||
397 | * pte_present() is true. Undefined behaviour if not.. | ||
398 | */ | ||
399 | extern inline int pte_write(pte_t pte) | ||
400 | { | ||
401 | return (pte_val(pte) & _PAGE_RO) == 0; | ||
402 | } | ||
403 | |||
404 | extern inline int pte_dirty(pte_t pte) | ||
405 | { | ||
406 | /* A pte is neither clean nor dirty on s/390. The dirty bit | ||
407 | * is in the storage key. See page_test_and_clear_dirty for | ||
408 | * details. | ||
409 | */ | ||
410 | return 0; | ||
411 | } | ||
412 | |||
413 | extern inline int pte_young(pte_t pte) | ||
414 | { | ||
415 | /* A pte is neither young nor old on s/390. The young bit | ||
416 | * is in the storage key. See page_test_and_clear_young for | ||
417 | * details. | ||
418 | */ | ||
419 | return 0; | ||
420 | } | ||
421 | |||
422 | extern inline int pte_read(pte_t pte) | ||
423 | { | ||
424 | /* All pages are readable since we don't use the fetch | ||
425 | * protection bit in the storage key. | ||
426 | */ | ||
427 | return 1; | ||
428 | } | ||
429 | |||
430 | /* | ||
431 | * pgd/pmd/pte modification functions | ||
432 | */ | ||
433 | |||
434 | #ifndef __s390x__ | ||
435 | |||
436 | extern inline void pgd_clear(pgd_t * pgdp) { } | ||
437 | |||
438 | extern inline void pmd_clear(pmd_t * pmdp) | ||
439 | { | ||
440 | pmd_val(pmdp[0]) = _PAGE_TABLE_INV; | ||
441 | pmd_val(pmdp[1]) = _PAGE_TABLE_INV; | ||
442 | pmd_val(pmdp[2]) = _PAGE_TABLE_INV; | ||
443 | pmd_val(pmdp[3]) = _PAGE_TABLE_INV; | ||
444 | } | ||
445 | |||
446 | #else /* __s390x__ */ | ||
447 | |||
448 | extern inline void pgd_clear(pgd_t * pgdp) | ||
449 | { | ||
450 | pgd_val(*pgdp) = _PGD_ENTRY_INV | _PGD_ENTRY; | ||
451 | } | ||
452 | |||
453 | extern inline void pmd_clear(pmd_t * pmdp) | ||
454 | { | ||
455 | pmd_val(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY; | ||
456 | pmd_val1(*pmdp) = _PMD_ENTRY_INV | _PMD_ENTRY; | ||
457 | } | ||
458 | |||
459 | #endif /* __s390x__ */ | ||
460 | |||
461 | extern inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | ||
462 | { | ||
463 | pte_val(*ptep) = _PAGE_INVALID_EMPTY; | ||
464 | } | ||
465 | |||
466 | /* | ||
467 | * The following pte modification functions only work if | ||
468 | * pte_present() is true. Undefined behaviour if not.. | ||
469 | */ | ||
470 | extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) | ||
471 | { | ||
472 | pte_val(pte) &= PAGE_MASK; | ||
473 | pte_val(pte) |= pgprot_val(newprot); | ||
474 | return pte; | ||
475 | } | ||
476 | |||
477 | extern inline pte_t pte_wrprotect(pte_t pte) | ||
478 | { | ||
479 | /* Do not clobber _PAGE_INVALID_NONE pages! */ | ||
480 | if (!(pte_val(pte) & _PAGE_INVALID)) | ||
481 | pte_val(pte) |= _PAGE_RO; | ||
482 | return pte; | ||
483 | } | ||
484 | |||
485 | extern inline pte_t pte_mkwrite(pte_t pte) | ||
486 | { | ||
487 | pte_val(pte) &= ~_PAGE_RO; | ||
488 | return pte; | ||
489 | } | ||
490 | |||
491 | extern inline pte_t pte_mkclean(pte_t pte) | ||
492 | { | ||
493 | /* The only user of pte_mkclean is the fork() code. | ||
494 | We must *not* clear the *physical* page dirty bit | ||
495 | just because fork() wants to clear the dirty bit in | ||
496 | *one* of the page's mappings. So we just do nothing. */ | ||
497 | return pte; | ||
498 | } | ||
499 | |||
500 | extern inline pte_t pte_mkdirty(pte_t pte) | ||
501 | { | ||
502 | /* We do not explicitly set the dirty bit because the | ||
503 | * sske instruction is slow. It is faster to let the | ||
504 | * next instruction set the dirty bit. | ||
505 | */ | ||
506 | return pte; | ||
507 | } | ||
508 | |||
509 | extern inline pte_t pte_mkold(pte_t pte) | ||
510 | { | ||
511 | /* S/390 doesn't keep its dirty/referenced bit in the pte. | ||
512 | * There is no point in clearing the real referenced bit. | ||
513 | */ | ||
514 | return pte; | ||
515 | } | ||
516 | |||
517 | extern inline pte_t pte_mkyoung(pte_t pte) | ||
518 | { | ||
519 | /* S/390 doesn't keep its dirty/referenced bit in the pte. | ||
520 | * There is no point in setting the real referenced bit. | ||
521 | */ | ||
522 | return pte; | ||
523 | } | ||
524 | |||
525 | static inline int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) | ||
526 | { | ||
527 | return 0; | ||
528 | } | ||
529 | |||
530 | static inline int | ||
531 | ptep_clear_flush_young(struct vm_area_struct *vma, | ||
532 | unsigned long address, pte_t *ptep) | ||
533 | { | ||
534 | /* No need to flush TLB; bits are in storage key */ | ||
535 | return ptep_test_and_clear_young(vma, address, ptep); | ||
536 | } | ||
537 | |||
538 | static inline int ptep_test_and_clear_dirty(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) | ||
539 | { | ||
540 | return 0; | ||
541 | } | ||
542 | |||
543 | static inline int | ||
544 | ptep_clear_flush_dirty(struct vm_area_struct *vma, | ||
545 | unsigned long address, pte_t *ptep) | ||
546 | { | ||
547 | /* No need to flush TLB; bits are in storage key */ | ||
548 | return ptep_test_and_clear_dirty(vma, address, ptep); | ||
549 | } | ||
550 | |||
551 | static inline pte_t ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | ||
552 | { | ||
553 | pte_t pte = *ptep; | ||
554 | pte_clear(mm, addr, ptep); | ||
555 | return pte; | ||
556 | } | ||
557 | |||
558 | static inline pte_t | ||
559 | ptep_clear_flush(struct vm_area_struct *vma, | ||
560 | unsigned long address, pte_t *ptep) | ||
561 | { | ||
562 | pte_t pte = *ptep; | ||
563 | #ifndef __s390x__ | ||
564 | if (!(pte_val(pte) & _PAGE_INVALID)) { | ||
565 | /* S390 has 1mb segments, we are emulating 4MB segments */ | ||
566 | pte_t *pto = (pte_t *) (((unsigned long) ptep) & 0x7ffffc00); | ||
567 | __asm__ __volatile__ ("ipte %2,%3" | ||
568 | : "=m" (*ptep) : "m" (*ptep), | ||
569 | "a" (pto), "a" (address) ); | ||
570 | } | ||
571 | #else /* __s390x__ */ | ||
572 | if (!(pte_val(pte) & _PAGE_INVALID)) | ||
573 | __asm__ __volatile__ ("ipte %2,%3" | ||
574 | : "=m" (*ptep) : "m" (*ptep), | ||
575 | "a" (ptep), "a" (address) ); | ||
576 | #endif /* __s390x__ */ | ||
577 | pte_val(*ptep) = _PAGE_INVALID_EMPTY; | ||
578 | return pte; | ||
579 | } | ||
580 | |||
581 | static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) | ||
582 | { | ||
583 | pte_t old_pte = *ptep; | ||
584 | set_pte_at(mm, addr, ptep, pte_wrprotect(old_pte)); | ||
585 | } | ||
586 | |||
587 | static inline void | ||
588 | ptep_establish(struct vm_area_struct *vma, | ||
589 | unsigned long address, pte_t *ptep, | ||
590 | pte_t entry) | ||
591 | { | ||
592 | ptep_clear_flush(vma, address, ptep); | ||
593 | set_pte(ptep, entry); | ||
594 | } | ||
595 | |||
596 | #define ptep_set_access_flags(__vma, __address, __ptep, __entry, __dirty) \ | ||
597 | ptep_establish(__vma, __address, __ptep, __entry) | ||
598 | |||
599 | /* | ||
600 | * Test and clear dirty bit in storage key. | ||
601 | * We can't clear the changed bit atomically. This is a potential | ||
602 | * race against modification of the referenced bit. This function | ||
603 | * should therefore only be called if it is not mapped in any | ||
604 | * address space. | ||
605 | */ | ||
606 | #define page_test_and_clear_dirty(_page) \ | ||
607 | ({ \ | ||
608 | struct page *__page = (_page); \ | ||
609 | unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT); \ | ||
610 | int __skey = page_get_storage_key(__physpage); \ | ||
611 | if (__skey & _PAGE_CHANGED) \ | ||
612 | page_set_storage_key(__physpage, __skey & ~_PAGE_CHANGED);\ | ||
613 | (__skey & _PAGE_CHANGED); \ | ||
614 | }) | ||
615 | |||
616 | /* | ||
617 | * Test and clear referenced bit in storage key. | ||
618 | */ | ||
619 | #define page_test_and_clear_young(page) \ | ||
620 | ({ \ | ||
621 | struct page *__page = (page); \ | ||
622 | unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT); \ | ||
623 | int __ccode; \ | ||
624 | asm volatile ("rrbe 0,%1\n\t" \ | ||
625 | "ipm %0\n\t" \ | ||
626 | "srl %0,28\n\t" \ | ||
627 | : "=d" (__ccode) : "a" (__physpage) : "cc" ); \ | ||
628 | (__ccode & 2); \ | ||
629 | }) | ||
630 | |||
631 | /* | ||
632 | * Conversion functions: convert a page and protection to a page entry, | ||
633 | * and a page entry and page directory to the page they refer to. | ||
634 | */ | ||
635 | static inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) | ||
636 | { | ||
637 | pte_t __pte; | ||
638 | pte_val(__pte) = physpage + pgprot_val(pgprot); | ||
639 | return __pte; | ||
640 | } | ||
641 | |||
642 | #define mk_pte(pg, pgprot) \ | ||
643 | ({ \ | ||
644 | struct page *__page = (pg); \ | ||
645 | pgprot_t __pgprot = (pgprot); \ | ||
646 | unsigned long __physpage = __pa((__page-mem_map) << PAGE_SHIFT); \ | ||
647 | pte_t __pte = mk_pte_phys(__physpage, __pgprot); \ | ||
648 | __pte; \ | ||
649 | }) | ||
650 | |||
651 | #define pfn_pte(pfn, pgprot) \ | ||
652 | ({ \ | ||
653 | pgprot_t __pgprot = (pgprot); \ | ||
654 | unsigned long __physpage = __pa((pfn) << PAGE_SHIFT); \ | ||
655 | pte_t __pte = mk_pte_phys(__physpage, __pgprot); \ | ||
656 | __pte; \ | ||
657 | }) | ||
658 | |||
659 | #define SetPageUptodate(_page) \ | ||
660 | do { \ | ||
661 | struct page *__page = (_page); \ | ||
662 | if (!test_and_set_bit(PG_uptodate, &__page->flags)) \ | ||
663 | page_test_and_clear_dirty(_page); \ | ||
664 | } while (0) | ||
665 | |||
666 | #ifdef __s390x__ | ||
667 | |||
668 | #define pfn_pmd(pfn, pgprot) \ | ||
669 | ({ \ | ||
670 | pgprot_t __pgprot = (pgprot); \ | ||
671 | unsigned long __physpage = __pa((pfn) << PAGE_SHIFT); \ | ||
672 | pmd_t __pmd = __pmd(__physpage + pgprot_val(__pgprot)); \ | ||
673 | __pmd; \ | ||
674 | }) | ||
675 | |||
676 | #endif /* __s390x__ */ | ||
677 | |||
678 | #define pte_pfn(x) (pte_val(x) >> PAGE_SHIFT) | ||
679 | #define pte_page(x) pfn_to_page(pte_pfn(x)) | ||
680 | |||
681 | #define pmd_page_kernel(pmd) (pmd_val(pmd) & PAGE_MASK) | ||
682 | |||
683 | #define pmd_page(pmd) (mem_map+(pmd_val(pmd) >> PAGE_SHIFT)) | ||
684 | |||
685 | #define pgd_page_kernel(pgd) (pgd_val(pgd) & PAGE_MASK) | ||
686 | |||
687 | /* to find an entry in a page-table-directory */ | ||
688 | #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1)) | ||
689 | #define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address)) | ||
690 | |||
691 | /* to find an entry in a kernel page-table-directory */ | ||
692 | #define pgd_offset_k(address) pgd_offset(&init_mm, address) | ||
693 | |||
694 | #ifndef __s390x__ | ||
695 | |||
696 | /* Find an entry in the second-level page table.. */ | ||
697 | extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address) | ||
698 | { | ||
699 | return (pmd_t *) dir; | ||
700 | } | ||
701 | |||
702 | #else /* __s390x__ */ | ||
703 | |||
704 | /* Find an entry in the second-level page table.. */ | ||
705 | #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1)) | ||
706 | #define pmd_offset(dir,addr) \ | ||
707 | ((pmd_t *) pgd_page_kernel(*(dir)) + pmd_index(addr)) | ||
708 | |||
709 | #endif /* __s390x__ */ | ||
710 | |||
711 | /* Find an entry in the third-level page table.. */ | ||
712 | #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE-1)) | ||
713 | #define pte_offset_kernel(pmd, address) \ | ||
714 | ((pte_t *) pmd_page_kernel(*(pmd)) + pte_index(address)) | ||
715 | #define pte_offset_map(pmd, address) pte_offset_kernel(pmd, address) | ||
716 | #define pte_offset_map_nested(pmd, address) pte_offset_kernel(pmd, address) | ||
717 | #define pte_unmap(pte) do { } while (0) | ||
718 | #define pte_unmap_nested(pte) do { } while (0) | ||
719 | |||
720 | /* | ||
721 | * 31 bit swap entry format: | ||
722 | * A page-table entry has some bits we have to treat in a special way. | ||
723 | * Bits 0, 20 and bit 23 have to be zero, otherwise an specification | ||
724 | * exception will occur instead of a page translation exception. The | ||
725 | * specifiation exception has the bad habit not to store necessary | ||
726 | * information in the lowcore. | ||
727 | * Bit 21 and bit 22 are the page invalid bit and the page protection | ||
728 | * bit. We set both to indicate a swapped page. | ||
729 | * Bit 30 and 31 are used to distinguish the different page types. For | ||
730 | * a swapped page these bits need to be zero. | ||
731 | * This leaves the bits 1-19 and bits 24-29 to store type and offset. | ||
732 | * We use the 5 bits from 25-29 for the type and the 20 bits from 1-19 | ||
733 | * plus 24 for the offset. | ||
734 | * 0| offset |0110|o|type |00| | ||
735 | * 0 0000000001111111111 2222 2 22222 33 | ||
736 | * 0 1234567890123456789 0123 4 56789 01 | ||
737 | * | ||
738 | * 64 bit swap entry format: | ||
739 | * A page-table entry has some bits we have to treat in a special way. | ||
740 | * Bits 52 and bit 55 have to be zero, otherwise an specification | ||
741 | * exception will occur instead of a page translation exception. The | ||
742 | * specifiation exception has the bad habit not to store necessary | ||
743 | * information in the lowcore. | ||
744 | * Bit 53 and bit 54 are the page invalid bit and the page protection | ||
745 | * bit. We set both to indicate a swapped page. | ||
746 | * Bit 62 and 63 are used to distinguish the different page types. For | ||
747 | * a swapped page these bits need to be zero. | ||
748 | * This leaves the bits 0-51 and bits 56-61 to store type and offset. | ||
749 | * We use the 5 bits from 57-61 for the type and the 53 bits from 0-51 | ||
750 | * plus 56 for the offset. | ||
751 | * | offset |0110|o|type |00| | ||
752 | * 0000000000111111111122222222223333333333444444444455 5555 5 55566 66 | ||
753 | * 0123456789012345678901234567890123456789012345678901 2345 6 78901 23 | ||
754 | */ | ||
755 | #ifndef __s390x__ | ||
756 | #define __SWP_OFFSET_MASK (~0UL >> 12) | ||
757 | #else | ||
758 | #define __SWP_OFFSET_MASK (~0UL >> 11) | ||
759 | #endif | ||
760 | extern inline pte_t mk_swap_pte(unsigned long type, unsigned long offset) | ||
761 | { | ||
762 | pte_t pte; | ||
763 | offset &= __SWP_OFFSET_MASK; | ||
764 | pte_val(pte) = _PAGE_INVALID_SWAP | ((type & 0x1f) << 2) | | ||
765 | ((offset & 1UL) << 7) | ((offset & ~1UL) << 11); | ||
766 | return pte; | ||
767 | } | ||
768 | |||
769 | #define __swp_type(entry) (((entry).val >> 2) & 0x1f) | ||
770 | #define __swp_offset(entry) (((entry).val >> 11) | (((entry).val >> 7) & 1)) | ||
771 | #define __swp_entry(type,offset) ((swp_entry_t) { pte_val(mk_swap_pte((type),(offset))) }) | ||
772 | |||
773 | #define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) | ||
774 | #define __swp_entry_to_pte(x) ((pte_t) { (x).val }) | ||
775 | |||
776 | #ifndef __s390x__ | ||
777 | # define PTE_FILE_MAX_BITS 26 | ||
778 | #else /* __s390x__ */ | ||
779 | # define PTE_FILE_MAX_BITS 59 | ||
780 | #endif /* __s390x__ */ | ||
781 | |||
782 | #define pte_to_pgoff(__pte) \ | ||
783 | ((((__pte).pte >> 12) << 7) + (((__pte).pte >> 1) & 0x7f)) | ||
784 | |||
785 | #define pgoff_to_pte(__off) \ | ||
786 | ((pte_t) { ((((__off) & 0x7f) << 1) + (((__off) >> 7) << 12)) \ | ||
787 | | _PAGE_INVALID_FILE }) | ||
788 | |||
789 | #endif /* !__ASSEMBLY__ */ | ||
790 | |||
791 | #define kern_addr_valid(addr) (1) | ||
792 | |||
793 | /* | ||
794 | * No page table caches to initialise | ||
795 | */ | ||
796 | #define pgtable_cache_init() do { } while (0) | ||
797 | |||
798 | #define __HAVE_ARCH_PTEP_ESTABLISH | ||
799 | #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS | ||
800 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG | ||
801 | #define __HAVE_ARCH_PTEP_CLEAR_YOUNG_FLUSH | ||
802 | #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_DIRTY | ||
803 | #define __HAVE_ARCH_PTEP_CLEAR_DIRTY_FLUSH | ||
804 | #define __HAVE_ARCH_PTEP_GET_AND_CLEAR | ||
805 | #define __HAVE_ARCH_PTEP_CLEAR_FLUSH | ||
806 | #define __HAVE_ARCH_PTEP_SET_WRPROTECT | ||
807 | #define __HAVE_ARCH_PTE_SAME | ||
808 | #define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_DIRTY | ||
809 | #define __HAVE_ARCH_PAGE_TEST_AND_CLEAR_YOUNG | ||
810 | #include <asm-generic/pgtable.h> | ||
811 | |||
812 | #endif /* _S390_PAGE_H */ | ||
813 | |||
diff --git a/include/asm-s390/poll.h b/include/asm-s390/poll.h new file mode 100644 index 000000000000..e90a5ca42061 --- /dev/null +++ b/include/asm-s390/poll.h | |||
@@ -0,0 +1,34 @@ | |||
1 | /* | ||
2 | * include/asm-s390/poll.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/poll.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef __S390_POLL_H | ||
10 | #define __S390_POLL_H | ||
11 | |||
12 | /* These are specified by iBCS2 */ | ||
13 | #define POLLIN 0x0001 | ||
14 | #define POLLPRI 0x0002 | ||
15 | #define POLLOUT 0x0004 | ||
16 | #define POLLERR 0x0008 | ||
17 | #define POLLHUP 0x0010 | ||
18 | #define POLLNVAL 0x0020 | ||
19 | |||
20 | /* The rest seem to be more-or-less nonstandard. Check them! */ | ||
21 | #define POLLRDNORM 0x0040 | ||
22 | #define POLLRDBAND 0x0080 | ||
23 | #define POLLWRNORM 0x0100 | ||
24 | #define POLLWRBAND 0x0200 | ||
25 | #define POLLMSG 0x0400 | ||
26 | #define POLLREMOVE 0x1000 | ||
27 | |||
28 | struct pollfd { | ||
29 | int fd; | ||
30 | short events; | ||
31 | short revents; | ||
32 | }; | ||
33 | |||
34 | #endif | ||
diff --git a/include/asm-s390/posix_types.h b/include/asm-s390/posix_types.h new file mode 100644 index 000000000000..61788de3c0c3 --- /dev/null +++ b/include/asm-s390/posix_types.h | |||
@@ -0,0 +1,99 @@ | |||
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 | #if defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2) | ||
80 | |||
81 | #ifndef _S390_BITOPS_H | ||
82 | #include <asm/bitops.h> | ||
83 | #endif | ||
84 | |||
85 | #undef __FD_SET | ||
86 | #define __FD_SET(fd,fdsetp) set_bit((fd),(fdsetp)->fds_bits) | ||
87 | |||
88 | #undef __FD_CLR | ||
89 | #define __FD_CLR(fd,fdsetp) clear_bit((fd),(fdsetp)->fds_bits) | ||
90 | |||
91 | #undef __FD_ISSET | ||
92 | #define __FD_ISSET(fd,fdsetp) test_bit((fd),(fdsetp)->fds_bits) | ||
93 | |||
94 | #undef __FD_ZERO | ||
95 | #define __FD_ZERO(fdsetp) (memset ((fdsetp), 0, sizeof(*(fd_set *)(fdsetp)))) | ||
96 | |||
97 | #endif /* defined(__KERNEL__) || !defined(__GLIBC__) || (__GLIBC__ < 2)*/ | ||
98 | |||
99 | #endif | ||
diff --git a/include/asm-s390/processor.h b/include/asm-s390/processor.h new file mode 100644 index 000000000000..cbbd11471672 --- /dev/null +++ b/include/asm-s390/processor.h | |||
@@ -0,0 +1,355 @@ | |||
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/page.h> | ||
17 | #include <asm/ptrace.h> | ||
18 | |||
19 | #ifdef __KERNEL__ | ||
20 | /* | ||
21 | * Default implementation of macro that returns current | ||
22 | * instruction pointer ("program counter"). | ||
23 | */ | ||
24 | #define current_text_addr() ({ void *pc; __asm__("basr %0,0":"=a"(pc)); pc; }) | ||
25 | |||
26 | /* | ||
27 | * CPU type and hardware bug flags. Kept separately for each CPU. | ||
28 | * Members of this structure are referenced in head.S, so think twice | ||
29 | * before touching them. [mj] | ||
30 | */ | ||
31 | |||
32 | typedef struct | ||
33 | { | ||
34 | unsigned int version : 8; | ||
35 | unsigned int ident : 24; | ||
36 | unsigned int machine : 16; | ||
37 | unsigned int unused : 16; | ||
38 | } __attribute__ ((packed)) cpuid_t; | ||
39 | |||
40 | struct cpuinfo_S390 | ||
41 | { | ||
42 | cpuid_t cpu_id; | ||
43 | __u16 cpu_addr; | ||
44 | __u16 cpu_nr; | ||
45 | unsigned long loops_per_jiffy; | ||
46 | unsigned long *pgd_quick; | ||
47 | #ifdef __s390x__ | ||
48 | unsigned long *pmd_quick; | ||
49 | #endif /* __s390x__ */ | ||
50 | unsigned long *pte_quick; | ||
51 | unsigned long pgtable_cache_sz; | ||
52 | }; | ||
53 | |||
54 | extern void print_cpu_info(struct cpuinfo_S390 *); | ||
55 | |||
56 | /* Lazy FPU handling on uni-processor */ | ||
57 | extern struct task_struct *last_task_used_math; | ||
58 | |||
59 | /* | ||
60 | * User space process size: 2GB for 31 bit, 4TB for 64 bit. | ||
61 | */ | ||
62 | #ifndef __s390x__ | ||
63 | |||
64 | # define TASK_SIZE (0x80000000UL) | ||
65 | # define TASK_UNMAPPED_BASE (TASK_SIZE / 2) | ||
66 | # define DEFAULT_TASK_SIZE (0x80000000UL) | ||
67 | |||
68 | #else /* __s390x__ */ | ||
69 | |||
70 | # define TASK_SIZE (test_thread_flag(TIF_31BIT) ? \ | ||
71 | (0x80000000UL) : (0x40000000000UL)) | ||
72 | # define TASK_UNMAPPED_BASE (TASK_SIZE / 2) | ||
73 | # define DEFAULT_TASK_SIZE (0x40000000000UL) | ||
74 | |||
75 | #endif /* __s390x__ */ | ||
76 | |||
77 | #define MM_VM_SIZE(mm) DEFAULT_TASK_SIZE | ||
78 | |||
79 | #define HAVE_ARCH_PICK_MMAP_LAYOUT | ||
80 | |||
81 | typedef struct { | ||
82 | __u32 ar4; | ||
83 | } mm_segment_t; | ||
84 | |||
85 | /* | ||
86 | * Thread structure | ||
87 | */ | ||
88 | struct thread_struct { | ||
89 | s390_fp_regs fp_regs; | ||
90 | unsigned int acrs[NUM_ACRS]; | ||
91 | unsigned long ksp; /* kernel stack pointer */ | ||
92 | unsigned long user_seg; /* HSTD */ | ||
93 | mm_segment_t mm_segment; | ||
94 | unsigned long prot_addr; /* address of protection-excep. */ | ||
95 | unsigned int error_code; /* error-code of last prog-excep. */ | ||
96 | unsigned int trap_no; | ||
97 | per_struct per_info; | ||
98 | /* Used to give failing instruction back to user for ieee exceptions */ | ||
99 | unsigned long ieee_instruction_pointer; | ||
100 | /* pfault_wait is used to block the process on a pfault event */ | ||
101 | unsigned long pfault_wait; | ||
102 | }; | ||
103 | |||
104 | typedef struct thread_struct thread_struct; | ||
105 | |||
106 | /* | ||
107 | * Stack layout of a C stack frame. | ||
108 | */ | ||
109 | #ifndef __PACK_STACK | ||
110 | struct stack_frame { | ||
111 | unsigned long back_chain; | ||
112 | unsigned long empty1[5]; | ||
113 | unsigned long gprs[10]; | ||
114 | unsigned int empty2[8]; | ||
115 | }; | ||
116 | #else | ||
117 | struct stack_frame { | ||
118 | unsigned long empty1[5]; | ||
119 | unsigned int empty2[8]; | ||
120 | unsigned long gprs[10]; | ||
121 | unsigned long back_chain; | ||
122 | }; | ||
123 | #endif | ||
124 | |||
125 | #define ARCH_MIN_TASKALIGN 8 | ||
126 | |||
127 | #ifndef __s390x__ | ||
128 | # define __SWAPPER_PG_DIR __pa(&swapper_pg_dir[0]) + _SEGMENT_TABLE | ||
129 | #else /* __s390x__ */ | ||
130 | # define __SWAPPER_PG_DIR __pa(&swapper_pg_dir[0]) + _REGION_TABLE | ||
131 | #endif /* __s390x__ */ | ||
132 | |||
133 | #define INIT_THREAD {{0,{{0},{0},{0},{0},{0},{0},{0},{0},{0},{0}, \ | ||
134 | {0},{0},{0},{0},{0},{0}}}, \ | ||
135 | {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, \ | ||
136 | sizeof(init_stack) + (unsigned long) &init_stack, \ | ||
137 | __SWAPPER_PG_DIR, \ | ||
138 | {0}, \ | ||
139 | 0,0,0, \ | ||
140 | (per_struct) {{{{0,}}},0,0,0,0,{{0,}}}, \ | ||
141 | 0, 0 \ | ||
142 | } | ||
143 | |||
144 | /* | ||
145 | * Do necessary setup to start up a new thread. | ||
146 | */ | ||
147 | #ifndef __s390x__ | ||
148 | |||
149 | #define start_thread(regs, new_psw, new_stackp) do { \ | ||
150 | regs->psw.mask = PSW_USER_BITS; \ | ||
151 | regs->psw.addr = new_psw | PSW_ADDR_AMODE; \ | ||
152 | regs->gprs[15] = new_stackp ; \ | ||
153 | } while (0) | ||
154 | |||
155 | #else /* __s390x__ */ | ||
156 | |||
157 | #define start_thread(regs, new_psw, new_stackp) do { \ | ||
158 | regs->psw.mask = PSW_USER_BITS; \ | ||
159 | regs->psw.addr = new_psw; \ | ||
160 | regs->gprs[15] = new_stackp; \ | ||
161 | } while (0) | ||
162 | |||
163 | #define start_thread31(regs, new_psw, new_stackp) do { \ | ||
164 | regs->psw.mask = PSW_USER32_BITS; \ | ||
165 | regs->psw.addr = new_psw; \ | ||
166 | regs->gprs[15] = new_stackp; \ | ||
167 | } while (0) | ||
168 | |||
169 | #endif /* __s390x__ */ | ||
170 | |||
171 | /* Forward declaration, a strange C thing */ | ||
172 | struct task_struct; | ||
173 | struct mm_struct; | ||
174 | |||
175 | /* Free all resources held by a thread. */ | ||
176 | extern void release_thread(struct task_struct *); | ||
177 | extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); | ||
178 | |||
179 | /* Prepare to copy thread state - unlazy all lazy status */ | ||
180 | #define prepare_to_copy(tsk) do { } while (0) | ||
181 | |||
182 | /* | ||
183 | * Return saved PC of a blocked thread. | ||
184 | */ | ||
185 | extern unsigned long thread_saved_pc(struct task_struct *t); | ||
186 | |||
187 | /* | ||
188 | * Print register of task into buffer. Used in fs/proc/array.c. | ||
189 | */ | ||
190 | extern char *task_show_regs(struct task_struct *task, char *buffer); | ||
191 | |||
192 | extern void show_registers(struct pt_regs *regs); | ||
193 | extern void show_trace(struct task_struct *task, unsigned long *sp); | ||
194 | |||
195 | unsigned long get_wchan(struct task_struct *p); | ||
196 | #define __KSTK_PTREGS(tsk) ((struct pt_regs *) \ | ||
197 | ((unsigned long) tsk->thread_info + THREAD_SIZE - sizeof(struct pt_regs))) | ||
198 | #define KSTK_EIP(tsk) (__KSTK_PTREGS(tsk)->psw.addr) | ||
199 | #define KSTK_ESP(tsk) (__KSTK_PTREGS(tsk)->gprs[15]) | ||
200 | |||
201 | /* | ||
202 | * Give up the time slice of the virtual PU. | ||
203 | */ | ||
204 | #ifndef __s390x__ | ||
205 | # define cpu_relax() asm volatile ("diag 0,0,68" : : : "memory") | ||
206 | #else /* __s390x__ */ | ||
207 | # define cpu_relax() \ | ||
208 | asm volatile ("ex 0,%0" : : "i" (__LC_DIAG44_OPCODE) : "memory") | ||
209 | #endif /* __s390x__ */ | ||
210 | |||
211 | /* | ||
212 | * Set PSW mask to specified value, while leaving the | ||
213 | * PSW addr pointing to the next instruction. | ||
214 | */ | ||
215 | |||
216 | static inline void __load_psw_mask (unsigned long mask) | ||
217 | { | ||
218 | unsigned long addr; | ||
219 | |||
220 | psw_t psw; | ||
221 | psw.mask = mask; | ||
222 | |||
223 | #ifndef __s390x__ | ||
224 | asm volatile ( | ||
225 | " basr %0,0\n" | ||
226 | "0: ahi %0,1f-0b\n" | ||
227 | " st %0,4(%1)\n" | ||
228 | " lpsw 0(%1)\n" | ||
229 | "1:" | ||
230 | : "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc" ); | ||
231 | #else /* __s390x__ */ | ||
232 | asm volatile ( | ||
233 | " larl %0,1f\n" | ||
234 | " stg %0,8(%1)\n" | ||
235 | " lpswe 0(%1)\n" | ||
236 | "1:" | ||
237 | : "=&d" (addr) : "a" (&psw), "m" (psw) : "memory", "cc" ); | ||
238 | #endif /* __s390x__ */ | ||
239 | } | ||
240 | |||
241 | /* | ||
242 | * Function to stop a processor until an interruption occurred | ||
243 | */ | ||
244 | static inline void enabled_wait(void) | ||
245 | { | ||
246 | unsigned long reg; | ||
247 | psw_t wait_psw; | ||
248 | |||
249 | wait_psw.mask = PSW_BASE_BITS | PSW_MASK_IO | PSW_MASK_EXT | | ||
250 | PSW_MASK_MCHECK | PSW_MASK_WAIT; | ||
251 | #ifndef __s390x__ | ||
252 | asm volatile ( | ||
253 | " basr %0,0\n" | ||
254 | "0: la %0,1f-0b(%0)\n" | ||
255 | " st %0,4(%1)\n" | ||
256 | " oi 4(%1),0x80\n" | ||
257 | " lpsw 0(%1)\n" | ||
258 | "1:" | ||
259 | : "=&a" (reg) : "a" (&wait_psw), "m" (wait_psw) | ||
260 | : "memory", "cc" ); | ||
261 | #else /* __s390x__ */ | ||
262 | asm volatile ( | ||
263 | " larl %0,0f\n" | ||
264 | " stg %0,8(%1)\n" | ||
265 | " lpswe 0(%1)\n" | ||
266 | "0:" | ||
267 | : "=&a" (reg) : "a" (&wait_psw), "m" (wait_psw) | ||
268 | : "memory", "cc" ); | ||
269 | #endif /* __s390x__ */ | ||
270 | } | ||
271 | |||
272 | /* | ||
273 | * Function to drop a processor into disabled wait state | ||
274 | */ | ||
275 | |||
276 | static inline void disabled_wait(unsigned long code) | ||
277 | { | ||
278 | char psw_buffer[2*sizeof(psw_t)]; | ||
279 | unsigned long ctl_buf; | ||
280 | psw_t *dw_psw = (psw_t *)(((unsigned long) &psw_buffer+sizeof(psw_t)-1) | ||
281 | & -sizeof(psw_t)); | ||
282 | |||
283 | dw_psw->mask = PSW_BASE_BITS | PSW_MASK_WAIT; | ||
284 | dw_psw->addr = code; | ||
285 | /* | ||
286 | * Store status and then load disabled wait psw, | ||
287 | * the processor is dead afterwards | ||
288 | */ | ||
289 | #ifndef __s390x__ | ||
290 | asm volatile (" stctl 0,0,0(%2)\n" | ||
291 | " ni 0(%2),0xef\n" /* switch off protection */ | ||
292 | " lctl 0,0,0(%2)\n" | ||
293 | " stpt 0xd8\n" /* store timer */ | ||
294 | " stckc 0xe0\n" /* store clock comparator */ | ||
295 | " stpx 0x108\n" /* store prefix register */ | ||
296 | " stam 0,15,0x120\n" /* store access registers */ | ||
297 | " std 0,0x160\n" /* store f0 */ | ||
298 | " std 2,0x168\n" /* store f2 */ | ||
299 | " std 4,0x170\n" /* store f4 */ | ||
300 | " std 6,0x178\n" /* store f6 */ | ||
301 | " stm 0,15,0x180\n" /* store general registers */ | ||
302 | " stctl 0,15,0x1c0\n" /* store control registers */ | ||
303 | " oi 0x1c0,0x10\n" /* fake protection bit */ | ||
304 | " lpsw 0(%1)" | ||
305 | : "=m" (ctl_buf) | ||
306 | : "a" (dw_psw), "a" (&ctl_buf), "m" (dw_psw) : "cc" ); | ||
307 | #else /* __s390x__ */ | ||
308 | asm volatile (" stctg 0,0,0(%2)\n" | ||
309 | " ni 4(%2),0xef\n" /* switch off protection */ | ||
310 | " lctlg 0,0,0(%2)\n" | ||
311 | " lghi 1,0x1000\n" | ||
312 | " stpt 0x328(1)\n" /* store timer */ | ||
313 | " stckc 0x330(1)\n" /* store clock comparator */ | ||
314 | " stpx 0x318(1)\n" /* store prefix register */ | ||
315 | " stam 0,15,0x340(1)\n" /* store access registers */ | ||
316 | " stfpc 0x31c(1)\n" /* store fpu control */ | ||
317 | " std 0,0x200(1)\n" /* store f0 */ | ||
318 | " std 1,0x208(1)\n" /* store f1 */ | ||
319 | " std 2,0x210(1)\n" /* store f2 */ | ||
320 | " std 3,0x218(1)\n" /* store f3 */ | ||
321 | " std 4,0x220(1)\n" /* store f4 */ | ||
322 | " std 5,0x228(1)\n" /* store f5 */ | ||
323 | " std 6,0x230(1)\n" /* store f6 */ | ||
324 | " std 7,0x238(1)\n" /* store f7 */ | ||
325 | " std 8,0x240(1)\n" /* store f8 */ | ||
326 | " std 9,0x248(1)\n" /* store f9 */ | ||
327 | " std 10,0x250(1)\n" /* store f10 */ | ||
328 | " std 11,0x258(1)\n" /* store f11 */ | ||
329 | " std 12,0x260(1)\n" /* store f12 */ | ||
330 | " std 13,0x268(1)\n" /* store f13 */ | ||
331 | " std 14,0x270(1)\n" /* store f14 */ | ||
332 | " std 15,0x278(1)\n" /* store f15 */ | ||
333 | " stmg 0,15,0x280(1)\n" /* store general registers */ | ||
334 | " stctg 0,15,0x380(1)\n" /* store control registers */ | ||
335 | " oi 0x384(1),0x10\n" /* fake protection bit */ | ||
336 | " lpswe 0(%1)" | ||
337 | : "=m" (ctl_buf) | ||
338 | : "a" (dw_psw), "a" (&ctl_buf), | ||
339 | "m" (dw_psw) : "cc", "0", "1"); | ||
340 | #endif /* __s390x__ */ | ||
341 | } | ||
342 | |||
343 | /* | ||
344 | * CPU idle notifier chain. | ||
345 | */ | ||
346 | #define CPU_IDLE 0 | ||
347 | #define CPU_NOT_IDLE 1 | ||
348 | |||
349 | struct notifier_block; | ||
350 | int register_idle_notifier(struct notifier_block *nb); | ||
351 | int unregister_idle_notifier(struct notifier_block *nb); | ||
352 | |||
353 | #endif | ||
354 | |||
355 | #endif /* __ASM_S390_PROCESSOR_H */ | ||
diff --git a/include/asm-s390/ptrace.h b/include/asm-s390/ptrace.h new file mode 100644 index 000000000000..1dc80666e97e --- /dev/null +++ b/include/asm-s390/ptrace.h | |||
@@ -0,0 +1,475 @@ | |||
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/config.h> | ||
185 | #include <linux/stddef.h> | ||
186 | #include <linux/types.h> | ||
187 | #include <asm/setup.h> | ||
188 | |||
189 | typedef union | ||
190 | { | ||
191 | float f; | ||
192 | double d; | ||
193 | __u64 ui; | ||
194 | struct | ||
195 | { | ||
196 | __u32 hi; | ||
197 | __u32 lo; | ||
198 | } fp; | ||
199 | } freg_t; | ||
200 | |||
201 | typedef struct | ||
202 | { | ||
203 | __u32 fpc; | ||
204 | freg_t fprs[NUM_FPRS]; | ||
205 | } s390_fp_regs; | ||
206 | |||
207 | #define FPC_EXCEPTION_MASK 0xF8000000 | ||
208 | #define FPC_FLAGS_MASK 0x00F80000 | ||
209 | #define FPC_DXC_MASK 0x0000FF00 | ||
210 | #define FPC_RM_MASK 0x00000003 | ||
211 | #define FPC_VALID_MASK 0xF8F8FF03 | ||
212 | |||
213 | /* this typedef defines how a Program Status Word looks like */ | ||
214 | typedef struct | ||
215 | { | ||
216 | unsigned long mask; | ||
217 | unsigned long addr; | ||
218 | } __attribute__ ((aligned(8))) psw_t; | ||
219 | |||
220 | #ifndef __s390x__ | ||
221 | |||
222 | #define PSW_MASK_PER 0x40000000UL | ||
223 | #define PSW_MASK_DAT 0x04000000UL | ||
224 | #define PSW_MASK_IO 0x02000000UL | ||
225 | #define PSW_MASK_EXT 0x01000000UL | ||
226 | #define PSW_MASK_KEY 0x00F00000UL | ||
227 | #define PSW_MASK_MCHECK 0x00040000UL | ||
228 | #define PSW_MASK_WAIT 0x00020000UL | ||
229 | #define PSW_MASK_PSTATE 0x00010000UL | ||
230 | #define PSW_MASK_ASC 0x0000C000UL | ||
231 | #define PSW_MASK_CC 0x00003000UL | ||
232 | #define PSW_MASK_PM 0x00000F00UL | ||
233 | |||
234 | #define PSW_ADDR_AMODE 0x80000000UL | ||
235 | #define PSW_ADDR_INSN 0x7FFFFFFFUL | ||
236 | |||
237 | #define PSW_BASE_BITS 0x00080000UL | ||
238 | |||
239 | #define PSW_ASC_PRIMARY 0x00000000UL | ||
240 | #define PSW_ASC_ACCREG 0x00004000UL | ||
241 | #define PSW_ASC_SECONDARY 0x00008000UL | ||
242 | #define PSW_ASC_HOME 0x0000C000UL | ||
243 | |||
244 | #else /* __s390x__ */ | ||
245 | |||
246 | #define PSW_MASK_PER 0x4000000000000000UL | ||
247 | #define PSW_MASK_DAT 0x0400000000000000UL | ||
248 | #define PSW_MASK_IO 0x0200000000000000UL | ||
249 | #define PSW_MASK_EXT 0x0100000000000000UL | ||
250 | #define PSW_MASK_KEY 0x00F0000000000000UL | ||
251 | #define PSW_MASK_MCHECK 0x0004000000000000UL | ||
252 | #define PSW_MASK_WAIT 0x0002000000000000UL | ||
253 | #define PSW_MASK_PSTATE 0x0001000000000000UL | ||
254 | #define PSW_MASK_ASC 0x0000C00000000000UL | ||
255 | #define PSW_MASK_CC 0x0000300000000000UL | ||
256 | #define PSW_MASK_PM 0x00000F0000000000UL | ||
257 | |||
258 | #define PSW_ADDR_AMODE 0x0000000000000000UL | ||
259 | #define PSW_ADDR_INSN 0xFFFFFFFFFFFFFFFFUL | ||
260 | |||
261 | #define PSW_BASE_BITS 0x0000000180000000UL | ||
262 | #define PSW_BASE32_BITS 0x0000000080000000UL | ||
263 | |||
264 | #define PSW_ASC_PRIMARY 0x0000000000000000UL | ||
265 | #define PSW_ASC_ACCREG 0x0000400000000000UL | ||
266 | #define PSW_ASC_SECONDARY 0x0000800000000000UL | ||
267 | #define PSW_ASC_HOME 0x0000C00000000000UL | ||
268 | |||
269 | #define PSW_USER32_BITS (PSW_BASE32_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \ | ||
270 | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \ | ||
271 | PSW_MASK_PSTATE) | ||
272 | |||
273 | #endif /* __s390x__ */ | ||
274 | |||
275 | #define PSW_KERNEL_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_PRIMARY) | ||
276 | #define PSW_USER_BITS (PSW_BASE_BITS | PSW_MASK_DAT | PSW_ASC_HOME | \ | ||
277 | PSW_MASK_IO | PSW_MASK_EXT | PSW_MASK_MCHECK | \ | ||
278 | PSW_MASK_PSTATE) | ||
279 | |||
280 | /* This macro merges a NEW PSW mask specified by the user into | ||
281 | the currently active PSW mask CURRENT, modifying only those | ||
282 | bits in CURRENT that the user may be allowed to change: this | ||
283 | is the condition code and the program mask bits. */ | ||
284 | #define PSW_MASK_MERGE(CURRENT,NEW) \ | ||
285 | (((CURRENT) & ~(PSW_MASK_CC|PSW_MASK_PM)) | \ | ||
286 | ((NEW) & (PSW_MASK_CC|PSW_MASK_PM))) | ||
287 | |||
288 | /* | ||
289 | * The s390_regs structure is used to define the elf_gregset_t. | ||
290 | */ | ||
291 | typedef struct | ||
292 | { | ||
293 | psw_t psw; | ||
294 | unsigned long gprs[NUM_GPRS]; | ||
295 | unsigned int acrs[NUM_ACRS]; | ||
296 | unsigned long orig_gpr2; | ||
297 | } s390_regs; | ||
298 | |||
299 | #ifdef __KERNEL__ | ||
300 | /* | ||
301 | * The pt_regs struct defines the way the registers are stored on | ||
302 | * the stack during a system call. | ||
303 | */ | ||
304 | struct pt_regs | ||
305 | { | ||
306 | unsigned long args[1]; | ||
307 | psw_t psw; | ||
308 | unsigned long gprs[NUM_GPRS]; | ||
309 | unsigned long orig_gpr2; | ||
310 | unsigned short ilc; | ||
311 | unsigned short trap; | ||
312 | }; | ||
313 | #endif | ||
314 | |||
315 | /* | ||
316 | * Now for the program event recording (trace) definitions. | ||
317 | */ | ||
318 | typedef struct | ||
319 | { | ||
320 | unsigned long cr[3]; | ||
321 | } per_cr_words; | ||
322 | |||
323 | #define PER_EM_MASK 0xE8000000UL | ||
324 | |||
325 | typedef struct | ||
326 | { | ||
327 | #ifdef __s390x__ | ||
328 | unsigned : 32; | ||
329 | #endif /* __s390x__ */ | ||
330 | unsigned em_branching : 1; | ||
331 | unsigned em_instruction_fetch : 1; | ||
332 | /* | ||
333 | * Switching on storage alteration automatically fixes | ||
334 | * the storage alteration event bit in the users std. | ||
335 | */ | ||
336 | unsigned em_storage_alteration : 1; | ||
337 | unsigned em_gpr_alt_unused : 1; | ||
338 | unsigned em_store_real_address : 1; | ||
339 | unsigned : 3; | ||
340 | unsigned branch_addr_ctl : 1; | ||
341 | unsigned : 1; | ||
342 | unsigned storage_alt_space_ctl : 1; | ||
343 | unsigned : 21; | ||
344 | unsigned long starting_addr; | ||
345 | unsigned long ending_addr; | ||
346 | } per_cr_bits; | ||
347 | |||
348 | typedef struct | ||
349 | { | ||
350 | unsigned short perc_atmid; | ||
351 | unsigned long address; | ||
352 | unsigned char access_id; | ||
353 | } per_lowcore_words; | ||
354 | |||
355 | typedef struct | ||
356 | { | ||
357 | unsigned perc_branching : 1; | ||
358 | unsigned perc_instruction_fetch : 1; | ||
359 | unsigned perc_storage_alteration : 1; | ||
360 | unsigned perc_gpr_alt_unused : 1; | ||
361 | unsigned perc_store_real_address : 1; | ||
362 | unsigned : 3; | ||
363 | unsigned atmid_psw_bit_31 : 1; | ||
364 | unsigned atmid_validity_bit : 1; | ||
365 | unsigned atmid_psw_bit_32 : 1; | ||
366 | unsigned atmid_psw_bit_5 : 1; | ||
367 | unsigned atmid_psw_bit_16 : 1; | ||
368 | unsigned atmid_psw_bit_17 : 1; | ||
369 | unsigned si : 2; | ||
370 | unsigned long address; | ||
371 | unsigned : 4; | ||
372 | unsigned access_id : 4; | ||
373 | } per_lowcore_bits; | ||
374 | |||
375 | typedef struct | ||
376 | { | ||
377 | union { | ||
378 | per_cr_words words; | ||
379 | per_cr_bits bits; | ||
380 | } control_regs; | ||
381 | /* | ||
382 | * Use these flags instead of setting em_instruction_fetch | ||
383 | * directly they are used so that single stepping can be | ||
384 | * switched on & off while not affecting other tracing | ||
385 | */ | ||
386 | unsigned single_step : 1; | ||
387 | unsigned instruction_fetch : 1; | ||
388 | unsigned : 30; | ||
389 | /* | ||
390 | * These addresses are copied into cr10 & cr11 if single | ||
391 | * stepping is switched off | ||
392 | */ | ||
393 | unsigned long starting_addr; | ||
394 | unsigned long ending_addr; | ||
395 | union { | ||
396 | per_lowcore_words words; | ||
397 | per_lowcore_bits bits; | ||
398 | } lowcore; | ||
399 | } per_struct; | ||
400 | |||
401 | typedef struct | ||
402 | { | ||
403 | unsigned int len; | ||
404 | unsigned long kernel_addr; | ||
405 | unsigned long process_addr; | ||
406 | } ptrace_area; | ||
407 | |||
408 | /* | ||
409 | * S/390 specific non posix ptrace requests. I chose unusual values so | ||
410 | * they are unlikely to clash with future ptrace definitions. | ||
411 | */ | ||
412 | #define PTRACE_PEEKUSR_AREA 0x5000 | ||
413 | #define PTRACE_POKEUSR_AREA 0x5001 | ||
414 | #define PTRACE_PEEKTEXT_AREA 0x5002 | ||
415 | #define PTRACE_PEEKDATA_AREA 0x5003 | ||
416 | #define PTRACE_POKETEXT_AREA 0x5004 | ||
417 | #define PTRACE_POKEDATA_AREA 0x5005 | ||
418 | |||
419 | /* | ||
420 | * PT_PROT definition is loosely based on hppa bsd definition in | ||
421 | * gdb/hppab-nat.c | ||
422 | */ | ||
423 | #define PTRACE_PROT 21 | ||
424 | |||
425 | typedef enum | ||
426 | { | ||
427 | ptprot_set_access_watchpoint, | ||
428 | ptprot_set_write_watchpoint, | ||
429 | ptprot_disable_watchpoint | ||
430 | } ptprot_flags; | ||
431 | |||
432 | typedef struct | ||
433 | { | ||
434 | unsigned long lowaddr; | ||
435 | unsigned long hiaddr; | ||
436 | ptprot_flags prot; | ||
437 | } ptprot_area; | ||
438 | |||
439 | /* Sequence of bytes for breakpoint illegal instruction. */ | ||
440 | #define S390_BREAKPOINT {0x0,0x1} | ||
441 | #define S390_BREAKPOINT_U16 ((__u16)0x0001) | ||
442 | #define S390_SYSCALL_OPCODE ((__u16)0x0a00) | ||
443 | #define S390_SYSCALL_SIZE 2 | ||
444 | |||
445 | /* | ||
446 | * The user_regs_struct defines the way the user registers are | ||
447 | * store on the stack for signal handling. | ||
448 | */ | ||
449 | struct user_regs_struct | ||
450 | { | ||
451 | psw_t psw; | ||
452 | unsigned long gprs[NUM_GPRS]; | ||
453 | unsigned int acrs[NUM_ACRS]; | ||
454 | unsigned long orig_gpr2; | ||
455 | s390_fp_regs fp_regs; | ||
456 | /* | ||
457 | * These per registers are in here so that gdb can modify them | ||
458 | * itself as there is no "official" ptrace interface for hardware | ||
459 | * watchpoints. This is the way intel does it. | ||
460 | */ | ||
461 | per_struct per_info; | ||
462 | unsigned long ieee_instruction_pointer; | ||
463 | /* Used to give failing instruction back to user for ieee exceptions */ | ||
464 | }; | ||
465 | |||
466 | #ifdef __KERNEL__ | ||
467 | #define user_mode(regs) (((regs)->psw.mask & PSW_MASK_PSTATE) != 0) | ||
468 | #define instruction_pointer(regs) ((regs)->psw.addr & PSW_ADDR_INSN) | ||
469 | #define profile_pc(regs) instruction_pointer(regs) | ||
470 | extern void show_regs(struct pt_regs * regs); | ||
471 | #endif | ||
472 | |||
473 | #endif /* __ASSEMBLY__ */ | ||
474 | |||
475 | #endif /* _S390_PTRACE_H */ | ||
diff --git a/include/asm-s390/qdio.h b/include/asm-s390/qdio.h new file mode 100644 index 000000000000..0ddf0a8ef8de --- /dev/null +++ b/include/asm-s390/qdio.h | |||
@@ -0,0 +1,401 @@ | |||
1 | /* | ||
2 | * linux/include/asm/qdio.h | ||
3 | * | ||
4 | * Linux for S/390 QDIO base support, Hipersocket base support | ||
5 | * version 2 | ||
6 | * | ||
7 | * Copyright 2000,2002 IBM Corporation | ||
8 | * Author(s): Utz Bacher <utz.bacher@de.ibm.com> | ||
9 | * | ||
10 | */ | ||
11 | #ifndef __QDIO_H__ | ||
12 | #define __QDIO_H__ | ||
13 | |||
14 | #define VERSION_QDIO_H "$Revision: 1.57 $" | ||
15 | |||
16 | /* note, that most of the typedef's are from ingo. */ | ||
17 | |||
18 | #include <linux/interrupt.h> | ||
19 | #include <asm/cio.h> | ||
20 | #include <asm/ccwdev.h> | ||
21 | |||
22 | #define QDIO_NAME "qdio " | ||
23 | |||
24 | #ifndef __s390x__ | ||
25 | #define QDIO_32_BIT | ||
26 | #endif /* __s390x__ */ | ||
27 | |||
28 | /**** CONSTANTS, that are relied on without using these symbols *****/ | ||
29 | #define QDIO_MAX_QUEUES_PER_IRQ 32 /* used in width of unsigned int */ | ||
30 | /************************ END of CONSTANTS **************************/ | ||
31 | #define QDIO_MAX_BUFFERS_PER_Q 128 /* must be a power of 2 (%x=&(x-1)*/ | ||
32 | #define QDIO_BUF_ORDER 7 /* 2**this == number of pages used for sbals in 1 q */ | ||
33 | #define QDIO_MAX_ELEMENTS_PER_BUFFER 16 | ||
34 | #define SBAL_SIZE 256 | ||
35 | |||
36 | #define QDIO_QETH_QFMT 0 | ||
37 | #define QDIO_ZFCP_QFMT 1 | ||
38 | #define QDIO_IQDIO_QFMT 2 | ||
39 | |||
40 | struct qdio_buffer_element{ | ||
41 | unsigned int flags; | ||
42 | unsigned int length; | ||
43 | #ifdef QDIO_32_BIT | ||
44 | void *reserved; | ||
45 | #endif /* QDIO_32_BIT */ | ||
46 | void *addr; | ||
47 | } __attribute__ ((packed,aligned(16))); | ||
48 | |||
49 | struct qdio_buffer{ | ||
50 | volatile struct qdio_buffer_element element[16]; | ||
51 | } __attribute__ ((packed,aligned(256))); | ||
52 | |||
53 | |||
54 | /* params are: ccw_device, status, qdio_error, siga_error, | ||
55 | queue_number, first element processed, number of elements processed, | ||
56 | int_parm */ | ||
57 | typedef void qdio_handler_t(struct ccw_device *,unsigned int,unsigned int, | ||
58 | unsigned int,unsigned int,int,int,unsigned long); | ||
59 | |||
60 | |||
61 | #define QDIO_STATUS_INBOUND_INT 0x01 | ||
62 | #define QDIO_STATUS_OUTBOUND_INT 0x02 | ||
63 | #define QDIO_STATUS_LOOK_FOR_ERROR 0x04 | ||
64 | #define QDIO_STATUS_MORE_THAN_ONE_QDIO_ERROR 0x08 | ||
65 | #define QDIO_STATUS_MORE_THAN_ONE_SIGA_ERROR 0x10 | ||
66 | #define QDIO_STATUS_ACTIVATE_CHECK_CONDITION 0x20 | ||
67 | |||
68 | #define QDIO_SIGA_ERROR_ACCESS_EXCEPTION 0x10 | ||
69 | #define QDIO_SIGA_ERROR_B_BIT_SET 0x20 | ||
70 | |||
71 | /* for qdio_initialize */ | ||
72 | #define QDIO_INBOUND_0COPY_SBALS 0x01 | ||
73 | #define QDIO_OUTBOUND_0COPY_SBALS 0x02 | ||
74 | #define QDIO_USE_OUTBOUND_PCIS 0x04 | ||
75 | |||
76 | /* for qdio_cleanup */ | ||
77 | #define QDIO_FLAG_CLEANUP_USING_CLEAR 0x01 | ||
78 | #define QDIO_FLAG_CLEANUP_USING_HALT 0x02 | ||
79 | |||
80 | struct qdio_initialize { | ||
81 | struct ccw_device *cdev; | ||
82 | unsigned char q_format; | ||
83 | unsigned char adapter_name[8]; | ||
84 | unsigned int qib_param_field_format; /*adapter dependent*/ | ||
85 | /* pointer to 128 bytes or NULL, if no param field */ | ||
86 | unsigned char *qib_param_field; /* adapter dependent */ | ||
87 | /* pointer to no_queues*128 words of data or NULL */ | ||
88 | unsigned long *input_slib_elements; | ||
89 | unsigned long *output_slib_elements; | ||
90 | unsigned int min_input_threshold; | ||
91 | unsigned int max_input_threshold; | ||
92 | unsigned int min_output_threshold; | ||
93 | unsigned int max_output_threshold; | ||
94 | unsigned int no_input_qs; | ||
95 | unsigned int no_output_qs; | ||
96 | qdio_handler_t *input_handler; | ||
97 | qdio_handler_t *output_handler; | ||
98 | unsigned long int_parm; | ||
99 | unsigned long flags; | ||
100 | void **input_sbal_addr_array; /* addr of n*128 void ptrs */ | ||
101 | void **output_sbal_addr_array; /* addr of n*128 void ptrs */ | ||
102 | }; | ||
103 | |||
104 | extern int qdio_initialize(struct qdio_initialize *init_data); | ||
105 | extern int qdio_allocate(struct qdio_initialize *init_data); | ||
106 | extern int qdio_establish(struct qdio_initialize *init_data); | ||
107 | |||
108 | extern int qdio_activate(struct ccw_device *,int flags); | ||
109 | |||
110 | #define QDIO_STATE_MUST_USE_OUTB_PCI 0x00000001 | ||
111 | #define QDIO_STATE_INACTIVE 0x00000002 /* after qdio_cleanup */ | ||
112 | #define QDIO_STATE_ESTABLISHED 0x00000004 /* after qdio_initialize */ | ||
113 | #define QDIO_STATE_ACTIVE 0x00000008 /* after qdio_activate */ | ||
114 | #define QDIO_STATE_STOPPED 0x00000010 /* after queues went down */ | ||
115 | extern unsigned long qdio_get_status(int irq); | ||
116 | |||
117 | |||
118 | #define QDIO_FLAG_SYNC_INPUT 0x01 | ||
119 | #define QDIO_FLAG_SYNC_OUTPUT 0x02 | ||
120 | #define QDIO_FLAG_UNDER_INTERRUPT 0x04 | ||
121 | #define QDIO_FLAG_NO_INPUT_INTERRUPT_CONTEXT 0x08 /* no effect on | ||
122 | adapter interrupts */ | ||
123 | #define QDIO_FLAG_DONT_SIGA 0x10 | ||
124 | |||
125 | extern int do_QDIO(struct ccw_device*, unsigned int flags, | ||
126 | unsigned int queue_number, | ||
127 | unsigned int qidx,unsigned int count, | ||
128 | struct qdio_buffer *buffers); | ||
129 | |||
130 | extern int qdio_synchronize(struct ccw_device*, unsigned int flags, | ||
131 | unsigned int queue_number); | ||
132 | |||
133 | extern int qdio_cleanup(struct ccw_device*, int how); | ||
134 | extern int qdio_shutdown(struct ccw_device*, int how); | ||
135 | extern int qdio_free(struct ccw_device*); | ||
136 | |||
137 | unsigned char qdio_get_slsb_state(struct ccw_device*, unsigned int flag, | ||
138 | unsigned int queue_number, | ||
139 | unsigned int qidx); | ||
140 | |||
141 | extern void qdio_init_scrubber(void); | ||
142 | |||
143 | struct qdesfmt0 { | ||
144 | #ifdef QDIO_32_BIT | ||
145 | unsigned long res1; /* reserved */ | ||
146 | #endif /* QDIO_32_BIT */ | ||
147 | unsigned long sliba; /* storage-list-information-block | ||
148 | address */ | ||
149 | #ifdef QDIO_32_BIT | ||
150 | unsigned long res2; /* reserved */ | ||
151 | #endif /* QDIO_32_BIT */ | ||
152 | unsigned long sla; /* storage-list address */ | ||
153 | #ifdef QDIO_32_BIT | ||
154 | unsigned long res3; /* reserved */ | ||
155 | #endif /* QDIO_32_BIT */ | ||
156 | unsigned long slsba; /* storage-list-state-block address */ | ||
157 | unsigned int res4; /* reserved */ | ||
158 | unsigned int akey : 4; /* access key for DLIB */ | ||
159 | unsigned int bkey : 4; /* access key for SL */ | ||
160 | unsigned int ckey : 4; /* access key for SBALs */ | ||
161 | unsigned int dkey : 4; /* access key for SLSB */ | ||
162 | unsigned int res5 : 16; /* reserved */ | ||
163 | } __attribute__ ((packed)); | ||
164 | |||
165 | /* | ||
166 | * Queue-Description record (QDR) | ||
167 | */ | ||
168 | struct qdr { | ||
169 | unsigned int qfmt : 8; /* queue format */ | ||
170 | unsigned int pfmt : 8; /* impl. dep. parameter format */ | ||
171 | unsigned int res1 : 8; /* reserved */ | ||
172 | unsigned int ac : 8; /* adapter characteristics */ | ||
173 | unsigned int res2 : 8; /* reserved */ | ||
174 | unsigned int iqdcnt : 8; /* input-queue-descriptor count */ | ||
175 | unsigned int res3 : 8; /* reserved */ | ||
176 | unsigned int oqdcnt : 8; /* output-queue-descriptor count */ | ||
177 | unsigned int res4 : 8; /* reserved */ | ||
178 | unsigned int iqdsz : 8; /* input-queue-descriptor size */ | ||
179 | unsigned int res5 : 8; /* reserved */ | ||
180 | unsigned int oqdsz : 8; /* output-queue-descriptor size */ | ||
181 | unsigned int res6[9]; /* reserved */ | ||
182 | #ifdef QDIO_32_BIT | ||
183 | unsigned long res7; /* reserved */ | ||
184 | #endif /* QDIO_32_BIT */ | ||
185 | unsigned long qiba; /* queue-information-block address */ | ||
186 | unsigned int res8; /* reserved */ | ||
187 | unsigned int qkey : 4; /* queue-informatio-block key */ | ||
188 | unsigned int res9 : 28; /* reserved */ | ||
189 | /* union _qd {*/ /* why this? */ | ||
190 | struct qdesfmt0 qdf0[126]; | ||
191 | /* } qd;*/ | ||
192 | } __attribute__ ((packed,aligned(4096))); | ||
193 | |||
194 | |||
195 | /* | ||
196 | * queue information block (QIB) | ||
197 | */ | ||
198 | #define QIB_AC_INBOUND_PCI_SUPPORTED 0x80 | ||
199 | #define QIB_AC_OUTBOUND_PCI_SUPPORTED 0x40 | ||
200 | struct qib { | ||
201 | unsigned int qfmt : 8; /* queue format */ | ||
202 | unsigned int pfmt : 8; /* impl. dep. parameter format */ | ||
203 | unsigned int res1 : 8; /* reserved */ | ||
204 | unsigned int ac : 8; /* adapter characteristics */ | ||
205 | unsigned int res2; /* reserved */ | ||
206 | #ifdef QDIO_32_BIT | ||
207 | unsigned long res3; /* reserved */ | ||
208 | #endif /* QDIO_32_BIT */ | ||
209 | unsigned long isliba; /* absolute address of 1st | ||
210 | input SLIB */ | ||
211 | #ifdef QDIO_32_BIT | ||
212 | unsigned long res4; /* reserved */ | ||
213 | #endif /* QDIO_32_BIT */ | ||
214 | unsigned long osliba; /* absolute address of 1st | ||
215 | output SLIB */ | ||
216 | unsigned int res5; /* reserved */ | ||
217 | unsigned int res6; /* reserved */ | ||
218 | unsigned char ebcnam[8]; /* adapter identifier in EBCDIC */ | ||
219 | unsigned char res7[88]; /* reserved */ | ||
220 | unsigned char parm[QDIO_MAX_BUFFERS_PER_Q]; | ||
221 | /* implementation dependent | ||
222 | parameters */ | ||
223 | } __attribute__ ((packed,aligned(256))); | ||
224 | |||
225 | |||
226 | /* | ||
227 | * storage-list-information block element (SLIBE) | ||
228 | */ | ||
229 | struct slibe { | ||
230 | #ifdef QDIO_32_BIT | ||
231 | unsigned long res; /* reserved */ | ||
232 | #endif /* QDIO_32_BIT */ | ||
233 | unsigned long parms; /* implementation dependent | ||
234 | parameters */ | ||
235 | }; | ||
236 | |||
237 | /* | ||
238 | * storage-list-information block (SLIB) | ||
239 | */ | ||
240 | struct slib { | ||
241 | #ifdef QDIO_32_BIT | ||
242 | unsigned long res1; /* reserved */ | ||
243 | #endif /* QDIO_32_BIT */ | ||
244 | unsigned long nsliba; /* next SLIB address (if any) */ | ||
245 | #ifdef QDIO_32_BIT | ||
246 | unsigned long res2; /* reserved */ | ||
247 | #endif /* QDIO_32_BIT */ | ||
248 | unsigned long sla; /* SL address */ | ||
249 | #ifdef QDIO_32_BIT | ||
250 | unsigned long res3; /* reserved */ | ||
251 | #endif /* QDIO_32_BIT */ | ||
252 | unsigned long slsba; /* SLSB address */ | ||
253 | unsigned char res4[1000]; /* reserved */ | ||
254 | struct slibe slibe[QDIO_MAX_BUFFERS_PER_Q]; /* SLIB elements */ | ||
255 | } __attribute__ ((packed,aligned(2048))); | ||
256 | |||
257 | struct sbal_flags { | ||
258 | unsigned char res1 : 1; /* reserved */ | ||
259 | unsigned char last : 1; /* last entry */ | ||
260 | unsigned char cont : 1; /* contiguous storage */ | ||
261 | unsigned char res2 : 1; /* reserved */ | ||
262 | unsigned char frag : 2; /* fragmentation (s.below) */ | ||
263 | unsigned char res3 : 2; /* reserved */ | ||
264 | } __attribute__ ((packed)); | ||
265 | |||
266 | #define SBAL_FLAGS_FIRST_FRAG 0x04000000UL | ||
267 | #define SBAL_FLAGS_MIDDLE_FRAG 0x08000000UL | ||
268 | #define SBAL_FLAGS_LAST_FRAG 0x0c000000UL | ||
269 | #define SBAL_FLAGS_LAST_ENTRY 0x40000000UL | ||
270 | #define SBAL_FLAGS_CONTIGUOUS 0x20000000UL | ||
271 | |||
272 | #define SBAL_FLAGS0_DATA_CONTINUATION 0x20UL | ||
273 | |||
274 | /* Awesome OpenFCP extensions */ | ||
275 | #define SBAL_FLAGS0_TYPE_STATUS 0x00UL | ||
276 | #define SBAL_FLAGS0_TYPE_WRITE 0x08UL | ||
277 | #define SBAL_FLAGS0_TYPE_READ 0x10UL | ||
278 | #define SBAL_FLAGS0_TYPE_WRITE_READ 0x18UL | ||
279 | #define SBAL_FLAGS0_MORE_SBALS 0x04UL | ||
280 | #define SBAL_FLAGS0_COMMAND 0x02UL | ||
281 | #define SBAL_FLAGS0_LAST_SBAL 0x00UL | ||
282 | #define SBAL_FLAGS0_ONLY_SBAL SBAL_FLAGS0_COMMAND | ||
283 | #define SBAL_FLAGS0_MIDDLE_SBAL SBAL_FLAGS0_MORE_SBALS | ||
284 | #define SBAL_FLAGS0_FIRST_SBAL SBAL_FLAGS0_MORE_SBALS | SBAL_FLAGS0_COMMAND | ||
285 | /* Naught of interest beyond this point */ | ||
286 | |||
287 | #define SBAL_FLAGS0_PCI 0x40 | ||
288 | struct sbal_sbalf_0 { | ||
289 | unsigned char res1 : 1; /* reserved */ | ||
290 | unsigned char pci : 1; /* PCI indicator */ | ||
291 | unsigned char cont : 1; /* data continuation */ | ||
292 | unsigned char sbtype: 2; /* storage-block type (OpenFCP) */ | ||
293 | unsigned char res2 : 3; /* reserved */ | ||
294 | } __attribute__ ((packed)); | ||
295 | |||
296 | struct sbal_sbalf_1 { | ||
297 | unsigned char res1 : 4; /* reserved */ | ||
298 | unsigned char key : 4; /* storage key */ | ||
299 | } __attribute__ ((packed)); | ||
300 | |||
301 | struct sbal_sbalf_14 { | ||
302 | unsigned char res1 : 4; /* reserved */ | ||
303 | unsigned char erridx : 4; /* error index */ | ||
304 | } __attribute__ ((packed)); | ||
305 | |||
306 | struct sbal_sbalf_15 { | ||
307 | unsigned char reason; /* reserved */ | ||
308 | } __attribute__ ((packed)); | ||
309 | |||
310 | union sbal_sbalf { | ||
311 | struct sbal_sbalf_0 i0; | ||
312 | struct sbal_sbalf_1 i1; | ||
313 | struct sbal_sbalf_14 i14; | ||
314 | struct sbal_sbalf_15 i15; | ||
315 | unsigned char value; | ||
316 | }; | ||
317 | |||
318 | struct sbal_element { | ||
319 | union { | ||
320 | struct sbal_flags bits; /* flags */ | ||
321 | unsigned char value; | ||
322 | } flags; | ||
323 | unsigned int res1 : 16; /* reserved */ | ||
324 | union sbal_sbalf sbalf; /* SBAL flags */ | ||
325 | unsigned int res2 : 16; /* reserved */ | ||
326 | unsigned int count : 16; /* data count */ | ||
327 | #ifdef QDIO_32_BIT | ||
328 | unsigned long res3; /* reserved */ | ||
329 | #endif /* QDIO_32_BIT */ | ||
330 | unsigned long addr; /* absolute data address */ | ||
331 | } __attribute__ ((packed,aligned(16))); | ||
332 | |||
333 | /* | ||
334 | * strorage-block access-list (SBAL) | ||
335 | */ | ||
336 | struct sbal { | ||
337 | struct sbal_element element[QDIO_MAX_ELEMENTS_PER_BUFFER]; | ||
338 | } __attribute__ ((packed,aligned(256))); | ||
339 | |||
340 | /* | ||
341 | * storage-list (SL) | ||
342 | */ | ||
343 | struct sl_element { | ||
344 | #ifdef QDIO_32_BIT | ||
345 | unsigned long res; /* reserved */ | ||
346 | #endif /* QDIO_32_BIT */ | ||
347 | unsigned long sbal; /* absolute SBAL address */ | ||
348 | } __attribute__ ((packed)); | ||
349 | |||
350 | struct sl { | ||
351 | struct sl_element element[QDIO_MAX_BUFFERS_PER_Q]; | ||
352 | } __attribute__ ((packed,aligned(1024))); | ||
353 | |||
354 | /* | ||
355 | * storage-list-state block (SLSB) | ||
356 | */ | ||
357 | struct slsb_flags { | ||
358 | unsigned char owner : 2; /* SBAL owner */ | ||
359 | unsigned char type : 1; /* buffer type */ | ||
360 | unsigned char state : 5; /* processing state */ | ||
361 | } __attribute__ ((packed)); | ||
362 | |||
363 | |||
364 | struct slsb { | ||
365 | union { | ||
366 | unsigned char val[QDIO_MAX_BUFFERS_PER_Q]; | ||
367 | struct slsb_flags flags[QDIO_MAX_BUFFERS_PER_Q]; | ||
368 | } acc; | ||
369 | } __attribute__ ((packed,aligned(256))); | ||
370 | |||
371 | /* | ||
372 | * SLSB values | ||
373 | */ | ||
374 | #define SLSB_OWNER_PROG 1 | ||
375 | #define SLSB_OWNER_CU 2 | ||
376 | |||
377 | #define SLSB_TYPE_INPUT 0 | ||
378 | #define SLSB_TYPE_OUTPUT 1 | ||
379 | |||
380 | #define SLSB_STATE_NOT_INIT 0 | ||
381 | #define SLSB_STATE_EMPTY 1 | ||
382 | #define SLSB_STATE_PRIMED 2 | ||
383 | #define SLSB_STATE_HALTED 0xe | ||
384 | #define SLSB_STATE_ERROR 0xf | ||
385 | |||
386 | #define SLSB_P_INPUT_NOT_INIT 0x80 | ||
387 | #define SLSB_P_INPUT_PROCESSING 0x81 | ||
388 | #define SLSB_CU_INPUT_EMPTY 0x41 | ||
389 | #define SLSB_P_INPUT_PRIMED 0x82 | ||
390 | #define SLSB_P_INPUT_HALTED 0x8E | ||
391 | #define SLSB_P_INPUT_ERROR 0x8F | ||
392 | |||
393 | #define SLSB_P_OUTPUT_NOT_INIT 0xA0 | ||
394 | #define SLSB_P_OUTPUT_EMPTY 0xA1 | ||
395 | #define SLSB_CU_OUTPUT_PRIMED 0x62 | ||
396 | #define SLSB_P_OUTPUT_HALTED 0xAE | ||
397 | #define SLSB_P_OUTPUT_ERROR 0xAF | ||
398 | |||
399 | #define SLSB_ERROR_DURING_LOOKUP 0xFF | ||
400 | |||
401 | #endif /* __QDIO_H__ */ | ||
diff --git a/include/asm-s390/qeth.h b/include/asm-s390/qeth.h new file mode 100644 index 000000000000..930d378ef75a --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/resource.h b/include/asm-s390/resource.h new file mode 100644 index 000000000000..366c01de04f2 --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/rwsem.h b/include/asm-s390/rwsem.h new file mode 100644 index 000000000000..8c0cebbfc034 --- /dev/null +++ b/include/asm-s390/rwsem.h | |||
@@ -0,0 +1,355 @@ | |||
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 | }; | ||
65 | |||
66 | #ifndef __s390x__ | ||
67 | #define RWSEM_UNLOCKED_VALUE 0x00000000 | ||
68 | #define RWSEM_ACTIVE_BIAS 0x00000001 | ||
69 | #define RWSEM_ACTIVE_MASK 0x0000ffff | ||
70 | #define RWSEM_WAITING_BIAS (-0x00010000) | ||
71 | #else /* __s390x__ */ | ||
72 | #define RWSEM_UNLOCKED_VALUE 0x0000000000000000L | ||
73 | #define RWSEM_ACTIVE_BIAS 0x0000000000000001L | ||
74 | #define RWSEM_ACTIVE_MASK 0x00000000ffffffffL | ||
75 | #define RWSEM_WAITING_BIAS (-0x0000000100000000L) | ||
76 | #endif /* __s390x__ */ | ||
77 | #define RWSEM_ACTIVE_READ_BIAS RWSEM_ACTIVE_BIAS | ||
78 | #define RWSEM_ACTIVE_WRITE_BIAS (RWSEM_WAITING_BIAS + RWSEM_ACTIVE_BIAS) | ||
79 | |||
80 | /* | ||
81 | * initialisation | ||
82 | */ | ||
83 | #define __RWSEM_INITIALIZER(name) \ | ||
84 | { RWSEM_UNLOCKED_VALUE, SPIN_LOCK_UNLOCKED, LIST_HEAD_INIT((name).wait_list) } | ||
85 | |||
86 | #define DECLARE_RWSEM(name) \ | ||
87 | struct rw_semaphore name = __RWSEM_INITIALIZER(name) | ||
88 | |||
89 | static inline void init_rwsem(struct rw_semaphore *sem) | ||
90 | { | ||
91 | sem->count = RWSEM_UNLOCKED_VALUE; | ||
92 | spin_lock_init(&sem->wait_lock); | ||
93 | INIT_LIST_HEAD(&sem->wait_list); | ||
94 | } | ||
95 | |||
96 | /* | ||
97 | * lock for reading | ||
98 | */ | ||
99 | static inline void __down_read(struct rw_semaphore *sem) | ||
100 | { | ||
101 | signed long old, new; | ||
102 | |||
103 | __asm__ __volatile__( | ||
104 | #ifndef __s390x__ | ||
105 | " l %0,0(%3)\n" | ||
106 | "0: lr %1,%0\n" | ||
107 | " ahi %1,%5\n" | ||
108 | " cs %0,%1,0(%3)\n" | ||
109 | " jl 0b" | ||
110 | #else /* __s390x__ */ | ||
111 | " lg %0,0(%3)\n" | ||
112 | "0: lgr %1,%0\n" | ||
113 | " aghi %1,%5\n" | ||
114 | " csg %0,%1,0(%3)\n" | ||
115 | " jl 0b" | ||
116 | #endif /* __s390x__ */ | ||
117 | : "=&d" (old), "=&d" (new), "=m" (sem->count) | ||
118 | : "a" (&sem->count), "m" (sem->count), | ||
119 | "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory" ); | ||
120 | if (old < 0) | ||
121 | rwsem_down_read_failed(sem); | ||
122 | } | ||
123 | |||
124 | /* | ||
125 | * trylock for reading -- returns 1 if successful, 0 if contention | ||
126 | */ | ||
127 | static inline int __down_read_trylock(struct rw_semaphore *sem) | ||
128 | { | ||
129 | signed long old, new; | ||
130 | |||
131 | __asm__ __volatile__( | ||
132 | #ifndef __s390x__ | ||
133 | " l %0,0(%3)\n" | ||
134 | "0: ltr %1,%0\n" | ||
135 | " jm 1f\n" | ||
136 | " ahi %1,%5\n" | ||
137 | " cs %0,%1,0(%3)\n" | ||
138 | " jl 0b\n" | ||
139 | "1:" | ||
140 | #else /* __s390x__ */ | ||
141 | " lg %0,0(%3)\n" | ||
142 | "0: ltgr %1,%0\n" | ||
143 | " jm 1f\n" | ||
144 | " aghi %1,%5\n" | ||
145 | " csg %0,%1,0(%3)\n" | ||
146 | " jl 0b\n" | ||
147 | "1:" | ||
148 | #endif /* __s390x__ */ | ||
149 | : "=&d" (old), "=&d" (new), "=m" (sem->count) | ||
150 | : "a" (&sem->count), "m" (sem->count), | ||
151 | "i" (RWSEM_ACTIVE_READ_BIAS) : "cc", "memory" ); | ||
152 | return old >= 0 ? 1 : 0; | ||
153 | } | ||
154 | |||
155 | /* | ||
156 | * lock for writing | ||
157 | */ | ||
158 | static inline void __down_write(struct rw_semaphore *sem) | ||
159 | { | ||
160 | signed long old, new, tmp; | ||
161 | |||
162 | tmp = RWSEM_ACTIVE_WRITE_BIAS; | ||
163 | __asm__ __volatile__( | ||
164 | #ifndef __s390x__ | ||
165 | " l %0,0(%3)\n" | ||
166 | "0: lr %1,%0\n" | ||
167 | " a %1,%5\n" | ||
168 | " cs %0,%1,0(%3)\n" | ||
169 | " jl 0b" | ||
170 | #else /* __s390x__ */ | ||
171 | " lg %0,0(%3)\n" | ||
172 | "0: lgr %1,%0\n" | ||
173 | " ag %1,%5\n" | ||
174 | " csg %0,%1,0(%3)\n" | ||
175 | " jl 0b" | ||
176 | #endif /* __s390x__ */ | ||
177 | : "=&d" (old), "=&d" (new), "=m" (sem->count) | ||
178 | : "a" (&sem->count), "m" (sem->count), "m" (tmp) | ||
179 | : "cc", "memory" ); | ||
180 | if (old != 0) | ||
181 | rwsem_down_write_failed(sem); | ||
182 | } | ||
183 | |||
184 | /* | ||
185 | * trylock for writing -- returns 1 if successful, 0 if contention | ||
186 | */ | ||
187 | static inline int __down_write_trylock(struct rw_semaphore *sem) | ||
188 | { | ||
189 | signed long old; | ||
190 | |||
191 | __asm__ __volatile__( | ||
192 | #ifndef __s390x__ | ||
193 | " l %0,0(%2)\n" | ||
194 | "0: ltr %0,%0\n" | ||
195 | " jnz 1f\n" | ||
196 | " cs %0,%4,0(%2)\n" | ||
197 | " jl 0b\n" | ||
198 | #else /* __s390x__ */ | ||
199 | " lg %0,0(%2)\n" | ||
200 | "0: ltgr %0,%0\n" | ||
201 | " jnz 1f\n" | ||
202 | " csg %0,%4,0(%2)\n" | ||
203 | " jl 0b\n" | ||
204 | #endif /* __s390x__ */ | ||
205 | "1:" | ||
206 | : "=&d" (old), "=m" (sem->count) | ||
207 | : "a" (&sem->count), "m" (sem->count), | ||
208 | "d" (RWSEM_ACTIVE_WRITE_BIAS) : "cc", "memory" ); | ||
209 | return (old == RWSEM_UNLOCKED_VALUE) ? 1 : 0; | ||
210 | } | ||
211 | |||
212 | /* | ||
213 | * unlock after reading | ||
214 | */ | ||
215 | static inline void __up_read(struct rw_semaphore *sem) | ||
216 | { | ||
217 | signed long old, new; | ||
218 | |||
219 | __asm__ __volatile__( | ||
220 | #ifndef __s390x__ | ||
221 | " l %0,0(%3)\n" | ||
222 | "0: lr %1,%0\n" | ||
223 | " ahi %1,%5\n" | ||
224 | " cs %0,%1,0(%3)\n" | ||
225 | " jl 0b" | ||
226 | #else /* __s390x__ */ | ||
227 | " lg %0,0(%3)\n" | ||
228 | "0: lgr %1,%0\n" | ||
229 | " aghi %1,%5\n" | ||
230 | " csg %0,%1,0(%3)\n" | ||
231 | " jl 0b" | ||
232 | #endif /* __s390x__ */ | ||
233 | : "=&d" (old), "=&d" (new), "=m" (sem->count) | ||
234 | : "a" (&sem->count), "m" (sem->count), | ||
235 | "i" (-RWSEM_ACTIVE_READ_BIAS) | ||
236 | : "cc", "memory" ); | ||
237 | if (new < 0) | ||
238 | if ((new & RWSEM_ACTIVE_MASK) == 0) | ||
239 | rwsem_wake(sem); | ||
240 | } | ||
241 | |||
242 | /* | ||
243 | * unlock after writing | ||
244 | */ | ||
245 | static inline void __up_write(struct rw_semaphore *sem) | ||
246 | { | ||
247 | signed long old, new, tmp; | ||
248 | |||
249 | tmp = -RWSEM_ACTIVE_WRITE_BIAS; | ||
250 | __asm__ __volatile__( | ||
251 | #ifndef __s390x__ | ||
252 | " l %0,0(%3)\n" | ||
253 | "0: lr %1,%0\n" | ||
254 | " a %1,%5\n" | ||
255 | " cs %0,%1,0(%3)\n" | ||
256 | " jl 0b" | ||
257 | #else /* __s390x__ */ | ||
258 | " lg %0,0(%3)\n" | ||
259 | "0: lgr %1,%0\n" | ||
260 | " ag %1,%5\n" | ||
261 | " csg %0,%1,0(%3)\n" | ||
262 | " jl 0b" | ||
263 | #endif /* __s390x__ */ | ||
264 | : "=&d" (old), "=&d" (new), "=m" (sem->count) | ||
265 | : "a" (&sem->count), "m" (sem->count), "m" (tmp) | ||
266 | : "cc", "memory" ); | ||
267 | if (new < 0) | ||
268 | if ((new & RWSEM_ACTIVE_MASK) == 0) | ||
269 | rwsem_wake(sem); | ||
270 | } | ||
271 | |||
272 | /* | ||
273 | * downgrade write lock to read lock | ||
274 | */ | ||
275 | static inline void __downgrade_write(struct rw_semaphore *sem) | ||
276 | { | ||
277 | signed long old, new, tmp; | ||
278 | |||
279 | tmp = -RWSEM_WAITING_BIAS; | ||
280 | __asm__ __volatile__( | ||
281 | #ifndef __s390x__ | ||
282 | " l %0,0(%3)\n" | ||
283 | "0: lr %1,%0\n" | ||
284 | " a %1,%5\n" | ||
285 | " cs %0,%1,0(%3)\n" | ||
286 | " jl 0b" | ||
287 | #else /* __s390x__ */ | ||
288 | " lg %0,0(%3)\n" | ||
289 | "0: lgr %1,%0\n" | ||
290 | " ag %1,%5\n" | ||
291 | " csg %0,%1,0(%3)\n" | ||
292 | " jl 0b" | ||
293 | #endif /* __s390x__ */ | ||
294 | : "=&d" (old), "=&d" (new), "=m" (sem->count) | ||
295 | : "a" (&sem->count), "m" (sem->count), "m" (tmp) | ||
296 | : "cc", "memory" ); | ||
297 | if (new > 1) | ||
298 | rwsem_downgrade_wake(sem); | ||
299 | } | ||
300 | |||
301 | /* | ||
302 | * implement atomic add functionality | ||
303 | */ | ||
304 | static inline void rwsem_atomic_add(long delta, struct rw_semaphore *sem) | ||
305 | { | ||
306 | signed long old, new; | ||
307 | |||
308 | __asm__ __volatile__( | ||
309 | #ifndef __s390x__ | ||
310 | " l %0,0(%3)\n" | ||
311 | "0: lr %1,%0\n" | ||
312 | " ar %1,%5\n" | ||
313 | " cs %0,%1,0(%3)\n" | ||
314 | " jl 0b" | ||
315 | #else /* __s390x__ */ | ||
316 | " lg %0,0(%3)\n" | ||
317 | "0: lgr %1,%0\n" | ||
318 | " agr %1,%5\n" | ||
319 | " csg %0,%1,0(%3)\n" | ||
320 | " jl 0b" | ||
321 | #endif /* __s390x__ */ | ||
322 | : "=&d" (old), "=&d" (new), "=m" (sem->count) | ||
323 | : "a" (&sem->count), "m" (sem->count), "d" (delta) | ||
324 | : "cc", "memory" ); | ||
325 | } | ||
326 | |||
327 | /* | ||
328 | * implement exchange and add functionality | ||
329 | */ | ||
330 | static inline long rwsem_atomic_update(long delta, struct rw_semaphore *sem) | ||
331 | { | ||
332 | signed long old, new; | ||
333 | |||
334 | __asm__ __volatile__( | ||
335 | #ifndef __s390x__ | ||
336 | " l %0,0(%3)\n" | ||
337 | "0: lr %1,%0\n" | ||
338 | " ar %1,%5\n" | ||
339 | " cs %0,%1,0(%3)\n" | ||
340 | " jl 0b" | ||
341 | #else /* __s390x__ */ | ||
342 | " lg %0,0(%3)\n" | ||
343 | "0: lgr %1,%0\n" | ||
344 | " agr %1,%5\n" | ||
345 | " csg %0,%1,0(%3)\n" | ||
346 | " jl 0b" | ||
347 | #endif /* __s390x__ */ | ||
348 | : "=&d" (old), "=&d" (new), "=m" (sem->count) | ||
349 | : "a" (&sem->count), "m" (sem->count), "d" (delta) | ||
350 | : "cc", "memory" ); | ||
351 | return new; | ||
352 | } | ||
353 | |||
354 | #endif /* __KERNEL__ */ | ||
355 | #endif /* _S390_RWSEM_H */ | ||
diff --git a/include/asm-s390/s390_ext.h b/include/asm-s390/s390_ext.h new file mode 100644 index 000000000000..e9a2862b230d --- /dev/null +++ b/include/asm-s390/s390_ext.h | |||
@@ -0,0 +1,34 @@ | |||
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 (C) 1999,2000 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
9 | * Author(s): Holger Smolinski (Holger.Smolinski@de.ibm.com), | ||
10 | * Martin Schwidefsky (schwidefsky@de.ibm.com) | ||
11 | */ | ||
12 | |||
13 | typedef void (*ext_int_handler_t)(struct pt_regs *regs, __u16 code); | ||
14 | |||
15 | /* | ||
16 | * Warning: if you change ext_int_info_t you have to change the | ||
17 | * external interrupt handler in entry.S too. | ||
18 | */ | ||
19 | typedef struct ext_int_info_t { | ||
20 | struct ext_int_info_t *next; | ||
21 | ext_int_handler_t handler; | ||
22 | __u16 code; | ||
23 | } __attribute__ ((packed)) ext_int_info_t; | ||
24 | |||
25 | extern ext_int_info_t *ext_int_hash[]; | ||
26 | |||
27 | int register_external_interrupt(__u16 code, ext_int_handler_t handler); | ||
28 | int register_early_external_interrupt(__u16 code, ext_int_handler_t handler, | ||
29 | ext_int_info_t *info); | ||
30 | int unregister_external_interrupt(__u16 code, ext_int_handler_t handler); | ||
31 | int unregister_early_external_interrupt(__u16 code, ext_int_handler_t handler, | ||
32 | ext_int_info_t *info); | ||
33 | |||
34 | #endif | ||
diff --git a/include/asm-s390/scatterlist.h b/include/asm-s390/scatterlist.h new file mode 100644 index 000000000000..a43b3afc5e2d --- /dev/null +++ b/include/asm-s390/scatterlist.h | |||
@@ -0,0 +1,16 @@ | |||
1 | #ifndef _ASMS390_SCATTERLIST_H | ||
2 | #define _ASMS390_SCATTERLIST_H | ||
3 | |||
4 | struct scatterlist { | ||
5 | struct page *page; | ||
6 | unsigned int offset; | ||
7 | unsigned int length; | ||
8 | }; | ||
9 | |||
10 | #ifdef __s390x__ | ||
11 | #define ISA_DMA_THRESHOLD (0xffffffffffffffffUL) | ||
12 | #else | ||
13 | #define ISA_DMA_THRESHOLD (0xffffffffUL) | ||
14 | #endif | ||
15 | |||
16 | #endif /* _ASMS390X_SCATTERLIST_H */ | ||
diff --git a/include/asm-s390/sections.h b/include/asm-s390/sections.h new file mode 100644 index 000000000000..3a0b8ffeab7a --- /dev/null +++ b/include/asm-s390/sections.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef _S390_SECTIONS_H | ||
2 | #define _S390_SECTIONS_H | ||
3 | |||
4 | #include <asm-generic/sections.h> | ||
5 | |||
6 | #endif | ||
diff --git a/include/asm-s390/segment.h b/include/asm-s390/segment.h new file mode 100644 index 000000000000..8bfce3475b1c --- /dev/null +++ b/include/asm-s390/segment.h | |||
@@ -0,0 +1,4 @@ | |||
1 | #ifndef _ASM_SEGMENT_H | ||
2 | #define _ASM_SEGMENT_H | ||
3 | |||
4 | #endif | ||
diff --git a/include/asm-s390/semaphore.h b/include/asm-s390/semaphore.h new file mode 100644 index 000000000000..873def6f363a --- /dev/null +++ b/include/asm-s390/semaphore.h | |||
@@ -0,0 +1,110 @@ | |||
1 | /* | ||
2 | * include/asm-s390/semaphore.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | * | ||
7 | * Derived from "include/asm-i386/semaphore.h" | ||
8 | * (C) Copyright 1996 Linus Torvalds | ||
9 | */ | ||
10 | |||
11 | #ifndef _S390_SEMAPHORE_H | ||
12 | #define _S390_SEMAPHORE_H | ||
13 | |||
14 | #include <asm/system.h> | ||
15 | #include <asm/atomic.h> | ||
16 | #include <linux/wait.h> | ||
17 | #include <linux/rwsem.h> | ||
18 | |||
19 | struct semaphore { | ||
20 | /* | ||
21 | * Note that any negative value of count is equivalent to 0, | ||
22 | * but additionally indicates that some process(es) might be | ||
23 | * sleeping on `wait'. | ||
24 | */ | ||
25 | atomic_t count; | ||
26 | wait_queue_head_t wait; | ||
27 | }; | ||
28 | |||
29 | #define __SEMAPHORE_INITIALIZER(name,count) \ | ||
30 | { ATOMIC_INIT(count), __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) } | ||
31 | |||
32 | #define __MUTEX_INITIALIZER(name) \ | ||
33 | __SEMAPHORE_INITIALIZER(name,1) | ||
34 | |||
35 | #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ | ||
36 | struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) | ||
37 | |||
38 | #define DECLARE_MUTEX(name) __DECLARE_SEMAPHORE_GENERIC(name,1) | ||
39 | #define DECLARE_MUTEX_LOCKED(name) __DECLARE_SEMAPHORE_GENERIC(name,0) | ||
40 | |||
41 | static inline void sema_init (struct semaphore *sem, int val) | ||
42 | { | ||
43 | *sem = (struct semaphore) __SEMAPHORE_INITIALIZER((*sem),val); | ||
44 | } | ||
45 | |||
46 | static inline void init_MUTEX (struct semaphore *sem) | ||
47 | { | ||
48 | sema_init(sem, 1); | ||
49 | } | ||
50 | |||
51 | static inline void init_MUTEX_LOCKED (struct semaphore *sem) | ||
52 | { | ||
53 | sema_init(sem, 0); | ||
54 | } | ||
55 | |||
56 | asmlinkage void __down(struct semaphore * sem); | ||
57 | asmlinkage int __down_interruptible(struct semaphore * sem); | ||
58 | asmlinkage int __down_trylock(struct semaphore * sem); | ||
59 | asmlinkage void __up(struct semaphore * sem); | ||
60 | |||
61 | static inline void down(struct semaphore * sem) | ||
62 | { | ||
63 | might_sleep(); | ||
64 | if (atomic_dec_return(&sem->count) < 0) | ||
65 | __down(sem); | ||
66 | } | ||
67 | |||
68 | static inline int down_interruptible(struct semaphore * sem) | ||
69 | { | ||
70 | int ret = 0; | ||
71 | |||
72 | might_sleep(); | ||
73 | if (atomic_dec_return(&sem->count) < 0) | ||
74 | ret = __down_interruptible(sem); | ||
75 | return ret; | ||
76 | } | ||
77 | |||
78 | static inline int down_trylock(struct semaphore * sem) | ||
79 | { | ||
80 | int old_val, new_val; | ||
81 | |||
82 | /* | ||
83 | * This inline assembly atomically implements the equivalent | ||
84 | * to the following C code: | ||
85 | * old_val = sem->count.counter; | ||
86 | * if ((new_val = old_val) > 0) | ||
87 | * sem->count.counter = --new_val; | ||
88 | * In the ppc code this is called atomic_dec_if_positive. | ||
89 | */ | ||
90 | __asm__ __volatile__ ( | ||
91 | " l %0,0(%3)\n" | ||
92 | "0: ltr %1,%0\n" | ||
93 | " jle 1f\n" | ||
94 | " ahi %1,-1\n" | ||
95 | " cs %0,%1,0(%3)\n" | ||
96 | " jl 0b\n" | ||
97 | "1:" | ||
98 | : "=&d" (old_val), "=&d" (new_val), "=m" (sem->count.counter) | ||
99 | : "a" (&sem->count.counter), "m" (sem->count.counter) | ||
100 | : "cc", "memory" ); | ||
101 | return old_val <= 0; | ||
102 | } | ||
103 | |||
104 | static inline void up(struct semaphore * sem) | ||
105 | { | ||
106 | if (atomic_inc_return(&sem->count) <= 0) | ||
107 | __up(sem); | ||
108 | } | ||
109 | |||
110 | #endif | ||
diff --git a/include/asm-s390/sembuf.h b/include/asm-s390/sembuf.h new file mode 100644 index 000000000000..32626b0cac4b --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/setup.h b/include/asm-s390/setup.h new file mode 100644 index 000000000000..0d51c484c2ea --- /dev/null +++ b/include/asm-s390/setup.h | |||
@@ -0,0 +1,82 @@ | |||
1 | /* | ||
2 | * include/asm-s390/setup.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 1999 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
6 | */ | ||
7 | |||
8 | #ifndef _ASM_S390_SETUP_H | ||
9 | #define _ASM_S390_SETUP_H | ||
10 | |||
11 | #define PARMAREA 0x10400 | ||
12 | #define COMMAND_LINE_SIZE 896 | ||
13 | #define RAMDISK_ORIGIN 0x800000 | ||
14 | #define RAMDISK_SIZE 0x800000 | ||
15 | #define MEMORY_CHUNKS 16 /* max 0x7fff */ | ||
16 | |||
17 | #ifndef __ASSEMBLY__ | ||
18 | |||
19 | #ifndef __s390x__ | ||
20 | #define IPL_DEVICE (*(unsigned long *) (0x10404)) | ||
21 | #define INITRD_START (*(unsigned long *) (0x1040C)) | ||
22 | #define INITRD_SIZE (*(unsigned long *) (0x10414)) | ||
23 | #else /* __s390x__ */ | ||
24 | #define IPL_DEVICE (*(unsigned long *) (0x10400)) | ||
25 | #define INITRD_START (*(unsigned long *) (0x10408)) | ||
26 | #define INITRD_SIZE (*(unsigned long *) (0x10410)) | ||
27 | #endif /* __s390x__ */ | ||
28 | #define COMMAND_LINE ((char *) (0x10480)) | ||
29 | |||
30 | /* | ||
31 | * Machine features detected in head.S | ||
32 | */ | ||
33 | extern unsigned long machine_flags; | ||
34 | |||
35 | #define MACHINE_IS_VM (machine_flags & 1) | ||
36 | #define MACHINE_IS_P390 (machine_flags & 4) | ||
37 | #define MACHINE_HAS_MVPG (machine_flags & 16) | ||
38 | #define MACHINE_HAS_DIAG44 (machine_flags & 32) | ||
39 | #define MACHINE_HAS_IDTE (machine_flags & 128) | ||
40 | |||
41 | #ifndef __s390x__ | ||
42 | #define MACHINE_HAS_IEEE (machine_flags & 2) | ||
43 | #define MACHINE_HAS_CSP (machine_flags & 8) | ||
44 | #else /* __s390x__ */ | ||
45 | #define MACHINE_HAS_IEEE (1) | ||
46 | #define MACHINE_HAS_CSP (1) | ||
47 | #endif /* __s390x__ */ | ||
48 | |||
49 | |||
50 | #define MACHINE_HAS_SCLP (!MACHINE_IS_P390) | ||
51 | |||
52 | /* | ||
53 | * Console mode. Override with conmode= | ||
54 | */ | ||
55 | extern unsigned int console_mode; | ||
56 | extern unsigned int console_devno; | ||
57 | extern unsigned int console_irq; | ||
58 | |||
59 | #define CONSOLE_IS_UNDEFINED (console_mode == 0) | ||
60 | #define CONSOLE_IS_SCLP (console_mode == 1) | ||
61 | #define CONSOLE_IS_3215 (console_mode == 2) | ||
62 | #define CONSOLE_IS_3270 (console_mode == 3) | ||
63 | #define SET_CONSOLE_SCLP do { console_mode = 1; } while (0) | ||
64 | #define SET_CONSOLE_3215 do { console_mode = 2; } while (0) | ||
65 | #define SET_CONSOLE_3270 do { console_mode = 3; } while (0) | ||
66 | |||
67 | #else | ||
68 | |||
69 | #ifndef __s390x__ | ||
70 | #define IPL_DEVICE 0x10404 | ||
71 | #define INITRD_START 0x1040C | ||
72 | #define INITRD_SIZE 0x10414 | ||
73 | #else /* __s390x__ */ | ||
74 | #define IPL_DEVICE 0x10400 | ||
75 | #define INITRD_START 0x10408 | ||
76 | #define INITRD_SIZE 0x10410 | ||
77 | #endif /* __s390x__ */ | ||
78 | #define COMMAND_LINE 0x10480 | ||
79 | |||
80 | #endif | ||
81 | |||
82 | #endif | ||
diff --git a/include/asm-s390/sfp-machine.h b/include/asm-s390/sfp-machine.h new file mode 100644 index 000000000000..3c79b5384f44 --- /dev/null +++ b/include/asm-s390/sfp-machine.h | |||
@@ -0,0 +1,139 @@ | |||
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 | #include <linux/config.h> | ||
29 | |||
30 | #define _FP_W_TYPE_SIZE 32 | ||
31 | #define _FP_W_TYPE unsigned long | ||
32 | #define _FP_WS_TYPE signed long | ||
33 | #define _FP_I_TYPE long | ||
34 | |||
35 | #define _FP_MUL_MEAT_S(R,X,Y) \ | ||
36 | _FP_MUL_MEAT_1_wide(_FP_WFRACBITS_S,R,X,Y,umul_ppmm) | ||
37 | #define _FP_MUL_MEAT_D(R,X,Y) \ | ||
38 | _FP_MUL_MEAT_2_wide(_FP_WFRACBITS_D,R,X,Y,umul_ppmm) | ||
39 | #define _FP_MUL_MEAT_Q(R,X,Y) \ | ||
40 | _FP_MUL_MEAT_4_wide(_FP_WFRACBITS_Q,R,X,Y,umul_ppmm) | ||
41 | |||
42 | #define _FP_DIV_MEAT_S(R,X,Y) _FP_DIV_MEAT_1_udiv(S,R,X,Y) | ||
43 | #define _FP_DIV_MEAT_D(R,X,Y) _FP_DIV_MEAT_2_udiv(D,R,X,Y) | ||
44 | #define _FP_DIV_MEAT_Q(R,X,Y) _FP_DIV_MEAT_4_udiv(Q,R,X,Y) | ||
45 | |||
46 | #define _FP_NANFRAC_S ((_FP_QNANBIT_S << 1) - 1) | ||
47 | #define _FP_NANFRAC_D ((_FP_QNANBIT_D << 1) - 1), -1 | ||
48 | #define _FP_NANFRAC_Q ((_FP_QNANBIT_Q << 1) - 1), -1, -1, -1 | ||
49 | #define _FP_NANSIGN_S 0 | ||
50 | #define _FP_NANSIGN_D 0 | ||
51 | #define _FP_NANSIGN_Q 0 | ||
52 | |||
53 | #define _FP_KEEPNANFRACP 1 | ||
54 | |||
55 | /* | ||
56 | * If one NaN is signaling and the other is not, | ||
57 | * we choose that one, otherwise we choose X. | ||
58 | */ | ||
59 | #define _FP_CHOOSENAN(fs, wc, R, X, Y, OP) \ | ||
60 | do { \ | ||
61 | if ((_FP_FRAC_HIGH_RAW_##fs(X) & _FP_QNANBIT_##fs) \ | ||
62 | && !(_FP_FRAC_HIGH_RAW_##fs(Y) & _FP_QNANBIT_##fs)) \ | ||
63 | { \ | ||
64 | R##_s = Y##_s; \ | ||
65 | _FP_FRAC_COPY_##wc(R,Y); \ | ||
66 | } \ | ||
67 | else \ | ||
68 | { \ | ||
69 | R##_s = X##_s; \ | ||
70 | _FP_FRAC_COPY_##wc(R,X); \ | ||
71 | } \ | ||
72 | R##_c = FP_CLS_NAN; \ | ||
73 | } while (0) | ||
74 | |||
75 | /* Some assembly to speed things up. */ | ||
76 | #define __FP_FRAC_ADD_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) ({ \ | ||
77 | unsigned int __r2 = (x2) + (y2); \ | ||
78 | unsigned int __r1 = (x1); \ | ||
79 | unsigned int __r0 = (x0); \ | ||
80 | __asm__ (" 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__ (" alr %1,%2\n" \ | ||
90 | " brc 12,0f\n" \ | ||
91 | " ahi %0,1\n" \ | ||
92 | "0:" \ | ||
93 | : "+&d" (__r2), "+&d" (__r1) \ | ||
94 | : "d" (y1) : "cc" ); \ | ||
95 | (r2) = __r2; \ | ||
96 | (r1) = __r1; \ | ||
97 | (r0) = __r0; \ | ||
98 | }) | ||
99 | |||
100 | #define __FP_FRAC_SUB_3(r2,r1,r0,x2,x1,x0,y2,y1,y0) ({ \ | ||
101 | unsigned int __r2 = (x2) - (y2); \ | ||
102 | unsigned int __r1 = (x1); \ | ||
103 | unsigned int __r0 = (x0); \ | ||
104 | __asm__ (" slr %2,%3\n" \ | ||
105 | " brc 3,0f\n" \ | ||
106 | " lhi 0,1\n" \ | ||
107 | " slr %1,0\n" \ | ||
108 | " brc 3,0f\n" \ | ||
109 | " slr %0,0\n" \ | ||
110 | "0:" \ | ||
111 | : "+&d" (__r2), "+&d" (__r1), "+&d" (__r0) \ | ||
112 | : "d" (y0) : "cc", "0" ); \ | ||
113 | __asm__ (" slr %1,%2\n" \ | ||
114 | " brc 3,0f\n" \ | ||
115 | " ahi %0,-1\n" \ | ||
116 | "0:" \ | ||
117 | : "+&d" (__r2), "+&d" (__r1) \ | ||
118 | : "d" (y1) : "cc" ); \ | ||
119 | (r2) = __r2; \ | ||
120 | (r1) = __r1; \ | ||
121 | (r0) = __r0; \ | ||
122 | }) | ||
123 | |||
124 | #define __FP_FRAC_DEC_3(x2,x1,x0,y2,y1,y0) __FP_FRAC_SUB_3(x2,x1,x0,x2,x1,x0,y2,y1,y0) | ||
125 | |||
126 | /* Obtain the current rounding mode. */ | ||
127 | #define FP_ROUNDMODE mode | ||
128 | |||
129 | /* Exception flags. */ | ||
130 | #define FP_EX_INVALID 0x800000 | ||
131 | #define FP_EX_DIVZERO 0x400000 | ||
132 | #define FP_EX_OVERFLOW 0x200000 | ||
133 | #define FP_EX_UNDERFLOW 0x100000 | ||
134 | #define FP_EX_INEXACT 0x080000 | ||
135 | |||
136 | /* We write the results always */ | ||
137 | #define FP_INHIBIT_RESULTS 0 | ||
138 | |||
139 | #endif | ||
diff --git a/include/asm-s390/shmbuf.h b/include/asm-s390/shmbuf.h new file mode 100644 index 000000000000..eed2e280ce37 --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/shmparam.h b/include/asm-s390/shmparam.h new file mode 100644 index 000000000000..c2e0c0508e73 --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/sigcontext.h b/include/asm-s390/sigcontext.h new file mode 100644 index 000000000000..d57bc0cebdce --- /dev/null +++ b/include/asm-s390/sigcontext.h | |||
@@ -0,0 +1,69 @@ | |||
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 | #define __NUM_GPRS 16 | ||
12 | #define __NUM_FPRS 16 | ||
13 | #define __NUM_ACRS 16 | ||
14 | |||
15 | #ifndef __s390x__ | ||
16 | |||
17 | /* Has to be at least _NSIG_WORDS from asm/signal.h */ | ||
18 | #define _SIGCONTEXT_NSIG 64 | ||
19 | #define _SIGCONTEXT_NSIG_BPW 32 | ||
20 | /* Size of stack frame allocated when calling signal handler. */ | ||
21 | #define __SIGNAL_FRAMESIZE 96 | ||
22 | |||
23 | #else /* __s390x__ */ | ||
24 | |||
25 | /* Has to be at least _NSIG_WORDS from asm/signal.h */ | ||
26 | #define _SIGCONTEXT_NSIG 64 | ||
27 | #define _SIGCONTEXT_NSIG_BPW 64 | ||
28 | /* Size of stack frame allocated when calling signal handler. */ | ||
29 | #define __SIGNAL_FRAMESIZE 160 | ||
30 | |||
31 | #endif /* __s390x__ */ | ||
32 | |||
33 | #define _SIGCONTEXT_NSIG_WORDS (_SIGCONTEXT_NSIG / _SIGCONTEXT_NSIG_BPW) | ||
34 | #define _SIGMASK_COPY_SIZE (sizeof(unsigned long)*_SIGCONTEXT_NSIG_WORDS) | ||
35 | |||
36 | typedef struct | ||
37 | { | ||
38 | unsigned long mask; | ||
39 | unsigned long addr; | ||
40 | } __attribute__ ((aligned(8))) _psw_t; | ||
41 | |||
42 | typedef struct | ||
43 | { | ||
44 | _psw_t psw; | ||
45 | unsigned long gprs[__NUM_GPRS]; | ||
46 | unsigned int acrs[__NUM_ACRS]; | ||
47 | } _s390_regs_common; | ||
48 | |||
49 | typedef struct | ||
50 | { | ||
51 | unsigned int fpc; | ||
52 | double fprs[__NUM_FPRS]; | ||
53 | } _s390_fp_regs; | ||
54 | |||
55 | typedef struct | ||
56 | { | ||
57 | _s390_regs_common regs; | ||
58 | _s390_fp_regs fpregs; | ||
59 | } _sigregs; | ||
60 | |||
61 | struct sigcontext | ||
62 | { | ||
63 | unsigned long oldmask[_SIGCONTEXT_NSIG_WORDS]; | ||
64 | _sigregs *sregs; | ||
65 | }; | ||
66 | |||
67 | |||
68 | #endif | ||
69 | |||
diff --git a/include/asm-s390/siginfo.h b/include/asm-s390/siginfo.h new file mode 100644 index 000000000000..72303537b732 --- /dev/null +++ b/include/asm-s390/siginfo.h | |||
@@ -0,0 +1,24 @@ | |||
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 | #ifdef CONFIG_ARCH_S390X | ||
17 | #define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 4) | ||
18 | #else | ||
19 | #define SIGEV_PAD_SIZE ((SIGEV_MAX_SIZE/sizeof(int)) - 3) | ||
20 | #endif | ||
21 | |||
22 | #include <asm-generic/siginfo.h> | ||
23 | |||
24 | #endif | ||
diff --git a/include/asm-s390/signal.h b/include/asm-s390/signal.h new file mode 100644 index 000000000000..f273cdcd1cf6 --- /dev/null +++ b/include/asm-s390/signal.h | |||
@@ -0,0 +1,197 @@ | |||
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_INTERRUPT is a no-op, but left due to historical reasons. Use the | ||
88 | * SA_RESTART flag to get restarting signals (which were the default long ago) | ||
89 | * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. | ||
90 | * SA_RESETHAND clears the handler when the signal is delivered. | ||
91 | * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. | ||
92 | * SA_NODEFER prevents the current signal from being masked in the handler. | ||
93 | * | ||
94 | * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single | ||
95 | * Unix names RESETHAND and NODEFER respectively. | ||
96 | */ | ||
97 | #define SA_NOCLDSTOP 0x00000001 | ||
98 | #define SA_NOCLDWAIT 0x00000002 | ||
99 | #define SA_SIGINFO 0x00000004 | ||
100 | #define SA_ONSTACK 0x08000000 | ||
101 | #define SA_RESTART 0x10000000 | ||
102 | #define SA_NODEFER 0x40000000 | ||
103 | #define SA_RESETHAND 0x80000000 | ||
104 | |||
105 | #define SA_NOMASK SA_NODEFER | ||
106 | #define SA_ONESHOT SA_RESETHAND | ||
107 | #define SA_INTERRUPT 0x20000000 /* dummy -- ignored */ | ||
108 | |||
109 | #define SA_RESTORER 0x04000000 | ||
110 | |||
111 | /* | ||
112 | * sigaltstack controls | ||
113 | */ | ||
114 | #define SS_ONSTACK 1 | ||
115 | #define SS_DISABLE 2 | ||
116 | |||
117 | #define MINSIGSTKSZ 2048 | ||
118 | #define SIGSTKSZ 8192 | ||
119 | |||
120 | #ifdef __KERNEL__ | ||
121 | |||
122 | /* | ||
123 | * These values of sa_flags are used only by the kernel as part of the | ||
124 | * irq handling routines. | ||
125 | * | ||
126 | * SA_INTERRUPT is also used by the irq handling routines. | ||
127 | * SA_SHIRQ is for shared interrupt support on PCI and EISA. | ||
128 | */ | ||
129 | #define SA_PROBE SA_ONESHOT | ||
130 | #define SA_SAMPLE_RANDOM SA_RESTART | ||
131 | #define SA_SHIRQ 0x04000000 | ||
132 | #endif | ||
133 | |||
134 | #define SIG_BLOCK 0 /* for blocking signals */ | ||
135 | #define SIG_UNBLOCK 1 /* for unblocking signals */ | ||
136 | #define SIG_SETMASK 2 /* for setting the signal mask */ | ||
137 | |||
138 | /* Type of a signal handler. */ | ||
139 | typedef void (*__sighandler_t)(int); | ||
140 | |||
141 | #define SIG_DFL ((__sighandler_t)0) /* default signal handling */ | ||
142 | #define SIG_IGN ((__sighandler_t)1) /* ignore signal */ | ||
143 | #define SIG_ERR ((__sighandler_t)-1) /* error return from signal */ | ||
144 | |||
145 | #ifdef __KERNEL__ | ||
146 | struct old_sigaction { | ||
147 | __sighandler_t sa_handler; | ||
148 | old_sigset_t sa_mask; | ||
149 | unsigned long sa_flags; | ||
150 | void (*sa_restorer)(void); | ||
151 | }; | ||
152 | |||
153 | struct sigaction { | ||
154 | __sighandler_t sa_handler; | ||
155 | unsigned long sa_flags; | ||
156 | void (*sa_restorer)(void); | ||
157 | sigset_t sa_mask; /* mask last for extensibility */ | ||
158 | }; | ||
159 | |||
160 | struct k_sigaction { | ||
161 | struct sigaction sa; | ||
162 | }; | ||
163 | |||
164 | #define ptrace_signal_deliver(regs, cookie) do { } while (0) | ||
165 | |||
166 | #else | ||
167 | /* Here we must cater to libcs that poke about in kernel headers. */ | ||
168 | |||
169 | struct sigaction { | ||
170 | union { | ||
171 | __sighandler_t _sa_handler; | ||
172 | void (*_sa_sigaction)(int, struct siginfo *, void *); | ||
173 | } _u; | ||
174 | #ifndef __s390x__ /* lovely */ | ||
175 | sigset_t sa_mask; | ||
176 | unsigned long sa_flags; | ||
177 | void (*sa_restorer)(void); | ||
178 | #else /* __s390x__ */ | ||
179 | unsigned long sa_flags; | ||
180 | void (*sa_restorer)(void); | ||
181 | sigset_t sa_mask; | ||
182 | #endif /* __s390x__ */ | ||
183 | }; | ||
184 | |||
185 | #define sa_handler _u._sa_handler | ||
186 | #define sa_sigaction _u._sa_sigaction | ||
187 | |||
188 | #endif /* __KERNEL__ */ | ||
189 | |||
190 | typedef struct sigaltstack { | ||
191 | void *ss_sp; | ||
192 | int ss_flags; | ||
193 | size_t ss_size; | ||
194 | } stack_t; | ||
195 | |||
196 | |||
197 | #endif | ||
diff --git a/include/asm-s390/sigp.h b/include/asm-s390/sigp.h new file mode 100644 index 000000000000..3979bc3858e2 --- /dev/null +++ b/include/asm-s390/sigp.h | |||
@@ -0,0 +1,131 @@ | |||
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 | extern __inline__ sigp_ccode | ||
71 | signal_processor(__u16 cpu_addr, sigp_order_code order_code) | ||
72 | { | ||
73 | sigp_ccode ccode; | ||
74 | |||
75 | __asm__ __volatile__( | ||
76 | " sr 1,1\n" /* parameter=0 in gpr 1 */ | ||
77 | " sigp 1,%1,0(%2)\n" | ||
78 | " ipm %0\n" | ||
79 | " srl %0,28\n" | ||
80 | : "=d" (ccode) | ||
81 | : "d" (__cpu_logical_map[cpu_addr]), "a" (order_code) | ||
82 | : "cc" , "memory", "1" ); | ||
83 | return ccode; | ||
84 | } | ||
85 | |||
86 | /* | ||
87 | * Signal processor with parameter | ||
88 | */ | ||
89 | extern __inline__ sigp_ccode | ||
90 | signal_processor_p(__u32 parameter, __u16 cpu_addr, | ||
91 | sigp_order_code order_code) | ||
92 | { | ||
93 | sigp_ccode ccode; | ||
94 | |||
95 | __asm__ __volatile__( | ||
96 | " lr 1,%1\n" /* parameter in gpr 1 */ | ||
97 | " sigp 1,%2,0(%3)\n" | ||
98 | " ipm %0\n" | ||
99 | " srl %0,28\n" | ||
100 | : "=d" (ccode) | ||
101 | : "d" (parameter), "d" (__cpu_logical_map[cpu_addr]), | ||
102 | "a" (order_code) | ||
103 | : "cc" , "memory", "1" ); | ||
104 | return ccode; | ||
105 | } | ||
106 | |||
107 | /* | ||
108 | * Signal processor with parameter and return status | ||
109 | */ | ||
110 | extern __inline__ sigp_ccode | ||
111 | signal_processor_ps(__u32 *statusptr, __u32 parameter, | ||
112 | __u16 cpu_addr, sigp_order_code order_code) | ||
113 | { | ||
114 | sigp_ccode ccode; | ||
115 | |||
116 | __asm__ __volatile__( | ||
117 | " sr 2,2\n" /* clear status */ | ||
118 | " lr 3,%2\n" /* parameter in gpr 3 */ | ||
119 | " sigp 2,%3,0(%4)\n" | ||
120 | " st 2,%1\n" | ||
121 | " ipm %0\n" | ||
122 | " srl %0,28\n" | ||
123 | : "=d" (ccode), "=m" (*statusptr) | ||
124 | : "d" (parameter), "d" (__cpu_logical_map[cpu_addr]), | ||
125 | "a" (order_code) | ||
126 | : "cc" , "memory", "2" , "3" | ||
127 | ); | ||
128 | return ccode; | ||
129 | } | ||
130 | |||
131 | #endif /* __SIGP__ */ | ||
diff --git a/include/asm-s390/smp.h b/include/asm-s390/smp.h new file mode 100644 index 000000000000..9473786387a3 --- /dev/null +++ b/include/asm-s390/smp.h | |||
@@ -0,0 +1,108 @@ | |||
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/config.h> | ||
14 | #include <linux/threads.h> | ||
15 | #include <linux/cpumask.h> | ||
16 | #include <linux/bitops.h> | ||
17 | |||
18 | #if defined(__KERNEL__) && defined(CONFIG_SMP) && !defined(__ASSEMBLY__) | ||
19 | |||
20 | #include <asm/lowcore.h> | ||
21 | #include <asm/sigp.h> | ||
22 | |||
23 | /* | ||
24 | s390 specific smp.c headers | ||
25 | */ | ||
26 | typedef struct | ||
27 | { | ||
28 | int intresting; | ||
29 | sigp_ccode ccode; | ||
30 | __u32 status; | ||
31 | __u16 cpu; | ||
32 | } sigp_info; | ||
33 | |||
34 | extern int smp_call_function_on(void (*func) (void *info), void *info, | ||
35 | int nonatomic, int wait, int cpu); | ||
36 | #define NO_PROC_ID 0xFF /* No processor magic marker */ | ||
37 | |||
38 | /* | ||
39 | * This magic constant controls our willingness to transfer | ||
40 | * a process across CPUs. Such a transfer incurs misses on the L1 | ||
41 | * cache, and on a P6 or P5 with multiple L2 caches L2 hits. My | ||
42 | * gut feeling is this will vary by board in value. For a board | ||
43 | * with separate L2 cache it probably depends also on the RSS, and | ||
44 | * for a board with shared L2 cache it ought to decay fast as other | ||
45 | * processes are run. | ||
46 | */ | ||
47 | |||
48 | #define PROC_CHANGE_PENALTY 20 /* Schedule penalty */ | ||
49 | |||
50 | #define smp_processor_id() (S390_lowcore.cpu_data.cpu_nr) | ||
51 | |||
52 | extern int smp_get_cpu(cpumask_t cpu_map); | ||
53 | extern void smp_put_cpu(int cpu); | ||
54 | |||
55 | extern __inline__ __u16 hard_smp_processor_id(void) | ||
56 | { | ||
57 | __u16 cpu_address; | ||
58 | |||
59 | __asm__ ("stap %0\n" : "=m" (cpu_address)); | ||
60 | return cpu_address; | ||
61 | } | ||
62 | |||
63 | /* | ||
64 | * returns 1 if cpu is in stopped/check stopped state or not operational | ||
65 | * returns 0 otherwise | ||
66 | */ | ||
67 | static inline int | ||
68 | smp_cpu_not_running(int cpu) | ||
69 | { | ||
70 | __u32 status; | ||
71 | |||
72 | switch (signal_processor_ps(&status, 0, cpu, sigp_sense)) { | ||
73 | case sigp_order_code_accepted: | ||
74 | case sigp_status_stored: | ||
75 | /* Check for stopped and check stop state */ | ||
76 | if (status & 0x50) | ||
77 | return 1; | ||
78 | break; | ||
79 | case sigp_not_operational: | ||
80 | return 1; | ||
81 | default: | ||
82 | break; | ||
83 | } | ||
84 | return 0; | ||
85 | } | ||
86 | |||
87 | #define cpu_logical_map(cpu) (cpu) | ||
88 | |||
89 | extern int __cpu_disable (void); | ||
90 | extern void __cpu_die (unsigned int cpu); | ||
91 | extern void cpu_die (void) __attribute__ ((noreturn)); | ||
92 | extern int __cpu_up (unsigned int cpu); | ||
93 | |||
94 | #endif | ||
95 | |||
96 | #ifndef CONFIG_SMP | ||
97 | static inline int | ||
98 | smp_call_function_on(void (*func) (void *info), void *info, | ||
99 | int nonatomic, int wait, int cpu) | ||
100 | { | ||
101 | func(info); | ||
102 | return 0; | ||
103 | } | ||
104 | #define smp_get_cpu(cpu) ({ 0; }) | ||
105 | #define smp_put_cpu(cpu) ({ 0; }) | ||
106 | #endif | ||
107 | |||
108 | #endif | ||
diff --git a/include/asm-s390/socket.h b/include/asm-s390/socket.h new file mode 100644 index 000000000000..0e96eeca4e6b --- /dev/null +++ b/include/asm-s390/socket.h | |||
@@ -0,0 +1,58 @@ | |||
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_KEEPALIVE 9 | ||
26 | #define SO_OOBINLINE 10 | ||
27 | #define SO_NO_CHECK 11 | ||
28 | #define SO_PRIORITY 12 | ||
29 | #define SO_LINGER 13 | ||
30 | #define SO_BSDCOMPAT 14 | ||
31 | /* To add :#define SO_REUSEPORT 15 */ | ||
32 | #define SO_PASSCRED 16 | ||
33 | #define SO_PEERCRED 17 | ||
34 | #define SO_RCVLOWAT 18 | ||
35 | #define SO_SNDLOWAT 19 | ||
36 | #define SO_RCVTIMEO 20 | ||
37 | #define SO_SNDTIMEO 21 | ||
38 | |||
39 | /* Security levels - as per NRL IPv6 - don't actually do anything */ | ||
40 | #define SO_SECURITY_AUTHENTICATION 22 | ||
41 | #define SO_SECURITY_ENCRYPTION_TRANSPORT 23 | ||
42 | #define SO_SECURITY_ENCRYPTION_NETWORK 24 | ||
43 | |||
44 | #define SO_BINDTODEVICE 25 | ||
45 | |||
46 | /* Socket filtering */ | ||
47 | #define SO_ATTACH_FILTER 26 | ||
48 | #define SO_DETACH_FILTER 27 | ||
49 | |||
50 | #define SO_PEERNAME 28 | ||
51 | #define SO_TIMESTAMP 29 | ||
52 | #define SCM_TIMESTAMP SO_TIMESTAMP | ||
53 | |||
54 | #define SO_ACCEPTCONN 30 | ||
55 | |||
56 | #define SO_PEERSEC 31 | ||
57 | |||
58 | #endif /* _ASM_SOCKET_H */ | ||
diff --git a/include/asm-s390/sockios.h b/include/asm-s390/sockios.h new file mode 100644 index 000000000000..412aeb4dd6ce --- /dev/null +++ b/include/asm-s390/sockios.h | |||
@@ -0,0 +1,20 @@ | |||
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 */ | ||
19 | |||
20 | #endif | ||
diff --git a/include/asm-s390/spinlock.h b/include/asm-s390/spinlock.h new file mode 100644 index 000000000000..53cc736b9820 --- /dev/null +++ b/include/asm-s390/spinlock.h | |||
@@ -0,0 +1,251 @@ | |||
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 | #ifdef __s390x__ | ||
15 | /* | ||
16 | * Grmph, take care of %&#! user space programs that include | ||
17 | * asm/spinlock.h. The diagnose is only available in kernel | ||
18 | * context. | ||
19 | */ | ||
20 | #ifdef __KERNEL__ | ||
21 | #include <asm/lowcore.h> | ||
22 | #define __DIAG44_INSN "ex" | ||
23 | #define __DIAG44_OPERAND __LC_DIAG44_OPCODE | ||
24 | #else | ||
25 | #define __DIAG44_INSN "#" | ||
26 | #define __DIAG44_OPERAND 0 | ||
27 | #endif | ||
28 | #endif /* __s390x__ */ | ||
29 | |||
30 | /* | ||
31 | * Simple spin lock operations. There are two variants, one clears IRQ's | ||
32 | * on the local processor, one does not. | ||
33 | * | ||
34 | * We make no fairness assumptions. They have a cost. | ||
35 | */ | ||
36 | |||
37 | typedef struct { | ||
38 | volatile unsigned int lock; | ||
39 | #ifdef CONFIG_PREEMPT | ||
40 | unsigned int break_lock; | ||
41 | #endif | ||
42 | } __attribute__ ((aligned (4))) spinlock_t; | ||
43 | |||
44 | #define SPIN_LOCK_UNLOCKED (spinlock_t) { 0 } | ||
45 | #define spin_lock_init(lp) do { (lp)->lock = 0; } while(0) | ||
46 | #define spin_unlock_wait(lp) do { barrier(); } while(((volatile spinlock_t *)(lp))->lock) | ||
47 | #define spin_is_locked(x) ((x)->lock != 0) | ||
48 | #define _raw_spin_lock_flags(lock, flags) _raw_spin_lock(lock) | ||
49 | |||
50 | extern inline void _raw_spin_lock(spinlock_t *lp) | ||
51 | { | ||
52 | #ifndef __s390x__ | ||
53 | unsigned int reg1, reg2; | ||
54 | __asm__ __volatile__(" bras %0,1f\n" | ||
55 | "0: diag 0,0,68\n" | ||
56 | "1: slr %1,%1\n" | ||
57 | " cs %1,%0,0(%3)\n" | ||
58 | " jl 0b\n" | ||
59 | : "=&d" (reg1), "=&d" (reg2), "=m" (lp->lock) | ||
60 | : "a" (&lp->lock), "m" (lp->lock) | ||
61 | : "cc", "memory" ); | ||
62 | #else /* __s390x__ */ | ||
63 | unsigned long reg1, reg2; | ||
64 | __asm__ __volatile__(" bras %1,1f\n" | ||
65 | "0: " __DIAG44_INSN " 0,%4\n" | ||
66 | "1: slr %0,%0\n" | ||
67 | " cs %0,%1,0(%3)\n" | ||
68 | " jl 0b\n" | ||
69 | : "=&d" (reg1), "=&d" (reg2), "=m" (lp->lock) | ||
70 | : "a" (&lp->lock), "i" (__DIAG44_OPERAND), | ||
71 | "m" (lp->lock) : "cc", "memory" ); | ||
72 | #endif /* __s390x__ */ | ||
73 | } | ||
74 | |||
75 | extern inline int _raw_spin_trylock(spinlock_t *lp) | ||
76 | { | ||
77 | unsigned long reg; | ||
78 | unsigned int result; | ||
79 | |||
80 | __asm__ __volatile__(" basr %1,0\n" | ||
81 | "0: cs %0,%1,0(%3)" | ||
82 | : "=d" (result), "=&d" (reg), "=m" (lp->lock) | ||
83 | : "a" (&lp->lock), "m" (lp->lock), "0" (0) | ||
84 | : "cc", "memory" ); | ||
85 | return !result; | ||
86 | } | ||
87 | |||
88 | extern inline void _raw_spin_unlock(spinlock_t *lp) | ||
89 | { | ||
90 | unsigned int old; | ||
91 | |||
92 | __asm__ __volatile__("cs %0,%3,0(%4)" | ||
93 | : "=d" (old), "=m" (lp->lock) | ||
94 | : "0" (lp->lock), "d" (0), "a" (lp) | ||
95 | : "cc", "memory" ); | ||
96 | } | ||
97 | |||
98 | /* | ||
99 | * Read-write spinlocks, allowing multiple readers | ||
100 | * but only one writer. | ||
101 | * | ||
102 | * NOTE! it is quite common to have readers in interrupts | ||
103 | * but no interrupt writers. For those circumstances we | ||
104 | * can "mix" irq-safe locks - any writer needs to get a | ||
105 | * irq-safe write-lock, but readers can get non-irqsafe | ||
106 | * read-locks. | ||
107 | */ | ||
108 | typedef struct { | ||
109 | volatile unsigned long lock; | ||
110 | volatile unsigned long owner_pc; | ||
111 | #ifdef CONFIG_PREEMPT | ||
112 | unsigned int break_lock; | ||
113 | #endif | ||
114 | } rwlock_t; | ||
115 | |||
116 | #define RW_LOCK_UNLOCKED (rwlock_t) { 0, 0 } | ||
117 | |||
118 | #define rwlock_init(x) do { *(x) = RW_LOCK_UNLOCKED; } while(0) | ||
119 | |||
120 | /** | ||
121 | * read_can_lock - would read_trylock() succeed? | ||
122 | * @lock: the rwlock in question. | ||
123 | */ | ||
124 | #define read_can_lock(x) ((int)(x)->lock >= 0) | ||
125 | |||
126 | /** | ||
127 | * write_can_lock - would write_trylock() succeed? | ||
128 | * @lock: the rwlock in question. | ||
129 | */ | ||
130 | #define write_can_lock(x) ((x)->lock == 0) | ||
131 | |||
132 | #ifndef __s390x__ | ||
133 | #define _raw_read_lock(rw) \ | ||
134 | asm volatile(" l 2,0(%1)\n" \ | ||
135 | " j 1f\n" \ | ||
136 | "0: diag 0,0,68\n" \ | ||
137 | "1: la 2,0(2)\n" /* clear high (=write) bit */ \ | ||
138 | " la 3,1(2)\n" /* one more reader */ \ | ||
139 | " cs 2,3,0(%1)\n" /* try to write new value */ \ | ||
140 | " jl 0b" \ | ||
141 | : "=m" ((rw)->lock) : "a" (&(rw)->lock), \ | ||
142 | "m" ((rw)->lock) : "2", "3", "cc", "memory" ) | ||
143 | #else /* __s390x__ */ | ||
144 | #define _raw_read_lock(rw) \ | ||
145 | asm volatile(" lg 2,0(%1)\n" \ | ||
146 | " j 1f\n" \ | ||
147 | "0: " __DIAG44_INSN " 0,%2\n" \ | ||
148 | "1: nihh 2,0x7fff\n" /* clear high (=write) bit */ \ | ||
149 | " la 3,1(2)\n" /* one more reader */ \ | ||
150 | " csg 2,3,0(%1)\n" /* try to write new value */ \ | ||
151 | " jl 0b" \ | ||
152 | : "=m" ((rw)->lock) \ | ||
153 | : "a" (&(rw)->lock), "i" (__DIAG44_OPERAND), \ | ||
154 | "m" ((rw)->lock) : "2", "3", "cc", "memory" ) | ||
155 | #endif /* __s390x__ */ | ||
156 | |||
157 | #ifndef __s390x__ | ||
158 | #define _raw_read_unlock(rw) \ | ||
159 | asm volatile(" l 2,0(%1)\n" \ | ||
160 | " j 1f\n" \ | ||
161 | "0: diag 0,0,68\n" \ | ||
162 | "1: lr 3,2\n" \ | ||
163 | " ahi 3,-1\n" /* one less reader */ \ | ||
164 | " cs 2,3,0(%1)\n" \ | ||
165 | " jl 0b" \ | ||
166 | : "=m" ((rw)->lock) : "a" (&(rw)->lock), \ | ||
167 | "m" ((rw)->lock) : "2", "3", "cc", "memory" ) | ||
168 | #else /* __s390x__ */ | ||
169 | #define _raw_read_unlock(rw) \ | ||
170 | asm volatile(" lg 2,0(%1)\n" \ | ||
171 | " j 1f\n" \ | ||
172 | "0: " __DIAG44_INSN " 0,%2\n" \ | ||
173 | "1: lgr 3,2\n" \ | ||
174 | " bctgr 3,0\n" /* one less reader */ \ | ||
175 | " csg 2,3,0(%1)\n" \ | ||
176 | " jl 0b" \ | ||
177 | : "=m" ((rw)->lock) \ | ||
178 | : "a" (&(rw)->lock), "i" (__DIAG44_OPERAND), \ | ||
179 | "m" ((rw)->lock) : "2", "3", "cc", "memory" ) | ||
180 | #endif /* __s390x__ */ | ||
181 | |||
182 | #ifndef __s390x__ | ||
183 | #define _raw_write_lock(rw) \ | ||
184 | asm volatile(" lhi 3,1\n" \ | ||
185 | " sll 3,31\n" /* new lock value = 0x80000000 */ \ | ||
186 | " j 1f\n" \ | ||
187 | "0: diag 0,0,68\n" \ | ||
188 | "1: slr 2,2\n" /* old lock value must be 0 */ \ | ||
189 | " cs 2,3,0(%1)\n" \ | ||
190 | " jl 0b" \ | ||
191 | : "=m" ((rw)->lock) : "a" (&(rw)->lock), \ | ||
192 | "m" ((rw)->lock) : "2", "3", "cc", "memory" ) | ||
193 | #else /* __s390x__ */ | ||
194 | #define _raw_write_lock(rw) \ | ||
195 | asm volatile(" llihh 3,0x8000\n" /* new lock value = 0x80...0 */ \ | ||
196 | " j 1f\n" \ | ||
197 | "0: " __DIAG44_INSN " 0,%2\n" \ | ||
198 | "1: slgr 2,2\n" /* old lock value must be 0 */ \ | ||
199 | " csg 2,3,0(%1)\n" \ | ||
200 | " jl 0b" \ | ||
201 | : "=m" ((rw)->lock) \ | ||
202 | : "a" (&(rw)->lock), "i" (__DIAG44_OPERAND), \ | ||
203 | "m" ((rw)->lock) : "2", "3", "cc", "memory" ) | ||
204 | #endif /* __s390x__ */ | ||
205 | |||
206 | #ifndef __s390x__ | ||
207 | #define _raw_write_unlock(rw) \ | ||
208 | asm volatile(" slr 3,3\n" /* new lock value = 0 */ \ | ||
209 | " j 1f\n" \ | ||
210 | "0: diag 0,0,68\n" \ | ||
211 | "1: lhi 2,1\n" \ | ||
212 | " sll 2,31\n" /* old lock value must be 0x80000000 */ \ | ||
213 | " cs 2,3,0(%1)\n" \ | ||
214 | " jl 0b" \ | ||
215 | : "=m" ((rw)->lock) : "a" (&(rw)->lock), \ | ||
216 | "m" ((rw)->lock) : "2", "3", "cc", "memory" ) | ||
217 | #else /* __s390x__ */ | ||
218 | #define _raw_write_unlock(rw) \ | ||
219 | asm volatile(" slgr 3,3\n" /* new lock value = 0 */ \ | ||
220 | " j 1f\n" \ | ||
221 | "0: " __DIAG44_INSN " 0,%2\n" \ | ||
222 | "1: llihh 2,0x8000\n" /* old lock value must be 0x8..0 */\ | ||
223 | " csg 2,3,0(%1)\n" \ | ||
224 | " jl 0b" \ | ||
225 | : "=m" ((rw)->lock) \ | ||
226 | : "a" (&(rw)->lock), "i" (__DIAG44_OPERAND), \ | ||
227 | "m" ((rw)->lock) : "2", "3", "cc", "memory" ) | ||
228 | #endif /* __s390x__ */ | ||
229 | |||
230 | #define _raw_read_trylock(lock) generic_raw_read_trylock(lock) | ||
231 | |||
232 | extern inline int _raw_write_trylock(rwlock_t *rw) | ||
233 | { | ||
234 | unsigned long result, reg; | ||
235 | |||
236 | __asm__ __volatile__( | ||
237 | #ifndef __s390x__ | ||
238 | " lhi %1,1\n" | ||
239 | " sll %1,31\n" | ||
240 | " cs %0,%1,0(%3)" | ||
241 | #else /* __s390x__ */ | ||
242 | " llihh %1,0x8000\n" | ||
243 | "0: csg %0,%1,0(%3)\n" | ||
244 | #endif /* __s390x__ */ | ||
245 | : "=d" (result), "=&d" (reg), "=m" (rw->lock) | ||
246 | : "a" (&rw->lock), "m" (rw->lock), "0" (0UL) | ||
247 | : "cc", "memory" ); | ||
248 | return result == 0; | ||
249 | } | ||
250 | |||
251 | #endif /* __ASM_SPINLOCK_H */ | ||
diff --git a/include/asm-s390/stat.h b/include/asm-s390/stat.h new file mode 100644 index 000000000000..d92959eebb65 --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/statfs.h b/include/asm-s390/statfs.h new file mode 100644 index 000000000000..099a45579190 --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/string.h b/include/asm-s390/string.h new file mode 100644 index 000000000000..23a4c390489f --- /dev/null +++ b/include/asm-s390/string.h | |||
@@ -0,0 +1,137 @@ | |||
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 ("0: srst %0,%1\n" | ||
64 | " jo 0b\n" | ||
65 | " jl 1f\n" | ||
66 | " la %0,0\n" | ||
67 | "1:" | ||
68 | : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" ); | ||
69 | return (void *) ret; | ||
70 | } | ||
71 | |||
72 | static inline void *memscan(void *s, int c, size_t n) | ||
73 | { | ||
74 | register int r0 asm("0") = (char) c; | ||
75 | const void *ret = s + n; | ||
76 | |||
77 | asm volatile ("0: srst %0,%1\n" | ||
78 | " jo 0b\n" | ||
79 | : "+a" (ret), "+&a" (s) : "d" (r0) : "cc" ); | ||
80 | return (void *) ret; | ||
81 | } | ||
82 | |||
83 | static inline char *strcat(char *dst, const char *src) | ||
84 | { | ||
85 | register int r0 asm("0") = 0; | ||
86 | unsigned long dummy; | ||
87 | char *ret = dst; | ||
88 | |||
89 | asm volatile ("0: srst %0,%1\n" | ||
90 | " jo 0b\n" | ||
91 | "1: mvst %0,%2\n" | ||
92 | " jo 1b" | ||
93 | : "=&a" (dummy), "+a" (dst), "+a" (src) | ||
94 | : "d" (r0), "0" (0) : "cc", "memory" ); | ||
95 | return ret; | ||
96 | } | ||
97 | |||
98 | static inline char *strcpy(char *dst, const char *src) | ||
99 | { | ||
100 | register int r0 asm("0") = 0; | ||
101 | char *ret = dst; | ||
102 | |||
103 | asm volatile ("0: mvst %0,%1\n" | ||
104 | " jo 0b" | ||
105 | : "+&a" (dst), "+&a" (src) : "d" (r0) | ||
106 | : "cc", "memory" ); | ||
107 | return ret; | ||
108 | } | ||
109 | |||
110 | static inline size_t strlen(const char *s) | ||
111 | { | ||
112 | register unsigned long r0 asm("0") = 0; | ||
113 | const char *tmp = s; | ||
114 | |||
115 | asm volatile ("0: srst %0,%1\n" | ||
116 | " jo 0b" | ||
117 | : "+d" (r0), "+a" (tmp) : : "cc" ); | ||
118 | return r0 - (unsigned long) s; | ||
119 | } | ||
120 | |||
121 | static inline size_t strnlen(const char * s, size_t n) | ||
122 | { | ||
123 | register int r0 asm("0") = 0; | ||
124 | const char *tmp = s; | ||
125 | const char *end = s + n; | ||
126 | |||
127 | asm volatile ("0: srst %0,%1\n" | ||
128 | " jo 0b" | ||
129 | : "+a" (end), "+a" (tmp) : "d" (r0) : "cc" ); | ||
130 | return end - s; | ||
131 | } | ||
132 | |||
133 | #endif /* !IN_ARCH_STRING_C */ | ||
134 | |||
135 | #endif /* __KERNEL__ */ | ||
136 | |||
137 | #endif /* __S390_STRING_H_ */ | ||
diff --git a/include/asm-s390/suspend.h b/include/asm-s390/suspend.h new file mode 100644 index 000000000000..1f34580e67a7 --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/system.h b/include/asm-s390/system.h new file mode 100644 index 000000000000..81514d76edcf --- /dev/null +++ b/include/asm-s390/system.h | |||
@@ -0,0 +1,477 @@ | |||
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/config.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <asm/types.h> | ||
17 | #include <asm/ptrace.h> | ||
18 | #include <asm/setup.h> | ||
19 | |||
20 | #ifdef __KERNEL__ | ||
21 | |||
22 | struct task_struct; | ||
23 | |||
24 | extern struct task_struct *__switch_to(void *, void *); | ||
25 | |||
26 | #ifdef __s390x__ | ||
27 | #define __FLAG_SHIFT 56 | ||
28 | #else /* ! __s390x__ */ | ||
29 | #define __FLAG_SHIFT 24 | ||
30 | #endif /* ! __s390x__ */ | ||
31 | |||
32 | static inline void save_fp_regs(s390_fp_regs *fpregs) | ||
33 | { | ||
34 | asm volatile ( | ||
35 | " std 0,8(%1)\n" | ||
36 | " std 2,24(%1)\n" | ||
37 | " std 4,40(%1)\n" | ||
38 | " std 6,56(%1)" | ||
39 | : "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory" ); | ||
40 | if (!MACHINE_HAS_IEEE) | ||
41 | return; | ||
42 | asm volatile( | ||
43 | " stfpc 0(%1)\n" | ||
44 | " std 1,16(%1)\n" | ||
45 | " std 3,32(%1)\n" | ||
46 | " std 5,48(%1)\n" | ||
47 | " std 7,64(%1)\n" | ||
48 | " std 8,72(%1)\n" | ||
49 | " std 9,80(%1)\n" | ||
50 | " std 10,88(%1)\n" | ||
51 | " std 11,96(%1)\n" | ||
52 | " std 12,104(%1)\n" | ||
53 | " std 13,112(%1)\n" | ||
54 | " std 14,120(%1)\n" | ||
55 | " std 15,128(%1)\n" | ||
56 | : "=m" (*fpregs) : "a" (fpregs), "m" (*fpregs) : "memory" ); | ||
57 | } | ||
58 | |||
59 | static inline void restore_fp_regs(s390_fp_regs *fpregs) | ||
60 | { | ||
61 | asm volatile ( | ||
62 | " ld 0,8(%0)\n" | ||
63 | " ld 2,24(%0)\n" | ||
64 | " ld 4,40(%0)\n" | ||
65 | " ld 6,56(%0)" | ||
66 | : : "a" (fpregs), "m" (*fpregs) ); | ||
67 | if (!MACHINE_HAS_IEEE) | ||
68 | return; | ||
69 | asm volatile( | ||
70 | " lfpc 0(%0)\n" | ||
71 | " ld 1,16(%0)\n" | ||
72 | " ld 3,32(%0)\n" | ||
73 | " ld 5,48(%0)\n" | ||
74 | " ld 7,64(%0)\n" | ||
75 | " ld 8,72(%0)\n" | ||
76 | " ld 9,80(%0)\n" | ||
77 | " ld 10,88(%0)\n" | ||
78 | " ld 11,96(%0)\n" | ||
79 | " ld 12,104(%0)\n" | ||
80 | " ld 13,112(%0)\n" | ||
81 | " ld 14,120(%0)\n" | ||
82 | " ld 15,128(%0)\n" | ||
83 | : : "a" (fpregs), "m" (*fpregs) ); | ||
84 | } | ||
85 | |||
86 | static inline void save_access_regs(unsigned int *acrs) | ||
87 | { | ||
88 | asm volatile ("stam 0,15,0(%0)" : : "a" (acrs) : "memory" ); | ||
89 | } | ||
90 | |||
91 | static inline void restore_access_regs(unsigned int *acrs) | ||
92 | { | ||
93 | asm volatile ("lam 0,15,0(%0)" : : "a" (acrs) ); | ||
94 | } | ||
95 | |||
96 | #define switch_to(prev,next,last) do { \ | ||
97 | if (prev == next) \ | ||
98 | break; \ | ||
99 | save_fp_regs(&prev->thread.fp_regs); \ | ||
100 | restore_fp_regs(&next->thread.fp_regs); \ | ||
101 | save_access_regs(&prev->thread.acrs[0]); \ | ||
102 | restore_access_regs(&next->thread.acrs[0]); \ | ||
103 | prev = __switch_to(prev,next); \ | ||
104 | } while (0) | ||
105 | |||
106 | #define prepare_arch_switch(rq, next) do { } while(0) | ||
107 | #define task_running(rq, p) ((rq)->curr == (p)) | ||
108 | |||
109 | #ifdef CONFIG_VIRT_CPU_ACCOUNTING | ||
110 | extern void account_user_vtime(struct task_struct *); | ||
111 | extern void account_system_vtime(struct task_struct *); | ||
112 | |||
113 | #define finish_arch_switch(rq, prev) do { \ | ||
114 | set_fs(current->thread.mm_segment); \ | ||
115 | spin_unlock(&(rq)->lock); \ | ||
116 | account_system_vtime(prev); \ | ||
117 | local_irq_enable(); \ | ||
118 | } while (0) | ||
119 | |||
120 | #else | ||
121 | |||
122 | #define finish_arch_switch(rq, prev) do { \ | ||
123 | set_fs(current->thread.mm_segment); \ | ||
124 | spin_unlock_irq(&(rq)->lock); \ | ||
125 | } while (0) | ||
126 | |||
127 | #endif | ||
128 | |||
129 | #define nop() __asm__ __volatile__ ("nop") | ||
130 | |||
131 | #define xchg(ptr,x) \ | ||
132 | ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(void *)(ptr),sizeof(*(ptr)))) | ||
133 | |||
134 | static inline unsigned long __xchg(unsigned long x, void * ptr, int size) | ||
135 | { | ||
136 | unsigned long addr, old; | ||
137 | int shift; | ||
138 | |||
139 | switch (size) { | ||
140 | case 1: | ||
141 | addr = (unsigned long) ptr; | ||
142 | shift = (3 ^ (addr & 3)) << 3; | ||
143 | addr ^= addr & 3; | ||
144 | asm volatile( | ||
145 | " l %0,0(%4)\n" | ||
146 | "0: lr 0,%0\n" | ||
147 | " nr 0,%3\n" | ||
148 | " or 0,%2\n" | ||
149 | " cs %0,0,0(%4)\n" | ||
150 | " jl 0b\n" | ||
151 | : "=&d" (old), "=m" (*(int *) addr) | ||
152 | : "d" (x << shift), "d" (~(255 << shift)), "a" (addr), | ||
153 | "m" (*(int *) addr) : "memory", "cc", "0" ); | ||
154 | x = old >> shift; | ||
155 | break; | ||
156 | case 2: | ||
157 | addr = (unsigned long) ptr; | ||
158 | shift = (2 ^ (addr & 2)) << 3; | ||
159 | addr ^= addr & 2; | ||
160 | asm volatile( | ||
161 | " l %0,0(%4)\n" | ||
162 | "0: lr 0,%0\n" | ||
163 | " nr 0,%3\n" | ||
164 | " or 0,%2\n" | ||
165 | " cs %0,0,0(%4)\n" | ||
166 | " jl 0b\n" | ||
167 | : "=&d" (old), "=m" (*(int *) addr) | ||
168 | : "d" (x << shift), "d" (~(65535 << shift)), "a" (addr), | ||
169 | "m" (*(int *) addr) : "memory", "cc", "0" ); | ||
170 | x = old >> shift; | ||
171 | break; | ||
172 | case 4: | ||
173 | asm volatile ( | ||
174 | " l %0,0(%3)\n" | ||
175 | "0: cs %0,%2,0(%3)\n" | ||
176 | " jl 0b\n" | ||
177 | : "=&d" (old), "=m" (*(int *) ptr) | ||
178 | : "d" (x), "a" (ptr), "m" (*(int *) ptr) | ||
179 | : "memory", "cc" ); | ||
180 | x = old; | ||
181 | break; | ||
182 | #ifdef __s390x__ | ||
183 | case 8: | ||
184 | asm volatile ( | ||
185 | " lg %0,0(%3)\n" | ||
186 | "0: csg %0,%2,0(%3)\n" | ||
187 | " jl 0b\n" | ||
188 | : "=&d" (old), "=m" (*(long *) ptr) | ||
189 | : "d" (x), "a" (ptr), "m" (*(long *) ptr) | ||
190 | : "memory", "cc" ); | ||
191 | x = old; | ||
192 | break; | ||
193 | #endif /* __s390x__ */ | ||
194 | } | ||
195 | return x; | ||
196 | } | ||
197 | |||
198 | /* | ||
199 | * Atomic compare and exchange. Compare OLD with MEM, if identical, | ||
200 | * store NEW in MEM. Return the initial value in MEM. Success is | ||
201 | * indicated by comparing RETURN with OLD. | ||
202 | */ | ||
203 | |||
204 | #define __HAVE_ARCH_CMPXCHG 1 | ||
205 | |||
206 | #define cmpxchg(ptr,o,n)\ | ||
207 | ((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o),\ | ||
208 | (unsigned long)(n),sizeof(*(ptr)))) | ||
209 | |||
210 | static inline unsigned long | ||
211 | __cmpxchg(volatile void *ptr, unsigned long old, unsigned long new, int size) | ||
212 | { | ||
213 | unsigned long addr, prev, tmp; | ||
214 | int shift; | ||
215 | |||
216 | switch (size) { | ||
217 | case 1: | ||
218 | addr = (unsigned long) ptr; | ||
219 | shift = (3 ^ (addr & 3)) << 3; | ||
220 | addr ^= addr & 3; | ||
221 | asm volatile( | ||
222 | " l %0,0(%4)\n" | ||
223 | "0: nr %0,%5\n" | ||
224 | " lr %1,%0\n" | ||
225 | " or %0,%2\n" | ||
226 | " or %1,%3\n" | ||
227 | " cs %0,%1,0(%4)\n" | ||
228 | " jnl 1f\n" | ||
229 | " xr %1,%0\n" | ||
230 | " nr %1,%5\n" | ||
231 | " jnz 0b\n" | ||
232 | "1:" | ||
233 | : "=&d" (prev), "=&d" (tmp) | ||
234 | : "d" (old << shift), "d" (new << shift), "a" (ptr), | ||
235 | "d" (~(255 << shift)) | ||
236 | : "memory", "cc" ); | ||
237 | return prev >> shift; | ||
238 | case 2: | ||
239 | addr = (unsigned long) ptr; | ||
240 | shift = (2 ^ (addr & 2)) << 3; | ||
241 | addr ^= addr & 2; | ||
242 | asm volatile( | ||
243 | " l %0,0(%4)\n" | ||
244 | "0: nr %0,%5\n" | ||
245 | " lr %1,%0\n" | ||
246 | " or %0,%2\n" | ||
247 | " or %1,%3\n" | ||
248 | " cs %0,%1,0(%4)\n" | ||
249 | " jnl 1f\n" | ||
250 | " xr %1,%0\n" | ||
251 | " nr %1,%5\n" | ||
252 | " jnz 0b\n" | ||
253 | "1:" | ||
254 | : "=&d" (prev), "=&d" (tmp) | ||
255 | : "d" (old << shift), "d" (new << shift), "a" (ptr), | ||
256 | "d" (~(65535 << shift)) | ||
257 | : "memory", "cc" ); | ||
258 | return prev >> shift; | ||
259 | case 4: | ||
260 | asm volatile ( | ||
261 | " cs %0,%2,0(%3)\n" | ||
262 | : "=&d" (prev) : "0" (old), "d" (new), "a" (ptr) | ||
263 | : "memory", "cc" ); | ||
264 | return prev; | ||
265 | #ifdef __s390x__ | ||
266 | case 8: | ||
267 | asm volatile ( | ||
268 | " csg %0,%2,0(%3)\n" | ||
269 | : "=&d" (prev) : "0" (old), "d" (new), "a" (ptr) | ||
270 | : "memory", "cc" ); | ||
271 | return prev; | ||
272 | #endif /* __s390x__ */ | ||
273 | } | ||
274 | return old; | ||
275 | } | ||
276 | |||
277 | /* | ||
278 | * Force strict CPU ordering. | ||
279 | * And yes, this is required on UP too when we're talking | ||
280 | * to devices. | ||
281 | * | ||
282 | * This is very similar to the ppc eieio/sync instruction in that is | ||
283 | * does a checkpoint syncronisation & makes sure that | ||
284 | * all memory ops have completed wrt other CPU's ( see 7-15 POP DJB ). | ||
285 | */ | ||
286 | |||
287 | #define eieio() __asm__ __volatile__ ( "bcr 15,0" : : : "memory" ) | ||
288 | # define SYNC_OTHER_CORES(x) eieio() | ||
289 | #define mb() eieio() | ||
290 | #define rmb() eieio() | ||
291 | #define wmb() eieio() | ||
292 | #define read_barrier_depends() do { } while(0) | ||
293 | #define smp_mb() mb() | ||
294 | #define smp_rmb() rmb() | ||
295 | #define smp_wmb() wmb() | ||
296 | #define smp_read_barrier_depends() read_barrier_depends() | ||
297 | #define smp_mb__before_clear_bit() smp_mb() | ||
298 | #define smp_mb__after_clear_bit() smp_mb() | ||
299 | |||
300 | |||
301 | #define set_mb(var, value) do { var = value; mb(); } while (0) | ||
302 | #define set_wmb(var, value) do { var = value; wmb(); } while (0) | ||
303 | |||
304 | /* interrupt control.. */ | ||
305 | #define local_irq_enable() ({ \ | ||
306 | unsigned long __dummy; \ | ||
307 | __asm__ __volatile__ ( \ | ||
308 | "stosm 0(%1),0x03" \ | ||
309 | : "=m" (__dummy) : "a" (&__dummy) : "memory" ); \ | ||
310 | }) | ||
311 | |||
312 | #define local_irq_disable() ({ \ | ||
313 | unsigned long __flags; \ | ||
314 | __asm__ __volatile__ ( \ | ||
315 | "stnsm 0(%1),0xfc" : "=m" (__flags) : "a" (&__flags) ); \ | ||
316 | __flags; \ | ||
317 | }) | ||
318 | |||
319 | #define local_save_flags(x) \ | ||
320 | __asm__ __volatile__("stosm 0(%1),0" : "=m" (x) : "a" (&x), "m" (x) ) | ||
321 | |||
322 | #define local_irq_restore(x) \ | ||
323 | __asm__ __volatile__("ssm 0(%0)" : : "a" (&x), "m" (x) : "memory") | ||
324 | |||
325 | #define irqs_disabled() \ | ||
326 | ({ \ | ||
327 | unsigned long flags; \ | ||
328 | local_save_flags(flags); \ | ||
329 | !((flags >> __FLAG_SHIFT) & 3); \ | ||
330 | }) | ||
331 | |||
332 | #ifdef __s390x__ | ||
333 | |||
334 | #define __load_psw(psw) \ | ||
335 | __asm__ __volatile__("lpswe 0(%0)" : : "a" (&psw), "m" (psw) : "cc" ); | ||
336 | |||
337 | #define __ctl_load(array, low, high) ({ \ | ||
338 | typedef struct { char _[sizeof(array)]; } addrtype; \ | ||
339 | __asm__ __volatile__ ( \ | ||
340 | " bras 1,0f\n" \ | ||
341 | " lctlg 0,0,0(%0)\n" \ | ||
342 | "0: ex %1,0(1)" \ | ||
343 | : : "a" (&array), "a" (((low)<<4)+(high)), \ | ||
344 | "m" (*(addrtype *)(array)) : "1" ); \ | ||
345 | }) | ||
346 | |||
347 | #define __ctl_store(array, low, high) ({ \ | ||
348 | typedef struct { char _[sizeof(array)]; } addrtype; \ | ||
349 | __asm__ __volatile__ ( \ | ||
350 | " bras 1,0f\n" \ | ||
351 | " stctg 0,0,0(%1)\n" \ | ||
352 | "0: ex %2,0(1)" \ | ||
353 | : "=m" (*(addrtype *)(array)) \ | ||
354 | : "a" (&array), "a" (((low)<<4)+(high)) : "1" ); \ | ||
355 | }) | ||
356 | |||
357 | #define __ctl_set_bit(cr, bit) ({ \ | ||
358 | __u8 __dummy[24]; \ | ||
359 | __asm__ __volatile__ ( \ | ||
360 | " bras 1,0f\n" /* skip indirect insns */ \ | ||
361 | " stctg 0,0,0(%1)\n" \ | ||
362 | " lctlg 0,0,0(%1)\n" \ | ||
363 | "0: ex %2,0(1)\n" /* execute stctl */ \ | ||
364 | " lg 0,0(%1)\n" \ | ||
365 | " ogr 0,%3\n" /* set the bit */ \ | ||
366 | " stg 0,0(%1)\n" \ | ||
367 | "1: ex %2,6(1)" /* execute lctl */ \ | ||
368 | : "=m" (__dummy) \ | ||
369 | : "a" ((((unsigned long) &__dummy) + 7) & ~7UL), \ | ||
370 | "a" (cr*17), "a" (1L<<(bit)) \ | ||
371 | : "cc", "0", "1" ); \ | ||
372 | }) | ||
373 | |||
374 | #define __ctl_clear_bit(cr, bit) ({ \ | ||
375 | __u8 __dummy[16]; \ | ||
376 | __asm__ __volatile__ ( \ | ||
377 | " bras 1,0f\n" /* skip indirect insns */ \ | ||
378 | " stctg 0,0,0(%1)\n" \ | ||
379 | " lctlg 0,0,0(%1)\n" \ | ||
380 | "0: ex %2,0(1)\n" /* execute stctl */ \ | ||
381 | " lg 0,0(%1)\n" \ | ||
382 | " ngr 0,%3\n" /* set the bit */ \ | ||
383 | " stg 0,0(%1)\n" \ | ||
384 | "1: ex %2,6(1)" /* execute lctl */ \ | ||
385 | : "=m" (__dummy) \ | ||
386 | : "a" ((((unsigned long) &__dummy) + 7) & ~7UL), \ | ||
387 | "a" (cr*17), "a" (~(1L<<(bit))) \ | ||
388 | : "cc", "0", "1" ); \ | ||
389 | }) | ||
390 | |||
391 | #else /* __s390x__ */ | ||
392 | |||
393 | #define __load_psw(psw) \ | ||
394 | __asm__ __volatile__("lpsw 0(%0)" : : "a" (&psw) : "cc" ); | ||
395 | |||
396 | #define __ctl_load(array, low, high) ({ \ | ||
397 | typedef struct { char _[sizeof(array)]; } addrtype; \ | ||
398 | __asm__ __volatile__ ( \ | ||
399 | " bras 1,0f\n" \ | ||
400 | " lctl 0,0,0(%0)\n" \ | ||
401 | "0: ex %1,0(1)" \ | ||
402 | : : "a" (&array), "a" (((low)<<4)+(high)), \ | ||
403 | "m" (*(addrtype *)(array)) : "1" ); \ | ||
404 | }) | ||
405 | |||
406 | #define __ctl_store(array, low, high) ({ \ | ||
407 | typedef struct { char _[sizeof(array)]; } addrtype; \ | ||
408 | __asm__ __volatile__ ( \ | ||
409 | " bras 1,0f\n" \ | ||
410 | " stctl 0,0,0(%1)\n" \ | ||
411 | "0: ex %2,0(1)" \ | ||
412 | : "=m" (*(addrtype *)(array)) \ | ||
413 | : "a" (&array), "a" (((low)<<4)+(high)): "1" ); \ | ||
414 | }) | ||
415 | |||
416 | #define __ctl_set_bit(cr, bit) ({ \ | ||
417 | __u8 __dummy[16]; \ | ||
418 | __asm__ __volatile__ ( \ | ||
419 | " bras 1,0f\n" /* skip indirect insns */ \ | ||
420 | " stctl 0,0,0(%1)\n" \ | ||
421 | " lctl 0,0,0(%1)\n" \ | ||
422 | "0: ex %2,0(1)\n" /* execute stctl */ \ | ||
423 | " l 0,0(%1)\n" \ | ||
424 | " or 0,%3\n" /* set the bit */ \ | ||
425 | " st 0,0(%1)\n" \ | ||
426 | "1: ex %2,4(1)" /* execute lctl */ \ | ||
427 | : "=m" (__dummy) \ | ||
428 | : "a" ((((unsigned long) &__dummy) + 7) & ~7UL), \ | ||
429 | "a" (cr*17), "a" (1<<(bit)) \ | ||
430 | : "cc", "0", "1" ); \ | ||
431 | }) | ||
432 | |||
433 | #define __ctl_clear_bit(cr, bit) ({ \ | ||
434 | __u8 __dummy[16]; \ | ||
435 | __asm__ __volatile__ ( \ | ||
436 | " bras 1,0f\n" /* skip indirect insns */ \ | ||
437 | " stctl 0,0,0(%1)\n" \ | ||
438 | " lctl 0,0,0(%1)\n" \ | ||
439 | "0: ex %2,0(1)\n" /* execute stctl */ \ | ||
440 | " l 0,0(%1)\n" \ | ||
441 | " nr 0,%3\n" /* set the bit */ \ | ||
442 | " st 0,0(%1)\n" \ | ||
443 | "1: ex %2,4(1)" /* execute lctl */ \ | ||
444 | : "=m" (__dummy) \ | ||
445 | : "a" ((((unsigned long) &__dummy) + 7) & ~7UL), \ | ||
446 | "a" (cr*17), "a" (~(1<<(bit))) \ | ||
447 | : "cc", "0", "1" ); \ | ||
448 | }) | ||
449 | #endif /* __s390x__ */ | ||
450 | |||
451 | /* For spinlocks etc */ | ||
452 | #define local_irq_save(x) ((x) = local_irq_disable()) | ||
453 | |||
454 | #ifdef CONFIG_SMP | ||
455 | |||
456 | extern void smp_ctl_set_bit(int cr, int bit); | ||
457 | extern void smp_ctl_clear_bit(int cr, int bit); | ||
458 | #define ctl_set_bit(cr, bit) smp_ctl_set_bit(cr, bit) | ||
459 | #define ctl_clear_bit(cr, bit) smp_ctl_clear_bit(cr, bit) | ||
460 | |||
461 | #else | ||
462 | |||
463 | #define ctl_set_bit(cr, bit) __ctl_set_bit(cr, bit) | ||
464 | #define ctl_clear_bit(cr, bit) __ctl_clear_bit(cr, bit) | ||
465 | |||
466 | #endif /* CONFIG_SMP */ | ||
467 | |||
468 | extern void (*_machine_restart)(char *command); | ||
469 | extern void (*_machine_halt)(void); | ||
470 | extern void (*_machine_power_off)(void); | ||
471 | |||
472 | #define arch_align_stack(x) (x) | ||
473 | |||
474 | #endif /* __KERNEL__ */ | ||
475 | |||
476 | #endif | ||
477 | |||
diff --git a/include/asm-s390/tape390.h b/include/asm-s390/tape390.h new file mode 100644 index 000000000000..f1d66ba0deef --- /dev/null +++ b/include/asm-s390/tape390.h | |||
@@ -0,0 +1,39 @@ | |||
1 | /************************************************************************* | ||
2 | * | ||
3 | * tape390.h | ||
4 | * enables user programs to display messages on the tape device | ||
5 | * | ||
6 | * S390 and zSeries version | ||
7 | * Copyright (C) 2001 IBM Corporation | ||
8 | * Author(s): Despina Papadopoulou <despina_p@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 | #endif | ||
diff --git a/include/asm-s390/termbits.h b/include/asm-s390/termbits.h new file mode 100644 index 000000000000..eb3f8bfabf61 --- /dev/null +++ b/include/asm-s390/termbits.h | |||
@@ -0,0 +1,181 @@ | |||
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 | /* c_cc characters */ | ||
29 | #define VINTR 0 | ||
30 | #define VQUIT 1 | ||
31 | #define VERASE 2 | ||
32 | #define VKILL 3 | ||
33 | #define VEOF 4 | ||
34 | #define VTIME 5 | ||
35 | #define VMIN 6 | ||
36 | #define VSWTC 7 | ||
37 | #define VSTART 8 | ||
38 | #define VSTOP 9 | ||
39 | #define VSUSP 10 | ||
40 | #define VEOL 11 | ||
41 | #define VREPRINT 12 | ||
42 | #define VDISCARD 13 | ||
43 | #define VWERASE 14 | ||
44 | #define VLNEXT 15 | ||
45 | #define VEOL2 16 | ||
46 | |||
47 | /* c_iflag bits */ | ||
48 | #define IGNBRK 0000001 | ||
49 | #define BRKINT 0000002 | ||
50 | #define IGNPAR 0000004 | ||
51 | #define PARMRK 0000010 | ||
52 | #define INPCK 0000020 | ||
53 | #define ISTRIP 0000040 | ||
54 | #define INLCR 0000100 | ||
55 | #define IGNCR 0000200 | ||
56 | #define ICRNL 0000400 | ||
57 | #define IUCLC 0001000 | ||
58 | #define IXON 0002000 | ||
59 | #define IXANY 0004000 | ||
60 | #define IXOFF 0010000 | ||
61 | #define IMAXBEL 0020000 | ||
62 | #define IUTF8 0040000 | ||
63 | |||
64 | /* c_oflag bits */ | ||
65 | #define OPOST 0000001 | ||
66 | #define OLCUC 0000002 | ||
67 | #define ONLCR 0000004 | ||
68 | #define OCRNL 0000010 | ||
69 | #define ONOCR 0000020 | ||
70 | #define ONLRET 0000040 | ||
71 | #define OFILL 0000100 | ||
72 | #define OFDEL 0000200 | ||
73 | #define NLDLY 0000400 | ||
74 | #define NL0 0000000 | ||
75 | #define NL1 0000400 | ||
76 | #define CRDLY 0003000 | ||
77 | #define CR0 0000000 | ||
78 | #define CR1 0001000 | ||
79 | #define CR2 0002000 | ||
80 | #define CR3 0003000 | ||
81 | #define TABDLY 0014000 | ||
82 | #define TAB0 0000000 | ||
83 | #define TAB1 0004000 | ||
84 | #define TAB2 0010000 | ||
85 | #define TAB3 0014000 | ||
86 | #define XTABS 0014000 | ||
87 | #define BSDLY 0020000 | ||
88 | #define BS0 0000000 | ||
89 | #define BS1 0020000 | ||
90 | #define VTDLY 0040000 | ||
91 | #define VT0 0000000 | ||
92 | #define VT1 0040000 | ||
93 | #define FFDLY 0100000 | ||
94 | #define FF0 0000000 | ||
95 | #define FF1 0100000 | ||
96 | |||
97 | /* c_cflag bit meaning */ | ||
98 | #define CBAUD 0010017 | ||
99 | #define B0 0000000 /* hang up */ | ||
100 | #define B50 0000001 | ||
101 | #define B75 0000002 | ||
102 | #define B110 0000003 | ||
103 | #define B134 0000004 | ||
104 | #define B150 0000005 | ||
105 | #define B200 0000006 | ||
106 | #define B300 0000007 | ||
107 | #define B600 0000010 | ||
108 | #define B1200 0000011 | ||
109 | #define B1800 0000012 | ||
110 | #define B2400 0000013 | ||
111 | #define B4800 0000014 | ||
112 | #define B9600 0000015 | ||
113 | #define B19200 0000016 | ||
114 | #define B38400 0000017 | ||
115 | #define EXTA B19200 | ||
116 | #define EXTB B38400 | ||
117 | #define CSIZE 0000060 | ||
118 | #define CS5 0000000 | ||
119 | #define CS6 0000020 | ||
120 | #define CS7 0000040 | ||
121 | #define CS8 0000060 | ||
122 | #define CSTOPB 0000100 | ||
123 | #define CREAD 0000200 | ||
124 | #define PARENB 0000400 | ||
125 | #define PARODD 0001000 | ||
126 | #define HUPCL 0002000 | ||
127 | #define CLOCAL 0004000 | ||
128 | #define CBAUDEX 0010000 | ||
129 | #define B57600 0010001 | ||
130 | #define B115200 0010002 | ||
131 | #define B230400 0010003 | ||
132 | #define B460800 0010004 | ||
133 | #define B500000 0010005 | ||
134 | #define B576000 0010006 | ||
135 | #define B921600 0010007 | ||
136 | #define B1000000 0010010 | ||
137 | #define B1152000 0010011 | ||
138 | #define B1500000 0010012 | ||
139 | #define B2000000 0010013 | ||
140 | #define B2500000 0010014 | ||
141 | #define B3000000 0010015 | ||
142 | #define B3500000 0010016 | ||
143 | #define B4000000 0010017 | ||
144 | #define CIBAUD 002003600000 /* input baud rate (not used) */ | ||
145 | #define CMSPAR 010000000000 /* mark or space (stick) parity */ | ||
146 | #define CRTSCTS 020000000000 /* flow control */ | ||
147 | |||
148 | /* c_lflag bits */ | ||
149 | #define ISIG 0000001 | ||
150 | #define ICANON 0000002 | ||
151 | #define XCASE 0000004 | ||
152 | #define ECHO 0000010 | ||
153 | #define ECHOE 0000020 | ||
154 | #define ECHOK 0000040 | ||
155 | #define ECHONL 0000100 | ||
156 | #define NOFLSH 0000200 | ||
157 | #define TOSTOP 0000400 | ||
158 | #define ECHOCTL 0001000 | ||
159 | #define ECHOPRT 0002000 | ||
160 | #define ECHOKE 0004000 | ||
161 | #define FLUSHO 0010000 | ||
162 | #define PENDIN 0040000 | ||
163 | #define IEXTEN 0100000 | ||
164 | |||
165 | /* tcflow() and TCXONC use these */ | ||
166 | #define TCOOFF 0 | ||
167 | #define TCOON 1 | ||
168 | #define TCIOFF 2 | ||
169 | #define TCION 3 | ||
170 | |||
171 | /* tcflush() and TCFLSH use these */ | ||
172 | #define TCIFLUSH 0 | ||
173 | #define TCOFLUSH 1 | ||
174 | #define TCIOFLUSH 2 | ||
175 | |||
176 | /* tcsetattr uses these */ | ||
177 | #define TCSANOW 0 | ||
178 | #define TCSADRAIN 1 | ||
179 | #define TCSAFLUSH 2 | ||
180 | |||
181 | #endif | ||
diff --git a/include/asm-s390/termios.h b/include/asm-s390/termios.h new file mode 100644 index 000000000000..d1e29cca54c9 --- /dev/null +++ b/include/asm-s390/termios.h | |||
@@ -0,0 +1,114 @@ | |||
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 | /* line disciplines */ | ||
51 | #define N_TTY 0 | ||
52 | #define N_SLIP 1 | ||
53 | #define N_MOUSE 2 | ||
54 | #define N_PPP 3 | ||
55 | #define N_STRIP 4 | ||
56 | #define N_AX25 5 | ||
57 | #define N_X25 6 /* X.25 async */ | ||
58 | #define N_6PACK 7 | ||
59 | #define N_MASC 8 /* Reserved for Mobitex module <kaz@cafe.net> */ | ||
60 | #define N_R3964 9 /* Reserved for Simatic R3964 module */ | ||
61 | #define N_PROFIBUS_FDL 10 /* Reserved for Profibus <Dave@mvhi.com> */ | ||
62 | #define N_IRDA 11 /* Linux IR - http://irda.sourceforge.net/ */ | ||
63 | #define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ | ||
64 | #define N_HDLC 13 /* synchronous HDLC */ | ||
65 | #define N_SYNC_PPP 14 /* synchronous PPP */ | ||
66 | #define N_HCI 15 /* Bluetooth HCI UART */ | ||
67 | |||
68 | #ifdef __KERNEL__ | ||
69 | |||
70 | /* intr=^C quit=^\ erase=del kill=^U | ||
71 | eof=^D vtime=\0 vmin=\1 sxtc=\0 | ||
72 | start=^Q stop=^S susp=^Z eol=\0 | ||
73 | reprint=^R discard=^U werase=^W lnext=^V | ||
74 | eol2=\0 | ||
75 | */ | ||
76 | #define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" | ||
77 | |||
78 | /* | ||
79 | * Translate a "termio" structure into a "termios". Ugh. | ||
80 | */ | ||
81 | #define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ | ||
82 | unsigned short __tmp; \ | ||
83 | get_user(__tmp,&(termio)->x); \ | ||
84 | (termios)->x = (0xffff0000 & ((termios)->x)) | __tmp; \ | ||
85 | } | ||
86 | |||
87 | #define user_termio_to_kernel_termios(termios, termio) \ | ||
88 | ({ \ | ||
89 | SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ | ||
90 | SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ | ||
91 | SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ | ||
92 | SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ | ||
93 | copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ | ||
94 | }) | ||
95 | |||
96 | /* | ||
97 | * Translate a "termios" structure into a "termio". Ugh. | ||
98 | */ | ||
99 | #define kernel_termios_to_user_termio(termio, termios) \ | ||
100 | ({ \ | ||
101 | put_user((termios)->c_iflag, &(termio)->c_iflag); \ | ||
102 | put_user((termios)->c_oflag, &(termio)->c_oflag); \ | ||
103 | put_user((termios)->c_cflag, &(termio)->c_cflag); \ | ||
104 | put_user((termios)->c_lflag, &(termio)->c_lflag); \ | ||
105 | put_user((termios)->c_line, &(termio)->c_line); \ | ||
106 | copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ | ||
107 | }) | ||
108 | |||
109 | #define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) | ||
110 | #define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) | ||
111 | |||
112 | #endif /* __KERNEL__ */ | ||
113 | |||
114 | #endif /* _S390_TERMIOS_H */ | ||
diff --git a/include/asm-s390/thread_info.h b/include/asm-s390/thread_info.h new file mode 100644 index 000000000000..aade85c53a63 --- /dev/null +++ b/include/asm-s390/thread_info.h | |||
@@ -0,0 +1,120 @@ | |||
1 | /* | ||
2 | * include/asm-s390/thread_info.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * Copyright (C) 2002 IBM Deutschland Entwicklung GmbH, IBM Corporation | ||
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 | unsigned int preempt_count; /* 0 => preemptable */ | ||
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 | .restart_block = { \ | ||
67 | .fn = do_no_restart_syscall, \ | ||
68 | }, \ | ||
69 | } | ||
70 | |||
71 | #define init_thread_info (init_thread_union.thread_info) | ||
72 | #define init_stack (init_thread_union.stack) | ||
73 | |||
74 | /* how to get the thread information struct from C */ | ||
75 | static inline struct thread_info *current_thread_info(void) | ||
76 | { | ||
77 | return (struct thread_info *)((*(unsigned long *) __LC_KERNEL_STACK)-THREAD_SIZE); | ||
78 | } | ||
79 | |||
80 | /* thread information allocation */ | ||
81 | #define alloc_thread_info(tsk) ((struct thread_info *) \ | ||
82 | __get_free_pages(GFP_KERNEL,THREAD_ORDER)) | ||
83 | #define free_thread_info(ti) free_pages((unsigned long) (ti),THREAD_ORDER) | ||
84 | #define get_thread_info(ti) get_task_struct((ti)->task) | ||
85 | #define put_thread_info(ti) put_task_struct((ti)->task) | ||
86 | |||
87 | #endif | ||
88 | |||
89 | /* | ||
90 | * thread information flags bit numbers | ||
91 | */ | ||
92 | #define TIF_SYSCALL_TRACE 0 /* syscall trace active */ | ||
93 | #define TIF_NOTIFY_RESUME 1 /* resumption notification requested */ | ||
94 | #define TIF_SIGPENDING 2 /* signal pending */ | ||
95 | #define TIF_NEED_RESCHED 3 /* rescheduling necessary */ | ||
96 | #define TIF_RESTART_SVC 4 /* restart svc with new svc number */ | ||
97 | #define TIF_SYSCALL_AUDIT 5 /* syscall auditing active */ | ||
98 | #define TIF_SINGLE_STEP 6 /* deliver sigtrap on return to user */ | ||
99 | #define TIF_USEDFPU 16 /* FPU was used by this task this quantum (SMP) */ | ||
100 | #define TIF_POLLING_NRFLAG 17 /* true if poll_idle() is polling | ||
101 | TIF_NEED_RESCHED */ | ||
102 | #define TIF_31BIT 18 /* 32bit process */ | ||
103 | #define TIF_MEMDIE 19 | ||
104 | |||
105 | #define _TIF_SYSCALL_TRACE (1<<TIF_SYSCALL_TRACE) | ||
106 | #define _TIF_NOTIFY_RESUME (1<<TIF_NOTIFY_RESUME) | ||
107 | #define _TIF_SIGPENDING (1<<TIF_SIGPENDING) | ||
108 | #define _TIF_NEED_RESCHED (1<<TIF_NEED_RESCHED) | ||
109 | #define _TIF_RESTART_SVC (1<<TIF_RESTART_SVC) | ||
110 | #define _TIF_SYSCALL_AUDIT (1<<TIF_SYSCALL_AUDIT) | ||
111 | #define _TIF_SINGLE_STEP (1<<TIF_SINGLE_STEP) | ||
112 | #define _TIF_USEDFPU (1<<TIF_USEDFPU) | ||
113 | #define _TIF_POLLING_NRFLAG (1<<TIF_POLLING_NRFLAG) | ||
114 | #define _TIF_31BIT (1<<TIF_31BIT) | ||
115 | |||
116 | #endif /* __KERNEL__ */ | ||
117 | |||
118 | #define PREEMPT_ACTIVE 0x4000000 | ||
119 | |||
120 | #endif /* _ASM_THREAD_INFO_H */ | ||
diff --git a/include/asm-s390/timer.h b/include/asm-s390/timer.h new file mode 100644 index 000000000000..ea0788967c51 --- /dev/null +++ b/include/asm-s390/timer.h | |||
@@ -0,0 +1,46 @@ | |||
1 | /* | ||
2 | * include/asm-s390/timer.h | ||
3 | * | ||
4 | * (C) Copyright IBM Corp. 2003 | ||
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 | #include <linux/timer.h> | ||
14 | |||
15 | #define VTIMER_MAX_SLICE (0x7ffffffffffff000LL) | ||
16 | |||
17 | struct vtimer_list { | ||
18 | struct list_head entry; | ||
19 | |||
20 | int cpu; | ||
21 | __u64 expires; | ||
22 | __u64 interval; | ||
23 | |||
24 | spinlock_t lock; | ||
25 | unsigned long magic; | ||
26 | |||
27 | void (*function)(unsigned long, struct pt_regs*); | ||
28 | unsigned long data; | ||
29 | }; | ||
30 | |||
31 | /* the offset value will wrap after ca. 71 years */ | ||
32 | struct vtimer_queue { | ||
33 | struct list_head list; | ||
34 | spinlock_t lock; | ||
35 | __u64 to_expire; /* current event expire time */ | ||
36 | __u64 offset; /* list offset to zero */ | ||
37 | __u64 idle; /* temp var for idle */ | ||
38 | }; | ||
39 | |||
40 | extern void init_virt_timer(struct vtimer_list *timer); | ||
41 | extern void add_virt_timer(void *new); | ||
42 | extern void add_virt_timer_periodic(void *new); | ||
43 | extern int mod_virt_timer(struct vtimer_list *timer, __u64 expires); | ||
44 | extern int del_virt_timer(struct vtimer_list *timer); | ||
45 | |||
46 | #endif | ||
diff --git a/include/asm-s390/timex.h b/include/asm-s390/timex.h new file mode 100644 index 000000000000..4848057dafe4 --- /dev/null +++ b/include/asm-s390/timex.h | |||
@@ -0,0 +1,34 @@ | |||
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 | #define CLOCK_TICK_RATE 1193180 /* Underlying HZ */ | ||
15 | |||
16 | typedef unsigned long long cycles_t; | ||
17 | |||
18 | static inline cycles_t get_cycles(void) | ||
19 | { | ||
20 | cycles_t cycles; | ||
21 | |||
22 | __asm__("stck 0(%1)" : "=m" (cycles) : "a" (&cycles) : "cc"); | ||
23 | return cycles >> 2; | ||
24 | } | ||
25 | |||
26 | static inline unsigned long long get_clock (void) | ||
27 | { | ||
28 | unsigned long long clk; | ||
29 | |||
30 | __asm__("stck 0(%1)" : "=m" (clk) : "a" (&clk) : "cc"); | ||
31 | return clk; | ||
32 | } | ||
33 | |||
34 | #endif | ||
diff --git a/include/asm-s390/tlb.h b/include/asm-s390/tlb.h new file mode 100644 index 000000000000..51bd957b85bd --- /dev/null +++ b/include/asm-s390/tlb.h | |||
@@ -0,0 +1,20 @@ | |||
1 | #ifndef _S390_TLB_H | ||
2 | #define _S390_TLB_H | ||
3 | |||
4 | /* | ||
5 | * s390 doesn't need any special per-pte or | ||
6 | * per-vma handling.. | ||
7 | */ | ||
8 | #define tlb_start_vma(tlb, vma) do { } while (0) | ||
9 | #define tlb_end_vma(tlb, vma) do { } while (0) | ||
10 | #define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) | ||
11 | |||
12 | /* | ||
13 | * .. because we flush the whole mm when it | ||
14 | * fills up. | ||
15 | */ | ||
16 | #define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) | ||
17 | |||
18 | #include <asm-generic/tlb.h> | ||
19 | |||
20 | #endif | ||
diff --git a/include/asm-s390/tlbflush.h b/include/asm-s390/tlbflush.h new file mode 100644 index 000000000000..1bb73b0e61fa --- /dev/null +++ b/include/asm-s390/tlbflush.h | |||
@@ -0,0 +1,153 @@ | |||
1 | #ifndef _S390_TLBFLUSH_H | ||
2 | #define _S390_TLBFLUSH_H | ||
3 | |||
4 | #include <linux/config.h> | ||
5 | #include <linux/mm.h> | ||
6 | #include <asm/processor.h> | ||
7 | |||
8 | /* | ||
9 | * TLB flushing: | ||
10 | * | ||
11 | * - flush_tlb() flushes the current mm struct TLBs | ||
12 | * - flush_tlb_all() flushes all processes TLBs | ||
13 | * - flush_tlb_mm(mm) flushes the specified mm context TLB's | ||
14 | * - flush_tlb_page(vma, vmaddr) flushes one page | ||
15 | * - flush_tlb_range(vma, start, end) flushes a range of pages | ||
16 | * - flush_tlb_kernel_range(start, end) flushes a range of kernel pages | ||
17 | * - flush_tlb_pgtables(mm, start, end) flushes a range of page tables | ||
18 | */ | ||
19 | |||
20 | /* | ||
21 | * S/390 has three ways of flushing TLBs | ||
22 | * 'ptlb' does a flush of the local processor | ||
23 | * 'csp' flushes the TLBs on all PUs of a SMP | ||
24 | * 'ipte' invalidates a pte in a page table and flushes that out of | ||
25 | * the TLBs of all PUs of a SMP | ||
26 | */ | ||
27 | |||
28 | #define local_flush_tlb() \ | ||
29 | do { __asm__ __volatile__("ptlb": : :"memory"); } while (0) | ||
30 | |||
31 | #ifndef CONFIG_SMP | ||
32 | |||
33 | /* | ||
34 | * We always need to flush, since s390 does not flush tlb | ||
35 | * on each context switch | ||
36 | */ | ||
37 | |||
38 | static inline void flush_tlb(void) | ||
39 | { | ||
40 | local_flush_tlb(); | ||
41 | } | ||
42 | static inline void flush_tlb_all(void) | ||
43 | { | ||
44 | local_flush_tlb(); | ||
45 | } | ||
46 | static inline void flush_tlb_mm(struct mm_struct *mm) | ||
47 | { | ||
48 | local_flush_tlb(); | ||
49 | } | ||
50 | static inline void flush_tlb_page(struct vm_area_struct *vma, | ||
51 | unsigned long addr) | ||
52 | { | ||
53 | local_flush_tlb(); | ||
54 | } | ||
55 | static inline void flush_tlb_range(struct vm_area_struct *vma, | ||
56 | unsigned long start, unsigned long end) | ||
57 | { | ||
58 | local_flush_tlb(); | ||
59 | } | ||
60 | |||
61 | #define flush_tlb_kernel_range(start, end) \ | ||
62 | local_flush_tlb(); | ||
63 | |||
64 | #else | ||
65 | |||
66 | #include <asm/smp.h> | ||
67 | |||
68 | extern void smp_ptlb_all(void); | ||
69 | |||
70 | static inline void global_flush_tlb(void) | ||
71 | { | ||
72 | #ifndef __s390x__ | ||
73 | if (!MACHINE_HAS_CSP) { | ||
74 | smp_ptlb_all(); | ||
75 | return; | ||
76 | } | ||
77 | #endif /* __s390x__ */ | ||
78 | { | ||
79 | register unsigned long addr asm("4"); | ||
80 | long dummy; | ||
81 | |||
82 | dummy = 0; | ||
83 | addr = ((unsigned long) &dummy) + 1; | ||
84 | __asm__ __volatile__ ( | ||
85 | " slr 2,2\n" | ||
86 | " slr 3,3\n" | ||
87 | " csp 2,%0" | ||
88 | : : "a" (addr), "m" (dummy) : "cc", "2", "3" ); | ||
89 | } | ||
90 | } | ||
91 | |||
92 | /* | ||
93 | * We only have to do global flush of tlb if process run since last | ||
94 | * flush on any other pu than current. | ||
95 | * If we have threads (mm->count > 1) we always do a global flush, | ||
96 | * since the process runs on more than one processor at the same time. | ||
97 | */ | ||
98 | |||
99 | static inline void __flush_tlb_mm(struct mm_struct * mm) | ||
100 | { | ||
101 | cpumask_t local_cpumask; | ||
102 | |||
103 | if (unlikely(cpus_empty(mm->cpu_vm_mask))) | ||
104 | return; | ||
105 | if (MACHINE_HAS_IDTE) { | ||
106 | asm volatile (".insn rrf,0xb98e0000,0,%0,%1,0" | ||
107 | : : "a" (2048), | ||
108 | "a" (__pa(mm->pgd)&PAGE_MASK) : "cc" ); | ||
109 | return; | ||
110 | } | ||
111 | preempt_disable(); | ||
112 | local_cpumask = cpumask_of_cpu(smp_processor_id()); | ||
113 | if (cpus_equal(mm->cpu_vm_mask, local_cpumask)) | ||
114 | local_flush_tlb(); | ||
115 | else | ||
116 | global_flush_tlb(); | ||
117 | preempt_enable(); | ||
118 | } | ||
119 | |||
120 | static inline void flush_tlb(void) | ||
121 | { | ||
122 | __flush_tlb_mm(current->mm); | ||
123 | } | ||
124 | static inline void flush_tlb_all(void) | ||
125 | { | ||
126 | global_flush_tlb(); | ||
127 | } | ||
128 | static inline void flush_tlb_mm(struct mm_struct *mm) | ||
129 | { | ||
130 | __flush_tlb_mm(mm); | ||
131 | } | ||
132 | static inline void flush_tlb_page(struct vm_area_struct *vma, | ||
133 | unsigned long addr) | ||
134 | { | ||
135 | __flush_tlb_mm(vma->vm_mm); | ||
136 | } | ||
137 | static inline void flush_tlb_range(struct vm_area_struct *vma, | ||
138 | unsigned long start, unsigned long end) | ||
139 | { | ||
140 | __flush_tlb_mm(vma->vm_mm); | ||
141 | } | ||
142 | |||
143 | #define flush_tlb_kernel_range(start, end) global_flush_tlb() | ||
144 | |||
145 | #endif | ||
146 | |||
147 | static inline void flush_tlb_pgtables(struct mm_struct *mm, | ||
148 | unsigned long start, unsigned long end) | ||
149 | { | ||
150 | /* S/390 does not keep any page table caches in TLB */ | ||
151 | } | ||
152 | |||
153 | #endif /* _S390_TLBFLUSH_H */ | ||
diff --git a/include/asm-s390/todclk.h b/include/asm-s390/todclk.h new file mode 100644 index 000000000000..c7f62055488a --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/topology.h b/include/asm-s390/topology.h new file mode 100644 index 000000000000..613aa64019da --- /dev/null +++ b/include/asm-s390/topology.h | |||
@@ -0,0 +1,6 @@ | |||
1 | #ifndef _ASM_S390_TOPOLOGY_H | ||
2 | #define _ASM_S390_TOPOLOGY_H | ||
3 | |||
4 | #include <asm-generic/topology.h> | ||
5 | |||
6 | #endif /* _ASM_S390_TOPOLOGY_H */ | ||
diff --git a/include/asm-s390/types.h b/include/asm-s390/types.h new file mode 100644 index 000000000000..3fefd61416a5 --- /dev/null +++ b/include/asm-s390/types.h | |||
@@ -0,0 +1,101 @@ | |||
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 __ASSEMBLY__ | ||
13 | |||
14 | typedef unsigned short umode_t; | ||
15 | |||
16 | /* | ||
17 | * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the | ||
18 | * header files exported to user space | ||
19 | */ | ||
20 | |||
21 | typedef __signed__ char __s8; | ||
22 | typedef unsigned char __u8; | ||
23 | |||
24 | typedef __signed__ short __s16; | ||
25 | typedef unsigned short __u16; | ||
26 | |||
27 | typedef __signed__ int __s32; | ||
28 | typedef unsigned int __u32; | ||
29 | |||
30 | #ifndef __s390x__ | ||
31 | #if defined(__GNUC__) && !defined(__STRICT_ANSI__) | ||
32 | typedef __signed__ long long __s64; | ||
33 | typedef unsigned long long __u64; | ||
34 | #endif | ||
35 | #else /* __s390x__ */ | ||
36 | typedef __signed__ long __s64; | ||
37 | typedef unsigned long __u64; | ||
38 | #endif | ||
39 | |||
40 | /* A address type so that arithmetic can be done on it & it can be upgraded to | ||
41 | 64 bit when necessary | ||
42 | */ | ||
43 | typedef unsigned long addr_t; | ||
44 | typedef __signed__ long saddr_t; | ||
45 | |||
46 | #endif /* __ASSEMBLY__ */ | ||
47 | |||
48 | /* | ||
49 | * These aren't exported outside the kernel to avoid name space clashes | ||
50 | */ | ||
51 | #ifdef __KERNEL__ | ||
52 | |||
53 | #ifndef __s390x__ | ||
54 | #define BITS_PER_LONG 32 | ||
55 | #else | ||
56 | #define BITS_PER_LONG 64 | ||
57 | #endif | ||
58 | |||
59 | #ifndef __ASSEMBLY__ | ||
60 | |||
61 | #include <linux/config.h> | ||
62 | |||
63 | typedef signed char s8; | ||
64 | typedef unsigned char u8; | ||
65 | |||
66 | typedef signed short s16; | ||
67 | typedef unsigned short u16; | ||
68 | |||
69 | typedef signed int s32; | ||
70 | typedef unsigned int u32; | ||
71 | |||
72 | #ifndef __s390x__ | ||
73 | typedef signed long long s64; | ||
74 | typedef unsigned long long u64; | ||
75 | #else /* __s390x__ */ | ||
76 | typedef signed long s64; | ||
77 | typedef unsigned long u64; | ||
78 | #endif /* __s390x__ */ | ||
79 | |||
80 | typedef u32 dma_addr_t; | ||
81 | |||
82 | typedef unsigned int kmem_bufctl_t; | ||
83 | |||
84 | #ifndef __s390x__ | ||
85 | typedef union { | ||
86 | unsigned long long pair; | ||
87 | struct { | ||
88 | unsigned long even; | ||
89 | unsigned long odd; | ||
90 | } subreg; | ||
91 | } register_pair; | ||
92 | |||
93 | #ifdef CONFIG_LBD | ||
94 | typedef u64 sector_t; | ||
95 | #define HAVE_SECTOR_T | ||
96 | #endif | ||
97 | |||
98 | #endif /* ! __s390x__ */ | ||
99 | #endif /* __ASSEMBLY__ */ | ||
100 | #endif /* __KERNEL__ */ | ||
101 | #endif /* _S390_TYPES_H */ | ||
diff --git a/include/asm-s390/uaccess.h b/include/asm-s390/uaccess.h new file mode 100644 index 000000000000..a7f43a251f81 --- /dev/null +++ b/include/asm-s390/uaccess.h | |||
@@ -0,0 +1,436 @@ | |||
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 | #ifdef __s390x__ | ||
42 | #define set_fs(x) \ | ||
43 | ({ \ | ||
44 | unsigned long __pto; \ | ||
45 | current->thread.mm_segment = (x); \ | ||
46 | __pto = current->thread.mm_segment.ar4 ? \ | ||
47 | S390_lowcore.user_asce : S390_lowcore.kernel_asce; \ | ||
48 | asm volatile ("lctlg 7,7,%0" : : "m" (__pto) ); \ | ||
49 | }) | ||
50 | #else | ||
51 | #define set_fs(x) \ | ||
52 | ({ \ | ||
53 | unsigned long __pto; \ | ||
54 | current->thread.mm_segment = (x); \ | ||
55 | __pto = current->thread.mm_segment.ar4 ? \ | ||
56 | S390_lowcore.user_asce : S390_lowcore.kernel_asce; \ | ||
57 | asm volatile ("lctl 7,7,%0" : : "m" (__pto) ); \ | ||
58 | }) | ||
59 | #endif | ||
60 | |||
61 | #define segment_eq(a,b) ((a).ar4 == (b).ar4) | ||
62 | |||
63 | |||
64 | #define __access_ok(addr,size) (1) | ||
65 | |||
66 | #define access_ok(type,addr,size) __access_ok(addr,size) | ||
67 | |||
68 | /* this function will go away soon - use access_ok() instead */ | ||
69 | extern inline int __deprecated verify_area(int type, const void __user *addr, | ||
70 | unsigned long size) | ||
71 | { | ||
72 | return access_ok(type, addr, size) ? 0 : -EFAULT; | ||
73 | } | ||
74 | |||
75 | /* | ||
76 | * The exception table consists of pairs of addresses: the first is the | ||
77 | * address of an instruction that is allowed to fault, and the second is | ||
78 | * the address at which the program should continue. No registers are | ||
79 | * modified, so it is entirely up to the continuation code to figure out | ||
80 | * what to do. | ||
81 | * | ||
82 | * All the routines below use bits of fixup code that are out of line | ||
83 | * with the main instruction path. This means when everything is well, | ||
84 | * we don't even have to jump over them. Further, they do not intrude | ||
85 | * on our cache or tlb entries. | ||
86 | */ | ||
87 | |||
88 | struct exception_table_entry | ||
89 | { | ||
90 | unsigned long insn, fixup; | ||
91 | }; | ||
92 | |||
93 | #ifndef __s390x__ | ||
94 | #define __uaccess_fixup \ | ||
95 | ".section .fixup,\"ax\"\n" \ | ||
96 | "2: lhi %0,%4\n" \ | ||
97 | " bras 1,3f\n" \ | ||
98 | " .long 1b\n" \ | ||
99 | "3: l 1,0(1)\n" \ | ||
100 | " br 1\n" \ | ||
101 | ".previous\n" \ | ||
102 | ".section __ex_table,\"a\"\n" \ | ||
103 | " .align 4\n" \ | ||
104 | " .long 0b,2b\n" \ | ||
105 | ".previous" | ||
106 | #define __uaccess_clobber "cc", "1" | ||
107 | #else /* __s390x__ */ | ||
108 | #define __uaccess_fixup \ | ||
109 | ".section .fixup,\"ax\"\n" \ | ||
110 | "2: lghi %0,%4\n" \ | ||
111 | " jg 1b\n" \ | ||
112 | ".previous\n" \ | ||
113 | ".section __ex_table,\"a\"\n" \ | ||
114 | " .align 8\n" \ | ||
115 | " .quad 0b,2b\n" \ | ||
116 | ".previous" | ||
117 | #define __uaccess_clobber "cc" | ||
118 | #endif /* __s390x__ */ | ||
119 | |||
120 | /* | ||
121 | * These are the main single-value transfer routines. They automatically | ||
122 | * use the right size if we just have the right pointer type. | ||
123 | */ | ||
124 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | ||
125 | #define __put_user_asm(x, ptr, err) \ | ||
126 | ({ \ | ||
127 | err = 0; \ | ||
128 | asm volatile( \ | ||
129 | "0: mvcs 0(%1,%2),%3,%0\n" \ | ||
130 | "1:\n" \ | ||
131 | __uaccess_fixup \ | ||
132 | : "+&d" (err) \ | ||
133 | : "d" (sizeof(*(ptr))), "a" (ptr), "Q" (x), \ | ||
134 | "K" (-EFAULT) \ | ||
135 | : __uaccess_clobber ); \ | ||
136 | }) | ||
137 | #else | ||
138 | #define __put_user_asm(x, ptr, err) \ | ||
139 | ({ \ | ||
140 | err = 0; \ | ||
141 | asm volatile( \ | ||
142 | "0: mvcs 0(%1,%2),0(%3),%0\n" \ | ||
143 | "1:\n" \ | ||
144 | __uaccess_fixup \ | ||
145 | : "+&d" (err) \ | ||
146 | : "d" (sizeof(*(ptr))), "a" (ptr), "a" (&(x)), \ | ||
147 | "K" (-EFAULT), "m" (x) \ | ||
148 | : __uaccess_clobber ); \ | ||
149 | }) | ||
150 | #endif | ||
151 | |||
152 | #ifndef __CHECKER__ | ||
153 | #define __put_user(x, ptr) \ | ||
154 | ({ \ | ||
155 | __typeof__(*(ptr)) __x = (x); \ | ||
156 | int __pu_err; \ | ||
157 | switch (sizeof (*(ptr))) { \ | ||
158 | case 1: \ | ||
159 | case 2: \ | ||
160 | case 4: \ | ||
161 | case 8: \ | ||
162 | __put_user_asm(__x, ptr, __pu_err); \ | ||
163 | break; \ | ||
164 | default: \ | ||
165 | __put_user_bad(); \ | ||
166 | break; \ | ||
167 | } \ | ||
168 | __pu_err; \ | ||
169 | }) | ||
170 | #else | ||
171 | #define __put_user(x, ptr) \ | ||
172 | ({ \ | ||
173 | void __user *p; \ | ||
174 | p = (ptr); \ | ||
175 | 0; \ | ||
176 | }) | ||
177 | #endif | ||
178 | |||
179 | #define put_user(x, ptr) \ | ||
180 | ({ \ | ||
181 | might_sleep(); \ | ||
182 | __put_user(x, ptr); \ | ||
183 | }) | ||
184 | |||
185 | |||
186 | extern int __put_user_bad(void) __attribute__((noreturn)); | ||
187 | |||
188 | #if __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 2) | ||
189 | #define __get_user_asm(x, ptr, err) \ | ||
190 | ({ \ | ||
191 | err = 0; \ | ||
192 | asm volatile ( \ | ||
193 | "0: mvcp %O1(%2,%R1),0(%3),%0\n" \ | ||
194 | "1:\n" \ | ||
195 | __uaccess_fixup \ | ||
196 | : "+&d" (err), "=Q" (x) \ | ||
197 | : "d" (sizeof(*(ptr))), "a" (ptr), \ | ||
198 | "K" (-EFAULT) \ | ||
199 | : __uaccess_clobber ); \ | ||
200 | }) | ||
201 | #else | ||
202 | #define __get_user_asm(x, ptr, err) \ | ||
203 | ({ \ | ||
204 | err = 0; \ | ||
205 | asm volatile ( \ | ||
206 | "0: mvcp 0(%2,%5),0(%3),%0\n" \ | ||
207 | "1:\n" \ | ||
208 | __uaccess_fixup \ | ||
209 | : "+&d" (err), "=m" (x) \ | ||
210 | : "d" (sizeof(*(ptr))), "a" (ptr), \ | ||
211 | "K" (-EFAULT), "a" (&(x)) \ | ||
212 | : __uaccess_clobber ); \ | ||
213 | }) | ||
214 | #endif | ||
215 | |||
216 | #ifndef __CHECKER__ | ||
217 | #define __get_user(x, ptr) \ | ||
218 | ({ \ | ||
219 | __typeof__(*(ptr)) __x; \ | ||
220 | int __gu_err; \ | ||
221 | switch (sizeof(*(ptr))) { \ | ||
222 | case 1: \ | ||
223 | case 2: \ | ||
224 | case 4: \ | ||
225 | case 8: \ | ||
226 | __get_user_asm(__x, ptr, __gu_err); \ | ||
227 | break; \ | ||
228 | default: \ | ||
229 | __get_user_bad(); \ | ||
230 | break; \ | ||
231 | } \ | ||
232 | (x) = __x; \ | ||
233 | __gu_err; \ | ||
234 | }) | ||
235 | #else | ||
236 | #define __get_user(x, ptr) \ | ||
237 | ({ \ | ||
238 | void __user *p; \ | ||
239 | p = (ptr); \ | ||
240 | 0; \ | ||
241 | }) | ||
242 | #endif | ||
243 | |||
244 | |||
245 | #define get_user(x, ptr) \ | ||
246 | ({ \ | ||
247 | might_sleep(); \ | ||
248 | __get_user(x, ptr); \ | ||
249 | }) | ||
250 | |||
251 | extern int __get_user_bad(void) __attribute__((noreturn)); | ||
252 | |||
253 | #define __put_user_unaligned __put_user | ||
254 | #define __get_user_unaligned __get_user | ||
255 | |||
256 | extern long __copy_to_user_asm(const void *from, long n, void __user *to); | ||
257 | |||
258 | /** | ||
259 | * __copy_to_user: - Copy a block of data into user space, with less checking. | ||
260 | * @to: Destination address, in user space. | ||
261 | * @from: Source address, in kernel space. | ||
262 | * @n: Number of bytes to copy. | ||
263 | * | ||
264 | * Context: User context only. This function may sleep. | ||
265 | * | ||
266 | * Copy data from kernel space to user space. Caller must check | ||
267 | * the specified block with access_ok() before calling this function. | ||
268 | * | ||
269 | * Returns number of bytes that could not be copied. | ||
270 | * On success, this will be zero. | ||
271 | */ | ||
272 | static inline unsigned long | ||
273 | __copy_to_user(void __user *to, const void *from, unsigned long n) | ||
274 | { | ||
275 | return __copy_to_user_asm(from, n, to); | ||
276 | } | ||
277 | |||
278 | #define __copy_to_user_inatomic __copy_to_user | ||
279 | #define __copy_from_user_inatomic __copy_from_user | ||
280 | |||
281 | /** | ||
282 | * copy_to_user: - Copy a block of data into user space. | ||
283 | * @to: Destination address, in user space. | ||
284 | * @from: Source address, in kernel space. | ||
285 | * @n: Number of bytes to copy. | ||
286 | * | ||
287 | * Context: User context only. This function may sleep. | ||
288 | * | ||
289 | * Copy data from kernel space to user space. | ||
290 | * | ||
291 | * Returns number of bytes that could not be copied. | ||
292 | * On success, this will be zero. | ||
293 | */ | ||
294 | static inline unsigned long | ||
295 | copy_to_user(void __user *to, const void *from, unsigned long n) | ||
296 | { | ||
297 | might_sleep(); | ||
298 | if (access_ok(VERIFY_WRITE, to, n)) | ||
299 | n = __copy_to_user(to, from, n); | ||
300 | return n; | ||
301 | } | ||
302 | |||
303 | extern long __copy_from_user_asm(void *to, long n, const void __user *from); | ||
304 | |||
305 | /** | ||
306 | * __copy_from_user: - Copy a block of data from user space, with less checking. | ||
307 | * @to: Destination address, in kernel space. | ||
308 | * @from: Source address, in user space. | ||
309 | * @n: Number of bytes to copy. | ||
310 | * | ||
311 | * Context: User context only. This function may sleep. | ||
312 | * | ||
313 | * Copy data from user space to kernel space. Caller must check | ||
314 | * the specified block with access_ok() before calling this function. | ||
315 | * | ||
316 | * Returns number of bytes that could not be copied. | ||
317 | * On success, this will be zero. | ||
318 | * | ||
319 | * If some data could not be copied, this function will pad the copied | ||
320 | * data to the requested size using zero bytes. | ||
321 | */ | ||
322 | static inline unsigned long | ||
323 | __copy_from_user(void *to, const void __user *from, unsigned long n) | ||
324 | { | ||
325 | return __copy_from_user_asm(to, n, from); | ||
326 | } | ||
327 | |||
328 | /** | ||
329 | * copy_from_user: - Copy a block of data from user space. | ||
330 | * @to: Destination address, in kernel space. | ||
331 | * @from: Source address, in user space. | ||
332 | * @n: Number of bytes to copy. | ||
333 | * | ||
334 | * Context: User context only. This function may sleep. | ||
335 | * | ||
336 | * Copy data from user space to kernel space. | ||
337 | * | ||
338 | * Returns number of bytes that could not be copied. | ||
339 | * On success, this will be zero. | ||
340 | * | ||
341 | * If some data could not be copied, this function will pad the copied | ||
342 | * data to the requested size using zero bytes. | ||
343 | */ | ||
344 | static inline unsigned long | ||
345 | copy_from_user(void *to, const void __user *from, unsigned long n) | ||
346 | { | ||
347 | might_sleep(); | ||
348 | if (access_ok(VERIFY_READ, from, n)) | ||
349 | n = __copy_from_user(to, from, n); | ||
350 | else | ||
351 | memset(to, 0, n); | ||
352 | return n; | ||
353 | } | ||
354 | |||
355 | extern unsigned long __copy_in_user_asm(const void __user *from, long n, | ||
356 | void __user *to); | ||
357 | |||
358 | static inline unsigned long | ||
359 | __copy_in_user(void __user *to, const void __user *from, unsigned long n) | ||
360 | { | ||
361 | return __copy_in_user_asm(from, n, to); | ||
362 | } | ||
363 | |||
364 | static inline unsigned long | ||
365 | copy_in_user(void __user *to, const void __user *from, unsigned long n) | ||
366 | { | ||
367 | might_sleep(); | ||
368 | if (__access_ok(from,n) && __access_ok(to,n)) | ||
369 | n = __copy_in_user_asm(from, n, to); | ||
370 | return n; | ||
371 | } | ||
372 | |||
373 | /* | ||
374 | * Copy a null terminated string from userspace. | ||
375 | */ | ||
376 | extern long __strncpy_from_user_asm(long count, char *dst, | ||
377 | const char __user *src); | ||
378 | |||
379 | static inline long | ||
380 | strncpy_from_user(char *dst, const char __user *src, long count) | ||
381 | { | ||
382 | long res = -EFAULT; | ||
383 | might_sleep(); | ||
384 | if (access_ok(VERIFY_READ, src, 1)) | ||
385 | res = __strncpy_from_user_asm(count, dst, src); | ||
386 | return res; | ||
387 | } | ||
388 | |||
389 | |||
390 | extern long __strnlen_user_asm(long count, const char __user *src); | ||
391 | |||
392 | static inline unsigned long | ||
393 | strnlen_user(const char __user * src, unsigned long n) | ||
394 | { | ||
395 | might_sleep(); | ||
396 | return __strnlen_user_asm(n, src); | ||
397 | } | ||
398 | |||
399 | /** | ||
400 | * strlen_user: - Get the size of a string in user space. | ||
401 | * @str: The string to measure. | ||
402 | * | ||
403 | * Context: User context only. This function may sleep. | ||
404 | * | ||
405 | * Get the size of a NUL-terminated string in user space. | ||
406 | * | ||
407 | * Returns the size of the string INCLUDING the terminating NUL. | ||
408 | * On exception, returns 0. | ||
409 | * | ||
410 | * If there is a limit on the length of a valid string, you may wish to | ||
411 | * consider using strnlen_user() instead. | ||
412 | */ | ||
413 | #define strlen_user(str) strnlen_user(str, ~0UL) | ||
414 | |||
415 | /* | ||
416 | * Zero Userspace | ||
417 | */ | ||
418 | |||
419 | extern long __clear_user_asm(void __user *to, long n); | ||
420 | |||
421 | static inline unsigned long | ||
422 | __clear_user(void __user *to, unsigned long n) | ||
423 | { | ||
424 | return __clear_user_asm(to, n); | ||
425 | } | ||
426 | |||
427 | static inline unsigned long | ||
428 | clear_user(void __user *to, unsigned long n) | ||
429 | { | ||
430 | might_sleep(); | ||
431 | if (access_ok(VERIFY_WRITE, to, n)) | ||
432 | n = __clear_user_asm(to, n); | ||
433 | return n; | ||
434 | } | ||
435 | |||
436 | #endif /* __S390_UACCESS_H */ | ||
diff --git a/include/asm-s390/ucontext.h b/include/asm-s390/ucontext.h new file mode 100644 index 000000000000..d69bec0b03f5 --- /dev/null +++ b/include/asm-s390/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/include/asm-s390/unaligned.h b/include/asm-s390/unaligned.h new file mode 100644 index 000000000000..8ee86dbedd1f --- /dev/null +++ b/include/asm-s390/unaligned.h | |||
@@ -0,0 +1,24 @@ | |||
1 | /* | ||
2 | * include/asm-s390/unaligned.h | ||
3 | * | ||
4 | * S390 version | ||
5 | * | ||
6 | * Derived from "include/asm-i386/unaligned.h" | ||
7 | */ | ||
8 | |||
9 | #ifndef __S390_UNALIGNED_H | ||
10 | #define __S390_UNALIGNED_H | ||
11 | |||
12 | /* | ||
13 | * The S390 can do unaligned accesses itself. | ||
14 | * | ||
15 | * The strange macros are there to make sure these can't | ||
16 | * be misused in a way that makes them not work on other | ||
17 | * architectures where unaligned accesses aren't as simple. | ||
18 | */ | ||
19 | |||
20 | #define get_unaligned(ptr) (*(ptr)) | ||
21 | |||
22 | #define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) | ||
23 | |||
24 | #endif | ||
diff --git a/include/asm-s390/unistd.h b/include/asm-s390/unistd.h new file mode 100644 index 000000000000..f1a204f7c0f0 --- /dev/null +++ b/include/asm-s390/unistd.h | |||
@@ -0,0 +1,605 @@ | |||
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_time 13 | ||
29 | #define __NR_mknod 14 | ||
30 | #define __NR_chmod 15 | ||
31 | #define __NR_lchown 16 | ||
32 | #define __NR_lseek 19 | ||
33 | #define __NR_getpid 20 | ||
34 | #define __NR_mount 21 | ||
35 | #define __NR_umount 22 | ||
36 | #define __NR_setuid 23 | ||
37 | #define __NR_getuid 24 | ||
38 | #define __NR_stime 25 | ||
39 | #define __NR_ptrace 26 | ||
40 | #define __NR_alarm 27 | ||
41 | #define __NR_pause 29 | ||
42 | #define __NR_utime 30 | ||
43 | #define __NR_access 33 | ||
44 | #define __NR_nice 34 | ||
45 | #define __NR_sync 36 | ||
46 | #define __NR_kill 37 | ||
47 | #define __NR_rename 38 | ||
48 | #define __NR_mkdir 39 | ||
49 | #define __NR_rmdir 40 | ||
50 | #define __NR_dup 41 | ||
51 | #define __NR_pipe 42 | ||
52 | #define __NR_times 43 | ||
53 | #define __NR_brk 45 | ||
54 | #define __NR_setgid 46 | ||
55 | #define __NR_getgid 47 | ||
56 | #define __NR_signal 48 | ||
57 | #define __NR_geteuid 49 | ||
58 | #define __NR_getegid 50 | ||
59 | #define __NR_acct 51 | ||
60 | #define __NR_umount2 52 | ||
61 | #define __NR_ioctl 54 | ||
62 | #define __NR_fcntl 55 | ||
63 | #define __NR_setpgid 57 | ||
64 | #define __NR_umask 60 | ||
65 | #define __NR_chroot 61 | ||
66 | #define __NR_ustat 62 | ||
67 | #define __NR_dup2 63 | ||
68 | #define __NR_getppid 64 | ||
69 | #define __NR_getpgrp 65 | ||
70 | #define __NR_setsid 66 | ||
71 | #define __NR_sigaction 67 | ||
72 | #define __NR_setreuid 70 | ||
73 | #define __NR_setregid 71 | ||
74 | #define __NR_sigsuspend 72 | ||
75 | #define __NR_sigpending 73 | ||
76 | #define __NR_sethostname 74 | ||
77 | #define __NR_setrlimit 75 | ||
78 | #define __NR_getrlimit 76 | ||
79 | #define __NR_getrusage 77 | ||
80 | #define __NR_gettimeofday 78 | ||
81 | #define __NR_settimeofday 79 | ||
82 | #define __NR_getgroups 80 | ||
83 | #define __NR_setgroups 81 | ||
84 | #define __NR_symlink 83 | ||
85 | #define __NR_readlink 85 | ||
86 | #define __NR_uselib 86 | ||
87 | #define __NR_swapon 87 | ||
88 | #define __NR_reboot 88 | ||
89 | #define __NR_readdir 89 | ||
90 | #define __NR_mmap 90 | ||
91 | #define __NR_munmap 91 | ||
92 | #define __NR_truncate 92 | ||
93 | #define __NR_ftruncate 93 | ||
94 | #define __NR_fchmod 94 | ||
95 | #define __NR_fchown 95 | ||
96 | #define __NR_getpriority 96 | ||
97 | #define __NR_setpriority 97 | ||
98 | #define __NR_statfs 99 | ||
99 | #define __NR_fstatfs 100 | ||
100 | #define __NR_ioperm 101 | ||
101 | #define __NR_socketcall 102 | ||
102 | #define __NR_syslog 103 | ||
103 | #define __NR_setitimer 104 | ||
104 | #define __NR_getitimer 105 | ||
105 | #define __NR_stat 106 | ||
106 | #define __NR_lstat 107 | ||
107 | #define __NR_fstat 108 | ||
108 | #define __NR_lookup_dcookie 110 | ||
109 | #define __NR_vhangup 111 | ||
110 | #define __NR_idle 112 | ||
111 | #define __NR_wait4 114 | ||
112 | #define __NR_swapoff 115 | ||
113 | #define __NR_sysinfo 116 | ||
114 | #define __NR_ipc 117 | ||
115 | #define __NR_fsync 118 | ||
116 | #define __NR_sigreturn 119 | ||
117 | #define __NR_clone 120 | ||
118 | #define __NR_setdomainname 121 | ||
119 | #define __NR_uname 122 | ||
120 | #define __NR_adjtimex 124 | ||
121 | #define __NR_mprotect 125 | ||
122 | #define __NR_sigprocmask 126 | ||
123 | #define __NR_create_module 127 | ||
124 | #define __NR_init_module 128 | ||
125 | #define __NR_delete_module 129 | ||
126 | #define __NR_get_kernel_syms 130 | ||
127 | #define __NR_quotactl 131 | ||
128 | #define __NR_getpgid 132 | ||
129 | #define __NR_fchdir 133 | ||
130 | #define __NR_bdflush 134 | ||
131 | #define __NR_sysfs 135 | ||
132 | #define __NR_personality 136 | ||
133 | #define __NR_afs_syscall 137 /* Syscall for Andrew File System */ | ||
134 | #define __NR_setfsuid 138 | ||
135 | #define __NR_setfsgid 139 | ||
136 | #define __NR__llseek 140 | ||
137 | #define __NR_getdents 141 | ||
138 | #define __NR__newselect 142 | ||
139 | #define __NR_flock 143 | ||
140 | #define __NR_msync 144 | ||
141 | #define __NR_readv 145 | ||
142 | #define __NR_writev 146 | ||
143 | #define __NR_getsid 147 | ||
144 | #define __NR_fdatasync 148 | ||
145 | #define __NR__sysctl 149 | ||
146 | #define __NR_mlock 150 | ||
147 | #define __NR_munlock 151 | ||
148 | #define __NR_mlockall 152 | ||
149 | #define __NR_munlockall 153 | ||
150 | #define __NR_sched_setparam 154 | ||
151 | #define __NR_sched_getparam 155 | ||
152 | #define __NR_sched_setscheduler 156 | ||
153 | #define __NR_sched_getscheduler 157 | ||
154 | #define __NR_sched_yield 158 | ||
155 | #define __NR_sched_get_priority_max 159 | ||
156 | #define __NR_sched_get_priority_min 160 | ||
157 | #define __NR_sched_rr_get_interval 161 | ||
158 | #define __NR_nanosleep 162 | ||
159 | #define __NR_mremap 163 | ||
160 | #define __NR_setresuid 164 | ||
161 | #define __NR_getresuid 165 | ||
162 | #define __NR_query_module 167 | ||
163 | #define __NR_poll 168 | ||
164 | #define __NR_nfsservctl 169 | ||
165 | #define __NR_setresgid 170 | ||
166 | #define __NR_getresgid 171 | ||
167 | #define __NR_prctl 172 | ||
168 | #define __NR_rt_sigreturn 173 | ||
169 | #define __NR_rt_sigaction 174 | ||
170 | #define __NR_rt_sigprocmask 175 | ||
171 | #define __NR_rt_sigpending 176 | ||
172 | #define __NR_rt_sigtimedwait 177 | ||
173 | #define __NR_rt_sigqueueinfo 178 | ||
174 | #define __NR_rt_sigsuspend 179 | ||
175 | #define __NR_pread64 180 | ||
176 | #define __NR_pwrite64 181 | ||
177 | #define __NR_chown 182 | ||
178 | #define __NR_getcwd 183 | ||
179 | #define __NR_capget 184 | ||
180 | #define __NR_capset 185 | ||
181 | #define __NR_sigaltstack 186 | ||
182 | #define __NR_sendfile 187 | ||
183 | #define __NR_getpmsg 188 | ||
184 | #define __NR_putpmsg 189 | ||
185 | #define __NR_vfork 190 | ||
186 | #define __NR_ugetrlimit 191 /* SuS compliant getrlimit */ | ||
187 | #define __NR_mmap2 192 | ||
188 | #define __NR_truncate64 193 | ||
189 | #define __NR_ftruncate64 194 | ||
190 | #define __NR_stat64 195 | ||
191 | #define __NR_lstat64 196 | ||
192 | #define __NR_fstat64 197 | ||
193 | #define __NR_lchown32 198 | ||
194 | #define __NR_getuid32 199 | ||
195 | #define __NR_getgid32 200 | ||
196 | #define __NR_geteuid32 201 | ||
197 | #define __NR_getegid32 202 | ||
198 | #define __NR_setreuid32 203 | ||
199 | #define __NR_setregid32 204 | ||
200 | #define __NR_getgroups32 205 | ||
201 | #define __NR_setgroups32 206 | ||
202 | #define __NR_fchown32 207 | ||
203 | #define __NR_setresuid32 208 | ||
204 | #define __NR_getresuid32 209 | ||
205 | #define __NR_setresgid32 210 | ||
206 | #define __NR_getresgid32 211 | ||
207 | #define __NR_chown32 212 | ||
208 | #define __NR_setuid32 213 | ||
209 | #define __NR_setgid32 214 | ||
210 | #define __NR_setfsuid32 215 | ||
211 | #define __NR_setfsgid32 216 | ||
212 | #define __NR_pivot_root 217 | ||
213 | #define __NR_mincore 218 | ||
214 | #define __NR_madvise 219 | ||
215 | #define __NR_getdents64 220 | ||
216 | #define __NR_fcntl64 221 | ||
217 | #define __NR_readahead 222 | ||
218 | #define __NR_sendfile64 223 | ||
219 | #define __NR_setxattr 224 | ||
220 | #define __NR_lsetxattr 225 | ||
221 | #define __NR_fsetxattr 226 | ||
222 | #define __NR_getxattr 227 | ||
223 | #define __NR_lgetxattr 228 | ||
224 | #define __NR_fgetxattr 229 | ||
225 | #define __NR_listxattr 230 | ||
226 | #define __NR_llistxattr 231 | ||
227 | #define __NR_flistxattr 232 | ||
228 | #define __NR_removexattr 233 | ||
229 | #define __NR_lremovexattr 234 | ||
230 | #define __NR_fremovexattr 235 | ||
231 | #define __NR_gettid 236 | ||
232 | #define __NR_tkill 237 | ||
233 | #define __NR_futex 238 | ||
234 | #define __NR_sched_setaffinity 239 | ||
235 | #define __NR_sched_getaffinity 240 | ||
236 | #define __NR_tgkill 241 | ||
237 | /* Number 242 is reserved for tux */ | ||
238 | #define __NR_io_setup 243 | ||
239 | #define __NR_io_destroy 244 | ||
240 | #define __NR_io_getevents 245 | ||
241 | #define __NR_io_submit 246 | ||
242 | #define __NR_io_cancel 247 | ||
243 | #define __NR_exit_group 248 | ||
244 | #define __NR_epoll_create 249 | ||
245 | #define __NR_epoll_ctl 250 | ||
246 | #define __NR_epoll_wait 251 | ||
247 | #define __NR_set_tid_address 252 | ||
248 | #define __NR_fadvise64 253 | ||
249 | #define __NR_timer_create 254 | ||
250 | #define __NR_timer_settime (__NR_timer_create+1) | ||
251 | #define __NR_timer_gettime (__NR_timer_create+2) | ||
252 | #define __NR_timer_getoverrun (__NR_timer_create+3) | ||
253 | #define __NR_timer_delete (__NR_timer_create+4) | ||
254 | #define __NR_clock_settime (__NR_timer_create+5) | ||
255 | #define __NR_clock_gettime (__NR_timer_create+6) | ||
256 | #define __NR_clock_getres (__NR_timer_create+7) | ||
257 | #define __NR_clock_nanosleep (__NR_timer_create+8) | ||
258 | /* Number 263 is reserved for vserver */ | ||
259 | #define __NR_fadvise64_64 264 | ||
260 | #define __NR_statfs64 265 | ||
261 | #define __NR_fstatfs64 266 | ||
262 | #define __NR_remap_file_pages 267 | ||
263 | /* Number 268 is reserved for new sys_mbind */ | ||
264 | /* Number 269 is reserved for new sys_get_mempolicy */ | ||
265 | /* Number 270 is reserved for new sys_set_mempolicy */ | ||
266 | #define __NR_mq_open 271 | ||
267 | #define __NR_mq_unlink 272 | ||
268 | #define __NR_mq_timedsend 273 | ||
269 | #define __NR_mq_timedreceive 274 | ||
270 | #define __NR_mq_notify 275 | ||
271 | #define __NR_mq_getsetattr 276 | ||
272 | /* Number 277 is reserved for new sys_kexec_load */ | ||
273 | #define __NR_add_key 278 | ||
274 | #define __NR_request_key 279 | ||
275 | #define __NR_keyctl 280 | ||
276 | #define __NR_waitid 281 | ||
277 | |||
278 | #define NR_syscalls 282 | ||
279 | |||
280 | /* | ||
281 | * There are some system calls that are not present on 64 bit, some | ||
282 | * have a different name although they do the same (e.g. __NR_chown32 | ||
283 | * is __NR_chown on 64 bit). | ||
284 | */ | ||
285 | #ifdef __s390x__ | ||
286 | #undef __NR_time | ||
287 | #undef __NR_lchown | ||
288 | #undef __NR_setuid | ||
289 | #undef __NR_getuid | ||
290 | #undef __NR_stime | ||
291 | #undef __NR_setgid | ||
292 | #undef __NR_getgid | ||
293 | #undef __NR_geteuid | ||
294 | #undef __NR_getegid | ||
295 | #undef __NR_setreuid | ||
296 | #undef __NR_setregid | ||
297 | #undef __NR_getrlimit | ||
298 | #undef __NR_getgroups | ||
299 | #undef __NR_setgroups | ||
300 | #undef __NR_fchown | ||
301 | #undef __NR_ioperm | ||
302 | #undef __NR_setfsuid | ||
303 | #undef __NR_setfsgid | ||
304 | #undef __NR__llseek | ||
305 | #undef __NR__newselect | ||
306 | #undef __NR_setresuid | ||
307 | #undef __NR_getresuid | ||
308 | #undef __NR_setresgid | ||
309 | #undef __NR_getresgid | ||
310 | #undef __NR_chown | ||
311 | #undef __NR_ugetrlimit | ||
312 | #undef __NR_mmap2 | ||
313 | #undef __NR_truncate64 | ||
314 | #undef __NR_ftruncate64 | ||
315 | #undef __NR_stat64 | ||
316 | #undef __NR_lstat64 | ||
317 | #undef __NR_fstat64 | ||
318 | #undef __NR_lchown32 | ||
319 | #undef __NR_getuid32 | ||
320 | #undef __NR_getgid32 | ||
321 | #undef __NR_geteuid32 | ||
322 | #undef __NR_getegid32 | ||
323 | #undef __NR_setreuid32 | ||
324 | #undef __NR_setregid32 | ||
325 | #undef __NR_getgroups32 | ||
326 | #undef __NR_setgroups32 | ||
327 | #undef __NR_fchown32 | ||
328 | #undef __NR_setresuid32 | ||
329 | #undef __NR_getresuid32 | ||
330 | #undef __NR_setresgid32 | ||
331 | #undef __NR_getresgid32 | ||
332 | #undef __NR_chown32 | ||
333 | #undef __NR_setuid32 | ||
334 | #undef __NR_setgid32 | ||
335 | #undef __NR_setfsuid32 | ||
336 | #undef __NR_setfsgid32 | ||
337 | #undef __NR_fcntl64 | ||
338 | #undef __NR_sendfile64 | ||
339 | #undef __NR_fadvise64_64 | ||
340 | |||
341 | #define __NR_select 142 | ||
342 | #define __NR_getrlimit 191 /* SuS compliant getrlimit */ | ||
343 | #define __NR_lchown 198 | ||
344 | #define __NR_getuid 199 | ||
345 | #define __NR_getgid 200 | ||
346 | #define __NR_geteuid 201 | ||
347 | #define __NR_getegid 202 | ||
348 | #define __NR_setreuid 203 | ||
349 | #define __NR_setregid 204 | ||
350 | #define __NR_getgroups 205 | ||
351 | #define __NR_setgroups 206 | ||
352 | #define __NR_fchown 207 | ||
353 | #define __NR_setresuid 208 | ||
354 | #define __NR_getresuid 209 | ||
355 | #define __NR_setresgid 210 | ||
356 | #define __NR_getresgid 211 | ||
357 | #define __NR_chown 212 | ||
358 | #define __NR_setuid 213 | ||
359 | #define __NR_setgid 214 | ||
360 | #define __NR_setfsuid 215 | ||
361 | #define __NR_setfsgid 216 | ||
362 | |||
363 | #endif | ||
364 | |||
365 | /* user-visible error numbers are in the range -1 - -122: see <asm-s390/errno.h> */ | ||
366 | |||
367 | #define __syscall_return(type, res) \ | ||
368 | do { \ | ||
369 | if ((unsigned long)(res) >= (unsigned long)(-125)) { \ | ||
370 | errno = -(res); \ | ||
371 | res = -1; \ | ||
372 | } \ | ||
373 | return (type) (res); \ | ||
374 | } while (0) | ||
375 | |||
376 | #define _svc_clobber "1", "cc", "memory" | ||
377 | |||
378 | #define _syscall0(type,name) \ | ||
379 | type name(void) { \ | ||
380 | register long __svcres asm("2"); \ | ||
381 | long __res; \ | ||
382 | __asm__ __volatile__ ( \ | ||
383 | " .if %1 < 256\n" \ | ||
384 | " svc %b1\n" \ | ||
385 | " .else\n" \ | ||
386 | " la %%r1,%1\n" \ | ||
387 | " svc 0\n" \ | ||
388 | " .endif" \ | ||
389 | : "=d" (__svcres) \ | ||
390 | : "i" (__NR_##name) \ | ||
391 | : _svc_clobber ); \ | ||
392 | __res = __svcres; \ | ||
393 | __syscall_return(type,__res); \ | ||
394 | } | ||
395 | |||
396 | #define _syscall1(type,name,type1,arg1) \ | ||
397 | type name(type1 arg1) { \ | ||
398 | register type1 __arg1 asm("2") = arg1; \ | ||
399 | register long __svcres asm("2"); \ | ||
400 | long __res; \ | ||
401 | __asm__ __volatile__ ( \ | ||
402 | " .if %1 < 256\n" \ | ||
403 | " svc %b1\n" \ | ||
404 | " .else\n" \ | ||
405 | " la %%r1,%1\n" \ | ||
406 | " svc 0\n" \ | ||
407 | " .endif" \ | ||
408 | : "=d" (__svcres) \ | ||
409 | : "i" (__NR_##name), \ | ||
410 | "0" (__arg1) \ | ||
411 | : _svc_clobber ); \ | ||
412 | __res = __svcres; \ | ||
413 | __syscall_return(type,__res); \ | ||
414 | } | ||
415 | |||
416 | #define _syscall2(type,name,type1,arg1,type2,arg2) \ | ||
417 | type name(type1 arg1, type2 arg2) { \ | ||
418 | register type1 __arg1 asm("2") = arg1; \ | ||
419 | register type2 __arg2 asm("3") = arg2; \ | ||
420 | register long __svcres asm("2"); \ | ||
421 | long __res; \ | ||
422 | __asm__ __volatile__ ( \ | ||
423 | " .if %1 < 256\n" \ | ||
424 | " svc %b1\n" \ | ||
425 | " .else\n" \ | ||
426 | " la %%r1,%1\n" \ | ||
427 | " svc 0\n" \ | ||
428 | " .endif" \ | ||
429 | : "=d" (__svcres) \ | ||
430 | : "i" (__NR_##name), \ | ||
431 | "0" (__arg1), \ | ||
432 | "d" (__arg2) \ | ||
433 | : _svc_clobber ); \ | ||
434 | __res = __svcres; \ | ||
435 | __syscall_return(type,__res); \ | ||
436 | } | ||
437 | |||
438 | #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3)\ | ||
439 | type name(type1 arg1, type2 arg2, type3 arg3) { \ | ||
440 | register type1 __arg1 asm("2") = arg1; \ | ||
441 | register type2 __arg2 asm("3") = arg2; \ | ||
442 | register type3 __arg3 asm("4") = arg3; \ | ||
443 | register long __svcres asm("2"); \ | ||
444 | long __res; \ | ||
445 | __asm__ __volatile__ ( \ | ||
446 | " .if %1 < 256\n" \ | ||
447 | " svc %b1\n" \ | ||
448 | " .else\n" \ | ||
449 | " la %%r1,%1\n" \ | ||
450 | " svc 0\n" \ | ||
451 | " .endif" \ | ||
452 | : "=d" (__svcres) \ | ||
453 | : "i" (__NR_##name), \ | ||
454 | "0" (__arg1), \ | ||
455 | "d" (__arg2), \ | ||
456 | "d" (__arg3) \ | ||
457 | : _svc_clobber ); \ | ||
458 | __res = __svcres; \ | ||
459 | __syscall_return(type,__res); \ | ||
460 | } | ||
461 | |||
462 | #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,\ | ||
463 | type4,name4) \ | ||
464 | type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4) { \ | ||
465 | register type1 __arg1 asm("2") = arg1; \ | ||
466 | register type2 __arg2 asm("3") = arg2; \ | ||
467 | register type3 __arg3 asm("4") = arg3; \ | ||
468 | register type4 __arg4 asm("5") = arg4; \ | ||
469 | register long __svcres asm("2"); \ | ||
470 | long __res; \ | ||
471 | __asm__ __volatile__ ( \ | ||
472 | " .if %1 < 256\n" \ | ||
473 | " svc %b1\n" \ | ||
474 | " .else\n" \ | ||
475 | " la %%r1,%1\n" \ | ||
476 | " svc 0\n" \ | ||
477 | " .endif" \ | ||
478 | : "=d" (__svcres) \ | ||
479 | : "i" (__NR_##name), \ | ||
480 | "0" (__arg1), \ | ||
481 | "d" (__arg2), \ | ||
482 | "d" (__arg3), \ | ||
483 | "d" (__arg4) \ | ||
484 | : _svc_clobber ); \ | ||
485 | __res = __svcres; \ | ||
486 | __syscall_return(type,__res); \ | ||
487 | } | ||
488 | |||
489 | #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,\ | ||
490 | type4,name4,type5,name5) \ | ||
491 | type name(type1 arg1, type2 arg2, type3 arg3, type4 arg4, \ | ||
492 | type5 arg5) { \ | ||
493 | register type1 __arg1 asm("2") = arg1; \ | ||
494 | register type2 __arg2 asm("3") = arg2; \ | ||
495 | register type3 __arg3 asm("4") = arg3; \ | ||
496 | register type4 __arg4 asm("5") = arg4; \ | ||
497 | register type5 __arg5 asm("6") = arg5; \ | ||
498 | register long __svcres asm("2"); \ | ||
499 | long __res; \ | ||
500 | __asm__ __volatile__ ( \ | ||
501 | " .if %1 < 256\n" \ | ||
502 | " svc %b1\n" \ | ||
503 | " .else\n" \ | ||
504 | " la %%r1,%1\n" \ | ||
505 | " svc 0\n" \ | ||
506 | " .endif" \ | ||
507 | : "=d" (__svcres) \ | ||
508 | : "i" (__NR_##name), \ | ||
509 | "0" (__arg1), \ | ||
510 | "d" (__arg2), \ | ||
511 | "d" (__arg3), \ | ||
512 | "d" (__arg4), \ | ||
513 | "d" (__arg5) \ | ||
514 | : _svc_clobber ); \ | ||
515 | __res = __svcres; \ | ||
516 | __syscall_return(type,__res); \ | ||
517 | } | ||
518 | |||
519 | #ifdef __KERNEL__ | ||
520 | #define __ARCH_WANT_IPC_PARSE_VERSION | ||
521 | #define __ARCH_WANT_OLD_READDIR | ||
522 | #define __ARCH_WANT_SYS_ALARM | ||
523 | #define __ARCH_WANT_SYS_GETHOSTNAME | ||
524 | #define __ARCH_WANT_SYS_PAUSE | ||
525 | #define __ARCH_WANT_SYS_SIGNAL | ||
526 | #define __ARCH_WANT_SYS_UTIME | ||
527 | #define __ARCH_WANT_SYS_SOCKETCALL | ||
528 | #define __ARCH_WANT_SYS_FADVISE64 | ||
529 | #define __ARCH_WANT_SYS_GETPGRP | ||
530 | #define __ARCH_WANT_SYS_LLSEEK | ||
531 | #define __ARCH_WANT_SYS_NICE | ||
532 | #define __ARCH_WANT_SYS_OLD_GETRLIMIT | ||
533 | #define __ARCH_WANT_SYS_OLDUMOUNT | ||
534 | #define __ARCH_WANT_SYS_SIGPENDING | ||
535 | #define __ARCH_WANT_SYS_SIGPROCMASK | ||
536 | #define __ARCH_WANT_SYS_RT_SIGACTION | ||
537 | # ifdef CONFIG_ARCH_S390_31 | ||
538 | # define __ARCH_WANT_STAT64 | ||
539 | # define __ARCH_WANT_SYS_TIME | ||
540 | # endif | ||
541 | # define __ARCH_WANT_COMPAT_SYS_TIME | ||
542 | #endif | ||
543 | |||
544 | #ifdef __KERNEL_SYSCALLS__ | ||
545 | |||
546 | #include <linux/config.h> | ||
547 | #include <linux/compiler.h> | ||
548 | #include <linux/types.h> | ||
549 | #include <asm/ptrace.h> | ||
550 | #include <asm/stat.h> | ||
551 | #include <linux/syscalls.h> | ||
552 | |||
553 | /* | ||
554 | * we need this inline - forking from kernel space will result | ||
555 | * in NO COPY ON WRITE (!!!), until an execve is executed. This | ||
556 | * is no problem, but for the stack. This is handled by not letting | ||
557 | * main() use the stack at all after fork(). Thus, no function | ||
558 | * calls - which means inline code for fork too, as otherwise we | ||
559 | * would use the stack upon exit from 'fork()'. | ||
560 | * | ||
561 | * Actually only pause and fork are needed inline, so that there | ||
562 | * won't be any messing with the stack from main(), but we define | ||
563 | * some others too. | ||
564 | */ | ||
565 | #define __NR__exit __NR_exit | ||
566 | static inline _syscall0(pid_t,setsid) | ||
567 | static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) | ||
568 | static inline _syscall3(int,read,int,fd,char *,buf,off_t,count) | ||
569 | static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,count) | ||
570 | static inline _syscall1(int,dup,int,fd) | ||
571 | static inline _syscall3(int,execve,const char *,file,char **,argv,char **,envp) | ||
572 | static inline _syscall3(int,open,const char *,file,int,flag,int,mode) | ||
573 | static inline _syscall1(int,close,int,fd) | ||
574 | static inline _syscall2(long,stat,char *,filename,struct stat *,statbuf) | ||
575 | |||
576 | static inline pid_t waitpid(int pid, int *wait_stat, int flags) | ||
577 | { | ||
578 | return sys_wait4(pid, wait_stat, flags, NULL); | ||
579 | } | ||
580 | struct mmap_arg_struct; | ||
581 | asmlinkage long sys_mmap2(struct mmap_arg_struct __user *arg); | ||
582 | |||
583 | asmlinkage long sys_execve(struct pt_regs regs); | ||
584 | asmlinkage long sys_clone(struct pt_regs regs); | ||
585 | asmlinkage long sys_fork(struct pt_regs regs); | ||
586 | asmlinkage long sys_vfork(struct pt_regs regs); | ||
587 | asmlinkage long sys_pipe(unsigned long __user *fildes); | ||
588 | asmlinkage long sys_ptrace(long request, long pid, long addr, long data); | ||
589 | struct sigaction; | ||
590 | asmlinkage long sys_rt_sigaction(int sig, | ||
591 | const struct sigaction __user *act, | ||
592 | struct sigaction __user *oact, | ||
593 | size_t sigsetsize); | ||
594 | |||
595 | #endif | ||
596 | |||
597 | /* | ||
598 | * "Conditional" syscalls | ||
599 | * | ||
600 | * What we want is __attribute__((weak,alias("sys_ni_syscall"))), | ||
601 | * but it doesn't work on all toolchains, so we just do it by hand | ||
602 | */ | ||
603 | #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall") | ||
604 | |||
605 | #endif /* _ASM_S390_UNISTD_H_ */ | ||
diff --git a/include/asm-s390/user.h b/include/asm-s390/user.h new file mode 100644 index 000000000000..c64f8c181df3 --- /dev/null +++ b/include/asm-s390/user.h | |||
@@ -0,0 +1,77 @@ | |||
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 <linux/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 | struct user_regs_struct *u_ar0; | ||
67 | /* Used by gdb to help find the values for */ | ||
68 | /* the registers. */ | ||
69 | unsigned long magic; /* To uniquely identify a core file */ | ||
70 | char u_comm[32]; /* User command that was responsible */ | ||
71 | }; | ||
72 | #define NBPG PAGE_SIZE | ||
73 | #define UPAGES 1 | ||
74 | #define HOST_TEXT_START_ADDR (u.start_code) | ||
75 | #define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) | ||
76 | |||
77 | #endif /* _S390_USER_H */ | ||
diff --git a/include/asm-s390/vtoc.h b/include/asm-s390/vtoc.h new file mode 100644 index 000000000000..a14e34e80b88 --- /dev/null +++ b/include/asm-s390/vtoc.h | |||
@@ -0,0 +1,372 @@ | |||
1 | #ifndef __KERNEL__ | ||
2 | #include <string.h> | ||
3 | #include <stdlib.h> | ||
4 | #include <stdio.h> | ||
5 | #include <errno.h> | ||
6 | #include <ctype.h> | ||
7 | #include <time.h> | ||
8 | #include <fcntl.h> | ||
9 | #include <unistd.h> | ||
10 | |||
11 | #include <sys/stat.h> | ||
12 | #include <sys/ioctl.h> | ||
13 | |||
14 | #include <linux/fs.h> | ||
15 | #include <linux/types.h> | ||
16 | #include <linux/hdreg.h> | ||
17 | #include <asm/dasd.h> | ||
18 | #endif | ||
19 | |||
20 | |||
21 | #define LINE_LENGTH 80 | ||
22 | #define VTOC_START_CC 0x0 | ||
23 | #define VTOC_START_HH 0x1 | ||
24 | #define FIRST_USABLE_CYL 1 | ||
25 | #define FIRST_USABLE_TRK 2 | ||
26 | |||
27 | #define DASD_3380_TYPE 13148 | ||
28 | #define DASD_3390_TYPE 13200 | ||
29 | #define DASD_9345_TYPE 37701 | ||
30 | |||
31 | #define DASD_3380_VALUE 0xbb60 | ||
32 | #define DASD_3390_VALUE 0xe5a2 | ||
33 | #define DASD_9345_VALUE 0xbc98 | ||
34 | |||
35 | #define VOLSER_LENGTH 6 | ||
36 | #define BIG_DISK_SIZE 0x10000 | ||
37 | |||
38 | #define VTOC_ERROR "VTOC error:" | ||
39 | |||
40 | |||
41 | typedef struct ttr | ||
42 | { | ||
43 | __u16 tt; | ||
44 | __u8 r; | ||
45 | } __attribute__ ((packed)) ttr_t; | ||
46 | |||
47 | typedef struct cchhb | ||
48 | { | ||
49 | __u16 cc; | ||
50 | __u16 hh; | ||
51 | __u8 b; | ||
52 | } __attribute__ ((packed)) cchhb_t; | ||
53 | |||
54 | typedef struct cchh | ||
55 | { | ||
56 | __u16 cc; | ||
57 | __u16 hh; | ||
58 | } __attribute__ ((packed)) cchh_t; | ||
59 | |||
60 | typedef struct labeldate | ||
61 | { | ||
62 | __u8 year; | ||
63 | __u16 day; | ||
64 | } __attribute__ ((packed)) labeldate_t; | ||
65 | |||
66 | |||
67 | typedef struct volume_label | ||
68 | { | ||
69 | char volkey[4]; /* volume key = volume label */ | ||
70 | char vollbl[4]; /* volume label */ | ||
71 | char volid[6]; /* volume identifier */ | ||
72 | __u8 security; /* security byte */ | ||
73 | cchhb_t vtoc; /* VTOC address */ | ||
74 | char res1[5]; /* reserved */ | ||
75 | char cisize[4]; /* CI-size for FBA,... */ | ||
76 | /* ...blanks for CKD */ | ||
77 | char blkperci[4]; /* no of blocks per CI (FBA), blanks for CKD */ | ||
78 | char labperci[4]; /* no of labels per CI (FBA), blanks for CKD */ | ||
79 | char res2[4]; /* reserved */ | ||
80 | char lvtoc[14]; /* owner code for LVTOC */ | ||
81 | char res3[29]; /* reserved */ | ||
82 | } __attribute__ ((packed)) volume_label_t; | ||
83 | |||
84 | |||
85 | typedef struct extent | ||
86 | { | ||
87 | __u8 typeind; /* extent type indicator */ | ||
88 | __u8 seqno; /* extent sequence number */ | ||
89 | cchh_t llimit; /* starting point of this extent */ | ||
90 | cchh_t ulimit; /* ending point of this extent */ | ||
91 | } __attribute__ ((packed)) extent_t; | ||
92 | |||
93 | |||
94 | typedef struct dev_const | ||
95 | { | ||
96 | __u16 DS4DSCYL; /* number of logical cyls */ | ||
97 | __u16 DS4DSTRK; /* number of tracks in a logical cylinder */ | ||
98 | __u16 DS4DEVTK; /* device track length */ | ||
99 | __u8 DS4DEVI; /* non-last keyed record overhead */ | ||
100 | __u8 DS4DEVL; /* last keyed record overhead */ | ||
101 | __u8 DS4DEVK; /* non-keyed record overhead differential */ | ||
102 | __u8 DS4DEVFG; /* flag byte */ | ||
103 | __u16 DS4DEVTL; /* device tolerance */ | ||
104 | __u8 DS4DEVDT; /* number of DSCB's per track */ | ||
105 | __u8 DS4DEVDB; /* number of directory blocks per track */ | ||
106 | } __attribute__ ((packed)) dev_const_t; | ||
107 | |||
108 | |||
109 | typedef struct format1_label | ||
110 | { | ||
111 | char DS1DSNAM[44]; /* data set name */ | ||
112 | __u8 DS1FMTID; /* format identifier */ | ||
113 | char DS1DSSN[6]; /* data set serial number */ | ||
114 | __u16 DS1VOLSQ; /* volume sequence number */ | ||
115 | labeldate_t DS1CREDT; /* creation date: ydd */ | ||
116 | labeldate_t DS1EXPDT; /* expiration date */ | ||
117 | __u8 DS1NOEPV; /* number of extents on volume */ | ||
118 | __u8 DS1NOBDB; /* no. of bytes used in last direction blk */ | ||
119 | __u8 DS1FLAG1; /* flag 1 */ | ||
120 | char DS1SYSCD[13]; /* system code */ | ||
121 | labeldate_t DS1REFD; /* date last referenced */ | ||
122 | __u8 DS1SMSFG; /* system managed storage indicators */ | ||
123 | __u8 DS1SCXTF; /* sec. space extension flag byte */ | ||
124 | __u16 DS1SCXTV; /* secondary space extension value */ | ||
125 | __u8 DS1DSRG1; /* data set organisation byte 1 */ | ||
126 | __u8 DS1DSRG2; /* data set organisation byte 2 */ | ||
127 | __u8 DS1RECFM; /* record format */ | ||
128 | __u8 DS1OPTCD; /* option code */ | ||
129 | __u16 DS1BLKL; /* block length */ | ||
130 | __u16 DS1LRECL; /* record length */ | ||
131 | __u8 DS1KEYL; /* key length */ | ||
132 | __u16 DS1RKP; /* relative key position */ | ||
133 | __u8 DS1DSIND; /* data set indicators */ | ||
134 | __u8 DS1SCAL1; /* secondary allocation flag byte */ | ||
135 | char DS1SCAL3[3]; /* secondary allocation quantity */ | ||
136 | ttr_t DS1LSTAR; /* last used track and block on track */ | ||
137 | __u16 DS1TRBAL; /* space remaining on last used track */ | ||
138 | __u16 res1; /* reserved */ | ||
139 | extent_t DS1EXT1; /* first extent description */ | ||
140 | extent_t DS1EXT2; /* second extent description */ | ||
141 | extent_t DS1EXT3; /* third extent description */ | ||
142 | cchhb_t DS1PTRDS; /* possible pointer to f2 or f3 DSCB */ | ||
143 | } __attribute__ ((packed)) format1_label_t; | ||
144 | |||
145 | |||
146 | typedef struct format4_label | ||
147 | { | ||
148 | char DS4KEYCD[44]; /* key code for VTOC labels: 44 times 0x04 */ | ||
149 | __u8 DS4IDFMT; /* format identifier */ | ||
150 | cchhb_t DS4HPCHR; /* highest address of a format 1 DSCB */ | ||
151 | __u16 DS4DSREC; /* number of available DSCB's */ | ||
152 | cchh_t DS4HCCHH; /* CCHH of next available alternate track */ | ||
153 | __u16 DS4NOATK; /* number of remaining alternate tracks */ | ||
154 | __u8 DS4VTOCI; /* VTOC indicators */ | ||
155 | __u8 DS4NOEXT; /* number of extents in VTOC */ | ||
156 | __u8 DS4SMSFG; /* system managed storage indicators */ | ||
157 | __u8 DS4DEVAC; /* number of alternate cylinders. | ||
158 | Subtract from first two bytes of | ||
159 | DS4DEVSZ to get number of usable | ||
160 | cylinders. can be zero. valid | ||
161 | only if DS4DEVAV on. */ | ||
162 | dev_const_t DS4DEVCT; /* device constants */ | ||
163 | char DS4AMTIM[8]; /* VSAM time stamp */ | ||
164 | char DS4AMCAT[3]; /* VSAM catalog indicator */ | ||
165 | char DS4R2TIM[8]; /* VSAM volume/catalog match time stamp */ | ||
166 | char res1[5]; /* reserved */ | ||
167 | char DS4F6PTR[5]; /* pointer to first format 6 DSCB */ | ||
168 | extent_t DS4VTOCE; /* VTOC extent description */ | ||
169 | char res2[10]; /* reserved */ | ||
170 | __u8 DS4EFLVL; /* extended free-space management level */ | ||
171 | cchhb_t DS4EFPTR; /* pointer to extended free-space info */ | ||
172 | char res3[9]; /* reserved */ | ||
173 | } __attribute__ ((packed)) format4_label_t; | ||
174 | |||
175 | |||
176 | typedef struct ds5ext | ||
177 | { | ||
178 | __u16 t; /* RTA of the first track of free extent */ | ||
179 | __u16 fc; /* number of whole cylinders in free ext. */ | ||
180 | __u8 ft; /* number of remaining free tracks */ | ||
181 | } __attribute__ ((packed)) ds5ext_t; | ||
182 | |||
183 | |||
184 | typedef struct format5_label | ||
185 | { | ||
186 | char DS5KEYID[4]; /* key identifier */ | ||
187 | ds5ext_t DS5AVEXT; /* first available (free-space) extent. */ | ||
188 | ds5ext_t DS5EXTAV[7]; /* seven available extents */ | ||
189 | __u8 DS5FMTID; /* format identifier */ | ||
190 | ds5ext_t DS5MAVET[18]; /* eighteen available extents */ | ||
191 | cchhb_t DS5PTRDS; /* pointer to next format5 DSCB */ | ||
192 | } __attribute__ ((packed)) format5_label_t; | ||
193 | |||
194 | |||
195 | typedef struct ds7ext | ||
196 | { | ||
197 | __u32 a; /* starting RTA value */ | ||
198 | __u32 b; /* ending RTA value + 1 */ | ||
199 | } __attribute__ ((packed)) ds7ext_t; | ||
200 | |||
201 | |||
202 | typedef struct format7_label | ||
203 | { | ||
204 | char DS7KEYID[4]; /* key identifier */ | ||
205 | ds7ext_t DS7EXTNT[5]; /* space for 5 extent descriptions */ | ||
206 | __u8 DS7FMTID; /* format identifier */ | ||
207 | ds7ext_t DS7ADEXT[11]; /* space for 11 extent descriptions */ | ||
208 | char res1[2]; /* reserved */ | ||
209 | cchhb_t DS7PTRDS; /* pointer to next FMT7 DSCB */ | ||
210 | } __attribute__ ((packed)) format7_label_t; | ||
211 | |||
212 | |||
213 | char * vtoc_ebcdic_enc ( | ||
214 | unsigned char source[LINE_LENGTH], | ||
215 | unsigned char target[LINE_LENGTH], | ||
216 | int l); | ||
217 | char * vtoc_ebcdic_dec ( | ||
218 | unsigned char source[LINE_LENGTH], | ||
219 | unsigned char target[LINE_LENGTH], | ||
220 | int l); | ||
221 | void vtoc_set_extent ( | ||
222 | extent_t * ext, | ||
223 | __u8 typeind, | ||
224 | __u8 seqno, | ||
225 | cchh_t * lower, | ||
226 | cchh_t * upper); | ||
227 | void vtoc_set_cchh ( | ||
228 | cchh_t * addr, | ||
229 | __u16 cc, | ||
230 | __u16 hh); | ||
231 | void vtoc_set_cchhb ( | ||
232 | cchhb_t * addr, | ||
233 | __u16 cc, | ||
234 | __u16 hh, | ||
235 | __u8 b); | ||
236 | void vtoc_set_date ( | ||
237 | labeldate_t * d, | ||
238 | __u8 year, | ||
239 | __u16 day); | ||
240 | |||
241 | void vtoc_volume_label_init ( | ||
242 | volume_label_t *vlabel); | ||
243 | |||
244 | int vtoc_read_volume_label ( | ||
245 | char * device, | ||
246 | unsigned long vlabel_start, | ||
247 | volume_label_t * vlabel); | ||
248 | |||
249 | int vtoc_write_volume_label ( | ||
250 | char *device, | ||
251 | unsigned long vlabel_start, | ||
252 | volume_label_t *vlabel); | ||
253 | |||
254 | void vtoc_volume_label_set_volser ( | ||
255 | volume_label_t *vlabel, | ||
256 | char *volser); | ||
257 | |||
258 | char *vtoc_volume_label_get_volser ( | ||
259 | volume_label_t *vlabel, | ||
260 | char *volser); | ||
261 | |||
262 | void vtoc_volume_label_set_key ( | ||
263 | volume_label_t *vlabel, | ||
264 | char *key); | ||
265 | |||
266 | void vtoc_volume_label_set_label ( | ||
267 | volume_label_t *vlabel, | ||
268 | char *lbl); | ||
269 | |||
270 | char *vtoc_volume_label_get_label ( | ||
271 | volume_label_t *vlabel, | ||
272 | char *lbl); | ||
273 | |||
274 | void vtoc_read_label ( | ||
275 | char *device, | ||
276 | unsigned long position, | ||
277 | format1_label_t *f1, | ||
278 | format4_label_t *f4, | ||
279 | format5_label_t *f5, | ||
280 | format7_label_t *f7); | ||
281 | |||
282 | void vtoc_write_label ( | ||
283 | char *device, | ||
284 | unsigned long position, | ||
285 | format1_label_t *f1, | ||
286 | format4_label_t *f4, | ||
287 | format5_label_t *f5, | ||
288 | format7_label_t *f7); | ||
289 | |||
290 | |||
291 | void vtoc_init_format1_label ( | ||
292 | char *volid, | ||
293 | unsigned int blksize, | ||
294 | extent_t *part_extent, | ||
295 | format1_label_t *f1); | ||
296 | |||
297 | |||
298 | void vtoc_init_format4_label ( | ||
299 | format4_label_t *f4lbl, | ||
300 | unsigned int usable_partitions, | ||
301 | unsigned int cylinders, | ||
302 | unsigned int tracks, | ||
303 | unsigned int blocks, | ||
304 | unsigned int blksize, | ||
305 | __u16 dev_type); | ||
306 | |||
307 | void vtoc_update_format4_label ( | ||
308 | format4_label_t *f4, | ||
309 | cchhb_t *highest_f1, | ||
310 | __u16 unused_update); | ||
311 | |||
312 | |||
313 | void vtoc_init_format5_label ( | ||
314 | format5_label_t *f5); | ||
315 | |||
316 | void vtoc_update_format5_label_add ( | ||
317 | format5_label_t *f5, | ||
318 | int verbose, | ||
319 | int cyl, | ||
320 | int trk, | ||
321 | __u16 a, | ||
322 | __u16 b, | ||
323 | __u8 c); | ||
324 | |||
325 | void vtoc_update_format5_label_del ( | ||
326 | format5_label_t *f5, | ||
327 | int verbose, | ||
328 | int cyl, | ||
329 | int trk, | ||
330 | __u16 a, | ||
331 | __u16 b, | ||
332 | __u8 c); | ||
333 | |||
334 | |||
335 | void vtoc_init_format7_label ( | ||
336 | format7_label_t *f7); | ||
337 | |||
338 | void vtoc_update_format7_label_add ( | ||
339 | format7_label_t *f7, | ||
340 | int verbose, | ||
341 | __u32 a, | ||
342 | __u32 b); | ||
343 | |||
344 | void vtoc_update_format7_label_del ( | ||
345 | format7_label_t *f7, | ||
346 | int verbose, | ||
347 | __u32 a, | ||
348 | __u32 b); | ||
349 | |||
350 | |||
351 | void vtoc_set_freespace( | ||
352 | format4_label_t *f4, | ||
353 | format5_label_t *f5, | ||
354 | format7_label_t *f7, | ||
355 | char ch, | ||
356 | int verbose, | ||
357 | __u32 start, | ||
358 | __u32 stop, | ||
359 | int cyl, | ||
360 | int trk); | ||
361 | |||
362 | |||
363 | |||
364 | |||
365 | |||
366 | |||
367 | |||
368 | |||
369 | |||
370 | |||
371 | |||
372 | |||
diff --git a/include/asm-s390/xor.h b/include/asm-s390/xor.h new file mode 100644 index 000000000000..c82eb12a5b18 --- /dev/null +++ b/include/asm-s390/xor.h | |||
@@ -0,0 +1 @@ | |||
#include <asm-generic/xor.h> | |||